From e5fb34524f2dde71ea612ce711e27fbf83c49a63 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 14 Jan 2019 08:08:10 -0700 Subject: [PATCH 001/400] Add documents --- Documents/SpaceProjects.odt | Bin 0 -> 285081 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Documents/SpaceProjects.odt diff --git a/Documents/SpaceProjects.odt b/Documents/SpaceProjects.odt new file mode 100644 index 0000000000000000000000000000000000000000..34973087877d9b7024d3295ead13022d389c93ba GIT binary patch literal 285081 zcmce-bC4&^vo|`{j=f{ge8;x!nH}4I^f&k^=z&{geNafUM1}jh)=>jP>p8tjrDd zoy=`*=v-`!Xl?Z!%^hiN?Tl@VYz>{QjcuH0os8X_azongkR|g;FM4qW~+XD5ro7i;xnts0N3yBDbg-r?|Qh3$-X0 zyA(g?FMbv!VNMkZUUe}pZ3#9lDIR?pZsT7(;(|g#k}6WaG?b;qbQHu?6%_?!^u<&y zB(&_6v`l67oU{xqRZZP>?c5FJgv?b%&9s#5wIwZ#w4C&0J9RrPQf19`jTlmB|yZAeL1ls#VxV!p$dilG1huZ|CdiqDWh9tX2 z<$1>y_*<)oIB18sngw|}$9kCsc>9G1cqI8*#|JpZ1$riid1Zz;WQ93qM0({%xfjNH z1q1{J1cnEOh6IL1Mg#_g2Zu+51xG|gghnPr#-}AlhQvq5rN&35rlj~K76hdh2c}g< zB;`e>6^3V4glE^qC+8++6eMJor)TA*XO|^q*JkBqM;A0@=9i?EG!~|W=VzwYW`*VD zqE&M(i8^v+KV%uS7NObx8gj4sblE-Wm}FRd-FEiJ8Wt}QRDuB>jXEp2RU zjIJDwZQaZ*?JsWZ&u^ctZ|!aFuTSq@PVe6@?H(@fUu^9iZXTR(oSm)zx!;}XJ6IUp zUm8DI8#!E?{IfiCwmNjSF|oh3db>S-yuW;~yLGX*aDKRX`DgQKf9mdV{`PqN_Rr$| z+2+gf{M+f$>&3>$&DP1EKL_V`hgUD>SGT)27w0#ZN4JkhcW)QB4;S~Z7q1`p7l*f3 z=P#Fgk2l8;x0mmChi?xTUoS@=FIV^X_jgaP_b*S6Zy&Eu_wTQdUteE5m6I7jKnx@j z!U9Te>zCdLUc{>2rq}CIpd+||%_J@jaX%26?>k5kiHuEj5cBx0AJ#2fG}zP=9vsM& z#tN}KZu@MuCfgn%dC4nlBrb*2Wxu@K-cgMk=S2(Do?6)r%r7>q+H0juy^S)c*hI65 zh>N0Qkmfr*i9Ol2`JkW3HgS1Q?{Cc>j;B2Dv(k3nzq)&#M|$|b)xCW3;0pdf&Vz3` z%(&Q9?9J;QzhrgF_c{N!iXDgZi;C_GRyFkIg?3Puvz${8=VtTE zx*6!XoifGPBn>h3vczup>$7NIWM|a`IUUKKd-xPqZ9dTVOP@bfU(Hw70k12{DztnhXudDCX+n>YM*Qcjm<*zkY5k0nlE`nD5&u zoaxa&Y=7SQE|SwG^ZIxmTInkCe5$YMx)+*G|BUgy-1?Y)-f@-K$?5(o z=9&3qRDXN-6|#-jc~-sdlxTmDZMd?70cnboIR{m--Ige!tDA zemSfm(Up7K_Ha9z_x0FHvFQ}9utF4NIkRu9c_)@UVcF?4*$a~LPt$ywb`{Qsc9Pb9 zmEX1HMeeyp$QLgnchSl^gPO%C_|pRF%7@uT*~5f}ip>nwfVeubAA(a3rWqz`BfOLwvv?d-F%M4XwPSo>dG{A#U+HRB0aTC z2}_jHorb&g{8^K5x(Ceg#9VgC=M(Bdwbah?rQ(GeU9fgGWE{LbCjFRs&-0Pn2Pv57H^Gr`Z+3!?f-y1fb>-urco`!0M;YV5@3}?`kSs`~1txCFnmB6(5S}oj6 zP5cLxeNhFTsf4}b^>!q5D)j;GV^dPind8q3`R$0Rmu3O8Jwg!=frWoELE$nv{Lo7? z`_jPb2(%Iv*KgoXohmsi3hNOb8j8iWC zoS5f@nY9o8U~xeCl1j_Oh@VBPW!^m*{g8ZgRIX!pJi0<2hm_JtQg$ie>frrwOZ4hU zG2s35_{HB%ig<~x!}`K1`IMCePl{@28r){MvVRTAmOGk zV&E4@x(>D1WbA|ew11)Sc|JgOAmptD%ee;Q9*w-&qZx2BA0(;Q^Eg7!oQf@Az;fg+?t-pxQG3qcbQFqB6noE@G5=m|qzoe9MNlELgYtLNwQFb_6 z)NxT49J*DrQSnJo)^X(SNhCj}&1NfiHtYgl9G`MnXrftXrb~SPU{|}HG;tnrk&Bo= zK0KxTn5bBvjHh6kw!S)9o}5J(SH@t49v}iRVdTtN^JvFnx78cV9G->cOIGRhl+6f8 z_6cuOFT&<)7H6BKnoLV$rrIx)Y-CWJF{fnCMa@abQzD9HyCk44czCNdIX~)+6Ui80 zjWRlt5}U@rPL)*l;LOL#z(()ygOR2g=okc@ix8o+OwITFT4MIp=^j}=&tSB7xSZ=! zO~~7LdZet)bAm;T&Ph0!*NWm#OUN223-Nd(?D-K|KdLXj_xuEvPY@QG;sF741*Zz; zBMS5)nr2t4s-n=`3%CIoUwFWNVha$)=&O3Y$l9$m8|uDRybF1IzE$HUUkN7S7Ed;# z!rDN-Zs32{P8n9a{t>}@&OyD6{gGttXjg$U^D_5KKitQUug zGNY{cU@MI|KXA6IV6C?>S!2Ld3#yTt6md+~JW0SCq~o}{4s zCbZo;Z$f-voX+^IyZd@-sJn}qqoDT$cf;e?{sD!Dj0xv&_{*LYHPkO zEv(bptAur$In|1>DJ4i+0o5162$g5%1VzXkZi1do)$#LMqPqGQ236s9`KSxkgi7Ks zFuk5NaQP6@l~hvNcU&IXHi&}1%GRyVI908o$}kPZBF#Oi30vUe&G7ORMlS1q>B?dt4W#Dqggi^T~zbk~XO?52CJk?V_MOt)pd9SmO;lu0(y` zYqFEjpgii&->pIEkxVAx z5F_22iM0;nCyspcS+;p1&59N<+{!UVHx;ik&d=2J3KcCcR9QamMQR52X6xlDg(K;G9zRxQh|ZBDB4deY)T~H2CZbC(k@9| z&}CD->{!R*fh#9hryXP@bGE_O9c6f&;E|*Nkg} z!uu`RaE>>K>39-0VYC9THiIj9zJZV+(2qNeTc|MO;so2!#zE(SxnkTmw-BE>esy0N zA?4cACU@OQ^mAzSc{o>6H~LKB?94aP?Bn*EP@MHYb6_H1Hu*mN!UJ@h2#=M3;eC61HOb3!ysMW+9_*#(3p71rit z6!OJ%dbK>AsyZE6$-D+;zplw|0342uH9F1E`GlO;z}vGYyEV+@sXR&c24vVxA*~&% z&h9WmqpMaceCbr>6nQdC(;G@+Se9hwcLWAcF~uRsW)DfDyvy*8?aUwyy#DFYq=}P_7ojpWB$+(qkX*r%{Exn*v(uy%Auq#>Mux2%@ZDLhe`Q z_Udp0a3NsI3<;X4P-{UO$nE)R?i9q&Ld17Z4&%7+zK%WdKA3td`ek;`)&?T>pWk-a zfbh@!%gDH)fp|N6zy`Qre54nJLa#Holx`gL;?YAwtZ;)BPRH`iF=U4Ihj1*dplLK5 zl^3Qdy?pJZL7I6_|F9ai2-ZzvQmNWsjO|m~J(7^ems zPs-M5iE7hIdzh=$G79$6lNEG|f?YR`N>A1hLE0g0)wNB%)@QLSEIr8UMJ1p>-y$-&%6BHj2hTc1&hDw@}wgPS<%XLdDLoW*+Jh2O(k+ zWFE82JufB8YmcXl-r<4kdZaahH^|5}*AP3T6o@e8V%^!8TWy$eW&h=ZIx_yk6H=t7 zegKP(nlWCL7{M?OBsTgs9}mPF!35PD7b2NgQ< zUI~ICM~qzP4?e}m6D#ftG1~pYB_OUWx`iA-WHY+$z{@xGFr#9^QsO5Jgie+(ZT($ZJgD~su!@KI;H3f(9ZD|`Vft&H!jS1v>QpW2Itrimf~NSjNSWEil(q2t1j_n3MWS`~&oRS=dv@hP zhGXKGQ(?9r9I!BfwOpdym8ZfJlO@XW8RF*T$7V^0^CX#koRydbuOJfB7QrqgVop!J zKnTt}MKNzeD0f(RGQ-egMsR}VoB(W+6a!C&bb|CU(lMd*U_+1c_ytFUNW^g%Sy~bd z>-_T{+2j<wK!U7&t1ckljc$VYp}=K>r`jyIAS!-FaM)Nq z)f+x=BkYfXg{B_@0AzQK!{A4TcpNC=fze~BgLzQf#eUuxO+5z$&|`sb5MW%Ox90;* zT*!u#<700SY1eY>;C#a6ppbIba%MY`zESGF;J<_a&PlII)<Qv2QszK z48RRR(l$O?v*%VNR!f;cB%chQ+%pItHiRZksvl9~q{Qv=jYMU}rPGK+hZbvad}U@} z13f4V1xG}aETxL(I&fQQ%w3MlrSxxRDszAfL=2jF-tpiQWW;F;h!JQcy7TUN7Xo%b zc$_eA*IjNNw3Bm{z)Jq@b~bQplO3Avm4r6^L4%^K!3TRO-$=*zG36>zOUUQn0XUFA zEcg?1eH;Vk`n&A8TFd*el+r8<7{uIPs53NuKw8Ohgf)0kRp z#GAxM&)SqIC&_Gj7RKQK>j+SoM4SQ@sT{%lWs=%6_i~*cM;4sdEIWC6wkEw)6!x)Rh^7;8KZbqj(*CLql-Un#nE6mvl4k}Y2hA%cF#cIxx!FYs7bm` z5ZzZ4&&Gy@s6M_J1M5O~TB?2acj^9weV+zfz)2VKb(eowiY9UAS@j9RhZEeo*_$>V zUe$Y18#)WOZ(zpB+wv8gYRU20B2R5iHz!m2(Zksi=@~R!%hfN}L-R9N*T!L3Zl}SX zY>$P4W_c51HJvTX`h@eTv&@sVX1<(ui*@H7*0ZY|ef6gb1Y8@1QOW#Z5jFu|Vl7_; z!ynL2_JWW~gs33DYAOQKejM_3P+{fKGdq@Y4LaN76tyNm;2V2#tGL3BaR%lVK!)sH z#?1(`kKcc_?t30a^W$Q919`do3WDQY{DGo|?)rVM)rL*N35>D+bH5?WVC8Gt4U+8> z>I}wlK6-@UFlKUR8xi$bOZMJN&APXiyESZ=eAYiFt_bRYyIL-i{y8xK4;7Yny!U5h z{A-~Rs0|E^*4yDho1Q>x2#NK#W%%}=AR?iDA}@}t$a6zW_) z`m`pKZWoYruHdX)1h?J!+p{DAqvby*3>AN|6q*13BA&o)=L%~w1tr}*B z2{oaPNY5e;LW8z&NtWiupC(Z|KmQT!6mF7$lul(KJ^>78$stWxax|aKU7BFTSzUBT z)UhPY9K3dpN<%*;U@vPODHY&jAlhf)rNp+XEG}$gRc*MtZhPI8?!@Rz-92@Ui8%Ko zAIJ?PKBuH~X$uZNoEKTN`&0gj_|XvB#@h_x15eRaGYR;m(?hedf*KT-7`F_AR44!T z(tvz_mFhZX+h{{CJ-koMMd&slKA7Y>h&R`I?E0N^zPZ$O0&cNHGCcE`Sk1thm?D&j zu1+y2NX8lV0Yw!XejNxJ5iq8Q~|G`PJgu|ZpkFQ`Z7s9tqps|o&2h6j%0{fJUn9f`>{_JCj}lj!HUJO|^Mg@opg-`e|ei43N|~BY69F_17{otyM7C_uq>(VDSbNG5Syg)?19+ z{bC~>tsF&6FdTl$grR+q*C7tJPA~Ah1JE-O#A^h}&HCmTMupE|CF+mdRx;oE7|k+9 zcXOOz2C5X}aDZ{>JaW#qJ>pl23t-Kw1Exe{R8hTNK4AC=DdJn~L(*m{CS8qW;@`MO zz>s#|dAkc4VWl%B80pE@C@Xc=o^#C>#XY8LkL#7%#_%XoO<4*2nc5Qc^x`gY z+>T~7#|odOWdln~E}gROw3Kn1S3R2`bh(V*JIXqIOa}|jnN6WY_ZA zljKZM<~|I`pNqGycg)p1upECDkA>Zjsva|OXwInTGh}F{%bmc(7Qsz4T3Rr$L6L<^ z8=r`;Q_7^ZXHEYE7ntT*9t@UoULYX_ozD%oDo~SUFO%8ift&a3ao_ ztoUo6FpuAe=pO76RB>BtCkisR6O1L3vUp*(EeXAjU#Q;4Y8~_~w7PI+W8}mPx*dFf zxzV4J#ktmU{mR4)qZ2c&es>lzdI7h}Rk^xk9SMHLsEG0qQtsq2lTnoPv&-*g36dEK z1{so|U&kxt3a#R1G64~oCG^9$+WQrSeD7$c)mfRmRO2U7mCig!riwvbWj|e~9^1O+ z7RmJ7;5?w>f*dOx0lX6vPF2HlRjGKHns5=7EiUIy(dGG~%PDekW>wdlwk#MWix<1c z>Rw)E7s&$AU2l{l_JEi;4V zmm!2cXK6Z642#VUYOU9?m~;BV!=)HsV0yC2Z90Cr%aqU$y`Q`TcI=Y+NOl)nV&QxM z>sva=U0M#T6tF>WLoI_hi7jf_AHORS=03aRLFaG^2u4E+cjxU-$K$5KMWUT}%RwBy z@Rc}^N)h7M#Y&^C^X{2e$lpHTw`7XN-*)raBm9LNmrMyLr|cKbEHgT zpIWRl4;PRr4w42K&|1rsG20fy^)myA>jKL##4h9VJ`OxSF@GVL%!|gSic;e*Ty_r} zC&>s{xo7A@)QehBGI;d7JG(fFOX^Xv?9u#pMTil1+Q~w5-!}?LAn{SYnW-a{vlTKjZoSHS7~1Fu;=`%qO3X8dcbVp#TQw0Ay2wmr#DBt zs9?R#$B*sSVfu9a){!}PNy9P~eRDyi{+@p;uag-^mW+C_{#mfVBy1=hB9{>1Ph#N&YN2NgJz!~IhxJ51$dbGDO_#X z6k7rdi!Cf1w%5X5T58QNjt)Pa)vgTR-M0LA%3hQ937zsbDS1 zyoAI}*Rcuj#+BpzYE;$Tt4y$4d(5TV1mAy|%XbWRLiucjd6I?I0*kzzp5gCxl-`W; z_zkF+s|dYDZ}t`H7EM_ZM6-78%Wf>yM_4eF-(NwzJ#3(2=PH~;_=in+D_fG$qp zcb8tXKO{Mh<)e*A13}CODvpl84CyX1!rSeAVDA(-);jui^;WZQo)%aKWEfk3Cnnao zwD19BWU)Xm3X#t}DwTs4a$OKR<0ya!5yGFjW=I~>Ds76}ANp)2zi#ho1aWx1CktNl zVLOYqD)NJy#Lf#b_^P^B1L%#as1Pswdwag_OK0?!zW)jqK{_>NK6>}XW*q;=cJwn& zY&Cc-b!@PU`K~)vdQH8uF(fjzL>_tT0 z_otWd7-|b|cT5?-FZc(RXG{A1ujIC23&W4Wc}>X8dKubv*3G3OS@EvNBAr}v8y{^j zIZf9;s|z$|j+SLV>P}A0_&Ox21Xa&U-oftFcoldCY{HyHSg|ug;^c_>*SV8Oh6k+} zCx0P_P!4h~(O+S6k|9S)ohZU+VGVy``N?bdS-`4e(hk*?^23`;dyLW+$91p*26D+e~uR1g22;c1DFVGPM zsXnq00fb@Zl~=K-;oR*hnt?!&%BSv|X`r~oLhtWFX$f_jco=*gD1`((Pir&8r4&+= zn_v_W_^H8t+Ci)aRyHIC4-Ko|4YgNsfG?Sa+l|P-r(sh#1!MDv$G-V=BJ+|H_<7Dm~$%K7~%F zLzl_I6zyu!!$^-#Xi4=wD6AkkI$aJHnrliK_F_K=y>I-purDM)CX zViDxQVy(F0muzW^3IQ|mMcr20 z(@yf+=}=NsGeA|G`!M;??Rw!LZ99$&{55)y%a|4)S#!dal&{McyubS#Ucwjg7)Cp; zdlW=!#^(JlT)aL1>&^|hah_BtdE+<$2v`P84p%&|L&%G-a0dZ%e@f`9@=i0v%U_>s z^7IH9=x!d0sb1jsB1XR!@kAdjZFk>yk3FhGYMTQh4M1KLg{of#N0s3~A@Vpih1F3( zfkDZRzYoXJn{W`5Q2)IfE$qa$R1hgb_b7j@Z<*j{?z~EBiyvv*VIN9mpF9j=v|(uX zFZPfiipp%`nk)=~p^(W!?<{XToh474;m7u|)N&&$9e0Q58cs zeWvs7c514@6C88>v}{9t2WLb>)w|X~$Ms1nf0|F^zND_xD$KOKC#L0VVxa8wzU`j* zm4n1OTXo1pZ_y6a;>$`B8aavQ7Ywru?a&@r@Fbcv0|$hCqT>v zCleXV3-{SY4Eq@&%~`c?V20j0$Cw+eU8j%-##2QOW{s=TThdC_F^&1I?%B z`n@=FOh`D)rPmS?lpW)ZEY{*}Qdtl95LQVopM(LXXkLQOaOFzHt7Bh8l*!i8I)&Dm z&}&@F5Xu{2Z$XpB1D~EKHQv8VOfqcdnw#Pc+Xh~mpisYc!xW7oUwm3^WEa!fgKD`7r4g6H5xTJ#(Bt=?cgLB%XF2&T>^5X+2n6dk6# zW%O{66CA}lP=Yxu*EOQedyGf2oh}T#!%ul8_D(R5?oQ8e93{&mST@pX)6N-HWjatM z8d$|jlF2W`o~GBU+q4WgX8`JtAC(f?9EOZrVl)GFQi`N5k3|;4*_3NI^;!8nYO4)f zi;WjU`@eo=r8WWhFluoU)-n}xxDA>C$~W5=@e=BfmEYo zDNwLoTiycvMo}|Iqw^MlI~!QeZatCes5rkcRoQ{_mD%xtF{yb6KUd5-s{OC59)@mM z$ME+A^+S!xx{rkj^M1g64rE^n&6N3ry%T`Q-GjgN>V-fBMR$ktEtBm36%I|qAv|)j zTTL7zJ%PNvd@04L)T^Xmlps+bnfQdEuo4>?>y7**RUZ~{MhFK#$OJ`O5R&SVg^s0r zWCw910!rQ;H{`ZQ5Gjfzi03qTn^?*$&xmpsxKZ-CG)ir*^vRG6siKDp(Ue>_r zsPKawb0Q(Qbv_U+DD_9<&cTlXKk57Prt#?+zv|r9tllK@@L|zNSD0K2B(C@s0ex)NgZdBEIKnd3JY6NdmDB3ENr|Xci3l; zYPm2Kx&ggkZCfH@wokKBI_2Z{9C~#pC#E_gK6^KYBY`AJCcUG>NY?L8ig^0?vU)?r z@QVy2etKsD$DnZ1Tl|l2!hZIObIlL1tsWsTbF59jj&@^T={1!1*h+fIj3WRNu(0wm&NQknLspAEoWY1Qqbyq`zfOr+>`hPfJhAksy2+`vz!{&PzaCUN48?aPtP)@}$W>HKhKmZJAO1e2QGd|rc zY5F1l?r(Rj=jnOkdbSwGX?_&N{{R0R{*IgZhM4P22e1Vg?fnfQ0+JAs6|NT4^Zz$I z2?`48Ke0~#y!r0~_HV&T-`&>PiN;Xh(9GD-NY99Z!bndKYWMFY4uWx$9}Go4)o%|k z77ECrr<8%d6E&#(S4f$@36S4AKMRpG6pK6{7fJ|PJ}3<~-Nic>3`kxI5(@HLepmP} zZ|A@H{|t`myEvBp1_cKCC$s$X*4)s^*}>S6j)DIFbubD2`@qN`B+MYn!obWX$Sz3F z#KyrO@PCh-0__C?0>Oa-`OC4HPo5eG=r_>6(IOXF;95!>>mf0Nvs(bkpR4w;O8kje zvH}`Kmi(~NR=INf%3H&F$ro4j70s9j`{gZO}iT`safP!KE-;uIG{)>-*pXh(FL^b>0 zk+{MCOO`)K)W6~hC}#h6BsZA<{(W$)f2$!NpNsTgV*l@?*dCI-Jfoiy=EziBR6nq( zn5d{weo!&}sJhvRM@L4X!WP;k{ecpe7WO$&TSwne57fxUn2?$lqM6I~=>4PeyON)( z;qL~l+B$VC>;vV0>iUnwR~u^eN(mzSa7lnTm28SaCSlP7ok@G*d?OuGmKt5zN6g1W z)n}|Yh3w%WT5L*OUq$49srhbec5(I)4H040iQv^hTR~Y&(AiW_S47c`vN^A4M17i z{NnGpWIiz*8uN7o^}{0zQFV;}(dJ)O#$E>pr*mTTw0>td7D8Ufu)^V*<8iJFM}0Fw zM=ci4NLT?e;Yn9t%hh}*uFa+_t>!GPvSrGtN8vAE^O3GRlP)3*vdQmbi#6ZtPUlfg zA%`y*lhi@}$83L_%;9_8O9Mao7ujrLflRPr*<@^DUWJ`}(X6IC$TUWa>#~2AmXow0*DsRryH5L{Y8d51|W}s3{jm+pY>3r^Y zBofdPcs9H?yo5u5h7`yu8Om}>YY)ZEx3XGy0_WCG;dFk4p#|ymW#0c$_jfeEQ2ZGn z4K7D=gD=)~P<$Nl7rJFLxYaGk4771+c(ieaKzW3OyoC&f3>_UEEwL@RAgQQ4wY3k@ zm`=pSB^w-Xp(RI8)j09TsQ~6~_T`_7E(;@#Z!u%epka@Tfp2_(*|Epn2UIB3e|!Ev zsPm-(lBL0?w#pdmUZk=z9+wef+gX375H;kXv7U|Lp!+FJ1kf&^7Td zM*UOO?-`J+yIk_RIKhwdYblf>6IOUs*C$&!4qp2=Ee3|LHpk<0v-65+O$t)d3CVpu z17qwVNdtXC`@islz&Dr?6%>|{pe>-YEx$9nur*=amT|ma#5iA%ld09OpnzVjvzB6; z(&Wp%COB4EQux&k{4JZyOIlY<_ti)KFUbDWKfl}gD=HkJL%}a)WO{ZImiZ;DF{RB5 z$=Kip;<3ymY;sN59+O&`yFzC8H@7wkq*BZz#Y5{H?I)sgE-=~}9(+cInzIez@aNCp zkQO`=l9zmg5c*L%_5oRbf-EV{)yuat(@(P?6 z3)jC2JtT=Pn5u#Z^AT0&hzR-AHLy(g`2QPKfkCofbIA+h;mEc1(*;pP}C=Kyev zo5z0h&91CeAZzSxWYLPt>g6mF#*C1VF~o!!h`_R#q2hXJ-coC^$Gc$jHc; zn5_mwFj7(z?)S%Iqod+dQWa%oZ51jp|#V4LG1NCX%YleWcqGzK{o+7mQ&^F1C<{OPawLBoBdEOSu9BT;tEr6DF! z3ORs>=@Yq+Xb9z(9RKfV_@5C13FNbuydf-oPFTh^7Ehc+}160fjy5d%bCW?+PLyrS~WNYCOd8|tgx`g3^K0F{JF0p0nf!IOPwooX*GHbPKV&GJi_7tVv8AJjBTQp(2l z6XN{iWc<^C`IK@)QohAqm>%7*kM<9`m$(qdqvG&uN^@%pAVH@3`xz}3OQBK7sCB!! z2?z+7nG9f?m*?hn+THBM<@I8FzAw@m+T6ho z$)z`tGaMerN*b!XIi>>4X@me%i;KZ>fEGMRd~wCp^6}x}nX&1qK4NB{IGg>dr;Fu2 zr}f_`YVanrjNC7W6C_&ZaY~ut|M8FhvBO;f_*;Y#o8q138y)voBQK{-WM_V4;LH3_ z`a;Q+o}nRmoOpxDlt!I_h@Kw7D%0Gpbm@Jyb_ajT^Ysos3JS`5T0pN~>HwtSv&c09 zg07*J)z!rz7E-f@=c$4YFEA3o9pUcyZa9S$7nD5xo$<=ac8oHkZ83FlN^JiS6$Nch zNi~F1lSy&`3sNCHnDKAQpiqwrP?rgiAAO+=Ys54AA7Hwso%P>8{48s0x^~C_xKAZ! zqDwx7GCwDAUuib5`CO&uQ%EC_1ZkAYCS&8!Z zLHZ4jpC)E@{sw*8Nv#ZLX$l7qPESc1Afch%-075YJ68{lKL$PG*QdWNU;%of=*{zy zg<5)K9gHgy_m#{gGKb;+@hbmuPavV3e6}_|&?SACSZadOSKeX{n-v-~A*Y=lf-a-+ znOtxXus1G#DyGnCQ`68)O;7W>UTGnk<-fZh3`cD=TNiBH?+t_qWc}5BLPCOKhy*qS z3;+PAWds0DN8^Zdx5&uIwzs$cb`Zni$i3ae_(Vl?RP3q#>51X7slGk{o5w>ioMjU% zY%w)6yUX*??XllxvR|bM{X5}kC@^`XM46S)e?0I1V2wVA_IGt|lEy5f(ky4&&uQMwJg^0Mg(L|p7U<+@&Z>Q+@7;M~NUUav!P9`S2x=pfQpHM8qYEd_8 z<<67fkyKlDD4#P28exSze=F7g4{AT4d!mMm^G`u+ib4^uTpP`HV1&cQSreTrE)~Ac z<@ec4Ca8Qir7KdPl%5(L#pAXw3J3@&DKQric#$9#780`1>~{b3crO^B@a0Qus*Sbv z+4*@m5x4!>Mjwm8Fg6ZO$~|(UPfVHJbcse{V&cKULHaN$gpO{I0x%cuq~wL2PM@3m z>m%tTzI7$L#mxI~nHtwYv+Rv(R2()mB9n}GbuW68Z@i-S1@OjOCw$B#li>Mv~aUaXg;Z^0>UZq9hi0g-?Wm zQ4R_O8XlG6-8(%40}_6B!bUJ|{{Vc@*!a-yi-gOd>7yquF7E7H-_+Ff=g*C0DGSo6 zy0G$?sCh_?tb~k_*}kQ%Dxac}ka=H>BoRqi?WJC=!nqDw+nHKE>*BK_qUw7Q=F*J+ z&uAWAcy7H$SHp_3uPERC!M*vF;PUG|Bmi>vd;Wb7F%SDSqW(I@cRfn0h?yMeq@2>y z(!9L9-@jpqrC!RFN%E}m>oSZVJ zZ{xJw$>1!?P+6R-)UB;0u7h#K!n>nBoAzT-rZn1K+E4cc%if3AqHWb86Iu}QjLPt$ za*NKhM?8%f5#13|D^v=k<4_KKmRR|}j1bOq3s(ax%DG^7aW|}u5m^jA|N18!+<}quo(E#0`ayGM$+*H z`@{bJelE8=R_q+vG}O#NR%DHIqxIC;nbrbOLe9?45|Wae8yml~vtfOGV{)YUzqxHs z6*eP{8yw^CVBqBBvA<$EBr!wf>> zJNEsvQ{nS0!&2Wg!2jDPL15FyY_%q$pfD~TMJb)iGuzQY&d3;HX$VE#flqyNfA8Yr zQmR^QyxAWU8yoxO%NOmDtT*XMtbY&Wo{i5lMD$7Y5m>i@c8f$;BE+2X5ff$bpW~r6v`EHBuYCy zIk~Vc50)gl)rpa^7jJHMHmGhs_XiFhp5!+ghX)6Zy7%@jY6N_IPkoi&B#%C7x-co9 z-Hay;x3Q#5j2}ji6JgKPt|EtiUK$b`3;N%ME~}*D+8_lKLwlM#d0b&ApUGKKUG8J^ z;?p>b@Xjx+6E|xJD90x3)-FH12i=r|gHE&Y4dLAIFseubbShK!^Sh@3_ILdMC-+ zcC=NEOp=HT-4#x2YHVyR*3i%>E-ucMP7;+;5~GWWj%H?I0UszoBO_#LO5enU zmW&JoA72&V>zJ6B$jAz(ampA3tPbJ6{plhiTK?Fiv=OJS{`$DIg0!o+Di5xE!;=GY zV=F2{*6KW)0Hz*uI|*8;{{t|WmC`5cZbjI-e#cceGPp=_K5wx5>%ZE3Sa<(?inVu} z8!Z{`BJ4nfNm9%hl(37Nqa`|;W2R5Utshbx8d{eyTiWupx3aSGaWF_HePwrd_vi@q z3QPo3U0oJ%R~(TD2ngWed;VCh1Dwt0dIOoCzuy_n0@EZQC}?kY7rYA`Fi<$G-cnI* z1Gph0BLmJfKvyqczFfn^^b%_KA3wv_y4G@<(mM0`0+We``WPUg;Oa~)AHH}Lp(yw3 z7k1D8Br9mx`U3F*7rRhJr#R;cEn7KOo?htgNh@rkI!* zz(g}Y^z^E=+n@mA1jrO15TIh<;o+H^n=1=T>DB^Tus>a@q^Jmb;%ginB7S!sfTft2 ztN@E+(H|_Ut<|bEPYDY{4fIwM?%7c^xV|h2$K`Ti;34LC4zPY=ieX~)R22EY@7t33$tG#Jt1vaY|Ylamt&1ai9GZF6=~e-As+vfFfZ zAnatI#aVp(5KP$O{l9bE0dx1oK<(K)^_DKx7FPq-gCY4 z=pU@BqAGYeLmFq0k{YB?RE*5aqo%I#_lMs(Yx9O59~-NvtOQUAj#ynz4xNbT@bC}? zik^~^&H2KRg{87st=8)uz^ULFSG6@YQ`6JnWIuxoS1Q$Pay&KW!wH!Q10VqIGo@kp3Ry}Zq*va|KT(UJ9M=_ zcVasd;Xu8aiHEkO(&(FD^!xewZH@fo?Z8*|0EDQ&U&0xU z^%ZN?i^HD+$1~-+ZCvyK(u!6UMLz#3({~2nfgE4Ir+Cm7T{u~r_mw6UeS?7-vH+E-hGw8>d!=YEUuvtM ztup)Zq9=bRN6{8dkYT4C;Sgpt>E-Rf8XUe&E+$Ia+L3nF8fh4C<1BfvQ`81rb0STSG$tJ$I6wY`nan z&CH4bF7B31aH`xqZHn`rZZO(&1>3co=NWqj-rGmj{}Ks)5|qoKa;8}_&-*WtVf=1q z*s`zAl!S$)z5TUp=U0pR#nKAu{R`^zC({%rKi#JMH1HNsD6zlPDDl{+<@%y5lAMs> z`(%p!Q{=65GRNr1hy~Cj?yryG{fGPeGs8Du_&2-WG8#VP+I2+5B z1g)3fDIvokaCN&fR)U9-~;lOYM?Dja{Nju)mc^jD_N zpZa^CV@C46jrf)DWnnMx|H~{qm^GUn6Qb<&Ki)EO-t^7|%$!veczO!*(D!Nubs6I~ zx@K~(RTPrA)z9(5EV))EIh%1PHBh(26_`ut0UOrjq@WkMg+tJC@8P-9O=vRYb({GUUE{>T#hIA`|~@c$J$g-62y&n zraN;iG-MEFOb)pJ*b-0TJNx_4x=U~HNbs?7Ut^MBz9GO(8lM{rGl095%s_w|qOE87 zaKBe3fHu#vsd`Piafj4@yeWF!8hZ3(!jL|^5^6xgEJ0HxO+U-|M<8(*Y6#%p;o*|Z zOiXNS7*w~Llhuul4bTffLv3#tideVV9{!7-W*ZEhSEo~G@&#!L5U-W ze41`#odjS4($<{oE2)Veq8vrc7IbF|{N#Sz2qT8|VV+2!0&hKOTG`NIo7ADx9U*uxn zzkmNr;K5M0S{LP39SYNyK07@--!`T4<@nMK*7nwiQGNU)AAOzgI{M$=)n^K3 z>FMbKZqS;ctE-EJi3!ROOb>xD@Pt1kB&4<&S+^}vr6-t*UOK|QgM)(;6JH&Xm|i$v zA1wmy2ig-A6?F^zSzEKVv{Y_(tqTf5_aG5zN=Gfgln1j{?Cx!EqX2@S=-Es+Wx>Y-JPnc)O2k&gj zX)NlCqm0JD&(M@8r#EwsVe(Z}Zr%q#H1R%$gM%wksifrMx&zpjv?nkyFh4(kS1U3$ z7LGP5GIDKwy{!g~nCA~rY&9C}KYjXSHdke|SZ_xPQOJ?o|VXe>Hp$%A@7N#Rl$_8`xEeaB7=%z3w|j^I;P&Xw=`?$*xZi zVs=8_i4H)MDl9qL-|r~=8PYm1uzxUH8G>J&0S86jNX2x1Rk_r_kk9(*=!u3Q?^+8J z&-o-M_P!+w9@0LJ#`y`iI&@HFc1A^6xh<(J)#G*nXQ;0)KQnV}Zx0c_$^FqeLKm`g zql4-H(#Y>!z{jFMFrGp~c`a97%v^z~R14mr)49Im^xkBlx3{-oy5LZtJmJ*TR1{Ty znT^$PK&XZD;`7R8Ys!&qoUy9tIE?C@OA2qDPI7W`bKN%u1*{r4SlHERp4Zd&Y;Rhv%pu$1gyKkCjG;$DT0WZ(H6tbG&89|5)k=?Hh;P+o2QNI^}0R)CfkaynMmY}0 z6H<*72O#7C>!55KG{lc4QxSbX`1$$Ktul4z+uNaFRNY3QZa8#ld%AI(>`LKCns-X` z%pRMeqzPdGdVjDBp8+`bv*{ym(?7Wd>>ZCjy<>2ntI6%8Z#;dn64cmxO2A{+oJ4vu zCN@aM5Kx{qT3mOn-86W8y<~YGlFop>SW;2~&@%zMd30Rd_U2|+PtRY(27nG9A0Jy< zd1WQEhi~HE9;@e4QoP;qEqGXkKXEgD!L1md%Q>!|YV+%zL?!5I26*kq$LTV=6`gB; zuQACv=ey1gNGCPwcX5(oCP4EH3=C$XVrZ4TM7?P{+>h>&qptyY-9t{QF<-1V8mBDV zw%ecb1uz*F*2%?%_WgT7Zqgk9yhtHjs*)U>bzAgfrh7+5&b)Hx70(i8g~@9$@AHq} zLl6-W%cLYF3CfKg?=IWh+yAR+TsS~xv3evUu_~i5&)!aZagn@(;bPtC4a@tT#D3(y z9KQbuQ3K=me(JEz^Ci#ibD=AkXS0{>c|ZjY6e&av$J@Jpz;z(q<*(>)$+1An}|g(V~qGlpSo zJxdPnW={O(PVDoZZ1$Gq@R%?3^0fTEJnNS|4GGX2viDxAp`SL#PXOO)duMl-UZei& z*RRoz5O$4pF%;-KS_+Ea1qF!QIayhifbs&a_4DUXlr&FnPe7hTMMTi|fY*Aky$xT$ zWwFFFW*}f7EhQBaiVOpDBRW89-@Iq!F|PG&onD`FDE5l=pfy0A@FW*L>4R4DAT>m; zZEo%k7j8x4qQpebSlMQ!^(6F|&TYh10 z@Gk%`h>D8dIdgdlL7hpg6So}gI&wo!j8BX;8j{;#-Ww$x(?WcxS;E#{w8X{6<|vUW zwxf1P{u%MK;bUZ!Q&pw;@L_mpNP1xd9SVhEwaFiqh|6y8tGql$ktYEhqeUKC95E_7 zD$29*KX&`Gy9?Vwp-nwK zpayneJv|Q$#4*gz%^fYbpiLo3L?GJ>|m^}iv9@h4Y!OJlCvCMyDuZfd{w>Sy5WMd0ZqOVPgD0IFon9Lo@;N_d ztRHHxoAh7$4KoE{{cfoh5Y_?hcjnulPI8#J$w?ekpVLD*cpCJSejfoA#hEH2tRfx4 zx|iSGE_UP}Duw=9g-_gPdz1Tv7vp4t@WS3}icV%VjCQOaZPj5(U6gC?d@Y@Vro~a2>6LD)fqKTG|DtBmw}>sqFbhOBE-PJ0RHj==w6k)wHyh0X!HSG@U9^0g!fO3cS*^13hI* zE-E}6?Kh#wRBNk%n3zGkqaG$f;Un|*vzGv)56*MXqZ>MZC0KsR6st$xtZ(2I+UZQ*XN zuDw6bfce)J4!|god0{`2@VU;6j-FmZ0@8d}$p|yyBP;f`Tuq(Dd|6wvYaYOnEz7y3 z*W+j@Ceb|CGb9?B=uXY(c8Km)YHC=+q?Ah02Lt`n$qJKhH=RcP1%PhZ+1c9umRE1d z$#FlZ_qMeO4h}E{?UG>GMtr6)CthOG?fIZt(P=fytmfiEPEI~~d!8$kkO_>EP6Sr{ z!T1dD`xe^i7U?ZtB_(YFDbdgx1KD#=M5gbXuWBEqE#NFz?ZY0IDlO67)xUlFMAG%L zxiCGQF|!?V@@5C9ao?vAnh38#KpZH$U|7_H>6AKG8_eTApM4)b*tS2WEmNfysa;kp)$kQED3ZEu7dPP`)Ejix**I z6D*&9*TK^u*EDChPE9#Xn4l0fZ+uiR7__&tgY{$swkxl5708AFGP}zNCTXs08eAwU z3Q9~w^v24@&$6-#My&Nj@uI;&siGpf1)c@WNX$x)luv_|I(kM3Ozc^qj%=*VtgLKf zERgA`NqLPw0{T^SEVK=U+XYv-izyb)YReZNTZsP5PH-x&y6^=?jE1*`0BD@v1=QK+ zdauMpd_t5)m=Qnzv2YT8p=t~$6s@jOeps50I5~idX->}1pBu0B{|Ss-coUpsg=FF5m{#0!UO^;vEZX+R%*(;?6H&~HvZf!2OD9J9hxF0QrR@B2! zr|}r;MH^AKIGyLLS;KCm$uyog{EUBa?A$QF=nGFtN!g8RFk5aWdU!*V%AavYQd> zAUwqTwY%!-r;WF(LR*WhMiE=3je1`5jLjQ}7H}6qXAt#-OMgL}Uy@P6D&u7HHM*`i zCBBM~0GGr}8-9QqlNJj|W1%s=QQj&3{%Sy3X}>wG^mw!zZT~dK#f5&^h2Juq!eZ3_ z1A|H4UItYItFl4bY=r-U-<=$IQE_ns*QDT2FH2a%kJIw-qwzlQCdOdAgC;1<-hnr}_6h*6y}d#}AD%mSvqB(L z{KQOk1a4=#-F=IqQtl6>Qb$(~epjS8?rk0K6U<6oxR=och+A@b++^Lxgx%(ZoyJ&B zcFeTy8=9}K9}kb==M7P%ji9sL`6r%q@-}&^VHfUrXIQG649d>UJhmG=!yMdBRc_BG zSwp0y5j@#|CmJ1HRaW-X1bzvSLZ_R(cFcZXU*Bf;W^3J^BYte9@iC{Ty_75!Sc2N) zDhK-nPKVUIXjUxRz`#znAm5m)7sB?aY#%<@qXKh-SjPOrD@PVOJ+T3}DB)vPHvZj1 zj|-i$%R>Q|5xJg*3~uT09-1d=PfBbR@NzKaw3J9|n4d&XfX70*a4|Zjg~XaM0K}Kf zQZmZeoO#Z_d2Xo3+I4W;dk`hs`}~EV&`K|6_BPP9&5n#SE%Hn2I@`7T!aiQT6A!~3 zC&aA9w?G@E5w9rjwf(*QrC!*m{Z_eK;ClCyqGq6kD0no+mNXn%mA)hg zSr_;@osng?y$1m^7syGboa%!sG!y8~P_gH9yZtiIp|Id80XmvJzI+$g)gd+k%<)|CixM00sRyC6=#U+l(H#>IT^a&x3&&z zt?t7*`tox}wEie8&pd1x?N@Fejx;0^^Vdz!*q%!0SsV9n6{|HWmO$89m4BCPt*ph$ zTW0R=28*TNG(}&bEo-F<`T`!c%dk3tY?2B@qaj2POG;uh8=IJb!9hht^x{{`L%>y?Hl2R*>21X$xutp3eR-vY{BC!) zLme%UDuR$Gk~9u0FDq;I?`OIIuz@b~gcwCa{)}#DXXozT=Ce`M!?2{Zt$ln>t-sJx5Mh4o4qH*e;(>*%TB%e*D(!>GjN%NqpLG z{G?zo{PGd!SL7B3c5H0S9i%$Kh^^wk6L40yZ%);gPWA%G#Zvn}F_a8j) zsj>UBYU*94gG!=tlKEpCxoi{$DSJ?!?)D#spcH4EN-y3H38E zYe>ew!QLW`{xhtw2s%r^U|hJcC5wQ zvRce~3q0AQQQ4n*UY$vvoCSgVd~O+Ni4cx~&n_&lv!?9SRX(Sx8vL5>%U3ycY;0g# zgV-v7!s(+zLP7v|0x3t~+c!H~TVymO{y+TsVng z-B~}x!YDWI=q^StGk6P-BO469mXyt(!qMsZMyOK0 z%ONwGjO8my2jqbo@@*CWjd`Dq*nTuS98M$^T2>H!y^zppVx(GX^4!lv z)1QTxi%|!lhA4;S*U*7A|9W!`V`Fs{L=nDy{kpNeoyKN{zn}+%Dia_S(bAruowZ9~ z=;+|Rf3Gq-y718G#SB$I$s(Hy3Oe%6oN`FcO(G;pNnyADYoAITv4CUZNqWG?_n6NhjHx&7gmJWveZ) zg72}&Hd>#&DiE^V%dh=OGlOKuC>gWqY<1COS??MY%}x}_-@<*q z+UV)!hfx)dO7Q;lRsKiwrc@6~x4Zv=_xPcZb&-%YosjjQu+31flYX01>{A{3`3h9< z3e+6)PQ0GBr=DerwBc683XIq^y`LnZ0qrxFsv#>$96D7R38T1qKF_qCIBr3+~c4@GW$;0Ttk-5n;3S*jCmIOy=@Wg`#)~k(upXr3 zn5U#zY~!CA)(!TJ9aq0K`a)r@Xl}0A*#Dp5CfhMz3%-J9QOkBhUoGPGtE$47g78ZF zpAGUSi06|p2j2G4viaN>zq|K?D|&Tud1h&MWz8HC1{n%u<0mpmsTy)Tln7mL+p1FG zU?#M_Rx?9om0Hr#j9hc2G}xYJw>Y_Yy9{ghQ5q91sU|9MnXD&*PRu&h?Q^r4rKg=` zv)$)ZyU!(dh99s^z0QiDkfglB6MV4aeK%D6HfQ{EI2;dHC#_R*i?|ej6uoMR4~UNs zsmSb4o;{B>q?;NaWrj?DWM*b%W7DiM#CTPen5YU&`9%W|D?I}8#o^p!Q2)TYcU`x) zx8>#jilv$;>~=`FA7Z0p*Ksj7Fjv+vHZh|&30Ty|jJ(a2W9d1U$tb4zSf_)MO)wJ8 zWQNNrww3+2l>L9q!)(poZqLGQ&iQW5`01&@Qzbc?vEoLoY_4r~{5Na^3euBj-7j`Z+@ml|1@dj&SLmImnNfXl~sV8wixP4;;A_OeO;IRN)t1=hK_Za zl69Geb%c_21QipiFZ&(qv|qA`_;4lZw(>89!zTN96YdcLevgp6M$$Bn()g;4KL}CV zLz9p()`@X8CI|}~D>$|HJ+HL9|$Yj2q8<{Yx_tssJ)z#=|kECDL)np(e z3|Au!d(Zf6sQ9*)Y$d?=a3J=b+MMa2{j;M8^>}{rFq?(c7JncQXf0C{rh)70EXE?(^@sZQaqq|F64 zjC#^>F!>c6;(s5q_AQyjHjUgVpWWduj+`QsFAJwv&)#r`G<_5vBkFaU(s5EOv@uiM z{`q@uv=dv3Yxx6RkG@^aGIC#~55Wt|{Rs8@pWZS;x;KAr98YNeu6t5L_)$u=n*O-o-rPRqb@I}( z!{PflCBfV{e-bGI!sxSS{Km}8*IrNPzWJJCtrqvJ7A=7jM5MBf5RIIOND(#aQk4v= zv$Ahz_Uk*7^(#{i9aYz*qoFE=xVW3jn$B<|jAy(ss!^e7Lyj@}p9^%AOY9s=HjN>A zstlzX$|Y{fp5%Cu76h>tc(J&8XO+({}H$@D-dvKfm#t76jYG+2btOJx$W`q!by`u zZBETro3Q2XU46Y@e?N_3tWxrTQHqmtjj(d_?w-1(p&H{ox@sKDs2HkVaD;1RgzGuP z)zZ+!IyL2)3_gSDVIlcngJc9cMgqh#T^{!~Lkn@Eu3(QSOvG;9fFvvsZV%_v1YTVL zJy|X5N>tSR?D|rLL|Zl0ST@ax+$hQFPwrjz>MsJ34>{aFmA8*;IWYCqBJ8liXG8>} zDjgge-eEX77Qwm=Uc*LqJJklONCvBzaa)zqtrNkcVBKt`9Ok>Nxt>3_-ZK=RqpNNF z;|J85>E{k@N2AZZRc!`*rA$*02%w@sMliRsV)}dzVgtTDKCkIjZ9yC|C@2VM_aF!* zDke5PF%cab+fD$YkpekDLVJaSO2}ckH8^V~&pqo@_gZ;aC2C!Cm_2vawM5tvwUh5{ zkG^!+0E>0vjk6{uUOxNo*5-}`8V$}aer0%GG*VeLAI_JhU-5ptaS2v4#@@Xcq z9nRJAgHrBH;nrn0pQ|x9`;i`gA6DkU^RtY#57lRW+*xyqxU&7t02s0(RP!1VxqTNg zbUjEav>#$NRsugYdkYjY=&b9qTxk+U9(}&QC6!JW%sT9_j`hvq_^_O5u){LVCbY=V zZR!@3B%MBdQzudRx?m5_Q()XV)hJ~I4i1Rw08W7d0bUBwCV)Hd4V5JzDJeMu_6>pF zr`>&edP)ibK@o2Ehnt}!cHpc~)6gJV!0W<+6rn;AkJDLKFfLe+uw3g51h~6Ii^S>3 zG#^CZC$Ix2cS|;SY^*(ZKreupIykVqf5L!)y|aLck&u=audZQ5 z(=;mgE@~MbA%)EAKHe42*Bs6_I*I+*$cb2iFlseKA5t2G&qY(r#!$==D;I9-aWiz9 zjUF)`#@jht5uilY;N^mbHe(i9*TYKHeJRw(#8cku5$5N|)$pP)ewcMf(n+$O z3G;&Y_msg0Rw^T!AR2@d32TJj(_X39NllJpH~G5JJ>iq8nSvKA-t2&O*q?6=frT9q zA^;x4*~JA6{qVp*B?#BwA(KHW4MyO|;5>(Wd*k`sxF%p+;3UIBL%+$%1q26^6JMd4 z(Y${TQiUZT>i}9F0NNm)I6JvlkXuo1%8>LFhG8`Sj;Qk13B^-=rk9u$O=ATadA^u`f#1I3}Lw zmpmT=bV1|dW#wL*J^n{OJy!Ul-pJ)zT^e565;ru3?tSU*?5>Hrfqr&(Nibcca$MW* zrkk!aW?v~ScsFW-3{aoy-mpWhiuH%39J<+~4YIgR_Bzw^z2{m^-S~LM~iiy z1~|7P@=8hu>*NW=U$vqdU8RGP?q5rO+@G~(p>XQ4J`Y*NPJ2sHN<+)7B=N(Gw1u_w zC*$(P`zYy)iy^+SXd&;#g1ARR@^TDwYwd9$AIYcxlT`71Iv$;yv(|q0TuFzdr^}JZ-lM#PBY3!U{$)%4nezUj^DDRY^$a=xc6?Deom4-7k$cw zRSgbJ5?Ek0da7jY6jKcPAMJdE>=IU?DRykw1nXH?!ba`VkD-uFn|cVBVo z7@3$qGP5$VG1rup&46eWn2JM#gCNZM@c0OfNW~I$yf<$?BZpHur-MBeI&yLrz5Zxm zw#+fW0!POAl4i!n%#8jOYu-8d<$%CLkSnkOjznZ6=65etM-aAG(a^YDX?w)V9S)N0 zw?wi=2;EvI8tS6&Au^&lv|AW@fYa?>% zj**TqsK+$K3&=??%nVrZ>H1@>t(|W7hWbGv@Zji(lIFRgL8S3?cRcr5Vly?BIB#Kg z_V$wUZt1B_Ai#onnEe*`!tzd?&?+r__TS^&k6U*SAA&)aq3bvWC9~RsnD3u4{%)nA zYkSxi#y_&JP*}L5i8p2H=8fpxzB4DDOG6@&vPl_Ld#7H4cbZmuetC6Wpn;`8(MZsc zAaQK&T2Y`shURA*uDCsy)vpgxJvZUx;1LC1r$M9}N&FQ;|Jix3Wl-U(UgMyUYHTG< z%8yH*TpJsDInX?MeF8_U}oU@tVDsc`c5!Iy%>$HRQWt z_6diuGdiWKr!L@qLjd)>ByCb??06(*3S}?-KpSlzeF=5@u=JX4hf}&ofIvr66lgz8 z_0WhXXV(;G6Zs0DvD|O6$o<_Q?92gH^55Xl6_arZFjsPND5F=o(+dhDJjh*r0hDmJ z7!mxjYBM`K8`ysmc+sC;2GX`5qIZ!4QqMrh##_7q>Z%9>H|d8Dn##&I@L|I@f-er} z7Y*^kiNXdZCu1~iI#s;v-_*9tg9Vevasdzr!MzI2<2M*4^7$TEZtpO16LC zBL{BwGZX{xz(+>3h=?)pg;0@SS=-bg*=ynNH5*pvI)g8PZMLJViOm@v;E9`shlM9Z zL<&SZ9mzx90!f9O4*lJb(k_r~fC zM=At8C4_fMOz+q+^w4zl(8%=Ibzp_%5%gB^SPaH;@>u}o$-ETsCQL$xrbLm zq_E0n0FrMBqK8wr} z6!9b)KM-2Ybxgi|!EAc}=Vg{fb#1Nx9oPc|CXbKtN;-HgPR=zU3zRc&rgt*B6}qh< z;t%{py`oZ(8-eQI$w^PWD7O4v2B-eKkLE=LXQokYjI%BQk~22}rLg$J#0&I{&A4IF zhOrz7A!6{?FCfDKPd6A)LykWosBS1$Wg-3ogqL9B{q&y?ou3yQF}t{$o{GESMxE)w zU~8xlm;J-#wQlzl)1?wWVD25v4PqdlSSEtGv9R z;$db6)3A2#61i@)HZP6Mh=?%x_m$18KEca7!IO1U&md6Gozl*oy`MRKk7|${ak)9caz}H{L z%)q!nF{7kue*1RWvmV)Im@$N*>(Mf+grbj7?5V;`!xs&Py-cZsrsmV-OLwfyj~w#L z*oK+NN2v8Y-wgtYh^<&&up!g7%$i9ZYy@Ngm$uU^BrT1^RF7~}P%DsSnGEzESy_lbNEfLIic)$aQ&jvltrEpV7fl z&eqAy%6d)~n4X;AFDh(uJ6`JUr9W^r#cV;OQ4S6($N3)8SRLVoBOxt|{`h;S4V(pRbu3gLLzE*#(O0bNBR5aV=>QR;6t|(k zxh<~*G{1+eG<3EiuVG~%n_)UYEidS-owVH6b;^V(ix0AVwm3|BXv?$u>n3T7CBX+FD+x*E`XARsseFruK=IYkJ9fsRX~_t*UT)%YQ6hC4b9$Z+^D193{v(q0?ZPv+<4LHu8%6J-N-O#h6S85}MDHn7%v8|Ya?V7JOO z?2U!Mw8)y0HyDJ%9lFHW*w}CQiE4x@e=s`@Cv*DvxmS8mfvDCs48DERjs@7Sfkzn{ z7=TuyY`l_v#rlWCH9?0x{o|isKc`+vKII5twKnwte@t*WkQ@H{4g3PKfRjiqmsLsg ztwQ@Umf@cd7ajgA=a)EmOyd6$A+SyuZZ;+3zC=cmEIfZFJO?{QARL@BkCw&O6XhN5 zZZ@*9LcXyw!`l#9`t_@wo!x4J2v{HA_ZAq~MWp2l4AuCMxk5+RqW)Q@t}L@M;=x)| znMUPvpbUC4hgD{CtY^MwetrgmVO8L-z;Y&fpSK=(^;}7ByetV4jZOBY;~9;T&z{R2 zC{LJD?w|Ri5i6)(eK%Ruy!KdJwmY8GG`qA{sLBjg{1!9zC3^}}gnn{NaS~I6IRQMS z%_oPt{9BRHd)0#ckI@p}#P!qqOt+<;mRZnx`hHLb9;}|byJ*%-W+N#V8GJJ?k)0JAPd+T8W(Am3(NCXHKcNh&Fs%VFz+vqIl$b%OIW zW!yj}4Qv9(Wr>Af986~YitifDbbA)4_z`qf3deIIQF&DgQ*(IC5d0IqUD)e6jo&$) zmKx$)%f*o$_*J=`X|~Lj;4U@l*DrbXbn!D_acqF^g>b`qtkt*r#X266-RA zPd7qvdXbYWI!6C4oXYO1iu}H0jV%lR#S708=$WFab$()5&4i1`)s7#7UF^V+BN%7N z{nS}MXCv}3(Km{OOL5S*kXF8#6g{c6cL}#3E4K@EIG$tWzclp3{Cg8xSdE8+Rk=uy ziS;If9s2n!XIa?WoBQGwf>T~s$0G5ri;1~8)7|3O`bo2!N}~t{C2SKz7%TR4%ZKq;*ldkDZ`mUY5X=v54-0VEMg(& zoNGy$wrQMhSGnu_LrL7Fzm&3GqutxRLNmV(@-XyBt0}#ycHt~Da}=0&2M?`X>552~ zdFu5n`6CeZI_m0INjVMSZ}W>tb-Di1>iNT>185eWIuU0VmjU>(a(a#K4zR0IR&RR7 zqt6vLp+&nqsP`g`BKQNn!ID($NWI-={m8=~SEwQ9<;`^@6+{U`LqjXi9QNJ0Y;%3p zh_6W+8jg;Cs$$K-Vu2+H!7b{$REqYOx@`?6d>P~9Rt39zn_@^-Ut$xdUc7i^TkIW@ z@IcB$X0;ub0t*XkUTeicNEMcrcrD-9h~=y*@^EwgTILNmHxnPHTgR~YI<7kp71@5P z4))rM7&?gC-CdRWScXz%m_^kAv!ko8L9NvqDyy3LnQ5)f#Uw1DRmF8Yp&X7Ha*F-R%9BH^5SSr51 z^=aOi-s*Zg%2)J>6sDdTrv5~cXy=1QJtG-Vg2*)}aVg4!gMz+KCT7#1TL%&{eTOML z6Xlaovp-r$2$hb;O{cbv?TUzt)rI5+;S4BHV*>$1H)dDeuV1`O$Ega*j0bGW12dS5 zvT#e#r5t~70#3CnIh9R+7sY`BVryS-iK$>;1-8yc1C>Mhr>50-+_Hf>S;eHmeZNIY z6l+JIKyHLn?HL+>5xp^lFFqe(GY(sUj6U@^2x!udx-DykYrWEhOtcr=3n&dLve_n( zw>Fm8%Ta@d=lvBI_q=(hG5!|&%hLIuQ6xB&HO)6?y}AGsSbF5)}|J&4}iXe&o7dxt(I!B_1=R@=fn zoL1Vx4oMu#-2CC^s!f(_q?6b(ip7J~YF-&F6{(XMmEBID|#RCnn)_T$6KnJl;q1`xbyS7^}nhk zGE1|7^K4f5e5Rg55Ka2=cl8%M-7mb6oNQsCbaJV61Kl&_dfsgU<~`1ueJ$e0pWFI! zHMk;G1P$XZw7z^f)1M1Y@huvS;$`WjYp~lFRU6yg`Tb?7w_La9^U$o|&IDbpr|M_$ z;Dxx@P1p}I$sA-YUvQOU^zy|4Q%qvF$Z=4<65kHj`Jb2_!kDck zgf^mY0@q)o;$3JuE-NiLnoZm=1)FaQQw=7hl>I-Vt}?8upj#t?G^j{Oh@zB~(w)*N zozmTK=#o~DkcLBdgLES;;-R~djzf3eIey>0mtXq8o;`bJ&6;=ByPW%N>)c-=#YVPz zcX(@a*xbt=1UwX(X`8t5oAjS)c`;<5uh{#*4-faiX1;&+-cHVI)(x%t7|VQvVrW4@ z$9!jJv8T5@yv~=`W0A9>MNi*z5lIup<-lsBP+{oZg#96kHTRJOXG7`F_Y-Bp9!)E&@NBCinY;r}jxfE}=|D}|Anf_Zl z#jnV>(RPwCXA10|8NOjIDc*yfWH+LEA!`PH&zQ>*2fUcpFbPtJ&A} z^G>jtQ)_v_*)we0QC6;MGez^kpF@;wMDnb!Zx0~b-M&Z z!C7^_#YA3OElcxP?t(lb=FImKEneDvD-AzChj{I91`17n(x9+(ap9Og?)r-FAc}(mVI>-%yZL?(4^=pmz%b( z(Q=3p&V6V8YiSAhfz3V9T&tcURQ+bQ_36;r+UMHal!r&3&a%_todL6L&*nJz3T)bb z)-E5Rn_nvlK@)Cfn>Q)0vM#D%VGkHYx?Pb)uCMAaj*Xsx8q)Mwz2TYX1GYx#6D{2t zs1BFz>1r+Bx#rW*Pn9@cbXuoCh4e#xYWKEg8}lQdW%A!>ogdh!vS|t8Z{B}a=nPK$ zT5;C#=>Es-HedT*{S>O9&9sk8+4@hP#6R^nTlwa*|Ji}C!ov?6K8&R+@ny=X-| zE~-5y@@x3g4lTqEA>Yk!RWkHE_peDaa3OH9?BQ?De_i}-{|P5Oy8ppWcNoU+i*P*~ z;H_!P_9n;eEz}$Ez1xyjh$*VLc&SvVlJh*Add^0X8~Ij95!xFtdrD<@_C&X#+}8?( zjy@#n6~EI9o$&S&)ofmxy+Wlh8}irt?zT`qe%yLwK0R9}reNnD$TwN7F$5LJVmhxc z?5|tVOkW@L;Pe&$7O&u0_m+e){mAw*Clc_0GJi&CGN!v2LwzNuW6V;<4 z`pV~M{R7=tZDP#Y`z}fZmvezmg3=dT7lZY)8BbBJN)2E$Xf=C;Q|qYr69xjMoj2Mo zOL-d?YWF{w!_)=>G0o&rWr`0Rm@YnY@kV;j_mnaj?^7OHA3oM?=w=o86KB^uYRKkU zL?`wuMoybBJc=f{c2jkAMy7;^JfeA+XUehiZtk+Y|3hJWh@X0A{7rYd4K4 z)Zb5g{aqQPy+JxoEJDSwVj}L{{5g8~(FlyED(aGJa4b*l^=TXSj~7Zku4{JJ-it{3 zrw$)AXb*RCb|oo4p=9D((OiT+(&3xqb_mN)CdBdR4G}x0Y0=G^zE6H6I2@SOy&@+P zDt_FX+}M-dx?n@X>Hps~()we1%-PiXRjcwOgu}GisJp<2I-NYpnJ7jNBJdwE3E1ISN8PEvjwrg??dyH zPz2Y>Zwg$iB)ZevBRN_Kc5_`7>+<~OlfN7;_O#!hW}#=fefaiMA{j+sPUS_ru6MK6 zV&qp9OBz6^)ESK9l%(-N9+VwH2}}UdR=qCDJbk0l$jKH!p(pd7<@2@cm~3|9OQ{CI z7c#Bh)Itum=l}u@bi7Fn3P6i+KV5qeLoEwE|IXqV%C&#Kn}h*vo$+&56%qq#pyDUT z16UJEwa-Y~xUxWI*5m6(g7DXorge^QwfMGH=<+EqzUH;hx9C!C9_BGUxzNB*KzFPD zArpne=_Gyt59)!vun>82W54o}P#22A`+8Fi<*t|aV6oNkrZuIlp)A}EWrZeDos^;JVRfkLMfJLfaH)t=93~`0;KeFcVG-)X5Q;E8SEq^&r z;Jr?ZGm`M;$XFcmD{sBix;N+yfkl6Hp38T__Ze&nh2p(^IVAc}8!h-ITXVKIxz3%T z0G=((NP%a57wB6>bCa^Xc!SYKIDaeBcpWk{*n6w>WqAkNA@ed@pnbkMRT!(a>`*V^ z0K=n;s`()W(^FwxD963}C}G($EXzG1k8>rx6?VU+{^pK3WBMNTclMfKGP}iay^kn5 zWFCKWb=6o4nwAzpis}dOBhKFEl$8E3qOvr?%)}=RUcYma9$w>-92^}u>@zZOluLIs zj=?qqAFUB>)&)PRJ~+2oBR}|T_w(V&Xm49UWIFMJ4<}KV>&6!R z;c2%1`H!l+b+u%eW$KF&hK_EBIUD?LeTl|NeRuJEet_IF7{_N3-W51X`F9=m@l*2w z{T?xGz7QVy_Rjw7P_b|T_4)jy%C|@1q-@q>LsWZhZEkGlo8PptP6lpq=%0mmnU56+ zXN#XV^xPV{^{upClMrE*Qw|Rm8w3QOj~9pd7VgOoug*yKpWtpWcs2l%(V-zl4p;qv zM>tpK`^@PA_JEcFFcBGAfhfCpI0@C{Cg3Rm#6&@*xdEU$%I)dq8GP1>C6NVi+(@Ij za9RWtl1!aS#=id)84tIWY8E_#X#VTX~>e4>+z8}9{TevTG1f4{)eYcVFmtpRc zmYT__F)%Q&X0*_>w||F0aY>QHhCvx4Q-=(g5DaEMPl$_&eSG+fe2d0L0TT$QeA8%q zAKexeK4d}?xPSn6-%tdwwCH_gsUxb-D)485ai>bPIWL2hvHB9F!nPPrnBQ(u+lXq9 ztPQz7Y-ID0GBaz6G9G2Bjwg>I_jCC!FF`3YB73cLoS5_bR@>k9iEh{l9@qS*86`_% z;TM0fp{f43yufthq4s{5c`e0EwU%opOd2H`Lpb^fkQ(GYlEIa;$=3cbDM>mMU&5R& zFQ=!znHhDZY-PbXuiChLp$ou`ZpaS}22HdGxwQJ6Kq=L!$DMd)-KhdWeJu}=RB4A8 zO8t#LYRL#lH}=Kzy6(ve(Cj->!*bzLB^K_$Y-f_lBkxb^5I&MVqS+^-+Q`OPA53Rv zkFGt0=;q{)@%61!Ipwyj5;5t9LA)AKw#XaVj$|B9M9c;qfc>A#jEAiy#?v2fQL5uF zr7GpWcH90mr!-nynYYgztdZAr>KlT*n$_P*ueao-uR-#MOw!*I9rL6)EuZn!6iH-8 ze%u}qY~K2yRPLU6Y=>TrLr&O+1$5jFhuPpA&v|xzG^$q0oM$o%wFd!DCio(np*QZ; zveZS2v^qx~QZ^QGGA-QkYh+KJv|}fpXtiqhBuZDs2)ZILHb>&M4^Yz~NDaNyRzzq_??pQ4`_|~#i-{ox(0oO*oE^U%WCbm1x{y2 zYm3yO!z#0$Tl-y!x%Wsy1Q=|yLef9rQ$Jq!z26})g*F7esT@k0V94c^9MKf_Go^xu z+D$J=9f~&w$rF*2gTrJ;*Pg8V<)&lJ`$tLJ1mhoxtickBcPIj5)iF326S??pmd3ov2qM@`N}W)*u)ke6@-r;$(j z*Baj(uJ+!K`n7THo17XTpY+*6F_rzjuccoww`dj#RgHae_p#4pHEBTc zGc`g1B$%sBLtg-y|g`XF{vRyLo2Z9YY04$qaf!_4XGZ zR8*eb#$t{D-<0ukcQ0KurVRHRCS*Cq7#`QX-4S9BV2}G==T%{lGrItu=)2ja$#x-HaaPf(wtn9Q$K#Wlrf;H(e!v&+)mR* z#-i>b(t7%vImUgv zo-z)8ri;F-4OF|eRn?&71WMyT_PBYS^}shb!5Q6k@tZ$e4pwS5MX_{U50K7Ta&+F< zyz$Q#52qBRS~ki}NXi1~IN{dc#-h3aiJigj)DKV~6aC}+&*8Urc6M6DinLR-JQk&~ zAB3f)tvWk8G`8)Zqb8SpmuDnT8TZImt_VnYI|LwHiH-41^>cc37*qJ^`=->@$XsK{ z{zB@9Bo6)V_Zl&qYHqxl%%l(@O9CgWnKYb>?DJf2jQIWK5ntwze< z6Xlh4UlQM&-t^%^Y@~u`0FDcL{2mGG+y2EY)tqzm>?FE6T5b3d@HZcvwlD-iF#PM;qLF zJte97xg~(GfB`NB%UJvC^d(Adq+#mQ>dsLKw$|Qoc1U$-M0`?`6xw%>&8@_dR!B=O zN90-D)g4x}&r%>hE{VH}dmYuYQgwYlkSV>@$N$UUFa}A{5pJwBAX9gaBAP#b>v8y$B@LJnhy%NX z%SOWa@83Yp&~O9d9RZYoe-8eu=J|pLLi_*!r}p%@hS%wV;yy3*|NIR~BgFH?d&4eL zyXFS~BF@dHa66d-eGCxBE)}%0EOa0a3f-|FNR5?;#eF0cSzwvN2!&hqr z&);7-T-X2ENa1wltVLZh+EZm7XHdIVzz-<()>^}%f<%$DJfZRtGZkdu zdxL1N;!_}lfy)Y1iU1Ws1R3{JWE`aWe3ax*ziAT6KCFi79BC<;Sq6JWA6Oc7eR(qW z%@N{b#YST3bXeHY|7r+wITrjBrExp$BgPO-pw>TJtc!^t%9E9S6Vnrdgk*pI9SZGl zbn72+mey{(fv3rSUtlA~PP2}lXq+;hMxDXm&9UvCv8~f{6u~lS@KQ3KsjsI^$bD{G zUKUvOtW73bXtd^;ph_V!e9I!9zs=uf|LoHbYJ&Z{5MY}6G2w&yT2Q@CDewU4bJI6a z@#(rf_SIi&djnv50!(ZhU$L!0T3rio{U%n902DCCz8}T~Zg=TjJ?(bL-zz5OR*47_x znD%y=BT~!<4^Ug=^a?8;Zz9is;^JkQ?*rzg|3~`u>+ql%kY&@(KzxF=>FFQkhZ#S&noRBx9PL?JuUIgt2{J zO~keapl@|Fr|2X)C)~!411hy{PNXC{(jFTd8x<7=fHsRY4-vk!!WJ6Pr+s9Fe0>z` z(90|~oyfV^Pau~yO5S02>b(mYQD^)w7%Z21co>ifm>W%qSiZA*nkr-YhP?D*50YDL zr=>+QFAn4c1Kw!fzEu>4v<2=9XkXA@)1Jmc=!}0nS+?ug~4X9ELE$!mFNis&msWf^sgCxw5v7* zXN0(fN{EY($aqu&^9l(W{vD7j1DZLkND3tT1YwU4ByZF;o{oZHKK=G&lN$K-a;*^A zSfv_g=ZnefgVpJme^C28u=d{sW!DRZgoJ=Qi$}&#;*k`lOc9Ns3ZOA*+2Uvk)NR#? zkfM;H+}aU7G_7Y>Z`2);u_TqE+4&id1v$JHaurfCmdfZWU9$oHYk9FkIWYI4 zz6r8L=}QA@xKRA!?PMv}45LP%z|hGx8BvV>*wFGlP>PwJa_C6*VS^qEYAmU7X4M>8 z3&LFbYqqu8wI(;BS;!~Z7oOw2g$#_8LRBV=E=NC8DF!COo&9}gqRptN$Cp|YZT(CQ zyU23dBVR>CML}V{#&(5>>CdBCktRtR!}Gb^#Z+&6{YBrGLjbtSyaEFO!j!=mNcKc` zP^KNUxa$HMFuOlIbn`6sOFuhCLSZ%p@a@V4aSet0bF!E;e7b#@~BsU@KDLN42vP$kApg-Sl-X{^-E2|GA!F- zV>fqq0wVMHt_~%E-%3HR>FKS2NidSp18lUv$mD=rrBWTJ!y=IktW>&5pc8WjWcT`Z z=kJKrDut@9yqS<;cRcOXHh%w9%2z;3BL~u^@W7X=10ED2qTcxiC$s0MTG_)xGax_i za&I*ikbjj-#v~OqbC8w77g~6E-Bi&}0I5PQ!zT<&Y>ZrOzr23ezSNfhQ8Bb=ioD)B z+NyBm1O)ea;hK+Xn^O^1?Dvl|lO~T1a?#mrq&W4`;4r0;`H5F_ni&>EYT2T#VK;K< zY`~`-{qsN=hzYhbWuFAxg}1n0jnIz?5}*0{JOC7`Np<32*{%6joe;S50*;LK zM*@{$x#`vif5|Z*phrd_GR!e{EumA~rZIK1$=J_yYi#V@)`MZr$Ck!G3CgUSO0;HA zKL;DNNUwkK5@~5K*!asO6`d{w!p0a97#ORY0br@dd>zolZ=YdKtjVH%FA2Me#$n5; zfnd6SZvrY#?O@7g(GpDeD|u>Avb3XYt9*E7P0lHmUTbp@F#4l!ni%F+f#nO?0mj@S z*n^o=f>C=5nkE!ANod5Nts}r-ws{E&MDxZovPJJV)G{>Zg=P|&0&|k~-g&2HxX!7) z1k0JrtghP#$()tsjM0)*r@`Sd#^3|QhTTs3NJ!_6LPm(`mxb(x%7(FpVSn{H2P!@1 z!^q;Eh34BVJ|O8JUA=KvenPCV$Au=~&8Qq#F~aXc+wQYWcM&EGs9Y|tn$l+Oj3T30dHYT2gu$8>>fe+04rt8MGb+B z%Dy)BsBD?;J4B?UDHPOcf-7a^JMe-Rpfl)ly?qMB61mX$0UyuMvQ1R#R}7=rMqI z>#Sg=$5b@7lk011!$lyv99Qw0d~vjp%5TD)tva_|pH?+vI^K2=K)%PD+th%pu@eng z6u6+BLry+uO=0c9mjx6EU~Z2mwg2!T5Y%&MlY)DboSdln3#r)$9JE- zIW!wc$vkeXCPX0Qah%)53iDw~J|m=`E!0EN{ZHTIoeUIw%r@tyrw^O1s-Cc|a|P9Y z;KMXoO3B|F2Hxlm`#nUfWHL~KgPbIHJXCJB)PWeG7#j^5{kEK-!OYJA^AKi*+ro?>D;jJ?AU$@f-n$uKE1g1Ht|peBAa= zFq|cL?VPA|@q3Cvd&{4 zJDg&zaE)%uqb8hVxyU$k2)P7GfFW?ygb;}N)E%D8X9#Bb{a1$_WOqsv|U)3h4 z5|9lS2kB7lEOF0)XzE*#1`R}5UPe?q0Qt@>GbHlc8_5m3c?OP!QdyNw#?~+6GbZP~ z0-S#bu<;QWP_F){SO<^?x4qWd_X^ZQ&rmU7vSuUXwf@`OO`Xd_KCGb%2NPb$FYFrq zdLI@PEFj- zKT(gwU<+bzAB;++)CeDsO3=x;>})=x$k`V+iAoew!k3y_T6ks-l2zif`2dKCFPHWC z!=Zl*Gw#e8TdgcH1f^_`wEG?T08yER-b^$>oKXNS;A*!}1xtfqZ~x~-Q01*dmQ#}F z1tf4on&w12sH8cYltZhB#>*u!&B7&9b7{mhTwpi6ycsny~ z09JRDS(gaDpw~DJiYRh6hkx((QhLl=c=i*`>w#ma5IY7$T3Q--1*MGpKKBWSZAeDd z*1EE|9q7BaaIkpB$ETd4Q*Qhu4m z-4w1jURjYSRHcJEn#3Gb)EDA{?!Ufd?UUOE;Sv6*;HuNE{rxuv0I3N5ZUU%^C9ha1 zk&=yum7a zQ@2;nIG6v6@6Cr%ov8VJWZL64$EhqvTJ*8od_>*F1vS$K3w?58`3nLRjkoN_pYYh zg=t{artZ;Kw#9F2a_$$Bh^HTKCYu3I#Ojb+Rt^4mcgfA@EaTMIBmR-apzUGo zm)!*`&LFHF$B3q^ax{*xfr=)GCt($r(p@;iKOYUU?lCCCHCp}kodb%aQ0l*c&J#^X*QC}?- zGtjVfxoMW)e|xTqm>STVRe-(|Fb4AtXklGu@iu4BbMNBitT zx=sqNASL2hRXJNV^}cycb>U)zT=#qDD-9g??GpF+oOmXxbQx}S7ZN>o{CdQ|;Nqcn zOQQgq1xWQFmlbP|;Gl*w&u_8O%%v0h*@D(2^Ix~^+^_Xb%&R*MChiPmJ*P6Q?In;) zr#a)872|H%OmA^cm%D>i@#eR_e()PeR&MvQLJTaFLEi-^n}O_wnQ2}R?>*n=keMQx z)QDNocG{+gO6j(9%efUxwb|%nIKShQhU5J(ftt;>&tgIZ^GPOdMC+ZLTiwgZ?GAf( zF8B}wKHemG*on4-*+?%qrCxWK6X&0mX6tMQ`x#=xX<~j0CzN&t9p7G~+11UK z5a$DM1U`4Z%AhkCtm2CB1Ob~MZQ$yX58`uo4P4jGi}AyjnRiWX2<8pY>_*8o6MYXK+jT-15tBt}B<358e9pT5 zJC5Eh${F=`Jf?Qsrk^r7f=fQ(ERpJ7N0V&k75dCW3Y8D`HN9D=c-%v3x6Zedw}BTu zaR!4auPz_-hwBv;cuuv?IxjLW#rW5l)e2=GuqS#oDWHDDWry>RN7H{|^&VWZnb{|riRr@i0p=X|0j?Zy=>h-B=X{O2ptefHmY zX5GW^h5s{uh=a;of?&J}vFhHH%bW}r%<7CK2+bSYPWmmfgjQVQFpw)Y48&-M}YqfOe?< zZP6o?HbOrCkiPS(7%+Ta@U4#=MJy@g+{P_=(z7Jl`r^2xA0_0dqJ);Rew&I4qxw}% z82f%Tm+A2GV-ub}qngK_*!h~2!8hiRvZuJV>T~(`CZ&o}tZux$FL}PH`vQ939ga>E z;QB;Jt#124dt=yq)@1qK8`|wS=lGa<@nBX`ewbs{?H$%Dx*=t}A3he}mjiOCMXl=a zR>FNP2dyiqng%gm5#7_eE%`oPjEWc~gO;vtA8W+}yT1p+h-Zc1!UX;(<=`$ju z2I;Z6dRA5zh}az7Z087R%UzB6VmX}83x_x0C^WzW2}ffm?-dj|7*?j*l~9w_=gv3I z98mkCZTK)ca z;ZVZGS-mdotERtgsMDa%lyK(U=zeJmxV-u0;XJ*A3f;k<)S2oncM&|zVESFd5^T|s zXtJyrTZOEP5&EYw7yh2g)X|r-e9Xg3HepL!*iT^4?e^Q%Zp016Q`L}GMR@q1MV=3F zXE|?MQ+0Lc(6@7Q#^gM&EdLTe&rlF!%n2TPBFY22H|zb z)MIcLwdW~2iEz-|3WDp|^eqamr8gj?A75gK^*O5VG>QNhCudjgQ-?2b-^zq?LvMdo>;DP6X2$Osi59 z);{f(rB^sTSW>L9H=2ukL9d#@zK3aBA#1LX^eUO$ZZ_PPhs<9rJ^%8(T3usR{*Ook zJO?$gdAo~$w)SK5C)gAvJH$u6Re5|W-v!hK_5|d5^x?UpGh-5S>vr`TC7Bv$Vi?Ig z^#o;C^s{32G`}Z^zw}T&H5}&)Hygcp;?RhcJrGO(Up#**%k1ue{ z;l$&Wl(OdUqt+XDa{~lk{oD}_L4vV#7q7{DRdg!62a~F}U`%`433K6W@-@+;z4l(i zAZro367Ij|8gJ>SoYAJ&1$F-KN^W-i*L65pve$9kY^$7@!JuT@@l5xH1OvB<4A(8D zeCn^l5iaLPW?VlpOeWTNF_pFj>m1dU8*buKgkSxJn0TWNF*~mZcFi5OPSoe+g*A~i z6Qpw@Rufsb-g>$cxKoys#&vgHiVZsP{VV-uV@*uM31Tg*81gmybmiB+UGHZ^Hc-AI zYiZEGj2N|EQ|U|5bU;HrlKeg{)8**q9`?a#!1XSN87ZDX=W<)fst#uvXY#-Rp_E<@ z1$ngi05Wpw7!1T0Xv+o1`ZoR%rd6mLVr29de~R}Si@POSxqJoN^FwxAPOW$cDG zw*@|z)mLg8EvC>)TMHAHpG35`u!cnpCe(by$+Wk_gaBIzTu9Elrl|sj0b$I)QD;6v zT7R;@DoU5wzNUC!nenQ`jO^B$Y1M@(m#>%X{r1>QXpGNuAzdeMjn*wKDW7Nk=Vk#i zbt3o9>wrnf>9#Uzq;|E)=_sL=fQl|JZj3u=6kf7?x31J#kuaL$XqqHG8%p?yuARmF zFAF%UNKzk!Rno%ye_uI^D9+_y9&sOsv*HT>r1^J}ffG=_=C6GRVQM*wgFNqh6iu#0 zS6jui=lg7JW>{7t{Y*oRwC9CC*EN2aO&;LTkQI(^GX$*=o6YnV+FC&Rj$cNT%CAXAa9OueFP82Bt2{EC*L_0w^{pKII9-WVWSs&i;{4XOhbZI~5{IchP1V zs$PnwWQZ@&?t9+0OeV1dcqjrLm|YqDMkSg)J(~}_>E=XxVi`Zzt}i{}Fq$l%C*z6Q zgi4{0m<_TweoP-5xDQ%BMdqvKuHJgA4#w_XT|5pOnIxH2R2-u>YG>EhF>)T!W2cFB z3u~XIfj_bNROT)B#ILs7UR<-#D6GGqKgm$21|IKL#M)i=x#740WIof+bXOHko%h%5DV{Se#5s12PNpXYkvh z<5Xmew!@@qF7|M{_?9t7#^_o7@MYP7H~KT;&_79MD#|8}mgxO;DW>FRs*c-7@*N^) z);C8M+IJ0=C$|UzURrp%3Gyq_c$_gKi#*;H`;OYVYf75yq>=n_ki*$vmHtIlp^Y89 z8j<#tBNPjg=@cz!#E?Jz>o8>hsdGGyxZYxi#a}xYF(L|KbLNjFr&di`$MWs}V#Daw z^nf5chDM>ssYu?MFxy~5TSR2kk*k`!L9X5InqMx!td4+K>7J_mp)N4y{?^kEr@T4_ z)Z;F*1f_CoyG&~-2?;Fx^;7~GOG7S#hJiyUz>hgNX z1$x(?k7^>SfNT>%7!X%hMau|f>$*{pp7Cbms{oLJ4}J} z{|tu%`nPepAH8{@gkv~y_p##ciA2M;qav|7f6kq-0ehh>tWl{zfD5W{5@Tni@s_YE zCbWJlhFg1r-)vB63fCbxR*6jO7)IQ5=rN2Ibg7IO6&+%*46c4awH!&KvI2ywwiMI3 zYn(n^6wBfCqz|u%<@He&=i2?5@?P2Vvk$(L{!eAPL!Cv)^0ldEoR(WG2ct!Ilw}+@ zi)VY*bZ%9&{4RZA^Q5wHxhW{PwOSzr()Jn}=YTG!m;$8?4J^oQvRW>wQDUtLn)+$xbkL@lVwxNQ- zh2R9h?@|&3$Y|!r)D;)>8qTbxml%G{(YhCP1fAkGvdW zR{-pSzzd!xXCrz&-~1c)_g%Ncy6lwGmchax!JF|!QLD-O$VuIf4GQr01ue)nRny`T zWQ9tF2iBIULg|a$<(3~UZj&(w>cjCPen$2`3rvZ1B|i-yK%$!5ScJpapkYV zA>-tc^a6!%z%amXBL--p0HYhK+q;^_EmwHj(jgtcB?G7#M}7J*7CXP~zl4x-dv?HB zTxMto$QTKy^*KigUt2<2mGc!V*4D}J@RgQThOlt&-1l9))=3fXtjLU zEnsrps0If9c_-#VRxizeKi3=dpam4}2Yiu;fp^LJXxQjj3MIaoTSsSU8ga?RPKmvx zb9R_zrM92AmGov(r|k8SkNI_IQj8>r7v#h9cIdW5<}yJpHJ||--29)l7>59CokhJe zXKQ2mDOUBZpG)QhUj0DH(p{Q~u^?ei%~FQJY^Iw#q9eF}XQ)XxCbO7!_s8j}VCl0G zaj#v(7&G*UG0;%1ChY)x4C{|?o=k%E!?$u>$a^V*(bQ?HNx1|TxF55M{|U^i=ut6U zIEL+QoNTzk0V&k~PvZIq$#`DP{l*uk)KTa&&9wZFk6{E1ZKaS2ZHpJ;T0JRr1m)Pb zjAmMN)I6g$oJd#YHBdIfq9fx2YGk%_$e!{O<8tW?FdnX3rdU2;Y><3~R)O<9Vx4<1)# zuL*sBDcqklx zN9U#0!-0$T6M?@eR9?9?|bo_5r!i+xZ z?n&j5OY(S%J^F-pp-E<>!;DIVx>_DT@K@TNYb>~tQ#c~#P>XevDH;O8w2>hn)oB&= ze&pPYe}qVjcnS(c~x{P z>bO(aI49jh)!7iJDiIlS&nxgWQq8A~_g)oDS#4KUHqN{WC_0@i1C1T*^ph|8w^$Xu zvWrCOQmbfUjUx6us7<0gZmTXm^VZWPKkEKsA!Q?GNBFPCp8I{Ov(>e~ z@61q|j~nmS?k%Nmq5U~;jR#kUlvvnW#(cx~Hr}Qs+RG&IWNt}qO+wUeGpdQq54RBN z4YbCi;C3_yOiFIp&d=a=PM06r{+5|)wignGQJ03VStoi_gm!vJrX(uTnwYldCEIPx zU{7L^6Tkd7a|gdP(0&-~#{sb=DsITnV`?~iXS&&+N6wlohK#{pM%#ixhOC}4EyI&) z4lXL?#liBMIAj$2!)c5d53WYH{K=0U5qQd3F9VP$zIR-egu;S*6{|F`PPRw&Hf%h# zTZ*bQx6Hm;C_bhrSU9QNni)j4V{Rx&I@@@*Fy9quSZ>B(cJpX_r^rMpZa#&5_%`RQ zmo@+VA=iT8&kZs#bUi5w*k3C`;ic1rR#h9%*~g0=%Vk6jLR;kv94ej$=`d@E+r?;` zew`)9*;?FrQ_>volbC#!$(*+m+$|vM9?)*KVVkEOhVV6fN4A^4qZ|pSmZfv|P@LYdi&>UR8rCM{^E`j`NDy z?caYdl2_(&sMx4$72#js>F};S-o04;w+`9}X%e?b_kVSs=y6QXVG?sB*J2R9Ts<6K z^S-rbGZS7RHteqL~Wio^m^zCj`j!w?oB1BiMd zy%0Jrtm@2cbJ1#nGiv+m9pbJ?%C=NCBfKI=fxq1NJf>!sSXJ*I2z3&QXV2ze zP``%La2UN{;Xw=lt^fea(%G#DZN1s;;rVh!f6&LbeKlj{imTAHVm_m6CexYbJLL%j zb>fVgui0Ud;8;t1ewt~bJACTAb8lAfg`|rJoc#B~H$@SCw|blGtCIO?a=z@uQ6)eq z|J8#=)4y7nuCGJ;_5N(dhw2WWX~+|G7ZN(Hn@6JZ*bb-_oJ^31KV{ImX$2!8)yN}u zlUfcGO_$#k%m`!^N#JK8LrRMt$!(YD{U%^w?#>LV4{i*o+RgL2$@}++Oa`aTOl)G} zm+Mbe#O3MA@E3M+2j!s)=Gxe1b6=k~TTw%Jxtl^90`t}k?bs-^k2VLdPtfwQQ0)=U z%M1>T6A;K|{?rVfCmqt`$x!fAQRFE3!UR>f-=<12*ndKixS#jvzDTI zR)J4G^C?S|_wU{)d14RL_8HH+5(M}xKt=Wjy@a2$nl9x{z9>QEfwf8s47csJ^xKB< z5yyWePhk)h%3re9w4YAKxT7_*C;Xei%rQaC$xSL^t$CHXW98anGrvXV{J6TUgtOdo|4Xr6FgI7%-FmZ_VM0|{%JYP;Uu&!VsGm@AS+c0mH#B$u zts3H%z)ud%6^IeF%I;zzkBA0CZ?$b(wEBb!ytp7oh@PcV2I!apGi9~)VEo`p*WXxV zGc7@wtp25CfT?A8g7^nyW;`y199cJD1%1+?xl(f5Nx0fGWI%6Kygcm2;8kHN&rUY7 zT$$)+al|oXe>0T9k$wBIod&gmfKE3SN`kvO)MH|Mf)(R7X4O_IuUP)>D5a1fLs*o4_i3s+U+gtOX+)@XP|oFzIY1GqIvHmVpm^|5BH=Eja_ z)yy}}_mFpdZN53bO^FODlV$d+EV?2=w;Y+@2YvLRT+(ca)!KOv%@&Fqo=0n`zZ(V2@bA z)X*W}XF_%>7atCx-`K^yGqRKp~mSKHvzmoh23VGE&I? z9ZKW)Ycl$$0ZB*lvrY0Wp{ibkNCGG8&9HD2F;(tr_Jvt{5ju^Ni*CeL`<2m7-Z$UL zoG}CEQC&TgA$wss)C1%9_56Lyr&ke@$13B(VeZXVY8h?I7jfgU4IiV3jrpKVQ;MmG ztwm}4du38nCOdU-n3AhrrsJ$Hvefuh3~Hryucz=3^HPJe6U`3u#07i^=1H05Q*&iU zG@}8R_K4qm;OUn`1i|0jCnH*%OuH45strfgc_CWldyeGYDe1};%TE+=;fh~y8BM2o znzG>U2fnsyVxl=_SSe=IEy^z!WMz~~1=r}p)FZi3c>n1=5UKM^Nx@2o$$U%6`j!&? zj@@v$!Kn>1v8QCf@HemB)It60*38~#pxv)#?M$xWrw|QFxD{e<5b<%$Y7KJ}<$Cse zGSf>$61ra*8McS$pQEuY<&``IxkLeWhi&8TqMQ>1mjqyVj*z-^BECP{BC|+4!aenPQ@V56-dc8%V<*7PbdVvhxotBazirBzV{WGr%dXB6 z4^~%-{Wi?VqP640TlTj@(4r3+-MeQsk;J~dvd?yIgZifHtxTB^kNyDAj3!{V{~42O?O$#Szsoh$~u_zf)R{@ z^j0%NA)V)Vc-O5#NP(=$c=Z57Ci|J^Ioa5jB3JW(Ia!2Yd(*FVcH?0oQAb)p%ZsiM{wiRlMKz+8Q-UT)skakX7dgOhLu?jM1B z@GhY>EQqjhd+28D^Y5I;oWF9=PCPfdi8^|}CA02lPk~Y*^(}Le>|wW+9-J`Ldzd;S z$ml;Fwd^l)iKxHYL-in_A@lz=p@Rp(?4{?2yrK6V(|)vm-`sAf5+;g79x?loHdxqG z_q2bq2>x1SCta=7Q>4bbeou)Ia~vVmpzN&cM>fs+pT=nnez&C@qHDlYLBB5xKKpmh z=C@MM;xhahYYxD2!*jin{_!x|yWh8!Js?dd)21zRjOcy40Zf z0IZ%fCY!^_=3x>=7lY2@HlO*tE#(CH)Dr#YCvge*&X=*jy{F z*{8R5Ue7D-roDRhA!fc9Z32`00IWr;A-@R}JleJ0o`JH|f}@Y)8jRHNOWjM->%+rv z8RG1oUdKl4SpTvg7U*!Qfhp|1TlJ=M1pKJOTr9Dl?8L2*mG z?M(g3M!N5NlJGd^EWj%%8iK3a>Xo$N&etFMddRz);J}4`uwvF7nk#f1!o$n&JBuzl z5^z=@j0;`^qvGOlT<1EcBdfdrP;te)z8I-bXp8s`7Yw$-1f?Ig;;ZnzjgR|(paN^z zxncON8X0^}Jo!q&SGu6jCdfnt-L={o7zuhURSM5xLphM~9`?yME<=(1BkW!{!k$xIJzz4grfEUpJ;< zy~kYrvO`FvfeEZB^Q-8q2om(`^ORR#@mCu_EY;yT4egv9eZ9>WU0;H)3J6hPd}Pq?WJW@1eiP03lI{dzhR`tNQoRw5-L$cDEd zZh-_{ZU!Ols-6n3k^70_i3ei8Is}fB2lE3^U(-Kbol;d|A2ar=#TFiQ+{#?MzcWz{BAa;{3h9Hcvq}grR@zSI1S2M_h{OQYNX|GQ_~a9d&hOcdD?y&S88=HTTy+f znYSIh z5k(2<29<8<29@saQo51uP)b_5S(G5%v8W}|-CeTi?ymo^@4fH){qX!=K8fpM)?DYz znRCu@FygTB&SCHBoqj(RL@_8*d21$soS(n)%pZBvmB`Q(?kYZ;QI==gV17u&a2{s98lQ}kZxYJDC~ zi^;FAl>-^l?;7oG7W-6fJsb99Y0+}grprx^pgY10s^p+=eFs4KV$n1xzVAz34BxKj zjYTbZb{tRPp~?BLpE!?XZ%#&; z$p*BB&jVVRPxmNAmjuiopIrAO+E+<@A2_u7BS zol4_BX-Knkn=D;hU)^7a{CDJg3vXs>h>VpwOqSbYdXE#xxN9HyqNIcLWgONr+yPeakE`|zN|N_#6+7I|4P<;tL~;gfO)YC8W? zQ@(QUK>F>lI9Y%8#UDS-{Yb(xo9@Du9&Mb`{eU4y117CXirKsED>5;C$U(2_R3WhPz{)oJWJ;a)j!{ux+xaq`fVkX5 zy>6MeU1O^rmd!#WBV25GV!X1p1IDwOW}4f4ys{F-EJMKMIO1;yAm<@$rhAQU5Fh?? zHqb$uErt?)Z}scT*lSJ8MIFJy!K|)zHaL>hStI$<>0sVDhft)VmolM^w3<}<9xT~XID?Ri{j(cdCa=B|h7(cKH#sgS zduvqKpl0!L;ozzF!vTaZ;Y+h>t+;ZFqh=1_4%lTIebe2kJ%oCZnEmsGwr!;QdDFLV z=xcqKo(qlbWL`JZsXSTlU|d&CKhdA=$YHW^)pWw{mZnUx1l?FHcVD_gg^ar@rk9o% z_Kw?6yi?Ts?@m2A)778=cW#EHHNc-rHSN3)(^@k7N0#}_Y3hLhdo5i91h#TaC-_mjt5SNGUHr{90e z!RFNWCAP&j(8X)FJuf$mgw^tBXcKE8k=JJEIvYvGliIVdY#|%z-19t~G<(7IYW}^v zEdJF>kRjyKQ)=)MLqMJR8HDF5NpoMIaxK)G4^vO*JFow${f_Q!M@?*3C5%|~T!ZJW z9*=?Ud<*FP#g?l4t&X)Q*0e=-nIBm=lCF{`kS}!^DKTO!OJ6CsccrUaOC-w9%-ps-r z_q2SC)A|s~ipf!uNUS3KzuN;EE%k9!| z0|T|rj*?7`dWOpwdAxxnw)1%xF{b2UpV1I?nAV+z*xawjw8DZZa}Mo6pTJ%ziFBvD zJU)nnG{v4wOH&Nx42Ljx+@CC;yPCK}2+MqBD%Ku`BHX?#0=-iQc)4+mz=ZbD=sg)u zwLmu2Q4`5-H;SY*Kr7K0WFko$QXRT&EN5+i*b4UKC>+Nz1byr*eaM^?ydKFuH>sRH z;oU_SNAu?0t)^s4hwwBn`j=-5UOL)2I!Y$&;g|(L$Sy^xZfR7daaI* zCK0R8owKp(?SEG#R8rKJim98&EPq4u!o7Xy-F{d7oV}cm$89Z46RSf$@nj)Go(gtw zcF(gZ;#je6J}Q`au;*I`T{ zbX3((C-Q_0o9|u_g9`wE{Z#wX{5^(k*)M4{Z!ner^1jlA?6a)y3*ydJr1wumKHC-! zPE1&k6pz=Ri_JZ*9TRvrr&V38y8Yp7fk*`#@d-|C9iB&a(f23*6z2<#F(Mc*u^F_g z@Avs2o*yJ0QMp0x>L3n-%9b7__xdzwNv<0DB#6V`9FS@)THgReQmv<*3JTN6&0AbAER35-q?2=B$bYP7bJz9Pl(y3>#T0J;^^_1G+2${H^!moRx=xAR>Sd4M0t>MNamFE zYU(WfMT<|nP@`U0aidUDST1ewpLVP>YofD!P5y>lN8McK&mYGp(au|QpGPaQRER@>VZXpfkj2KuMSAjNf2!GGcdOb`tvE@@VFb5w=|$Kz?@rpw zT|v|3ktjAtl@a^LAO>gg0GX2?pMmm=6aQ9zPXl0-_j~SgZrQEGcvJh%Q5b#*7$azfMDW% zHrG!@N)3cAD^#@({2q9EWgi#0`FOMD>yJA!>p`w!LLwgeWYk3simXyQcW-z8>K&SjhUfQAa$epUy zz;8ZTzc%eT8WZlH&y(x%BS++;sRyF5!hW^86Q6o9#mW=4&EULYBLD&=n39`nHYGPV za7}McCJwtN9ufn?2)X1GmBfQ)Dz}}@oW=~-^g!QJeZ8Sb?g#^iE$`m>B&OE8?5D?M zFSkBL7kLw?Ds}7F$BRqEnnZeSJ5%iscEUDI#4Ag9UX5&H8J?ScEb72jp2NO z-}po&e?~DnnPad|{5O}4;}4_Q%v+N)D#=!sIOw3dnPTTm})6S8$oQ_G= zTITKyvZ@{fzE;Vo>rwjoo$C8HfNmO{u6ok=8r4L9ez3P*JT%})8Mz!E2;x#e|LuTr-zuLOHEOXKat zW_#pXoW%{?>Vqn%H zoOGfCx>Fb?qLE*vLRbl;7(}@qcI}4mnmzQ++gor!(9I1x&a{vUQU7R)_0inse64() zF(u;4HAo~iT+nXr)@terDLPxGP^f#ZoBFv#>Zzp=WyTI-s83iss)#VGI$c;3^Qk61 zEU9;nydtcGH?-B|ReP`NwnuyHn!r+OvYyFenJ0^FX1IH~a_F1V=ABCEsq?uDw{CVy zB@s4UeNaONTCJ<5hKoUJV{4g^oGhiNa(a(yn%Lz4mc_or^`(333|6RYZHd11rrEyT zhVOMpb?5!ezWx0I)(!Oy7Bz0%XC|9C?#*VlWa-Gt5VYQ0GHgd8n)|L!S2GYZ`(9tb$*h6EJHP@Tk-k2!)YRZS1rZy<&*3x_WyHSBs28vflh=)*^9u@tl8q z)7yU1xl@*CcTp$7@LFy5r$hON%$K%PFuCuz^aq=wd_Sdk-*u;=Z}GOMvWxs1`k#HVwlPe$^|sx8u2HvD*4w=e(k6ECQa)h!3-%UI?zN*l#Lgb zKcgRcnmx#O*q7=Fu?yecpD%uZqsbGdiR-e@FL;tr`vcml{pdmMoH@NW&68XQ?-)~` zE@0yMou@3yOiwsl;wbrt1W;Yb6-CqFI&2Fm4*m{hxGPMnFGRUhj6Z1G7GmpyyjgAU zo0`BMO8sLO`-+H63uuu%J2=`?Lcei)MZqod%5|`{_0jwCNcD?}eh#FnAJAR0>(ob& z2L-)Pa^mx-Kip_cZ1^#+*}*2)YIKNts@zz!q_mx`3~3dG^`jEV-Q z?lWR>)euYmN4saJ?XoTF;L`CQWt5F|9v)8WB3&IF05E>njkwz2LP~biyWQ_Ml)^cq zt))RGu!Dg?>c9lgO0gX3Cvw?l?zLO1ddgZ7RA~pY5%%y%roaCBm4`F*A#-SSet9D*8{Fi- zKM)#!)ckAqcqd-=Om%>SUAx|Nx4_z4uq97UY=3^Y%DW$fYcd83y>wj{WZi2oj#X|w zr#CFWIcfPS%p7Dz^c!aUqAFOft69{(Ou<_^Up4%N=<%-R4V(U0rrFW?yF)kJ&Hzfc zNEmxWw;u1>cz#m*_^zz-&QuY@J&Ry12vQ+B?;N;wnC16DF?ynxiQ2A~jC5)rYQEg- zH?*xrrd#oGn|;}>(zLI3s?4QR?WwebIP2MtbED%S)tTyLqDU6&7kS$bxm5x6{6ZVF zDuegP>7L9@GsHe|Qx)7cMI#%`OA3yf457=tbd`mzU)H&(Lt%ou6*Jv$(HQfy5Ir3q zHXGEJs?EU8i;=N&{ZL@Ol~a34Gnr4rs!YqsLeRRWh(LLL0McZ08X}Byu4-rhtY^SG zf@?o}DOWdhPTOye#mVfh%X)s+Cy9-nQ zb}S(@*QSg+Pm`ZolNY8paA|g0Xga3-&cjpOPWkUHo{OW$T6Cax1I0QYTJzrr0covO zafNlL_0*pVMp*%6^?&`Njo@$k1$up7w}>B-lb33mQkIO6;p7-+Y8ao zQt^C3!AW<2Gl)}SsNMH)hICPi$Zod@?{9+fz`RUtS!=Ykf{?`Hy&mZp65NJoq7`vadEt^Xhm6nsdcyetov5Ijc-T( zWS6S(Mtl0mQ}wE@Cztw%+7TlX{XJHlTJoG}W`K(hck^S4Gs6Abf_QEYJRJU(JUn0n zV3nK7cJ{4@tjJ;)i*uN z)(~we`hcevyt^&BdU1qvwSYPFq0oXeVu`mVo`lB)Uy5Nx5EbL%%mX&PZhSUFxtU=8 zyinjF9^iVUrM2w`-X`MmDi!y6fGfGsOU0zJsY*V>JROz+iDNrm-pWDSKUAIHq}@48%< z$?b`Y1ViI{zxz+GzQA)~o{acnDm_c$3>hTV+k`_a0`U3rA3cZ{C?Ep8QGdkC%(d9R zO7b+5v7e+yYsSqjeW1U;o#^t*LFJy*oZfoTlw2W=>xbc(m}n)YR)r&-k|%*~0t=@v z`x&DAXc^IjyO}# zWmiAj_*0H8)Bu0+;Y}jhrz=v_{%{QuoaOt6y#GGQ*93p9V&_$ra`n^9?r?2JlKZJ` z+zlTlHu8pMXZtT)IP*@qI>|I9mY@B^j+70}f)%b_>wg{y_p1ukOB>)@A^wCMp~lO= zSYG1ZvA{PV&fh{O*aDA{CQ>UWDV$RCUPUZy+d7Q^8{J8pJzI(_fw+|SQ}&gwAm4re z77h+xd@8X#pVC$xSpM_RU;g1wTH8|sF{vQ-4#muw{eG>Zz<+fZiK)= z(SwRBP0MWXtFONdMV&ZuuUTwvziVUJpXJ(LDr$-J%lfJ09p&j27OD6V(=O@H3gXNX ziDhj$I*ie%yOuj>as7bJd=6gAS@OD94!AuCzFW1@~uD+*S5xRTw7rk2tz>1nJ; zn-E`$vz5X%M0z^^h>UwQ%fK@cxV1Za1lfAVv!i~224djSfIr8_et8Gykqfypup_-x zEZLtb5Aad({sUdZ*;^=0r<@okt}3xdtUqz(=;eehmRm0jTjZv7dHXlnm=7=p=32N1 zBTk=-kdka+A9_aGwps1`1S${gx7izJ=D}X_ldeUk^F2ZA(013>W|a?np_q$$VNE@J zE@Yl;pCnU`BFdhltKQF_KbuRC)V+MglJ77a?DHA%YCPJRBF&PwC2D_0Qt6~->W6tU zp5CPDZY;O@nZgG&LBoel9S1gbZdu0n))t>Tm=QbWk{DwiiPM(K4~m3PwBGt8hl^Wk zbrqtaFi&IjU|E6GM2%)d@yjr48`L0(@#1r0O=HvsuDBHe`qSOZ0T?@-bphOnqOXoY z+vDLz-Q5cWRDExOQTFqmblzQDrg9UUTisha+t#Z7_0zYnaN1?_Z>6bc z1=DgVvXpE(7|-GsUp($SOq+dS&7MSfmt-8_PMIH7m4gC#=zj!n)=_7=K8%LCWlShG z{&@V1x3Tb=g7QhlNRIi!^yOHCx56e-$`iV+q=HZFVbNjI?38>TbyD4QSEiHP)H7g) zq|O&_3MlRc^n|C|Py*wl^+mgw2jq=}kSPWF(byP|E}=s;NkdxUHOflFf0)m1)MD@b z8;LLefDQdBW2sVwjt0}+M>p>hy_&bpvJ>9m!zdAwLHYYg6E@c-aiyzW^?6~6;k&x9 zKup(~?#z*U@4LXIdETO_?Z^IcZQNOy-1=+!l9vVR&o>MXO)#Z z9wj^5PhX^qDrI4Mo`JW0IaD1Dfee~d9>)9d)&;Lq*z|8*{;Dj-UBBVQpw8~G=t;#x zjy0W~DQ#D@zp=7B6yedW7+pWH6uh*8& zyetolhl1-_C$pgGy3cVsi38y1?w< zU}P3euH+-e2cj z%S}7aH6oI?kF)(#0y)80njj8))?-22Tox$rcFNV^V9K^pUnp& zY8V(LOn%lf{zZ+8`@-{j%%+_yK4Yz$C^n7vJ{?PUp4}iB^Vm;Z`E1Kc;HD3@{~?rx z`JwX=;a2iF3JRbnXENUacb-6pd3_Gz_)#g+35mzd_#dw|{wZ3#SuWb=943qBFAtCL zrH%%sTPb%?qCB3iLDJKIwl$QgDW&R<${6hZD0b9!_K%XybKa&ip@z5qM;s#aO&$q3 z#{gXkV3elD#Q4?T>!WRSB2;OU0OYyK@fEkzPx@0`-p;u)3S9~Ym%(<`$(O%m!*Uj? zpLaGGa(({kpK=!u>2lkUg%Xb2oz@4a*f9w{+)jJ8A&(6ign(fIY-%-NX_N80JAcf( z$-leM$l2-jB!V$ypmg1|qkEvr0~#wbZ-U}rOLkA)+t-cj?aYd4q8CTDTXLC~(;+pd zJ;|7{&!Y^CH~xP_UNWaMJ=}bIeSUp$@n`ow;Xb`P1PfYiv`|hK!b#nc6_(OI6zx;d zlVX*E*?GQLE^3gcdGjmDTYdAn9zTZ1#HTEY^6-ea=Lm8DS?i(9iMH9XUaCamVKXHG_UeGz0H7NYu zWJF6lP?(T*X%?JF#QwEpdCQ(zUc1V&4Q44EdQqKf+%m+@?8s_dsyXZHy&-CNj}3-H zJXwDdlX-leYv{`fai>MLRbWn;{8g=1S7-qznq< z8{hX;OCT$DcSd;`)2`it_3^#mrWqN4#{5M_a7 zjTJW?xTShR>#qh*=sh;I_6e8{HdW(2_Q~!Dt8&8dTy%Cuc6O<;?U{?RrJnygiTH;} zyjRBbF55v73NC(rA9eneH#;K1NgY0{rxn`H(nIVhJ!-gMxYm(^9|#wEfm!cjv=a;J zFb>iy$A5#;Alwot$pkigoHOZ#M22BCMcG?)2^hb@XuNnQ^!1aO%@lFZ`)%EA0s3QG z(j5P}tLqkUb2#Yck78Am*eQb7NFpYGrzsE#5GzzlQc|np40L$xTEBaX*1Zr2#NMpfm+s*35Hz~IA)ma}4oL|dd>HA`6&o%o zX|vO|noQtbBBC3u=w>ZV`GMaZw$vMV8fz|zg-&KtjVfFS`QjxEiPrw87C~sY;+M~> zU4=~r$3x`sipHR+o(G?gaO=kBxbeNAfln_e@>~9*F_*<}=_ZClGv(za(^4`Ty{o6U zrXfL0jP8~a)2*=wlPRbCG3-lzvrbMT)0G(haQoM z$U}B|{$16PcKyrsi^bvJUqxj6K(q_yhYXfKR7BBWVcMz5G{&|8N`#Dg3kKGxLMr?h|z)w=?LNuovJsyN2p>~81ec-P$ zwpHETuYlodKfv z+RBRmvxL!qddR50`y? z1M6Fi9$JV%#4{Fdz*?p7O?KzuSMUrUr@br5KmVo&<+R_w;b3~MwEzBBQc@D&?pVQO ze&`kZ>k*;FD)<-x_WgJ0ncx2%8i7g}Y=?(A+q@-sNZ!C~o&5eY+h=A!|2JEb|7*5f zps`#Nz)}8pkQxAi3En;Mzc2m zqy6usa5z(}O-yjf$o?mmBfxfnL$7vl>G{8>$jBhT{VoIa{r}8c0ULmdm(3|)lY9cb|mc0kNm90&hiDv@NMRb_kBC+W!Gd9!I6ISSqMQbEVADUFe+mM(&rwaYNgcAd9d zj1&sL>QMHoTJmJHZU_(Z9*t*{&0SJ{P>*M3t|`2-fodkST&z2PJ}(8EHg-`4JIfj9 z#F*96ksq#p4o;|}RAM?bm_!WL{@TXzMF*pyJ4oC!NxX50{Jlu?YVbFe6;{xNI zgeCIQ&d?wZn;G{j6)excFBT)9+A8OD579CF5DVP3&W1p#l+b9Eg0MSilThm6uRaw^ ze8L+ULdJ%|V$q_%91GgZS&G|E1 zt0|j$mWaPGiXIUz{5XrrRHa9(G7K4G39y&TO*Ib6(nr%2=tUQ5pjO&DG}b#be!Zz8 z@_hf~Hq3W>kl$dhUUc4>&u8{_keSB$pP{wq0nhEcudI@?P2Naciz@3b;VlH}qYHWoUfT_NVDk#jW~sUjMx1 z?ivOO-ql-rh9t6Nx-;o$SBhvy6P@TBicZPc7_#+LisGZ?Ez3H7#@Q``g*x-XO{$KI zznA~P5ah5SZ~Xf8%LjjGAh=4r@xZfYij%!w{62H09*I%Ac5nLl8sV`Isi4)=6iasJ zcNXWd4Hj}Fbb_%$^-{E5K0<;TGlQ`Tk41!B%Ua?yL9EYgt5$D>C{*EbH}*``4sXoO z@}=KAdN8yvhYo0$K6BHn6}bXRV~?lo1SQDP87mbpx}T8e4cO$&<~S8jJifkXH(B{M z40?=+IE|);T0nBvZ>E@ua#$=Nr<+IIBh4L;Hkz>b^UH_ zDFdjEzbZ*JVfD;m(Ig;ta4dn=;BbDMKnEATkkPC5hQ!B7MLhEDnR zZCP&jP)|k7v)L%$Gl`eIR5aAm3(w3tm^B?Qp|0iawpW3Sye?b(jt2)Atzu61YYk%I zCo1FYapPm%3hJu18M#ceQrgm$Uvk}-19^2D97zN$PUd)y*ZR`=j1Gq6Ncgt5wrlt1 z-1Z7i&+?ely_G)mita#Y4r7b=6}_APY%2lqH_!jUcz&K(r4X z6Uf|R`|i82_Qm(Xpdqq1Ce+FVs;Mbi7>y0EtmV5jCRP=RXSE4PZc&ky1XsLI=Aik( zz}ZlD|1+2umFRSH++pQFaq)a(y6h9Vu`vz~jw?8Gup}K=yvTh zcpy!G_SUKymBk$z&HaP}S}y*ML&n(&u8iO5dv2w?I+HSJjHVeh$`A7V9vzQP#V+ee zn|3{Z?o~}>c7J0CE6?tzv6$A<)z#J1Ow!@BUGN;rcn>(~SlHMArAb;qDmbbuh28N2 z0I#EBfF=n*fB~b{(y{D%e;QZby)Q!XjMH0-aqp47OXn}9gZy5k@mgC63}+I#x-kT` zMlm0=>mE)`>ZNoR6V?zCbR25g<+Z11%PE_GHUmv#_wB$T&Sc1;EGBBW{59fQZv-s>*y60Akl#&(;7y0ss+pOJ!4V9j?67Pn72Rz4fv5HCdM^${{t681wAicIn1KgzVt`i5Pj{bo6;%auxLuL38R zp#3v>f_%WU|JdwSq0==ZGaO^!lPY}A^QyzR|R)GO$H z+aVSp|IN(Gl6rL2u-~j*_xW}H`swy$jQavWM+IS-1n>TQ!}P1)IV37WI`en>8VjD*1GN{INI-Sjq^z^718y18A_ z;i)o?f9>AgLMqBFT?VA-xmkz0^QHU6kGG!)qAi*IM{yab5$0>v2ZOPwIBX|AXle!^ zo&faozP>(An>jOcbIC2ur~#jw!%m3Lof}|3gx%j=16o>feIDnNsU_i{$x>Y|x8H3^ zqo!6GwKm3RAuR$cSp5%-yx;4JGwzhiO=yUHK zJpj;W1f6#h%=&g6^PZ;Y}* zZ;??4d|cKsrHYjuU&v-`a?x`><&YK)x3m8d_LL52cs{gb}+tJLmiNmfi3lp?HjX4JNxl2eoRgCv&~> zL<>3V{YA9)YPar|hmh(6w~|p$P6*L2R`VpOMtz7`oKohy|KzYjjDlTQkL?4Iq0xP= zFqX#jxZPv!yxFSLs(g)(2U`YGBOh#pUGG)%&mlB#S56&;w)@5YL3*1ojvb$zBlIQX-X8((8v--)1k`6AgK~> zj`*^7C&e1XP;NV&CKu4t-w#!G`X4R>$B~(v%jtfy0W^Al4yw%Jw!9C!R~xI$&L-b9 z9O)4h6!iA?MnFLL^5qM-mG=BHdQQSUIkqY^v^QPA0~j+?E33Ieb>?EEnF2yB3!|U; zT*H%GEa{$qN^g}-`w3b4$0*l^yH_eQuq8jzQC=4-8Mi{hu-E#R@R)B%5FT2dL8f-^ ztEOf?*67z+ees>0C0_}1D04GTOoG?ktUGB8&SP1#O~9_Mu4p};)t)061G*YZii_t< z^?g^RCn^6!oup;+Bx!6!)`ySXdj7qrsH(84 z*B@U50N_s1JzJn!s99-JtPk@BU{nn*`&6i2fU?KK!-I>9i;Rp+X%O(G0p=54hcy`y z5s@4n6_v3ECWmwZ=|?j&Gwz!sKY+JTwd&1!W`>ID^w^K8(xe}-wNZ=S2`}Ci*4`6f z=;J3-J(n>2I+~N2Kk{-qZcAK&PFCz=)`9#!4dO#Z0OVnJkL&G@&-5nY^0}eHY(`K| z-s~;zq;CHo&m*7en$7=cs0c|;uCQp}+zks42b4;=g@t@3eTf{F6B-&CRx?%IBO~^J z!4#NBK({C^E)JNQ0AbBY3q^8vb~ZpwaMg_P++1IO@NW+e4WJ6s#c`OA7@h6#;4$l> zp*-KbKW1JIGxeW$^<*hLF$&~<<@b8ilP;VmX~2K%?blH=*00eo|Bd9Zhs3NsOFM&p zfQw>pO-GW-P|V{n=o)f_NsWBCK38e^b!^dDXb~m@J3%bq?g&VfJkE9ipRE!osfY^G z)5HfXG`N%kTUc9r4hS>`L8%|eacXJ`P?|(fg62Nz%%Y;AzG!+#V`gco5cp$y_0oli zP~h#nTgAeIBGdkO?2UvIzdw1=osU9CA#2Z?CK%U}N?|N7#*3vTIFeI}gcYrFmf(_8 z^1gTTAIB;zphSsaJvFm`Rar>@XG?N)Me^blcBiTw;ZCCzNP91894n_$rKSx_st>78 z4haG52j%5cnY#!g{W5IO|dLa85yYc!)7C8VT>p-rgQywY9LADNv=y z!I>6h09CpWUn>2A!a^c^{Ju24bD)ZV>t^LOU^%(bueB+jsUZ>^o?>3RI-MKYz&qKL z*;1i`#?m3tZYE?ORmBWZ3?uxrEtXoJIJ)LuSm8P_#RPZ72AZl8=47_A{&X<^p&i-4 zWw|ITE2^vtHni$#9>hDD)mW;*c^3(t^k%yh7Og-9wYm#|OWQ+D`jb@))rvLBzs?2C zDeLP)Rw|T?Lz0L>+?nX;?46u$_Zs%EPPfHL1>KHT)U0R1(^==4*Ve}IvVN|gBr)(Z zNE3>A7s`lnvSMeCC>|?!XZZ;#*314I*k7Smk)4C z+~1uG85$aznwrYX4}y)Gh%Y~1W>I{(RSg0xtLc*YtkX4?U;_1H3PsIm2P31=^$MEl zt{j}8K^$`a>YZ;l&)ENQc?zW<=oqOpPZ=UY9-f9D^YjG}QxzP&LSVd)XDB7F6j=c6 z2Yc6{$@RHKU*h5&xRvG9gkz!mai7^{uUXi`9Zp!hu#g zuokP!BRPF1o7qgi%aSISin>YtZ&?*07}FKYLs6O(*~ZGUJ)P6+!x%6cT|eB!-~XvY z{ao}_v#}bwS_y9p)x=a9#7iHg$fif<q|`(zlZYkP!ICg)Ru~OuiRQ$C018A^G_#fp!r78BR4egB zTsEK*nFsC@1O!CwJMYdo0kaOMBLN2z@R%p3rvO%;2AZZ)4R~G*o<#1upE)1#oz`XS zNR?1*L3cJ>vCTKE)^rB8G1B#%+k})RGcHf^l@FL6DxaY6%$DJVss*X1eX(KY_D)>L zv>+^Wu$^Tve`9?llzC%{A#*vuR~NQlSX9yikp5Iv71dQo6(%<(OUaN|?Up;D6l$uf zbZTu#y3OogTt-uz0vL8+-ndK$h_SF@02jv3!a^>yp^xykU_cKA`e^xG4>I6gj=(44 zGV2v-u<)|79-VBCf~WhUu6*i-sdA5|gJ(&jS(%JfN@fPtD(v>OFm<1E`dOnqyNS7GL zGHJnNVQ!YH98Rh@#vC9gH&&IEEe4og(F*B24r_b!4IoAZjExn5NetLWM!;|d4x7PL zlUWRrkT*a!Yi?%dc{;A1QvMg}4%@b>KiAkHo?F9%#C=->w# z`S9$_+1`Ez1iIf}3(LsLcE=$+Mk3_2rfe!+9{Ps#5?*ZU$lle&r2S!!vJ-@4vay9ZoA!)!kuOo+dt`O z^UJWexeGaLiukN&*hhw>;~5mKQsB$W%S%gkK(zs1)b}tdQ~{^0F%UC01L{8zt575Z z4Zqz5h%F!p28SSE5rA3s1O(VRI&+|64k88eH*dg)AW&FeTLZy9i_#z{M^hunrWXLc zv*vZ2YTS0#PcC}~9%%f9yn*{~_WJbM#%#B`-cZ6(j*(9HkHWAi zoy|DBkwWI2$rV2x=&erO@^{%3w6yV9RTX1|;)1NKl7fPn3gcd2UF9KyUj4}&6B85Z z>FE@ql8As@@F@}!px<@`>JE~S>$MbHu`qlI7(6h@pU>?&87~a|jS~HhJG( zf%E)_a01lck5E?Jh)GC*VUr}~GwOPI98P4Ch)+a7a6-cU$7tvDIv|Ulxed?Zr!;fo z5k{J(GykjS|33Oy2bkmii^5&Ti zSp*)cH1+}`1uBK^*+n^7mSbyHIz6X4R~CW})xOQ~gF3wl&0adRMkUx1Hme7mJ6GAV z*K)}g6~1Z)w6vUfV~@2gt&m0X2<_i%Ywm*~pNhqGAHDOu*LU8;Obuxd-UL zz+M5-1n}sjL_{7-zn`>AIpaLO0xU1Nxw#~~&iK4mT?OOxonfTLAI;dExB9k&HPNR} ziapnQUWj@7rb3fdEr_s#|0xuXvEjsrq<>2J#%IoTl(_w5Wcx{9xcaiYpl<7{QyC;L zK7H(K28X~+r6wv_RXxRcWsu&WHUVQQbbmA2(b3V`nhn>9NKC|!?xKj5WCA38>m|g{ z56z9>5ulYIc$ZMR1~o!pQ19;UKxjEAZ0`wN2-q@vLz%ZcvEQ!E?(H^sdvz@^ zMv+5fsGILn>*IUpy5jVDF=zfQmYvGQAv%suD4vhlu11-~N82=?TFmw3SrSgZFj_Vd zbfT_Z={tSu*C8`DV*WEXSF9f7Yz9n0_4QYgLU(31HgW}%EiGTzs~`|E^NrCwdB9|s zD&&){auf$P4q%Xyx&pp{BCXpAb7IB$NY|dselR2BmC^zTks~4^fL4Q@KMyKVbI@ZD zQlB0V-l`X|r@VD*d|$an-XRZ7Il3Xx_M}dzze{aSqHju9HNnFcedJ!xvi5HoBa#r= z%x_|SKX-m0+ZI=1byJ46WA{US;QM*nmz_9LHaH`80b}!xO6xIEx84K=qh%Q8X2#Q` zixs}{#a6(nnr#5Wz1i8>hWdJU509sai2i|rz|qpOg1Cv7ifS#I7;3-tJK*Qfp9cq@ z?Vq+UnF4yMqjyK2>FMc@_+%+nmLw14%3{EvdH6*EO=&127VP41I;O zSCEiiLz{I;Tcgk&V}yCke+`O!fmDyXthR0)#GYCnGl97&hB=%*V-a7b-7e1;s{Jl% z))r4{`FT=9MIck<5!&9gPex!(O~vy|NJU6=K}bbGNC=(z1~7yGw{{I290Fld1W3NT zzPx<$RkkUM}a{!mN< z5aPg!4g<=$1ut)nMx#SeQcJ7GZZNHDcdjEbJW6*cc%V%WBBBS8V z?2@*oW*ntZv4W`R58!G;@t6exextb=H8nLCSM5<48Zz>0O0R-P(E}jW4soY)A$MVd zz~0lPBAx&rZQ7qa4l07c>GpxL#!QttaMPDt+ofqYU!yPK4NtOW1IDWHDA8Vs zNQktwfPjE>gVNpI-5}jv3P?#ycXxM6mvpCegQRd%|KWMx=bi7L`RAYSo^b#fZZ59t zoPG9Qd#$x6H;JL!d>|rP1<^st$)VNNUNi_&_6}Lm(GzjhO7%7?lFW;aBLa+o&vfP!5e%!jW*s0 z29J^GW$Ij;_V+F*Tw(u>7+z6+?KkhYeMm*BZw#EFA1b{n^&%0l#iB2DNgw=VK8@1W zU85Y`UHpb$DTT(G| zqobp*UcF*xX9s1|)?+R}9v}X$`P^B96!M%%h1=4?;u)U@Ne+NMSS?q*IxC|&Fqk)* zF1_owt}hI!{w+8jVUzQ6&8E*MW2X@Uu_O#MC~%dDBIm;mKhnq0^yT398L?lKW{%Kt z-uDZ1*BYbhSm?ZpnMh7f2B!o&8=DTup}>Iw4lx5;TREDfxLQYWc@8;cWpqv5V4CSG z5?(KW<$~1WbfG4==Py`}I3Lu(+C;$E1^`7GKs5jW)&VJY+#B>W zE!4dY{R#CHOe6RYXaX@ne~1!h)Pm$z9=K`tv=UlrGNofpMAD+&9-nuaDxFzH&+QlL z1w~BHP87Wv-H=L_~7|WJjXkwW;NHLAwoN-2-9abw)WM*I~jLpZGiNy3128C0JYzUVR{2Z?6|NDuJ zl@$xMOxQ;euDQ7x79J&$*Bb%`ZAyp&#QXI5U?7Pnmnai|#$JyAoWIuY4Sd0tK-dLT z0~-sACIIOGL(5vLg_w_y;QoVVA?pkv#rb%nB;zO1>&4S$#&E`nHT9lQkzXdWvoQUy zA$X>vtT@49<-9GSDTt0emNn=$C>n2O7IxU+6e18BRs>TfA}UOnCj7o z{$M`>>Cb>Pe4dll)6=Wsb?R**{0c%U*a%e8iHtt?H^2ltF)8VIxhXd8@=@*aW)tmv z8*E?DkO0%~z%b1ec57x14yvD^nlT4_5fOf{SSIG(hWwx(t}d^_%|=FPqjPaW(p%qO zqeP6eFbe*A0`O&4@JdK+jfZ@s#(P;I`Z2+sE!P$$|2z}35zL@J1LuA9aKHu}?d&B9 zqdu5w3GSphs1Ob5UQygq(n?lD<+8J~f{Ax~V74m)8Zj77%MU6SaL&f6QuazWC%wA@ zNqvLWLbmvGC*^s!^@Zc*wt`Ob3)_Y2ZDYg9TsSI(zHHwzF%}_|6U%i zG=D=ogq1F2_&p5d>TN?Sp<=JN+owbt@@OfFKjPdhXI>an*?R~tjVR@axUFsgbkG+; z03ZfrBBC^awa09!6!F`uCoj*pdwa(G1nEd_RtMyu1SGc6l9Xkw0?#eB++x7O0chGJ zn5ydnX0?A5R#8!rk}3fyx)NBM;P#I__*z*Sn=^m5F~CccRphOhJ~Ylv7hs9CxOzPf zj^cc_JF2mfb-S;E2E7>pW6#ZS7<}GaKXyy+V+{{?eyZ4?Wz2~UXtzfDFBHc!Ka1HY zSg3p!C!nALVW-U&EZHppXHNj2jE#*=#4FZ}k(n8?ouD@$1n%)l$=u&xTD9tRs~@qf;ltM;g4ti zBod;uluQY72X9ejs@3h~-MhYq0KhT@jJp|2{{&Lsa!?n6+$*srt2|${JXT8+6j2vr ze6e@o02le)>0hQV>JI$h7fr!_0Hm>J)o9x ze2`qr^if?eRN}|Q!pa>~xzh;|7HrQ;tXELtr#(?RZF_FKfW82Ncti17*v{uyaF)RtTs02Lr zTYFVt!Gfs?celG4T6LBt78ZEe*v`7&wMm(X@bR171~GC>f8igp&(2KESY_rFmzPuW z^pr}5CZhnHot(Uz#N#hMi)r}abPT}nnM)Yj)c{R{lG9};4zMHhz&9&TH2Dir(lDsfrK@$ z3)H6Uk`k@6^sQ6>^9(`VA7Bwv+nj=+VP*B#x8CIs>w9%H;}|+P{YC7%Y!X+C^{!1byeKNcfjP(c_@wfb zypn>F3TTz6&dJ+??N+%Gs8}T!kJ3n)!L~in`e#g!!ZGnz7O;0swdo6J^t$r{h~JJg^_)kUCot#!u?Gb6LAub^|1e0rFyb^yDP>Yti>+rD2~4fBgjIxY5}NGT|CD&L1ONbkO6fy*8-q)gJmvAb?< z7pN(^!W{=O)Y}oYWqf?xk|ZWRUL>Yjl3y;FwP?e;7uww@In5O zWc_4)s-V^Hr)0*k(&~6>FSJfI#X*;;{{slUt7OiB66dU}LQqnFzi2*kZxB{LivO8=&zG-m&bp{~f zN<>6TMMOzQLq3TMOPg*E2h5^P3xUP_U~_VL?eL2 zA+5apq+!j62Q;rhYc-A2p6u=0-yo^nB_ksvC-?S#pp;2k&QySX_|Ytyc1gfCH$AB| zWtE%1$}b|Lq#`6GBcmkL=3lQ+GTY{h&*-%E_0;D^K}=0fLq{WiSwKsqpeSF#)0;@> zJZGlX$*FyR;qz4ar`?MFye%9^2KQ7C@XXkZ#2N=x(H8F(NsGg_B&ee?rnVSf{I}8o zvN(Kvcu_h!_T!U69f_3GAGTK-ru!ZGN}bEURxj8WM>QI~ z&lBN>rjeRR8-VwE(w@*m25k2?tFOzm_1r9mRyTY^QH(aj(4}8AJd!c z?rtPZJ5W*~-hTy%w0x`!*HqP(#HGrjn~Upzm>L~ZmJxW*H2fOJdoZ=dZ@8ZKlG^PZ zMw2FDEmI4lm#IaWW+f=*U}MH-@km{$puKduGLucYvWIB~`vx8!9>zcO{>S*Z{COd$ zgvc}hAv8U}!PPbgX~N2E!&??ds5tYmLV!Enxlo_hvP{Dr{rnM+r(>tnaHhqM0L#c1 zQ|s%Dmfn7+lGB*7_Tdq49P4wP)?U{^%7$BlBeQaD?%poTM^)My3sa*MXJ%#F+_Lf& zbsZrsy^cZ99+DZV21x|4fUX6Ul*-CC95&h@fhSXWd?lv%Pdf5B? zxB^l4aDsbC8QI^YaJyg-kPC=gQ5{-L_S7vIH&`^pt}KgUa3;wtK2A={OiFyTNQDUM z?>_CJJsAAG6X*APw_^Qc#lnoYqP5K3E%!AKWSeE|B<7KTOE2aE&A6W;iT z;TXRCg9P8(VLeSPt+~gzbyw6qz|k>$&e!z$yZJ`_a3q8!6$X9G{u+C3)ETkV^v7Jl z?lOPEEE;tz8r{-XBU|BO!u9+x^B|mmvD~6#wo8t=b+&R+bMXnYrY)r572hMnL)GA{ zPFY^925FXvgXm~V1oo0EYlGYUBR?l0D3CdlhK;$O5lis-f|ZNC{aMWzujgh2M}B^c zj!rZPZ1Bp_7nq33gJavnV7yLHji(*thEJuhVqk1sLoGkp~n{}I~CU6^JUNlu42 zy_r3Epa;|Op$jAJG%fWoW#m#O{|;mS(J`q#q-k&AFnZ9HhicaYqoz&C7FFi{<7$Fc zg%!ix{0y^Zo}z{IPId9nqELFh-P>`z^WbjdPr(Cz<)x*$?+-w9((^j&HI#Mf-N3l5 zv)dg#mg9YVmnO;gw0vRIFU!hKSi2DVrcN_IN+OOdNmEQ8q>C{*f19jdbE379b`P+n^hM8GR4K(*H(usm+v3XVVGM6J7S)~l+T~y z>logyC8hrCp9dQkteCYazt!xhLnM+m$)Nq;TV5ZMLMWJFZz-pSW%4`<225rCO6wiU z-8(R*|55W8urYlXr!GKiJ(^wYjljJ~w$A?nBNQHXU7ztaQYLwmSJ!r!0viAp@H}5H{YuFZGl=kr?-RN3~^f8MFiW3HczrRT9mgm zyc3yB-vhrP7jyDm;F@K=FY^>nQizPH2ga#z?|9l)E9VGadXQ)FyDflKjTgiPCL?W5Kf5zfcIYv7R+h5 z)qhWRwMJHlO;1g6PfSnO#^~wky_`?4H@0zoEbSNmy3tZTT8lTn=bejBJmlqByX(1X zXQ7oD>Bn%?QF7E7lx8K>=8VknG&7ffGah*S<{xGXG-`^ul>a-9OoZ5)FG@-CvHR~e z#-=O`_~lIC3(84kM^PzuJ!2hLl#2G6GWx?xO0`^7>tlZsA_WU(EeldcZZW>scB72U z()TMp*e>{iz&c!Q%U}pSj*H*L9X&+-@9Hhl^?*M?SM=2Nm$@_4Y&H*e@z=K`x z(oIckn;rM+RI%W@?oPKj_Z)WOP5LeqZQtRL^f8+3umd~-N1Jk~#%|;9R(q?1pJBi3 z!Xn9@eERwiNc?8J(jAFdVW93jR_zs)Qg^K5Lx}X+!eLd&;l!Xjvyf*@O`1|sxiO`1 za(cuS--_w7X`zKR+Sg{_k)r;~pP!K`b!oz%uwyNQPe@r!Ef(4v^a15~Z@-3bPE05y z=MRQIUQWrad7ggC7*o^Jdx9KR#P;5IAu~kPJ%De-?t1~0aA9E~LD$2==W*riOi43k z^a*xM8Y1pcPL;HuCW$6n0B@!UE0^byAuEz0DH6NCI_Pwge~fagbZPV)H=*EJ@7GZF z=oFh|ulHsijk)Q)w23q_9KQ@sk6+g1>^?ddUWDZD+?3xam6<&?{hcI;oDsW@JEpd_ z_zN!>E&pnv-$l`Lb#uBY>FGW@NoF>ytx4kVo_P#l=>QD5y{3kxmW(eGbUVSYsH)mp zVcoUK$@7|whwu+O0AG%bh=`uMKLCcHdhNG6DIj%OSy>_RzC=%2G*(elQPBZT@QX)U zY!NdQGqbS?E%doTAV6Pkb&zm9Y^u*;rhj@wlFG}f1#)>|qw|D^-8H=QCU(Y8OR-)p zW{Cep_vavBP5qj>wwj9mub!8u)y@p&ME^tYofSsg4f+Xsv-o;(gVjYm7k+7~mX7%2 zL?uE>atmx$d8HkkhnLs=lpNnD-^cs?sRBTCc>o5i_n@Uf;`IkQY2fybd-j!ib-nN1 z(i(U?VBI|fm$w9IgPUOt?QYvc*bdU^WKSo6^UL6K7ItqY5~~L0k6J!LmQVQ}S3+Vp zHA{B*GnqLj8;6xFogA10#g!XHq_N*S1qNy+iMNU9i=sf@D-HMY8m<$U`3U)#J;B=}g~YDi0lzu$7b)q91C8aP{6R5W4E3hsZ$<5h(kU-x&y zs0lAnYB03lYz#AWjAT4*l04l2SP7i#v`-eUpmqA($XjVKHeK^x@69m360OqyU@DBE zoBiR(Vad#Q7ay$*lRE<;_l#8yGgG3{Z$#-T@|4r_lrP{pGmENRJtoV)$9U-)tajr6 zy?+zkf$YhEa4oC8{>NscKI08Ql+B)8!jKn^x*l8=ZRgmh3ont(+OppDB@j*|5V6I5 z|C5*Fk%hkM-J{9$o924yvZYZ_mnL5%uvD2c7J>#j`-e{g&uWDqt*Fdzt6*!E$~#rx zeO)Fdz1=UJm*aKzt=vjl%|%;^z1CBB*L?B}=lG}4aTfv~0{ObU+f^{4P*?u<`*>&_ zJ-v#l{d=D$&(pTQpWrVQUG@cB&Rj{nIUNjzv#6bB@#;}Eq{J?J#hgp9iM9#F@cJ2* zSPPxe5|=-jN`(bEm*mn6l8y=dr*#Ytfc(r#KL;Au9?4*E1{A6KrjDiN{MCczjEOg5cY9Pp>>W*8FrwOi4b_uQvJa zimCbZXt_P8_7SmRqgjN#I#hKe+DYw>JN!1}tiF%0jE%;WXFp0*>mchKR)F_UV*=y? z`RHNB;Sq~O474OHajD~Rgu7pn#{?nwK`taLHir(1lp=tLGIok4d~eJf{IsaQT3A&T zy?a|ZKx#k0TA41uL7S>E22g1-{6x3Q*pNS@?%wjj}(lrxlsOp6Gl z+ZQFLr2L26^ZYRK0`iGMiR{G|n97Z%mDr0Jh^7#UHYFqXrNrF-D#X^Q_G>u@Yc2+4 zW%6wx2jA=I1w4{~zAh!~;^vt#bCT8doz55C){aEbo!;E+@28HPT+XCEnBlr>n$dpH zR$x#g#H1m+vJ5rEH{+LscamZ$|8Lm0B2G5K>YY3%ZQtYE#y64_t)=LnrpQT-Q7AW7 z)?)5z38r(3&d%;4;>1FVg?r#Y*|Xz~ESNE8t*dpL+`r`LJL`g|ju|_W3`g_nj?g3W zNx1!8?TYlh$DHjcbfpQ)_7Dr#itU>n*7U$DdHp%8>bkJ+WUfk9<#P?fzc+mc)f~0N zL1LwCC!4(W@LRiaq9f7F50pd6V7Bs{p-BUskhP&dPTl@}l?;>EM+YO=FU7i=RMpNc zo0hV=n+nK&>QfC)Et*zweoPlCa-wXhP4up8tbDf|W6#%OXS=@o5ZJPC)F$F!6C&(# z@z8tZeSZH%?C8)9IPHNu0nMq20aNc_T~DIA@p7scD*?1%0!< z<))`wN7f&W3X<*No)c;ia#;{+lU2C#wwY=^5B$d82n%NYZXk1(S#Kq;^HI13SnblJ zO;~)K_Zc8TdO@BQAMg|LmiaZ}-Nmg?`^-SXR+0Ss*RK%k>gpFqOy!i6EZN(lyeljJ zyiM_LY`npC*Vep0Sf5mrYLZE_rEa-oy!*Z0^#uVLjo6gLC!TMV_iY7f&Rt({2OkrA z`PNpDW*_>FRa$snShWjN{kKIN%BqruZu~oePuAW4^es`$=a->>nJc?!xKAJ9|4y^_ zp72}rNu&$?JPcvowzn232&|{3aj~(!@c6QB_qI0mPZhzI8slrk8(5#N-3#}&)mIo? zdwb@#)>m$t$)D)xa+{O!bAHO}s~9e(}h3?oYfv4o;WzzkkcK;v)x>^Xg@GAClMAxw5je;U>flyru$mHRZh47Sc+KB`&p= zxvAngbNJzuIfJDfZ!TK}3U;}^PZesg4KreuDZd9hM42r5TW`}lMT}cT8l1tNY{B&^ zej1EHVT?Rw$>H2uWl4#=;_Y`>5@f==hVL*`$xM3%!_|AfQG~1K|G;sm7A(`wiXW~E zWNwS2PvBXsn}zy}R1|Iy&n2t@6W-fjE@5pkG1(aSoJxV!5sSc@qoiScQaOk>#bXGj zvsfQ0wPY`D6fQ30Y!SpeMF%*`m&Q^S>1^?TvwyFVAgLp4-y2>ZHxpmvd=fu2?G@Np zt7Ep9$D*<`wZn3JziAQI%m|P0Oec~77wAxDZzG#qqw%mB1QvCAYltBrh_6PIuvOrCanAzzB zx2HNm(&!4l8i!FN^)Y(=h#A9qQmRiIOC|#nzIgfDQVG2fL*{ z5x>T`yetb6oZa!v5JE;j#jp?#3LLzyb}h6fDpmPb<&KvUSqD)MOJJ%9@v@+hbJvJr z{7{LX+Wr4?&%a#Rzoh%Wez5oH)Bv+&R%~>TBy#g%T8`|K%`5<4ZK=CE10)^id~w-kQ8D{N>}a3GCOUdAT!s zTT<;F+_)S@N{78dVkld3J-s19TP ztS&nx!dmO+ZcP7SOJO5Sa1u>oJOIB{C%xhP$Fqg-l z>nD*vcmAxje?5uRURjri{co(!Uubqt87j16-5=@tge|E=&{F-SBX5S<%1USScb01Q z#mj_Ht@cmrkTZzDNNn=gF^GC>sBP}~K7lg9c0#-9Dl6P5vUPilU6K}i=THg3D zIl@Oy?kOY(%8Z;Jvana>Yxhz1%{S5u!M0%-6`IZU&9OjW zYujyfnl&wj7V&5Lt}F7jLkN|&qDxdQzhWg@awUWjnqOnbOsgPW>E_AD|0!H3nLLu0 zaN00M`vQ_1pfz7Jz<@j7$N{#Hl9tDqilgcfv1Dk2wd5>4Sv>lF#16?8=te0&< zON<*Olb2+6U%jy*Am4r`lTP`+yow{UL2aN(@Q$~pPSmz!V)5_iTkg6?sE}WIJ7|?b z+_UNh?6Xxti(b<7>->5$`#*A=XGWT@t)*KcXI0C>O0pZ<4ku4k&svm&A{5^F6j(M9 zVRd|2cdh)ac-Zjya;eF=sgAj>wh8Xv(1M9@Ig5lxkrzR;SUixIJ3=!gthhrQ2)md& zl$RSZtT0UdzT0x>i5)wHin^U{+W~%iu3ztO#2i8U#G-ACTuB@a#jjugg9Qp&v$fx$ zhnQ^8P10!@3zAidzq^NU+yCUij23R{kB42d zHrfi^r~7kkX$imLTgtV%%*>*Hqu(=L3&QmO`2m1r&;R*<^Wp#fga3bD{olOXe}C`) z=i5B$-s7%*IaRFPGOK&OI0+G1;c`L!0C_3c7r>7L5eiD!m0mXQriSKr85-*O-?R0L zyoHgIvxA8v0~6!_@nRAB&lk*0Lc*fL?97aU!Yr&JoE(gtqV#q)W+C#jVyH;?NZ{vD zCB%gl!JX&?)B-}pXJTqSpZo_9E1{kvhuh*&8-hBP#NT#06wE=qcS*ge3RubxqOaxU z`Cr2cFlHsrr8;WEa=paBdhtRz<^{F_Bec*c;u{w=3TcR}D>8Cn%cJjF@nQRw_U>`X z-igJ$D{;w*l1_mq6zGrt``RyIgL=^O`})5Z6#l>8difHX72|&|81r}kd%YMJ2d^hg z2WO4^lAMy9yppoKvYfm;9yR3pHX+=#1s z)z7n;6>pw@$3O2r$w#eVz{D-2tu81aPiUy``rgU5Dk!QEhFCr4)S?Zh{4Mm7KgvsY zfe)1~6|o)7q-PBgyuM4j`06R7q+*yjMC|5_kkIHTpyc8w2ZY>*SVKnP-Q*9;-b@~9 z{FC21w}|{XTn(cy&0bI(?-B68V!Fbu?h(ASqx5nSlRsxzsbVQSb#Aw{;=*N?P*PLS zMfdJ~{^JlcpWpLQV&X;bE>{Jrw>-)Hy?1BWwI41?K>FWMTwl?*seg`i#(tQ;_!xZM z(rI=Ykp4(~f8=^ZHpY9yXZzQ86@B_tagF2NVVLdL@fP|&S4Zk6Dkvxj35HH4HQlM^ z-Lu!?$D3``H7@#H4s&(Rp+V}Le{Sc#8QfkIeoYY!7IO$qryS+QMeOYj+zqMtiWbIE z?w{yCH}h{VqHk{B-+N833T#kC|Ms0PxEXM}Y#yEC5Z9Z#IqZ}pkA*9oJ~Qg?>+d6D zczjskSp@wzF4X7slY!{4T=PS{jU^(NGPxeNQ~4fH601%3a_ zrn5eRMw)jlApL_cb~AWP7lGM-Km+=XR?YoT*2L4?18{EnG-Vi)+KTa?rR$^Wmp}29 za*P>KnhtTO=zOf~Y`E;@K-sH-G6>6g@%`DKLz|mjRk)oWe~~$-_!<`ZD*6~I`Zy|Z z$lg{wuU_ruhxyrVEm_&KY5N!Be9|ZaOb@qGFt)fDC+ANzt}2grE6z;Y{^@mXFq++v z2$2WJmk9l6P|e|(JzH>pLpzz%eYrRa!?BeXk~AN9-?iCI49Q@cn!kUAM@q^gudb}A zt}Lmnt*L2~nVKCsG*E?Uw*SFN$D0&lDtdgH^y?@$`Fr8{cScIu!mmVs(EF>_U^<3z zzg+Ql9Fl~Gp{1Dqa*T^r=V)pJL zyy(2o_hUZELt5QN0uJ6cHO@owL+smMtr}2 zPPcvY!=A5g^l$iZV8zkwX+n$&m;Djv`9>tHIl7M4-%hcz$L+)xFFyN(C#n;q&X}t2 zMlA+f;MKn# z!_GX-!NF3MXvRC%<&_@4?FCx%w4arf!WL?r`yx_4R1}gGd~_;ZJPNcSxW{y4DOsbK zcI+DF$wK(DMVA?Os5XQQ;rnU-+SoO3xfA1+)qkSgLj&~UhqoPr9VoO@P1+M3tGykm zD=eSi{K+P7%w=g#b}c9;Z^^n?l~UDp#6`#Zr9+LHcE*;*#8yfhU+OpM@>ET4NWG3m zJ=LUqX}KN*tLX6MHUAU;#2y)UJuQr#Utd_~ydFJ_5nTHoBK2{zYPU?u>444A$f1jx zjiZ`}qnd-anYIkzI@7jR9|pG^8Vb~WZ%g<<19LY4MWj6x^8PTC!Dh+hKA( z_jb2DSvw0gteQ_%=iMt1SEl{Ht**q3y1yB9t*`e&4vY%S->5Gxae6`sxers~(o`ps zS1#90z15T#g8#&zk&ehVHj;$XN{9b|x%;vIVtq>7?OtT_iHjb$UANIEBd&BZWYhd* ze*FvmRdTSV(phs z=CX%q8y!-(lz(nWZzS~M;j4jMt>jT^{i&stG&p62ZrJ+}@6Vm$$7_P|Q`f^ycojh=;eD7dA)fSIm18 zm`4Y@FOvT03;#WpH=$(upt%td%jIEX}V0Oz$)Zrc!qjbM(Z!S#ZFO_fz( z!kvCKD{=`c?#uA}Pm{`RIABz{g%DQB>|*GAxBYcweKTKNO2T4va(rfjgwH1+Dhg4; zPx>oVQdj0gkBBfh-nNZRdPGD-z6P3@7y})Sk(Ker(GlQ0WpmZ+4h%?24GhVqlr)?T zR9KAEhcAAAW9q4Hfm=^VqW31Ef_Ve(H*!VD+IPItI06{dfi+1kXbK{Mywk`$77o3^ z+q&O%eD$xsA~Qyive{gvH>R%TGL1q1Cu8#^%zQ{Xs*Jf_awZZOY?36Wj56=4c5ncl zfaE+TDK)YF`GEm`y|r<9&=*#cu?_{gfv8Nz_@USF3XJN%-6+YJa?Y(iKJgS4)3&B! z&NoOSKwmy_^RqNP=9LaqU&jrtMZ)XEk}xNCy~Zmn{Va*=>UiJz=<85<)T#Q5ASlQk^d<9YWmml&B~>j-*l!17 zVR;TwJ!+%1QXgN|%jC?&+$I`4{yH7B^`S_$@iRqu z{bz-!9W9x4gvc0y?CI@u8tV#;pOZRS{&|~ZayXgF!d$7)sn;K=S<^8B^-3ljm2M~L zS3@d?Z+qZ2OiEzbF)kOqy`8qDi3x{U{YmCeAqx}(=;plv3H+8Z_&jWm6&qs_HJ7hH zd=R^cE1`0RpU~~wP2)*n_A+2HtH>Bl)dXjPOI%4J)3asG5K-}1)#bF1mrX1Ur-yZr z5nUH}IJMM2B(gb{XU8BV(TL+lHGX7&Maxkqz;^4M`76E9zL0&&#yHjLtp-V zvG=E|{u{H68y81uDuL$D?(9_D05M}Ys=A%-=uGqEs6BlX3MKMx4HhPxsi~<& zMf*VC2+T!*&UJTlv&J0^N^Hz*1MF5#V+)I-@^W5NFuPW1bK7PZmxohYA%&iroWmV5 zLf6k=tkNM-^!Qq56&-#ya7}j=TXhv%6KrX-;Ei=X@JJSj?{iHyE2{AGWkboQtyGWO z?HXuGv9ucCAG8o38xuSE))K$LLDf?JQ{v=;mFUR>5R%;0&{1pCFlw!P(K?g^7iYgxl&xAiZFAXt-KR z&8C;Whl-ZwL-1#l({8Dj0I9~Gh?!3f(A=B}{9yk~nFw8))qh4o;J$?bWnGJws3j`*Bw+-kOW}s_#XAdL_Q$P?lI5;>kV4l3l zs-?BWR?>!}KBg9xphC<$^wUUZxeYhTnZ$5-u{$x1bY%3mgQ`A-DlLZg&sVgEt%~;^ zwmo!4yKFQ@X7VE2{h#+pB7QZWZ|J;<#a8TlY2YBlC#z;uGbhZy#MdD))urI_R#PYv zRHT;|uuiYRJc51wvE{vPr186cWvA70H>1t!P(hP$MIvisb4x38Zi9Pce3>ZW{IlpH zFJq(#z%_~;@S6YpgZdq>#LF`f4IAlPFV3~wI{RF<5LMuHzKvwcO(r_>a+B8VM8;{_ zyt{s^v{lLf0tL}S9KT`VfZ+JY8;IyL-EIf5e-8-A-t3owa@{|~|E@?Rb?k!ctLLgP z_)Y^4?~_hj{0Z$(oeR1$1T=g>(y4&}6la|;e|Va>B6K)DyQxWb7@)s_**irTr}u?% zdV$lrimue#q%*hgNv`93^a74c15>DbA=&Xg77cK<%+1Y>i1-D#s?Yq1ahA*rpzQj4 zyyOaGKtPd40*J?8#CAV;Fy)tj7+KiZrsuR8JZ6Tl%VQ~JqN9~kdFOsdoyMm^u6u?? z2OLzz;W!FoaFs{D>$meIoewNJrW|Z7Y$zfr3owQJ%$Z9=e(65zk{6Dx+Sm6*=*7*) zT%JrKzkjO#{Q?AYB=1S>sqx?lgS?~HR@Gl0s-zM01SOXP!b|R>?ps|35+wu!!kdzl zAs(WbRI(Va--3Em{2g=*6ziZ9z6_YRE1_Tz6K2lD+>$mSH&tW z_4PofoHc0?uo06Vrfpb_AKak47d80MZVPi4POuSM*6-54^kjGeNzeYiPT$iKNW#`_yX$dQrlge z>q0nJ+&d-Lz#mnZ#k?<8hLnhzG$j=UKaUa;SwBqV^k2H*CZQzZ>VV098WIX38WNI< zF+cV7hqWm3SlL*CquX4muCbyIeo|zKq50;rrmI};ibrp+g%;YpH2=KPNaT~2 z73}#X9g1an^8~+^`A3RlfjnPANoq}JrgdYNHeYJoWo-HIjy7;D26W~(yk12O14201 z{tr-oCzuoQ>ZBHSlGk6UEfqHmHItLM7d?6~UctcyZVx9^0M{L00s`pVOF;1oxI)lr zk%U|hfV2Y6+H@d(0$X&q+4=es@0$*fYnj$&o4$WpP3$oIDJr+-V)jOikeHly!|wF) zWPKd|>=n(mifN0jZp6iR%uTaHDHLTK44jmY1_6z^%Yqfh9Xm5$f7EmjHLY)_(wZF6 zZof{o``G0nqVF?h_1}aR+V2&ud25$(aJ+r@5GScylB`^wtT`T4R`G*}&&v=}8k!Hr znK?#F7X%}*4?0K_Z-)IgIsf`eRIG!;Ry%NyOs_YFtX?ny?9o|0b zWOi}07qin{30=YM-3 zF4%g}-_y80iglk@K7 zUL=@V_X*-eojSMf_4VWnj$0}O-n;IOuc#+TU16P&CS)j0-{@czm_1w6aY4f$!)@dl z^&%>E<*IfSs&-_wcRe$bs)p8L@|LST)CU`af|jvVZ}9hkyUQ2H%-yrgOYIJy2cUZa z4g?cIV^n~i2pk82Jpcn>%mAOD;YKfkO8?osVIWXnYV%wR#iq3`wf1VA1Fpk*lA<=h zGts}Fd{!b>%TK6>5TYq_RK*gMN}3=l78+x+Y+4*7PhFMD_U;BJctOPmCtQ>(|0##M zgcUVnT;U5KVgFU7P8O^S_fLo>f!afCUF$cMq;V7e`ojoa_oqzxaX7>KJfsi_Dak|v z;Arz^%G?PUDL|Qb;%aGWy(#odG$juwm8U|yQ{gmo2k32iNh)6cO#YVA(lg4pI_#U zH4Ri9P@*tlU*sM7%9!aIxWKbivDMx5aH*oNwMh4qKwoyiXLge`ycW?{CsNmQg@(LgMUs|YdYQ<_+j}tFR9@@FJy$v1rlP{wgISO&P&il?qe2JBf&A-OXV&qbD zyY6Sd*jgvQwxXiCwAY#B>E&eK<>KEt+Qo{vs(>mQ))Aeo`G}jy6Qsf;L}*uRb`PRU zqK_`@I?96+yHRUx&32}0;|VLi3MM~&Z%kFUee&+n}^ zPzQtTQFv)>ZEbAqX}V}?son;d&S_N{_Ev8XBcS2Y(2*C|w)6X@rwt9f3^1HzZGJm2 zI=eV(FtKM*j;Ggwsaj5?+8x?;VT-SuV zjlA;D)yCCb?iO}r4h13KYd@$=>y>h>`s?L@)7|ot_|&a~Yrie4?JRPvt?iwpM01P% z@qH&d-0?v$O`}s&pV8L#l%WZ^ejJ!YmIMZF|0ew+BOTsgyVBY><$d!SJE(F#ya{43 z=<0Z|y7J!FH?J1fvp|lEz!jGVkrw8#5z=aXx1Bi1je{Z~!ke6!{Mb4b@|RqS@2mHM z4ynm96qNa0Jo6sTeFMVYZTVqNMqQt3l@X15ReWn=F)zAGZ-yB8ND^G{ zbMyCa>wp-^YrMC&cV@;JNcMqyMgSRxlYu>wjJ%&THV#&;p0VfFfWN&`0aw|Y^R~e8 zRrTmzXu0{@J4r@%oM`OjG10y5ou>a*-I!1-)2QPQ!%o>WP1Me%TD_>2_?lfP%~|E& zllDK-#Ix&nLSclw*hG5!Ju-3(co9Pxdi;hDDgi=jLXb@gGo*dAKj?gftw+WwmdiM4 z9x>Uywl<|S1+u;Dm~*L*9J#z@5*3G`W%_|?4nj2Uq}b|7qeWZ6l(Hpx*rMYWWXjFo zrhh9C_j?J2>FE`{wRDZe+JeCaHRH*l}!>sCluOjBLYj5~-yAc&yCb zvjzSph)8u172Y+zhCJ!?d!N}@y*3$To^-*>FD=Gmvhz3?Bw!YS3&{?{3ieIq0u(5F zpv=#1Z3ql?YkO544NKhS-WI!8wUOoH!|v6baRE3rR>JtDLbL{p89qLK=(leJgM(b$ z+yT}=Oe-eM2m48{(GGf#>-~Gg*LeI~;KTv?7O3!L@*OR?_m?saK9qIV8o z;8C+D%wdd?k_7V<-^09%$!S}uODusG6?K#@qhD(!QM=}?k0Da}`MqpIbkqM=w3-h) z=Q`YfA0s)`!!C+b2Xk5p_R-ga>&t3WRBLbUz*2ULn20MF0RhrXGXVhs5RUl?4P9P~ z;=d_@viYW!Cmb;fju+qK*##CehV=gWU^F5iiD;u785x<%xq zB@af4M%4(~BbQ2;_cd+d_X4CaB&3&eX{`2tqSjT*569NZdh+3i&nSXSj=ue~V;ld} zJwP5nZ6pKr>tR|)0lRc7`TO2c7c~p3aA2UROook>v0wqqix)4T{FaxOJ#hUWB3fiK zpk33rymx;4ljGn3sb;;W%W<7nCBLR*5d8-On+~!w`>V9Y@~@Vv())MANh9ty1i5j+ zih*APzkX$#HXA@y)~yG_MDBN9Tje3_lz(Grp)LGP0W$V=5`(i_TBuAtoo@al*S1hx zwH2yz6~_uSXPx#d^YR54j3mh%`5;t0LmL}jhb?jOP9P8oVH*c_O)$HDX7oDESa06E z0rLgW0fvOKM~I8-y4e>2GW?VkNoncu$Vh}3VCisnexA%~5!2Yn$)`IdNf`^BvG0_e z^Tm5~&hP=nb_hsN@P2y9yNt|12Y3g81b<$yYt`VhnX3{)@LRL;XrD zHF2q{WNHo|3WSz7bdgrMJFcG9aEy2{IISRrurRMaI5-Tw0h(KG9v(n1YXBs? z!bz`~*ybHeELs1$?;*f}e@Xvpoh$#MV0pR66hO8S zYi14+TO09E=(ydZn6Yq#>oqxJiZ-^gO_{!I1v$_hI*yPs0zck$H@piV~M?{9Z=ZVPfG zqS_%~^ClzCPR35wY965o&5`Ah?v3l9K8N4v2K~FMWU^pOU zo5vA^=+2h6NTw9>TIE+rP{-@nB#ijk5EgW;UQ)6RCa7A>{~!?=gqd}}vP1EWXf-C{ zm){%>%9Gd%xU7BK5>|1gYlhH*n~Vxf{h9XMRav(GJ?D8jO~`4 z&%&8wety}60)4LE>;L12DNxsu#SQ|a$Eb8`;79_9^T0S1n40iMwtOQv`(2)XUNP2u zxHT9Hs)OMK1_a*#BRrI#^U8@(p?*f;yrKXyR(v6K_4z5sz_jj-2}{RFZHX3L2r0g+ z+SXbV?WICkbQ=}Op6QyS66=;AjT>qlmYf`xjW1_fzb5lSLlLR{3h`du@!tEWBCO~q zY#?tzE*9>0O0=h;tGfz3K%f@;`w^O{|0s@Oa&=1m&IYWzOf$b7;Hi0ZbOa`@&kIu4 z1C23IfB75S+}wO?GUGR!hmnT;g!|FM>B*-(dC|#2;}$tf?R2Jf(EKR8#H3%jszS|v zqom26t@ZHr%rYNr25*OGCEI-a>kR)N1mD^XK?6NEgE+H78Kya74u_TJv!#s;%t4ZtnAglGa=he;)Mk7l)BlE^B0(2R`mpX4|vqrL|uB7D2$=2n{J7Y>#`-#HU8OYlod zPmlB40 zWM)PQ*`&zcWFE=RXdwHPq%tD1_YC1=7qa&r+2eP4e?PZhf7Kt|)H$!$^Lbs5>v7#5 zBNr}SR4yaa^7QZ^@Ior1v~=d5SI*<%Sy`~v-%nrVyu*AiP2kB)*Ta_t{{}liavWI? zoXRgy;cbDp5QQd-{8N@!sWXyb(4mz(!G7P3*3LWPJL}bV30|2AbY>lzxwdlWUfz&) zzoCjzzV@=Yxk*Gs1TZ78g$E5zx#OtRBn@93uIVB^JH?ZJfN0d|$E^fEbsVdKB%ry~ zRm$>h_f8#AXbAuY)VG$M2t)8SpSMX+G=_E?f|AA2Z9DZqjwO zv@q(ozOvQ5zqu-u7M|^tDs~BdrhOP{_u>A^9z3 zBZ-3rJvOJ|E?1v~nDSw;;BU0gz!?J_nFRr!yullaCb|WzUmhh`R8!ySx=;+Zt=sKhRC{;KPH#Ld17hMf&3Ux6R*q< zyq{y-iV{+cJ2bz{T?y{ZT67<#zs2(W0 zoy_McsuhoJ%M`NwQH=Nk=)ly}OF>=Fi7_oQ3R&=+Z$mEM+1j%A`ZxeACl1VY9}o~Q z-;4SoU0$xaQpzMr;z3RSd&;@HT1P?gG@kR<|H>W|LRP6&X7l>T)p=8NkTfQyF?*7o# z_m;>F=uWx`O+PmVh2vv(B*PI0VW{Gl)xJNs^m2*G&DahiDiPQR^^(^(q7q*I5D|)C z=jXArut3f?nhW&x^$p~kEKN;q!2$*JPvbyY0Akw}S7FS<1{3tph=>S~XRAj&P;|~a zKuocE^azPTgx+R97qVGMY~Sd!Hc8ig#+tN!_NV;Q8~oYfx3Nm*feU;ihSW46c^s7R z8j_(a^VGTgJ!laXF)7c4-Pg)UWTG7*%3`>p;y@|9|w&uc{`C4le%iAVtQHe_XG zooNKAMz8L@#GXOG0D}rhYls%AYil}uM;yv=QI?i}8|lM$;|9JDVG$@jXH^Hh4p1e1 z`&O*0t=l7*!kTtJuD8!6r;z7!OqxNfW^Ty%xRGP`o2Pf0Zo;cvi~ql&6B0XRD=}z$ z^WH}kGAzH=X4rchk2SulyYBv?;CLNDXHDHfvEW|O@ogrSmCmGU zTKY-kpJd)j$D8?T`7mE-jA@{e%O^F`+Y1p&i;b7k&!~1$MjWpp=7;9;3~1=}*8Y`W zDPYvIy4ATEUAfOCa*kD1QQN>jv?4zKfSFb<GM>tJ$@+K-lfU zT3_J-UbUW~A)`eei;!1W$7^HAB9nJ$Loe$}v> zq@l5=KvKrDxe0ha9)T7E``#E6z%K&Y6Upa0h37-~A(Rz5NQ!N8Nf~!bU}eF<5YkOa zFMxUL%i$Py%W-XbdK<850LY1qBt@ZuX|5_Go(=#09VF@HIBIKQd4=<`6Eh>9LsQpW5>~j-_XhLx5@gomc--2 zLAg*qHli^(O-wFkj5R~bgIl5r;>LM6UEW2K3meguW$Wmlv&ia`1yzJh>oD$FT>wbq-ht23h(DGy{#za`@H?xuw|n=`IYU1i0`Q>{i%N+NwM;HEP9jl=Pun@4AV^O zGY46fM`TDF#z9I@VmlKgg{y;pshXqcy|eP{oftBaaM){XR3)(CPnfMJ~+5T3|I3MIuNmf^}`O6h(k_p(V{vm`4C;>#~6pq@`^wgl=Qi4Xh3hYzuH;o;#x9D#3j>1Y4WgQe<# z&OdN(cJT1{?%B6<=XKaER+tQukf*&67GW78_qo#~>+mZrcHsXkl$?lz$IK}PkGzXY zx<^~s-*bGd;5pe>H;RpB|H2i*YV_!K<}bJc5RD`v0FRa9?G2Kx6E867=N-2PXcefq zmVS#S9~ESJ8#_B!VBPWTx^|uZ0q{D&m;qW!^6`kojKx*YbeW9%zZ3d@B15%4O`Urr zMPkO+8v)~+HRSxH-sDHm&ACwm#3)08k!{tGCWiY(xjGuHrq=%FkD*(x`Nv6fCuO|$82Nkol+4Q2y~ zEp$IHzpDj^5u9TGhY=3?u(GluDk>tLJBA>>>HWhzzFtAgn3VgIf7)Q*)5@S|&FI00 zFMGr%GmvQMA02J~vv|%C*tCf7zGmW2evQN~31Ut(vM4cHyqx8WjT1PPrLi8@IOa2H2Oy=9Up^-drP9f(FMhLhu+t2Y{fRdtNkN z6A@R=nCtaz)lqff@l4MvOYDE&)z>EyIM2vPTF#J4f~f(BQ0xWAU|rqN7)CEPZnn}5 z6GPgPyIh}R3NCUkkgZniEXOBhLjSim4g(13pMwkk=+R?OrbnJk@5B@_z#0W+sATq6*lB}FvOqH2IzEk_^qx(CXuCDVu|G9sYkcPwT6U`mdK3cA_ z{NEE24O>^}t{Ws#@|VYW{4-5zz(rUEFv@jti7<9HG&D3eD#*)QLQMc?_w)KECZz}Q z3)JD6`T3OgeMRkY=u2o@`tHc6C~0Zwj*gCryFkN)LhE_#4OkO9oaHrjbo|l?Nok@x zaZb0jWV>)pFCHJ$b+}Ke2N;E-wpGC{dLE;(GI~z^&nvl$LH=zfBOts97bbmc&m`FU zd?a!B>@zgQ@S;P5iS&fIh`O08-5${h!NP+z(cC8cD|-$wqlAwW#--zhPkKK_gMk6C z)6S2eu&9>yER&MF&dn8*EYZw=^V-*i-EEG6u?n8m-#l*kxG_`m(D^H+|DHT@5@M8i zg6Ys4*{*r{>qnc7RhGDXa7uq&7gwO~jrrtB?fW;8H(ahfWV`%>IvMh5B=DEyd0Bgs!-bf|YHFy*23&nrGp|YF;!$i6ilb-PNz|eX+37yz-0K z3)xQ2AcX&4APDqTkn(DI0hc&Jz-eP+gULL&5QLN+92`_|+*$1Bf%Fy(8%$`&S%CYa zuHJE>!Ai8RqP|HzPdP3*>)?&2oEuB{gRfLe>5ntk`PxCOTt`|ns zqq}j1#ue@h&|~2Uh0(3wohRh$?8wN-TwGl2C&IpMu1_>JH#LD!`teQ%WywB}520=* zB_&-QtIc@%63LzhMt^2zfZwTAk&iw}9j_vRdCV|Zq8j00;3 z9FLgQo7zs>*~emALMi25DU$xdzNHa~qfH%8CTHYDT#M|6QIowKT7%E=&0qp_g2ZXw zVo{1uNJtlVVi_VNcRo3KIw_g}(H{L zq?~i`J_Aq^UI3r<@mqR&1MnXJGaghl6IYxm>D%h+5X+?j$3An{Vz}EQ6_jJvqiXbU zdt#-Zg)@VqJKu=A_+D91iemZy^67%Do2Fy6camv0haN+~-Or6$c6FqdcNw2DXy#7O zd1PjHPh5RzZo^m?J8GNVYg6&(&r)?Ycx@aV99AHh44~XWQJ;RXB{0DSFCi%jA;L6N zs@REV|HTFEu8xA3146HLcRGaxWu}gr8tIEW&}yP30f`Cm2_LJgk6{c3QWZPZ|}~3jLdx@$m@3w#JQzqGDnn$MNiRKIkn6BE+Pv!5? z<;|+gOyhX>oK{$G{c2ui65sa$d9ygU`lf^Eks^1u{8;sDG@?<*KA4LkY|z>G+H>TC)I=#5CiWW&IC| zS%AoK|G@(Wgu8_W8)ADDq~S9R?i+|O5S0*y5mP`YHo9dzZk*KF=a!9P#^u#f&uW zu&B3V%>L#kk6g%2MBo%6MB^iI9QbBe>{q~Wh;c_Mg6VLuQke)>o~;q)tuCzd8AYyZ zY)syGj$BTl064Dl(3(3-LUGH>OQ9?}8S)eQO`u3aS{hu+#*oV+5LY!hew@uG>v(hw zzIH=YO;Z62(YF@4s}cJH7eHJkz?%I-Y-g{kIW0G=*#%b`L@0SUrg(1Mvq7zMqn+vE zHD11sN6jI2(E$WI21SoGo$P{A)6(FmtCt6b9MjcwH3MmbNe3&i9|SizGw)VII9??I}ODSR0X0z8V?x5y^f09Zu z2)uw3&~Fr1Nd0vx$bJz%GI$*ThEqV$jn*@R-V*BV5VHC54L) zWm_2>7+{g{F35b{7I{j9im zCTRn13YA<6zQM+ZG*IZ9OqKRpg^LH0NldDJzQ2A=8`RarW@l%IwW4oBe4n7UkAL$9 zC|>mBpXz0g8gSHGYcN4b3VdPA*7K=&aIRu)ub0Q_yeO@1Fw#Rs2 zjKzaU=CCjHR$|<`uY8qmB>sfK%f)9T9!i$a4pi0gU!|TZmsal8o1lN0pS#_5k=GC( z>$fqfgo%fz9Yt6l`@C|Tx~!wUo%97hA}=!&^<4Jprq$D@PoaO3O5mKq{P9W<@b8*ZDu5>|4+W_2DuzDU;Jv|#*4?^3!POrs`#>< zoQuMR(v%&wP@I(?kL`y%Lf?w$EsB~WNSNN@|FFv4d<+9hgdil3u5WDx*OSao1Kk(h zgBAt`$d(HQqe!@NCXz2IJRC9bqrDx#?MMblE3mS*mh;&TFH`k_k<*6{?DWG>K~LDi zAA)-^PS9ysTG_B)<&+z&=G-M+iKhZIk;cm62U;!QrT7P<$1Er#A(t?TfyBBSu^qAl^SXfQgFRV&CU86$I5i zkjl$;&7r1FOtN-er{gd;H0DlJ-8m#SO$Ns}@3hK#OUE~s!Ye1B+iqf}#C6N({Y(@x zd(>fSx@P$&SN>@6T)~?csR)uDzY~^Q-NGPF10o*a(yX884!AJpXp7r}Ygou0Td&#1EyL zwSn^oT?9nZn^k!Wii_`p4PS$!sJM9hECDB7<|%a6z{7p= z)W$b7EcNW%esYgJ>)N3GXo7wauYRY!`6Cg_<~`Y$cXtLT{yUGys8`z?5^_$WD_xm> zlkBE1C3l6rd7<&adZ?)3bDb>k;qmGSF5mQ6JnwwR$?J^C1Zk3SRoA(=!XqL&lZ1(g zNhFx6;F{1Fc}C=gBta7XgWn+Vyr1=sPsODKae_QP=>0T?K~(;(@?sr?$9UxJntDEh zRgjcx4i`Zas-`E`QK8BhS(IBXU0?k!@4V*KT79w0`s&w^*S(}ho&mjwDOBlF<)g#m`Z&sJp;PXhRxuQ=wHP?RO}f7Fi8$-R+T-ViqOKkjW2U%@rE2 zO?pd60TN>B7nclo}AT0MJg;<|0CNU@MqMoCW?X#G=Q_it z%1U3lAoylY8%dAw&l6l9drm@oSpiVoGgm4JB1t!eMXXiE+Hd&m^Ob%^@!&PG;v-oq zhkvN@J}GQMFkT4qHzMg#N-R5^zJI!b4e_dt-^IosV&k{G>H~1?KDd^yFy+QI{k7=@ zqap1D^4n_>)KrfnvL(1b$BFe zKPzK1J6k)Ql~{85|Mro~k;xhs8m&kvCJ92GUW-7bBuZ*3p6s3I%xv)_j@#FIKY4>s zLc~e|ew6(DT zS+u)bTPQy^mJf)g*Dqh*DkI}!5EA5gO|tL+wtYVnlaEJua|`V0>FCt={ORfKQ1A~; zhQGX#}Tzk9I)O4u}*`J}^rN0NQqsb2D8t;S)j9+9>1s-vTu~GcKDNvl4 zNGEW1ZUqH{gX^nlHEBLVB}f+AfoDvZgEqrAvT08A z1Ly|EOM!~#kin&-gj9gYnMQ3z?Jm$Pqaq_QZ!^5krn61*ja5}Lld3rap)?51pET*x zUXGyaf|D(?<%QvLf%pEmtf`im`wT*UV+&+TnzeGaQ?u1aMH-w%lcJQkNDvFLHWFxS zy{dg5uNmr9TOZc=ba71uGO$a|@ChZIg-lpm&%sy>1T|jh0I)>bp=JA&42Cd70jnrT z0Cig3z9a$oJ|}l+=nF$HT#{xHaXI=n!`G!1qX2=PAEgF%7yrFaTq83qFNemNay7rW z=ORyb{3aZ=qG&Qw_+kUJ4`+3F=5)x`bjau!3H+ZK;To2hV+BGv%#*{mL^!|hl&Tk! z2)mQ-T{piLfD9Ol+utwrWdu7C@Za0o7Mdbx<5o}#wCcgwT0AFoB0+9yAFlxU5wSFh zPiO#%Pf1-J`n}yV9t0YO{N2{U-7ukm0`uowQe!-{>o@qWRXdzcsPuQCRw z$Xb9Y+WunOyVfD-j@gc@5Ss4<`aFJqYd0N(d;aWB@K9l?!LGa2R}Z&zI$F?))W(*- z&JpsKc!1HUV#=EP#|4!?j7gvsg}R4}T)ld&WEVzd=sCfBI7^>7`CMcKP4irMFA4|I z2yzgxos+Y4yZ>d;oQ;onu7IfUOMP9T!V=9NeBLLK$JmJY;U>7f%McDcrT^zANanL# zm=7r3EUo(Lsn55XKXP&4_|G8SSL1uyj4$M(r|x(m6+j^6H>l(xdzock-O2_e z(6zrIm&mK|W3J@(cbkCL3k4+oJTMPoc&OH{25kKFbe4*WKd-*IQaYwH+-c7!DO}xk z)%SVA17$2eE`4cp>F@ax7gD3A2E{IiiafhhC#&8gExvs%Jo6V~|42|Rj+us62;MWw zPH8@In{DlCg?WKAHmTTw+meB z@uDzF=4VxoP#wY+%ZJ_t81vwWfEU;CqmAKhXXRGGr)h`5O#R#=F}=qRf?r0b-T0rj zK!^Qob)ezUo4PqD`$&qaVk&@aPW|O@dz;sKjK0g3A^!1<^AhWOU)K_n*CEQ$THDLh5dtb2`)M z5P^Z`22l(6-|He}mCW&BK5&+A`1q#*H0!O`C_57PnFZDEKbu5W8r~DfHr%ZDA8GM1*oD_K`geu0h?K(k zREn-3O*z8{E4cb0=H?IFSV_Xxh^YDt<2*l(>e=*tNCKXx#g*L3AWSpUcnt+e) z*RQk0FEppXU&ue((XFHnF@t)uP71nQv{*ri*z$t@M^xhlza4N+3KSqG!IWV>A#X&V z+GpM6>|$gq)U9|+^+EU0m07*6sFHjYeq>dFP+DcYlWgggvlc^wbl%d#Lu>6@g`no99WvFIRa82QXU^-T<2^PE#h9{0Q}iJoo5x zB}m%!zT@ciiEJhFI`qenkH39$tvHbC7)@NDpI7T>|2@QC{cn7KOV62(D3{=6n|+bz zrXu2)8S&?LM8^vWfypqk?flS5VZ*D~+*^qLdl^zG;?%lKWH6=TmVofeY}iM2m9 zDM+FfOQ`61!2|j6BdB5}FuOUkFK7|?Ew8On?GP_sL)Z;X&CL;UVm9i;#_J$kK)x1# z{TQq&b*+GJ<$2x#hhSHiWBZ%7S3N>0o~+&m|2CVMJS~i@DG6~=Rx_u9r*&rEK`@1r zK46FI$PJUZ?sY}w>`26%v?^xdte>Pz->>o+YVaRwXncPssLL9Ts93`X1#-2~y9LpQ zW#4%!-#2@VDu;fe-&r&cIEozKzM+tkGt&{EQnQ9!Kc_*DU8nqAePW~57%Oto?>qpbF=zxL@#nXjjwN6cE_xcrNnvDsLU(puealHSbD?8L#1r82h#av`o|^1CL=&a$xf`4AmEpFylMG| z&*&D-`N`I(I%hBBF)@^Pmo8n>nz&+1S}y=%Aqd}?Ux;=^<{|6R3l}c@`+Y?K%>|3d z@wd3i?CEZJ8p!zV5kJkUpL=%2w781jwsGViHY7!7z;b1ok0;`G<;D~hw{&L_>`xQB;U7d$Zaj=>w?=yDalG>dHX?tZ zhrIza*{`NBkE9^EK#%fCk18Yn5DFUvbFltdFC5pSkc~f0`m-7$$*|TiF972x*1D_= z&hWgvypjRqCkza<9RyyarUGN%GQNAv#ET~%Wg;kkXdUUxz)91a2?y(Q1+c8k$ADu) z9&t>CC*qJ0^XvFaLTlb~Yu-q!!3E0fK=T=C|M%k$qba{;-{s7H|I4M{Co)ceu~D{uB`H&~A@ZYRrL~R6q|jV<$Mz zL7M~D+M;kj7)0DXJZ1$=$*%dBF06ohanvf2+$ z)*oG+3`nc=$qkWSd8EHNWvQM$bEIp?@8w@bK*f;!@+FNkxdguU+p-lF1_ly(iZ>d4 zLH>(;SZilG!DEfwvH9zG;HX;ysk7e1$HzyjOA9I_c;+2*24^nn%lP*17sPwiMyEaa zYgN>zNhqr{VRWdXZS{HZpp~Ll&KGrw9RH{9hPAU?%Thr7Q%FOqeN0zt*?5voZ(Wow zc1jcf>a&y04NTNmqb55&^Vnz4@cb5Vz*i)or||EBBNQZl{}QA1t3h3mBMFT(HMlZ55$#TdK2~v0VF0AQfj9;vNJj$DAR?%)` zpz%tr-tpzmn+57SFTmX11BqP-ZDJgoK=P+P(1lm8?a?5JDZzig{br#Kp$wC=@YBr> ze#m-&={Q8orO5@>K)UN9JeiytRp(jmpGcFPyb5zzUS2G@KMXp#Gv*>brt7PJ2y|B= zm87-f`K@`(Z3O)GsR_OG4Z1=}&&uu4-D+%@QLrAM>Jja*5m!GpmQiPep5`y-k&(GH zqIBcoHAhDTIn7phTzY4!ByGN==duB;HN(Bg&BJpi<+IC**2OJxJvLMPg!@Ru3U}~8 zLBPXb0+_$+A2xO;#f`6+`jK~S#n$_ugbs?A?FD$=sq*gRemZ*pDD>Yp@9y=Thl7n@ zII>F?3G7RORv7yd;z434NcEWb~P zF(PO#(aLwfWnsC`J;7%=Ni9?i$;;pjxOjOMJ{xdKZMPD=h9}E^mHUxyi;^LqRZOjWkoIW2PV@B$IvKgEG^>^$agWnhS$VI>tPKDz$Wl9%2 z>GJE~ZO)t)zY#em@4Sv7Tzfsf9rLPmxkucj!2cxSaGAGqkN0pjN-etl51bcuY3sbf zQN+?T*BO32LK^T~zYaG(-1jt25nvbI+}H>@Pv(cGOG<&4RxdDK0e(gZNDW3!_?2-K zT0wRS?M)lOZet~-2RaX~@m_eaJV zcx?%h_s%-iY*=qQ5>>F7B$PG)734A>H_aWn2+qBor%Zn0r5_@M6MW#Za;Cc+1+PSA<`f*1b!_OCaXvZYjEbn+ zKOvCF>tOrIk4_k*%9oM33OjRHJwo6xWVnK&q7;}{su{L4yE*JceR(Cm{Jx~CD)M6p z-zhs9)}#r4qH6PD+}4}9?iA!ac*=r~!b8j19aJxivlQvSk$1o9v0(Is(r%ufk9S_X{hj-{ zm3k|)3*8R{du#tiTpeb6M!p&+)nJnw%6L zIb=m~@%gl7cp5{UL>Z%Pcx;~&7ZJ_#cbPQ2std@ds94L*XA<*3Dx6MbroYZ)v2*3P z7s?q_Zv?te-(4dkGCbeK&)H~sFI~ErE^IzzCS3eX_OBBY4Jq)Sb-9-XxVcID;*($9 zI8SXn(l)2@EvI5Cl&?8$cu>{{TtAy}{uby89_H$RO+$kr4dE+H>rEhci*6^>d) zkBRqY?1swz%`mAD<}*v|9^WG~eN|cUOdh^!ES`&}XQ-)c`%y3}^8%@+RLtY=bPZL5yD(~S zCw;Gy?Q1wc^_UqZlt6;}zi(NB{SeO_)La7I-&FXyMx~Sk2#qNOMIs(6*%0LBp&Ue88WY3aH=r%@g{0pmbq*yxQ^oa5l!ipac@b8)r*_v^o8T4<76{(cVFDft(N+)Ttdq znR|<2)k~unJk}P41~~1fzP=AB-kN6X~C;{w+#8aqyt9R5i!uv*vpQ?)Gx3Xz9l=MhiSD ztGLbnN;wl&PznuhAXG22uxGO^$}<-MB>`y-Y3j_M$qpW4`7kJi%}^jHqS$z?lWWDpYSgZV@=W zACy_wc`Q!3JGQ)3>rx!JzV$GBOT9fJe$a7wGj5} zQl!4%^H)temsBmca@8elzQ`PWOWU#dxmT7iLklmARpc8x1$N{gKHsnmPRB}Fvn zt_Uo3`_p}8sc@e{lssNvZ_a2H7vZ_jO&NxAkbA~db*mwRlW0X-N9UzpPRJk_hmkyT zr$<}eHxF;bQB>iLAdayjX`q?N!**8!cnnBrIRMdueaT{T`b|LC+q;aUdD42eI{ZEP zZu&t@fDod1`~**A{3NcPNhAQJf@dvw2@7Gedo`V*&ppv8_zpvN`soe8J(m5WOuqBm34o}$}QZ`IkZHd zPCyfiM(ChmJYOfWF33fyPsc^^natxSZb8^bZb{r>ecAzRMBX2LmwYK zPfuGwrYb&9%+8kQBYNdY6LssgYx$*vp+XlIZ8j*pK79CCr$-th6kvH=pUK%xNzPK~ zz9NPmo1>;wZ1Fx%)W<8KL4~yWf|M zkjF!*lb0^@^HT|2gHd~ODwJ@VNkWe*Ix#6UBbVKkGlS9Hl9G}*h)( zD{AJNo{rU-Q~w55>qs}EdK_d zaFLXXsm39uLOun#uhNT(LU+_xf1eK7jT}@icns zI9RMUH2B}Ilch4&qJ5Xk%O@%5p0L{LZ=PFX?=&n5FAhR2n3xDoV(#;#+tX=K2(3aF zkberrHX>8@k?lMoYQ2yI~71;hj!W9o6jM`ev_Hig(ug~slJVQ^`pFQsWM zt*l%>A7$O?JF&$2mAO`;?DQuU#l6Qv@)EOuRWPAqS8v?-c{374v5&rLMTNuM!2Lwj zFaND(8n`6mO|9L1GlrT`7?3kVRJq76OqVW^lafA**FFK=4vZloPW8P$ERGny97*US za@~v-EunCtE2|w%asD)?vHq zOHA~`{Py`U|8w+|I4+J05+v>fq#(FZEk;aeypX>+eih3nacjP$UJ0R8{}*kt?xM}O zjXOE=l1#nbx41!J=HDA=JAUvv$Szy3)}?~=Xm$bl^A5#`grI+P95 zH`#clL3GtoL#(57*!u6}BeS&Q*`vDdY(A>=GQZ=x1t&qwtSmLAB~t?3<}LruABnY% zOFE_&+GbeA!$GnzR?wKY0Acj*r<3en99(Gdkda`!Pn@^Ke%Cepf{Kf9v+~iRaZSLU zUUJvJhl!_xUi*w$yp$IZQZh0lu+yBJGdXGbsW<4uuS<7!Xx$N{3hJTh(ui$x?9}8W z9t9IMIY!>qRY>G97}79Zxb>?wLB~)}Jb#XlUfeF$jaJU`bPIH8P9~Exl?zz-Q(u(G zn0>R^AAyLTjcl0W!Og`!Ri)7hyB+7<3Ln3y#+$4G!!UwFgpJ!J2Ry z{~R|L*O`NO63GlrC2IS!M^Gd>>oO-}bm&dWL;S9?c>IK9ywvHHx!V0s=DDxNt&a5> z2l<~Yp=^6~=>~bkB;b)(3yJ2T*!Ow*bfS$4st2a0|Dv_F^9*=kTH{wr>k~i#{?l-@C-f zMa1~!oAeigI>s^Ev5>2XWO#TEGl=HTuhbXO#hx%dk!l?eF5zmdK^l~K9`&3ib>zr5 zHs*Z!f^o$|p{}2Ae?~wCV+ia@cUv1xgd(EeW|8ZVL<+%-u}5U;I7;J+Qc{?ToiU;X zBwUv$9xA9B5V8Ze>etdggJdml`q)+yVoKA&jm3SQL29(Prtf70#keJFGZH@`CB@Fn z{0C9cLrf^>8stXr$SHBowmZ#O)!;3>P*Wi71#0?DIAdzE*#(SE49*SJ7me9$X;@55 z09gZ*f^Nhe%Ez)iuhI1Jk&0@TPZN>hX6z%dLqEs-!2E)49-IH^6IZ+%0ai8Zt_2mA zOJo}dF1&DFqK?~kW*MJRf!tA7aPg8j_b{Z6~* z4gznwEu5AF?iCuZJQhm9nlj4zh#bkv|2qdKvMeb+uB?7ICdTu!xxb#)T12mJMQqLK zetlX-K%vJRQI42H`f<-@+Z|cynkRQ1MweVeyMCZ6va81p- zn(Csd9}B{C0Z02k<8!j%r^+G_{wRc0ht-5EJ*FjS=tMcmANeK^Df?-6EHDrTN+9w; zRS_5o-vr??hVmUKk)b>&847=OZ}sQS)KDok5f|^^ezV4y5K7e_?J)~^9@(x_dT3 zp@{9cC;njc4{F}vy1y5B8bfd6_Io~^EHURA(jsKG5%{40pB9Z?fhoNBis?N_=I@ghd-mUUJE&Rn2L zQRQ&|z^CltVvmgoz}#>l>gsm}7mL?P7hkn~z~+Z0l&nr=cU!2M2NP*MMEH*>NI3qv zdyM9`p?uD!YQBS@7(v-04^(V#k?kO&c_>(gn&ujUmk=4vtf?EEMDxF##iZa_bpfj{APP7aT9bi)^poc_r4p0Eb7&>`uy zs-OE@v6BB0lMl=hTC$a49=940E2i35>VBPWHx)Gei z)j!_7=%r}_lJd?ZXL`PyNjHLq@ z)F&l98QRT!|BafQ%W5$;cpmyxMpl*puO2p5Hxd@|O8?@$NS6x?&~_F`Qgd>RKacSd6W{D13D57=B=g|8aCnr=4Gc&W#=B%ty8}oJKK6$2zFO!nu-psEoDOi7d zCVzFnVNvGL|8zn9R3c!(c6UFj6M-|XKTacJ+z@1GMw0DOcpc(7$2gPXC^ge%7#NFS z;D<*)%8Y$^Yw5f9hNaDl_Qx&|<5+iS=AUgQH=3C#FG~FmRPg}RCjLO+6kMldUuzFe zPW8NMx@gta)jALuY}iL_F0=_33Hk37ry3IaGY?6Y+Ki$rp~r8-tF)aL zGOOFAT1TD#(bc8A*xuDnxY=^9&VEs?`)9a%xYw>T=e;K+s-K-!y-$~^P}yjc#IGze zTfBt0s>4*p@C2j{^z}E;W-i{y^V6hF!gd2U=Bt9H|3Z{wB}(M4Dymt&l=dYqLoODV zq{t{-bJ8cCNSU#}^PQPh=H#c_0|E~5K>pD1>#nr;?0fjv4t`WMYtW=!H*XjHf(>6E z`tZTMTCf!R!_f4;iL`~~meuA~(!$KJ+E>U(NiW^ICtC6Nyz%?(ZTHK!!GKj# zB334ZdjuKwgUFAC=on_{zoX@D?R}rMZ|OV`VN6t;c=bevP`^pP?DJ7@uqEvzg`{M{ zW_vP;$Low#!QJL-ZWs9+ZBp*uePHoJu;p6we%RiVs{8Wg=t=I_$U6wnK#TpwUAeKq z<;s(EVKeKLRqJyT)xTv&qW0F_GKZfPXo!OV#P;p%q3IVjTXLx^WdR569?Lazb%tKpSJC$hWr3E_lV`pV4iD>WbmoH;a2u3WLu7d4Hgqz^D zVcuN=LINcf6@WEkb>`-W-eSiuhxEjES$Xg6b(t1V&kv57>}@PA1e|rW4UfpNl2rKE z4XzltJ7s1%Y7iBwwyasC4r@mm6{qqbrV!0 zbeqqsD+-=o2)M?ZQjtHkxLED%V%*E_PW(+c;fh$cjOmJp6`I{r63DbjKG+PR?T(>eq#0=bQVxYJ^Mu62B zuQ{gh+P>h7Je@vZ)3JH_aq?QnKy1d)#l%z&-P<;nUxXAd+L4Ni+u6;Xk4`c(PfGZh z6CK$}u^#2-^)E4MR7r*)u_gP}TPva0?c*-;fgi;#cE72l4*Aj*C~lMkj60MPoJ?9UD68y2}XbEn^~ODJ%^aD5@32I$K! zqooYE|4kQ}*szN=Cn-ISdU`j@aPf=9`p|hk)n!OI&<aacqzOO;;jx^h$(O{VXd zx>g$i+Jf70ur=SQpX>PIXQ&=c%R?!y;PIH1KiyRM8EabOIoZn8YB3YfWX)$L>-Kd0 ztPbWodHd!`xVnZS5(lLhx;sBVAAt)`@%lrq#89){b0w?i`A?ElepR#9zr?G_FW#R|o>xI>E8ZgdEt3ty{?x{d+__7ZMT@qt4R4Vz5g5*C`KwGLfA1e zFmeHEIBIqdHS{wdpswbPx>tnZEG}w(+~-LeHJm8Qh8!hB5pC1S8+;5v(=Ioh%5w={ z|Ha)hxd7KJ9b|r*%l;)1`rl;Qft6B-;qw=Sb-VZxUXmz4G_U*p&;!U4je)M8JU?9R zqj{(-{S`!luC2W6Orob{dD+T86r~n5xZ^h-Nz$3=f-&Tip^_rXoO}>gPU(!athq{; zr3pJ+t^@$q<(#6(1?rBu><_ zG)t2%+{2NbHQ^~BprtmK==+-(M5i6FH39>@Y&b5dIgb}%kNfBB6ep=Bix@s&EKQBg zm;kWU0PW(nhc|F$>+0ZzBY@cf$!~W<1G5-jT3t&;iWZs3^wN^dC3Yt}C&fyDl{7N6dM9CTWLpo5TL6 z8;%7rqaQBd!~y~hu|j%iQl)@%F`^;_H(Mf#fG{iF6$fs=!$}w;v+eRK=+!s9?b%n5 zZVa+GZCeHz?H@?FeNJaN^S0j~eyDyChEdMyVt4T~&3@+6aU5G;@b5r{6V5t&dw6aa zz9s#_8q07g_W&9P)HR6Rz|0eny!OEmiHqiSbn>ju;}PQ%W0So;-nzM-ojm~YCkjn% zkGW^}r@unho~+l706g&N{N?0flAd;>Wrs}oQi0$PHU3^@^>Ly2iDdVP#x-R=dM# zPp6*zZG0||oe5c^h8BEp?aC`iw%6c>jcj!IJXGgw#&#v?IM7h z-`2vyzjuCU2*`Whq8jWHl55-eJDKS^L*&Lb3NNY7RR$va&h4*Dy^!* z_JIWmK>{elLb!lRwCt4Z^v}fSrn}R(rKAuM03b^8vUwgFjd^|Yd_Ba%FQi#nX*E&8 z6|MnEtv6Si`a7`0l@~4oR%cS4ORhA+WAQoo1tupG_TA`A@J%PYCse_A#zL}n&U$HW za0Ci#zz~HBD`MDS1j89hAi}{6`1n9qIr~4ozWsEc8?xr^lAcFF#%3jw#KO7X^ToNM z!l05OsbX%Yp=A45DAZ_bYr6#vNR$g=NgEzH`N@*eCyF0{y#TB61A@HJ;sv&c~h| zbf&Vc#62~(!BU?I0Rt1Iq2Aot+kiw2CmD^eDoKs4Q`5_8^Hme<4nGZgRKBki&98GR zgd(k_oJ!KF{5FmK-$2FyasO|P5q>LN1B{1|r^R~puN98Wtc>Io3N@x80VqdYHx_C< z8QFxC6iuF`>4>+%LFx^uUGvLErgunGhLG!P6UQ1@$oE3}?qaIkcJ1N5+No+-Tp*{S z`5!_40cijCH%b75j!w+IOd)61$6sq?NyA>Orx=su>!+Y^uWA^^P1p9%bveE;)5l<8 z@OEzPehJ^xQ$Ah5<91oYZ0sgOptk(%9HJn6G~fJlHQ+&xWrW5g-y<)lUHf@C0AG03 zZGRdQ&QI6Or+M}6h6XMB=N)=BKt04z4B$XwZr6Dt*r7lG974G>mi}o|laty1Z74YH zRs|Y9A~*PZ1}nfKc%xlgR{)iRNYPsWwHuuTot4%M3dlSS3T#~t%Ck-_(q4^a9dk7q z^6f3C@q*~EEWEt1C#OpLJDz| z7c;&1R$^Fi!mYlmMOBS#>HPRHs{aYZd6o`ew?!&qz#UDDO}KHobwrFqloksaMN_7jJ{OQTb)B4s5@gk3)u$im35uAR_Xm)*~MstJL z4StJ+g5EP$TEubR(aK(HwR+UmI@P#+H&dSQ{Aafxpe)k7oesYebzQ&f(=Aee#hMUKAhsSlB$7P$x zt+Nyb*~QRIzN=I#vV51*b%)z6C5;hF1#W`V~J|3Ppe-~ zs1%AOQBVg+LxCBOBSrR_IuAfu07~?(BVc)pD9~d2ve-~LBw#u4Z;X`ws&;1AgVKQ^m+G|gm^72m0vEBv>+G~5SkGb zNt&1_H=F2^=ztoz8!Dx&ki!uq%Nh4yfnk8jB*M?jOHEstC2-eufr`)5(%Ry93}2oN zf_z&arU(^8K>0Zl95&tlO~F6xWY{sc%0i%0ggI$x-q^Um3PDIk$P}{O#g6>oQ z%*rpSSVaQaH_)3>f{D?0qp5#@j>U8S$^@>G-OSYP=}X{8>vj`32m*k)kTQwb}RsjLHwL>QN%;#CQlFdrzfP4 zKAL>G0?U?XxE&&%Iz?GCCqQT3H>)}`I~^Y%PfbTRWzLzSXkMvFE0=oRiOS~e>}(By z_-Oo3mLFCDzA~>DYpA?oD50u`0o0q>Vzom4dojR|>u8Z)yr zW{2Leu&Sqwp{0Rz8(}zJb;&4)*i!ive~ zjegJ88<>2_c5=cOvHYr{L9shez_B}$oR(UVv%j1u2aGd^^QSnbN-0I1e?Y!sX9m#4 zi;`~Q?&A}FNJ&rpH)C>Gg~pesWW`C8U7ebea~rE8sj<_(?R>JZW(@+gt_+aZP5ZJe z2w$slRpl{?k*QjZPEiDF?x!Hx{4_o;@X{nVOUNye)Cs`%*JSw>CsAA-5=Zz2`*VF6u0VUMii+ zkE+8bS4P@i98^Xsu37ZmOo_u?!a%19#cQ%RH#Gd+!^mLS7WJh3xz5}XQ1(}j?A-cQ57bD(Ga&c_5dRYh!b!o&+}&JXyDpL7 zJwiP_p`MuD7dv}E?Y?T2rl<3~X&9LnG9RbMzcgJn@XjkjJi*yeY!n?F)K3iaSedi` zY4UPkzq4@~tR$-~!n#4R> zhjTa)X<23#GSNe*ju-D^w2UFY`!=hJaTc$}Mrdp9LttX!K17b}{zfon72ofO9>HYI zO#HIZ6OdTjQ%3v;`tFlUt&aAOx>>erdG})X;ZDlGkP@?MnL;a;I2F`XYzeuc(iCNa zQcPkg7kxOMYItgFLe=e!jSkc59M4-o_#)zq=H3rj6Wx)gd-kqy*;5Kb=zjG$n(~F1 z-Vs-(78tMQ8ygWKi~k@B@AD{Y;m))fEX$PJB1`%!T%1`~pxcYnBSqEHc zQMrk%GDD_TGGG}FK>MWz_T*KulH2&<9a{> z&09N+{=V4Cinn*jlSecO-?$MsK6~KxbMSDlOXBY6a@{CN_V)LPG@I+?(4Qa1oiyY* z@P5FefkDf9ZMpMIKg4sfL2~~o%04u?Ur>4k5W|f7@_8C}Bhw|u@#+3iBG!1(T{Rj4 zzFR!b+O*WgtJFm&9X~iuG9kAx5U2W7Js9k;2Y&S$_DLWcE!o%I=p$#S^Z21{SbUCL|<$7X%A>1kf?B`+3o;fZ*akNjLyd0%AP?2_>zH zkEUkPH%b@EFZ@#^2VU$t@>@;S@f)lLT0+_%Ga0^Y?E;(A2n zY+{m3-^kcl=6mA!!;Q^>Jk(-&XFC7z`H?9)c6LUD2zD=ggmg(>tN8D6>Ac@6?TcLlUefG7^2B1srcssNiqzzfvs{iOe) zS(FBGXKy%j2=}53z2j!6%>EPL(X9LIi0V$v&G+L|@yc=-Ldv!g0eW9FjPpi!0v^bm z9ScrwUXUH3KG4P ztlunK>Vq(sudzHHYW61X{l`rfC^C3y!)d9Wvihf4LeEM8G$=|!!d*lUW)^MsA>3E-3 z|IZT>#RCAIs2Gtsb_Q8;`+pGW-)*lq<@KBDHiwICzQX6%dcy8+kv#P_%MBJAo%n#8 zQCHbePFgySK~|r7yZ5b1h@EA_~ zY5wJ%B+oWc#h*Q$Yc$hZZ9tR@0Nem{1}Na_>dGM)(N7(aC5?|Cz%F>*E|`&Egox$< zMW=_m^gE6ELOdf&LFB` zxs0IsK*c%~b(Q^q}!Y=MvGHiX4X$>SVZ|}(7f6;HZO0GXx!Lrq|gXW(3`pSikxJ_CHWYyF|>>M;s zhVF;S;{g^@(JUir*I_1?v@&UBtYvyy>j~M^|2;fN*&!8|0LUsPF)xowajxwRx9#Si zZs%*9D}eBSnrEN{J;H!$esO@VyG>~7Ca_e}!0{A`+p8uprWrK@0v2%=m%W_>rGs0S zzrHcHDl)pLH6eur_0V?H6w>CKP#>WYYUcqZ<>NPA0J@&cm&w@x z0COjnr34Tn|=z7hy5d4;CP3If*CFITLwso8k3wLWVb6G@+)S# zs)K^Eao-_;t^uK>zx(+3$M#5X?0I{a6aI#`tFg9c^SRUdx>izL+%XkL>8wxOb~TH! zEsm+s%a9_}*=6;lheW744pKgx$Oj4%OrmUZ^r@e9|0?8t@@srTXZXaktkLfxG#mv9 zoHgF{MGo8;bEtAg1u(?e8!K0GbJ6s1AEpCc8IV>0RN>zW@zxwx@~Wd|%%l@Oujxe76dCumrie@#cv}T#+tI z%gSD^r=l}6UeNS);6hox0D%iwGn8xmHAqB-Od%)Vl5}9Dbtc z_OEBjn4Q%K*Ma^k0~gGWHrJu=_U+=MOp_?sy#>M_r}SxOj3%3K>Qe>qwfrdMFu(cU zGMfGCCYU*I0wWtxO(z0QtF|M$EHA@aZ37z15TL-go>oz?`DueHg86Y2Uu4Adj_mM2 z2!8k%#W+^GbxeRRRrmmEM#bOvO*D%sQ;RU!D)ZApk*KRg{qR)>ods2vr-Ri9M0ni) zYP)qrrJN^+3E@TF9H_=eF(vJD>fZ|Nm89( zph`>1O34k4A6(Z@o7~qz*J+Lto8OB>6MTlHN22kE!8S276EgxGY6JM04+;XWqx^Pm zcluKLoHM9CXcK=J*O&99HqF|f*|u)8-yBS8RX?9a-n@lH()FOVHP)j;-BG}`MAqY5*| z_5=ban_W4x;P~g?y~rQ{N43qf>JI1U-WiB8J_%w44249N6gYGKa5caV$q(>eV?o_u zxUdI5296S_N{@HuJegJi%sX!Y!&8C1vY!mFcmN*R-Pu~x)=I{YRv!U|J}OlTR2;`? zwA6@iDzObhs!9Z467jA3adXFa5@K`TWVXTr-Vse%X0o0~DE}D%`c+q97(Rf*Dqo0+ zhL#P;6rWgtc*L}k?=WP*285Rx7W&lykaosPpz4g6atIxUE|LCn+h7VlBlKn)&rvTG zPtzZx_n9-STtEJui9&-HK9T2T0OPyLcno9da;>Eq-KpvmzP|Ad;J}TODH^z2DWm}5 zM-{Pl9GZS`y#}O=NW7o!;l4>A>mg;pJXxWFv8qPaAF~CwG;m8`uU+o%I?2xO-(AO- zrlt}(-vA(DeriObR^&Hc=&`*+@ExV?st@N<47niy#oI-0r{nv~T zZNWW02Sc*Y6xrOl9(`;Y&|(6KklW#Gtqpc-LL$a7T;V+dtkbVAPXL&Xkcfy6I2|yB z?m^BAlasK*Z?iT!287Uxqq*`B+QXgNBQYw2))k+A*%fj3n<=lN!3vwki-C=go0W-a?zftpW-S1OWw%-6jFJ8y!j4c9!9#tVmhc!&+hc!K%o8p< z0%@G;sFHA6^j=yKt698$bo~T4P6Aer_D>gl*Y)Lngo5OALi??S8F^9}<;@1F8d53! zB?#AA((^utZZjDA(1)DL=QB!DDr738^DB(f@?$+x9IwI(Cb24ndCeY4ARDYkqo)W$rsixNVV`&QvyqJO4Itlu0u91j0iYFw4%L>mr z$f(J}bDNM^LtUNHTF_}1O`orVIl#`@X2Rvy5Ufcs2`*y<=2aI=yUs^zPd`NCkn&(u z4BQ|=5x9w5RwO>_d10t-`+}Q5A0QvB5OXKS#SOy1g|HmjtJ#fgr~sSy+uRM9m8E>9U2*G1qd|6J>$q9mhXyS3Z=sNqDcH)7>8 z^Znt(JYYU|)>Y>pbue#1a1tue7IH*<%zYoVJ4)&4QroP|?rLCbt0HTwGM$X@C{-GM zgpcz?18qWZ&nI>~onsJlZr?AEJ%?}I3o%%>F8)$y`9o*ygp@6q9s{Z0iH5mY5w?u;coFz>F( zJWOwyAu&U970VHnatsRKQ8l&oQKdvD)qDZ9KO#AM;YRb;dhcdt7XEyhT<8eB4@GG* z^CPouPvxEW=M9O|0zmBlzEQRMIgI0Nxjp!wWaIUS!2*JA#mP*Mi;cr191*oqC(4;P1X?4LTr)=V~_~;EFsecuPY69Ubp8U>9)05@AY^=H-7nNBrnQ zkJ)1Wya@YaOJ{>gkpzK=3h6sJJ7YBcELrvmIlL9-_&M%vv(?z6TZAq-@QQjsnBHO* zyVtuCw&rMFUqLR17I*kr`2i@UoJvQ?nJK<aZn&7ig`D*3)V@q2l zfGZiaFHDe~L4Kp4#03#Ktdd{UoPd_(K1&&?wze@#_QxxI)yEdj^bOEawanJ+jSNNM zIlNJn^YZ~E{WllVP6aMv&$AXJPzyj?7TE@%0Z&qc??uW1(=`#AVp4gzowYUdv{w5R zx%V|z(h$P^cdBuK+OTcUyU!|6g!(rjHTCwiiQm#v!ok>jE4g8oD<~PtjmJ~YSdwBi zZ223N$I~CGED|Gn^M zgFCcwdQLnZKMsAv_Z$I|Ug<8i889lHgMi5FE6jW#EK2svN|gyJS?;+43{m8-MNAh= zo_3Y{BM@(J9;|F11%V=NiB-19{nRhP^$z0Sf0f_^USOy;v$&2hR4iab+i7|A?)zgz zjCsG#JNHp&wmZ+mhtxdI1%JQ3u;Mos6(Pw!8Nh{bkid~pyc?)MGJpEy44kOHLv|>V zh+MFPB`h$J%(>IhC4~M)2)1rH@B()$5)7Znd{u+{A`@<;%-|($0n%S6YV#MIMh-DK z2NXQ|TxtP5Zn3XM=N7uGI!TF%Zk~bmK!N7Ryw5NQ>f_6RR90fWS_64D-q{qKN!l86s(Ee@&U-9L=|J(Te3t2cA&C z5;R>lBwYY0_p&yqbdZfz$W7fF$nBS6<|(26Mj!s(sYMHoFtQ_0ipJ2}gAdvS(;xuc zyG1s@AScu3@!-EIW&0W!ulo&O*Q3MK0N5LH0-B0 z6m~7@7?}pZ$MftqV&X@GRqJSMu-W7_U)V`#u)NNc8$EC|zN8kH7{G{?mhz@rW{xzH znNZGsgV7s}439)|oF#VA^2qyYcYh-=9^3@tjNz&20A`jgJbpsfsQdGt=6be1LKzBi zy$)&!x*AMNwezE8X!!{RHHu&s9CtM>b6W&22ZFv(c@U?;9maTDAUpO0Z~e~E^4=nK>15t54s6A|1-80IO(a}fD| zZ)(YVndQU*#QYIqVV&U}?35Z$pU?Oy4@l87&PWSw>X6LWO`l~pm=&pq-}?pIHByP> z-2<_~f*~MIpO`L*O{F&j-u(}t7e5%Fa2i(8CdvtosRnBqe@WR8kE40FT>X%V z2hl+3%WLlul>7QYWtz-ZE7&@ZES!CKaFCIe^}i8&HXM8gS@s9>n9HlHoIaFmqcvLq zZpz2Y3o`ZvWPu>o^SOY6pu^KsL`5J^mx<^j{C{!gR^=^-J&LIq*B{rsu0~os+n%?l z#x7-pWLd*m3@X3}oL^E3D673KHqGmRtkUV~zbMuax^UXO3RO<=WZqsJ)oJ73qwgq` zq!fguK-c6*;~4Tne{4<4zMuqA48CWWO8BbYj@hS3jk@e~pQ#Qp`#d*At<)ov%<60> zOs)%FSXcl6l|Y+I+>d4%2z1f@x!I++$JJwtDp<@w$R0@K*E1*_h+BuP#Z483nMO!p zz?jk(narjiCsUpSs3w4y&|$s3HCpJEnveU>XpWPKYyndwBi#g-aUHoF_K=dPeY{5j zb#Rx1(WJ3)T`(jnmRh@0da>$dQ}8!+1(FRltrYga4M4{)T_~}{Yqqrgf)u`4v}rXg znk16Btd^JpnIUxXFfvX2VaNIWi7|g(*F1`vK#JB=TP8>}YBq!_HGG5vo8~Q=l>eZ~*M89&gTe ziejT_JeZLmwsKH`2d+pw1a1ugttu&g1N^ksfG@&7n2e@!1=tn%vh&=XQa+M*Z_ways1{(w9w7wJ$7w!Dj(^J68|(>43#fTxpu# z;_?o}N#su!%l_M^xM^MJRcz|OS^usnS_F9h$ZP*Z^Zv2GsnnKCQaW&qE758(g$Gm5);pOBtmv zb4{W~Q6#gkgm7pW02LTQu$5Ad`c0Y?lN?mcgj9^mXXN7I;>Qb`qPK=~nK{l!0G;gY zAgGHtZLTsK>gI!J(%e=u^DB)Ogxbs3ka+nGwkMI;%z=R8|)}yLXHFF;J zMF$Mru;)8`WC{Zq=Qm@MCP!Ez#LjQnB1lL`a3Vb1+$&5X=A2{_;3jX{Q>R2-6Pjb7u|lvs^x!aQeKH`(npa|Pbivi5x^ zwY|U2d0BkG@%!B!rb^OP9tH_gA{#iiTV)S_?I*xCnw9&APXO@?r0ax9BU1)m5+YEvFem9Fwi)xO#y)L1xN2LyfZ!%O9*w>Mm z2#u-r;rFp?3E|LX{>r2JZ!AtPiY=U4!m!22m;%9NHu)l>)uEj5iz6OawpMK&dkC2M zhgM20K+~C-e~riF^DJH)aT55T{+*z;uENh4eNRLrpEC{^7j3G8jaK0>NI(5Ubw#!$ zBPP4kuMS%yvO4|ZWtFp}K0B**bn?adT+!7QPfpSy)NIIUp8dmzE3f^CO5>lhQe-PM zS-Y_cAqY}rVwqh#2ppsqfj-DhZhnYf0uD={B>$7~Zu|RwCd;1}>)P~)$H>h=-@^?E z2e)#%Kp8;4PcL6zfl`5Xe;nn60+-j7dGS?+GX*hq4tBPwv2i2kV+G1cNiZ_DT!w!@ z1y=2n7=?6U7dZunY$zGJlSIR}yt(^@4xUb!E~$+@`NF9SYjMtI^tC7sR$W17OZ#E- z_xRv?z@@Q>xys@%xSqq_hLk-4;?^a9uA-upP~v&R$yQ3{#rbYDf4|J&-pvh2%pJOO zga)1S8h83t^SxZqHMqidxWmdzYE~$ElwEmk)pW;TKg)>2xR{#knWICQ%{{LHSJ$%O z;Cp6j>h6I73&7HRhd3VM`Gj$I%+y`r>^9Cg5cjJvbg5V%?5|LR4$F$ z#f(g1TK$S9SAqT{W_+K+JK+$`VYJ>$O=$*&DQ7a>=2hV2Tf3mhsEMj1j;m?G{$W!n zRzIlmfa@L6N+zzh_X)1Og>;cXE$Zk!V{o14YaV}}BNGMv5UyP9?bkG!a=N!ySlh6T zD6sp=MZaxNUJ%#C-7)_>+i9Q!gI3qnl;yokSgF~4lP6WnY{4oPD-pLnX}ln7fu|DN z6JtE(kVM?jEK&fMfV}Y$n2&fgz*ucw^{v#%b^FHgKR)lwXU&=1JzdD~*IPr2h2j0uhv}d?CBmD~`3ljXWMw;!f zJAu_H1Y^9x1iF}5T_=8H5TSyX*h5Gn1;5k0FGEQS5e|KCqSpDj>rdWPecONt(DaZv zNMd-AC+Zbr`+ZmIg7=$^s8X2PXw*O!s8N0w9hiSW0FzZaPY}I&{)CQ$1_BI&-gY1x z;+F$Kpo|=>DOS#p*ptxMy^L4KNG$%<6jaO%Yg@ozgMpd~8^!4_v&k=b(Y^I8=t&}l zYD9@-@QOvnugJC-HT=hmIG8M-(j@oyR;P4?0({j3@mFy0S~)Aoyr@4r(c0FwmB$ZJ z9Tt{v+_S=Um;jPY_0FhRHk-As1sac6VEG$5tm{DC7b+F;QApo!Hx6NgQ|^zV?GD2~ z67kPsKZaGcG>K5fRQeO?F5RW0eC5iiY^d+zKc&9yb-UAb7z zm4RzrcP`b25}Eay%?H9!e|Q;mbRwYQjb^=dE`PbAjVS+s9B5peCxb1M*@JDSBEDek z?(%sOjOHAgG2~2Q3xWXzj(ITV5HeGsJtt>xfrAy|eE4o+LQ`=QlcT%Nv2G*+Nli`t zkFe6W+X)#59@=%X);*vjoS8?%J4PzmkOZX~)K@rNM=FBI8NZW%L+~p(q1zO3ZUS-` zp0{qP`IbR_6aRj?F{1(S=8f}g(6Lj$B40XwHl5e|-)lnO;K5525(rl3N1!Hz&5$FM zrl1f0^?sL%Aed`FUTd)M8bZ)2rumDNKYcew@lPjHj0q+Ax7@D4=87S zJJXAeA#5x4ss#{Jz+b9H!j<^1t1}m^wBb-Xvp|y`W#d9zz?-i|nGdYq+lFI;{9n>M z2>jzmRKZqD5+~^~x8)gAx%Io~F#RHiD%m=#jq)kycbd{1Lx}}Ofcto|8?Ub#&En~&t{-8ypXM^|qrO`1+HY=yT_((6@0KpGnH30JrUWd&V7|u-i zI_m@J$dKR@@i^iyVZIR7sE@J0oBqYk7)^mJVnzyVVu4@rs0r#X zLQb-oktwQAywvo()F0{TKYr>L{x}Zor`E>i#^(C^hL(n=rn**ER^+x!o!sur)d3_2 zWSvnXNSOi~Re~=V=!gOHv= z?mdy*o1WZ@1ZNl(xNZ-FSR{36s1Yrw-;|WlR3K*Ik*WrGQs&g*XsVS_ySXntG%3~) zVc@CxpYoSOM1>c}6f}^Rex@zwQf64hxWMRMW>~_gRU#b)4Jc(Xr^yFBUk%7VAXZ4fcL8a5P&Dn`@1z8~P`Q*yd-9e$=cAA_je(a~r zoKFtMrg)BDZU^I259%{0xIS+`SSyi)4?Cs4!eez_gb=1E?20R{Fg0Ye(iE^J%4yfn zsEsBOyOVt3=okK^lVl_V@F@;_+Mw4SV(#wUdC^e>!akiDphwn2XiG$FyT_BO@3oe* zE}Hluvy>5o?D3i+J}rwZ_$SF%_^Ffw$>(m&X>(mh;pBor{QePL9aAzf^>)=%P3aHd zg2Jk2$x#8ig5&}0YE460m2Q1xLNu7j-n{XLoB*MLtu-Pd8v5d$J{dSd;eW>dV{jCs|YSYV@jT+S} zR86ea2)k<2OIUZC3c?6TJRH3o>$vH3vNBBi2WQPp2<=ijK26&RQ)A#&#q@Res?c9= zZceTMllo2+PmH_U>l^30Tjx6x(G6y8^rT_hjJk15I3uZD6 z?@YO5uDix}sWcIr>4`CMLdapJL;MU2^y8^wxbPFIjj&om5{Y9~a>gC1+n;eCa6x|I2HO4}GF69G|3(>oDoyByq@iYgM(8q4 zA`MWkVK-cUBioe{(85O21=@qeVVI->`#&u0 z#s-KzG#RY&dEt}hZI?K-OG(_Z>;b_1_kZ7zx?h1~5wl*b=O0O!c$H2U7K1@)trEjJ zXflMkz~T}<7nG^Fn=7UOX~$l+iOR1yLf5L(6iYio(_XIR(yD7FWqz+jPL3}@r4q(6 zyV4|l(vj)qNwBkVeNA?7#P8T}hTO|tzf!mHX}2Y$t?COiNu2?f{b=wFF=Z#!{<~Ni zc9p~t=YjmjZRPwg5rC3K%X!%ZvF=ms$*_Y*I`YOn989XhZjdq;UQTXzBD{KMd{WhP z&$=^igVM+A4F)dhl@l|krBWGR9Wd13kbS}wL<`c! zJgCRnUx=9CP!j8$IVUqu7If zDYUW$uY(^5nb}I z-x9L#No51^nKdi)a}ZF)%>n%dDvPFhhbSsbjsAcC;JFDcm)|oCIGybT1cEM}zV}8t zjR9)&3_ z-Y(8wPtV>Cd-d9$PG>me?CPJJZwJqa*j|LZH|~m2+sa2VrhhzxPkPpb+>(5!>|gOQ z#wF0l?=&oL_pT zvF1Y>4>^q%_SrkBe*#`>?e*jhReG*X3HrMC_UwE1DjW|9H50db_I*BTd%dfCdt7UM zV|#m6czeitEq}YudVM*0)6YM8yKmYMe!FTjxA@|=yS#)iRPO1PePQT>JzqU}vsC2F z#qIV*gdEE1W1sWTwaC;q5`&NLo7Kwu@uR$z_K($_JG5yN-z1-1pS0Fww}rK7L{?HL z>dOIY8w7pj=dv5uo-02x;H4;DfqXw*=5d_a)ox9c$v7)(eGe@!Ve`^*@~Lk+7YBDm zTQZh5KR4*I&V?fEF9th{NvJ*P*(yvm!cINAtmLP;*!U*=eEa_LpH3byPGv{`sWBG= zao=O{DX*(t**xCDYK(7-Bw4FCTH&$dT`PZ0~r0_agk@uqdKSZ zRcqoAMf}J+4DS>yJ@*tOqcN1=Bo{iFFkm`5o8{e&7)EJ!fZC_0l9g zmw!f-+H^>ojY*ol);7MJ(pr^)KeMnlW9qAepL6a+`zm)5^lHZXWYw68x|Sky=32Yw zi`$r*XjiJ!Di?IRJSU~$eR`DYq&HW0J^KyvP-@xeq^Ft{yX)dYkG`D_J;tZH-Ml8*d(@C}DsCA77+?!pqh+u{s&>aBaiaraejx35-?)P==& z`F!{VM`NvdOPlXVN64D@PN{(AY;VJ;uMm_f>OyotxS7 zjf0NsRj>T;sb9L8;qg`WEvTG?d8CJdR@OZzSgpQYIhCct*MXsjSNWy4muJc;(Iq9U z>6Mde8uABF)s+}FFu(ZG&w~=XHQ+aA++^O9&!m@o%LqP@(c?1qtrbN1_wB&)x#E-* zXM)zRByv%oUCXRSyB*6>8r`e8 z;{IAMwFLVa7QLDE)V6<7x>NWJjfrC_d#+81W6CUT%O@U|M?#WcM4Eu-UkY*m5gL43 zg6ZS?dU?y4F`UpQsrMQV1wL%wA5ITrrGC>)S$Ylk;#;@PmuwtKt(M)De}X=>mb9I# zy;QHQB0Ax>F28yn91ZWRKF+T4E$@_1{?zEp9Ma>d@ri4!61*~90>9R6T-M(tT}DL? zd7~#i60zRSgq$j`-M-GY2A||zKFh82*d5ieV6`n}7Q~&%*uA}|oBrlMO>>?an>1rj z7&yy-{vZ`GvrOX$KHF-iBrcR=w!_POR1NP3kC}WsVr^mJH*6V=qq&ro{8FDn=Na*Q zCgLQ>Fl2JZEWdPj)Ac}_PFe$8P<@-Bjg;Lr(^I-ItYFFNty131`&N40*t*zxy0n;R zXH~bt!?kzCDy*v8vSnEx64?fkiXssv7CtSjquAa%4Oi_{8{z`X^qgL)Zkeey?CPo4 zULQM-WT|t#Q991lo@KcBxi;!TKA?@`FR^kz)6d*C?aKHjW@TTQx#0WiCB50IpX3Xd zHgYPu?YNC3AraNl?FcyC@I!1pqei28az;i6c2{oe$~+&foDQtF>k1E4Lrx#yGlUwS zb<=H<$dw=Kh}<@abw_UPeE6SSqM0g?)QV2P71LP}6}UtQ0FUWshX zMpqA>vgd~U5R$9)DDGv5`X=cD6i06g09O@(yrwtWD%KnLs^Q}_O-d>p}Idm zRk*a5>xCV+QFd%0SYd1(aH&sCXSmf(c-Iv-S=N_AEcl0{ZcVxhv~FF8+D zk6zoYMK;I(1a&kX*w)^{lX~(d^KZlDgv-3|cv3E9H0neSN(40zq=!K=f=t>pGII~* zx2#}%NItQTvQxn#%%gpRH;>L+-r;eQ3rmZcPHPDt61=b45()2X=F?@0)kE(0Qf}Xy;H{}lI7|lE+1{R{z~D52XQr{)g2z?hTzkZ$5W1_(>RV4 z1x5~X4WXx(`;6e|G0x|ImP_8c`H{nYGsUH5t9&{eTE~tl9v&V*GTO!F#{SmEZPF){ z2jnv=3kwwKI=fgvOcp3|2J(&tphIV~zKSoW@5yAXTyKwz##{BIi$S5eNn7=#nu`2E zSeW|3BrblLcOv8}%MQ-jq&E5^83dSLX1#uN*|_3!-0rMByqdF2Z7s4uBk|RN2s({q zX-Gg0s;BFg$S5ESJ06zof-{7?y!PlK=WHdS8gEX^3*%f~j@(zn84C{98a7SQW8D2O z%+A?YDUXnn$7tmna<#K(bu*!VWtPBkGeiCpuSu5;3}DIL!8|rF5MjCb33Y(HYhPBN zb$}d&nC)7_F8cNbdiv~E+mjx7lJdD|)njj^8ij8!K&hpl%NM=)uWMs@tZg6YV#w0m zG-+sT!lGGy=K1GL;|gS_x@4D3cTiVG!KI5_BTK67itX)~YFq+o{0uz!+)z+kZcym_ ze|)`lR8`#>=DeiZ^WbK;z9fU!T*&u? z9hi2segBV(9rG49t?aA1{@-T1u_O;hKRWY=fA;v!Th#Ts@bHs+aQ=19uRz}&iqOJ% zv%4$&a~{JVLe7*ubygp39Z(*2!EgT z`BLGV^WpZZ=233gidIO~;rkX`czvV`5C#VA9oP52zE-?`4f;DMXjWEMy8XY>#E!mu z2L!i=WkH){5RfON1bvV1hJn_n@9CE>uVwOba;!}YmjPw^;B0RvrXm?BsgEO|Q?jv% zI3vkLN&J20oj+E1dFk8!bG|)V_|YSm#Tg~H2f6h!*x$rNM96OBYHDgQqeMM<*P2mg z78lW^pK)&w(+t@<3|hqvjE=^fbUcs>y)~jyQos@utEWP(X=T`96KqzdRB;dn145=I zCQF+fsPOy`lB84bZG*OROkd6v-2rLk%wlV6y2Uf)&Dq)6?#j2q4&!A}a3!7Zk2A?S zXqkJEF5IE_o6a|%su$L$ep;4)xU0T-Zh5o(=v1bD#Nv6_-BjC!!Pm|Jv5GQPoyn_S zs${#YnoO4)36h?Vzz*An2DVr2xqh#3FhyLvb<&^Z_3J4zT)Zp8gx)uR2&`h#EsJ8M zhBxe!r(AhW_3ccXB+_w~yviakW_tYvnm#T(w(fh@$3-(Gq2Fc2Rg9l*(|n#PcE2fQ z@xh@M$|;g~hVwYHMp%*6;hp~1gBjXQo$|F`Roy>yF5RkPWa{74Ro_>eRo^>bwz~|^ zyY|#{u5=Fw^_pfmS65d)pKV$4<$EGgrB_{2f_Pg!HOYl6T?2@f&7sLR?%$D_$V%k+^u&;$y}V`tk|M808~|D95*p z5xZO{dE>UVNyQIv@$fj=iDh+4>Eu#l0vctdB?^@lzC%)*(KvA2U>oRVB)Bh36)l+9 z1B*N5-_n+|b|g92)O#+0&TsWeEe(;xj-llDFL5+lZy6AeQ$}8TXL=)U#NNlPgG`AE z_7ZXtY&dIJ%@da6^s~GAXI}NQKB13XY?xxf8=ubgFS~d<%vJ9*{MYp-cXK)$UAhhC zFMhiJAU{2JH?-rmK*)vLNlC7ry#$7MFC*bohI)~nu@md8Z4ZzVK*~|m)skALSY3Q`rUq9e&?LgeYG>b?M8oWpHVmeC*q2N znT!p`W2u%J$6Zy!lV1*Zs@}16&&W*H>w{|e!K|CFhg;9ZYKG8Py#>9PQ#Ie6^(w(E ze#4)HX1=?R<}*CV{JtWeo^-gZt8{jB{P-%meRZ|mabG#42s1~U1}p-DbORbs6TtY8 zG~Uu%%K+R{gt|?!Zw!rCs5x#AuOAe0(mlnS8|xa)0@}p_Pz7)xs3Ph`wSC%pduxl$ zU^v&Dw6LyB8CkP*NvJ&`?A_?7s31Q-L;9YXV_Qc@*2&MGf!2Mv1a4zVk_*u=34*r?F7kg!nR{Co^%_&lO)V zy+^r&aj#x~Jw09UCE+AgykAa2v&&S$wTnE)LdflBVqaty0ivGV{lqzZf@u3jUqe0H zx-ZqPOop$h3L2_Ec<8FSeRuaied+LF3g_cVXMvdbJa^H&LOuI8oi>83qKKABH_gE+ z=jT%FtQq5)6XUnN9G($3=H+iNV_g4#7SMB#KK4H%|5ALDAWbgeQo(BJ> zJ+EI|>K7L9<;6rDB2RayR6Fyhmd@W>c!eYNNa(O>`0JDK03aH($%L>lH>bC6 zIh=OR+bLKgL-A5b7G;`d$qmBon!&=#D!cQ3x8f~%T_zHIOYlkZ^k^I-ltpE9H)bxM z^N3gjL!Eb1h7!(=0Eavj!P1QxblwT@@e!m7Z!g7fhd#=|x-g|%1eJs%-dZ)8tw2A& z%zn9~()gJ|2+mwg48z-GNoGiHS)*i`a(Z!ojqOfoT%g?Vb6UjKa}%9ddcp57UINrp zNFOC^bwk};D(#Nz*}chS^hYnDgvDwBO9}sk)t7~&Vc*=I1~6m~2tChrzHa64x$GY( z__P}u+J3s{Ak*=lhqlP+HhW`Yw0H8iuD?TD z`%->3wqNz>$-mD7;aUSyh;8@v`p8PV-c<`~M*a8ndfx4s`R9)1HK$hPH8lYTD?BD3 zbvpF__~rlt(ngCeK!fUv|1fpbM;6kotsHKi>Q$=jS|XWJ1QCDx4*x}3s|l`j>{-@i zo*)y#4ZvOax!DSEeJ}iRQY0vcv%%RVFj@-OGSCVJh?MW;1B`u&~<)$uBZpJTPBIgGliUuM=9Eu5s+ ztDWo~#&e)KW=&pJqtKI>X4P#X64MV*Ltw*6DSe{Su>mI7u(U-S6t2Wqud-42DDUp> zb|I|{$*u1ik50*lmH3koe$2}oTUz#eeU7O|L8fH>N(NJ{WzZ47OGB7(fOmGvEn;ma zLBvaJMNMPG{o<3P$>uZKIUNo;DeGT<*R^PO=qqb5SVT?i_wDre5A87L0O^-$jh~sb zrr|SkL;bhqg)rE#ZwENC$?qi~1=351gVu}h8i1I zyyN&lKV~xb33~B*f0$)VKM;f5h4}2$7fu`R@RT;Ip52ont1bwH*W(rHGDD zsRE6T)>bujb;;+~T2*AY9%RUlaZ%+sEuk$z8}=RZ|3I9s>d7iO9T1C_il#z z-wbw5J@ntWou0t^o}O~Anf}};NI1Fk*fnoT=q>VB>6-9guYO)p0uAojR@+~%7X4*^ z{NdOeCLnUI=y9JCHt`GHmp+(gqIKqSAyj2?RnefEV}i~6ZS{82`mLqJOLLw@&dh9f zvpTg=40tuk1rPc(=ljzHcX zkoEGilySy~FT97-bK4RiTmYvo=uUxH17FDYc5?&s0WUAKzivYy@82KNxQXFjTewWg zf9IEleqj@1#*0OR^E=}1$vL|bm8GU3J8m^ESZQaKwzLQoX!PIA!>D2Z-kGfvvwdC1 zfJbL1Z-AR>o>M0QD*u{<9yCUAr1`eJqr)X7J`zE2pXIZ;JAyl^PRnww)T^NaXOcrO zTJpI_)+}1G{Y|W>MaV037`G8$)?HPvE8xk5w4ye~Mb=?5pw8}u>f2+81~s>7ANe@DyVtk1`8qir$Rkd(7FaS!Z*)C-_a^%;0^~I7FMr@u{n--ri%Oo~ zDLo{fxdP}b>nOv;&#xUwI5jt)Gb3K8&Z&~y_(T1mQv7v$3zAso;0_xK%<7+(1Nmyi ztfQlkg%N<=AL!F2?fL?ODbQ#CqU&dwp`7>+di9r(CENK7iYczJnw zcofK(*@p^7PR+^e@CwCpvEL!wIQmHXhj4c6>Sz2}t+upD-{-`*aCcW%A3wiykvuX= zE3Y_ueMd^i)5AlXQbB1V^kN)bT$$CsX+%UnpmPfUy=2cCwwzs5l=T~qYGQ?%bk13{ z4`$)4$2PvYBXaR$D)Q&ypJ~f}Ii8*mH;Gizz}AIs%+JrCBjg6}h@_40({LA-*w$C_ z`7#3IP!`DJfh7C9HDL@l5gfhME{I4lF%f*hTX74noZJDTlRS|gMuyqNMZ@FuI@Z#3 zy)fAnCR1uyl2OvLBF3APJfY)AemYhTHXZih=53VTw_(bI&I1cz&_C7qC4x^_SpP}*%+k{eMvaEr zS}s&LII0B1nB+gO;B-%cFcgjeoi^p$`8JuSgs>L1r>F&35wUwF5?#8h!Z_I2$uUqa zxk*&E+B+Yno12@d-=m|biqRt!aY?UaHxCjMaUXTm)p7SC57hnQ4*9C0Oj#3J;G=^O z#MzPY-p;Ay`m%ar7jkmGGQKNb2;tt0v}v&H$3@TNTZarm+wt2c5cWN71;sjeqrNan z$5QcP#R4nJq%sw@RHw(m{2O@AW>4s)ayWm2$V6O)+9QTw7o31e&+?8ALt#qbe<=h2 z*W&c`#oAiFwIqSAKf|lXwyxnX=TPpDNBXew@Uq_c^O*A`QGuoZ;r+w!!CpdaSFDBU z{}vw~HsW0JunJ%ao9Gvy^|ZJtCnpE(QN$I12-3d)l!4+t^zVmIqXt_+L(g}{DdlZR zX8@3~XJ*XD=w3Y~bg%MGmvI7x$dX2o>Ei)RfU@x`5Go|$)M3mESs2fX^LuhI6Jbxj zjt-YK&5D?L;X9b_1C>(2*+H$1qj;YXUV3-JO>RlS1#P|E~>h>n$~rV?eYHe@#*6tBvjwYAnl+uoM0EvSd!uxyT0!=lwrTdv5r;w0d!9vQg z&tjild*;`w4UPWWyk1C->I|(yY^~J=>Q6Z9yj@{ZwN?Y7IiW&zS7#iA5P{k18aDUE0p7suJPkdMS_txeLU6OLyD7YIM&HlC7 zpHblhq_!->mJnk1$UUI-JAtuR2@&sTxuNM*YW;Zv=mSnq+sA5aYsX;AT(rcZ{;{;& zmDsw6_^`F<=|P&%48(jFEGXND5&UN#13)xL8^fY(XFN#1O^$eae%?%)Dxiwz>s0c@ z%e#ypZ2k>Csv`_|)(ZyX?R8+TQfPK)eCD2`Jfy-f~S*$iSc7Z0?F3)cLSf^?B`U~p>C95*C6 zF8NJ-@=`}ZqmZoT*5onIA1jr0bT+rR=)l6m17OSPAoo6gL*vG{+z;x(e%=2Xy$&f2TJ%748U2o0!UMNXn3X5De!g*~TYhyNbEKT*cMo7)%R*)E?07LE+n zt@i@+|Ih!_wY=tfaHZ@nCGs`r|8>z?+gh7 z!PXx$>kUmrjwuv{h7L|2NzTq9+$=f$wZ)SjCGLCf!PHwpDK`g!PThX*XNUhfb3PD^ zgu8go@9gZPv3`8)*x%WiEy!eKVuI;kUt7D@7o7FX!NEa9q)2nX+|m*ac^OD`J{A_f zI@=odmf=Kz1EINs+}v%M+vWmn2LRueg0V$2lSi~b&Vrv`M)WN{-gpguB7^b;0E98Z z6UIIQaMnG1032ndnz7--!)hI9X#fxE;F{E<_ekAgzop2SZG~M~%~T!pRj1O{8qi}q zKF*g~b)kH!brY4Q_5U>aiL*asXu2@4?SICz7&h!9ZVskTS5|UW%7J7py&m=9*ROjX z=nk7gQn4{H7lr{7#`%*9!g)dzq)#T00ET&Rbi^oFY8w8i_|uz^U`=Suv6x}XPL|u% z(li($+UzPXm!IDBLr%n$<9FHAq9|fPy!G?-C5YIj((zzPn?4Yqcpt-6sD`j?stBo5 zT`G_nV0y7#YXznVU;B`L%1v#g8A&EuM(SCmVR$a^+hD;Brim?$w}W~$FSkYWg(hhC ze|H}TNZ~fMtu&B6=H=yqC?d8VqS)js_)7fY!$BJD=5}zrh0d^70i-6IEMrT+WIKKU zd=Trv^0M)jnx>|yBZad%?v26#>m&PX)6#yp0}$~GCM6}kp5$E}on0eiPT!w99Jq{KQP_u`Ez zt=UICAWS~D-YCt+K#RjZa-sb4MNVR4B?nzj-1L?jrim*3_^(qr?)dA{?*8v{K_44o zUbRU!(n&9GZ1BRSZ23oDqKhBz@56;_T~|l5V#Z3ODQgVIqWrik>mPmRc+iA@EgH=h zExYK7l$cA;iXQXigsqpSoreep@|;p74qK&y(_$pta!1aS+nIq-=O}{G8k;Rq zYkUz{t;(z&!iOlr5G;cSJt+sTs6witwl9#hEm>t>qe8|K~kxvbg-QRA^)zfe3fFu27_U zvY{4YX9RI)Z|~HHrlyC*V#UmRJIvv{g4%5R2;CXsZ440Il}0Zy2z9aTgL6Pv>flfj zF`w-(oJW%3Z7}#E8dA4qtvZlwiKQ~$w#Px`Etg5f)q4Rce!SYLYQsn6$kQdCWqkF=_-pJTswvK3PWd+;++!c(x zqM)zN&xrfO)zx+2{qXQ`m0r9o;#+TsIRDVX-1ypupegCYsVQt~j0A=>;u0O6cU>a> zyd~XTUF_d6@?^)2!H!0Dq4UHqwRH?+mI6g z*!;Vu7H&f+9jyToXYe{$M?GbyFZeF0tbyb@OD z-e-G>Kc`9NVY1|NqUOH{<-j5Y(~$Lo}g_Av`V*P~!hb7Kz5jKrj*?^%|2<+MZe$+?~-t7I+b zHT~4o)J#=4GO|l5$(|P!A4g_lv)L3~#c=C9Wrkwf8F1l$QtE%4(UF$Vk5lsjEQ-hu zXuqerO&V0lL=^Ec|5@~msQeK#rF!NA1?mS6lwu4JVK@uLYCXvbn=&~jSUF=YDevuN z_2$JxOls;MNc;QwO}sHC-C78QUbe+r#R(Xq8OGDnKkFS6F%- zm&n7-?S*MeOA#Ig!8!K6fy41dY=~XB9*K!nr4QnfMTC@=(V_S_olYJnrFAqAaX)7e zkd%~^kdP1+9g8Di<5biFGHx`bXCO9owRUo{wjNY-AG(<9(xx3pSjl5stRm1aL-0w- zkTd@qvweQ;vRI#UGB{n`8r=%^0Qife%6CacNIu0Lt=(pS^URsM z%l((D)Vm#E(K&(x^!DNj*g;6GBHI7OJT9gtc?>tl8`I8DpMC}^&C09)_xFEe3Sg42 zSSJ26%>TkF|7^j(VNqY)f5*hEeo+p1^tP`C;?luHf3En0wbTz+VYPY+?r^$k{`f~T3eTB z5L!QpPS4)6Jyga|)X>z7O|ME`9=`Jybds|kqQpp~wJ};zL))5T z30Uy0R%B2MIKL0E_P^awt0duf8Y5ZWEE%^zsB#WJ8YSQ}M}#2+y~yX2l}(I*)GXUX5n$8#$1mfe!ug1-S{obB&bDNia8Xf; z-?d%rIJa!l^+SLI)ta7#4f~9sC}L6yQUG)I_wS%C zC@fq!7;(%ieQS9y)>lyx8@%Y~6;-HAgzL+Rm0{dqCQvp8m(;18-EI1H}zg#il?cMHCdsc?HuQqohIkfQt>sHywLHf2h34Qh^W3 zW`ncE#q{BC*b6j(Rs?CUu~uFWI`0p#-4M}mCK2}8s<%2H?N3c7pJ!-+r6uJz__0nGU>ZV)AGMq5Ko4{lv{f>tY!lqq zzllrG0fai2VJshM{RSxWGG!Ab0B+dma7X+LD+sksxteeI<=ISHTAD)12r@Ab56`x- zJt2z2FL1;Na2>CQ-SrI&Fgt%BJK_sqC-*e=#Bi;ytdt~&`xcZWPa5|kQp7}pR{|=; z1KYsMXNlDF$tE&MTlR+*NL~l_GU{YY+Lu`)?U<#c>$#_sSU(=H%DR6m3u-h%T8v-c0j^#VV_$^g)T+(<~k$+1+l zyhsLh30Wlfx)5zd7)o?I6Ky|*`{Il%!58Nb`47FEpau*B+cNqx25X%*VvxGxA7_-| znbjkiJDdS|6!#r2PFr0Ov>J;f^M>qK>>dQY#zBrcr42({{~asDm*ZgpY7UIJ&%nUo^dR+x^{mO7dm;ZdCfm##^%Em(_9ijNEQ2^FNKxIckTZ9Hou z*2!RxtEYByA1sW~UIGY>Nb#cxPoZq1lv23!;=p6><(6c=$fX2{3Bv<24+MzUr>CEY zVm{8_00}_e&*pl0L;4^}d=;^t-d;0o*ntZBUE674x569Te?2u)>!L>eZ2kPaK3w>x zm;IHRh6XM!E}}KSV^eS-Fwo;PSq!vTGcq#JnZ>G69$L+gjL2ta_Y0>^wBxXTeE*)r zj5w#@jBOAxV*Klt{I@8dZ*gHM+kijtB5qL0EX2nrUH2LXt(`=(hsqy;>(J!|N@=z4 z;~~lXnq+Q%6j>hBA1XS`*FhHfB-}G(SI;q73i$OFbBl_SY#ziXi>X|(2cf*X#)y?g z{dSSA@*w5W{|*8O0K7>MT916^!KMQa@{*k#&C#R8jMX?J<0C@%*k0~mND8>&#g{J6 zp0xl(p_M!SPlQsR23uIzgP7Y^H&6aS8^9I{Vh=jod?H?;v2qLYi02>)tBo`Hz#Y8x z?7v8z6Q^Zf>y0d%ulRR_PsfX7`-X!T`Q89=)}- z6=LpSZ5`gC(y$%46qHgMc5}i0jkk$z-^<{-V4VmDzGKzA4PXUYN=nWqdp8|ZQ&UA# z;z{C^9aJnHebYB=t;pU?0-3_X!hrGkkCiAF5fa)Z_SU%&Z3vOn1t^m)GW=#C@eQ_* z4&?Kk`yfNvG9OV=Q9&V5{o9I&w7;)!mHe6^Eo}2$x5dvs8i}LHpSTO(h&N@b zf+ZojRAtBVkWVu+B_ESAHr91xutM{GbjIy5-`=kcmT3~vDkqs|ogN)MEnRxYW!7LM z!7}n@s-pC!n+BBhKBN$5lX2C&DU3t9C>GJK&ebHv?@bS!&@7Y?tKNO8bOx*hZOeAs z<3AQ|i$_6G@rP-jxOCCJ``$MMN8%F@^Udt}fnv#I7@;Pzw1>O9&KY=C3;b+!xeZyV z)aH%@tSMU71Ej@~L=82yWIN!Q=9XfAe5uYpUGJMj(xAL!2#51AyI^F2?p%oDe0$gJ z>M+>jHNP%qzCW=b7|~g~G%f(=<4;)5%;_?qx))O_7r@BIGl=ToHCITrg8dVZG6{ro z*ai`)FGqwC9eD-|wgswrml|SXA56%K;kA#fN%c5aaX_Uk8b+@$;2joF^uJ5#;+k=yVeP#!Nnt#7G(@d1x8~fu6Jn=H!;)3s>V`GfuFsV*G`Vy zf##g^(l-oMi)nqe@M{X5v+XnVB?KAE~GA3k+C3{^Z|30WSoi!$>aG4 z*1H3tc8Y>QDpk6fO`i2=0W`u6&4KmNJNGM31kSvWfKHFF3d;HH3dV><|a`v z_|OrDe%)~&9buQnsi+19l!k_8bU5ypM&TsFjS-}Ey%-paLuOn_ZNK#%f6cGT>T|CQ z3}?zd^#)2RWITpI;_37hyDzf!Wy(JAkYTPwZ6IF3>6g=bg>Q$tg!L;RYBi3thOr(A0*%1qt*K8oZ1|M3j%O(cue6ml}h%u!4eu-he1)$J29~8|)*& zc!X&>v=eKGNX|^--*Rotnh4R$&H@@c2j~Ke@&0jE!$Xm5!9FxY9G{?hijlz>Au+rc zm-foh%kl1UhJHYM+Io<22NYyY=|%e186ytowdS>Gb&`z9vLpeRS@w9|(0kglT1uy| zl$go4zbhB$g$o+O`82Lj3QGy zK?bTsgZhH_S*>5*6t3P#`N8m6MgzMI)7D$i8*Tla4 z_>7{w%-vd|A;L+X)M$<7%kJA_NQfu&_1)`AZE+!(d>syhBQ$(QSvH#1g|CuoH=H&6 zoMWzWnl2a3*-w&$D!Nj%+Cd?M%MGuNY*42eBi{a1&G$yHbXELj6cWVNh}~kHMv6mt zsSNjM`xlZY9uk!F*D=K9i~4K0hKocW<_9Sx2W+ISpkD$uuRt|(N!L{)DK$|k)g}sc z7XRmm4;q9gmk+{Uhc=B%GjWl#W(%`dDQn{7X-C!Kks`M4lT$QeY9FX=Cyz0;t&ioE z2gJGR2+|Q!h8je=d3WClsqx)ne&F24XF?AF=FGr*=c* z@VtaC7PaI3ugCDw_@dpj&n1nI#pJACFU=AfHL<#nZU?~}(c?HOhA4A~ShlkPg3`HR87`|HOh-?z3JOB{gj9VHIVrgw$TI&u*3tmLK~R)Vy5D!>mU44u8dh*xhXve1-BmCK)@6pu~XYrFNbo{Y7izT^gaiLe9gPwPvA$2m~4` zNv()*CRR3SlBW_!-dorKGx1Rj$kD@*AN3QRGt-eSToB>KLiEh9bVw3o52CAb2Au6R z(W9M1kJ-Xb@P*h}tH~-~b8^*k>_gH{ip!f=1fKJ$AlI0p*SJy$)C9dMshkWr#Flg2 zRQVie@F?oDUzDZmZ6}>p{B5oI6PTrd_3;w$Uc3J2i;euH^G+G*C!^Tz)RIaXZFKl`TuF6pMeCj) zm;R6!x-V+_B?syjCEl3w=d75;Tbyuxs)m%2JJMhdA9udzNxYeebH`6`^LR?Ar3xEz za9VT4(@YF5X&FB7WOhxbRUV^r5~+xG$(9pXh))sB^KB)!6#5Xv*`r5w(at}9yAVSt zR7F=Sasg$l#LvStaEV8H>smg^;dWay6{S@&gm3T#xiT;(lRw3Y6i*0Gb?_Ln(wXJC zrd`T?#j%;Lw%1%tN~0X4D*-2&;->&slg=X<2O|QbKl1gvME}41MjTt+4dcg~a6E873DN_bNu_Pk)LfIxMY0 ztk$WRZbi%GNoImdW1+Ol4(JNKh*wlML}yS|HP+xlhcidayMz>yZ!6Cd_WgJmKjX4- zcDQXtDWhd8^BqbkFkXpUBCLjID|+oig^*ju2jvkPP70o8Ge?eI$Xk3*YRak+SG6K= zXwPQnN*vg~%p|OHr*uvzdaTq|`FxS`JDb`r<1bpYnP{I!HVbF*f{!yVov}(6WIA4d zNsiiWXXKYB z_?#KN$Jn}RAvB!%%1|C*#>_RQwyj9dGgA_)heTn0mD+b{g8VG_xbjUnMY()n8TIPC zf|^Y}d(pA8SrKC-fdlnUL-2+pJ z>qYN#T7S{WEoMwGbl6CnN~?s9no%~AhATf*1nuo^2w+Q5Zk zqtGSa;Jn4F_Rqi2|Vj)$iHPmoegk*alO*rUy@>S%ZSJ)p8_T;yibr z)TONFG(NMnl`9}$lAo(dS+UJVDR(3`YZyM&AZ3{ru!$CEzQ-on4$c{|7#>F%VKn9n zv3Lr_wZ=7rEZRPynRjL8@1T=b+|4W)s5JheGp2w3Qa@E2SK$)x3G-2rjUg{8yu3z; z{Ao6cklpaQV{8*QIvNN47y2MVRfx|ZCO4Ny1tv^Z*E{FgK<8uR)WC-aTrXacj=sh+ zWRb@DRk=Sja4Dr#;W(BfoWfUyU0Suii`07Kx;1QPego(GsAAG2L&y-&{04K+7cg^S_&cm>_XnB(YaXXj4qH)57Yi zO3B7_D-7!?z6KINc^vpI47-*ihzfkI7&eDg^Hwx!?-Ynu5~0 z)UyF${ifAb^MvS^DoBFla-Ud9G295RkoO%OX|=zx=Lxn(I&3v(HqsFZT_St<(PPby zGSae^iF~~-TViU_@vrc|m>!~b9>CtWv!PUW8+a4nrywVNWm8;W4_%-mABj6|&$17; zKP`kLh#V4`IL33%zvK!Uj(60Aw%?#lG~K+jh@*M{OPkN_Q|tI9P)KYYt}cY}RMq5L zqg+*WiA!YGFT{P%vf0rVO;+jHF4_-#iBTO9rQ8#*y&)^F>e5otoFz<*^4_W`fAKXG$2)j`NQ&0_uw6F23$}5z$0r#aa-+IQUFGE#<6dHIN;YLgpX;#Rd+E*U{S)oLhb89zVd}UnMNhs~OB{dD#uoa`j zoTHo%L1^9QzLByNWDE92FezttDlA5xR<*WvnS+7AZ@QSZYB*mgn+FXhw5iRP$Aw%k zqh5`o|CXp4*%~GCm`@G!nW)&jf{<%syHpV=Luhse3R-e&b9lR5EA=;#6l^j!ww9%5 zHjX9EcM2sO65_j%g4HH;5ze2I0{)|So`7FJaw2<6n zHN12#x0DWT+|M1Hc>~EsD>4xgWU)3CFw+#1uF=$SMfe&4LbzQ}<$2DMb*U83pxBh< z^@7|a9S=@H!Xb)y=L}g9AHU8@Fw<*D9XgZ5Neh}*Njpan7qn0jCITs576d-mMa)mx zTiojOsu;X7Y(5&R8WqQN*U+VK1ab1(PP0hPpkW$~^b{Or?}t|V@ptX7a0d^$^FDkc zliu@V@iQXJVLQ0<&S?=z6p&`!qmh5gEkmTv!S9hyu4Afik=`QCng7cY8-`_{rULtx z9K>rMoVIGrN*~lk8&f6rRk&vAR6F?MbmrA!ofX^BPtGq|A@41PoD5uCaBUpRD&KMB z%XMzp(B^)tii%A`SB11n(9R6izq2KOl!2zIW9NRYVlGXj!O*Hn!Q3J%fH<7W*rO?M z!i@vpUO8)PKBNuq^5TOUNX4}1)|#YgyNV|0?3XUOSiAZ%7He`7+OTZ?LUhdWjTZRO z_Ri>J4zYEHzB!!5cuX#c*Vb6D=xy~|KHVXLl1AMMny0o%IElJv=sB-gmWOlI1r%J_ zil0NG{KN#b=Igi5cy0$7gWDsAJw$$ zG<_~UXD6M6O5m35&=0{GUG~LLpFNQ!N+H68n^=`CsXd?nQf*r#5m<7ehq*7=c`iO- ztfN!IRYk~!0}s%!*S%Qoa;!joRjQ9Q#OLJHYVlwsyScb(**fj@kV4igP5|#a6TfRN z%$vzZV|8Y(@-~&_*U50owL{9ba zT>0DEu@Re^FALp9VnAaymnkw;)N8kGE7_n5QkY$tYPT_caoM=NVVF?(J9N{QZLYdG zMuyUiRG&E^UpeL{s?W7p>e5DI3|QaxSG&a5^a&cUHiFlu(qAq$COW2XTT zcb{%hlpQuxYr_iXV>C>G0%A2n?tnx->?r}MmY6_~b<2w1j>=LN!|SPc75iM`g-9F~e4sI#F{HRXm?*6I3}tmDTdK zmED8x=4PFuE4a% z=$-np5r(Hm_MH3>faKuIl3FT<-5xrT7sS^5==@V>)S18fex7l?QuG%Gy~G5)lB9KE z$3a3XOG`j<+|0pdsb{jdGM!N^H0?RYSXN@it< zQ%FeP1;gw5&q(l{^U0to(0Z9@yIvtx9=JIh;ssf>e(`P#6qXzMetre>6`kr0XMnk* z9+26Fixw0VY~rqNO>G$RVTs;&5|oiJ{Ce}ohdR`n?dSUw!`DB5{^XO?f`h_nh${h1IQ;M^Y;fTwIzX>xTNz)c*M(1AU!=c0VDJg|)T(Mm{XU=kDfGjYXCNKx@oNm=SGD0#s_wuRwnVTNCT8 zbO<3Vp%63y^iqjSdmMpLFaSKh-sj@s!Ib=gyuZ6^N5dV|#Jv7hu0j4nitTo@!mGt? z46i^&{LSc_h3dglGr`tV5bcvR^AwMf)e@iG(lziK;_9R;bu{MXseN3efhnt%%PyJI zQ?szJD8&M@=7txz07G3F{wz7lRYt6707d=tokZmHY*Q$`>rbg#QvQBO7_CZ z>`!a>dA(d{6)O59C1pN?Y-weFlr@K70ZmBDr}$Qtrx#pIMd@dR1jt8SFE}(gOf|5% z)i4(_t(pCtv*`Vyp>caU{F-a5wN*3LW?G#9o&VD>t0^@B-Naa=UF|Qr&@2yf%aq$V7iSDh$6~43y5y}v--}?I6i*#sY zG#^57)kTT<3#R$bFQjCvLE8(~q6QcNQ;3^(p%?;S)AxLh3h?u?e9r|NZWYDB$ey8s z07IFjU(V7(-P%Yku+1+j;>{eJxWVTd(;_!gO((K5Muvld4H8QBo^Pc(++M!%Hb$XC zy`Q}y@h8Ps7kJ$?4$#;3bfv?$CDd*2@}(Z=8=N=k)4h)PO1tz}LV}7krZIk#(2T8C zdI{I^TtQRCXigSt!1(@|?d2h;shXIW3@J*7j6}5AT_C(jOiWA@eSRJEqPC1~TDN4H zik7ybL=_i7E7XzPDX22g-rhd-gkmJ-P?g1V;Xp;EvD?i$()aiM-M8K)^he><*i~<9 zlZm*zHVISq8n<}vgfr?X{K@3`)esQr&uk>cCA7ve&?Sky@%`fyq_O-0u`AUb%jZ(ToL(Hqw9z#|*sP&f98HT$GQ!t--WaRT_rH0g@sMt$)9Y~GTLG5wq)Z@#MRD9Lb^1-VN}b9k z6F*RiBFI%qSD#=qBEhbI>CmjEMuZ@!L@@J==eJ){jh3ZLGb|#b%F-J-$kQ{KBSX{^ zLxM<3@vcVi9VzT`+MHjzVR}p|afMhiSGt;4sFGM9a3T47AtRilhFCkE!A_Y@=32bk zW;9wa9G{aXDr_2paGu2)?LDH+qy90ulwwpEELp+0?W@A7r{5GLF1wSwUpP1`VLCUr zGa2dIyiMjr+&7!Xkw{djj-DfhFIABd`}MOk9saH<(f#!Rk>P!QE;o)s@}jeIDSv~i z5q*bLKLxum=&hg6WC!=$N0-yNdV6bfppRKOuHbyi z=+!Si%`mWA8=)UX5~0S=!1*$wWJ4*tyQj=NQ>!f7+WNv-3F7w2q{0CW1eqQK^!~tY90*6kUR5m z6xgD{tSXFShgg$MVq!NG)=Dp)nPB@L z-+%CwC;@F0spPn7&NlVjYQzhf9NpGm6D{n1sy^t#MS_h>Wgt}3`R=7Z(KFi-`oxhz zo3ZXWr_jbJlu<1@!7-xgt8Mg!F~}esk31dc-r1HOW8;`LW6opz8qB#5!Y`b3u_E65IlgP^-W`<3(&`vywnNK2uqFLIl3G%Tn6 zEls2(!U|1jFeLTaQ;;183lX(tIj05e4E@q^eNRVEJdG7QGaOpyJWK>6S<30PzIBZT z8PbqftE_^EK zs=V12>|H#cB=`vODXcaie9^+kvnr_NW-lTR=x*2~-Xb;)8@S{^5I_FlRE9dBPhT7n z-~7l`jU8`#j6l7jHl}v!W#O=@Bb1I`U{ z(#7Ysr!FO+qJngxnrsC{H?KCc#AtrZ6Rnbt~*6TZS!bwVTol)M0Gts!29^ z4oVaOK}_SXJS8i_L2)^)3<=v@kxng~<$;my)an*?e_v*Ee2`BuTF~*9D`qv!QxCL5 zBnE9-kIi`t&LD%bSz9?KVTMJVuxWX^H|~9mev!p2NjlE7d>eD6^)tK|<6s))z<9BK z73J6Gdw}fmOq!FY;N5v4;~ zK*W0IM$h@5`@8S`cKO8Gu-BSv&M`+m&zP$(0Zgp98AUNH&F&eLY|KMI%7V*}N)7dd zabzLn0zXt3iykKtWTmhSYBK^ibUeIt8HoI!jp6tgzdZ|y-UTXJ35W}G>jQx?^|8oH1{@Az~FAbo*=(RZAS?QSUQuaC zxyM2UdkQJiF@t@1V!PEVeB&4xx<^!w}4PE(;AQNtP68<|w&l%l7y_S7@ zM-vjK6u=`I`26Crosz1EtKC-gJ!q<3zKEDW;KYln#G$yt&yI*thmv)9-geqN#ucaY zY$Bpu9H*GYw+vviFbwU#A=f&~D;ZD?Ak|Dju9&`DkPEWN;cHmb}NXujx3 zU&GU`g2(cPDS69Qk9VF~_tKGR3Yz@vFl#izYvLfwBTjoM(Rj03P*zZ|-;{u@rP!2v zYBI}V!3IG+wWMygI;}Ea<;ZuW2bCwhgm8~2wW!Xh5V4Rs1NyEMQ{@{1kK(iE&+*Vd zUFNS;c-YSxPKl@Ua#hS0G(>aN97w#t%pPq~hgTH7qB+XoGdMc4L=Yi+0S0ESbTuZ5 z^zRJWiKRr&Tmsm@x4?P?nD@6uNofgDiG(<{g70DJ7$W6E7G`EF>O#b$KsIQDqTKb1A-^DnjZ9Q7Uin5M! zWyqgVP~_lw^{e~yDT3r-b+qWzi;3dN_CyHRgOaKzf~`}6TUpaco={Cvo^weFb@fDb zw<<~%!Vu7)Mn#lD`YsB^aVn;-9JQnEcFc=QcaM7^3$&5Q9;=aSlynHN`7v_y7D;m= z6)gl~waKulO$W?08m{SiiPk0g4mj$%Y$22^UdJ9Vj-%6F-1Uj=FI{`iU4;9zB)e$Z zmUWhwj=>E5281(5SoctC`NT$Q_cM)RNuNeOR!3h^nhDiE43%aMVYgjiNrYtDJ)Y+dA*?P2eItU~H38=~ zDng44CkD?@5-gVY-+|!HjjBUgrZ7(cOj| zn11d2G_Krj8rK1OVpep-hSB*EC4_TW8oi5pzfh2=CDbCZ-E?tEZS55x9wrE2ThCA3 zSc8nNmZmV?(H#+^8Vm^0V6oloS+hIPkgdgp&BL0C3A^7X$}gn#t&+4VQ@8Izdn2O6 zq=^k%EQe;kh@d&nJ7(eO`p0;^x__i5nVy%g{p5~eyvIEf!OW7Z_Du9E9X8JKrH2!c z^Nz99lr#?8#dDjd7tce(R4}6-_J=XQgQ`d$-pOi{L*Fw-m}2gc*&%Aj?C0$DD=zV5 zwXaK>v5QjiW!!F{fOs?Dt%rKIYxLR+7V7Y_~&X4H4-n`G$Cjmv-E#8Ki3sE9=IFuB?g zEmIMCHD(I4S5pygijt0cG;YZtLhEto*-Cp1@#Q{f$mDDz3y%)%uWG!eTnqRff&PT1 zxk0Y&?W1!A3sl5hg65p$dgon`ap`7<^xj9_9B9RxVk@aST{l|{JrD~?OA_0o;fcWM z1%2kT<&_>J^vKvL?@B}OpMei(hVX+JsPp=e*ZNyhLLIJ5t|81aES1^Mb0&`YJu@4- zgdu&pKL`~3lavRWi6F5p<}sqd+-d7A!n7<-9E1YG531g%?iv-M&j^+r%r?<#cdD;- z;+8k`M)(S*4l4LPMnP5nY)IOkekl5GI}=C!D~rCuEo$yhb_Y&i`1nYz{;sqbyhFer zNIV?Zf3Y?r?D_lj1spIeX^HUjVqf2?zaR0YbR@gMqd+v|_~eA|j8^WJLLy1^2cKVG z4S-m5vcZ8~y-@YHOy6y9|GJ`~um27);OkfWKkz(|PXbfLaxsAa4sqq^?k)WtVCBGb z{>y|MP^h|7XVGaCz@b8XSEHU6fLSdabpEEK7S$F3eJ|+ysILK%GT)-3^X;CGw*xrwhWz?I$k2fN$NbS@JBZWJLA#$)o)zmic$3 zq^c{SSY{#XI`_}l23(u?L6Sv6@sXm@;*|_*f5Ne`b=1co=Ev;v>cwFK#*g^8xdH#u zlz8Y14wgc9hOtbRPpXC6ArahMH0|2h;%VkYK0BX! z|9)KCJ>tD?NGT_^*uynpbq7GvqqYus>z|F-i$VOM*=0kB5jFrazKI<2ckb6#YHSDMQ z*7c(s@TcHAe$k0Qu`Kl7dj%n^&moSYxs}Fk4kS;$U%CAPtgUL?GKS&a$`J(U#oJ(l zu`tpfuV>BtM_;0H&9vM{t#6)F3^#f%`k_x_r$1_kG5A+pf zUnSI~eJfH58!Xu|IlO#-xY&`)9^g|z?rCXZI*YuRz$Fr-H=D}HFTm15?obRd@sw;M zBGLvFQEN;;b-pl1VisO?O>RhOqwFRPk!aWBNk%D@o>JuZK4^op9U@mII#KQBBLS>L zg!l0+sO*DsLLwHxNflI_Cc&d3Gm8ALK$oLcuo=Txo!#7cG8aF6qJKu-%>|HC@?_nw z*W2R|R@7@Fo<8A(dzXJ^BL(d-1H*e{3qa6Y{^YJ`0DOm1LLK6oa^p7V80(gp=eV!| zVniuytfhXy26{?SW1>~!K!Zfqa)-S%^W@;5$x|l@bRjY|Kt-V9O1w|MCCjLWBELo& z9%r*nER4@!qELG?PP&YzvH>|I_^g0=HZVnS_Mqari6#V(?TV!&8nm}irM$eigz#XX z#D^^-7RUi}i^5A>_r%isPcuGLmXsi$iWD-76rg+%F@=;z7zxmIzQ7_ zgqo}g@d9*y*^&B5pt{*}j`Kq)M(tX;u_-%7bD*80C`|bn;P(3aNYys7G%0y>D_C$f zsRoS1O2ErXF~`xh5-UR#wRcs-7*n*cF3`iCF7X_59Y#L_BYavUjTj>DIV#BxYYGk7fm!HO!+`RoNkha4@eh9=#W90Y_A z1T{rD1DLSq%Ow*(_Xkuadc&OzOp#MH$5|Z$Ps$-NhSo`-=Y<@x5_-&}(NgH_mlAYA z6i3O(i@N?rtc&-zvIp1BTn1h!(5Twx*yaYHH+4%)r_`;3f-G?BsBHF(SbLiQ=o~f= zkiJtOH*IZ;n*lgESdxI?KB(J=#|cU=8}e#9ytt|D@*p)@uUn(p&4bE(L&N~V<{D2` zhB19{Of<=sMWS`kf6Z`|lATuNwmg^!fZmymlOGa<`T6@e0FvCo-_%jfWr@9Z??6!s zkRNX+n}Ij_UAt?Dd`Ont6sYsO_1S9&BA$sqg(VtjEMKKnx3%$?p~nWLvcPhKwGb(( zIy9lDaG)-syizv8>Z6g8AW3?_W#{6of!vIi!$hTzLEi+|orre))glY>&U?==m=U46 ziQH=7DBpI%Ap+h6R~RaO@e=c_is;lc&GM2GCY&GpvlXlI82GGOg9&(q#I_fp!i<#g zW7Z5NCATQQc`;q>XBw39G9dKM3dE(INaG+T^=%(3bR@JiX2F&|Ruxfqd2g@Ml5k1a zRQ1n_usT(d2YDLo{04Tx`pqJlS?WaAO}5``tUXdQC$5)FY%CKkhz``l+&MTuBlJSP&QJfrHpV~#-jAfKy&nGHBs>Y(c03ooQAg`9If1} zXy!5(Rd|dIco4G*-`cVPIazx;fR^g*PRF!KUS&oBfIurk&UPy`O>xkg2j3J(J@%1g zFYbvh(`4r@(5}Gz$gWhKy;L&>e_s?YJDnl|RT^rB1%j3`wl%v%TZn7?9_1mKEwg(H zwx>it{u85sAVhZ#RM&NBiwqL|z&WLLXc12efV;aFv%{n@wvJpJo8j2uy2kwsK$$!mctuXI~3y z5o*C8fAbO!;>unj@p4sW@_?LuD3iceWnv5E(2D%H!^$`hHDn+@x4B}rg~+?n|A`He z0K4vt7sjjLD@249q>Q0qYtwJ;E~>C|v*Sl1z0`_A4xshw(6$a}DTz+B|G?X}YH?wz~#%SNhcbs%hP(5`WsxV!q&?u|E#164nZ0>rP^W0ig4S0uH_D((-(0U+2(Ilh61zxN-hB_8y3 zX0Z*i;hHUghW-L>;riFc*Ruwkh8~%ci=J7?7k5DgxLi!`nWnPUWWrs({o9QUr#8=k zg7AeB&LSwZ+R+xh`vq@p!|w@rxV?9^<^Vkr77fcJ7B5ac>+8vI7PV5hQ|T0 z`0?dc0HX)E$PUO8kA$B9&Q_2~M|S4}ErX|ZAHAo6DBbpAih^2L%%j&?6v0`$wPe9T z5o?Gy^ZU`O_zQ|3#y*^z`}`&2+_qH%Jf4!-^K$$v4~4k86odeHQ@_fn zZ+pAISvR+1fjiN4HlP6ysEvEJ!J0lJtgNmE<}bQDOZzv}$^L9tc~NnBH3vULJS%JL zZ27|n(1gh7IK1$8=|{jb8Ylq$ouChxZk}ThPQB^y?v%~V$+-L4v2dRk)%*LmEMJmC zV6iox?NOq3HZo%Sr=2S2SFX^S|CMzJA#(sNuw@ltd)D!o$F3gIn%gdHycNIXZW6%(=cM4fUe|v-u zv)X89LAbI1koym98)!CP&I=IRIg%=yTUyfHxl@>vV`6F=`vbH@csntX2sE@MAU1+I zNR0-a&^jNVc!7Rv3sL;(1YK=yBiiyWWp36eZI~(-?+{b%f{vP>tfVlr#64n1UJf$+ zV6(N<0gi2IyAo?UCD=y!`F2mm(||@RI!F-&#eEW7>2x3K{LF+`(FPl9XA&YJq&Fle zoBAr>c+QH%u*qcA?`;f36%YmU^Gf)2H8(3prFnuTz}Sg-xUkIcAUFd0#Wh1B?&N>e z)|T|oKC&48d7nW4wJ-1I=TS9c%_oq}S&&UJ^i;l4L)qe0^s7kdmPQ<2ZZu%Pd@+M@ zR{>9Nc{Yul8ia{9F6#wqA=(Y3q@-l%CZbzP+MugabDxF_NJ;RuN=EZ%|FQ=KG4jrek6V3)FhP|(RMSpp7`I+ix=DG;E7E&`# zn*{THkTXqBZTy90xL?dZ1R8sNd-7#x0)Vhi-4e!+;=l6@wV_PUegyfoiOjh^p#l`u zTt^a|1ugNeTN3|m6M^q&jxl3b2#+8Q;zaIf!XojLbJNp^dM?xssJ-%E5Ma1#kt(=h zO7GTLgxjc-ymucdHz^$uLc$*}yDqrOwygplkljOiJ8o+{!WUqTym#N5xl*Ig`Xea# z7KH*7BmN_-R<)*xfi)28`e`#(*%0AzdP_x=TR*`|4Y9VflWVjJSzyqck)FjgH8&?| zQaGJfRP*(n)B1?>t2)n;^A97DsJuNPd1k zU{s~tSx$)%`ogW5=VJoJDl|iWv&^6FekS~w`HADpbY9hG@PfPpx2GQ<=DwrfGH0x@ z+dn*3-=z* zt-b?e$xk6)fy6hKyN4x+% z3+cVXh2JRg^q^i!}r6vqbLdR%8BQUEPZ6JHR=_j zmr5eF<|6y3X>o+)7>0nE6MrF*3lfhI+jaq$VrB1=|8$qc{hKQl37@F(cXPuvKpncM zlBFPbCB^&o`>+7hgw*i&8;w`kO;weZm2LV(X*Ox?FkrIMo^iETw01atcJxM~ zP~vO8kWKXID{u(-2G^-jAnkZ#cXJ6pk)tcVlM$8IC;hAK{ryMyeIMNE@8qpg$uG zw6PTU(91L>==I8{C4ya}#3PUqwOwnB4^x~22!TCMT}}YEGu8!9pUnrGvY3A9mz?sU ztZxf2+LuwNnlL)C!098B)mCYYyx6o6Ur^D}+1S_y_=E%nPkCA%mzS2_=Xn(y6Qe_= zdmq`goQ@W0CV@r$reUqJlHKIwaQS7TFih)X z#gT2)o22FAKLRFCLzI~*CY=~E7XBd35>R#n1RF*%cs_VdSeLuA{@{Dcio2A!O@;4 z{acJoO!4vY^VQ8zH+6L^qsZuJ>h2>xu*Z0Kw7OBqFl@7Q%d}9bIGBQ%GjnsHDxt$! z^K_Y${761}dPEDnRz1>8Oq)%+F>VbkuRxDTVXCiCiJvhs7)+@{XSSmNa5&K4-ymh4 z=!1Mc)?_~p_Jz8JMx&90%eH1CO7)hwKr)Lex|N(H;BFef8hpHM=V_p76vX1mFJ2lE zfug2@tC#MbTFO2};s~F7@H&@RtJA=RUR_-UpjTUj^2$AnH%YYX4<;uk0g5ZQ7WbH6$G{-s<<mvFN!GJYuvATZl92nXN2YCtM@Q9u?uE&Wd5*QCprGi$IR25GgX9YU z^Dz0?6I2%0T3R|dFo1jzC2Q@MVz88F;4QC^&1c1H`J@afaW17Cw6v)Si?aFEgp}yk z1QOg&?%lg*Qu4zT3XLlXi;Y9s?6d0y{RZaC!BM%PEpl>l8#Ut0Gzm-2P-t%c-A4=@ z@yjYoN*qXuxJbyzXFLLafrQv+q~>HJVly@IkZ}9)tg7S()5S{VC9I!-7f;E`?QR?p6XsMq}pHV7APz4-rWmQJ$)$N$n3&AlkzrkW|jU?#53Qa z%#&=L(t^>fTp|Eb{nZiMq=6x}F)YMux)E;Ti8 z>`Q2V3uu^9b-c(sMMy|^P#=S?QS#tYiHnD4NZMWfu#6omDg3ps4jbxxIYj@T4LMw~`ksL+Fi`3a(s_;?K-BsYV1FNEeyH0=5BYUx*F()0?4 z81YHlLgr>cfU(ClQ>RcB+QW)eEBwO9ik(tgk!NaXXsE@Q?fdohCrJvPIY(i*>R>R& zIKQg|1AC6Je>FB`{5KQD);$^3{N}byffW*Cqm*^-!5`o!LD48H2g}FLuT3}4;cR8) zJ)|1FLccYX?7Kk)E4KBId8i2Y$Jtr^Zf0(7&6zu5?)mNQ?Kc;xNIy)R7WBwNvo>{G zgwjh@|j?|A_hYu z(8s%T7w6~s*RR=VW7ij#m-CLorxKKhNP-oW*1%cx(RcbnKtxo0Y@d^p6VuX?&<`3$ zFuaKCj&TO-yOcUdys6sN)s+$^c!82MH8G)8MVlSqnXlARMVUAqIxyg`HuSPt^)ytU8M6QyAJvL)y%E$QcI1hFaQ=gQw;w8GUTz(xL z9UW`mbRPLMCGP6-11!7emmb5Tx#%19_Z5hjMELO7K23g zTeeDJO1L0Uv+t4+XQ|OWsBob~hYlwXw5Cwqbs==DiKH6SU8hJG4$W#zL41{pJW#Pe zZiJFk*?iL{xR>jzu?!grDFf?M2Zk`Wk@EI{*CA5XC~^oCW{uNtpx27s8q{v96S&H#mF5NgM=tUJq&z&V`EHiF^^ijd;V33 z?GoN>{_$o!)FWI|ke1%NB_5eA2j*PAS46%(P*!BFlUGn+u#VyN)kld<0cIq}Q%5JI zEAC#mk>yB5AR+y87X38;mN|8!*u+%&S8~qE^`ZvRG7F3+i3tfcSCyqPZ|b)D?4)hkh^s?{u$B~WN}fK_~oLCSRz^wmYkeiW4H@l-1=%t@{O2H+fIv=VKH+h8nK=3`sOBAQW7;+ z$-p92?B|>kY+Hq8Hrm+9w^aM}h1$hKlfthpdhA#izNC(nB|W@IJkRZ*T0}H7+|?N* zX*lM2Pa6-0pD~K59hc5K1FJrNV-^o_5vD3}SC&*z;qpdS$0~0LXw_-g#z4IZK=vID z_oR(xF9OOeQ6l(a7;o)bpX048jfU> zI!ZT!CViBoPsX$P-ppoaXD`~{Nk3I8Ss(tT-EOI26uxcT!32zcpk5i|BN9?#7~E9a zrv-F~>2l$5M?l8E%V(0ny3`ed+eCI6)o*BW^72Z4=x3l>4GtgJu=4QW zYLu=K3aQdqy-t`RBLkF!P#;B|JEG=n?Ch$}0%ZjVPYbHN$4qZlbE*r?)vii~l1 zdg{@VzJ7220$K9Wq2F?}0@j6LcqeN?Bky;vP>g1jSTNvKbvvztY@JF4c`wpH)c2}9 zBFERjFPgJb@u?zK%pWO{nn~@#j;psb8gXtw%u;>6^Z9f2FQx5~R3>#t26Tn7#Zt!n zl=swIeS)Q!e5j~54&-|&DFh@4?Dz-lQ`h-2PhNqisN!s?Eq|(i0&_;@*;KSq0k(4q za`Tqcc8>!0b7kknk=AttPf_JS!i7!-ZIOq3RaR~;XB7u3!y#qlvkO}dP0hi_XB8VJ zBzvEM1&-oi@NJYx_mRc zY?|sOqid|Kazx+zPljo^=XhpLizo{Hoa~)*E(>#KsYpK`hs17>B~t@bQ?!HV#+#9+ zb_B?m18FfWP}n>JLnvD~sUlUM0$~<_eGX%RcdFcrl}VwhT9RG?oW62uQhDsju24pMwMSR7O=CnvOp!vDwwq3JmXY(BlCyy`ON`(jIwgmW%5H)(|A6R2W`@& z1W`cHIJR&cSJ}cY@EH_UoQ8ng!9Y6Gg55mLr8&tMpcXglyBgD5v8`L=9o$`8_abxSxA0BUI1e@ncn}6-Cgp^2Ih5p5uIx``OS)myX z6_xgGV2*`moz-!~Q#0TB;18%Pm89rMYMiCuW&Oq84;63BxV|_>O3a^SC-IFs{&B8s zA6u71E7kwfWxqlWgMnnv>>kXzPrddX7}DgFCen5U3Ej-`lq2$N+Gr*DCqwLJ!QAH@ zdfEOUf&9(hD7bDY={l|GGv`!W5C&Qq%P{y_b6)nzhW6`zEq#7c$C7TV0ti>h{xe2T zGjsDA9IW-dJq+uPsLfoV$3$^)ai_vbKT22fiynmu5DppFv8f|ZnbbRHopJ6=to~^t`Gkd;nf(awvni}hqnJ=V z^QBR>k}iO<)c6Shc=PMr{btEW7iNgd@C$EdTpyF!*NSTv@hA}m>NLb4$SfPPSOM8w zekYtVH^4V`{UeTtqdvV1Vntj^D{Z43d#9|VLig!i{m_LfsOKj#t|K>RAUBd>E2vN^ z3`1%S51aiQ>o`3g+;rv1a239N#~A4>yr1}k!gbDLuX)W9eJ$jQOlRv^%Izpo0Z<#dsI+C#pI=uNgbtl#NtN5$5L9Uky`# zYs3*l+mz#A#QpxO9HKFxk65OCq$NHVv|9!Xt5$nQ=h)maPX9|W6(`-{F7M(`5Pz1q zQsE07K++0dfu5-RR&F1)TEGTr-bg9j+#Wr8h}GQj+~oPi3sOg#yyhvLiYS798U03D-Va&mJu`jGHAV<5y$B1$c{&cmSH$!L;Yqn@P{O3GvV#mib&DDcvml+ z^(#9ed7@t6$P8gp$1*vg8jUEJ?kjvuOx>Gcx$MT!j?0%g5ntcobq(a!0wF*6wIg z-I5R{Og?CPFk#yEk@;%|QqUKy=DDLPsWbByh{lO;rJ9Ke1>FZ2hu~O!TE_KRo9Cw8 zH7cRIYj|Q~qJckW0hK+!Aa_Qg{?HI{ovt@3)`bYzvQP4FFb`g!QsEmnSeByI$~gxI z2Mhj)2R9ISUcW_-Lm7!?^|}y)w9(D(Bjdyd>wGbM~5ay zXvWM_z$-rQ1Sg2Dd)ndZaQ z6#^ccTv(1ArsLcw#bZh_T9-4FNW*fyn0k8tEIupHrLbo5^;R^t({A{x=1%6^Ty1y; z`UvP|qK3tB-!`x;E7ek6U0sKSS2V;{{}t$mp8dOXaB$FB>SG=iLy}@zngz96a)!R1 zo`+`x;`zOjEDdp{Z@j{;IBj4uXW6Et zmKrKFsiadRWvipXp?jYBdUF7`GLPxS!}JdGbSrb0jvSMCm&ljHUL{W=zQ>G{Iv@y% zb-j~By@`8Wpv=86Q;boaAbKhUTXikL<*)yNAvGN$DN>`i%YkwCTMNl=9E`gWEs`9H zbPJ5sdT9CmoMj9oSxko+11V^!>ay}A(Fd?e1;u^42AcRi;Zcc9OG-n}tfT6iv0bM(3B}zM?F+Jf&hWUC-5uHI^y1 z?+B9B5NRlL#MCI$&1@Og99(@J8O&ICH?qM0@Ma^xiz^I4KY&0jJqRVXSaC$J^iGTq zUML=8aR$45!e}S70O!+ZLGf-UYR4)S$Xd)qO3`RiO4E5fr5C4vM0zRno9eO+{k6xe zKMk3=Q*&Lp_c7*weWk<{{}GGNI;Js^_FMgLoCscL2l$>oex0!K};>9K@W zq_YM=6|Mg8fKqVMxSswa26AGn*F9T-WoH!$hMXD=>H@Zx_#aXT&T#EDE+6K#$i^8z z5hy!Wwo!I=Bgs>F%~qB$6OQq8ZRu(jB#7J-AjBX}ZRMIFL5H#$ik>=r!&S`ve4l}? z@lzzDe_2`COuH%}hk$O`uuAaG3niGnfz~1F`*A+zF*Ad*Tzyfag$3p*6O4yn&dzj$ zkyBrJt2_HX>}Oax*x6ylj}R9as z_zUs`vX5bDW69|v-7H$XKbC^S_s@e}9nktj) z=PGXIY;#~gQ5hRM(VdZ!_vh@hH~2{YH(3XNFaP_tr_7fp20C}_PyK2{ocHmz!iU*0OzruZn ze!@U8)${)A*RPd(Z(e*bcx4bQFnqOSvi$G}DRDe$&~u|LL9aEDOJ{aOR2{duNikSb z=donO2xo1tCMxu&OQ!V0xkiDU>7k5c;e*8OGW7FK%AQCJ-9jZTTqk&9^KUYAfmKS1 znhFIyP10eXmcgrvPFKBx%2YmosnSbV#zvt9SS4z%V2*NkVQCi&w5K7Jz#*ZC;{!*f z$ip&u0Yhvg(09`!M}Us!Q<%6FC7p4WMy60c5qe5~zU$nJ&PSnHJN|L)@*egvwa$4# z<3k2kjI-Vb8ZWCL)n!+40s57XnH5?#^*W#v6ic?->obuxq2r4EZu6>o4 zUbSOc1o|wyQ|YKv$$iqX_achLOY(o>MWy-wz`rAZU2{JJ>hg z#22?Y^(Q+L&&jxO0OjmFX0wwS;fF{Ew0ZT0=9jdA%7%=eU_7;`W($`3YXWmC>G4vNU6&-FsGGcx9U1gd{77eNWMF)=X(ca}r~ z%dr1VL*ObaXX$`O#IJ|eH9^R2uA@Qi=%nshhGYSSat^pxE~?w6IkT7?k<%Qk2a52AKVRO zNROFvzI7#@gJ&_(ay#k)MNCuI7i?-SzEC1NyESU@1Yxi+2N*bAAoQz1h9^fd5s1U^ zIcjZ_@5t8Cxmqf(hY+f>Gz*SJOtaI(J&_x-!j~lG>g7pd4QFB}3q<11UH@P#idd@o- z%fy(C)be(m@sXv5hK$kTGhPe8cHm?Gi9+>`p$$n~dzr5;Tvw*!5W|S)0Yfj8eG%mW zTe4&tm3yLKaM$FNE)fT{OsOu+R53LV!R}2QQdb1Jj7*)zYx_-l?BWx`%}F-~xBa0t?f zi1v~8B?!{AFy4$+vMRGDbMZU1UpG9khinHBgNdt4ITv)GL7OD`XlO$(B4Rix&-t9x zcKDe(GR0-V(3$FcpM6)(a67B&uj&70Iaf&_spLFR6f-Pr?DX6nkYo2PL9N_6-yUy7 zWUgv!6Q2)}M0LGmhajI-P*B@tLqKh7xx#LXxsw#KHa0TS=U|d_q(tCCHHdnt_ z;CReNx%>C&&CO+^q5{dIiwv@;LlZ$ci?DMzOC-_yfscTTB(}Nc_Hfm%XHWu_*|?kD z30_h>@nGsm>uHsde<^FdlR?&}1ZG!|cS>~ULPBGUoNFL6F3(CY{&!mvcwK@l3>B_z zG>b_0B0OUUYAW#U`cx7i*+9_&%<+TCd=5^|w1Zvh?`Tr;e~T~hqR`Iv_1Pu>La9>& zB>NZ8;NAKA8ll&B?B?uA4UXa&AE&PPzttOOMj4qPKq*JZr!&CURT+`hhFSR5sS{?_ zkMCMA-#(E*9%xr3lK<9`zy}}^3NJ62DiVT`{aZ`AEjfUCiC9!Z0?y@onYs*k8N_nU zW<&#uU4FvUrbZW3{!@|#$NexgGSQB`g2tP=oJU}`x%Jq6O%k}$S! z%V1=U>@*uz|0zDL$7`Ayl&zAhA7?v2Kt5@QMI=ODr?7`6uLndx|srIJQjF%^iVxwCX1eTyElSBX~o5F$H|Oa@cNcf)bFzY+urZd;Gg0xG5*0VoJ?9qiH6 zeRS_0w=vPvBUCqlL&gZ7Zs`9|TYFVY|6XD4E$)bM3jIv|qu%0iq@7F_kPRHH02Pw1 zWSyVB?6g zw>}VUEqlr!Fb+Cer%r;Y8M+$88!7}vztdfy^my(1vW3?}L^ke$^QWpjlyX%mHT3lL zt3Nye?!YN&)$1X)E`s8kxnDMGAp5?Mm6?f(hGz5Ruz6*0$Ptt(wm&c7pkW?Wk9&@p zjz4Z>x^w5w^fJKGji-uJ>tG8f=yTe5swqu)W-|W-rnsu2z67N5^2_J+2EtPX^@x8P zVGAeWR(lxeoh8VIhlMp5K~*>J_HSmIm6&TP)oXQ|{~G*eqmk1XNItqTvP~#2Ay1P$ z?bhEzGEn|U8T?twTvSRuF>sWN+;eFe8PfORWmUa1(~uS<+^VqRsyr^pcbE|Yh^U%7 zWI}`qQ_E2q2lc-3^c}(6m#Un`8Xz>W)10OBq|N1TV*P0<3?jx&pZNK)yOh0FaCEF} zVy35uNO%!CZl@xDIn0 zqYP7MRJi=71U+K2+D=Hd7=ak6(3kUb`J2Yw)qZuB#`h%Om|@C! z^T&6jASVvvZit4|e(pgK!^OJUl#r)9Ey( zqnw}J+uIvZWU#!E;vud4hQqBqbF*s=sn(s8sS{X#BaK?Gll+2$#>dNV_r_EsFYHmF zH?c3$4S5TM$^ZI|z}UcFTUAB)I)ABDFfCk=)AR_b8@P~FdzlB$x-uhKKVpT;1mBMg zlazh|rQ=*zt4_!r2``i{9_D314FC;JL1B_!0A`9S==;pNjO(vFKOF8Izu5N}Wp&e*E%rH#_HX$AVDN3YW zrdabh0;{_I9W0+9*tAmy;|opW;Tky10$?ZHIR|alHTjt-`Alm|Td;-aw4&6qaxFeY zHVUTTiKfeiRo60*mEw`AstkkN*<KVbJ zEBGLBwX#zyJn!>6(U2-$aiTyUPzd64&~xNhnG@JINK`!>mgnAIYGj%;a84zi$UL&A zfs}Z{GVMG+*a^|R@Y-jey7ZokTRGj%-?|C;ZNf69+0jn`w}InnpzSyn6_!AMML@oI zqgV;~bXj@%nCgH$XkVR!sALCVNz5XC^Y$Ng+3Gvf{*mCnXp`GO1db;m_{W6- z;Fdqo6tHx_6~|zBdjwR<9}LNVFfFU>aA)Fi;MVSL^+#2ef4mehhXjDK?c-yR&|X z2e1)K6js0qSXW~GcdtgQ-t9|1(P22KsY@9S1RD`p*I|TT`Qo08!T{vF3XmH;s1`;< z2{AD#JiuO`?eFd7HtiiX0%!iBz%gnK}; zDR;GLsH%X?e(|PV1Dp~+Hby`Dk7Ejt<9K4hD+(KFtEqv!Fm70Q_*n%&SG2aa#>Zpt zfC_bjs4`>M&aHHSIfjSlIcaHW0Hq?A3qrr(owtI`~;)6D;{LtMmRe76D&^!3R0ZwUjwOeQ#- zDB@pt{?@tvQ;z?i%mc~%cawm3{)64R^|_zH0a|~p8C=fc7yo>F>kh+|Q-^R_%=wJ} z85z-Si64GX3u=(9&SV@j+nxAl-Qmv%&NK0S_h4OE3-s3azP(op)YG?{ed^n{F1r7} z#`z_H0KnPc@9>}f55M|55C4F}{*5Mp(7-`xKrOW59v_pVO3D=6?n=0RU@bL*gD);# zhyNX5ikTry-?vJgaJ%};HqZY8mJU%H-$r#p5eu<`)|5XM;QwPv|8HT;KT`^p?T@&_ zpS|;++y9A&fNcMnNiZ-V(tjSX^~!!@FdnHOrSG%cKX^JluGtDJlD#F9|IPIO^%4KV z=luLDR${!@$Tz>fP4Jc=3mV)8> z`c^Ww)IGdy|9gX%u9W`_#+@tlZlzRA8ixtFw1t?AY4%$))j9zd7D;dKe+IaE7i>}A z2dm=X18_gE>?xAzxnoz<@CzW4dJmeR-MlY6l)wc|jx1NqG(q%lyczPmDMV(zXi`_R2i zptb4z_(9c1y1;`# zLm^iE_@v`2?Fox~vr{s#%i#m7V-bCoIE*4q_L!dO_+|fIb9#==3>M$ByL<^f;-sI1 zSZnD;dEPnp_wNb2dU###D(M!IuM6#bk>4ym@QhpiqV$o_)&lx!hX>3C{LRfZghdmF z-?>EQtqXX>kZ$ugdvx=uWq|xwKwmx z25Ht#&ISGQGG>C%I-K7Yql!&x+$C67fDFO-tDjiD*g3{e3DZO;FAhqOz^iuET{eRw1 z_ebyLcg@T>XJ*c5Ngc}+%eZf0-`EcgL42Z!*;aL_QO>8(>WZ>SeQAA%og$GMdTt|s zdUbs}5d*^+22FY+RYxOLb;ZJ{xZUVqtZq zZau@rgIq{mePEb89Exu%$9Hy>(}a}kKoK|q; zSM3^U^uV4=m3Gk>8!8M@JAMMnyZ#V z)MegI<+f1&q*cPo_DG6Oxq%;T?BHa#Rg}J?JC_a_cMmrCpl4^qaKw=Ojo2?3CxTsoYdFOvM^3 z93o5DgOv0JMxsWjVTw79Yrje(Vlo%M;y{}{I71bB=cD78?|8RDPo?L`j83xd#v7$Ig`fO0Q=;j7L{RQUi>E~OI{35g?cJ7b zC{fePEcEO*ei<%H^}ITs6fO%5y8}813Z8?mjx#7hXIUmsraw~s%@Z}u6)T$^Jyi4- zu0w5P{Q6i-DL+ZgZ0z9_ zr%YnwQ{MYoPp)KS(U7r*=w^7Rx+3954V*dsdYbSB?9}!K7~H*mY2y1-<9iERwcJb3 zLNcmtP# zxQICqS~XONJv4yEbX*PgwzUT@BVbcAZs&@ieRP}cN=~G7(0$blSz1enUHzk zd8`KRsYvK}ktd5eZ@CSJE}dX#{eif zY^x_UC@n#PkV)^c-k%?aO5SJ+64Z~xV&Z=qdtAP?n5>VFqlO8oejSbJVUhT|9HV)^ zHh{7I>eYA)dm(vlPoA~QS&fxr;7ndqg{SY@f#il|KXp)?ifESa44+5# zN+$3^GWL%g@1hu@l=%@Mf|RKKXL@0B4I1fl$pL}3=I47W`Qm{mkogvVx%oh%k+6G; zP^ADU&t7XiL+lMs%3`unjaaFS28*FMM}yp@YL;YVI~fh?Y@knFa;=vxpCxEhltEf0 zNw?UafSgefnv6!6X8-}xX`;g5&_+E~46?I2UlkVR7{SLZ>vs`zPZomNv5!?dW)hpP zHdf(gAdD`Kn`*ngT%JZwece#IA3JDZJ7w*#qVd*xSLokUxxS49F{iW(U>GavdvsOy zin_ep*aTX5Y^kKP1*_YD&!rr1Z^_;SxXnZo;@bF~u*{dJ*48lXx$UklRt{$cDk{s0 zST0hPwj2+I!;NCnr?t;iUjC{FmR#GF!#&$USyP2y1N$aV;k5l9f0n1k?2V>yXMBsf zk}@B;lfTaA(t6Bcc@R$gxw?6{v#svt>H*H(;?{+vd5{YNpllB)AIy35*92U!L(gX( z_A9IV=l0+(?n-$pK|Ni!7Yj>cPhD>gJZN}s#rnAPFG4mYVNpYSk0g@fwQKk;{L{G_ zEZ&TGUP*-%U;b6ee0-QDT}cKFAcFd1hB3+p6U0ZeJCRKIYmV~0`^=I zw4EiSu)G##HvQqOIYM6Ue52%DLFYi9Xi9<}A3~?Rr$47vme!-`zJ~lPXxLFcb#@Gi z5hkiKf2%Xb^1@S4@)2=g+~F`<>U!*}&Nl3bW#mVS$BNA$JXKoUak0WWYLYkIsM-l^ z(9IWpiHi$Z$%9BQ2)ikpoo#j2#l|>aU?PltgPaE^oPUpYZ(gl`b(RvGDo$X-$K>5X zO-JECMu~ayh1eSXVI~Ide!o0iN_MtH^*@%Z4;34-HW)5Z9b!=Kt`3X6SBsm68UDiN zj_sU1H9;^xy}+5o`N&Qlh?A@rjxf=YrG(7lpY6!J?2hCalBv9#rhmDFCa>?z$vE9S zazZ>fT*1+sIz1q0dr@~+N>bcW>h~OMNg-1ME|r#&B5r3EuIWKS5?x&#+T83>X|p?5 zU*m!ts`vGP!C=5_;{BVOz$@FqRBDl+YembR8pyVVb#b}NmWEwahV?+Xl(%`M_gtQA|oTZAT#i|^~%e8wh(5HV- zn3trTejvd#sWK_c=7zL?XIV&S6S}!pMS6;SFs;_zVWium4bk>l54lk1eK^uSJ})o6 zp;y!^2&L^Wcq&;Xwe8|L_H&K)HCP5?M}%vby^yqijD!bT90=v>?(Q&1db(|o<_}-t z68c?`Gvqx>LhoneHeGn5_eN?UuxEOex+MYOG3|QyYnfikc{ykX&UE`v>saqpf8YyP zFfSfa3MtVHG4bBnI5tRdtULhMw>VU2U6P;WOl`c`8M-+r$3^Wx(*IwPkWt<{tV z4pem>p#)?i^wCjK{rk%upe;go_imNl$T!=}0GdoqnS;*w$JzvB^y4MQ(wv<6Ce40> z$$~3C!+x<}DoaR88_h~Jcx}>Gn_qC^x9;&tG_qYVx)&!i2FT*z3@jZ`6B}SkSPy*O z^cTKO$cY{vwlB@JL+M8MBZ`mFn9GlI{Hp(ATBqXE%iC&QFoNK&MKwk@_U564-FpJGk zxg6cQakIQ+VV3i+%HIg!E1sJXb(n0>t_|+VFene)=)R$L8opqEysSKKn!guIH=`O#r)@wV4G#$yh`QvPJy{ zI`+3<=-rubIt?7ahp%obf;dd0QM`ohBP@t@kXJo@{q zahj2`@;8@MrODg9`Ih`> z%WdD%7M6>(*zJmbG8dAmhgQGpxmWm___XpSOz)mDC<2=HdG2Kvw;DC4;I_ZRA`5>@ z^J~lPrTM1%;jCXB5#)z-t7FxUwRwZ7q7I{-En4h^5#7=BqL9UJIu|E!nBNJrpv8D6 zF%=85`1SS0MUC689eTQ`!g{y8hP)mdYPi-0&^}o)zgm<({9av zzSU5B+igUZ>Xb=khOfQn7H6YIx<+r9vR;v-7PTf=fx`2fY(F-=s$k1^2yoW1;FI&* zve!20%4n}R70a)2M*b{TEfi!|IoXz0$SHS5WQ71lIyQEgihzdi?Y%p9?r)L0kdu%Y zH9$8VOPfzH+ocf^5ti#=v?lwfL1mUbF~Hfu?;vdBUFf=}(^U8Du{CYuugc)cv%Vp)Puk@D^@k;9tux(iAniE{qG zuWDD}b4fZvtJ#m~qoY;4DUjyugk(qd$dXyVTVi8c(qihr7k^KByQdgZ`d~YUaBlMa= zBTXvc&-)i9&1je1(Y)-?D`Q!|@TP;kSw++D>lq7)ImVekC-klXd;AlR>KiRlyV-?n zM(G7y+486ve(Qe_rUUR9E2809v*Pyn*!pE3E;304Ew#EgQmIs#2VU_ma(J%2{cnu) zp51Jfy@G;*tLwh-u*~7S$MCNVC3sgF(q|=F9O-`up+>hH?u|ZF?fFE%FgJGC%SrRT z`EThjT*A2-scBK?>&~dst6J1R%e%uD_0*1sP)7mlq|%!jXm7Y|h8%@hm5Xz6`Pj5X z9kkiS{%;RJNG1J0-=-Od*uw)cg$Ez~A|>4;|7jw%O$x~E-P#k>PtO$U@V>9Na-5}J zectu8^$vg|zZu&~&xMB)klvHB@=4-z2L60x^dfEf-xG9%0|?<>r}F`)0nL63=rvF9 zKGV{SjBro==B545T;r{P!^+;=>GdSUa86ouSJtkRo7>`bjLrA;OXPZb1;~f@u25#6 z2x1-=zN91WbR`Y<^%)?BsCA?JDQx8G9WLHc)HDbDV3n$Tid5ftrnK|%)}~^fTH#m_ zyh>o8Hw7m^5r4MZ8I@b_cyl_|z@rGYHoar)7Or*oDD-SkZobH~F;7FC00vu`DKc(6 z86_T=pKk~IUqk@B6k$<@_le;+=3Zf3R=rzuBw=g!|hQT**0Nqoi_bkGgMVw3;*UvFf9`2G8T zu1=9ROE~D_5Bld%R$;f%&CD%MN2v0ZZgqc1uVY+ytjlO;?`XFSZ(N3)k7 zd9-lT+{$nHJ6@qNkC&&2K}te`bO%}b(<6O~U|kxsQ=L}Y&nz1nA!Yf+4to0$Rl zYr%H|P9NR9-?)J?s02E~*~%zlKgBk~7qgkKBu3W>DrO1lHT6ft+)Ot35ZcbIe0D9#51#^nBhoK%ugYXS_@BS-?!^C zzi;mH#VqcMuh{Y(_w%fk)HaH2%jF6Jp9%|c9)uE#J=iqN%t zDzrxy-oIu}Yj?`+?2r|{mCK3|b-jT7eM<(VG58D01;0@Z=?ST4xM0xPazvqSu_1(2N=k}@!^ZQ?-F5jh);rvp{_e|5 zPeM%tH`mS&HyW#)Ev+qKH&~hRH@PgA4Q7V>Q5ukiB6_K0qd(Zg7VA57%*_{Ma0&T! zd0z%VQMog|hrQ64z@)dPIy0yrs6-K-X|4!(0g%g0QZ-?U)BFUfu99EM+B;DkmmwvI zu@7)w+iO3RzD|OG4aO?BoDq!oO3b)jk&>HXjgur~7TkRXUK+WQ4<6ukO+@jxoc-`P(uOpA^=HxWM#-LWPShUGRwk592a*&*w~Z0oSvT-xYo9K zWVh_R_|2#J`>|f@SU9Fp($8gT zX?I<|{#2al_-+6xPBZ8p#1TQi{ZMpH(1QL7IZ5X+s=o?WjI)6lRx`?4ygv;N@!n!3nANZV1U!EiEyuDAm)l*5CuUuEx z$H&o;-fQrM4|Ss|Q@)B&oz5$2 ziqMB|XpIZm5ZcU+-SnN?{0Pepo|l+BD-RQ;*CrF|^IZNMYo_U9>v|7pGfeA+i($ir zPCPu))sDh81Hbu<8$jFD3x&Ww|N2Iroz`!+dMbC1?u3z!ju>o@^?;4yo}N;JN{(Mx zHv613-QC?5yN&3U?Trm_@4dI3MpGrmUu^no;Au5mX7(!|+9vIs7?~I|NDM@rN8dO4 z`3998_CsbizW%LZI7*Cdo2082)6#T|$@n)=_PdxDk*J#rBRngqF#+z`H4xsw$JqZ?t*kwUl(Gh$l2(jCey$^Pi?3i?jv z5xmXeV@Yz3JUL0SW=IKV$aRgCYT#O;|H7mUlbm>AUhcaBUf&H}C+YcWy&w|d!*z}5 zfC#e9xmx~=mVKvKTTdA`HnGo4Y|qVx(aooe5iEgqe#Z{_LZ5uW6($BTr)e;Vl&78s z`n&rdeR&KTy?CwY>B)vOL>+Y%6xz}yJ<`+Dc|^q4b;S~OCv9xjV@^)^WljhFdM`SR z_3qAy=ZFPejZLNlT(Xu%Vs=90w4kh3uQQ?H7@KkO-qbACLrN=iFek2DSQrK%R5~$~9$-%43)H9M_&NH_hWQ+#3HT3UmxG^MopR*;hEP_a?&! z)enO$pvQl^{mu$e^ba>Qu%|SRW)RPi^5nw9%-Cj9!)QE#Nxhz5@Xs8_E@|#X|CK=l zVH*q?i{QqHN@f6NlbAvig=oo9T(P;=~_%j)~-2A6Ox-DNk=(Il(Cse_btIlfn z?W=mxo41`Y!!j7s8i879RdsWzUg=1Vin#q~uJ7SGKw-*xRpVGV9QW_zoG=0dFcuaH zB@H#T_aZKUGU0J6p{1I|NX9yMV zdT*xV-|1wTwl2fctq)7xJ)FA|FIBgGPmJZss3jy%Ud8?oPHv~U7Tq9!Mu$5~F{m|c zIt>(0XPBO7ox}zZl2z7J?Tk!ZExWDkGBJXo%iW!w+%)pLDw}zSpl0=Je&^OL@&T_> z?rbUa_wU~nWd8ftgxu`%pDvehlZTsppI~E;y`zaHjsL>QJJr0^cLl4Le^Ie5^qBoO!X(jQDJiP`x|DXn z5C}jQet!N{4WFi<^R=Xd`LHsBdUxx$Zy9&!+(}_T-XrOAtNlv-1YP+qf1z*jjg!Y95(y!i#fjm~fC^ z8>}w6-nvJuxH~rJ2V|~>5(S)~3Gwk?h%?>Q0xJUh44Zkl^&#RpbzrabE4dUauwLgd z94^o)l)H4D;4Xcyo+ia>7x)TsdA^8CDCRO!aJXQcNdh};uI`Q7;C0`eH@2Mn{W8aX zEN^YvjpBr9N7}*AwX?+Xg(T?8y(tnNx8{=dRLg%~8VGN&vmg5>3xkeI2o3}-{m^w~ zO8()R?gKihkd$Y7O76?`#}Tc2GqB+1?%8J59uQPD4ikN&qjv;P&Q@aC8%%tb@i*~o z=#5{Vmg?i)G3M6W%Gv&&M5CE1vf0b|js>^sKekYYr8xkUt3r zsEV~gs>(&!dTW(AfFLGlrwi5Ln|9>V_e1|i52`b9*Vys;bZkHPd=UN^aeN=q6ZC?w zNR4lt;V`CMHE$OaHtTr<QLmymNEBa(tlQZlWhv2e@(v@~8kzcIc1 znpJyoy(x9uxIn4atF%9Ip_fGiJgL)jaw1+;VE?M`4iH}BHD6yjjjO8!a)r%w_VjQ* zcmUX$7aV)w5!};E29X7zC?EtdV0{Cu2)*6i9p?mUWPqX$N8}Y z%f(1Jvk9)~I!&>W2!pUqZbSrO5k7tNG!Zee@8*(ClojsxjM<5po2$MIy!O4h#^p7v>eQa;^L(Ka z`SQl2L1xXWE72d~9@ur#UI3Bc>Iiwrt=+QM{{Flm+Akzyw!QwLiy+(k`M)^LqOBH( zVa`&0x#*wTS*m^fnlJgcggcS#1MS_T778~lmffE~o3y5)B2_Lx>ehp^=r{6(jhm0i z$P(nF(#W3MGVvs3NP&sBSNp_N9G{qF=^ti(2f9%8!@egTQ70uO!*b30YhC-xIPT`d0WNjss!(Q#5|dc3L?7-bh%oU?gAXL?W-zr*9;4tmHsz zWAQ_=Jxgk#N=`TqLkW3r&)eHiw`RcDavSxK2~aATF+0CvZ&Ok(BwP!b zraX~xp0BeROkFnL>E+CPTj!cRuE@W$g_ zU#qe5OoIPo>NIxh9n7IBoYr?;cz;a4&O+zKy>;!aQbKCy%WO_l$XT+C=d3^U1;!psn`L|ukOy(=D#%q3kdq}bRLzn&Ohqj zYedU2Fr>9E4p`XRTU*cMRrg2n%e0EIIivQ!Smq5yFP^T&G*$4PC!~3BAHzNW78byd zj#GUTlJ5w=%-7CxsZ$V#?vo|gp3i+Prj-i$spwcJ*HBQio@shDq8AX3VQ+8}rT-_A zgE#=}m63_*AU#heqxqnl0YHS$w!$*rFQC9hey)b>HVD-1snQ4!e*LmGa4Vs`{VAx; zG=;Iei^5Q$;;H1(d?0t(GE4gp{(tM)i@=%blm08R@ul_syVFjhIFqjl2Its?d6%h7VS0fS; zO3BwTBNoB@1h`!&KLh>RWiJWjir$^VGYhHgt~2-36!fQ z@Nn#t62Ev^m6!{nZF1J8^TTb$aMCB{W7&#?z8zg8{7qORA&MRD&$7P9Nxva@TIo2& zXYcsPED+Ru*Q_ZM7}?kHA_HOHQZ}%Mp;ECsTYtY=k%a{Wu5##G9R*{Kvz`@-jeuYMmGf6pN$wgOJ+6-=u|D?LbSxNGo4BF_m zYeHu9cVY_3b3IiEU)T%8tUV-bk*sh1;pAwp^tDCQe4@rbpt5}nwzYaQp=~=R{#`i3 zoa{)Q4Pn&EJrePXY^0j0_P9`+#KgCMV3r0fQY;{H8hZc_G`yEA>5(@|OgeH5)R+## zXE_I0;kLr43aJLU^Hr)xo>o??tG#i?Z{Lzu53K_#%!;4^KJUKhtJBH~k9GN$EYG zyaoVhiM~qn1^<51w)BL2_#CtxM;xk6gRVS5_Bwcb3i8(dwcz03eLWMnbb#`q&7hR` zv3}zzVk3W;QRaKt-ZsSL0K*OB!*Dg$?Fw({65`QL}}_73#TR#-chnw(0CISZ|n-5nnlH-IUVRa7kbq9!S#kC&qhYe3jo6i13AyO&iF9iezZ&TOe~ zqQ-1meIJK&kDYwF!}4$XaefpBVr{)E>DqbX5_!A;)zIDJ6WPlPwO9GV_g#UccTds> ziVOChg#%)bCX0=R(~Sk#II1$l$oLP9J}56 z#Nkm1*t!LGg0?m`yoY5^fgxb6-I&)p6^S=v@7d8&eY5 zg&@U!Gq3eCFac{`p3sSTVxGuQTzNl-%uY4$rcp*->dNY$-}_N_uHKjCK2aQe-(Wh~e= zXs^syPZM)pQdsjA@YNbmb7=tpr(nW?n~RImot&JU(#_X=dA8aS6bC<_c?J=5`S;SM z$Rh~Tj>;z{*nVMAPJX|ku1KyH`^$$!&zVfYPT=198b z@uKk?wqnv~5TB!s8X;aiA2T^>(FC?DI(-PDgEh2F?g*jyITtv()_Os1P;tXf^6rcC((gvN+B&T@Gw3fN5iWdP@^PA;q2#B%&_i(K9g_#BO`9B zzrXl=aQE_3{xosN7>LE+NNS?Xn#S;c!c6MjAMVg$ivhh$=2#tARETcKGJlKP4agO<_vqa#}OB(luzZl(4l_2FqCPI7yj%EQF@KZaVoIy-YN)QMM0K80r-1#pSVJAB*L6_yehc=y`A|iTDcIQra zX5xTG7#|-Gw&fWa{ilq**>Ez0u6=jfhZe8T^-OMrZhH6wx#V37EQTp`V69V{7<#BR zrp4i+Rvz<-%x-ySz(@@=AWIbHj_5_)d%W|tvn7yvNcA4XT(i68a{cL73VTLF!>ynP z5LWi%Z)d(sA%td}$zM3aN0*ytouwZA@H^Rg4D3wLAxxk$aLC9s{rG|U$B%%5)Zn@8 zb#rwJtjx&29_@@pVU9OfMr*E`Y)$4pc`oAqR5Z)SEB^L^$Nwyt&5)Xlxk3Ir^L|7| z%i0=T|CsZo1Nf8Mu^HA2U)-2nn>BZr)B{ZMjRZ4V?_n$9j9zR8W%t(96V}JsVRZK0 zTq6$^9}Q&4G7zwLoN|re(>;ZHq7dd_exjA0h=c^-hy@^AFRg(&i>M6$zl(bdM%9p; z%U0w}=6OfD%k*I=YT+Q+KY(5OAjL5P^B z_TDvYjH{6TO!*3XQ~B;DUvpvSe$WsjJnBay4Bg<@d~f@A0+xPW5ZX| zkctFjBxk257~Bm+sJt7p;1=DHp#r~iXbQQA&zA1W@2-4)YFm_>+I=-YO-=#=0@XyG zFQAe#-TP+7Qnv14EhS)q4T&Q9!q0VT^E(jtfe> z_Z-quC5`BL{0Fko{ccM-Yu=a_KC6E(R(nCO0-RWB6Ax|$JrgrF*C`*zkfq-~-u8BO zV2@Po5l&oElDz8@7M{%#-x4#}6%?2TxBr%^ftiGScb5v!+uYnNRyOWd8}zSFn8|^f z>^ZYyr03LHg);+b)=l7-=Wk*^|EQW>guYMcVXhJyyI9z1veI^%y2 zNQTBIoA+78TX%JI59PB}N-CI^+Nt~{O6%DZ4fv+E z5x7FM{byymcvdcUf4Z0Pfo{r>6}iT$&HLw~4f*+CGmVrjik6?iLb?8YMTjXl8^}M} zkM5q(7oz45!^s%v85qE6WCsTaGXd>4Z$8Du$aURmn(Ua6WlO!ivr+mZi#1>BINum1 zyfs&07=aceXUCU9b9r(kZoX9n_r{H1;o+iO$PwZNjeD$974o}$RYas3&;9<+&$3$y z5#IKseQ(>|-k!mn5knp`IyxH6v2$ObrV$~cThkc)X=L^Z_)o|Q8i|~nBiZBP<;A~v z{OD0I5;0eFc7E<#?|T`)pHrLGSoglJqM>`Q^5aZ&GaYY-cbl;~k7+;!QBe^IE~*p< zF`tpGMX`kuqSR$pb+NRmi3uD}e(p#In{FSlXKpr~NZIdqzAw&SfkpBjb))b)l^E|^ zK>-)uD#|(nm<*)b5I2>B4o#MW1o_b?zMsT3Y!!Ifa!^NCSHRH!nNkDedLABs;N}Oq zG2pY6nzm-7rruJ#xl@Q~DXog*LH|C@tD&eV!qPnLGo=wB zCf!7~{P%Tdqg_$zYHC>iU}-?ZKQq! zxH=|q>){+=O}0&YEw_gOrH@6;D|GI)4cn(tZEeQ2X(}$`M@90`i~(*D z`@gF!l-_I~8MWi{-baLk8!g{HGVaWoeDbE1x+2}fq59VHv^IDFP=f8vO<%xQZEZP| zUp;$_cp{^`<$N6husYkjjotK zesX&{!5s_b%2q_Qg(5k0rU(!*)dR5RMgVCP5KlBFc>}%UumSl23tcQkR^tb_(MGJZ2KZJc^T%|29iOTGXzpx zS{ej4cLAIS{cdmoXhak}J@#)f0%z~w@86ftpJSx~w>m%k_j$6#TqvKkMJac}z%tGH zZ3m_NXqRNl#14%2MTFWhX{<&mdf36%1}Y#dtz0=P?>xYRS2QA)NcMaI0sJn6pE;Xo zkQ3!faB8;S?BiC{5FE(>Q~WjrxR=s;jp6pcSi;6a8Pz&tQ_B17F99G$*?`OP&;4m) z;z=uBd4Q!Q`;iv7ii3p+3k%cCknug+2UU%h-{if(4xrkUA0aapN?KZOL+O&hp7+4j zpag4pNX$B(_hF$nvK83_-Lkr_w= zSc$+w93jL6Y!l?<tETN;YnQg5B;-Fh{ko zi#16?!}B2~CY8p%JA)|2go2nj{8O^+dE6Y1iWqvf;yYu?@Q{Bn?7y5%ib(G?2-iL3mKKuJ&I^6( z@vIN3ER5xrs^XCvKI+)O`_`X>>NjJ0I%8bm(lh;txM%kzB_#nvlaiK3PnY8=#{-?I zSijuj;7?cZh{7-cO5n9(Aq2XYTqQg`J+tn!+T03j|L^yd6cpTY!gD8$eM!LJXVXLWvIHq%%ts*Ac1ayxw16$x9aR*-3 z?Uf)`c90AX3w$1Gx}Vqw8` zCsK$N#>5h1-dbHkQ#5q@^}R@h8^PS21a!}<=0nvVtI4l~abH4+4fe5~;|F(-jR}j0 z+*Q7dg#3vHvT%=ZbMFHq?y5mx;q5OBcqp(U_i+H{$iQy_xZ+*NE#;pF z9y0qJKuQI0gPS#`xEP|Q_Ng*X80!?OUW~gDM>0p?Zn!98#~g?dl4@Bf*d>eUanEX% zRPdPb4U_w^8-V6pXKCQB40N6PNrLl7h;d~;tYdkZA;OGQpRQ&pLfCdFSTKe~p4`pQ z%Id*0XN74X4ggq&hl5>2v{Cru$3U7m#So$RJ28_wI2ZRfA^b&M4ice&cyB{Mf2G?r;Zq`sVYG#brT?ObVH;d;Pob zyZw(^*1SFiR;)pVDzUPp!&yY3XxRjw`+Qw3NzxZydr&D^2?-y-t<0F?vuElV+YpHJ zGC}&R`p*xiBiO-Zgnb@AFfAsqPchr|F*=7``AGbSNIX(Ha4HUJRN?X7NRFrvyg~nI% z5B&%u=D7<1G)$Wiia#(<8G_HYP=aWc#JY{dKFWmBI!gQ1u7;^BJ!Q<;A2Kd_LoUNy z3Nk^Flci-P(5XS1#css7@RK-nZ^5(1{#83gak|sff5Jk@*DyY+)xP8N>h{n z)7#T$bkA4|QiN?W=jY0Nrg_CbhdNZF^vnO6dn%gr%nhtB6Yn+XOxQh6rs_sB1wt> z(Eafe=mq-CFRZ19@!8qKAxm7cvP@letTrF&u;AdxEFOiHA8_Bb2Phg8v~WK1ZxZ_y zSRzL*02qALd-dw|>sv(oB)3dh+4=c7c)d^hb_+^^XmH1BKgl>)%h_AXnPFE6{O?m< z;fQd?Nc8{SdZIqn0pwRuWJ40?PENYVxZHfLS2ghCBqcd-zZzd&T6(3Y2kcSYJw1(E z17%5hgIj|iWAzE}SligxSXp5mwAtYmy)`wZ@IUC|8#B%yJx>W%tY~Zml3VD@ z76VP(g~k30Ld4;8+|URooZYS;-0f3i7(z4lZPWXXil!nD)-~K9OBMI-r;tQ+WQ(Je zJtUX1gM$_H^{2tWW#HAZ9@JdAj7lFz>IVQYNVvT*s1CpmRh?0R+V z6V=i^0gu1n${e7$$t{k-9M}r^Q&8*5J}C3`&wsRac|K8(IL-S25q6M{cX=Vi1U)du z#RVfw&!MjGz7T(ByyqEg7;GGD7HkQwHGuP{*p3bc1tldJukwV=3Fw=zu$%JVy?Ymv zp<(CqqdFn%L)nJ}_*lZH`Oy;bSZU>oxt@yI&xvDFsU}m+lvsuePJ{#q@4Ao z<7=b6zO8#LdJ7c-*PL9LtaVYwcm(r`9C4u9Sy))KcXWing0lfPz)lVEX%koiA=orr zUziKzhb&fcaoXmT`7=6HC?UnWM*n~S0FTvq2Wa@nGhM8nZ{)-HiG25~n(DR(*>gq6 z%4uE&YHU9@^lZ#Att(?CPzWl0{=gZz|D%WO>YQodGDgs9P7Y-}$czo6jv)^yRd zr=xqK)tl3+$0dDZ@Tu(z6-T}vnkpvD$?wGE_Fv(Q!KOcD&hjv@mXZwmrbcL}E1oWM zl$$-qE|4Dev`cgSY?G#pckfa&!kIeSpH_*8zJK=czFu+A-=>@&QRhVag$XIq zYM+I{*D}Mp8dPF+o4a^#Ew??mdp5SW#i;16KZl%uTvX$E%n|pvt~aiyF-kdSW_A`l zS$fiNzFe%^^pq6z*&&UrSc-y}xV^riA>bjL`3f%_=Lk$tZ49L3h$!{;Oi4eGc%@`u zp#OF&DL^Gd?1b7&(8IuE)$X>wp=U%6^65Wt6U?D~Nu#vdyz_X6@$rrojh8^CS4`k^ zvZi!5N7cKb^2;DmnN6~h-)K5w?W3M^K=QEMm54-1Gvb?&`{jx-au*<_|aDO-UOoJA^9)Tz>?mFcjSgY zaWQXG$S>|+l(t?s0GRvlveu6RJ9~R@ga*Lhm(Nv)MTKO&*^4V+k6IxTwVrqi8(Iuh zSrDyDWo&FMPy-(-P}MW}w=++k=Ir?$JpIRl#-%~T)U0Y{T3 zf$#$ICF{MVdsy^d?+Hd|UkTN5%gbl(@=e<|Mg?%M6Dye+)i@DTP$b2F6%i2u2Y9N> z%kNO$E_ZcpPBD73C>lR?YmZ)O;W(>-3d@iPh)1}H=w>D393^ARF1TfvaS&pus(r6K zf5p)J)Xsb(E$w_wLoNjG4*u}R4mRu?`DwiYEHA*&vnprH%sW8k14JXzLgYvW;TTf= zx|^68#{{@a(nvkrXP)KX1<-$>5{$};I!+e7tp|ROR6GTFdEtDr4|wi>`<~-1EM1xx zR96OjQ0gc_g*A)+Km6H(oho6Qp>tBX$QjfC!pM2!H~XsLs_T>Owl2c@JCR%hT)$p* z4hiAiCc-mAO%&>Z@}DNF{UPrjPRo325Q_q#0KGn88G$QdO<8723bDU%wpv8A1Q?ni zbV?N;e*XG(-)uLRh>TCo5F_^O@(=GbZ<#{lJ;^qzzgbIJrVL|V1$P5{nf(DTGRIqg z=~hYxt3L%N}^Q~WUU1hLaZFLHU`4L%z`^?WJF$ygkWP`55ClP58U&=f8>Cx6 zK)NKQ1*B6NWRO;bp@;6S`+Cl~_qx=z{G-Br-xK@U5jY2LP<{R~8q~KT4$m_zmZT?x zVgj~uxTke!yO0B5^(iMS%R`P`13eXbsrzA&PPB^uX|}~94>-oD!r{{_AV`)#EWw!p zgNxtoH6n}vfFfXL1cr0~8Zog#1um>=NB$*5BhQV}&SS;)D2L1K8=a22{@01jf>@jg zH!1bjr_R>eIVMf-qxiBDKm7deZP=^Y^7#t<{>NxfB%SFoqbfb2+7D9#0rfYLz008C z0YOLu*aHB^u5fxEtm<7{v(?7vux8H#TF4k^1rSddC5;r_q`)dF1Y(e-C@ZZgg6kKe zg8wg6d{zV8_dGTou% z*n3}4Sz(E7UzF=GS{MI)OHL4qmF7yQKuxV6hQ<^pe}f>L07kfA8wGGnLQG5uF8U?8 z4`WA6Cg5Ho`Gn7I@9ZE;74l;M*z?yzW7 zh?jh{(*j!O@x-3(V`a9DvJlD>JTOpzd@e}b0Ko>Ou0;6(JA#}OK^}6>I_&n5f~H=X zwKL|b-geFU#?jW34nHL^H+GfUxHyD~YQ>2s3lJ!gZ)ioFAnif`wMTJ^)!v4TEr4<> zq*UX2vhmu)7ET2QNY2S%UTl2yC)6~hu;=|pCnuR1>DN~`);88h6Je=*0Z)DAb!Wu0 z66h)Ucf7|7NOlk(7{Es*Ll9-4BJnuE__V`wmX0`>q|Fx2wej539aqv1s65UsTR#6_ zGM8S$TL|MD2FC`-yC7?zMREtgAK1+w^AOHG@^c517x;rv4fQsc2u?fxI2Y2*dYW;U zp%N)~B0yG&3F|%UFOE*s)U?)%uP=hYWgf7!`y{k0>Sbt{8f%TQAdfhiSW>Rl`O zd}f9W{54xQq-)%-ji%jboe{^ZZ1b(JuzdFw@xCYBq6?PoST~Xz@igYKvl`5n@<8L+ zeXz2Us}syhfRV9KE{62#=0>KXBcjOvDU??R4^4m0vXI}+w$#2WRPz3k5$39?`6)gg z7b4IG4t4oozkV${^1~Q9jU9DZC!Id;#^XOl=wkifaUc2A?}T;yIgBs6AilOI5OgD2 zJ|$7(>bXW81@#P~h}ED(gnv3NMtBjpsRCEZ9us6UJW<`q4=Nz>E)VeX3MCy z$k!RUaT?Wz8!LGInX&&&)=49kob4ZSOxePoKIdHe?XVm_ONf+aKZrz3)9R-wh zkz1G{em=NPL0Tcu!bcT$vGO}zEKOLqXan>6A5JE2aXbjf+or)O6@Y18qqDPQPSIRX z5c^~wjWmrWP8uQ2hkRLTv)k18PlF6UJha})Y~a47Hk=ZBGc)q^09BiIY0>or{YHV~ z;bYE-uY7q+1c#5jl5cSS%i-35kxCx|eCnQVJ!;C=%TnL1%EkT8j*pK4H0b2%8Nq2H z5V{YqGCT;A2wlW(DFnO$=>(M1HXyVM4GjgMfa@b^Agvu)s`mz25iG9yx_XfqSgP6i z-e=M({!30;S1&f|sB0%G(64;_ z!}HLEW<{P3E?Y=QNZMd}vHv3^MG7J7vN{cLiHeF+Tt&eHD-ND&_ansgFK_}ULF24f zw%q&O5F`Q_1LN~y4j`rj48B~WWcbMwdr7y7#shoBaf~-A=P^~x9K1pI2M|Qs-@rb@ zFnHDe^2;-t#IHgaQLk2xycU`?eWwh;H1zN86$#CiYC@GJ>*CczKd)`=aycY^9!HWL zAa9DniG=Ki20@BOx(2xP$J9hM?aYAl?aGXf{FR)<+p6UXOYn-~5DYG0k-ki8Jk_~~ z*FKBaK9AQvt<^iQ@;<=$+Wm7bB2M?d+A>jl;<>@!lg2vFriujJXljZ8gQb<_9lUmQ z;PyNhH3r*t!{s3nv#_(<1)?v&hXD4?JZL|3Op?GopTffg%VEC86xr=1T-0qpz1u|g z<;xH}3v+Y&DrC}Je#`j6!ouvzhNh;{FR{Dp&+&}T@uuDI)@K{^o}2#fDkv$nDd+}W zq1O!$tWvgoSEMpNH(53DYd^8BQOEZCL9*JLjUUTub*AI{T~0`5g!n^A%t|Ix($bs2 zH3FPA(BH_%xWDO^pblOImi*8uw2rGL_|6rhGB+`@T%KQ8s4wM(UD4zXMgMNzat9{Zbd;w z_4oHrwf6M+K47PiZCAPP%;fL$@$%+RSc!>=rKYArU^bJ*6JepV zc7F{Q7W8MHtIr93x~rIGrU&=NYE&4qp#NybeeL!|WqGdd^nimIo!~}MT6A@gVP{o zY5Bv}BmxgF0bp%gD*h#{Ss*%0q7w?qomi z1jU5S#cBQr`}ak&YKyOxyC2yfPucq9(ZMmvcJr5y=G4Ud!pdSm@;jXE zrm=1~4@=_E8aT$Hqo8z|AP?4o4W|nMIvtJaqe{OBnmoGt9)Eyd2L0|5-sPhquU%PL zv9q&7xQSw`Wn^T4mUj{tE8F)YwsM!NM6zm+j&qOF=eWRiKEd`XOqM6;z7evwLZ=R! zy3qA>zw_N^x7pSGX7N3*6or*_-^>#nxPo~BU30?kanP#d7MDOA2`7>n4>_o!;HbD@ zVP%D}|7&)#2n(a-noEJBqI{o?6z`AKYfvp7te8zMx}0=x;ALOG_c0ZL8HV)f+q|kOTw?)I(^#&gNKBmjBQLSg zyRL4aO2NMc8@p5q(I!>@l|=Z9 zPiJ4kDnL+u_W5yr$5{XTiPD%<^?e%VrTO67{`S3@XG*6l*@uaBLm7+8J1P$ve3G=w zCJbzMvJ48mf44F|G_pO5EzgB8z_X6&!p6o93Vy2Gwn1U3%p^|Zfk(N*qSB1z3+#}f;C@XR=T(s%>3 z7{Lm(qWG9$NTwhekQIoU^e)6CghKXXWEmb|VIfl^yXu3`lP6E4PH}m_T@Oz?UD%O! zSBeP_q0EvzG5Y~8<|lEsg4}2wEO)uUx%^O{_+f|E-{q>ueEcSsJsE67JTK2b=VtZ!E?!)Qcyv zDoz@!9Id9WV=itD!wO5E$6cXDjt1 zjDSJI7C8k)w-q`vNsS1{2uxm4P5PC#>7V;T9OPa>ahXFZxe5a%GUDKi?zYRyP*&&W z%Lr1zGygTN4KOD6q3=_cA-we`7CWD^qg9|1{Js=;+}H}*V;2d)%Y!Dmegq)_=*vRi z7SJklUCG`OEP%!CX%M>;AT*}}_$RI*1tfPD98Z1IacD=-Rqay@e|2=l!|2vtzPyIq zRUEAL-KQ~nmkoM+=^gFhySLI}uCaloTG5zi=6#SvNR4`ZE%S~>$0L!I-V zs*UdDmYn>8@cls&+byIX@OCH#v8Wr|y->=yficvScLe@1G^rf+-1pHzL3@dr*_tih zModBia;%`*|Iko^C|U6IL9&4Y^VvU`T^^{d65vm!3~R#tr7Wim5y$QLnZd0f+Qh=b zV!~PhV&znvoeh$5KYb2eD_c`~jV#mfR|XXVy9fU?b5NBPRp}1;IRK0-XCA)B)q-3^ zIjS2t{~EkWD5$N`!>NK4(sE$07f}1TBC9=w(Qg6@g@R)VsLCK(y(#eF9$elvG&DT- z7p!erX&E^8mcX@PqG#>*Zqst{# z8!!#Di{HQRXX!5}U@#!w7o-xJ7HSa0!Ij*hVsk*$$Uv?~47wrXROIA-S5WN#!UT}J z0m$FE-WJ%ib8!6YR4e9>234(Q*sc8LrIMb{d#iCFUcoRfFTiAf60iJZQo8x&ix)i^ z%;Mthpzna-1&AU)IX3-!da5Acy#!_s;Aj9A*HLiAee(uCoB6{sCg-G@h6ZZTVvW7! z&Q79bdoMnrEU2YRP*~B}o$;vQ9b-+h#@P!M#d*N(Sz0nSGNR3~#p~b~T5ansYdN>WBfmNvH*3M3$>qq?jv2=cP_q4XQipZwRvQIH%A&lsm-X1ncwR&emz|KZKh2<~%B)qL)?T**hULn>gN6eC67bp<$buryFK3RGz%1E?1t zb8vuMS!@P%P`bP@NzI|Aa%30k)E%wt-*14W8MJ@!Go|Am41rA+0Za*2=AmzImM_0a)!mt)ZPpCo=9G8fJMIWiJMx)aMiDb3-osi_G!2d7*d931ep zBO1Vkk&Mfr=~Gc(3|X&4TS`I#o*3$1(Ts;zMe3I0IXIDK78Yd%NsLy#z4eDjx>ZQh@y+o>J^?3j(=Ng5c&Jj&&xYISWK10#b_!aA~>{Mdi59*_EUzy zF#b@x3rA`ct`6Q*GcaW+m|Ivs=3r%HWAxo$nNHQg&xs@MK%8P=+^Nf%pyiSs4yU;Q zitP7lZie*d=8Bs3H(ev$6KU1*rhh~R?Wn13smWy;L(I6*)5n7o5{0h)oUpBt&CWtb zEm!sK;8wl#FBYYi<;L|x(qzlWrZ67Kp^$!fL(Omt4n1ITJ`E^UQHhu3+uG#R|IkDB zYLJbv+54HZmrA^%$WKKPz(f2w#Ke#jgS9nJOiVl_DB$Mq{#yC<*yz~im~ciRzvuNR zMZwBDbIe&g|K6DI`-0~kHs0b3JUqvKLAuvw@?QI~N0*pFd z7~ymePhlsZgyy58y^&Aol9`kKCJlcaCm$jyAW~;GfD71+A}-gb)^=Y80Bh{QEJ&!9 z-G18w`Lt8NSVOp0*|NUlVQic8IdMvg+K-8u8J0u^a8ip-NQhXZXbM$eDv0gr*v0*U zya{#~!?uu+Ucd4QuLHq^Yeqe;mJXy&5h~kK}nhN$YP^qJi{JdmL4b4Xn!%NO==YS*z(v0!7XMR7>kp;hY z(%FM6$mu)&7|vZICWZuogG(1be#+ir`*YxnGW>}RbPw5;AM3_lJYY_O%Usq$BEhW- znrUufA-IUOfGQQVA>KO#=XGLqN@;F>)@0i;A;!x)k)ENK=2#-w`69Y2nyRIZG}OOa z=}_t_*G)%Lb1Lw*F*rDQb?=l+X}E(x$~BBD&Tobnc53tGXxeG=>qM&b`yKjk7Ebl< zPG7uD5Ec)a;W{!n)#1hv8Ds`LJ}RR)!8Tgo`;03)lhZ4X_u?*2^|gVe&L&OHP9opy zeNuDs%bK5kM(1Q8#>Wp**#MAS*BGLGX~F>4s|gU<#Gsw;&N8B}!*>gYiO3vp>wFy# zd-_Df<=_3PqefX_qP|DR&9kPCm+DF$L?KN7(bs2Fql$7#N=k5kcF~%hJ`EF|yB$v? zL+<5%OSEah-MVYo)&a*B$lGH@u9=z97BO{l!f&_SywvG7hQbcLf^tj}5;Q~rJ#s=A z1xy4z1edlw@;+e5z3a>g=JJQbzl z?CuZucOVm{!)dt(tbq`pJZ?0YG*|04a>~j(BtMl`7knR=4tuZ|n8XBg?&d^5I zh4Zn#ASnrue8J)bo}=(8 z&D%PyfjP~kE_yLBYI1@e_QO$7lAu1IJi;SEtNS;38V_*5_ zDIz$d@gJ)W*Ehmx!0xc8@tU0Czx-0~a+1?N!^Ne|#bxWc+me%FIKQwcaHxOM<#a;t zB-ArJR{avLr9ee(L*w^{@367f^YD1@rso}@M8_gb5PYTJatYgVi>!d;bxT5Ep1Lne z3cwkHg^`0_|K<0ZI#I@Ik*_rcc^lqaCmSV#IFJ=jm*a7x4sS8uEAw|N!Da(Q+7HAn z=4F8jrAr@B?}M?BkjP}^UuKK>Zz~2E$@qfK`kfnnNeH{m`wEjML-)LHa&cPe&=z`1 zZcEd0gc=q!WtG(L6%=lKbpiG1G4Fmb3Je2OV6b_M2hH#|vODg3ho^2~`xzAT_m@vl zT=nv0i+)i?&!Obhzx7^;(RzLtt*f+}|(o zf&wMB!Es)JQ>;gSYTO5cS4%Ximb~A-F)(_l>uC5|`}M)X(lJ2yENU%AiGt&FBlFeJ zU}zXxcsPS1H5ie=itOX#V`qg%cE^#nx=$nQDeOS$p3%}0T2av!U7lKX@25nS`>`fv zM`%~VZLKHnkLs%tTdK^Q?~UzN2VOJ3^v)|JHWiKDxg4k3>!-;*^>lF-;>$T$*=pE? z)%I*(_b<){opBo{qzZcY=?2~N-v=)}VQ0r|N9yg6;HS+CP70*UV5MPi8 zh&uz)DN3*(yn6jQ+tE&Wb)A5abcHOBXvkbeEQhFBmET1b*q~r|J$mHaWr2m|`Vt+T z%+iv~@{9Ta_$Ktv^!E(^`Z22cQdLJqI;VfY(ZSx6pYxkL{5zU8duCai92C$dBZz#W>INVm1N-daN-kX$^R z-P}+-b^idb6Fu_GjM0g74ra#J>&vbe=i_Wo9JU@dq?g)mWc1A#?D0L#66AYo-?1%utWGnh?1DCPr82FIyyR+tA878bpXrG>rpqN z)$=j^AHYr%j?0u~JW@JT4~>$g6^oKz+bBHzFCsDU}fB{FpF6 z>gBPkep|Z&uvVvk;YKfByr>DmHMH`69z+nka>&B-Gaq(xcaMV~X^;bb++ctA)H6nO;C7(rizM#nAEqwB$SjruL~WP8f?dk zbKPT=nMpKJ!sNWXtrv*-5+VB;u`K}90nD~1uhaPezr0yg6li5O(kZt!K9yi#Vg0JD=iq4CUZT%@(g z_qHG&T{h>`$Yqe(E;Gb4tEf34r+6OQf<`W#BI!lltpEZ0cZhJ93iDB-^*c=p!Ll+v zcDKh88bn0NSH~5mjFY;>$KR;@F+Re)HAKou+69olDv+d1K4OW#HMa9S`nA{6+ zy2d_ctGM=;U(((4eo|*z+g!U8XdndC*mZ+s*O(K%t;{L8$+*dKnZ6GjJd+`_pT&rQ z#Z^gDQIFki4l9$bk}@ExD-8{OPS>xzbUw>!7G-$x&UirbFfK5wD@0!R|2>!Fc}Hmd z8x56zEBLbWH)a_*LkjIf3SaxnoYCABjqB&k2z?UrobkYup!2$UXVL`CLuZ>b6{5Eg zWvubXH9v`-pL=Kov*y`>j`-DfZ7l8ukc7wL#*nR(c7oue-Z;PEJB{X z-ao9>Uv72vRpm|PRvIz^BzcU3JDqO%v?!113Cm-8hF4^y`B;xmexWvbd$DO!hP^`N z`Ox1xz)?a^M@;Bh*0cPGZ*SD)UHJh{IU z6A>!@G#?_Kzp=4Oj7vT;V66W#xv$eQh{YQXMbh>_CZ;RHIIg~KxRcU%X{zBYbxN2_ z!uF}{Uipr9pUW%|XiekAwt3-b;_Oq}ZwLNC*{7uT(K~rp-cnrDK%$3&hJ^j$qnRH8 zc?Js#UINYYVbx7M{rWGBwMC6Zn~TXS-_ok8?kv8x8V5Dz1UJQsHN|i}eMKg{(1*NV za0DbK+>&&k`5D-c)tnVacD}zpi0%qn9boSekP1{O^$w4S5EKw#f#6@-BSBv0ErVGZ zfNe|9OX5xj$mJv%jDHAWshmNlN72Om8C`UG)NBjK`lXPbsSB zWDiPZ6H19_N6wqP`}7fWW5geq8IL|*g(1uxxQr;5W}#LX8_U!fzvo|e=^&=DvGaI= zI01SZ_=KAECv2{ws-e}}sdWA9%?LcRf4_UXe+E6_MBDNAm!fKp!h$s#%Ep_ysCw2b z3vNo=jMkms*E#NIk_Q2Q1uh${;jgg(vj1nJBd`O3sJ3?KOuNI#`!P9!4536k6A^i< ztgNi7dj*zFy0oo@X4gMGzg~E6Psy;V7&Uoctn8iEv&vm*ok8~3aVq7;Dfx3#7e@lJ zQj>k3i{D+Qf6HtF zgRi-?_~$lyy()Og$m2|>&8j6mhoZryZ}izWO@a4locaOq-R9U5ISZWEf}DTd_x#Tc zk-2@k3?1*+s}^U+pI@^ZH8L5uORtuoqgrH-Pq zqB1_My_Gn9#aRc#mdwN)VjIJmt+yA)(nh>~~xuFN;K98oR}{!3k4VXnhx-pMP2EvHvNwEDEY7Qk@tvlrKHv zDLY$!xsZ(UQWvnf8XZ;E)Fgh2lDi3DK0ZD^kedlKQqHG{2?WAQhs+Yk-JO7dS4Avd zq0bcy-+INMtxkY~b3*rgvZ8n6s@lb<4Nr&Fh@st{3Th zBK5prUb8sVL`qj#A%yq15*-pJ(4U+;t!Qqj-`AZf9N0`s61qEf zo$KKtawQ@WoKDx%GgV3}G3qoln0+%lzr-V=`4<<`evgH8nmZJ{SZg)_JaJ5UWJ>TR z+%}IOaqkQ7aivtrKX&*Au@JW3h2(s{5ITD}uPFRpdOn{%g;gc7$iPR4LK%!LCBquh z8mY;}OTk7@c}b{KW!QPrwftpdwp;C)s#0$1EV1^~g2KqH#f1df5@g+)zsUScZ|{dU zo?s^iraPlq&rX0JF0e0c1@P)0z0y`vEeBAz9cAf`Z=4p& zbI<9X2b@UvuO|IU`rXn}oZ7NMTBGaZ@pFj3WY+#I9XYkRm3iqGJ~`k0h0@EE*-1X7 zT;XX?JfSwqDy#it+}m=wQ2ZodvWC0DVUlsQPl*R3Dpz@MB8h)=e#1?S4i)~ZU@?JP zjo|NyH9wfs#6ywS`1?-%BWdO?Y4R>@$_i=vHo5zR#72RcaydWa5aWLA_=)uo*ImlT2bHsky}Ae5}OPT*TZLoGlh>g!RIQLvz*I$B!Y=#dUeuU-X} zd~>B+>~1L7$>3<*LoCOEa;mKXw!Eo5?3DmnPbB1_rCa?9FG;~toiE`iw2wVnnu!f+uZCA zNXGn65EBv-0b)SIi2$zwu8U|g34CG5=B8ab0M`X#m!RxN&^cq>A4LD5Pdf(nuO5ZV z7q3spdG`tGd(gr7h59B3vjnK+J{1(O9@PC{aVl!9-LwnSB@|mRFgHSq|1jXZ>}=j+ zPQA&bLe2W-W6kH!pTy#o`_%@$xG-6RMSRaI=mVF!f*@coK$wG&;fa_&z|O!%GXpnj z04cWv#ltj*j>F$J_fv$LRzn#RrLMA?f;lE#H42&5N7-fM(jFo<5eABJMJD{FX6CiE z_gj?Plo^T~%8%a+W|`w6k-Xes#TY(}egZ3dK`ch0y1qIon9=Dm5|5scOFBC>z*O-f zwf0625|_FKk@_b<3V2TL(m%d)`+#Ca7`40pEw7-M_r&>VJ5FEF-R($#FdluJQ7+TE zV!LDEXTq{MqJZt|<5xuM4DGID!O5X5SgQ1DC~{1)KZ=~q2}cYKm@xaKjJXAPOoBT* z0Uz#j^ox851aO49EmJ;ztN{leAf`3$@S`Yb`19R?ZZ1&jt!C&CnIugD677|B0^b8J z2kJ!dcdjO`|0vU>C}MNPiFL)IjOSaTiuI(`$|1>JEA-vw$?s@MGL_}T>;VQhXqZn|M? z8G0@KCl#E^dzGAfm6a8Hc9r&f6}!83YC)uAWD$#x-c@dIZ?mVeFMTaXyXWBM;Naxs z92(~y92y!MROs}-*|>5AsuP3nZbL7yzFjT&E!dn8Gn{+(Gkf=rhrnFxI7|d?O?J@+ z3N`Y)Ynqmrh5FbwK9*#3AVu|`rAVqGKJ|0IkNBrwCzpCa4PtS9t(HweUN5U6oiaN1 zdgU=D+sT%wEsCRCf+PuPE;(`L8dYZO7jpUCqf^tljBCo##@Q^>g7Q30wtOJORwetm zToR=oN_?fY@dS}ER(z~+iUaam!STbqImk6VD}!H2R{BTUGG&7#y-W3Mfw93Y;nT{Hv(qfg((Mt2(kP6<6X%#D#anX*ZsFIT z*^8g%If(YLD+G2^4j}ICd0*c8>*$X+=CBw1cu7E?R4Qvtp-ZMCtijJO+6j-hf8L2C z)$4TQ+-+=Sg?PB2u)@^xZS07!%=;9}5S962gEdN(NZ>e!sAHbv-p$JIorzr?cT$(n zFW)U(&v7eTGsin!56a0+juBhM$gdc|t%zTKVk-*;!yjx!HQrNMAH&K{HpV8?zjCuZ zel&x0E%%rC$rFVl^=?P}%72%8RbL;Us>qlJ_ls&54Px0(vZVIdk)m+2<^kJf7Ry`_ z*BDe+cj^+=i9|vj)WMaa$d8eJk*!{G)`S|U4V)#v!^f}|;e@VM(x;}92_pRNM9k9O zv|OUW%FFwRCBBnb z-s&)2_cON)6gBl5IYqs4Pf$FHRXUBA+)Q(lcp||ovYjQ#$jfu@XL8DW5P9dYtZ!G~ zc`0X)E8vn5Q?eW>z@9TI!=NTBD=Q!<2-J)iC_UhoZ~-hK+_uz}l$1bGrKhF0)~+Q@ zc~P{|beNhW$9VeHlzT4%BHtjPqt@BHN!uT6zYP@JM1XbHu_Z=%oT8fagzJXc% zRh7sAUG9&T@)+g4CjO*$?W{BX#(`evBfpg9x`iGC6n5y#6{h57p@+704v3qP(ISde zFfaKSpX@B<4YgEn#EB#}jQXkPvXz&Eb96y`>?+@CBr@&cYi6eFnuT?~pN0}go3})S zAuB)8d7tpw79tVkQWmJgB~l7e!oDisVvJtI%5%?dJW?>Grmdj{62y2m=|zwaS}VLk8G>`EFt7@T zUAsfB!7$|X^ODNh(!wI2W9Ci;cjuDha*0!Fl^_W0a%sB+xhqK@cf*m~4C-_Y%7s@y z;4x0~b4@dI%|F|(k09%Pp)74)-2c>!$ki1~38Yv(_ocV6HE;K#;-J#E5}Ik8(H5HV zI6wDTg;0tz0I(_~Oi~>%+iY!j02Jxv1@8)OY7!A}Y$_;NIZ9>?lanLqf~|M`(wf#1 zBw0_%&wniTLg0^6GJ?p+nN8&pn~L+0LoFLEZ`oi4zis>iKT97o%QP>`G@H;gDmi6N zoY;1y%@fsPlm8L@xTRcO)I$d|W+rcE{tV>es3>4Yw!>+&SBO*A$g_6`72IQAd&DZc z>u0QyCvM}rQk?G4rkJqg_fN5>*f_8G z`Pbwfz~#rq#l=fZf|s|p{+|y4cKYwKiqX+gF|R`tW#xL{mN}Zf-NR5Ib}Qgu#21w| zIJCm4Yd^j0UENnuCbp-mLV(2ce*1i^!t>?C}{i9 zZE$@5p~uHPzMjmjvRN+10fV;PKCM?Bdg?X|UbIeR!SW?TgCo{f<8>wkNtKm=C5s#3 z3;Y1+amg#d@!A7E2@Jn3jw3AqliJ2+5(Nd-IY8i`)JC9^Nh<|JBpgc zXDgBDZ&Y?sjZ<62D9X5a70-FuaARY*fOA3<2jNgt801&3^OPi&=Lp;mYo3{+mTC40<>;_1`ULTD^8 zM#^8aE-^9#Gp?o=ctLA+5aALjIt#M2-KO1-$%)mCkp-WkiV7<$+c}klA}e(DnN}$p z0l#GC>3rQr9yAXy1j;nGK_JWU$OxEhudc4P+(f1Lo2&q-34f{TZEXRlv61uOM|bz* zPI@|t698bg`v#)!O8BgW)-=rt6qXU7`>&`Qtg2_PCW)^mw}GEQXF5#HmC7zrFOx*` zJY9TqKdcZqk77YGu>PlM$$?UGi_3`F1e#Fi@w;eEiEkstsypxww&nR^bEI>N_Hkm; zlWC-^H%hUV2dSGEw zrPnY#F07!W0hmxZ2|rbrmtQO}M+%=$>IDpjCGMg^$rv_oLr6a}X-F_-|It zA?IYAXbskLYoKggw7wWGtE_Z)bw#!f?(X`>6af9m?j`i0)_;)H4+$>gMAi~Ok;N16 zm>>W1UZ)=om`IIAd~Bw8>DFEld9h3r`9S28@K$3TFLBXtFlYvzWQRSs*P*`9ubVe3 z??@`&aKqAnNu~c>NUB#zL_|bFf>t6LWO=-R?F0K=+Lus0aC(D?0tN!o4G{AKeGXr` zACTgDeFn0N#Lo71alhY(rr?%?q;K5h1YHpTFR7SOlapG1$Wxp#-CI7t= z$=M8`;2FEbw<9PsR|qrLC_&9nTcb!@gFcVdG_jhEG@~s)S>ySy8P)+so->oRdu^nQ zReC%Ya&r&jSqD&D86;8h%_r{?2F}>dt9WLb$auReM&pyke<(RRVOLHsFEleZTeq`Z zwQ=0Bv$rsNUZsoQO=J(K3YHtkcL`JZ(U!r zG|q6H3sreEs?5yLHDM`Ww2L?a$x1!OF0yBBbQgI2-_pt~pyB~;65YClSm6HY%$OuP z+9hTT=7_Zd*Kf4bRicol5$5xR1rn@%(UmgmsuwGd&5Vzh*r~}P8sl6}c_VEWR+9a- zv#`vmjo{yY>5XV>nX_lJ56dOP3DuT$CbeKwx$In==B3qUmS#9_v8S+_Zg;9X!$U)N z|F&KL-8zt~<4cP9UlV)SEsX%WF7t*NC296kPt$US_(#~mdLBzMRe zBymRCFIbVfRKdp0CoDW3@OhmMG0rIOZX_YO{AqL8e4J#{&n(^x)v>X`sNkzZ$rl@T zOTsVhP7!y}lM)=`z5}c+eaz3~XxuZSp#uL=2Z38>@Jop3@kegPz7VbA)kcOPMris| z>C15EZmhSgk0`f;of7K<`MgNL^MNe~SEN5-u z&4wfmtAJ- zu^k1*&=2PIl5v<2uSN3+u6tT~QTwwI!_?Gs4?9n&)X3lDf*VWx!|-Y2 zdA!)l*Ldiu&LLj9S!#;St!XEnDmvHvvIT)vo`_DgPEMv$^kB7eat9xzkx(c!0YAb;{yT`A;(3(of%H2k?XS^R~MIx$|Yv^8fXUC(De)D zLZyZP1v97=E3!E+&jdtnz;yFFIzb+eeJ5pNxD{Mwt#+TA*`ZNtlYhN1c5;Wcy1Bf+dYXuuhQcLTn+Pqvn_B% zCLPqVdq)w0a`7W#^84{{z1szia8M9S9>tRyu ze`xUB7-IYBRxL7RH;;t zjgbq-Pn@AlCs)TX{5<-ghIIY1Vbv?){Vj(vFM&G6T`IY1_RTU?8kO(zjbE=#ub-8S zU!3j`{U+=cM*nGqioH$Yb9$=Uug_wGk92j-$Rp+W_i)sdbLWZZ-9oHG$=QC3O_QyG z>ue_SrZH{00bA)qBY3dVXI2B7z6u9o)o=F?OUlJA<~%;F-_o?=R$Zme$n}G z2Zj)k)i+r)3F4Blu+hXUsJ9E7cYs}{nr7JfQGc=|(nF8*U&BJG1wlXgZ>ef1LVovS z6B?2^rMsNLaweIyd3*8Yseh9#lW?|NJkyoEoTd_vQ)_M6U2Rcme-rG&5h<-$&gWk815&9}AY+11S@g=}B%`h&NOTc)jqy`W4sAzN^` z{MxD~u=(&E!k1&QodwTL8Z^}Hp0#{Sh<-@}owQUK0 zehn?Hvtf>E@<~a0i1@{Vt7F@}wuVxs<#)@C<*6`X)}O{SQ^ovCuwl3TK>yv~*$6s6 ze?)-2VMJ}QN2T)SsnRNEvR=?V8a7OyGHCdBjHh!rgg$ZL7oB$DE%5*P*4;_j1+roW1n% z#4(!kJQvTbO>K!tWHmO5=WK=I+Et|^+wbfG=>r1K(jk=tco$Y}_5qc86%#N`bBO@a?gd^WWbAa0&AGVoW9g;j!i1#7DI|~!uFBK%c z9?e7L8qVRR&9lG*oq$8 zu)PEKC_!pkDIU~iWbA(WQkrXYOiWCh8#Jr0(>i5Y*Ar`c>G6#q+jN0L!_p{A^f)`X z3R&>AS!)UHw&>Xp#GRy=dcE))1KnSl3IqH^q401NhZiR&Cm{P5rAaNg=J>1e9cF$1 z-4F&0*upo?+b!KJUc?rK0;;e`e8}bT(E#1U^=u~>8=JL_O^e4KWs_O9xbMumi#V`5 zrSm@}xU>ekCr{7uz>c$%`DX8#F_r^+LobWnw)4it;N*vNi7V}gGGX+6-=c>fN_QoJ zqJH<&M_AQyw%;;;r`F1p7*krOSA;`-Vvy^FkZGRXAvw){-mi*sbyUv2nV;GsE5`K` zpWxM>mN4Y?E!rGSPQD0mtt;hvqpe@n%3&(DKu%4Kk`1b1;O6rs=>9)5FYbV&7y!)L z5s+JTLq_d{LZoK_c3Jarb_dlPF>jfR>TklHQ5+m|e>otDv^q967TgQm@@UuWc*Fqp zmWrC%=i+jJjMksGZsyP?C2l1C1^4YfHS)X% zRK91gJtq3Kel0rGIw^2vBr%{D9ZEm;`Z?a;+D@u37n) zR7@69ykB|P1|M+ow4sMXjbF;Y>(KD8^)s{Hy5{E=<19}$y`zkcDDq}27YU+b|=CNq+7I*)Ko z#ya|yO26&$nI}1{=B+N)W{IZ`S(3o7x=vGif|zsb%*fy;Cz(sPXlsNY9q*6RI)kWw zttLp`fA74r2aV-|%K`=Q5`4}e3lqvV&{P|2EKrdVpz{MRQOeh2lo$Ga6iCP(5P`tv`J#i)&5Ma+yaS9sMq{tf~yE_$)P& zm8k5;Z=|>ezR4eZs7M0jFM}ce>%%GQt-s=mQl_WZA5QKcs>&-_ES^qrM6h1M1;{=( zM>&Qcj=j6Lo|23TV;O>rknEGKWB!z$TV@Uitm@xY(BI~QHzO&osw$F)E8W!+Li4=y zPe{J8GorH+GmRkU%=s`Vb}|OP1>g^AVIGB_Hd=o!9*` zHR%D@Sz5CXE9J%6!6WTbl+CGyFcJ}ODyOs*L4EJ!k`D)2W#ad97*4ZSbTp;ge^HT7 z-;YR(ik+?O>l$D3kcqyC!29<5$G32kH)4Co2Wheiu*Deybn9mnN_|8_+#{n`(3Z9~ zY7_)ItrvVB>2!N#_;~o(a%2|o=eP#Lx{Zkp;|r%G9A!S;4@7QOS=ey|-OdbOh$slw zL}yg={{N?L=h4DgRa;%m-V*IZA~;DJG5&a}uFu+WzFytuBil3CU5UI@JW_Sqwt7EL zcEOL47a^xfuZqIM!vn5Hj45sN$Vf?JUv2};M5Sc1nMe{0qC%N_05YWuxXeEyC1Hd; z-9}=K%kcc@CDjCdG&GlojQBT*-5hk{6`ZpM-uv13(3V*7ziX^{pJ~JFng1(*<@LzcP=;Wq1=6{AR@InCm`oS;Rz<={Vv6vj9uXn65evg~)H6-_)`eC1DNp z(y|V4B{0(QyKIRW`b4s4B8SvNHZ9q0%GDL&RSg6C!1d5?Jw+#|6&T4#yP>h(+}ubb z{mj-z$p%2{w|Q)Ni!Ql-eNF5W$e$qo!0XA}Iwie_!w5-8NN{raqrjU#OCP!yS60pv zB(EyIafF+ErV!K@iTP_^bYbGcPo>Dw%Ci1TSAtOIlM8|Kv$3p4C!(GWp_2nXuP)@? zpzQb5Hou_Iw1>aiG+362?H9}3a$5G5aCw7`^J>^Zf*7~&hOpLLAZJ%8_~E|rN>|_9 zSXVcS9^=xZr4`a%SKm@!hpm3fuPS-)$gAmZsAS*Oz}qGAWM-aWl$W33JT%n#$dsB+ zkz_ko>@mjtCdw@ziFfM=D<>^k=_(1Nt@r}FP;vnPtT}d;)to@dk_yb%Dzsz z!p6AgFJ;B)C@JZdNh~dZujqhk>4(-9&3Smc2F>J%ggG*i86+oV18s|>8_&}}F?cSR zS6jqMygw5s90W!Dga}(*i(|}yTV7Zwf`$DBV!!z{m#8vy(5uiW4-@9%?CjUs!2PkW znzCM)7g3tvG}n-qHW`H=5AfP>WQ~_~W zD{*8XB6c%3-N3u4!i;pYvvW!2^b65I;n>)qtK~7nQ8KkywC-3vkxbZ`AIde4ox=Vr zO_C7(MP3gaZtUdQ_7KFtrpaGHDr?QyynWmC;pmtyWvonCXp}0ut?z8Jn_6>_(BO6i zysrYF9#(@e2}W6t)SfiG7Y2UWIJ6MZh5ZoBqRqq|mhn6~8&)P+(p!^meJ_Vh4Ofx& zRy}kW+5(G9GvSNW{inX_o%D4W7hA_TXgkX|*7B zS|0e~hANbKKm3YnYnc*ddaLz(j@$KCCEMf7t8PKZiw7TUX~TZDqR`&aAvM+F3iZd{ z8}uUz4iEYLqohtz)wib!2X^1FdZ6E&ZXsAA$L@voeLP6Vy+9SY&rdwThC+)iG?a^x z4epHUd}po`$MNNT$*_3uwA9IhU8?r|;RPf7GS5|4_Y7olKWlge_JfDH09tiNtio?#JQ(#1^myAGMO zEz*2c*28H0Zf@2U1s@-1NbisQefGy3gwATp4I0iqb!-l5lGHzC2A|_8r1C#Zd4rDp zjoC~wNvQMl(CsaZo-C&jBjU>LDbah?6#58yD>Z4OGRn-JnYAz{el*BmcF!xEP1zIw ztjS_=&6C&lQy9@kXQ*X_CpG`5jZT?@lnQ=vDg)t17y?4F3XJY!%M2j&7C z%IP8Qt|My*$q{TNEMl8~Xk6`{K9 z#LGSKQF2Eq>Dho2&7oRLnlLlm$t|qDfBX7n!_w;hz@`eeRt#L41%628E*hHH7`u2B zyEHQaZD3M~`DgMa@^ZeNF{FC+wvfSN6`#)=k>cMdz1)1VR&ls7M~fIrAu)1+aZW5> z2COYi2SoTvqO|4|J+r?&@6Dy8pizc6i6d*0CU!3ko^4|P=SFi2o4`n@^P+6Oe==fV zRt&*l&h(T4ZoXP3m4}6!(&V{{o<0W_@#J&VPu!t`w@O6FnHl9^iWn z4cvH5!6#cQFLMM{tis3(Os8d|o_4OG_aSs{AJrt0N{OkLx^g@|sVCv9IqEm~zgYnfhFK+-#f~>p!iYJR87I`pk}C6)SA~S#Q9z7=W~yDaJb)S_Vx*f%m)RoeJ(Yi z?=U{M3*NgHwiLrE6Imm!6B^Gn*nAu>&21PgZ3sWZa8?mG%vlp`O{V|Q+igw3PU{)! zxx&0pnAx0N%^8JHvB(lbC#e)4eTEeiI;r!)`9;p>XRl=%l?Q^xNIqQsQo~sNj{aRV zVGE@YEeBdh&ap|V;!E7MBf(~hZU+n{IzqKG75$8(3_8s|Exs;Cvo?J}O|y13`IK@R z#`Kh!l(O2_Ol{Yrsonm}aHH$*8vhAkK-ZaP%3Kh(JZ+#BIrAXA#mgrm!X)VLk38(G zbay(s?6TKx;;Lh={>?(A(R35i4?r8G{V`7iCO<#Ve8v0eVUv&^DqC**?(ElP?r40R zpn+yy_S1<(o?Pz^!y7$=@tfZ|D|hBO%s*qXmS67U=kRysSbV>@WNT&LmsUOUV-4r( zrn`Sfa~vScUCSyQUZ50;r!Zi1lw|h1sX%B^Qia-q{UT0yF2NNC z&%w^=`ZY}aMw88Hm5&Fb!DxbYX;tMG({Ly%>Nd7|RFS2_hf_4Gqw&w}cUr@G4-H3I z&2;)DMhBEBfy*0E!)q#3&-UW^gHk-cpMD5ueS42cyF#|LD=Dy4Qm*b)=XB&gz0~2w z>!}Fj5UptfoZKJ;858{l1oP73LhDDyEyR-qhdC06o4YwJsU?`d3&Pn>T*r<$Xcf5* zcQcoks^{gQb-hp>J#2)|u9!36Nns20<~6Js|e|1idV zANE%?X&12Nn1@D3py{KU<^LH|Zfx0#m%U$tx)4H%FD+|Kw~c=L3wV=fuyzPohV4dj z-Unqb2Mq$;-8NAJB0bPFa5Xi` z%gb~PwBRcc9ev?1E-_1VpKMPL>-?6-CqFl(%Ag{#RL_5Fx?|yxZ&Z!plivCz|HD~e zf5R|fc^rx{LzIzZYzZd;+*6+kx%bb7L#PW3)v&{FrL2tjkr#2=P(7%!#`1jc4{!%h zvnBEHG|@b)jx|RbZEhvXnlxM%-MSoSekC;tKDnMwrMGBkH;1E9yzWz>BY20p+M3(+ zE9D(J>_wg|$|qy^HAUwlLHjYNbyG*4ak%zqI5FapRMSPe`BYuS4=T`3<2W?x=mYJ! zsnCqM63DReA}hmGxH1Tum}M7+GIb%vlCW^b4ScB7ZYIukr_itPO`P$HT#aRD%IXNp zFgm9c`VQYS$(^AS%DhH8e+<^R6C78ZABgt67kF{Smh?f&kgUXSE~CG zCZ%pC&t4Y08!%0V8*W9#TVYvUjtQBWSy-4@%7*nyO(ia69A+H0nbgqCMp9AL^F2D~ z%$3Cya@}1+B&qj#dca)rKh3P##s#pw4b87BE*m>zU6Slun8azRe1JK}!_18YqoS$l zq2n!Sqr;a`n48a4Lg_FlDfLGQI&Qw0byXx8A!YjZo%%r zcNM!HQZv2C;ce*Slhx)=MiAlQ?ryd?H9fhgqO2vZ5)%PLnP~l^G(iPqaWkw^6qHbs znK-hLa6Z22DWcPre@6DA>G?)!ShP$ERJ}2ma#lUY&Ueo~-=Dl*$c2cb`KYlouiQY} zrUVU>`FGc!7(>GLT`~OHES>@~Z2j14?r?vXO+h>#m7DOKl9lpa0)B;dn>2fIUCl5C z9dja6L}pnwN$CasNi!MD%daNyzM8*-LF#ox6DLx@GLVDM`;f}VhMfQf56?Hu=kX3O zrLhCtLy3Qwpf7wSo+jqPB<39<=7adiy$=j#*P#uMt)0gwY=5l<(0>zM0p2+=!W%ys z2V5uhwM(+so_{UH>3AVZMKZmVtGT6|=JcAo6UqZ#72DvemQ(Q>lL8i+hcbJ#Tl~aY zeNB^`!5&kW_ESNVTu75`wcW5@rB)G*K+BisT@L$YBq8NFV9i`W5vzO@$ayo+_&h-t zwKwMZE1d6NxSmsO&|)avImU~;DZ4P{%@8Ze4u!L3My!O!iWJf433g|| zY(<~46z|4WvliJT$}v~7?sSg4j&>zCmjt8ce}cg)bO?JlHhCoU9N&<4D9;M>CVnQY zm{+30K>sv(!i@AC^LV)k{KZ#HDjy_#;a#kr5b3h-zrrnBxy7C_9vV+Mixh6KIU+c7 ztQV~>qJJn?zT$fQ`0%++8sUbW5^|Sp=3o5W(&g3-2BB2u#}tmWstBQ_GSsrh@EeQ-wL1;b(6Y37jfTX-=Hes!Q{mN%?0w4xBy*?_&Vr1zGanp>KS4f9 z?LQ-YW<&}#Ou@No`Z5suudFc{aYvLgDo!9M#p3%ZMpPR40GIGBBFiZAFIiS`Wq&fJ z+ZX&~2~i*DSiWQbw(5xg#VDVNrPHhhzTV5}1iFs15UmmwL#atbkUA!XmAEE);LXG? zWrOv2$Lt%u571t+u&($d<4clE@*Ln7=}F$ce6R$jdT8uOJ=_AT)h(BEe~HoC*Id z>AW57hMFDIUZ|6k7bMWCmX4o!kS>wZd-cB{@fZdCRgmm~o;UcF9}W?g(>X0v-^;P$ z5HFOLk&h(M?#C`AwXToK2~2t?=3Ul^kQmx};V9s_k0GKlZS4xtH7#Z8O%UkJWs+;; z3H>OY3WZJPVJL%9=B{hiwaKq7-I^k7$+y^JkGjdEax3srXk@8JZ?bJs??$LwPlmof z?iU6T)7q?VgAY?JlI8+!MHiiGhBnesJ^G=|;On29a<<)+#1-(v0r*J6JBO>u-+iw5 zxS$lWpvs>02bFrTUSdG$SZrG#@@FVG*mPtD6^l1(a#EnVGR@sI>qQ}}3wuhCtAyqwW5VV&|E*y3dmb$i7 z1$yMXQUea24l+5SBW+CyIp;bQo$L!HP9uVQCnuqbuM!^|e%|`NW736%(vuW`>JMHD zhv6<2XU#y6BNm|{yfg2RH4sb0?UDF5JVwqaygZ;V4 zQ^zq}kykHt@sDzBHJLiNp4saKU=%MhbtTH)y_S+oMG7-h3 z?4f$`3!QxZ;zt+8m&vf)8xCzHo$pjTI4KSU*)j8=`-93nwnPryHlSHqG_yOVP5Cg& zdXNo^iJ=gbHci=>5n^fe0>^N;^$P27xOGIb^z)JF0^(o(Dd03A>22UJ=Cc2;hgPKc(qztRU1#LbE@h)hn!XWw2*?(s+B)1)6w0Vov$NflDrc=|N`8EDMBTh3H-GM90+f0FoN?8LQH}ji+p&JvcKqVaE1z3M zH(LVEBzSrN*Zc8i#1=KG&k)N=79MjYQX8y{G;2DDa^nKxF^1MX&HMV{WEkakUI3hHkVTwR#gy zQ^80O4mS`SK!V2uSZkk1HI*DvvyL_w-AWqcaR_MjgC=!kEXi`cWJ0m839#lcG=t2@ z9+_-8(hyaHOS7M^4=5X9zK+`rg#O5?HftAv+Jt0;M|Xgrgz%dwX{FornTJ#Lw`xQ4 z8|uzdGzfI;+4HoP$~C5$)Oy)jB9EnU?W87mi^Uq$nUb3Qyc$;z7SAJ!rTRH!i@%EI z85xg^u+?u?tJXAhMVY$;=@jHdl$?m)F?A9Ytm+1he)#Rn4Y!t32R*hr^X@6!#vi^C z1Ce3_3S-6}>bIW4fKhESh^<5$_?h^ux+;&NxW@GQgogF@OWg=Pc%+)2rmRZX^ ziGj~P&@+@L+$z*_8)NXRTf&U8Aro_8o87j;&Ff>vn3BF#(STwvyrY4R>M><_Lf$9R zqk$USj8#(Scxe~BzumQx(i5O60AKf?2ZH5a_VL#re`ns{^Z+~z|JsMahV|Fu|M@rm z|9*j1>aOWKqcu0#Yye$(o{GcQY3x^E_g#-ol)`Ll5U_OXW;{`O-pZ_?( zPbpcMxVkx;xx8Uv{?~&|?C)<_S;SaGCB!AT*tuCnSve%$vavBa+FOJvDM+HD5TJnH zN0*j*s{#cD+YSWweT0Uy_05x;dfw z`r&c(A=P)Lq~$89hRe~%JhkT9^*cGz2eLn3XLY*)@lYaIaDTp(GM@eQHx?W`!T;S; zZ=nBvnGYGlum1CjDD3}z>WP@>08xd#kJ9aP2tim*p2S{3UM7OF!%~qLRYP_o#W8Bm z*F9_Eersa7B4tfg&CsX5Z+lWIZ*$Yz43wU{gUcnyzPugJP-@iDI$Wqh^~d}B?I~p} zpjRRU%WR`iZSm{LdQ!&Op{9THT#&*Jm13wby;T(OA&(lxp?o_3P)4UphKu}B=#9bG zw(!5-AT8t&A$DMA%wKA2Og33@#*Wv;dp&Uh-@@K3rSSgyuSWULwziD6ysGh@d5!WJ zn|W+?oH#4X?|k@LZZIgbZ`S=D=SqY$p0gSyy<^a7K>O!b!8bmTMecA0HCK*unQF3| zY1Epk)!3HVj@*f|4lH-NtIjP94Qvg4-jd%uW?iKfuN=^Kp!09Zt)#1J=E=@7Qw?@? zF_WE+Z@QcAr}e}Vv?~*qt@PPd`K|Z%?@uSto~w^i`&wi<5s!eaC}-csl+fCgusGKa zrim3NP*j4d&&fq&F8Sb$ONV~NuGFWvFWD~EAN)_M`YCnxZ#^$@S+CfO3BSjF+xjzZ zb|&=%-OshjRxmyJEY6g7+arytcPPhPj398|}^A9YbQUEyUXKfdh$M>}D%YVl7HS zs?#WW8Clahqlxmg4z8Dy+rCv;*5Q^_w=?iB!~X!YdJC7K(GeCpd*k?ff-SQF(aqNn<>QKBu3O!!RJJ{t@Y zj0jrtE}ytN9PS^g%j*mz3lFmunI>cNVjRP_rk$R8*O-j2pjQ8PNx|Qx>ZEoU?Eu_M|-Z7e3X>ALys=5adBm_)%7Z-PT5=g$HBCM}3LaKD8Wug^!!x~uE2F(DD>Dx7lpNo`eK&d1SD*|Hof(AC_>v$|i6fDKy*4=F zVX=CcW`N+^lFdM|Z?xX&jQQ<4pEjpPAL|o6&$2H0FoQ#&F!X;v+`A{vz&QKT_ulna z@hBHt16vVOjQD33 z_CBUrID6J)*=e`P)Q>Pi5oRlWs zH25X2aoo4GvLxuqu#rC`3jN}_9j%Cz&{fHVG zXI}>8Z7=c9TL^sQf=iOCayl7meg7su3t!h$*33mC*0zcwG4@P&b9ufE#eSLP$ha%R zh8OK6^Q>DzO-)1yg0#FmfLw~{!G5MBh#gpWyr66hLAayH3{c1i?SM?73w4Ssp#MkV z@u&&%9ZOZ!1SLXd`%IuqVmrOrd23`aXv*Kd{C!nJmb9PF+WkGMS@P>mo9r-;QKca+ zhr;g;n=7L#kJMGaH!C~Oj=69d__Zqvv#45h8w*RcjwWKqiqlW6m;FlOGzbg+Rew%sRD^CT|GU(^yMZ}0HgD-C@Au}eUI^0 z^Rvq(&40K>@G)w)6#l3@-8pP?E?%}Rv>qvmGgp)4((I=qi9%l}iepgPONv9E8ctLn z))`zj#hLk*+*B6s(w88vg+G&K7QbP=>HS zY~Zr~RAr5JZA~LpzJvs2lXhAu$M^?6hiko}3}$Xo!O?}KVY^R!v0#c40u_khje(2| zBqHHWzJ`axdV`slG#-~NOcbEvXUJzYPKk$y7xs2MU-3Ahg2n0dRDXGSp0|+!V}^^> z>$oAgZN;;uT;jB#X)o?z&qJqpWlODXL1iLE58Y~@#4}p`dM0k)pR#1x2-sym%Lxfi zUEU98oy~<3ncL5H-9J4Cx2DTwDJzlxx0ZB-^OWomJndUt9VBa9bs}uNT zT6kO!<08%QNJ06K122Ggqc(ejc5%SN z0*r)r)s|zO!Kj%~mt7(7I`6arkel+Sd@3)`bfb-hqvd`ptfs?~cjZ-oCKyUrYhG5l zb$3x$l_+&Jag#N7b5XclAkI}(aX~@2lc@M9L0qU?>^E{=iFw4}UsF?QC95v$p3AO7 z4$)FqnKIS)d``k;kin=GBFp_xaM2bh%vFn0?b_sXPu@^7{_0Y`EpF-1UO@%Wc?e^ka+iGuPHwbr|bk#!$b*VqB>-lOkcJ zY{?L)oR2I!Q8k!mTWmE_7-dn+&&XpqPHJ%;+lvx7E%v`fjtlc(grL0!A+4;+yKOI> z30A*8OhuUJ%Ms+{6bbCwaYdMAOI7$57M95G$;xt#cEu0chm^LdWa9#u%C&0%?fWp^ zz)x#JW`5La-!Ia^U%MJy6$KgD`>iipud=exF3{N%`7P2(94VOY`)=p3SR= zm-fBLW-g-BbOL`!pL1HG#~hl)sSSH-fF`ZjY{9TyeR!cbxlX;#_JLAMGYw4mXZ_do z>zagZt{gAsJva6BgjtR zd3kzz3TU$c_?`x2&{(KoZI-V9~IzUln9zV7#gG(mT>7 z#>W9cDmg6;<1<=gGr&ZEap~j51~#CH_vQ^|trAc_L7eQ;x2yt87wKqfK>v*(5tv_G zOeyLoQ{H8MjgHPLrpor3!ga2)`|7KLQFK&oO3}RPC3X3ho}ZqqekwzqM(qm<1Jkoa zTk-#yHZ_cV?zQ99NYirty@typV}tN<>!q^$Qqf(WOtoDp{Z=V? z1Q~8}Sj0@k%9qHCoSd9RGdDCeZ1a0)cP}j|$&*WbPD&~SwCo|4N^9UQ15W1itCaZo zI-40L$R;cz29co8jTF67ND_ej1_>x8Fn9FzA?fPMLw{lm7R?(g$d-rz17x;~)m9pu zzFRqVf=Z9?J(l>CHuN%XYR2{4(lI}|3GTSr4Ps#Jd<_047Ndo%$YfkE+t2yx)LzHg zJ{{Hu>UqnMQZZ>QM2f2J7f4Vkd(B?F6!hT^@BZc702rw7fz)ZHT)uY~fJ)2+!~o~xe}7oF;{QZEkTC|SR7@8H+=90hh4f0QK0MqJ5`@G8 zc{v+g4>SLdL5;0XZBp%ud)3dQe8(GcaKKJGshUer*frzefwX_u=fwl zv%GRXTlCI8Z9m+4sLMrkkj7k$D@1_v8fBadoafrd#Ir$hosw4j+=w7~3jYyIRI9z7 z0^If+4AIWa7eLA`I=UlARYfHZ&??LZaUCs{{^%&B3Hmm^6EQc>OHL;I*88e;1PjVR zqhtk=p+uW4DQVE+1)4Nb6%CgY#b#jx73n*SA_}>YX1oZu!<}Uk%idxEk1x zld90D!l8^e6OKwyGhkWoG8r_&{X02C37#Gt^IeJP5%WmGShnKvDc)SQo9o~sbzc2y z>)&$FUYaK`Lm=mkt~QaOJSA=VyuY)Pf|r+oa<;F}5=b~tYHzXm_^YeXm%XpHD|Wm0i&3>&o>BhibF}|6Y6luf=zcQhjO@3?NRrl9 ze7aBMp?jMczN^zszFbd8iQfyr%AS%U*xLi*#$d$(m2@QltcD2$@k+QRv~_!$(Y+r1 z>Kw2eqpG=&yf3g|^Xp`wpW2!$d;BC3m{@=cIKgx+VnC(dqk(@bTT!+ZN*;` z0&y*9-CQN!?ch5*B=|^VE`ixuJxn z@R#y@qZ+$O@1iFQtWmCWRSH3O6p(8H`yW6qg8}2;;H){X_Uz$$B}gFXU66oSGWb}< zB_$W;=D^^HyCwW2J{&;|!9hbw$pQGZr>3SLvAMZs#>Nyx&q+uG={@gqDohxMhvfOR z7-d$R8%5S2myDtNx$x*@*8@K6POas?J*!1CH2rE=GEr`sf~uw}P1-EO^DyDBEzQk8jZcBPCXIX&doGTW#fen`bOni!pAXR7 zN2&&DKGFSZdJQ7f(MB`F$y^4&?E&F+fMvvg`4X^z%z;S*g5j6Xp9%0ee)T3+iNV59 zJr9%jzrSp{PWL{U3G3Nrv2)x8VBM)+BcDZ`vhv6E2j%?6|bk8r8t9Q znQtqxk9SUAIjU1E-(T-9#lc|hB*lkUx!XXvKTD3d9TZGIgR2LY&>toZ)CFoQD=DZm z17~O78E+y?Voi)1_5*hcRP0PD-u+zP6VC4F%!D=?1%oWW)l~sO<%LEJN(>DL^U05MlCMopysLvE%gJ4;Sw8$ksY?1+e zB}U?ZW%{i!^84$nr#8E!!RW(=qrJy9M6gzmw8JzI9!Goy*^OR^ zH5kN`8{g8il?#~^6r3jV5)%^v=Kd?lc|e}?0$Uh*5+5u#fHD^_{)q%=2Nx z=wM~F3v}=wLF5F6F#=%`KYRr-;9g(kE70aW1lkILV2^^r5m=8vAVozb3QSCX8ztqj zS6Pc47{pw`;p8N3pcj}Y8;wMuW07Z447w2Ru43sw57wUl-)cN$fcOgG?!36pAgQxIuIJlUSX2e#Krgs^VYkdTiGN$kjSTr4b3puP1Y`!{?x zYT)T6Jtqs4fer&A^40bA_W3O(yy5JhflbhA32yuQ_w|5G4m#!Z1i@wldgDM{)*bLS z!R7=y@&J#RkFN-Y3<4X_^b&$B0E_hpY-xbGz=!kXlJ3AMj+(ds@ehY}U};0D1& z{8Mjvgptph+)I?2xlE+X#1uWr-zVd0hLe$xVvE2Z)V z(7m0Gq%`;{0)S_RL#rKsXnLCE3bL}v051ko9pG+73fL;>fwnM1q8xRQbr;j@-tMjw zHxY0nyr~$&0KDr6bdi8YH#$4P02uZMvzCzL^z`)5&|Uzj%iwxtGBL8`{g6^~uCg9J zajpL}eR2h7^z{0FhW{u5BM%=asQh@6vlwd@d~HTUs3RDrmgZfldYzMhT$|GPz{_ay zjarhnE%JvL;w8pe_YmcCEdv7~5D$@&kqHX=t@lJ|0cGx5TP-j;nQ)Q7Vgkf*f8)F) zAW$h(gP7rlcN;PT9TFm9;*Kw17WfbR@b+vINO6JTSYUI1fY?odjt+#0FE~MVVTnsb z1g6O^GVR60jqO6o#p+0ToHo}C@{d}XnipI}1w9_gLyOaT}kO0xf| z-ZR>%xEi<@DZ4i+Yb?_8!NNm!iiCVbCBFAzN9ktpx$e+DQDCzsE@n#tV=+e~;lBYa z%K2u`^IE$F0NeXx2q3^iC**8rf>?shp6L%%kI(P-4G5}I0rUl23lMMv(lCG)|3^3P z{V7Gl1u&OCXb6yAfJ+kAB>M%H|K3db3RoQZenPnp$7w#~{sUhUyE#1G@V~#lU&>oK zs`QRaNmX^T$Y(t8%+yDDk1h+d&+U#?=1&c*Cv&F6(Xk4>Jow0|z1flKyAk z*`+Am(9t=pd%qHZe=ujv5{yFu1_U_c0RYaGN;6q|d!|{of|IdqN&kn-82}{%EV_f0 zHqz!>Fp|x|!Et$c3FZfDYH9$yfefMv@O}U#use~j4o`3=t*B@Ka?uQtAg`+f7EWrf zjT0$0)o6PGud<~i@568L7RPNop5?og1?Rr_vo6XegB3+I>-jGf*WP{pcNsdYWKNSD zlHVTHkw(fcwkDLf^DS?}BTb@P;g#|(_Vd^*iKAJOM@x{KBLuA-ACrRk6%e`rk161O zYjg8YngDJekg+iA0hl*>AR+JlM_vV7sXEk^+@cavQ-(+~zU7W7NZ_ojtdy0NdwP1x z#B^yCl2#8kGIFWDekQqIh^^cQ#EYjfG(Z2d){>pp16PwlhpBHg3W_*kuK(Jr>dJ)| zc)cGrZg+-A$0smz@=0q`Jjn#kg|9BL1*~}W<2vj7h6C8K`r1ULbIA3nf>4BYqIKXjD)XC|zKbj_t1M*QA zh#Lh8mxG@G1q={jrZ&2wd_yCBAy8Bt8yi?L_gmejoU^t5x0E)Td3gfao7R;x@8K80 z!m|G>Yc0HB)tVTY+c%wxuEI3!#v~uFDy8#-oCQmTlSnHHShl)8js9M@K>IQzML_wh zNjb*gTc>da1qB7jAVGQ)6&VSQks2Q_S+WTgiXbHDvNZ&PK|st?%UT62sQ5Pq2;PF; zR|lZn@+seui2wcf_ff>;kUy~M@myIGV`ByeMg$B3Kmp@ce1mBhmL_S~7pNLBH+Mh2Vw0wj(hBw8+D~I@=6B176n;fbA)aet_bc+ZUacJ4B-K8279_RU zLbeSjt4qOr-)79WmFINby1BfAcwZPypzDx)!^6jK0Hi-G1IHa8A^9A`7tGlM?qm(f zbqflR*a^Pe0<~JQi64wiOw{77Oi@v-4Nfs5(fz#a_|0z3zlNIFHxBJIC zo_Tk>p25QOlMRV|!IF#yQs>>F$0I`4yiZan!7g>A-4FGjMod*{v2%rCS0{)tXkNdz zKK<1VoI64&0C@e8`viXD>UhQf=EMlH146R^CNQ!7+?1eJDTJT^(Ob}Q6^i8{B{~|m zw@jz*2#mh!gB1S*JnDxav5U*g!@Ie!Bzyy1y<(b*D^p8cPk{3GZCMY@Fm;lSqx$!K zwodOJ5&mCr<3MYw?N9UVS5hw?sni?6@BQaLHlwA~U3N1s&bp`z+D@e0Pa~^0)|yl~ zFpcx5tt)w~2?(sMiKnI}u?@}`pR#b6;t8>^P9_wEN_88Y!EyuMo;=O24&b37e}IR9 z^g!X`0^IP`VWoh0CFG_IX!eCxUp}Hr5MhG#ER4DO3)JYMjcMGDCbc9r7Y2Ljt>3D7 z*w`=68xyAn{P<*oR~{?io1Z}JAn3V2mXqiLZ+vJb8^3l;@%ND+ifa=}^&sTDjzrgU z(PuOAU{7prO7e*uQnFETa3&e4?>nxhHpaZyWF?1@E=sM+&K@(m2|P%~m?a>kf(lhe zTSg}cV=39a7HaJPDFg8NhE<{Uj{t+*-EOWDJ}JH!+xryDRk&urR< zg%JwY<1gSt!3Q^2sJeYLySpe|Y{lFC+{y*{%fC*K2$8E>itm8~C=;}Y#%axS+~I6^d?&Nf z^8!C|KYb&~*!x`hyrHORWi+8{^@N>$19MZ!mkAM6ucxOmP*9TiJwXZQY*gr}8Pt=2 zq9pS!8hj#329z=SC5XNMaFsLWz$YEYpjBzu@d4Bz9#6V3C-N1qudZ-Wg0WG$r>8jq zL9L@hL`QOli~IM^?LN+^cA0>e$I)~bU6mj9C$~q>KzAi(;4Vjx;Fm&MQ1O_4w*76Z z-=A_}vw-*2DR>$*~YrJ`<&2Q6>+*P*1U-;D=c61NsY z&?yjL;cNoZJfB)#NqlMl?;DSWk&hY`_SS7Zzv)rkjmTdeD6+cT`ZjR3_RnNh%1J1=ivC~sHympWr;p#7^ z&5`xb`HW_tV+6g^lNFP30zVu?(_Rm#-eIR)+TBigaHUC?_uC}BPHTN&Vj7zqlB31` z!1{cz#OE!0MGCAt`b%bjI$E5Vcu~t{J_MzyUuoK}DD(igjJ5#8uE427G8ZP=eJH74 z00L0>2dfs8evT&cF(V{k1CPdY!_$e_Zk9fTZ}+(o`InmLlhmcU!eJzCBJjnlzX$D@)o+ zu)4w9*FnzA3>g|ibJfywQp{Az2t&34&dtmW2OE3i`1p8Z1CCk%1YUpikJX`;Q=+1> z)V2XK6YTpR1OVH1XMZ0Y-tE+aQn|DL)#dK=l#Hwnjoa=(kLECk;<8@D12+bo_Qf$0 z`wgI`xF)L;{k)3+epWpYK|Ca`2vrYc_8?pQ)B+MsrRcag33f*(r^rG%lNZ8fCMK^Q zTmEj=fO)_~sV?5Gxua1ZHH)=_k$DhgrNAMju!|nBkl!5D8Ay{IG+>Vx^7a1hTo@*v z-`-A!W$f+kjb+xEiR_@EDJ&-ow%kmmS-{2W>+1vD5I_w9isoH|gEqf@hJoroSmiX6 zos2I!?&_M1U}zV}6sW=TGBIK3cW!?yDtbK|8z0}h<_HH9SR@?8)KwuH#}L@E zI;{jdlhfMzxYiX4oMv!*#_G*=$Y1#)%7qX;1YNO6rv)EnYIOdsOwQh5q0h3)sV)kP z-fd;>)@}0UZn8WhLkK1*28^ABMSfu+55QCw6wrpfg`t+$Skx`J3&2n^A|_6ShDAUl ztc#a9oMq+9{81_8W- z0|ug*4OeppwJHC2Ql_d;?7MaM+Bts?c}v-5LsPymFYz-X?>hmL^QaNbXduFNmd ze#k*~px_Nh0iKm2^3$++7t;?%V*)~LQG7ISAk+zfLnI_5?(VhP+MOgV-WJCf~KbZ)ehV^+|?cBSCV?o z%F8!Jg;!b=5lzm4k9BFCA~zL#ufKxA(@Rcla8)4t+a6A~08n2Bn-El(_}mC#AQw<{ z)doDvFFMkn>w>E&>!lz6y3!2cCztQENw9hX14jZ4msz)A#(yMEoufm)vL#6iomh)8|h-Qd0xYqQ2HR z{}t87(raGrEhTptkF#5uvTEs76a>AcF0|Xm7T0fjx8<@Pfs^cG9;sHUs>tx z?L|E~y}Gz^zCLkub~>7GAq?$3o~kpr`q~`Q`{sz>TlM~6Y1muwg-C|@{L_F-2C|Sw z*)K8_vVn9Ib{|f%wE4)mIE1XLjF;mSkuT}3= zyzb4;?SkD`{2uM^n#EI_u3z$4U(`FT3uk~#8XXM{NR`FH_yXV_I&y}GhrF)#I1JmNG-o<~mYfHOzn_ay;H1jfCelZZqaajDlvK-(2w8(~X~l-gzjit4~Q}ywR;c z*<}m>2t|Wumi6`-^F@bY924Lm?S>}wA7}Flf{i$n85{A9aN}xm@}%f?S=MTuezygW zF`_)_xYe@A|M6;i(4+3jw(+v40RtOf_cr!mI{i#d$f4|BRU0+7Jm+$BWlG4Q$bZV` zem9+oL=aO#c-vv2W3k6~dXtu+Cq8)!Jn9eXJ!PaWQGT*Xa<8#-*rvMU#&B+EY8<*Pa} zedg`I_)xt2)fnO73RTN*Vw+MbC;UHPiz>C||1yhB=(mRn(S?TuG= z*tzBv@tc96r7CKd!6bS7;^~r9K|Zsgk73VVNdmRuU`dI$Z^ge73fa$n-t1K%DsS}7 zKb_hS(LAgmEI|_tu^IAAL*u356+Gf<+J6N+f zv>zJ(WqGzE8dhtyJp!w%8}f~~&hd5>{J;hYzw=pVEFp)7^^ri4|Hbd+2~94W;{zt{ zw6h7;w(pLN#Hq@!vU|S9u86#R@glppcmZVVAOk19|CrrIlFID#0g!mz%Jnrk1sX38 z?2h?o*$ijx|WJUnl|g~4d}{gc|8O@X3B7iHK-}6 zFi3ei7iMVKS*=ftrYy=9>mN3#kbED~88@%f`{A|s4X`Yg7C`L3DN8FR@9QgYdImP& zBJ|Zwuy+e5d0+0qlgRPs!4hEAkpQ__5v|Kiw~u1I-Q56w6W{~n*E?xm{5BE$E8YU_ zY(b)#+)WrQZr9Rw>l4KHC|M>nI+uIoz=dOvQ|VQwen7bSLNY$l5MG-o9Ia@AJgfcO zE-W%IvY{c-Y+FIEwCQ?>t#8imQ>a5-T8kX78}8m7TLXVG38zW6qymwU{YGCT$f0pi zf`KgT_6%(x~bCGPK*_v&W@bm&LL5#c}o0g}EjbE68hI~yz zzvvJNx^?wgC3cz2!1pj*AuAH`vRexucTA_=B@-^Z{45VgWXCDnXKLlN<3lYr^!?r5 zy9F?Gi4O?9X<`E2mj}5tW9z5yvEh9LN!hgx4B9{*TU%S((b4heP_5NetEXqE_2KX* z^{dIi{FH5WIy@*0SDd0i0L`ihWjL&$8i1WfCevVAc z)Au;t$gM=W_z3i%{W!4c8#6m|eV-S%B^KgEEuYT8z%ECLUH-22`M*z6(O<{*Z+^a{ zawS)_95~*dc;%C~;30%aWB*lV88jjbQ`%S%g$3H9y}0o2B#2e9SY8PMZWDvyL1#wa z+;Xcbv0m0;swCP)Dy!)RfBLL?S6&Hb!~#*;4@Oo$$)DB3nb8^u;&P;WSd+5lRh&Vi zSi9Dz;xM?;EvBdcp9b4WX-a~0b9;*e!47hBC&)En=Zo4<>H{=|S^StEY|M0Tm|5N! z0=?mwR1qgnk+7za4o)MFJ~i5nP|AZ(QX}{roAE!4P8DiN^w1lv&nazRCl}=w+f5gS zr|JoT>ZgZ?2M80fb^!YVhZwEE`nR-Sf`Jo(HU&TY&5s?LjcfriYdL!LKDkZ|?v`sre-UUkwh<&CSisWN5MPZf$|M zuNYWepbgawfL?&xEPuQAMB35|24HJfVB0~m3N*UF;N&r$_U}!NW{P4Kqa-vZcUKyh z?GD)A5^4=6s}Ch=jpAz#(`Tajyl3TbarT-TPm9WD_HMH^{Lx#w9dqvhPj``lrjT61 zyWCU$=TQz%@R$GLj0BLugvQEB9Tu2R07l7Qct(3mG-xN&=zLC&jm-})(oG!gCJFU))`#hd%cB$0g==RA!}il)f#^D$MF=i7hQm?Rfh$B<%dG2@C;(TZ7{9 z+1EKRuYupXGw|$-F-Pa){gbKs`dsl5kBrP0pLzJ->zf1@AMAYkItLgYp*u4Rtg+!| zKk!L%Vd$aXp0$c<$Z-}>zD#2jaW^d!^6pUFRQUY^_4!HnNhIlsVo&L&P;p+bn`ltZ zf4~U<9djeeKH#0kZ7qM_>a-R1iNuD-WZe%+|JYId?1c6CkI3ggB1$}QFT)*Mo7-wN zO=<6y_JCUO8IVId`*D^&As!MG5)ynF82l?Z-_@58V9*g5&np4mCrN(hvF+wvEv zu$}$^dFC5Q`lFZRWV>O!UnI!RT3t~t&fmsPPC`UIz|7Jl%3k@QRBVA1;eSDVdh{G+ z;e#S^|KA*!kiBcY+KCG*X6%j#@)601=RT3p{O2cO&rhyNd?O+^tQM{;ON+wg^O8J6eJEq4ky6Fy|rwEBrI2&^2-$#78Ha7N{4o?*xBLIW01T9 z!I}_IWCWO)y86%`)L%uGpuYV4c>_3yyylW&zs`ie+0(oe@Cvpz^O3{D){^qM8prbb zoh_~8bck2L{BVXiFOBxq%U1+1a8EP628ZPQ#KKVikK5)a{Ys&P>TD*zJ-qe$yyqH; zb~);yY~bN=atw%gUxX6{xpy}D!OdX(;QDWT{8U&_y14dy$K!BXz z9+CPFQ0xWM+rdiUoa0r{Q&3>g9}Tb4(vk29QJ{Yyy#JZFAcK+WJvVIesQY3Cm}T65?7#8R+GBO57Rwea)CS+uQj7S*QknA`J8-g9 zb1Z#JtUcZBL&B<$AT@%y+)jzg5PtC%#O&oRD7!@xsVOUuz7#~=njabAmXqtMs^XE5 zcxg7HfaTZXu`=W!G~^93h(=uiX%7##hh7SC2+cfw0xUcrYXF8yD5!h@%yb@r#>uqe z2*8Zl00CtRgKTHmZgUr^+gJ!STGC^ji*Z{Ugg>PPt1NDM_tUXV0VX=75*^cU!pFil zA0ta%M|ZbrP0;O=xWxY7J*|8O+yUx<^rUQR83$$g#Bfyzsa#)NPm>+3lVT*Hf;&<;lfZF=n@NJ2v-r+u& zX*X2>KU(Pkz*yP=s7FRnfTFwAyWl3RKYPi!Ov7N)-}~*892<3jB<9;n2W1YiZpRWJ zH-gYpLxZnS_OTp?MAE$t+|xD)DZx@)kC;7HdjlIPT8WZM$>&hid+;*cLieGq+`43U zHq^+F=zAA<-@ht3Pf}jT{rBd=(>}T2i5c3}^a(n6C+$6xQ zj?`Il_??N_VrQdbNL~EGyt+aoNe#q^)lpXmOqnP}Gc&595kQZq_$qz}jB_E{1JES! zKMH5e$Tv9MMYftVmZpeM>;ioL5s%CWmx(-C%~i8PR@*O&$7iyEF>uIpz4V}r%xw(n-kV2&2&suXt#-imnD9it0b0DBCj5H$nLaF_Sy_pj6 zqt|{?(XJLrv(0f7xoU|#c2N}e=oI#s6n)XEzxyB9rDwIgEp2Ie+w$J?t9BGf!~rY? zLV3A|C4k%m2yK8td|Sf)RcL5#qHhx5`*r-_bHKZ{D;{6*6`j7OG1Yi7;+*8nL5Ga) zz`Lt=HEd|A95;ApeYbGkUiw*aMXMIbKW6yD$MP?3(^3d+5DCn58@Z#@Ky3HJo28)+ ztf5^4tmp$3Zz5Hjl0^!!KlY37V=n=JB^>A-%UOrZh09grio~hSU535@u^AH92sjIW z9z(43O|12;19p0|5lE&2fn zSI|{Zr0B2fFgJI11q3K`{E>$9@xS2z)oLAJKYPH4r-k2CC0PQ0P?E0rT)ih&`MXwM zPwqlV0tNnOwV@LeIlh-rcfeo2)c)R?J~ zkrK|xTUV3$Q;(7VAwR$TWBH4l8`LM~`*Uv@u};hMi^mIOf30FSUXOH*j5K?!*gCJK zx{iyS61|MVPU^cHei?P5t#skUEMv%0WI1gE@7I6&-*Y`K5UpiR7`&@*_na#8BUO!g zV>e#2eW251DAXbGPXWrG&ws#)`13hDyz86(gLw&xK&XZnZ}t}rY0Gt!((lt3H0PA8OBDOkZ7DXzew*akCBDhi5kYi zmo>Y?!l%3Y==En1a|{$qRQZA~M$^^Q;-sQfXz6>Xp}J-d8{L0E;X_U&MC?8HJHwYX z`cawQQAmjhSAjfN3cgybUGo^+QCUBUt11uKs&}EGonc|`9&GYH!Hcy_162j)0&4(K zAAQ^0mz!B}|8A4jQ^OZ&wYBf*I`VotpN=k*-=fW9MRjPgY2S6$&Fsg>Rb%5rlPa^e zz~iat#PA2Ldg`i@N01<_e3xPGnrvpM}l`e`d5>`!KivzwV~?lCFznGmhL^WU zor4HV8PdgKDW?{x7*QSnrrewow}EfRDSu2`Iy?J8PPSPNl{pplOX@GV)SanqUHw|R zbIPVm>J}qV&9ZxB`|$`w9F?^Y8eToc{h3_HJ?6B)2LI4~sV+P##?1ai-s3Hf;@xq| zrQ`obH%rt6g(KgzTCipW@rbFTv62;AF^Vjo+jQ*Z1iOlA$-$>{gK@o zmyu%Z|EorVfS(H~!?*g(WBskYfEG+b%SI&0ULeVpu3wnIjv8%J!5|r9|BEEfS>8pk z4kXN(84ZWTxvM|B^y_HId;fLr;;(m~lz-zA@LH#C_hQBvr&DRwvtJt)r{fWz;kj!k z5alTlRr(f-3~%}3$|F=(yx`I4%GOzoN9d*Xt7Ds*&qOsxdYLKGN`v{F-kU=Y32eW% z*U32usLkXmk?I*5{11tUP}Wd3{9a6XYG(KyN;{(NPd|2tJ%@fcf5ogl4Qo@Cdw|gu z8u#bd_XmBSey)EB@_o?921ejnpF6xyjTNH1pWE7SS1G$9-BplSoJA|HM#hJCmby1; zk07RY%RIog_{BLrPFfMkP3$M^?VMfZueZPd~X}B9_L= zQ;hgB!d}Hs*1USXF+K&eL%T7yeo>XLAMX=1`JAZC*_F^Ko_x|HdH%(H<)!HIuh-sr zFQwc!hA191h_=nNarz!VCceCp1cBY1;`*j0f7pka8L~(HcHSLko}hLV+sDbn)33Q= z{rB1$8$~2$$HsWs*xmrpnV&s^2{b@xA*88)@Vp#gV2LL*WO+}XTKV0lHc3TMpJ{=aUX07rNnPNeR?suobF^ z?HjgFMUmjoBW*)NL$E?vx7A&c)hv|AzFa7f4YA>Ggl8&mgK8@vnL(`FSG#^sx9EZO zy3mvb#BF*4&uQOW<{pbDCitLo0X>LL5B)85%hmvRQ9qTOdsS#L7#{^&aPkD)#DD-X zy!x>`S-ki%xNqz`Kyoc4APJ7tr9=vgJQX%xK_65Mp~5?0*-2V=%pJkX!o|2=NG!&o zQ>j`lGelfb2yjt_=C;Im#5*B*MJ`fJ2?5T4{y+u6t0ghur$h-K*NZvVD@mbM>k8e# zCFagDZtY5)k6xgmNGHU&zQ2f5N2)ZEUWBfAt^ZP4Ig-juo_ zxl-P0=G*4HV4Kw*6H*?usc|3+N%sZ@RLhd$;`BuI?OZTXV*60IjgPc7H9;??-q8#7 zyHVfYyngMcx88vIv;d41G7iD8XAOAq;)S_|MdkS&S*4I|>rc!*cZ{;mdp`q)Am>km z@|h;rx$u3Kr|bzI>^=>6saAv-uc|WJHExdH@%>sCRn1;l;B`GRmnY^NI;#c;)^c69DmP5 zK1}!e8%F;P5lXkfcYbuB(7gAa7wN=K$J!2m4n5ESjU{sdw(lM)9Jg_p8ph>kFY27c zk>hfa*^=l>9PhIFAQCac^58^csi>kprWE)#SeQs-*1fkMzo|VROyO#LlW=9A(wuPm z2ItpQRG4UV*gm7($eLe?;etaRpse+NZ1!BWp2xZ1F1r`ma|hG-O2mxyVgZnk91>hK zb#-;U_NOoEc5&w2x=n~>l$Rt(PE_i55=Ka3o+NfZmvyMSp) zmlB-_otI}udZDa`*~+v+FmKoV24#SPT}vsaAI=|8;wnAuzoj!ednK`$@{KjXh8UQ$ zK%yUE81+laB2U@sohwwa_9tMu;Y9615#f07&KTy};z~4Yp^Ij`g6a~PFqi8t5rv0b zj8m~#$#WLZ=W=WC-it>%mfyE?9qlRg0!9qy-mi?HA3K~&Pl>r!GVVAKhvMdu4>Ju$ zv2g!9T4+#{jQn*bitNvKuXw)jozJGyCYC7!QR-fjtl<74wdfAD@vsPUmw;0*dwjX! zCuTThFWhFU@W#{O1LmD=%{{dKbRzAIWn<@n+xq(}Y-b|_14zfl#)eS`4mLKN@J_!o z_QoO!iEdg(hVm$z67?6`Yh=6+f9u;vu>v-G8vd7270|x6ZgRa9+?8<0?e;HqOk;>0 z4-bzD{0v6_40+K|Gt66CeDeZoK_iR@dj^NlW0o8-VQKDllSzcfA=5dpPU;f~h5Mrz zE2CBmd%o$K;=g57{!u*d;&TYANYC|V%&8@GD_2w@;}>O)_?&b7Swuwy{oU3&_w@7e zuRU95HXmDLx6u^{#g>wadJJ^46DQ!RdWdan^plK*VL*bQqoYHRSn8Em+xSE?qCzkU zv|n-?qxhj;eR9hFHiw?`lH#|Yu{SM3m&mo&Jzn`08EnH0&{u$YV(aYZ6EOOO5?QUd zUFuqeVpoSLa_5K1cn2wzE%1x8nhMoDH{(@M(&QZe!B$iKMLK-{(bK9vm_oiSKiwNL z7}dNp8`ahI!7vUm$aY6JUm^H~W=5s$FYNWM#07PX&(uIE3;t&b;%+;dfyBRZ(Y*R` zc6H433dOBRW9`lSpRmTOhDBwY5g7j0=K@Pnt67umopMB1v8N@t!BZ+?IS&}4YaIKY z##QZqo6cwcGHwvXTW|7OT5Ud=`(VIOwUV~bb(CFD^m{HA@s_4Iad2?3qHJ9#M60Hc zl8GkLrJPR!qnwT4Iu)YL(|0j7-|g5#{9+{ZgPmaAGi8@g0)a%2w@>ymGRW-EA;&0d z4WR*S*hYXF#YKr08N=m_jCZzw5)kNa5?Bdw=KZy7xVvbHf6=MHL#f~8NelPzWh|{% zQVdwq3I_@8o5>1-7^;{P=hO9vC9{tQolF0^#8rETN6MS}m+W)}oQA{{gHaz%usgRD zlPp?J1SG0$X{RjuE>dl&p?eRpHp5Q$58f*4vYpTj#O?_i_f6Uhs`!!M1MIVl0|}{D$QRoMMKtr}JGM##=y^Y%ic2Ii#0grBm`;gzC!) zQdHfDBwoWLrivy(=q}d%I(OcoulEx|%Mmc8%Liq*#QWpyG*MUuvkR=E1^=-4sZ?Kl zS$XBUX%OpB7Fv#3wPsZun~5?9<0Q1!?gNe;J`{L)SmhT*^xla$^ZB=xRCO?gv#u6k zP9uH+nxCQn{Th;O5`x-ye+hDxIU-o%b;H?aYDJ;em?%jUSJy^}^-j<(QQF>{i!`*0 z7w`@{X!KS!VOBVnIyHTK)y!oOkcA4~|oW16C#;I{0es0Wwe+#EjlQv0-^@hO)8 z`zMUsnO76Z)le~2-m!J@U7_mvyKw-_KpeJ{ufk;&S>IrWW|L1-}al^o!gSf zIxQ`eI|Rb-rMMcHhw;uW<_{i_{HQ|QPVw#64y?_pg>L_L?^inN9_{9l4{2a3`he*5 z;^BDf<3uI}YWn@};+Ya_aji-4v3S`TnoyJy;^MHdvDZ2DK5MIAh|@tr;*Ht#{v5D= z&Y0E7qfeq6B~h(3ve;OTCnnK+_ae3QX(}f2CDCI$JUx@~#G8CJy6+{(CvI*$c&V+n z`jXMt{_vPYsAa&sqAcFG>HFJnu|%#d<3?~OjCUZh_B)e`u7D~W)OdT-kv>@p_H zS@}VP4(Ke5oPt9m&njwUpALWq4TN1SWix0|s^DgWaukz??&BV2$VNt1$W4Kk4uYBN zz(H_)deaXXn9KFplD4snUm}bJSb1(r9rG$dXcR6 zg6;Q*KUZ`ym3SiIKYsgdxetJ;9})k-b$}Q7C+Gj4m$3d*EBOBlLH(aL)aiR|`fJAj z5r|?KX1E#-J&sLa8oFTvcR@=-!}Z?u+f5V*EV$pVr0oTKNFcx2DF5)`Ll0F3f1zAh z1!x7ASUs0=1;7s3o~KR;kD*ct3e9i))#BI6nc19?Pg)EN94-#)u_8iWfId8+DA9OH z^Zo{c1jgTRoAQEqrTJ3s{S&HBo?96Hp!;fg`fk^gUpLoPfd8b2xWNu}?4oy|HyP^M zuEM)cM89z&x-`8xQzY8Dkq1&XzrPM#|CGP?7o~yxejk%npJhZ%-aq@m=@x;%(F_9Q zE^BLRK)Ca1i+Bd^f>AmEuMw|V&tz6yR22TOEA)~C2Oa%}G2|PNeD?qLWH$nruXXMA zuOW0wORt`<*Alzyj|swbf;E<0R8$hBJ_(kn85uoGb9k17AH5`}$p+nQ>o%t`nwE-Nf_2j)@)mEbCoH-n_>O?`d0gfU zqhLuSttQKhc=Ylm1_Vw{P$pBeC?t4Z;*I(G_kx(Hs5#>u(SCiAI5sGLb_3>1@sthA zr9O$|@o}9ckkY{i?n^S$%{Zd+WBvqOA~JIFg>aF#9zM)bXjhG_893R{SVLQIBO{5k zvnDVTK;ktbIhmWC9S}67x%;}dq9Oq``#7)@j2;iEwS^?hd-IWb`T2pixn~dX(p5ZA zQBl(-r=|={5#EjO-#_v3dDa|@_Puv~-S)Mb+`K)BOeM4!wlh#~lPq9V@m>v~Uk3#7 zj*dJmnMjIbq09qCHUe>>X(Ssd#Z|)f+Kx2v0Cbx8NndDlof%$i)t{Z7GUhLl6iNlH z)-$A%#m|m7I^Z-cZ+^$)Fmca}i5`H#@1}@`Way?(ZLIzL0j(LMDi-ryWa;3%@uPMD zV;IEh8CMU(?d|RG%E;osiG0^4z3vWr=H|OSIS{njcQj)PK`|^F+Oasdun;f1?lnI) zTo70c?I3QKpbX*RLe1`gNL4~vQL1JxbvLH3i#i$LG4JhY=}|SY7oulp}5jlYS0Upx!;@%iCPXPFN{AdmH%BHetXT)>+9=u5$GW$_dB|qfr^4QpVi=* zeE-fO1HHF{Lw`zd%nJ2_%@20oADW{tK7`MV z!dfhj=+J3EC!K&3D-jkjLq&G#bjhmEKi&-%0-+WOj5$g|39bFE@dokUwb37=M~{v* zAG!aoO3NlBVeZH7rCN34j$G3NxU2I$G77ntBs3|Ym@;kB>H+`*V6J?9eRXvSV?(Ug z3ycx6!af2utQ3j7&|A734lXVz$|5^MRrJJP`aOKeIBvJxhV}r98E*ZD@m;w>s_c(a z?oUk@(d(=|8sG8bv6(3_t|#R6QMGEoY~WZXuX!)V;7D)96Dr{_612sFSDJ57Wk5qQ z1ru`ln|a~e#zr#JF_g{BiJu=Y*H)?^E1y3fJ&_}1Ny+c)>%%32C4Ooi!rzLSRh0`Q z7ZNM~=aa)5Uq2ASIjxxC`n#p=?d{jsp|opsw6u|plZM5U9H*5{O`rT-byOacpwYx8 zBqkmbE5!)$LlKjth|{IzP_6jN;s!uQe!xy-H=gMHoX^)z;ytw34%U*8fI}OlN~?H$ z7(aT6BNBoohKa@9_wkzqXM((is?HMbT{wlJIwA|@P5D$3B)KrGJPa&4v?ME9XR_`bGydS~tOp25io{_=e|^1>Ta||JLpX-4tZd#7J~A9{ z0_iQ`{20n;Yh^&W(ALH$%fxm&$BR)eE~s^%kU@Gh51}lvv9XoykCu@joa_1wq0x>vIKobz^|yKLq+zOy_>=9%OnH zQ5NLfC5hkJadJSPKHS@@Z6%w*%%W58b5%=)?B+l>`%6mLEkk4&oSXgpq-h9ZCp}=Y zjYT2;e`u~Ox>0fb6EVuT&Rg|G3fzFK6R1w=%g&6g{s~Q9#=*U{mqrkkaZsi#Hvl`S zh{YV01~4?o3ZYo&rn7)32Uu(H8gLT2)SAiL&Cb^%B{aA93SLu${N|iA@-u<+X_2!V zg0l3#zh3&tK(qlzBs|zaHqpf4$&E8LCZrt>e*V^ojl{&yC|h%R@7L&d&*N3gBx8w8DR-TyR!bOyqe{ASpk4H{VM=mda(AJ3pj@Cld3X8dafd%=l{Bzrq z@Dq~qC~%YoxfAP;L_!~{C@6x67;S)RM;peV91NBGOJt$of`=W33?nE7C>w?Q%FPv%#xNtJyXW_)(3HXX5gbo zI8D9G>}z6BrS)ZSvUJDYv|56^aenj|BkVw*-u$LD0WGNtYjSA?3}s%x;;H}3-_wpC z5=3)&9s*+`mn;V}+*~qTl9jJCs2qJ!cc}Z6F)#3ymV^dQ@ zsr!zOYO}V*)tN&yu!lO$;tFO z_5zee;EYq)o&(34S{)pxT0BIjNEkNCi!5`Hpi^z){Q)v+!0I??ku|w59)ME3w@kzbV=pe$l7zv)?C37>gxRluZM5(oe1DLmW-P!%S;8>0w6g4EA;2(PW56lPa2%d1IM|H7(#O35Z z10}96?0CRbtD@H#DsRp+?g@i~q z@3J7(Elo{hAFPvrK}P9aptD*>ILk97BQbE~EMO>xTd_u?DT9zb~eU6_$hjYJyP*xOBLwMqx;L$D`Lo@i?) zOQ)jo5UCYS)<8RK@#t3lwOgvI-A&*n&FyuaWzgm#*C807W@mr3M5AeUBPKpweA>|O zqN#~{E+F-RA9=K0JASn7OuA=O!W?jYKZL!Egom2f%@Kec(tw#knXD>|;S<%j{zAA` z*yah}>@_oZUg4QgTxL1pP5^{W{Qh}*$*h$_Co|={F+WcgnnMBGw{`O}7pKOoWsXKZ zOi^-vlJ#UKi|$D@Rk8;=!9}>JqE`<~?cu`c-gMVK%`0)slFVAmIY zu^O1~#px`wT4*t+i36M-gUr<2+(mlw;K<8=R+lo`>z_{omZUTlOzV1V-_hCGSzL_z zOLAS+Bl0dtUIe~@27b_rbHn5zmahG#xCV6LQq$qNIv+U0d+7iKhLq_wFy^`|mHuhS^AdJYK-d@E4-Yp8)^2GTmv(8rDm_!(#sUHq{ z&S9i$)!Vmk0T+sc!v-@_4Man=vDH1Ca`W6an@ns{wDV3kXjTL-$PPIqb2<$WDTN9AIDh9+}+O79moLt)ML-t|*s z_#uBh2$_u-sE(GU2$lw_COFY+0eSQgx!BcOhXnfi6E$-%x?LRfE|5vE7&ztXL97(W z9F7^hU|S}pri1lDUARIK!@J?Efn58XS+A008$&Hy-9vI%?0xYG2znpuJNpUD8wYTc zrVauFl-|vLq69gx-2`n(ZGyBg16BD=j__i1hlzi#y^0hTDv}96M@mX1iSPH5QVlR% z&reUci1s==Wy0Tlg#+KOr18D{AUv%Qi^Iq^L+`LDNy@WSOj_1o2f9B*Q|F>URI`KxwLWGKPMAHV%AEG%qo znNc}7kp*vy+GJ&9Mm?V&FNM_%-O!7_hZSh``REJ&T>3IOIq4-~3FI$})b<&Q)ZQ{t z;hiKposyoaH2mZ5N%q)Kgz|ypi?;?p>0a2c^A{Nzfv+TNT0lqAQLzrlF62Tova(`V zC9+1W=c}y$l!ARW`e-$pR0@OyKm(|aE(h60Xd@8EnI%OGb`XX*cCg%r3V-)EYVDcJ z!p<9^a(54pfMN+%H8sgXQxAARvShkCv;-C2T?KJ3wZIzO+H$b9wFOzL?62tMwQ0ZL z863&J9o|YWiKOYx(aRT;o2I4_QNDt9wQ?WS=oFG1eoo; zvTV~$!7aoOciL;-y{|?kOgV#q7W3rNQiarOH!%H;O@P_tM{D&IpnCm!2a7V`&1~`p z2RC{Yh0173AEsanikAz9&YZDk&z$#V(AtL-UQS|D+7ZKb~7@#YV!hGj^LQ31h4q? z^fXBAiu8u8-kQaIumh=>m9vA%GQX175B?R|eF`!>j0SBjPH=wZ z1@VsTL>s>eBNp27S$oz|ft#zVZ$~k}$D?oKKsMw(q>0OFbw$PEpP+i)oI_$52M-z~ zgvZOS2eJaPTC^S;uTU^Z+l_~gK=`V6nCt%ZDxk)IyC5eg=b&*`NSVY(2+qvS8D=F; zdl3<+N!rO~F$Xa3{5sF>fNpv`Mi1Wq{-lugpZl>E86F-sabWqW$mN8W6wb%Xdv@3C zDYP#b75>y10pb}$cQf-)FQUelmeQ&8dwFXMW!2S9E@y~wBA7JVrxazD;OG4OK=c)q z7C=}hZ-V)Fq`Ui0u<}K+`%-EFxd+uU#ys>P?teiaci#rDd!DtEllo*cOG{t*1|##l zXGn|SveyM@?;^Oc99;T{euHFydPXW@CNI@pug zX5k|>jV(SrJXDVtE3d5V+ul^HUFUmaWMzf#8hb2kl8}0SV!;F~)vd!PDn<7i17q$d za-@4~(!}Cdze}3Z6@>{X>fG0X$Ivh856pHvxAH>FksJODGE`;rP7`f`mWC2*r>jTl zU#N=EG{u!<@MA32(@;|%V@e1*eaxpPnX^-~o&VDmg{ON_c|g?=tR?^nFdRhE)w?~YuLUZh(=qPIEIfSt?4f!D@vc1eEbo$U zT?0;I$VZ7S9iLsf_HK1TKY?>80n88&v%lfgUQon@BI#b6HtM~oA#D%QQHir$d@g=1 z#BV8`mAto5U2W|i2@t;V&gT&Bk8>f9idz`c{V6Z}w1106fKvy+iUGk`#Udch7${Sq#ZC;?*eyVE<2!J)b?=$JmjZo161a9L+tYc+TW|fBu9&DHGh5rbx_Jggd!m zU!i(jfvnBQ-});*4lu+ZrUzJn3p{3LcQm`eq1b8Y0mtntzE{d4?4ylHsnjF`ac;X^{_=sI#r zN<+SN_q<|YU2*t^E(_9QGmA#j8a=@ULb%U zLfNk?3~|dO9B)dZlPHX_FdjELv=-747tDVPojypvKM;ff$$0r`pl~qp5ZB8ALqQY! zc#6A}e|Rco9v+xJ1!C*ipAcQ3ZI=8n6drb4#nDX^w*FBS^YGxs|$+D+bUB*5_`1L9|No{p8f3jP!P7(F{(kTnycLr`wW6>KAW)^IS5l5%j5KNNbIh=*~IDSBtjq^G9? z5aQ>F)wWfekD~-#Gg_HIxW%tDpe4m5o*D#Fe^Veyv}r=Z>%y1P>|;Sl{i=zVlywuA z>lRBBwn8WvKHm_Jl8}VZ$19&-AP9sO_VzgNs35We0?^zj!A%avu*eu7GPeMOxx4cc zFxS0+>_#S)OrchKbpaSCP-Z-|qM{;A7&CHdX-W13(|&+~KAX|$xS=C#E^iSpe)V1Dt+nO48R`I-N8iXo+z+;aF0B8%;ICmd# z62bBaiqu5)Q1TMn+uE3)9N4mM5y9ewXfR*&v#pU?a$3{0h(}POui$mkRblWk#!GHh z5ySqT^56USs{gsE{K)J-ZlujF?{>04??;-X+t0JJY%L`e+XTQNn^)pxprNVnv7)*g zJ#kWWK54g}D1oEWT>M?d;e(q#-PTmK49_%ACWM|Kw!wT3L@RxQ)G74OGbjmgHOmgqWl%U+i?UI5?t{Mp(~sb>XkFU{jU7*)ih*H3Ov6w2^$S%N;vZHSxrZ9mW)N|I-=|)= z)D03M=+n22m!MP-5MloX`S9m5K+SqwwGr+-d3Xc_8)Wm{_bpLMSm~Z!^NfOQ6D9z zFIY{A(KPqGCHA}k%!b_DT-(od4Cnn9?X_e$ekt>-boPf7Pw-NAnSKJqW{YaB_xFLO zLsV8_U6_WZrtnUt62hBz{v6Gw6?#YdZdM0R)Qcl#9S0f}LK)k}H64Mg1?B-of|g_?b! zoI$O#0s`EL9)<(^muEoITb%0AXbIHu+%ZCFh8jqQF@ie7a_zDYmY==#={Dxm*{oTszFm)WsFDM($vhBRL`9^`%2&Ni?m}fq)RgV4Z4l<$A zc=(**N^ypKNIJBp`>O`Rgx^J_J)shI`ugd~_ookS(*95%T?{d;?^V%$?k@cesvx{* z*#dq&ukySBE1ikWxhK~caXHWU2*!{^<8zMpb6wt#T(8ENL`sS;LHKNt!Dt{#t{94% zw=uyR3oX{zv&jGy%!h30>RzdrvVIFW=xQtHTRe2_l>k@TYp_Nb7RtrGy68*K?FF<*z23%k!);#SD zlGM*tBSGot79o#`!Fb8i4~%}0$ztRH^E=w`JK`T0ZXN{B6G|(~fueEV_j%8DYFBjp zWYuB`+}&5~dG;xIgoMr=M7nJ22q3vdL2!9K`dHzEnp^?7ag_;hSR6EvWNWyzNAd$l z%S2l8b1j)&On=q*viFA|ic?w9Q+lFsRQa^Hy1LrK5?@Cde|?sEcZ3x9`_qNH$cwa?DUJ6rPT{msuEuun_b+)cq}{2L|6I-eije&m0? zWQ3pqQ}s_>gbnFi(qVB-d;7iHl;Sk+KD(icO2R6UojDO6#;rc;8h|n`uuVXf0*@S^ z>(``9&2F{;XRCND)i{Mjrdiy-{nb4-MEQO2K0LTG-0%t9mq+nK;tMUFj9fN}oOU7L zu&_^4n|_wN^rH8iNJs@AcNdwc!BPbFY&;M?&~}dx`S~V5SM%R!h%=Jo>BEM zw}ki`@{=?~OJ&W*Buiy6rLuLgk`3ln&*lg8EeYydVn(lpbc(1Ev51X znXIktZP1u~flgx(XW&If0c!^&s7Lp1l{vJ=JcKhY=R2(=XwP55lEOJl>hH6xi>)}sUSAVC zakhW8!gO?7tZAMCBnHn5saQuBA3i%l|E+ztl7)F5wDqi~NG!!7Y z9Vprc*368FE@u;&_J9r_Ba&_-`q|VwL@AgLQi9VG_+DO)J6ewMm!qSdLXI337zI{ejDpWa5MW0TplYO+fUy~^0T;4# z`KHNV6m0dEda})gj2KG4SEN%tc~ymuD^jl*$%@a1AA)4=(UB0zflx-{s!bO`sJT-y zls|a6(EU(#G?S`YJj`2DQPyx6n(ZqLX8kuL?!QJ`#2-dF)-A^ z?$D*UdwM=5EKUD zy^i`2{0R43RQvK6Y zh63;u-ewHmnK+GVY_@M|TmfnVb?0@+Eb1nMwU_K-OQu5mgh0l=-f>h`O1phv%LiHc z^eH+cUKxbmShQ(7APj!#_lW&YBy;aQ7UYr2b`9@zNI|u-0xkti{2-T8_?i1o$8A3L z?t|8kGavLtUoZ>=fW&CQ9~W{LaXohko6n|j>Xy-SK7Z^^0>FzKh;abTv)6>VgiH=c zB-JU2O#lv(1&5jXuhGa>AV3|K{W1{>YGGbRxf4safEZ8cYG7>ac-)i7hTM}EV3M|X zUs_yDE9hBP#IL{#Llryss~s7fz=pNhgS(M`5p=Ofs31)pK$8n zrh1|G7rZiG1qHaY8m5$hM_&8?T+4-_t1I_SRJ;&0o5Un=>o>Utnqhtr9CYj2k_^d)E#6A@`O$+E8(n-2)530WjO8rnaX5nj%31uzBmlxLIU z@5>?9fLG{VE>81wHezrOaJ~vPqAp%>?r?y_S}DAhF9eO$y%#GviPWco*v-W4?ha|D zB%dY7Fw;PU+uw=a&ZG^j8BmNQ>g#qZd#OMJP+E{4t1-{!mDPa4_|`N1afxAX$1SDf zGoIIqDq_z!VS=FqA&(wCl6X(F_m}sMQ-+5Ng(kvK*nXgjm!Gsr zR5y8WGuj0)101f}BojMQeE_@JJ6j@Q$B}kiAK?v`pbvUw8Dp{=7?HM0$b_FmsU1tI z&%xzn`HPbtb`;X;a6GxQW3ebSpfuYf<s=VIJ>ixl0%W<0knf@(TfVm#0aZ#cAHiHBCPTH4p z6WKVSV8 zc2zFt_SK)2IQ-UHcjVNT8oU4B79Oyl}qcQ;fhdz2lyr)dxL1@1NvP7Cas z@yy;v@)YLGN)AhNbIxk|nU0EHSRu>P-ee(ZQ~bzzAW$`gTUXKk9R|d7IgmpY0Or?* zvv^7UIdzC2^=`lM0TooQ%gj4tj%NzmwS$b_w#NSas}(&IK#u=JMEblqru7S;7Nh^9 z14{%6BPJNCRpJz_1Zq@hlO)|Yw*({Dtu(>} zxCnEQ?VFgWdRo6IDJtq2qbPaFYe5%HIaQIa%S2S0(YOT^VM9Ppr=JW)XVd(3=0U)j zx3MX118aY9n{W$xql4^sp_=eUgggcXBm)m1M)j4IBjeGD#U^FVY~2AY>Cnh|hM8G% z@0N-JvB3gRN@_QUY^7c;vC+1}Z{u;t0U+x2=cGs5;9e zZX3N3jIQ9PNbIpJEiDE8giO9Oh8oV{;c`4_O3fEmc`?Ne?8rvvJ|TK%{eOgAWmuG5wAGA_J2uWa z8$R{>Jz~r2!Zv3d=x-V}Ce?&4(%cqB|FlJZHKwg#=a)GEFgUaTl*spDPo9`(DZ#Tc zGUQermky9`yo#Fu2%vDmhCyX6{S$1KQEUKL>qNq0AGrGSFvIbOW%nF$%iKYR$+rBN z+aT1LTR7v_^mMocY+j9d%HPx40DtLLOmv_ul7 ztLTIxE4Yr(yLaB%eHd!HN=hQPX|VP|@H<|_I+0rT)=*1)h`t-XSZ#9KF5g)Fxw6tT ze9~BDKBh7$;Ab~`xgkp^=?k*;LI!NzQ!f^za5AC_D|_ z-g=^%i}>X(L5nkiux*?g%*f^at*1x)^GGl{osnwXDZs6xTH>wwi!`YBhswjE+p{OB z2Fey6GJoE6FgWA(OvpVIYL73~cvBc1Mkp!bwv%FD#F&Ifv;f3)pv{1{Yi`LOvzAiy zAsYKZKVI1&E6f*uipQi?`7Y{V>*&v)N;ZN*LP?2<(#dM&pd-H{?U)N@KqZv*eqeL1 z`B;pZSXEg$Ch;@#je#)DR6ydM0WozCzLy(@sQcU7qr~wY?g?8q>?ohYm&$JMv3InM zuS>_Yca2T`ss$LolIf1jqtFU9|3#^il$;D)#X>rk0FoGtH})j;PW2Z3BR5*&+b;gB zWk?;i3)sT>PxKxL4~P&2D}$fbtj)pO2xe_&hJJNXn`@X8=V8d|Kt{2FL*#7RWU4b4%m5PQ1v=$s-@e}7sv%`Km?U<9x<1-XqLz$Un5;s!8QnZd z#?V}-_E{%vFua}M^-;rUD_)g=PW*GO9ivJtNS|ZY@5-|}s0&$go=oH01zXGbfsWB^ z2zJ~9F=LM;{u=0*f`mY)^!P3rCcA)LN*rJi(M|>{H~e)xUUBv)t{w&S;yV8GMSU*v zN?D=>kfC@zqF3$=YFGz!=F}sn8PdDIK;M$e$=d)jhzz#4`|O0$2KzR06ItXyi==p^ zylmWulU`<5Q4~`<;-nF zfEz2!56}NjgI4H*86fTP2z^2ziWXzE0uVg1ItBG(9KkaHrYgByTl_s)#=`)TnEjgP zMMI)8h|cHSOu)|XLK$sWKFu{Mo+$g9wG(JH+4~bHwjyoMr2Bx$`0v4t+Y64hb5SY& zdg5(8P=_t(MfSfZ941z7%`-PUe5v{`7tII3NykHVX1hP!7rqx*>#oGnBXjJ-c20Yj zI>I_rDmH^cb9_hkA^#k2K_ad%ZyKm>2)l zLw@!)j{DRL@EwlsDP&JK9=6fCOVV7;zy8J>F(Bt6KJB&5?C0rjGx{Ph0ksBZzQK+M zW2BIB+jO|)?4Wrh^A^qO``wU$>$dCJ=i>nQ=E(dm@fw;DYPL6ECl189=P!qa9GIf( zU)DlY*FcVikLg9 ztA#!VewpcXMz?Jr%Wb^HDqg-yO1}^GBQ8AvBI(XJ zptY_Rclf_1m*m`2up4wc?Ds9b&o_%M_ofc@)8o*nXP9Ed7p@S`c!}vhm)-3AXz@FV zOTwp+;o^x?>|{Qq86GDpyUl7SQdK39W{ay$`Z3p!8V`KY>0uK1wWrSS_l+VGU^qlZ*W_KIqhrw6sSwJm<^rYFiKfk6* z+(ULHDT24rtG`=C@@1_jB7hgQ@&`le7)#9WI7%3ha3x}Xfez8XkLP~}thS`Ks3(2L zWF@3vz7s?H!evbhJ~;2xazZX+9hV1@Y{9p=jR0cjtY3A9FT{mFB?q{d*&&+2GD zzTbR0%8Y-rw1@LwPRTMt3BtkT)qac=@wVp{meh1(c}MxWDu$PJ?eU?6DxLUu)SOiF zUz@Xh`^F=%EhW#=4UsE^VG~HfqlnRk=8K{1dEb3rzoTMgl(>Styn#oqeVuXxpNPl< zY;-Vws5V>|JWyxnN->Gu&0xRjIT~Cw1@$!q6^ml#csHvtpE^R72fY&8uW5z+Pw7pLhyHw!UUr6~22?$+am z=Fu_Y9iMaE;e9*U*UH17{kd}!_nE8xCPesAHmY&IZhn2<=S)9FD?7{KEWhy5(0lr`1VP-KM+n+|&jlw7XB6o)CaHfJ%W zTi6eOEol>KX9N#S2RIpadd^uz;E9$$-7AQ9E?SZ*2Lh|Q6QM&M#H{Duau8UPLk@6E zdcW(wtRAm%{RQ8{ps01fUF&bWPuGtkn%&fPDR`dR|EV*)S>6-leE>80Ypts1yAWmA zu;1;^Idbh;U%50Vg*u%q&yV-Zh9T?L7hnPe8~_bCYoAn!r7BPR_6kdi9C`zLnQz~|f!S(wF~_ffBf5M(*l>2l9af+{aCLd9qpRD{ z(4g<5z&bE^n!~kY>~K0VLWI>@jzxcv^bXLX3!n+6V8EZzl z$(smTbyFyE{eWi6IB6nQ-Z(`YPArzn6Vjlf{?%(X#2cnow+pjvVcu_*jaTT2o@-wn z%5BgbRqi&JEc7JHeX!=kgyBS$YybE+9;vg7p%)B4dH3szIZo`QyjV7fH<}jknods8 z{I0go`=vZD60@5t^jJ#*ek}=+CF`kc;h7 zSy0f0>}0Hb4?6`6t8+P?qSP*rH;hio?bV03e=->>wrFdUj^n&CbIF=Wg0-6}gvH=FewDpfqB^`f)# z;0Y~!GbU;@f0D(j@FPx2^o?Rn*2kb1jHG0N6SVupHf9+eJ-j0#w5eL7$e{;i#DClx zGP9f=C#FnPfm@d3sO!Lu5#ObU$Nu6j2LOyiE1@|t^im#1TQMzBsHNSBh4Zpx10Tn; zGf|=0@-J=*pZ2<47i!-Rno|qeOgG=0>e}0O?fNUCF54EcO+7XBo)Hj~}9uq={K8!Q`24hc=WE(EmEe?kOt7|Dnzk$0+H~NG^iA z%gN2Xip^7niDMMYT6j+C+d5VkN)-tYsHnpbUA;271xwARuz9xRS!V9M54hX44dfzGgB2m4))-5(ZM%nLERQKbkOnMT)dP0uJa&tR$@;w6* z6mzC-=AKRR)u%n_kS7Yn$eI!&nNWdOx3eHl=fzsQubYGSXI&5LpBTa{y>}&Mcz_fC z!a>QCbYTU%hTZ5HyO!f|-F<&3Vm(RMu4(yW>$md$r<1V14^fu`LlJu3zMJJQ?B_g? zm(~;47pi`G zorKR#O>-r>pxQ$RwC3!~$!_~Iy;_Vwe`K3iJ)znYVPR($Z)1q9BL|VW8>3!-`M0&+ zrWuF_4ucywoG%x8(7enoCqd)D4in3tF~X9QE(mX#eHtG>I^WVvl+*ssPMd9*FN6J? z_)Qu}lrY3AYy$%@OP74BB?%3*$#AdCEbi%S_WhIzzh zuuwSi zBa^266Hv3=OgwRiyYZ&}a55E|{q`>Q46w+xwLQPmS&C)C3B2}{Ypw!qw+V>dR6NkW zgRVJhXL5xOetP05lAq^2LzHGM1ebrZgGc$HCdPYaSOPPxCh4jKyCJ{$!PmfqDp-3f zcQf<(A0o2Z=w({;It#nXZYTmDZ)r_T@n1y~1f_rKbWUjBf&|MbYtGa0MiaI9>lk^l z^`Zr~dw<>FEStin_Ov32d)uzTYTH&A_^-Pn#t(uIy4Oa81J34&pv&~`K42ictfv08 zUv}d@b$}}D(TJ4Kbp?0S`c7y@&Dr5dJYflH#&AKGCjf9(0?r4l0k7SIEIWcGd3pV_ z9}^zT#`*hCl(g74=+$a#pi?sh|EU98xqRaJ%gbU&rdsEm+QsXKBX+OgSlrI>_$O_P z#g^SiM^4^<0G>2@=n&t9aP;<}R79i};uozGSqhhX^R@+-?}qJ4E7*-I+15`5*EDbA+DE@#&x5>VH@{jueaqo%9~zAn_sb%soVc(qhlp9|UB{V&B{j)!KST6( zA0Ak;>&`db6)!8CX*kBKN}p^>b_nl^G8_1b8kY^e{uyF+s%K$d}sfaWIeC=cl)c#lREbZ;rzt>!P0IY!(&*f+lZrF5)pb+KVYu^7* zR`#{_y!}{6&|YVz3iyF26sI_FOrU zjUXkf4M+H+)%V>Ck)pTG3D$QZQTOznS5qjzNhi9r;9DeE$ivsdve?NK{qeEZh%9}r z_Q(^`aPBN>&Vze&(VJr-ib1v;llQd0Efa^fvxy9d^VXLRzI%JO7CB=J+9RJ4TSn7+ ze+@A(5yE-Lz;7osJL8e-$e87eputG9m(}Z)q^D5Z%XF5=S8rFm7=dA5@+*MZUTkE&Wrri)P-De%o&&sE(Vz2Nm(Id#r%TyGDt`{I*({4v|Tthu5YxBj~66mM^y zq}J94-`CCNLdj)jf_@tLcb;C-ZLt+;K1y(&5cCkiTv<{wNT=Ce#N5+i(`6HkH>1E| z5!HKmyXTx6Q=`QsB|+w>@#c+O0U-T2vEc&km8oKYLJsBRPX?8+AUfc_*+;Z%E+9T+Bm`WBYJ$0n zBbk-6sM@a$T;c{|pA7w>&Pa0iUFfX72eE+Cq zl(X?!y?L42k>QP)2aj57k~ zovTted*)4q`m>(8yJ+sV7w7bThCI7Q@q~-Vbo2w)LNwVw_m0)iGYVhw%aGCcDcaxw z&Ta4AWfj6!A-Qq==Yi&qOpxD!&W0&$hy5n;HqpY&4_&bS$lg%KzW;_hqu0;g{`wE- zi+B6y$@#`b(d?vFg1GC`Pgkq=9gsls5thaTIXYb`!-;=X>!1zN*C(dlQIlVVoML8D zUI!mz`inT#Lj@GQ4!{l1v2&e#5S=C>+WIn zVhwwwiahJ*6nzFAe^Sq6yomxw>{hWH>H}t$^^8QN806B(3>YT z6#cZ3;uDrh;K?MS?9nL@dyRS8rnk85CMM52y_lKXC7hdbL)q5MIrekcJkj@l2{yFhyfYEE({H zM$q608Moc5kT;@ScfD}MUg)mntSS3FbPhp)u^*pND=_(dDHQ-ylyE#Qm_P^Z5kpU-R1V}UArgtp$j#HO5 zGJ({p(cAv~@`*LiY`r7kZ?_O+CKwk6EX`i3{(wy@$|*Grb45j*b3sa|;U#6*sR3m(BSdUnKh+ zFE3&kHdP=OzM`^GwV!bY{!6Q@?aj# z`<-I23>Cn7GRh%7U>^EeclUUSK1G;K!)D>`gyBr>($6vpmu*iJ<@HZjO~bm2ue^UH zUHXKF@L-}83LD{DUwQ5IP>cAwZiX=5Ip<92(gJ>PN|kk%!Y)T0mP^i0PKf82>Hw9u zCX6>wL|{>n3U;0tvjjv)V*dcI)t|t7+W-u0{=1!S-&npH+*|EBAzV^-9uYI^yBB0w z>Tyy2;>z97ZK=*syT-2L;>W`5@7cTF-NQdL7bt<+59Dp2$nd+ou{OM3Y9ghNq&H-> zCc<>PCy$?9;Bmb89HTmvNmn;pI)Xdi->p90uN)1{r@ycLl z75fX$#)}J_!#7?Iua8xx1^jqQ8ivhBIEBhq&;tQUe?)zW8VLbrCDX)0<=VA%JK@VJRuq&aEKIP?{y`PUV+AWnU z5Jjt8V?8l5?ov}%~xAyi1{rX92_(rk+BT{xMq4mpX5j` zB`eD<+4`wZN=60^C8hSkrpUy2gmyjMms_YeneY32jO67;YEic5r{kqa)w?RH^gaj* zRHY|kDDt%NOI_31RC8yUFKLs-x&r;p4VU|dfL4w~gb=S*jw*|)_BNZ8;re0q4KvD|O^!$A0IK|qK;IR>LV2uOxyv|&I ztRWIWko)J)eV~bs9%hs!3!KHo#GHK=z#R`NQRUcf(s_ST28-XZ>t2syDnIs_?G1ag z0Ma$BtE^qtFGnu`RS_@>TL$8{=PFHx*)Ye2Ht=AQFlYn1NVr>aPCw&Fty^`U-qCMy z%c3h(z|c2Xw+qR^c*o{HUIEl%^%eicTDpDpoM*CxNXlS6rXjTxR<7|ds_wG;c=*fJ zFlQ;QeeD@Q;Wv#oX!o0hn|HEU17kp>SQe-Nv{)&rY!#z-ILD^g`{9%TtE+ElaK?6F zAYunU$^lZ2rK`bvN}$Q@#&kElLmpJ|SNhHXGSSTOcd4koyz~;I^#dU%qhGKWe_BUP z%{Z|q2w>l4SB)X*{D51}_o648^~-@ysUJMQ_^Iz}w=ZOvV_-ThKjqhOA?Z!K$^oi& zzGQL7f{6Pz4wwR2!S4LU#QF^LkI(TFJLzgvLnTS})OpB5(Pyg@K-HF&A<=)cNZ!t& zI1KafGePsK2jifFD25hL(%Kt4OYB~b#T{Iz-FpN~e0#X6Ccnc|^QF39RO2!{+>?EC zuSrhhPdxRbSO5pi%+5xR#if+IheXN536ydoNEA1=E52_1#bNBE>560fUWhY|XUFcl}$qsp}+ zpB=0Ij*4KMF%tMoi}Ol1?IDQ~A=XR|2GCjlRU<5p#6PR3Rb-KAf<9pw0X7ce;q{Cb zq=v(v>16YO{3?a+ZIB{kQ&jEnL(J)HHYez7=YyE!{WT8$cFC-!lbnhQ65HM(5;)oA zOhygop8Ux&SHVot5wD1Se&s;V;!6xfC%3VfV+ez@7==5Rw*vaiQ!fRN(W#Oj#XuXd z%lu*7 zPj4@MtVdmytbziTc@9!1rgGt!^mRU;EFyT5`=1{?In*W z+DIA(o=dg31UKt7B+9KL0@yx`nlwr+g-*6|hn#-;U159!iPELzj>)g(8xgLQd}{|k zje#QOJ4%Ll@xMojg+Iyt%5?W@;62Z)C43C2?ySgwwqBx(9Nqp>X5`A5(5d7q1sRd0 z9zX7f??>s`ZwiSm6M|+Bx|d3#rA8N^AAkXY-{_Qlj#?_n$@MT!^IaNa&QWNmi>h?1 zo62SODj*cx1CE%-=U4lF7H4~N`VEA1;vzkjg_5b$zGG-hQSMy}*Q;kOXEw*vS2r>D z<%QhmoX?n1=RH0B1so!F7H!R?zkvv1jPZakdz7&Pr^@1*gNDGA?G0x37vzX?7UYkE z`*J*W_E>Mo{331@wUd(C0qo6jIKKhc7{V#`d39nEBRUw-Dl`I&INrQTch_=s#}wsb1a;A!Mqfklw_U}I90ntKHM-Lmd=fp~J?)SH zGiZi!;Rz?ww$l>y40@0raUT0iPKY&m&dU$2Qw z+ZNQ^{<`-bUFytd5(})j_h7aJ4g37*oei$pBnM{*5dPPy?*R598QwW4gdZqaA4Kd&M-$k{8qe*I zy%uO=0XlTb>0{%-VFB|7tuwKc-vj4UK(sQ`2B!aPZh|(KO$DCrPoQB})(=SoGHj3~ zpuwSg;$0jRmfctuWR}r)5m~eA9lJTpf1mXbS{%aLBjLRs6z3Rej9&?8$e!`oGFt9xJ%3v+-4Xer07(8 zS9=ZnZsN7h?h~fKB~_9b&(C8behM?U#?JSoyJR=auth@fM1BG9=Bns48_A7k+P%)1 zowRC{Vn|C{L9%WScJG&-j&{qJUZTcf4Wk>$o`oW7YJj$ATE-ABwfu zg$9a%u}*IYsXdyca*~*;<424%;~t?1rlHk0cBRmnM$T7eG+i$(zlPH>7#Id$0v(9= z`!1wX zD#cLwpkK1eJ>qw>ZP-$IRld(%Qhg%nup$_vM*gi)Rm(U%E$qk$rz* zwChXv=;%FN^4HT~Ce{*yJUih$p{u7v%;opO!hY)72Ww%oD$$)z#uW5>ceEW%L{RVj zK(a0pxD1-p;vF_3#PyM~LV6*;cCGDD>J(gpR8h+bfP|IN{)eeTpJN3xsPs9Sv(tKH zK)Vd>B=*7mAyiQD&LM|cvqaP%%9nRn2Pf_9-a6t4J>IlZU3q*a-u0Y(1Aw$VacIfr zeldJftRp-4dD~sOWWqwf@=b#!AE;OOS+f3oKzI`IN|>%|bIMDBX6l)FYzpmD7h-Nl zJ9ziY=m9lS7KA_rtlt0Gaoa2nt-x&FHC@;+#~Qh1E5?(#Z{5{mhXuEH>d{CD0qy05 zUsE#z6hP-4^eW;tw{d zk>R2}cpA~f=wKq8LE9W5kMH~m2ITu@A0s5_G2!Ik&8 zwhU;Q#oFGwelc-!U@!iE6@|o~!RCwyP z?BOAs6CP$jrQ1O4(*_4*M#;pwFIJF*C6<|iu5N^^P9#v^3=zRqd@ipS%E4??UJbkb z9dCD^F$n=YB1tc`xj)GUPF6P<6d2oOGmVbPVXnv14SvU``+}iB2y~kPorYO~Rwfea zLP+L`xWp1JZP`3}p_zUB=eYE8oI7@NI7lvp-iP5bvjufSUvK*FML>Tj=68w6E<+C6 z&Z(aI9<+6?CL8>jb+I>d4rap>E^b;+J~YhiHI4XJG6GH#Yi!myg4Yi@mTkWL>oS-lv7_MwyqFhTmT2Em?-KCx*TS zaT?+@Bap07=W`X{cl9kx8K|=VL7aaZFS=1S`1@&pa>18CvGF$DIzssGj-DXTFT?F zBP=GGUh4KkR=V|_uH`^+31*J}C_qmwu`qAz$^(8+`bHUe!P^C7pxkxQ@Z}?0pqfv0 zq}u?jxn0Ydn{nNixfYcFjyAR}s2*w5U z(^I>ZPcGJF1-IKb3nDeS6A7@}azS#bDh8ec`sKhtuyvp?+ zC~l}c$W1o=1Eq<;>^qHtSGu~^KQV3|adB120xw^{@>_$^WODQJ)}R9>-Y=^nQ1I(| zed^2tL75Y;uI*YTH#XBiU*9%5T56(L8=>)sHouGUI!v5fH~}1C9Uyts zxVwg+vh;3W`o1c}&%aF9eqX!)-}i}xWT%Nu(>*7Yks5Dw>v0}#K7nIq1!;K!;>eN~ zIB{P+Z$tq8zsQC>pHy6S3EV@~d;fn!*IdNpt+r(NSwybS1G_dVU>h@~rbl)9 zIJzr_4Re}#{Plx4nZZHE5lY(>eQcHNb%TZ(2p*~BgM)QRnTi_m zo{3T0$!#cxyX@pY&gPoK$^r51?fUh9n!1jSA08e8YBXSp1>;cw=NE4c_^Bqt6M^a7 zqy{ZWW`3?X_kOUscdrIeXx#FGOiCYj3(x#y5P4&0xIfkBF>B5;0^GgR#aQF}0H6YV z;nvpH0P{9ly`f#=8`S&VijkfI7rEFEh`yFqEib9pS2>`^0E`z>3?$YeZjj90P+?&q z;7rkc&@<`y!SjG^C6aH9O*&_;;QUn-Fb~GS7CZxZ8#w8@-a5C|0$z|r=kurU?r#7u zU_3D)hULkp;^Hu1hBnM!pUeNn#U_kR512XJf{W!)Fn8zZ_}G?s6ZlrK^Z$v8$^TJZ zU2iw|Wdn%E5x@?iT*9RH)f)H=FGzxKdU_0pqbn#ui_9U6YmFYo>%eQY8u)&Lf;l{Q z4r~J(A}U+#t{OJ}b+BiMlWpb_G4M_R>Q@cg>pNag({V*Huj6y)Gb&{Ny8=FYqk&j~ zS|f0%JbtjkVn@>wIAF|XQw-ci>br}!V}n1|{DutT{C!24prxS^9QD=;G~{xMib9;{ zfw_mIX$Y)v>>zI>0(5KOF75uQt?!176a}~XdX8rAS_$i}`0s){M|}xgMx0LxSGwu? zKVVGTiW=~8TCH9d$^Nr?Ba#`20Vbd96v}v*I5AbyhQH?K@PmRn+9qd1F)}djI~Tp6 zzGcf|J|?1ZMbLlWO%?7S_1*0wn&A>92?GcJqUxBWutkjvUem#E0DlS!3o~=3*eNK4 z;Gg74)~-OQ48*+1L?+Ow*Z`Y*X&P}TQdy8c1I*7N-DJ0O@#nrBPmC-;cxs_SlF`r_2(l$3zbsb4~T0Ba#APwPs$E*fr0xc_=%S26Z{RA++5bW_h@elWonL=_&I`0h|Kjm**!&xN>90nQ zo)k>H1%J7Hy#-qWZi!;ahO+CH>-}XeV+V(kYM>RSBnU~as`U`JdjZek8m@r7c&VVE z06a2ryY?*wMaww20H_J{r`p<6;ew!?1TFb$rT+HC_q?;feNnng<+1F)1im9BOoRx~n%S{@~uw%?Ut+N`vUaLMV%@Lm&H z24inyIz_tXo&u&N8V?7DwpOBeHy60^0Hl5xxv;3}{8by+y&RbUJ24Xzrc`C1SgxfD z&IHT(pb`XH8|U?t6G1uhBf!xMiu&?}Lo+8gQBmsg<3&OzsM6Y+nrcD>>_7~#rcL-F zlpVfJ034DD2%F1+g_KGs2aqTa50X!OSOzdGWAPp%S(_!%IC*qL=M)uIY7Q4mr9`dh zaF+I;1^b#R2i30S!`h-BH#uv-SxSUrqKgjr4-w>Yj4;IdqQYzpSPp8w-#%AWA@Y{C z?7TOl>Vp=yrq)(kKi}|&X#rsp_)2rWYjp#dbEaz$n#4z9f>-Zn3^g>~ zp>^NZZlH4>4Z89vV!vJik#a;w7;W&rB}M-}r9?zyI3tUACbF1egU~~7 zd=cA4RyJT)8uUB`y?AV2G(0n1BS@Fuv?TpT$P-eMIoONO36VE=^~&gKF4iT~)z-G; zNBAR zMF6&ms;(|IGB82F?=yFd(++93o}S*lh}BwN3@Qz*byYB;cI3+iGbz2*U- zoA0%{n(hjwX<-|J>^J&mTpfG7NUiE?YsF>v|607=-~ zaM07Eij(y87M!zLUffIxqsa`_1d`TbGNCd;o&9SZ_GGP}038A++_zB$4+D zN7ZvAx-RB#C`|x3gzZtH4`I3Q>dcEZBU10PhQj}iU;q3s8?f|vTKL!hBNJRqPoj*2 zH>YvqjtA!A+!t~7&OK~V0_g@vrS8d(k$fY2p{~FX$LDG5S{L5dn*Y2^^}uaVY+CVH z7T&Qie4h<$pFrFqnjP3bbg|^0jpn=a6n)yXRYd7wkmR!E%a?-&Si!{3G|9meqoaI= za5tYh#2Kav{H1!CJ{+7!r@w`OK+SaY&?BSccrqsfp~sT7FYEo8TSb~yi@Zb41II=; zX2@wWJ!l9hQ7*qf_iVZ+B7I!HJM8&P@Hq2UQ}O=`#lc2CfH#gZ?Vez{8%@S zKtdm@X9pNn!(22;MQrb;gPxve|4Pq?t~>nH;?e-Nti-<}r5u50EA0Kddy=N38xI)h z&)URXaB_arVPsPP|EBV5vR)@^SO`2@}Qm z^rbeA7eqd^fNaC)aWBKW6d+6tQT67sZH7eUU%?(zd5nTJ6>f_S&iWoOM*)`Xs+9uG zUtg@5pKNNv*Mf;k8e$*CAw7z5X; zW5en`$#e_V*z$mpnW-@;*}7Lq zZ8*8R)>ds{Q`3#}&~hZH=A*=i7SXaba|NC65;z>MLKePp zP^+~ejNpz!4h|z2M+O-NUKq~}OR~T5Of2E!3NoTXp)Z1QL&(P*TNS$eKeN~_Hw%N9 zR$gcW4{i_F=3=PmWi51#w-bfY!IR#-Cq*oq<5g*q$4hklR(np&%t(8visJ(2UZlJs z_|xt9Y=>V*KCM%>*N5`20(H2h4P(XUn3QVOG!4SgFDKvchd^gcI0-bJ+Qsgg(NZ21 zLO-ZQRbc3p(AvwtqnUe+M?OLYT4#+%x7X^IR)G+f)A?i|2WMSb1=3IWSh;)(pEAL_ z&F$^<*jNTT&V)jpfEj63V{b4lL59h7&3>GN6r-KOIBz+Z`-o$PUqGO|LFJC@bB$8H zu#T`4EE?;fF?SME_u@Dc@x1(e_Ya-_p0=6t# zwC@MShfXrsxzHA^pV13MeJZvJaMpjo2AL(kd5^s!hk?HDailtU9^kKF)R}q~o3HFA z;;kbAeegVP{}bcV@aJ)-eJJ|ykmma9|NgNTRRxu@xDHn2{KMJ5{<*xoC3$OS059}k zRs*@&U%UV}>wS@(rX-f6*U6cBcGidgpp92Kh6Y(uzOqVTTXMKn8NlRAQ&SW8)?#6W zfYO~m3oAH7MMouDQs2p1PcLKgQQ^qXzP>i6spCx~$ES6TfA0_G&4~Iv0$2Hb>p7Vv z4sa>hB)$(OZH`P#)KpjVTzoQwd&r}u2!2TrB8!QS&B~2UP37?OYG05OKmI`f<~H#H zZ$a)SSa`Ptb2aOuHTQ=;`UFtgNyqK^WH$h6101>B-5BW(q?3w6wHvEG|4a z4;NRUEHL{^9LCUDo^lGjM#~Y*Hau60PrM!~8!_rS5h@?O!E}BEJ8Osu& z7T+q@p<7uhD(~6)63g}Y(bNk?<01Ih*Vhb%z*G4s5h$l$t?;9Zva@5Ci5h-WQ&Vei z%zilX%L$0W&CEWj5GmT(m0pjU-$^Ymd=>Fv;Pl|2^}|W8i5hD(H7V(9{vCAhuAUwc zjq|h2rR1Vw`PqBu)iZ!v3Q3L9NPr1m9tX_-HJnfW_jp+sdp<%j?R}ik8bCW@8VfimzT#?>u6~O1_d3;svsL6_@p-zI428J|2~v#L-Tdc3y8#h z(*bjA!G!jyDQ&v0yO}}l!2hNKY-~56*=%nCq=2r)8Zrs>U}&-^Bnmf2kcQZ=y*kp}9L5#oS#;pmVxQvZQgeCFRB8+}oBm;4bj%s9BJl%N zMdPDU;y?~~8I!=VQ+q24H?Qma+j(qJlF0mg0`-NrB~dNmQBhsd9*OQnarpP;f2>M9 z%rzUeGrz88zJam$sk-`_d>qoeJl1}xgbj`iO~stU`#d-&0^Qaq*G1}407fnR7{=90 z`Xt1~rA*fam&&a?7v<8;Ief{5QUPW)3BmRKM3z?W9GE)j@3%#w0M7we?&AFGc-A$evrT?DN)}0n+bLHuI;_gpHS;US7*eq`FxWCogTN`^h-?1=%1nWFL9-~s_)zwLEogr_gS;{I!h!es-79>uV z|Hif&B@EeqVcp3q^Q(svrJ-oPEWjz#!gBE3V)8y?Amk<-SFjm}1@8OMcbV)o(!SFo zHBj$;S8OE<-z!{;-7&MD@8dHOf46z5qHFOfPuHQbfl5wLO_- zZp>rTlhw{)JaTe!Eq_)}o#VbHlTGySE616z1!i~$ij1|^z}2yni~`NAt&3q9#>C7V zcXz6jfyb?LulAi%qEKf4WLFnP0R|S%_Z2zY0^gv=rm%ObMa+^V%Qw$nS2M9+NRQMOIli4JeR?UqcLuCgV^LnI5w6)3Q&BGB%`jf|}@MkoHgIv~3qd)p^d6b2uSHl=_Iz6l9r#(LixA$V0!F?5EhpD|MvN?l_vv z{sRHe@?RP64M>u%lx^;!aE+Y6-?#aqkUQqdwcDxk{h$(518+D=w57_B1y;R^y zc_Ifv;k>?lpHGLes~%Le=L)=FK=JfYJZ_|17+mi05QV8KoSCr9%xz;#hnRP5W=^td-3v3YQ?%H6%YLeOdT3H1z8B5*8A z3DH-5@rB}RErDy*TQ(YPl`n3bEs?IGt`I&mPX1O7HB}C!$?k5f+m+tofM=0$=zaawr==q01OIh0QM2Gjbv;-kF~9>OYu`Zb%w>k zymn@vCv_z^U2B~axH&o!_m7Z?goDQ;h#8ClY=PM!%_UvJHRAJ^ zC!1qh0kQ|qz?Mi5R=Q&9v(iRbfLj$4quQ6vt3<2L%`tM+oO;&<9?Zc{4% zx9^e#j(E2^n&FP9IX-+TTD{0{x2@4Bbo-l?X+DX1MWbyIPzL@0?x|SISSZLSl z9tBIdttkZuk;b`Pe-d{tExW?3S$FJDP4%3v#cxCD+dDg4LH9Q;zlGAbuCfegr>Ens z^SC~K>q{BYKv*EQgifS4dKPeCtW6gcg}XQ%p9MJ&fs{DQX2rfx<8=I%4f_@vM-=7% zXmh|TcRbi4R6f3jElDjwP=T(V{&TJhkwBWv7D@kEP%X$oe>PAu-I1O5j13sDe4oII zu`)R`gBXh%OUN_t)cqo0&w9yXd0_Du3uHWCaUub;dtEqBFzbmH-iuZZt5Xfw{<5lP zWMMDEpp3t{)ho(=QDLh#p%ttTvdo0d-w#2~F3oskT2NTn9-KR&4#&a4(L#K}=q@I` zgIh-t|Dmnm;P1fm9K*M8^8VU)pA6Lk*Obl*5`SwD)3UTsby02p@=AgtK7`=qLHi~g z|7h#zgzJ*rH6x2=4^n4H-yl_b0{@=GIN~H0QiNMTz8>TRmh2~IGG{NvDF1<1Z^?LQ zb!II%l)w#eBYTEp1s-GzxB3azC*QKrZ1SG_s?>?9^c-#q0m)wSCN^}t%uN*WtS?Cf z4xhh_`sf&KDa>I;b3^n-b=_C#Uk3aLg3lO_KK<(>1ra0aKB##v=43mGBBnHTs%Sdoz43VTN_ks9DBe@C70|hy&@$R<~hOw_m zGpJPVb{!=d-X`Ps?_2KHT<(VvsjEPL}{g@L_k2gI|XU! z5|HjjI^-bI-5?DD(%mf$(%oH$?ykF0zwh^-xpQYOGdhBtbN2hbd$0AZXT^gCeJkBX z7eHIX%FV5Qv!0G&MvUV&`FhI}el@C-VKGR1gM<6fH4xowvg`);^x-%Ras{W3BrikW z?NF=INNW*bqI^y7Qb!{XE(?S3wUFn`9psLTl08L36WtaMer4ECH{~wyIN#CU9?R%F zKh^Z%0X)PG?^IH!Q2!h~kdcIs|7~oHA0iDHsXx1v-0KF%KQz>6hyDSkQw~0aAiuZo z4}sq~OmxH(t#?}YjvkOkQJsH(a$hVkk#}AvaGX>2`}Z-yTf)bO-5Zpam2HpZWgRQV z#(IEhew)PJ^cG})Y&CelBYxk0+j^~+5Btt2p{YFjwHNxs3&C2PP3{^BWj!8N_3&oI ztCTjjw!i>@L@Agno*51DBnRyPV>ts#pvqft`WL>X&fxc30bZe!De z_w9SvQ(?f7TTGQ^hH021A|vOk6eY{&w7D?KtG`KjZM4+lJ^4C%worq+du!4CgD0|X zBrw+fi*(2{Jw16}k*%z(a;yo&+DIf>J6j%j1flfY?5uM7T!gGBuE%_Qd`Aj^plw@{ zs6>|jsQKuIlFI+a!NFnJMNzYnTl%eLby=BhjtzZulkpGw zv0al2u#LK+{azjxhW^P8%wiy3b`r|Gne?ivJ8|#b=zaUR`{I*`1nq%M4*OSRrL+BEmTFWN>(y%}>IaL9S9X)tfi{J!2Pb zJqSEio*Uoz!<6U&wVv5$J;l6?d;vGI^1vAqC@Ny@h1`5!e*;I>O4=^|_Cv{2>5rwK zl38JB)sTCPS!fnz65EfP#@2@v@zRMo#zHxIuSDA9$ec?A8#6_K zw#lF8jy;L?SrS=E0uBK|$VXRCuRR5bs|W@@!am4a9lua`uKTDSvGGj@4Y9*RBvCN< zc85gdtG56!D3a=6lJE!?9#zqcD7EJtPgt0KzRD~RTxi#>v36usrkYAiN+LuJ23x#b zQ`1IU`_&OYbxgWGa`{KUPo=V&;89dKnB$KZjwBbqcXo}zH0}<~jPLRtPP;2M&9P2; zEQ%yHPAwrsEw27)Fyh&aw6wI-h$JCxhx$73q%jmy@m|=ib^cWTtQ_<^dE&DIN>D!u+U+AXPL{gwEV041SIU^$?LZf>PzdfMf zK+(Co<*e;ZDM!HUr!^Sb3=I3QeY#b7x9Q~tC3`tko=o!svqflD?k(BNmm4LWsjnr^zLFn5AcrR&C|LOUN9sA!ZLfypJX?A&gLnH+SsGJbd&Ica zp$pzIg$*GNq-IdVURr$BT>~3%6&_I)6iQ9_zob(wopqE%EI;Uyf7VY+Q@olc>@mof zRKPVQv8HNkcC$o75Fv2CqfYl3Y<_lH5yu`D26yHQ##Kyp3Rze3f$3+}a9@ovBEbxo}Pv9VKW8ueQs_$j(`2Y zYP4{?f?y*PCFN5*irY4N-P971*=BNHucA>mAUi;;$sp&4iM`rVFfJVkltD1FP?`aX z17=C`moAtR^igXz;zOkX5=yivrJu3Yw-g4!B!MUSZFB=fu(u$S^a=H0m7r14v>Un$ zbhap|eq;y)-UVS+(gFTdu$3>bYH@9i>?Hvy347|OF}oi}n_6zx=+p3hzbfQ?>6}}* zzdp@5^GnLxo(%QbSMN#gh{5r_)yGCo{LBx{3j`rp1 zrlK<^`!^t{eFCYY0T)H=!;GBQ;JNb^((mZ-=5%-1+Iau5PdQyKZnVMdWqrf>g>EE zknNADt6nLPmonS$H}Y0`h%D@}&nK?$EH5hG)C6%q@yO=PC|mvLN(Qf1o@FuY>oR&z!NJwn#`!?8%*%cTZUwwS4J^ z?wvpWn|u`up&#z4t)ruFo-;60>rp^=HD#oR7J1z(+FCX(Vvxg_?9AIe78x1+m_0Be zEm!xS52YWTQPUJX9`Bla*7)S~U3Zw=x2l^Q$alOWy=WQ+&_UAKiQwz=b=!+^b$z`* zi5mwm0LYUzW}>1=rV@rB7~$dLtCvOyj;~DvZ?9$Q8Z+%WM2XVFW#kb-CX6jbg%zSE z?uMVka*3C72ljZsTCr?LBn~`OGL^uDhLfASZq?vb02s7`x!-?`Dft&$+;5A)^!<2{ zq4IzL$-&kYN00UQ;sE`C3w?kIh63aHJ=LeV#%B*6`a7X<(~MW`{dmEN6ZC=+MwDL3 zeJOrY(MLe2Vy$)T;d%kJoey(+kOpx5A->lQGk9)bAeWD~cQmqGS5Hr%zrRNqu_sS| zT5&Nt8!}ltOa=<>LBJY6rtue8FlQ(_w=Dag%HF`K^k{y^P6b%gw6q1r% z^1Wbxr!0ephW5$s6C$wYAtaBpK)H;h$frg0$@Y$p9~yNI9|R0H^A7`HL6{^FS3*!I z+$hhIYA0(RJwZTm?YryKVEu9DtJ_*kDC+~Y$h)^$;u!%G+#-|0N0B{;OAaR zNs0VpC;bMO(~JUO1r8*0lAn{<2!Y%f>By0kP1|BQ98=)1H8wER-%*VPSYpxbp59Pe z2}Kb+e@>FbvE^g=B{nuTiYSYmGY@qVhjXZyB#UDW=x8hs4(~nSIt&XtIJ`bxkjO5= zpQk520kwr~DbV09G+(`?QCZyjP$(NT5rX?2bPNKjK`0di1GnjISK#9aME0Y@!)L8| z=(@yylbE=;{stU**2`cjIdL^82a5P6h`6LQ>BVDhmVbDBOf8g3Y$O;D@OYYAu|8wD zzfkM55>_4_f}S@hN`ervobli?tzw$xkT2IwZ zaB-yi^{;G@J_I=sJdek_(~J<$FdPJPydS|S7AN?j?yU4F*VDG$V^jo6|LB^EI`vJRJ5 zFCERzt?+E?3VOb3M1{Jsw3G%plkzIoHy4b4FC~>Z5}r_%{f#A?J~!B>9mWL)dHxl+ z%lEu6Nhw8atOgIO^D8wn|HAC;BFPT&qo_gIv@)17v#P_UNX0q)A*bw4spk zCE+LK^*wUKq4uTGiICL+#PWJ^d%@Z@KXWp@RE>`x-?g!QA?krwi=w|`_^wa6N3hR# z^%NT8M_97BvXVY>53DKTi6rIVR#wVlA2_|guqKtde?EPB5$RWQz9$!N-1( z`Q1j=CvgW95?M32>RuWTKjKRv4CY$e=v<11ognFGbcJR_I5%AW`k>BB7a(lterCdbfpiv_b*kxl<%Fhzgm7|dQ#BIE0WT?6Mk;+#)cjA6{ z*6?{$#)ZoA=-<&piolBNSKv45UwB~)X@ZgZJiNS1?{#BzyKi1Sq~k$4Z1Od^Cq~ua zEvpBJ0Dbdx=$}1D$HaVX@FfhGQ=*M#6F!KC2jvhWe0he$y6=oC_8P%S$qQLrL2)7S%3|g+1k9@8A zpqUCa_uEX#jD90p56?kL06+G#j#LUtynh2+Is6r1t1PbOggp<7#s z`(8u8e6iA$fsPtF2MEV?B;`NCoqfgILY@U>P5j$2?{-3NCXsvvJO-JPzMv3)F1A%{ zZEqLOB7dVy@m`QhR?QPeP6jiC%h$`R%O3qSO5Lg$dvlukVb}ciww-G((Et;AX(r7Xe%f@v88v{Vfb3Mk_cz zPbjsXKYtE1XaPmj_VJ;P-vd$sS6eKb-V?O&$}8+hXcjA1k?PX#?Zd56!Zhv+UuS@L zq6_{CpPZZowlpd0=kL3Q1&Y_-gKhXH`wKADV;r3S^X-6?6UW0Uzz00A-y7>oLKT^0 z|Mw>y6R}{QJiH$8K_|A6-?|=__i)@<;I9T2mzw|0euFH4rH!rgBjCmVFN5_P&4HKy z;lUo>2>y!RM$rv(p5}SXz?{C3cet!#Y6o7)iU;Kyh`v3lqzuEmi zblSs*{K0>Jfg|{g2S)4nr~mzrzghnO*GGcu`v19>e?PKb7iR9es;v+#X=Zqhpow8N zixOV^vJ!<(rnLME zM_m@a7Kl;|W<=|SqKFPy@g$Y)^%mIk&m;5NuH>Ao1fP;5)s*bL4{<`_wIwvU-89pE z8!1h?=5^;}I~SK=HZUuwrd68l&QQP^&f+AfZEu!9A4{|JzqKJF2dO*Q%-C&BcSL=+ z&&jpVX-^{?_Q4Df7}ug|+pd*_PwV!^k3bTNL}Gi5V?O#rD)yxh8UO4zd32W?YYm&j zX-p+!6X9Du6Ai(=u$&Y%<)Q{V#=j2;Mg#H&IcOfbitWN>#P?0 z!``?cx=@A=QHpLlN{t}=%Gl^?WiA#eCF83`Tqp_iODieYdddoGH`Af%D3Td6a?HB3u*3VgZDL{r(xaV#ZVFq4noTuBTyug-Q| zWCSlHYF3=L{hI4k-s5asKiDj45`PjbGv`3;sIuO=i;GsJk7@qil_37g$<1_$>rKUv zauO+tk&KGz^1`;IU(|0?5v0@w{_Ki0fmr6pY98b77_u;n#1)#2g%lL=lO?t)OsI@c z)}y}8;f9`N&T6zn~(){N#rCS%2Je48?)$|adEK5F*6bRNQXdjt$& z@(~C5O024+3bj;UL7s}^-fX65)n0#6QUbe`juMbN%vGXRDm1s$%(OAc+hR3kH6E<4 zXjSKRJv$><<@~7!>WxF}x2BX!v&RokV}#tY=oWCxC=Mm;xL9f#kgpQn|204NbRNnt zDt1O)S2nlfuWwjv$8PBcmtQtYQMPk4za*6I-ko;OmN%I_3XY+hbG3&|)V%c+LG%t! zZqyNmg^!Te(#d6DVP#@sW@D1WQ?6vN8mjkB$eUp(S_1Q9b{8kpAPtYBsnjRgtQeQl zYqn7#P4t&{$>m=UqFRchmV=uX=s!qAz(;1Yy*49CgXV`MTaUieo;=& z+kgW%9r@S#dO)7R-2RB%UT2=DdX3X;z@CX|@m|Sl@Q18L5EGn>Oo#i~eWGeQM2}e^ zvOkH-etSAy9D^J1_5oPb%St-N9}3he9-nTrn@yKnB(UwyRJfKINCI}DR&Cz=(hzj^ zf^G*NWZY%wWTQjUbTm!D{MPJoq``LjKt@}}+(P&n15KuOgW(?M>6KzMd1iJ-oItt# zAe~S+JyxO2XY|i3&PNlj-NI&cIl#mrHe|%{=r{cES{R=8s`Je1uPFbU zlK~Npm%zOfFHfeEZLX=U>ERES3NZ$g*ZEV9mrHxh-B;x6(S6jX(5;=}0^c}QGG5+> z2~Ah297RxL1tc39?(eQK$lo6vA0s_^a&Ug0!e$X48anXP1D4wkI#_NpGG3rAlrGx9 z-(p*w)v9hamaotxGUt;{aaFM3ek1T}mvc9BKEiOpp3?-_ZuUqNtr4$a=$t3Oo3c&f+74cDKA-!2i2__#!3`K zLm$0F-zFA%TxB|!t9EL-Z?{`vd|L^%RYhQ7$KjjLKV1J>T>e#R(;I&zkS!C-JM--i zca7VTu}kg{SLv&2>5(%fvniB>N^OgqXj)46gz_b#1Qythc6@oIqw+l(IG30IxtRVp z$kA2~HgiXM{go_Z<97B=wd+dBm6>^GM!bAs-^Mb8sRJbp8$g)jT7!#=+jKT<24W>Z z91uY+hQxYo zYj%qM#HzKfI9SSahfLn-2w<$$s#0}mCyXqQt#3U z*{7YtZ=zjWiUEgebeW+KLo{*#ISh40-9dVmlyyWIa$P>hF?C zm;&?)G21k2=L_|46i5wXr3tUAPnD>Gfe`ZJ$Dma-iR07vrlxyPjsT+b*Y-Y)^qTcf zo5Pt}zb>|V3?#8>U$T#9$yim%k%~wsaE+OD4gM&aQK>B7n>HH!mE@~OH#e7{`i0a| zoPOT=FxEhnPFk(D(BixiTbV6JDK}321DoXtrM8CRha-CR;Q;n5Y%6ivVR9PdyQnM_ zqkZJl1S{2aw*Q_&BTT{5rOB(2Q$LpMGE;SzlJPWmnP;2Au1rKP#Tzy!YwE%UhjMFf z{|WVo?(G9Qu6@0|AZ#R;NhUx?XD}P5nLNI^Jm$aNVa~R-wmv8Y1$y*ajk@gtpkuOd zxODkmIbXBJbS(huVC&P$=Z1P8nRpK8{BtN9ss)uw!QDEy#(KeQJ^$fV^NH4kdjgx; zZZci+ypqKhWl)fX>4fFEa@~YFM?L>aU`1A;Z*%g z0wj+@`OE+?$p<` zZ5OE&TwO)VtfLaK%{tZ>?Oz;9?>DM9h!k{4CCH@IIbE)26R+Hu<29wR6qsi#j^`+p zrHE>E($O{e${pJ8dm&NXYoA;`JrkJ1Va)NNv`x&nAGu&K1{bg$4!9rokg!U~HFQkvCY* zalN@ned{?pJG(WSlP-(5jgLo(9DQ~57-ee==^LBDMXLdHaWb&4n=%XdH&9Y4zx?a_=&U@H_iSmzZDse!kmb*Q zs(E#^!@2?4-`vKhLP5qGw_?!m3aho>7JT4dQk!%;xSpJ-Xt|Mf096e2O7p2o3w%3g zP=yMrW`XjQKcofp@|HYKNF74Ae{r#Cfws*^*tXx)QUw#}jo390QJY6M4 zM{k1g?vqtVYf@Z0_i&)2A?ALUVst!9`Z{jA*pk09>EGZB6N*DTSWs8JD^~x^zQ$?7 z;B@c(X>yND=3Mbsk8oZ80^TNj-S-x;CS73#(iMQ+9CoL%VCIT-TKzF7TD}7@iWWaq-~87a5j=HXZj^fu?*(Ga^O)X^Y2ok_8dNr^ip+(Dp-Ie@f(Blti|?7t&f zCx9=M>PS96nWTgnoyoY~pjvC95>70^3n{V_{yy$x)06Y_ImXpOg;4^a-bA}I= zT8RgNsOO_ckHA9iq3NN3WqQNn0=6#@hYSHVAi=?)3;_yu?@Ia4tdi5)^98HX>}PhW z`%iV@Y9Y5*Dg8-~dmG2Le0Sv~8Y3oU8*a9D66R;E8mhwKu}X4rxpQ&3**&=$ndHGj zIHVT*DeS{3q<;cjOeko25YqGQFRUBbcxQwqY?O1Rp$z`Ef8NH$b$sZfw?Q>wnPH@@ zpPgl8sym#gLXU%kgMkq#ox~*t@X>U+NlRM0nYOmJtn480Ps;fpN`P4e#TWp*C3Ad& zK_vuSvJ^l~OiaV?$u-gh;pJNRYRSzn%JU}syidFMh_~H$-i9)Gl z9$fdc{e^{rfg&(gcjPH*1ApCx_IUc5Txaw;E0&9oOMKleGT6qfKt;oG z-nnyp92*Hhmb5`*ep-ccZL*yyFm$`K(+G^bDp0S&4#$UiR`Up$vohCaNhRq&7=s2a~-h9hH(bu;Si=c~c-d*_hSY$>_)|~ix z11!#e;Whoc)O7m!pqku(np{3RVYfHxN=!Nm?;VB;Qwmv}%hDmj2Eql`RG5eq6j{J7 z07Q#}B&$y&lgy)<&5TVh6%Xg(!|Q&~jKE+H*t^L}e}8driYFe0Dn&1MF1N<=0H)`H z+&FcH5YALua9hpSfBEu-SjY$N{poQEOHN-xf$4-9gGqmVt9Wcv!{No?7|DyKAN^AY zu9UZYrj6&rw?k?ksQXz45RI%ukc+54>qVj?)`CjPe4 z=*Yyx2>T#U5PHZqtDP}8J69m$&}o5tQFdVX>MMH(n5AI}T%2AfZK#x#lmLJMDBcZlJex^#qtIiNWKLS^UcYcDJod^8tGh#$o=~G% zzaC1SL=7i&tU9%P=RP`Yy$$(*@h2xRASC=-0|smama(^-dX}ay-8_#?!JD)Atpu~& zR++5Hymrw-KEBTd9P9C0gKJtU`@DvRs*>Dmvt~s~pQW@GQl)pNiKM>`7O1oP?Sr;= zP-W`PqW7qX7Xh;ue891X`aDyj@uA(w=sMcZP!46ad96*o(8n@Dc z4dMG-osggos(Z13v}#Videt6)=`qR4$DGbO3}5R$ zG(@Y5%l^3Jhb7+WgvV=Pu%8!#Iil<7ISx}v>cc*Vit1lBAW zL-Q07F`hvOh6V482LPD2o{!(A0tTm0_KjMV_1Ku1^W-xncBd;q(=Z4UKdp9! zD`ZI%@|51Avlq?adbH z?m8{2YSx3Mi%gL4 z2Jixw=dnPwdZkGn)o0h1V1xw?ce@j{rJ?QiBh1KncEiVdf0%Ai*d>x0O1{xCCrj9r z!}m$ybT?Qx3DZ&N)*|FeKjezrf-5flig-IYbb-cucyh5~f+d__S{4KaVW zX%7T|?*X=*%~*vJaM~>X^Z-BtXdPGpCkH|k;8}FQYY>oMFxdafpxbvSFV8)i|5j3B z6bY$6<=As+KHP5aYa@GJE$*#ot}jS^Qz8lg3iyz+SktYIrXsfw3um{Vi3X zGwtsT#cyIHn0T;L-ZI6DY=PUnE#HKHTA@PEb}3&?P9m2wPXA?e6ZDHO;@- z%t}d}0L_KYDQKTv>dx|2(|_dEbtbPI`d1O%TIWGmrR--> zq^{_)ECY`S zwi}R}L(%+uFqREG2s*>kNTidawVsE_90w=1LkjPlXwV(3+G2*|!$dB#{aL+2Tvh+P zvKv~>fLzija#&tS*24c7Cn6!(m9r$*&dmASyBID$9P!iJNKE&<3taKjU5h7nL!sbU^9-hHrz zpbS~;SVql@x3xfLQWvid3N=3Dz#<;JKX<>c((jG{Y!z#n)p(^v0;66%0y0!93v%mN zYqwB)FE*U?m6;uJ#Wp~DU|~TvNo?RasU%gcLhZl1dx=;+G?Szu^J62aHuH{8R@|%sr}xyvnp?_JdWvj#jB^Pe}RrCN#VpTWNQ@V)c?d) zFclZ}Pa@2NPA2NH$bS9ymB#ekNR{@0X#p3GzulF?A+!8YXicaLc%{9%{kp@F3_IlM z{0q6Pw;;b2j&5A=*39ya;u}oBR40Nzv09KC!#+Hx0|4znow!a1FcF?2Kw(5M7GO8T zxQF4ZF~s8^nt){l`o0e}Il!VY?4JUo`myFYNu$%@GCUGCGCo_qW`hgu!e_n7?DH#B zDB#jO*{mGZh-&tA_tML%0{UkalNxhEda5_LZ9TC5$11&`iUNW7sawY`krmdxlVq?R zc~$j0`Rn%oqdz~Z|Ti_^H7+!RZkTf5_>tRCet(?KyA9odp)GZ!psQ=+5b3nhy%tuT3E5p z6YR!?N~iJvZ6;@=a@$aFN}k&UKDSXavdY1*33PX%%7N5oj*IiJx0Jcd$ZnAkAPI2xfy;yJH=Mhi?U(>ycRufS_VRvjxZx|2 zEt2#cT|nJuSHVGwm~qw^8qF57@P|~b7mUU{jN9e-6nDFkRo=i_?!ergrJClw#w({$S59#A4+sV;0h2MD4WVBlZ?q%t1tzYXAlbP zd}~CN#SAtvtUCaldKgTv5~|$}dgz-zK0r5bB>vlz5iq6u$?(Ta39P7109@DB3>NC0 zJv$sEn>15g_74Xf10nSqPDe+({$>Ax930ZYtTIcX)PXs<`;YMg_cWQ@O$ZDjFgp^6EJB1Z1cw;Zbn}o11CuaLEvJO-XNbuPv2Yzl%DOpn3$`3dzt_&NJLYC9^$vD3ohFQ zrsJ%92S_)EM}2|L!bVm&ZCd@eVgEWw$RijF=w!u49JOQroSX^VRb@xo8s)Ri5X4QM zVT}qgf3k=V&P&pth70a#Ze0`_I*RbASkE!PBFcObN%;1SgPS`PkJa>OwHtkTttVC} zz3J|1yFzW;q#33SZ(Ak*!?WklVa9xT1ECv04Acn#1i*DT0%1fjt(bwqc;rVPK$1yy zb~y%mBV%K3=Osk)`#2QybR71aj>DoUYHAZ1|H9rL3~xb7xT_7G=nl{QZ2H-8DV+UW zh@@kHFqgXuJJ}p%<16HAX`Nq5qCJAG_)YV@px2$RBo)HWyh^cBM z9goET&K|Z#twNYx)f+|`H$F7-TaI1L<{f9GT;&Qys_4Owlwm?&Sb+)*2nMzmnwo$f zt=9_(vK(p*@#y7)uPN4U1}2RE?qUVxHU<(oM-~>`!F|`LwafWf!?Z&{7a}-&T|LEW z^07!~g^YT_fcMS&8uc&C@l4waAQqBCEfW4y@?ck!R>ZKiIJ-R?%}wdt9$UV-+^{h0 zT~A`s^0oF|M5XC)d;Ry-x={Kxti-0QE7iL7;W^R$(Bq0Kt9d|7f~_UqJgECdjpqd4 zat;)dL#-wXHLg#$&zF3O`a$w`zTTN(-CIq2?BY05hR=g5uq*h>mwy1J0<^_H+yP6# zwQ8a4^~E<>YLu;iCDYRAp?_beZq2scKbk62kUN(8?-K_~HAV|k4OtR3MIsWA2)a21 zUh%Ex;-_|0(lsj9o0>!I*SSdN0TKH+_n&X~609or#~ZEzdl%1c1%Q7WueXf{w%)M) z*63zICa^XjVixj2_7Desd@bLW`iR_4Q^uM!14CdaRZsa+Rl%L%wewDwE86_dRPgdlj zT+>|2ylxjiSL(hL?sg7!NV!N$wnzuU3fC7Gc3Y#}ZEbD8e&vEYDXZB)A@+vdCp)q0r76Kw0v|@dHO_q_qh@}H0owK=sI+r2GMf3e6uT@6a;+N0kGzd6)3*588B)MoML5lR{qs3&5euki>_HRjEZj~c=Z#p;C zo*Y95b4I=~>b)AY*0Qxd1}U1CJWketa0D@}*BhX0)bfS(Euoq(wj(wSAo*7JXR7u= z1m+5;s(N9hZ9G;grChJxUlalrI>S;sJGH>iX33<0E9WY=RH`tIcI2}23ks>ZlN<^} zHk&=3FNs%z0k%_hMvpw71Y?WZu$J6G$8ALk9s3&kc6^UV(!J!88X4M>)U>Aexlj zn73@GtFv>jI<7m#XUYDUx#g>nMP{H0Erd$7k#gbtk+sT z0+ogQ3hT;S4>l}Ao;TPqNoT1Xv`u0Xo0r0I=iw|a!E-{S=c5+-8>jQdC477<9l>Q~ zWqC?@<6zJ0rdW$T1dfSy4i(w*Q?))72CUSi7#OfXmPp9E5h!r5)>B3MfUESO186AS zy$J#fVnPn>R8jX(KN?umsW~}0CyRhp0Jr!>36@|GE6B`{z)I(S4FVB~UpfaD7s$y< z$fUfrBBr45O(A=*q96fJ4$2?wx2BmdujZ&P+f^WMsebjVX!NNV@ynWN9xI8(E_KE$ zCdL(wXCQ0^eYSULl#sx^%+0?cDfpUKy2pQ~ZMuk$YOw$`A%+m`05aK{C?dkfcDOju zAs+m20i-R887$(p3Z~hZzkXe(SDT$Hu=1Qx|1goSQDJIuEJ5BO;)4k51{?fdMG+5I z2^_jlk>miy9`8ENZ?3MMNF#KPTM)#vnW>HZP*$Rr%qpC#+?#Uby&pQ&Li$9KEh69V z`DN<(Ufd&@+mS8`=L%f@x41Z5JUr7hVPrNWkIM4$lcOUp7JdbjyA4aqcnq#7bqE*B5i5WH0{bE%uM%OFa`nfz~B%+@`Z^R*PG&WVf`=&P?J zb=G&UEeN^o_lNYr=>!(sTVSF<9f&z%!?-~QiN%;lFM)m1C2$$}5nROX=GNufDt-T% z__kwiH)98kd?877<7Vb6b3ddj;w$n^N6SkK<=S)AGJh%c_R{wD_ED=E z%Y&jAuw(Fe9p3L$Q54-D9Zb8wI`oc}OZjYX)9)$p#IC{y1By8C&lUC2PdgyhyXJa% zc}eUUrbj#o3P6vL$%HtfBn&{qSGfpW;BgrkZ27w^*{en1&{8F~Jdu0i2&wR1&6@XK z?kwqMbtf^MKQXz?T4zR@5RawIb--vAOvVpMf-{NB#C<329b;a!u5uPfcObwrsrDZ8H8P6z&{H8aK^)or3IEs?{tP z={3iOpHJi#gEmKCZusMwU0Z(yQ#1y1$J$Y{Zj7(hYk`g1dj}t*^_g-*b20H!dCZK4 zj>4m|xcHj_UQ4Kb*T6t%Xeel38G8l|3kxfSp9Tt0$vSO*&n5%^J2+e({ne0->043U zn)7}mP5%H+7SlwTBoP$kzG!mgjvr(1QK%_V`hxN%3db51vKSjNjCwEi508}89rrlx zmg^$#Mth(VrwK zF4f%_522-Cq~+baCaM&9M{{#i_GzWletW1u73o^pVkYF;`Y6N=VIb2Wb8UX$7rj{H zQ;%eo5SUvY#=++1W&k)qvxly=niqEuJQoW~xw*%9oVVv6_yCI5ebdsG>NIM##QOQ% z=nRHRl?dw`*vlChi)Fu!F`12*4E^-CoG*LqNI2d2sg5h!EFoS|j;a?K>xT~_MrLwL z>UWP80TcNGpJ1s55kw3O?>PUooH&o+Y`1HNbWzmvm#n6Psc%6bsg$c&Qe132QJ54P zs{&GXVq#q}wCZ52#M#~yhV3gu5Cxsl#^bAhn`9{|ymT3(vVY%~ho7LNgcpa87e^WN z9vLMl>X$_H*5q{M_JO6ZqsA6HM8m{TSNnSri^{hTRC(;#@?|B_H5GAb{%Ou*xrDVG z?zL|&plJL_lHCU>oa)TMbNpn3fD{kYcyaB83gXRT~-bgj>j0nOzWVFdWtQTzN5?zBj9&WX0j;0G$eF<|r z_)SVxA#TBV!TGtY#pT%shI4JDQ!~Nb)#dC}EZeK2C3?P&_-w|;pbH#Kt@+J|07g4? z2qaJdJ^=lugea6?=EJ+feC!_hI+xU*UIVqNph&b#D9Xth>4K zO3X}b?70i6OF!Qx&uM(jr^!R0zdRyBhl0NK2=<%Hi;KSn$C|7jXpv^NBr2t98}eWe%9=7S1I4ShnBODuvG#=|{k z>W#cyWz_HIqoR|EXlxR&d0O_7_UT^kzfgMTB+W{M^w-20x9YyhP_omiEFf+>>Yf@ zEF>zU!TY&40!$NhAmr$=IQjneZrc~ZJ2debBaij9>!Wa?EMZjC**&asgSLz?;#&$1 zcGoPOOuQcwwwW!HKik?)0tc{fVPV_=WA=^ivr6G8ltG(}Et+`HnBY&1NLLf^E6Bb1 zQqw08y|(&B=E|TrTt+JGjYX62myl<-Sr+?5)#>g(&+Zf)oggoU+<%2Y?&?Zr9o3>b zM>Sq5kRnJwJx;9MYbZ%M-{)Mnm{G2XRzi+i_lc&V9y61@m-1z!qvHjb`s!>KjJ`87 zHm(NLGeGDd?Mp#HAw(yW$Wh{QYU+M(vbX03NCS;@!-8Ki*wMM)UZ^lK6*J^3&g3tt z+s~X^%o!#2_=WP47vKS*b>pA?IwKB22QzzE#d=})XAm(DZiI_{0uKAmf0~j!ZycPi ztj^<~@!7aQvrCY!8n&luMMx!u^w#Q~k$wrMrkuX93QI}?qmn_hStt+4HWllGc9O|5 zPfyqrc7RD#VRqNnyrTj9Mn?TN(RiZ{H(h*}P;sm5BIC;?ii$GHIBAu&QJ$217caNb zd^dxDU{1tDJ3N9GQJYtEUw8+8B0aOiX|X$qhK&YgtxUJ5tNo#DD6)>NL}SWoa^a)L zos~T2db+(bUL`~C=*aF!i*D>K_zWBSv1?-n+2+&O#o<`GMBW5zuE2b=fBwOM7k~Fw zaR+)xn^4u8!0mW)%|}R3H#t46s#K($6A)M8JzO2XG;^D9O}EX?+d}DKXGPebkP>E?deXl^;|@R~fkO+l4ZdJ*!+T%@$EF{d&~&!9cL%o9SsRNTgUGpE4x8?CZY3ap z!b44eSM>uB2LnLdgp~#J+V(Rw*OxC|Z04vAlHcz(Wo|x89;rh6*66kvM5`IuNU+1U zJ||MJ9j}@IEHEui9t)(QCS4DQed5ucrRUWd?%>Q=flSK0+pNai-1QTWhdeEu3t(vk zQzP|_;jfn412-Zg=rl)f95;2J-?`t7=IlGXv%I$1Tt4K}GsmA9x6m|eBd7vq?&tba zr`X+$Z>sL2c$U`!Wjt;CHhvu!q`bGJ2v?%02MY{s&SKo@ROFy2aPfat5GN?CFubSR zOCI4uFr)~5lY6+BjQWOcVVi39sI!~!k;yfE%*HdRsRwDy6ZQ8#3M&#yeP&~pll9)7 zwpA}J_blD6&TQA43gjJ23@w{b!LSh-Md{;VLx($bB% z3z(G685|@_aB62~T}X9;)rr`_a0Ex(qNclApalZBq!f2P=OcXp4T=o`hY(X?qzt%S9$J{| z{e0>XA@GWr;PLY(jeSesxZ%WxccnuKUYpdCiF5P*$jgltsT+yT?XzQ&8gZzdwsSS9 zyVaQ~mrBSL4>HM=xXromfLOpjqDY#`xmnrBbbQIn_oV5d6$nE0V!Rmq2YkI4%v8u> zRkCp8J1X*(Zs2q~DkzDx$_#CY?Nl-d8GdP$Qm9NmUk~BPzcrQ9&2c66^(3aLN3?v*)7A;02$#B|3k}p z4a-LQhb@qCp^Cn`SP4aPdm)EU-PBwj?GpIU1)OO+=N`U9(RM2L6F_evXeCvdumF{m&f3eetw}_ z`!c@C!@bja7k1B6ebYHcs~M+O&tkt^kwZFwa!xco#X8P#>U3WcJ8b0c{<^rQ%Aj++ z`2$mY)6M&iLn!pk)UV^?WBP`Z=W+dDO6q>oJs&6by1kA7I|~c+^kG-r)$KQu_Ea}C zBpFPB^5LV0)EV%PfE=0zX-?oJ-;>)Ot&01$9=2h~d~AXw)pLQEo1yqVscM0jgPXo? z^}>@ki#|B~k=t_8lIXlR-_hA%33V%)7M=@qdGK&TA?uC@vL1XmTX9Uish}bfs>Oqz zXx{wq1u_<-wal3F9{R#&EpS+`2X`~O^Vl7omqli!pEjFL>x?qs(PoWxtF=?Jm5&~h zVC|R_g$TE#$+F-j0Vz;WN@i$el;XNqL*#xFPP2{!3M{}yCCA12Tgbi`9N;jj&C z%lKg{B10oapi~V~XYDFKh+Hl9*zb9297|hkg~z+F)bd1fHcYQ)Pj#B|=E$#{VY8}K zY5cA2UgJrwTe<;Gz+opV1tO6(vg$>%XwC5;rT35;2g8q!#}Ued5ZT*Sl4KZ(IcQITDeTBfvP|3;f_qkjats|I^qvfJeS8eaFtm_Qtk08{4*R zn;T=3jh&4)wv!Dvwr$%szRAVGz2~0y>*wib`ad&OU0vPNT~qz*u1iwDA-?-e*|(>| zFE6I9x=}Twi|mW&Qmk|JO~TYUIV=fILGrT`Y&rZB7HHqB)8^AxeeR1kYAQz3UmFCy zQJNXDfB`LH$dW9rp4={Wj(8!fYUOSJbRZ#bd5t-v;x1WTY`>_(OKz>bj{Si%P2>=a zU2|>k5>5zb>svfYazAF$`V!*ao@?gZ?1)^tKTA-+S~0e^4$r`s-0Mv4yHRS>C*B+9gk zTo3Q9YwHv*`>dA8j&GQEn{sCs42-p$^3(-6;pMN-xg(BNnF$!y+AkGl9-YX^4Up)i&ae_E`bD>ua_r=`c-NI60EAMe)CY2du8U{x z@ovB=aSmLvaL(Hyz=f@F5M6=@+}Arvx^!a>z;U+rA zXSQw!abaXOm2-x-V0ss#R;!tCMuuwCr02A$>F&SQsQO)37j($~!R3BqG%Txl{V*Ao* zaD=KBC2l*(ZT|}5gZ{4`78$Y_`DW0S`^!Y9tWEb45A7&&d)9HqKhK4q6z3B|#cWg) z2YVgBIU&S^6)B2bC1iC10ne1hzIy5<3%H_BBFmuJ)PpomTYbRC@ha^=kU3V` z=~TsH5`8UxGp#MoRpWe=VHInUOZb5-<&ct&q5RRqsx*kl^%eJbF>IMMuygZM4i~{| z-a_|zX?Ey7?=kH`)?z2u&D=C&rL4{^5rhd7hsk}!4u7lb&?+q}`v$iU@KOLAfiK0H z91dSzo^B;}Q`TNa2?}G5ICT}uGUU8aCOu}he(=)H=7N7oy^D(ZnF?B6BbpC5qv0rd zuMP(23cz%Wm1;WtO{*)S#6;(sUaZbhV#Gh$Ql~hDeQvmj6-C7|=h%r8CEJJuADSEj zrONL4Y<{c?5R!u_%hbfg=f-!G#?;od=I!EiCZkPfweKeciLJ(Mg!qyBR4hHIa)E=W zuEaGSq8H@?emq6^#WJUs-@m4LJQ3qSyxu1DnmdNAw7r)QlDC%iOq3VL*e^1-V;aSx z))5I7<`(!LqPh(xD6qyS-u8SWF%I|lSyBp%iViwMxNQ>`#vi+OtX#U>Php&HZyj!T zT~iKHuzF?Gx!leQ6%t}$+!bQENI4MBM?tktlQ*>~+bopoT_tNRK7Bd;{G0NFS!*V} zmGnAKxe6aYP|YyMx~klcMZ2BRXmgogK;ZqL34ZJfvvZ*M6hE94O1}9pt9t42u#~;E zOQ&bd?soh-v?49W3Y5d^A=4knFTQ)o*wQG|2xhhs&U7f7Y>b2*r z2FpQS;30z{b64n zZW#12MlAk0Jg_SpkrEXfcbT`6mw*!hMX;5veTCb)eC1T*<)5T%pKGAiS83CfK4bsoY; z5z;k^J&ELPwy#A@7x=+K@<6pOgs6|Q5U zw-85g3A=A95FXzMm#rqJD5Y1bkkhpNJd`fZ2;7VuI!)dl+#40f9~=$ckN8?%xD9== ziYR&sSN*^tD|Q{&f2A<9Zc)y^%GtkTs7*AAwwq2g%F`cf^*}tp*dNRO(*Yx4fXPIB z6u3Hy^U3EDKNUCq#osYg?`+TNJN za6JNc6fBea4%Xe^Ri94uJN0$V<%RG$FAtyXFkAaP#Jtu^X^@dU||PH!8LD1qgfv9<8c`7T)`GW(8wsqmYCgWvfUkO zTTK|TR`xP{-@`GH3vC<45}|6mu`gvYLnymw#Yla{Gpw*7ZyONoekuf)t_J4gwenlpF7aGFp z;Qr9di&eQ!wmt+?Gr2AV?8xUdsT!^_Xx5f>RF}bImL6yAYVcwuDf(<$a1Bi{6mDm; z$viLZW07`zougvn2ZzC(8)VAgu zN~;sik;$Rb9&`=ec30OsGLs)v(=H33A8ZL>Zm7Xgbcsv; zHqb0~-J8p%F-l%1@6h(l3@2`p*P}v}DQ>}vj_itki4}w{VV3XE_Z&7aRa2KQAyeao zPhbcMXc)je8w5Vd)+RFzF*q_fNpIY?(SWg$I2c{|^1T_nF`P=`kfFRjgi6AS9gXyu z4ZY`#36-?|a0k7$nlfP0fMj5VM35(^C15eRHXyOSMgb*>YgcxgEaPe_fd+!*pFM02 z=~R|fH>GUtvPai5L&oJgV9~5M+Orqszc{Mt3j5$TR4%am7*-vp9{!XzKx-whz+6*= z7cnVRayOCK`vWs}QLF?$NX;3iz-DU(B37=yMViGnZnnlsQ3#>JnCc=4>R-mxz}D5i zI-X@7W^+tc8YY*pCR>k{l=e3j>5`PWoL3hZVaj~n&_QDz>nn_MA6N@T5s4K<_n!~& z+ny<4hI#w}|29}9lrxH9q=Q5XDCZIrjs^$ocF?vjg8Rc$FPlpUmA9iT$rEzFdL8Wv zlRwnnl^fK-e5=>Wp=}mTFito!AEX)@sx?k4URDw|4hr^axO4zqwe+rtfBvBUaS{ZbkcWn zcKmxf+`p*J&cW8y!PxQtpd|PUN^@&{Q)5SZ0dps7eLKg$5%;eeX<}uo?_~UUjr=RB zca{Eq6aPvzcD8oTcJEsK8yWvfHTs5z##Y9F{vZQx8zQ~X^L4dG4TL22^;E%JC_(rtw`8ePBMA3)% zR}#IrGOM`!54v1iadhVPegju$W#^R=%F8DL{G4%*^&(`Zw&VF${=UsBa&IJhI<8+U zYc8hg1m&*>o>*X=TNrKE)uDY&M+0hIy09vJhn>SZF4Zh;(NfUPNHw7)uqWF6fqgy2 z;Z)b)6HLSs6;eB%5y7XLk*f$E50Ju4=Q{Yrjx}94>nhsD)vxgsSge50iJM^Ok}Hv2U%4)8@DZA&DPb%VQl@J z6{r4&k(?W)%VT3j^euH#V4haqy+{n(c8X7RPLfhm#oo_e&R`A;PQ=?$+fN4%TsKeP zsutuF5ByGTKLI&uf+rjJ`wC<=_{k0woEDzE(0Zx=&-T($$m^}y%_ ze$5|MQhRU)ati|kxbW^2Gy0X1{Gn4JrN$E#FYBk}-R4*9>w&a$+kRo7&STwn+;m(t zA^2Cc9a#xqZb2}vF+#zF7bGIevD)Bk>mfWsDK;@C_mlM(gfk(4GllD;L^nGCU-ktS zfE1{S4bjyzD3$TV%krh{mBR#=`O>+m2}L+adQONfd_%=Vk)ktLlgu<)z3l}O2eIH_YOFPpuyXkSY z`_f^aX|Dgyc#oWp7#$Ye21vgd=&R7r^3j_p;s=T(0ZsO2zaFa&1^qMrTY8$9LtR&* zk$uYNuRX;jd~F^0-3bGVRxo1zMiR3tz($-&T)v!1v*-?5olUO|Um8x!%XA+; z!m4{j4++BRL@d1$i4OOv=XYq-o;L*+T+2N!FD{Wc=O)+^=~HUv(x{`OF!;g)X*-P+ zbM^c4NWRGUVRnhJ`*CzD(*CR-EOh_|1_#;JV@Q@+Av#hrkq}q`>D`FaGn#^+e#X~d zbw}F;H3ySKjw15vMO4PxR!b&SOZT^tenB5fo(d!vguXd*6?|;SYuCV~fugv8l$zgK zH3LiW;=vhCADEYc6Y6Ibx-FMT7A;c`g07jbm22*zrb8cs8S`Xegw2oZu$SIu7-406 z&JVjyt?YYsLdTsG`Y@%1l4F}{Rsr3YBHN0>6Vt^q*L|NxmXQ^fGGzT0NCqe6C@uB6 zX7MBMyRMSOR09<}HVKJm=dMlKq~5K_Fc+xJ*a}K4JHtpy=9{hoPqO=#J?!pDho(KR z(_YO2^eMa)?CDxDp-XSX#l%0KbPGPNcD0Uav3=QaSoKM#x-@q8N`JJ73Iw%f@;nG0 z@JUb29eo+cg8zrkJ6a=_`$O0ps0kJe7Sd->6oL8_g7)B7zN1YdPs1 zbne=j=dNfboVgpBt}~1CK=KVN#fpbe=dJlGnas`5r-Cm}HJC{({p7d=tQz zE!d)p_Ni_>gvI_M7sP9=j9c|bex9{n9!qi>diuL(sGq{8#p$eo&=K|4vP*JaHceKZ zsxNIm;W@NDiFf<}w;1VSk;l_rfOHrS?Jr#G;Kdbx+YZZSwbqc$?~MWIrBWsnvg4l; zN`wd9wHjTzN}GH-euVPF;3zQ!Go5_>>Gg?7FMIPLH+0_LmGt(LN2{qiiMLco50ZfN zN{?*O5pT*Uxz<6&5G)III6mbt>KPT5Zw!$)`_3^nluiNGnNmia7_rodxe`Bt7`@^S z{;*MO;8FQlf?79cmkIVyQiHE=#9J4;rmHvnUGelv$kooOCZA9lAyM4;tOcX<%njps zL-g}&i@5I;&HRqr?!_OkDzlDwFb2N4uf{5Qsab@nD>y5B{@L>AJx~j-1HA;C{xI2j zo1!_6C!`Kn9x@4{-8tU~UT;LZ1C!P6eS@4;jjFxY)YjJASYrbo7>R=q!!TcWLz$rA zPpcsjjDXvL))1(GrOK5;nHff&IX8Twn^M-&9IS1c9ee_M zHb)4T&AMk+KZ^&wA8c;2GNA~22nQ~fri|V#04wMh%A8VUXWfV!Z^%zU$h_BPzTw#oz{s#EGY%PsaPuwUV$U!lwh?d*ZwICf0 zCP_)ndAp3G78bfZVN8u@`F0hc>@oLP!&13Nt1pcd$C%eMLS6axTpZkIS_`JLYjQ%_ zU@*!4^PRO>gr5^7)ktyc;bY;eWPv2}wEYnD?v3?%2w*A$Gj4F8P{6)X0cGl~6X-!v ziup(%_At}>)|^*$U1>RJ&Z|;DC!vISUA?_zzU9%VTHswKd+K`5($1%XXa{DGCl4s9 zn#CiU7U^WnHTco=c>#l+Z>(qBVB|bFGHIZ?%t3L1kdqXY8=klGEBN_XT+=ENxPWU3 zHVyfPIWDgtCzF8+?g}0-I@m)D$FhI#qOyz^%w|X|)U9M0|D>j4;f?QezzPjilcN!o z_%_JNY_mVWGJ?Da8CCQg;fD= z*eK1oaYVxpgxD9Kf57hu)jLrwpK;&N*^Tv5r&nwg=rJ48-isyQ^1rWwkY-|10b@az z2nL#qrbkU_`Iz}Sp`d3*RDqP|9i*p9Nwn7aL%4fFDH&RlPj}y&EfH1 z!-1H-9Y|_j6Dw3`G;M&J!FSoE#A!^YJ<%k+WFw_#`qS5+GF7W24!KQUZ<vyd>A$(I27IznuHjloAbc7!y{Dgel)i0d4PAfI`=+QQ;el`{&sumpuz7 zkqg{0cIFz4aZ>@2aDzw=F<8NL%5-t8yod=%if+eWrY{;z9&NgD=}6E#^-$0@mR>kW z`i#o4I^@$~J2ZY`jE-4O>x1#YwUwsYX}B=Tg5Yrx8y>);rnkP_GWd2xKo@d5y*X|$ zsjLjtQiF6|OGM-5J28^NG&Eq@gr5RBRFaL5W{60Wg4Pq|C`zTQ29#mU!wu8v;R@Dk zUn7ZZdXy>lvxg~*fh0u0WzH=^ts$tPCZE3UC?uu=LEx#o20$g*m1gw!$Hx+OkIf0# z9`wCUS}M@Zi%R#WIF|hqlI)pZ@sk!d})IYwGM* zreu;FA{Z(8Apb9pL&UKBt<9JZlBo$jNS57xA}R_94lL5$@Ry&7PHm@bxwQd{ zRl3)kTfsJ5g9a&zF(bTDm1(CizT8Bm6tQ!bu;0&UF@3lZuZ2M1Xkpa&tmRVLqism-qg)MnC?l+563OkoqP!CqYfTOlztOoG9WJvaH6kdq6JHd z>ELGr4{CpnXX&xC@yLJcafwNx(~||2GgtE|SeF3ChY?4wxQYGgz(_yaJm4sn+5~kR zKY0*O<_iP-iz(qQSIB;zbnZ2$z<1wz$Ovl~lmT3Mq+T&(EAQ7g!GCpoF8y=KXbm)6aci{Nw7*R>->09Oj}p!=%1m!jA;PPSeFEH9(?&!&#Nyxf1snx=YbcWQ;ylAwRa~p2 z+<~}|@JZ9!xC@_gbkcrBdV4#1GTTF(*#_qz)Ewx!EJ=3s(qSI}|c z4v*6Zw-YgiN+sc8eTjz)9^p#=DCbHCx>=IBO+J9r$o9#|IT8amt4On|@>m3X%U)?L z)!V;yp7z*Ss|o`XQ|h}Z=I}ZegyFAWFLqpbBj4{v?{7^wybJ?4byAx;AZ^v z47|y)R<@j!<$b-@R}_RIDs|ociZ>A^&)QZYGeIr6BIm|Err7plZq|EHYbNv4RG%N$ zA*s)Jk)r@)ALHB?SBNj{wgRNlklE)fmPe=0Yr~iVDyrVy%BtVo`|pO!M^gtbk|X&B zBWF}3?lpJ|o#o2LZ*Q^~4x7iLZaN%E(Pgxgj?kRcwDX?nIIbq|o@@z!7E~$^R{K#z zNjgk7V)KZ{PRBA>N#{5tu+18(XZ9ktMJX2$lzU3zwZ=f!#>?U5`xR}ZZM+;E-JH93d&WCNN zR;CL_y#eRn{yY`-)$7^J=zHvW;(p5MFk(uEd(5(M1Oz0n1q670_uBoH>*jr*+S=Gj z|J`r%Ep8|>jR7<0&KpL^6t>>auF5y2sjw-zI3ZPHML6<=$fiT27w%wbPD^rCEBgk&2>EYNBmp(hZ)yyGmtY z!(HiTYoc0=jFVbyuORY8K8|9J4?@H2^J5krSm?r=`z>yG+@KTOQ!%E<3{b{2Jy14Y1yZ084p z^cK6|fS@jDdx0kjF1_`~5m}?TI1c5FqRRBr8;e63LKD#zC|$xzdyGf;)~-gi=BY}l zwMovto5oBOBPxuM)xvogmRZ3^*4gKkpK@DUH$K9hX$V+Pa$}P*IP<3jq}_qwzohLD zypICn{;H^PfZuunu)XlVM*-aXDA2btH!*f}qH{1Z8HpRQ31C1BJo_AEJUY)u4-W1? zG1zF4+0GiQ22OvOioDtu8K)wjTYQ)~y;Uy4ycSuTcA}5lA6{M9p~PZHNjfNIR(C-C zshO@ZZ|T$Gd_6TmD&B=fKwc(QldBCCr*2{pEjygmSj`U#x74f8vMnDwW;pD{;CgE# zp`h`<37Fq(dtq~qZbF-=$~zrpMZ4b-a)+;cD$1&c(XUr%4XG!L@#FgjEj1Vjm^_+f zBzu?>ujDy9vQIYq^jfC^etgzDr;Z$(Uk!!J-_cobtvuBVSo2CS^Efs1aGvV9SR;EnWnwe@0uvL#K8){Ltqn&2*?ykIT|!x3t2hQu z-HDyVYLO*zjG=-r_%ryJKB+xl!r_!qgo)G+=%3RO$R!b$xJJfrA_6 z4s`?7#R6e2!-^>wwU6SVedyuxR3A^JE}Gw1E{Psco>mzN-9KY_(;z#SUVS{MW%uBq znTj1ZJ+!l6b*r!P;%lK$K5bD~-Q4WKBE-2HC#Y;J`%5_})Kd61$cj;B;bCDxnDgnE zQ?=GM&fNE;QxzYzlrOF|O3^Rh9YCvYMg}gcwHK|!lxB4~hi7%DPdv_kojqsmfr49w zikmz4(I7Vw%gIQ%CWIgM+(^4?4sZP6VqoJk&P0oQ8YX65q5SFLqTWnJ_6&PI;B;3# zR$`j)U6Me`el{d@6E0Pej692-B?1wgLA{BYD#+{8Vs*A%{st29JUJllDUaH-`EaZv z9dWW??Mdkh|L!W0TVanrovkR2M78+tR2JKu@orO+SY7`hQ z0gX&4h8x$wODjheMGFl{vtO@Xi{`!a4HJ3ymyf-I$aPruic0x%3Wt^8`T1cVzwMA! zCQVWc=dmN|Mg|{S|Eg6plRHuOTrHiO1w}-}4%PSy@Mn4u3ThAw2_~n}B}`WF`2!-( zgyRmnXnCcL-md7F^sgYu3G=iBn_?*Rz%lysQtomOrsVe_%h3j107*54JsNT>nVVNV zOx^0x)wn$H5rKNBwX5Qu&;|%6EhrYEz_h+rZfOS5KX_LzBeKD6Pi$)rUxUHwfBon$ zeM}$=pA&fMce=cVl3G#3=GC%~STQ-aEJctam12e%<#`cf4VEcZZK}s`kiCnZ-^V`e zJ~HWtf7OLT9;;vyPHkPfwiw@*Yd%!Kg6}6-Rlo;S$IQqGuZjUrm!g3i%Ud`IlW67^ zic(|dkI0=rf015GaujGUh*;qL3ZY55gP{7VEvPCasrnhjcz9g&acKH}d4%vQ{;pAg z(GO4>4^eTSHw5U;A*PrMs*nRdO{shTyE_sC2rFa6x=?kFnOZP4D zZ;;r96{nHh+cBjP|cQo1muoL_U*VT2 zM=jCwOS=Xf`=+dO_7TXJcGh(HdCRU@AL5#^8}0&BMctu2W3iWDF?!HN%sd4_DlfUZ zf_d9|ApTm%duXZ@Q)VpK!$Fy5gf-U1Q%f3yF-7Q{^?bt>dGpx$8q2h}U#Huv7Q8)5 zb%%Q(OSvx-Mw}&P9ZAvsc+8(!;PY71v&L1k@NtvTeQNbX{vh(;4ausYBCV*4%Hd8%~Zx3OC1o5+O{egR-YWO2+2#*rhrx6D$RO(8CaUZ3#quf(b-hxEq z6KHiWjrj;kvFAXJGwpVctr7`XrPk*#x5rj$@6sYJXOj|lyw|c;Utr&tC_E27C3C>G zZV%Ppt?)2_72eUw-OBhM3)G3Gb=1;Nq}Nql{e8O^vZZR*8cX&x!7Aa3IWkH+ab5zm zu=;tqAAAZv0~KfI%JDSrbop?{t$3$%vj$z$9R@y=2+B>07Q`6}$EqF_dGvtNJ zvRchyEF45~U}m42`+SMGqo8uMaBRmRg)l_9)vR8vQD%~Qh$h2bUd%aDNRzJrb;igb zQ7SH_3tjC;)gz@lCV;TOa#Q*n&PTPNLKW_c=>}I(RjJ-RA+T< z9C@27nsE!y=iSdL z5Z;_1im0COFb8bv*gGQU=*TO z0U6o=0IJ;u(MA!lUc zmYT)e_~K-zav&1v&<~}0P406R)<`gFmsr$7B;{dfA%lA@(PDx^_%b-LU&p&Y0 zb-6o2+Z0Adl`RmNJ*{|(USbX7^UL@MH1w-Fsq-s^dZ~{ldQ46Pp24_^9u@(?j|Zm| z^ww_05Q=Qyu#THEavB=8(10{25 zq>pn7G^*x-oAk*^9?q?fy>ckomj*2Ca1zjc(ZdA| z3GAg)ee%C{BMs0T1N)-(s0v{+HVth%kEBksdy&%zxLL_p4!94JqU38b%WxUU7~KFn z%1zW(P+RLUd2XTTWXI4yecuu?i*b`Yatyy#!_|vZ7c+y9f?rtT99$}E=U20VD2o82 z_{!@oWky2p?b<`2K~l|-$jvU3Nw*hQ>j*n_FqKMG!v459yjcsM3-JljE$V%avS&4-5Y_uL%jTU#-XMYdJ^_&qA|Ww*&j>7Y8>6abWy;9c*)_y z-Pda`S4b53bAWjT`>mm0t+CN?-4xv@T~Z^4Y=e@OOdouy887(4+@`Nk{KSI_F(42# z{6YsF62faK)GS)P2Bysx-(&P6rTtgn^P&Uv_cfP$yL*5An#1c7H z7p0y)vcJQur4a|`TT@0qxYRa?>cSwar9s!Gg8W}WqhQYW(hQh3xK?PkgdPE;NRux@qF)u9OPrp=g7hjE}_tx z7PYOeO3Axrc(ajVC@+L{x^^nrF{6J3FR$;j-4_%ZYTg%IGyC-`Q>?BhNkUZoOMXMB z_+@PR{$d5(VVHZEb9<`nrT0T;HW^X3u5#D>F(;{Z zru&DtGW_5+?NqSw_5~420DHzs*V!e1H&}h(sX-FGy=u=TO>(tRPyjukS%dR zyD(FKvJPE!Qfh@2cj%hggS_;SIm+QSbXKjde>lq!byeZ^%Cq0_6mVO3OY9!LYVl3v z9AeT!w12KHKe>*2?nIVtYDamN`(W;qSc$SD=V47G+N7G_W?3zZLcSKSfhxK8IgFH~ zCH|M9C#wEHuJ6P@WiXa$Hn2Z5FEtf<6@Dc-1a`JrO*N?K4ma{>u7+piK5dJlIn6Ig z>p)wiZ1-gf_Du9>uxLoNA3%zcZ@6L`&pd;p#z}{FD47^P`T&!(AnkZHOTB6z`%qwY zp!Kp8QmNUpPihlwcFdT$Iyzwh+Ro2Awk!&_fL>}TCRq;#vl5-UYkr6) zHi{=#+T1WW6nYa}oAXse+b>qwl+v)~JW+r!L*8v?Drttf_$K=VHRE6%>y24t5@TJH z$S@==aJ*@FO0gOpi!TmHhq!@`(RiOWO<&%UrkdaW;eyl2SCTh`1_B~w{X5eP4Pcr{ z3oG%{ipz-5|K^1OxDk5dmjM1a#Ne|#%8zR*^SIUUbpk4+>gAqQ-ar*tp`?by1S%UR zmS)x2#Xle@6&gEkBi`O{y4;=|4z~|MBhWO^C^{H5{5G4=i)qKl8mI;*hEC0w7)h}! zBXuB3DrFbO%>7#Am6)k%luJP+@d}zCl`T)XsfjVsgmW*|~HF{b*V_6`GJ>*ok9c+oH8EM#l+A4Ww7jV8$?cE{L z{I#3LQSk~YprBGQW0GEA{HTRjeS87sS%y8~!R#%O7R&W!a)kC_B(SyJtGsgfvz4n_+k~V~bb=XdgbkhfY_%%_&D-^o?;<2>4znyd}X0+ZDnModw#5BaO8ekat^q zpS>JD65tL(0@&MflE5ISK)+)lb$XfL$N^pXp5MKye@@os057Y%o$-HCMP>8jm;(T; z@A)0>_j{5C6qU@JtqpAS&8-~io&H^PiPlix(CokJ?>OF-c>@Iode4AS`iErkK4{Gioty#CNP0$wKO|-GO&ws803Ip{2u7XiOL|BBKg@Z|eiB&|1nfb4(_=9GE{&9@rw>PS& z!2TBa`sZQt8yTSR=MF#k3qHRCVgEOmKTAVE{om635g7Zw`Ml#le^07^!ROCF+5gSy z9V+{Kiunsp{{@`=-^~83q|v`%_B)XF|Cb9G&3`NDcVO-R=JID%fBFk9e+1h8Z$5uk zwZmWV`7`kLpPc^vYyacU&O7w>_f!ht^amjBe@+vB+zj~h6lKZ-_S-hle^UL?2ma^D z#hMR5^@nYP|D^n*YvRw8rTkz(fApCDC*>bk&Ue?v?@3k+K>3>^<3H*CI6di2n!IBM1)w literal 0 HcmV?d00001 From ae318219cb9be4d2451a6b60118682e4b5b0825b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 18 Feb 2019 17:56:27 -0700 Subject: [PATCH 002/400] include nice makefile --- Program/include/packet.h | 12 ++++++++ Program/include/port.h | 9 ++++++ Program/src/main.c | 9 ++++++ Program/src/makefile | 64 ++++++++++++++++++++++++++++++++++++++++ Program/src/port.c | 21 +++++++++++++ Program/test/main.c | 0 6 files changed, 115 insertions(+) create mode 100644 Program/include/packet.h create mode 100644 Program/include/port.h create mode 100644 Program/src/main.c create mode 100644 Program/src/makefile create mode 100644 Program/src/port.c create mode 100644 Program/test/main.c diff --git a/Program/include/packet.h b/Program/include/packet.h new file mode 100644 index 0000000..35386e5 --- /dev/null +++ b/Program/include/packet.h @@ -0,0 +1,12 @@ +#include + + +#ifndef PACKET +#define PACKET + +struct myclient { + uint8_t i; +}; + + +#endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h new file mode 100644 index 0000000..3eb8528 --- /dev/null +++ b/Program/include/port.h @@ -0,0 +1,9 @@ + +#include "packet.h" + +#ifndef PORT +#define PORT + +#define POSIX 1 + +#endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c new file mode 100644 index 0000000..f22214d --- /dev/null +++ b/Program/src/main.c @@ -0,0 +1,9 @@ + +#include + + +int main() { + + return 0; +} + diff --git a/Program/src/makefile b/Program/src/makefile new file mode 100644 index 0000000..89d6f10 --- /dev/null +++ b/Program/src/makefile @@ -0,0 +1,64 @@ + +PROJDIR = $(CURDIR)/.. +INCLUDE += -I$(PROJDIR)/include +CC = gcc + +#---------------------------File Names--------------------------- +CFILES += port.c +MAIN = main + +#---------------------------Compiler Warnings--------------------------- +CWARNS += -W +CWARNS += -Wall +CWARNS += -Werror +CWARNS += -Wextra +CWARNS += -Wformat +CWARNS += -Wmissing-braces +CWARNS += -Wno-cast-align +CWARNS += -Wparentheses +CWARNS += -Wshadow +CWARNS += -Wno-sign-compare +CWARNS += -Wswitch +CWARNS += -Wuninitialized +CWARNS += -Wunknown-pragmas +CWARNS += -Wunused-function +CWARNS += -Wunused-label +CWARNS += -Wunused-parameter +CWARNS += -Wunused-value +CWARNS += -Wunused-variable +CWARNS += -Wmissing-prototypes + +#---------------------------Libs--------------------------- +LINKFLAGS = +LIBS = + +#---------------------------Compiler flags--------------------------- + +#32 bit machines, leave this out if your machine is 64 bit +CFLAGS += -m32 +CFLAGS += -g -UUSE_STDIO -D__GCC_POSIX__=1 +CFLAGS += -pthread +CFLAGS += -DDEBUG=1 + +# MAX_NUMBER_OF_TASKS = max pthreads used in the POSIX port. +# Default value is 64 (_POSIX_THREAD_THREADS_MAX), the minimum number required by POSIX. +CFLAGS += -DMAX_NUMBER_OF_TASKS=300 +CFLAGS += $(INCLUDE) $(CWARNS) + + +#---------------------------Build--------------------------- +OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) + + +all: $(MAIN) + +.PHONY: clean + +$(MAIN): $(OBJS_FILES) + $(CC) $(CFLAGS) $(MAIN).c $^ -o $@ $(OBJS_FILES) + +%.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ + +clean: + rm *.o $(MAIN) \ No newline at end of file diff --git a/Program/src/port.c b/Program/src/port.c new file mode 100644 index 0000000..76ff875 --- /dev/null +++ b/Program/src/port.c @@ -0,0 +1,21 @@ + +#include "packet.h" + + + + + +/* +void ss_recvfrom(client *client) { + + + #ifdef POSIX + // recvfrom(sfd, buff, PACKET_LEN, 0, (struct sockaddr*)client, &client_len); + #endif + +} +*/ + + + + //ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); diff --git a/Program/test/main.c b/Program/test/main.c new file mode 100644 index 0000000..e69de29 From a9a2ef92c2a2feb3a3725fe8e5768eda20c2975f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 19 Feb 2019 19:55:57 -0700 Subject: [PATCH 003/400] Add simple udp server --- Program/include/packet.h | 23 +++- Program/include/port.h | 9 +- Program/include/server.h | 50 ++++++++ Program/include/utils.h | 78 +++++++++++++ Program/src/main.c | 6 +- Program/src/makefile | 21 ++-- Program/src/port.c | 41 +++++-- Program/src/server.c | 192 +++++++++++++++++++++++++++++++ Program/src/utils.c | 239 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 632 insertions(+), 27 deletions(-) create mode 100755 Program/include/server.h create mode 100755 Program/include/utils.h create mode 100755 Program/src/server.c create mode 100755 Program/src/utils.c diff --git a/Program/include/packet.h b/Program/include/packet.h index 35386e5..e80b8bc 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -4,9 +4,26 @@ #ifndef PACKET #define PACKET -struct myclient { - uint8_t i; -}; + +typedef struct PDU_header{ + unsigned int version: 3; + unsigned int PDU_type: 1; //0 File directive, 1 File Data, + unsigned int direction: 1; //0 toward file receiver, 1 toward file sender + unsigned int transmission_mode: 1; //0 acknowledged, 1 unacknowledged + unsigned int CRC_flag: 1; //0 crc not present, 1 crc present + unsigned int reserved_bit_0: 1; //set to 0 + unsigned int PDU_data_field_len: 16; + unsigned int reserved_bit_1: 1; //set to 0 + unsigned int length_of_entity_IDs: 3; + unsigned int reserved_bit_2: 1; + unsigned int transaction_seq_num_len: 3; //number of octets in sequence number, 0 is one octet + + //these are variable in size, and will get memory allocated based on the length variables above + void *source_id; + void *transaction_seq_num; + void *destination_id; +} PDU_header; + #endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index 3eb8528..5857d40 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -4,6 +4,13 @@ #ifndef PORT #define PORT -#define POSIX 1 +#define POSIX_PORT 0 +#include + +int on_time_out_posix(void *other); +int on_recv_posix(int sfd, char *msg, struct sockaddr_storage client, void *other); +void ss_connectionless_server(char *port); + + #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h new file mode 100755 index 0000000..ae1ba4c --- /dev/null +++ b/Program/include/server.h @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------------ +CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks +Assignment #1 +Evan Giese 1689223 + +This file is the header file for server.c +------------------------------------------------------------------------------*/ +#ifndef SERVER_H +#define SERVER_H + +//figure out what to inlcude for types ask nick +#include + +/*------------------------------------------------------------------------------ + Purpose: This function creates a host server on the specified port + on localhost + Perameters: char *port is the port number you want to run the host on + Return: It returns a socket descriptor to a UDP ready port +------------------------------------------------------------------------------*/ +int prepareUdpHost(char *port); + +/*------------------------------------------------------------------------------ + Purpose: This function creates a udp select server on the socket sfd. + Perameters: int sfd: The socket descriptor created by prepareUdpHost + void *other: this is the void* that we want to pass into + onRecv, and onTimeout + Return: None +------------------------------------------------------------------------------*/ +/*-----------------------------CALLBACK onRecv---------------------------------- + Purpose: This function handles what happends when a user receives a + packet + Perameters: int sfd: Is the socket descriptor that the msg was received on + this is useful for resending messges. + char *msg: Is the packet that was sent + struct sockaddr_storage client: Is the address of the sender + void *other: Is the void * we passed into selectUdp + Return: None +------------------------------------------------------------------------------*/ +/*-----------------------------CALLBACK onTimeOut------------------------------- + Purpose: This function + Perameters: void *other: Is the void * we passed into selectUdp + Return: None +------------------------------------------------------------------------------*/ +void prepareSignalHandler(void); + +void selectUdp(int sfd, void *other, + int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), + int (*onTimeOut)(void *other)); + +#endif //SERVER_H diff --git a/Program/include/utils.h b/Program/include/utils.h new file mode 100755 index 0000000..6333793 --- /dev/null +++ b/Program/include/utils.h @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ +CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks +Assignment #1 +Evan Giese 1689223 + +This file is the header file for utils.c +------------------------------------------------------------------------------*/ +#ifndef UTILS_H +#define UTILS_H + +#include +#include + +/*------------------------------------------------------------------------------ + Purpose: This struct if our configuration for this program, these elements + are set with getopt +------------------------------------------------------------------------------*/ +typedef struct CONFIG +{ + uint32_t numOfDecks; + uint32_t startingMoney; + int timer; + char *port; + uint32_t minBet; +} CONFIG; + +/*------------------------------------------------------------------------------ + Purpose: This is a node for the link list bellow +------------------------------------------------------------------------------*/ +typedef struct NODE +{ + void *element; + struct NODE *next; + struct NODE *prev; +} NODE; + +/*------------------------------------------------------------------------------ + Purpose: This is a LIST struct that contains functions useful for + doing linked list functionality. +------------------------------------------------------------------------------*/ +typedef struct LIST +{ + struct NODE *head; + struct NODE *tail; + void (*add)(struct LIST *list, void *element); + int (*remove)(struct LIST *list, int (*f)(void *element, void *args), void *args); + void (*print)(struct LIST *list, void (*f)(void *element, void *args), void *args); + void (*free)(struct LIST *list, void (*f)(void *element)); + + //returns a void pointer that should be cast to the type + void *(*find)(struct LIST *list, int (*f)(void *element, void *args), void *args); +} LIST; + +/*------------------------------------------------------------------------------ + Purpose: This function initializes a linked list LIST *. + Perameters: empty is just for the compiler errors, TODO use it for something + Return: returns a pointer to an initilized LIST * +------------------------------------------------------------------------------*/ +LIST *List(void); + +/*------------------------------------------------------------------------------ + Purpose: This function checks to see if the memory is allocated, + it exits if ok = 1 and keeps running in ok == 0 + Perameters: void *mem: + int ok: + Return: returns nothing +------------------------------------------------------------------------------*/ +void checkAlloc(void *mem, int ok); + +/*------------------------------------------------------------------------------ + Purpose: This function is used to make a configuration struct from the + arguments + Perameters: int agrc: the number of arguments + char **argv: the arguments + Return: CONFIG * +------------------------------------------------------------------------------*/ +CONFIG *configuration(int argc, char **argv); +#endif //UTILS_H diff --git a/Program/src/main.c b/Program/src/main.c index f22214d..f284a9c 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -1,9 +1,13 @@ #include - +#include +#include +#include +#include "port.h" int main() { + ss_connectionless_server("1111"); return 0; } diff --git a/Program/src/makefile b/Program/src/makefile index 89d6f10..08309bf 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -4,13 +4,17 @@ INCLUDE += -I$(PROJDIR)/include CC = gcc #---------------------------File Names--------------------------- -CFILES += port.c +CFILES += port.c +CFILES += utils.c +CFILES += server.c #used for poxix port + +#entrypoint MAIN = main #---------------------------Compiler Warnings--------------------------- CWARNS += -W CWARNS += -Wall -CWARNS += -Werror +#CWARNS += -Werror CWARNS += -Wextra CWARNS += -Wformat CWARNS += -Wmissing-braces @@ -45,20 +49,17 @@ CFLAGS += -DDEBUG=1 CFLAGS += -DMAX_NUMBER_OF_TASKS=300 CFLAGS += $(INCLUDE) $(CWARNS) - #---------------------------Build--------------------------- OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) - -all: $(MAIN) +all: $(MAIN) .PHONY: clean $(MAIN): $(OBJS_FILES) - $(CC) $(CFLAGS) $(MAIN).c $^ -o $@ $(OBJS_FILES) - -%.o: %.c - $(CC) -c $(CFLAGS) $< -o $@ clean: - rm *.o $(MAIN) \ No newline at end of file + rm -f *.o $(MAIN) + + + diff --git a/Program/src/port.c b/Program/src/port.c index 76ff875..f6a4615 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -1,21 +1,38 @@ #include "packet.h" +#include "server.h" +#include "port.h" +#include "stdio.h" +#include +#include + + +int on_recv_posix(int sfd, char *msg, struct sockaddr_storage client, void *other) { + + struct sockaddr_in* posix_client = (struct sockaddr_in*) &client; + int address_type = posix_client->sin_port; + + printf("%d\n", address_type); + printf("%s\n", (char *) other); + printf("%d\n", sfd); + printf("%s\n", msg); + return 1; +} +int on_time_out_posix(void *other) { + printf("%s\n", (char *) other); + printf("timeout\n"); + return 1; +} +void ss_connectionless_server(char *port) { + #ifdef POSIX_PORT + //for exiting nicely, optional + PDU_header *stuff = malloc(sizeof(PDU_header)); -/* -void ss_recvfrom(client *client) { - - - #ifdef POSIX - // recvfrom(sfd, buff, PACKET_LEN, 0, (struct sockaddr*)client, &client_len); + int sfd = prepareUdpHost(port); + selectUdp(sfd, stuff, on_recv_posix, on_time_out_posix); #endif - } -*/ - - - - //ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); diff --git a/Program/src/server.c b/Program/src/server.c new file mode 100755 index 0000000..dfbc585 --- /dev/null +++ b/Program/src/server.c @@ -0,0 +1,192 @@ +/*------------------------------------------------------------------------------ +CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks +Assignment #2 +Evan Giese 1689223 + +This is my file for server.c. It develops a udp server for select. +------------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "server.h" + + +static int exitNow = 0; +static int packet_len = 320; + + +//this code is reused from assignment 1, with small changes +//see header file +int prepareUdpHost(char *port) +{ + struct addrinfo hints, *res; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_flags = AI_V4MAPPED; + hints.ai_socktype = SOCK_DGRAM; + + int err = getaddrinfo(NULL, port, &hints, &res); + + if (err != 0) + { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err)); + exit(EXIT_FAILURE); + } + + int sfd; + struct addrinfo *cur; + + for (cur = res; cur != NULL; cur = cur->ai_next) + { + sfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + + if (sfd < 0) + { + perror("socket"); + } + + int val = 1; + err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + err = bind(sfd, cur->ai_addr, cur->ai_addrlen); + + if (err == -1) + { + perror("bind"); + close(sfd); + continue; + } + + if (err == -1) + { + perror("listen"); + close(sfd); + continue; + } + + freeaddrinfo(cur); + break; + } + + if (cur == NULL) + { + fprintf(stderr, "could not create server\n"); + exit(EXIT_FAILURE); + } + + return sfd; +} +/*------------------------------------------------------------------------------ + This function is the inturpt handler for sigaction, right now i just + handle sigint, so we can exit nicely. +------------------------------------------------------------------------------*/ + +static void interuptHandler(int signum) +{ + switch (signum) + { + case SIGINT: + exitNow = 1; + break; + } +} +//see header file +void prepareSignalHandler() +{ + struct sigaction actionData; + sigemptyset(&actionData.sa_mask); + actionData.sa_handler = interuptHandler; + actionData.sa_flags = 0; + + if (sigaction(SIGINT, &actionData, NULL) == -1) + { + perror("sigaction sigint failed\n"); + exit(EXIT_FAILURE); + } +} + + +//see header file +void selectUdp(int sfd, void *other, + int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), + int (*onTimeOut)(void *other)) +{ + //prepareSignalHandler(); + fd_set masterReadFds; + FD_ZERO(&masterReadFds); + FD_SET(STDIN_FILENO, &masterReadFds); + FD_SET(sfd, &masterReadFds); + char *buff = calloc(sizeof(char), packet_len); + checkAlloc(buff, 1); + + struct sockaddr_storage *client; + client = calloc(sizeof(struct sockaddr_storage), 1); + checkAlloc(client, 1); + + while (1) + { + struct timeval timeout = { + .tv_sec = 0, + .tv_usec = 1000e3, + }; + + fd_set readFds = masterReadFds; + int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); + + if (exitNow) + break; + + if (nrdy == -1) + { + perror("select"); + continue; + } + //timeout + if (nrdy == 0) + { + if (onTimeOut(other) == -1) + printf("timeout failed\n"); + continue; + } + + //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html + // good article! + if (FD_ISSET(sfd, &readFds)) + { + + socklen_t client_len = sizeof(*client); + int count = recvfrom(sfd, buff, packet_len, 0, (struct sockaddr*)client, &client_len); + + if (count == -1) + { + perror("recv failed"); + } + else if (count == sizeof(buff)) + { + printf("packet too large\n"); + continue; + } + else + { + if (onRecv(sfd, buff, *client, other) == -1) + printf("recv failed\n"); + } + } + } + free(client); + free(buff); + close(sfd); +} \ No newline at end of file diff --git a/Program/src/utils.c b/Program/src/utils.c new file mode 100755 index 0000000..c1851b4 --- /dev/null +++ b/Program/src/utils.c @@ -0,0 +1,239 @@ + +/*------------------------------------------------------------------------------ +CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks +Assignment #2 +Evan Giese 1689223 + +This is my utils.c file, it contains useful function and abstract data types +to use for general functionality. +------------------------------------------------------------------------------*/ +#include +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include + +//see header file +void checkAlloc(void *mem, int ok) +{ + if (mem == NULL && ok) + { + perror("malloc"); + exit(EXIT_FAILURE); + } +} + +//see header file +CONFIG *configuration(int argc, char **argv) +{ + int ch; + CONFIG *conf = calloc(sizeof(CONFIG), 1); + checkAlloc(conf, 1); + conf->numOfDecks = 2; + conf->startingMoney = 100; + conf->timer = 15; + conf->port = "4420"; + conf->minBet = 1; + + int tmp; + while ((ch = getopt(argc, argv, "d: m: t: p: b: h")) != -1) + { + switch (ch) + { + case 'd': + tmp = strtol(optarg, NULL, 10); + if (0 < tmp && tmp < 11) + conf->numOfDecks = tmp; + break; + + case 'm': + tmp = strtol(optarg, NULL, 10); + if (0 < tmp) + conf->startingMoney = tmp; + break; + + case 't': + tmp = strtol(optarg, NULL, 10); + if (10 < tmp && tmp < 45) + conf->timer = tmp; + break; + + case 'p': + conf->port = optarg; + break; + + case 'b': + //tmp = strtol(optarg, NULL, 10); + //if (0 < tmp && tmp < 4294967296) + // conf->minBet = tmp; + + break; + + case 'h': + printf("\n-----------HELP MESSAGE------------\n"); + printf("\nusage: %s [options] \n\n", basename(argv[0])); + printf("Options: %s%s%s%s%s\n", + "-d NumberOfDecks\n", + "-m StartingMoney\n", + "-t Timer(between 15 and 45 seconds)\n", + "-p PortNumber\n", + "-h HelpMessage"); + + printf("default number of decks is 2, but can change \n%s%s%s%s%s", + "if to something between 1 and 10. Default \n", + "starting money is 100, and is good as long as it\n", + "between 0 and 4294967296 (uint32 max). \n", + "Default for timer is 15 seconds. Default port number\n", + "is 4420\n"); + printf("\n---------------END----------------\n"); + break; + default: + printf("\ngot something not found using default\n"); + break; + } + } + return conf; +} + +/*------------------------------------------------------------------------------ + This function creates a new node to add into the linked list, returns the + new node. +------------------------------------------------------------------------------*/ + +static NODE *createNode(void *element) +{ + NODE *newNode = calloc(sizeof(NODE), 1); + checkAlloc(newNode, 1); + newNode->element = element; + return newNode; +} + + +/*------------------------------------------------------------------------------ + This function adds a new element into the linked list. returns nothing. +------------------------------------------------------------------------------*/ + +static void addElement(LIST *list, void *element) +{ + + NODE *newNode = createNode(element); + NODE *tail = list->tail; + + newNode->next = tail; + newNode->prev = tail->prev; + + tail->prev->next = newNode; + tail->prev = newNode; +} + +/*------------------------------------------------------------------------------ + This function will print out the list if given a callback that is designed + to print out an element. +------------------------------------------------------------------------------*/ + +static void printList(LIST *list, void (*f)(void *element, void *args), void *args) +{ + NODE *cur = list->head->next; + while (cur->next != NULL) + { + f(cur->element, args); + cur = cur->next; + } +} + + +/*------------------------------------------------------------------------------ + This function removes an element from the linked list, returns 1 if success + and -1 if item not found. +------------------------------------------------------------------------------*/ + +static int removeElement(LIST *list, int (*f)(void *element, void *args), void *args) +{ + NODE *cur = list->head->next; + while (cur->next != NULL) + { + int found = f(cur->element, args); + if (found == 1) + { + NODE *previous = cur->prev; + NODE *next = cur->next; + previous->next = next; + next->prev = previous; + free(cur); + return 1; + } + cur = cur->next; + } + return -1; +} + +/*------------------------------------------------------------------------------ + frees the linked list. Takes a free function that is a function pointer to + a function that frees and elemnent. Returns nothing, +------------------------------------------------------------------------------*/ + +static void freeList(LIST *list, void (*f)(void *element)) +{ + NODE *cur = list->head->next; + while (cur->next != NULL) + { + NODE *n = cur; + cur = cur->next; + f(n->element); + free(n->element); + free(n); + } + free(list->head); + free(list->tail); + free(list); +} + +/*------------------------------------------------------------------------------ + This function finds an element, returns and element on success and NULL on + failure. The return value should be cast to the element type. +------------------------------------------------------------------------------*/ + +static void *findElement(LIST *list, int (*f)(void *element, void *args), void *args) +{ + + NODE *cur = list->head->next; + while (cur->next != NULL) + { + int found = f(cur->element, args); + if (found == 1) + { + return cur->element; + } + cur = cur->next; + } + return NULL; +} + +//see header file + +LIST *List() +{ + LIST *newList = calloc(sizeof(LIST), 1); + checkAlloc(newList, 1); + + newList->head = createNode(NULL); + newList->tail = createNode(NULL); + + NODE *tail = newList->tail; + NODE *head = newList->head; + + tail->prev = head; + head->next = tail; + + newList->add = addElement; + newList->remove = removeElement; + newList->print = printList; + newList->free = freeList; + newList->find = findElement; + + return newList; +} From 9c467b797605c9982d7b7888711a5fbc1e4bdd5b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 20 Feb 2019 16:14:43 -0700 Subject: [PATCH 004/400] Add ss_sendto function for port --- Program/include/port.h | 11 +++++---- Program/include/server.h | 5 ++-- Program/src/port.c | 49 ++++++++++++++++++++++++++++++---------- Program/src/server.c | 18 +++++++++------ 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 5857d40..bb07cfe 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -1,16 +1,17 @@ #include "packet.h" -#ifndef PORT -#define PORT +#ifndef PORT_H +#define PORT_H #define POSIX_PORT 0 #include +#include "protocol_handler.h" -int on_time_out_posix(void *other); -int on_recv_posix(int sfd, char *msg, struct sockaddr_storage client, void *other); -void ss_connectionless_server(char *port); +void ss_error(char *msg); +void ss_connectionless_server(char *port); +void ss_sendto(Client client); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index ae1ba4c..7b24fc9 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -43,8 +43,9 @@ int prepareUdpHost(char *port); ------------------------------------------------------------------------------*/ void prepareSignalHandler(void); -void selectUdp(int sfd, void *other, +void selectUdp(int sfd, int packet_len, int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), - int (*onTimeOut)(void *other)); + int (*onTimeOut)(void *other), + void *other); #endif //SERVER_H diff --git a/Program/src/port.c b/Program/src/port.c index f6a4615..b21d459 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -5,23 +5,49 @@ #include "stdio.h" #include #include +#include -int on_recv_posix(int sfd, char *msg, struct sockaddr_storage client, void *other) { +void ss_error(char *msg) { - struct sockaddr_in* posix_client = (struct sockaddr_in*) &client; - int address_type = posix_client->sin_port; + #ifdef POSIX_PORT + perror(msg); + #endif + +} - printf("%d\n", address_type); - printf("%s\n", (char *) other); - printf("%d\n", sfd); - printf("%s\n", msg); +void ss_sendto(Client client) { + + #ifdef POSIX_PORT + struct sockaddr* addr = (struct sockaddr*) client.addr; + printf("msg to send: %s\n", client.msg); + printf("file descriptor:%d\n", client.sfd); + + int n = sendto(client.sfd, client.msg, strnlen(client.msg, 100), 0, addr, sizeof(*addr)); + if (n < 0) + ss_error("ERROR in ss_sendto"); + #endif +} + + + +//this function is a callback when using my silly posix port +static int on_recv_posix(int sfd, char *msg, struct sockaddr_storage addr, void *other) { + + struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + Client new_client; + new_client.msg = "stuffffff"; + new_client.addr = posix_client; + new_client.sfd = sfd; + printf("msg recv: %s\n", msg); + ss_sendto(new_client); return 1; } -int on_time_out_posix(void *other) { - printf("%s\n", (char *) other); - printf("timeout\n"); +//this function is a callback when using my silly posix ports +static int on_time_out_posix(void *other) { + //printf("%s\n", (char *) other); + //printf("timeout\n"); return 1; } @@ -31,8 +57,7 @@ void ss_connectionless_server(char *port) { #ifdef POSIX_PORT //for exiting nicely, optional PDU_header *stuff = malloc(sizeof(PDU_header)); - int sfd = prepareUdpHost(port); - selectUdp(sfd, stuff, on_recv_posix, on_time_out_posix); + selectUdp(sfd, PACKET_LEN, on_recv_posix, on_time_out_posix, stuff); #endif } diff --git a/Program/src/server.c b/Program/src/server.c index dfbc585..e7f3742 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -26,7 +26,7 @@ This is my file for server.c. It develops a udp server for select. static int exitNow = 0; -static int packet_len = 320; +static int new_packet_len; //this code is reused from assignment 1, with small changes @@ -120,23 +120,27 @@ void prepareSignalHandler() //see header file -void selectUdp(int sfd, void *other, - int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), - int (*onTimeOut)(void *other)) +void selectUdp(int sfd, int packet_len, + int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), + int (*onTimeOut)(void *other), + void *other) { + + new_packet_len = packet_len; + //prepareSignalHandler(); fd_set masterReadFds; FD_ZERO(&masterReadFds); FD_SET(STDIN_FILENO, &masterReadFds); FD_SET(sfd, &masterReadFds); - char *buff = calloc(sizeof(char), packet_len); + char *buff = calloc(sizeof(char), new_packet_len); checkAlloc(buff, 1); struct sockaddr_storage *client; client = calloc(sizeof(struct sockaddr_storage), 1); checkAlloc(client, 1); - while (1) + for (;;) { struct timeval timeout = { .tv_sec = 0, @@ -168,7 +172,7 @@ void selectUdp(int sfd, void *other, { socklen_t client_len = sizeof(*client); - int count = recvfrom(sfd, buff, packet_len, 0, (struct sockaddr*)client, &client_len); + int count = recvfrom(sfd, buff, new_packet_len, 0, (struct sockaddr*)client, &client_len); if (count == -1) { From 2783fadc9e40ea640ccf922d6916daeffea69657 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 22 Feb 2019 14:13:50 -0700 Subject: [PATCH 005/400] multi thread client server --- .gitignore | 5 ++ Program/include/packet.h | 9 ++- Program/include/port.h | 14 ++-- Program/include/protocol_handler.h | 32 ++++++++ Program/include/server.h | 14 +++- Program/include/utils.h | 4 +- Program/src/main.c | 11 ++- Program/src/makefile | 2 +- Program/src/port.c | 117 ++++++++++++++++++++++++----- Program/src/protocol_handler.c | 13 ++++ Program/src/server.c | 91 ++++++++++++++++++++-- Program/src/utils.c | 4 +- Program/test/makefile | 63 ++++++++++++++++ Program/test/udpClient.c | 81 ++++++++++++++++++++ 14 files changed, 418 insertions(+), 42 deletions(-) create mode 100644 .gitignore create mode 100644 Program/include/protocol_handler.h create mode 100644 Program/src/protocol_handler.c create mode 100644 Program/test/makefile create mode 100644 Program/test/udpClient.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f0a1c07 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +Program/src/*.o +Documents +main +settings.json +SpaceProjects.odt \ No newline at end of file diff --git a/Program/include/packet.h b/Program/include/packet.h index e80b8bc..02f60f0 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -1,9 +1,14 @@ #include -#ifndef PACKET -#define PACKET +#ifndef PACKET_H +#define PACKET_H +#define PACKET_HEADER_LEN 224 + +// PACKET_HEADER_LEN + data max size = (65536 * 8) +#define PACKET_MAX_LEN 524512 +#define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes typedef struct PDU_header{ unsigned int version: 3; diff --git a/Program/include/port.h b/Program/include/port.h index bb07cfe..c7114a7 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -4,14 +4,18 @@ #ifndef PORT_H #define PORT_H -#define POSIX_PORT 0 -#include +#define STACK_ALLOCATION 16384 +#define POSIX_PORT 1 #include "protocol_handler.h" -void ss_error(char *msg); -void ss_connectionless_server(char *port); -void ss_sendto(Client client); +void ssp_error(char *msg); +Protocol_state *ssp_connectionless_server(char *port); +void *ssp_connectionless_server_task(void *protocol_state); +void ssp_connectionless_client(char *host_name, char*port); +void ssp_sendto(Client client); +void ssp_cleanup(Protocol_state *state); + #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h new file mode 100644 index 0000000..44c9e5b --- /dev/null +++ b/Program/include/protocol_handler.h @@ -0,0 +1,32 @@ + +#ifndef PROTOCOL_H +#define PROTOCOL_H + + + + +typedef struct client { + int sfd; + char *msg; + //this is type (struct sockaddr_in) in posix + void *addr; + int packet_len; +} Client; + + +typedef struct protocol_state { + int packet_size; + + char* server_port; + void *server_handle; + void *server_thread_attributes; + +} Protocol_state; + + + +void packet_handler(void); + + + +#endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index 7b24fc9..4fc3ab2 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -41,11 +41,21 @@ int prepareUdpHost(char *port); Perameters: void *other: Is the void * we passed into selectUdp Return: None ------------------------------------------------------------------------------*/ -void prepareSignalHandler(void); -void selectUdp(int sfd, int packet_len, +void udpSelectServer(char *port, int packet_len, int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other); +/*-----------------------------CALLBACK onTimeOut------------------------------- + Purpose: This is a simple udp client + Perameters: hostname is the name of an address eg, 127.0.0.1, port is the port + eg, 1111 + Return: None +------------------------------------------------------------------------------*/ + + +void udpClient(char *hostname, char*port); + + #endif //SERVER_H diff --git a/Program/include/utils.h b/Program/include/utils.h index 6333793..5011bc8 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -62,10 +62,10 @@ LIST *List(void); Purpose: This function checks to see if the memory is allocated, it exits if ok = 1 and keeps running in ok == 0 Perameters: void *mem: - int ok: + int notOkToFail: Return: returns nothing ------------------------------------------------------------------------------*/ -void checkAlloc(void *mem, int ok); +void checkAlloc(void *mem, int notOkToFail); /*------------------------------------------------------------------------------ Purpose: This function is used to make a configuration struct from the diff --git a/Program/src/main.c b/Program/src/main.c index f284a9c..37fab37 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -4,10 +4,19 @@ #include #include #include "port.h" +#include +#include "protocol_handler.h" int main() { - ss_connectionless_server("1111"); + + Protocol_state* p_state = ssp_connectionless_server("1111"); + + sleep(2); + + ssp_connectionless_client("127.0.0.1", "1111"); + ssp_cleanup(p_state); + return 0; } diff --git a/Program/src/makefile b/Program/src/makefile index 08309bf..15987a1 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -34,7 +34,7 @@ CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = -LIBS = +LIBS = -pthread #---------------------------Compiler flags--------------------------- diff --git a/Program/src/port.c b/Program/src/port.c index b21d459..18205e3 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -2,13 +2,21 @@ #include "packet.h" #include "server.h" #include "port.h" -#include "stdio.h" + #include -#include #include +#include "utils.h" + +#ifdef POSIX_PORT + #include + #include + #include + #include + #include +#endif -void ss_error(char *msg) { +void ssp_error(char *msg) { #ifdef POSIX_PORT perror(msg); @@ -16,48 +24,119 @@ void ss_error(char *msg) { } -void ss_sendto(Client client) { +void ssp_sendto(Client client) { #ifdef POSIX_PORT struct sockaddr* addr = (struct sockaddr*) client.addr; - printf("msg to send: %s\n", client.msg); - printf("file descriptor:%d\n", client.sfd); - - int n = sendto(client.sfd, client.msg, strnlen(client.msg, 100), 0, addr, sizeof(*addr)); + int n = sendto(client.sfd, client.msg, client.packet_len, 0, addr, sizeof(*addr)); if (n < 0) - ss_error("ERROR in ss_sendto"); + ssp_error("ERROR in ssp_sendto"); #endif } - //this function is a callback when using my silly posix port static int on_recv_posix(int sfd, char *msg, struct sockaddr_storage addr, void *other) { - + + Protocol_state *state = (Protocol_state *) other; struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + Client new_client; new_client.msg = "stuffffff"; new_client.addr = posix_client; new_client.sfd = sfd; + new_client.packet_len = state->packet_size; + printf("msg recv: %s\n", msg); - ss_sendto(new_client); + printf("addr %d port%d\n",ntohl(((struct in_addr*) posix_client)->s_addr), ntohs(posix_client->sin_port)); + ssp_sendto(new_client); + + return 1; } //this function is a callback when using my silly posix ports static int on_time_out_posix(void *other) { - //printf("%s\n", (char *) other); - //printf("timeout\n"); return 1; } -void ss_connectionless_server(char *port) { +void *ssp_connectionless_server_task(void *params) { + Protocol_state* state = (Protocol_state*) params; + + #ifdef POSIX_PORT + udpSelectServer(state->server_port, PACKET_LEN, on_recv_posix, on_time_out_posix, state); + #endif + + return NULL; +} + + +Protocol_state* ssp_connectionless_server(char *port) { + #ifdef POSIX_PORT + Protocol_state *state = calloc(sizeof(Protocol_state), 1); + state->packet_size = PACKET_LEN; + + pthread_t *handler = calloc(sizeof(pthread_t), 1); + checkAlloc(handler, 1); + + pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); + checkAlloc(attr, 1); + + state->server_port = calloc(sizeof(char), 10); + checkAlloc(state->server_port, 1); + + strncpy (state->server_port, port, 10); + + int err = pthread_attr_init(attr); + if (0 != err) + perror("pthread_init failed"); + + + size_t stack_size = STACK_ALLOCATION; + err = pthread_attr_setstacksize(attr, stack_size); + + if (0 != err) + perror("ERROR pthread_attr_setstacksize %d"); + + if (EINVAL == err) { + printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + } + + err = pthread_create(handler, attr, ssp_connectionless_server_task, state); + if (0 != err) + perror("ERROR pthread_create"); + + + state->server_handle = handler; + state->server_thread_attributes = attr; + + return state; + + #endif +} + + +void ssp_connectionless_client(char *host_name, char*port) { #ifdef POSIX_PORT - //for exiting nicely, optional - PDU_header *stuff = malloc(sizeof(PDU_header)); - int sfd = prepareUdpHost(port); - selectUdp(sfd, PACKET_LEN, on_recv_posix, on_time_out_posix, stuff); + udpClient(host_name, port); #endif + } + +void ssp_cleanup(Protocol_state *state) { + + #ifdef POSIX_PORT + pthread_t * handle = (pthread_t*) state->server_handle; + + pthread_join(*handle, NULL); + + free(state->server_handle); + free(state->server_port); + free(state->server_thread_attributes); + free(state); + + #endif + +} \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c new file mode 100644 index 0000000..8c997a6 --- /dev/null +++ b/Program/src/protocol_handler.c @@ -0,0 +1,13 @@ + + +#include "port.h" + + + + + +void packet_handler() { + + printf("stuff\n"); + +} \ No newline at end of file diff --git a/Program/src/server.c b/Program/src/server.c index e7f3742..f6823b8 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -23,9 +23,17 @@ This is my file for server.c. It develops a udp server for select. #include #include "utils.h" #include "server.h" +#include +#include +#include +#include +#include +#include +#include +#include -static int exitNow = 0; +static int exit_now = 0; static int new_packet_len; @@ -99,12 +107,14 @@ static void interuptHandler(int signum) switch (signum) { case SIGINT: - exitNow = 1; + exit_now = 1; break; } } + + //see header file -void prepareSignalHandler() +static void prepareSignalHandler() { struct sigaction actionData; sigemptyset(&actionData.sa_mask); @@ -120,15 +130,15 @@ void prepareSignalHandler() //see header file -void selectUdp(int sfd, int packet_len, +void udpSelectServer(char* port, int packet_len, int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other) { - + int sfd = prepareUdpHost(port); new_packet_len = packet_len; + prepareSignalHandler(); - //prepareSignalHandler(); fd_set masterReadFds; FD_ZERO(&masterReadFds); FD_SET(STDIN_FILENO, &masterReadFds); @@ -150,7 +160,7 @@ void selectUdp(int sfd, int packet_len, fd_set readFds = masterReadFds; int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); - if (exitNow) + if (exit_now) break; if (nrdy == -1) @@ -193,4 +203,69 @@ void selectUdp(int sfd, int packet_len, free(client); free(buff); close(sfd); -} \ No newline at end of file +} + + + + +//https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c +void udpClient(char *hostname, char*port //,void *other, + //int (*onSend)(int sfd, struct sockaddr_storage client, void *other), + //int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), +) { + + int sfd, n, port_val; + int serverlen; + struct sockaddr_in serveraddr; + struct hostent *server; + char *buff = calloc(sizeof(char), new_packet_len); + checkAlloc(buff, 1); + + prepareSignalHandler(); + + sfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sfd < 0) + perror("ERROR opening socket"); + + port_val = atoi(port); + + server = gethostbyname(hostname); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host as %s\n", hostname); + exit(0); + } + + bzero((char *) &serveraddr, sizeof(serveraddr)); + serveraddr.sin_family = AF_INET; + + bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); + serveraddr.sin_port = htons(port_val); + + char* msg = "some stuff to send"; + /* get a message from the user */ + + memcpy(buff, msg, strnlen(msg, new_packet_len)); + + for (;;) { + + if (exit_now) + break; + + /* send the message to the server */ + serverlen = sizeof(serveraddr); + n = sendto(sfd, buff, (size_t) strnlen(buff, new_packet_len), 0, (struct sockaddr*)&serveraddr, serverlen); + if (n < 0) + perror("ERROR in sendto"); + + sleep(2); + /* print the server's reply */ + /* + n = recvfrom(sockfd, buf, BUFSIZE, 0, &serveraddr, &serverlen); + if (n < 0) + error("ERROR in recvfrom"); + printf("Echo from server: %s\n", buf); + */ + } + free(buff); + close(sfd); +} diff --git a/Program/src/utils.c b/Program/src/utils.c index c1851b4..1e39d32 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -18,9 +18,9 @@ to use for general functionality. #include //see header file -void checkAlloc(void *mem, int ok) +void checkAlloc(void *mem, int notOkToFail) { - if (mem == NULL && ok) + if (mem == NULL && notOkToFail) { perror("malloc"); exit(EXIT_FAILURE); diff --git a/Program/test/makefile b/Program/test/makefile new file mode 100644 index 0000000..dabb7f1 --- /dev/null +++ b/Program/test/makefile @@ -0,0 +1,63 @@ + +PROJDIR = $(CURDIR)/.. +INCLUDE += -I$(PROJDIR)/include +CC = gcc + +#---------------------------File Names--------------------------- +#CFILES += udpClient.c + +#entrypoint +MAIN = udpClient + +#---------------------------Compiler Warnings--------------------------- +CWARNS += -W +CWARNS += -Wall +#CWARNS += -Werror +CWARNS += -Wextra +CWARNS += -Wformat +CWARNS += -Wmissing-braces +CWARNS += -Wno-cast-align +CWARNS += -Wparentheses +CWARNS += -Wshadow +CWARNS += -Wno-sign-compare +CWARNS += -Wswitch +CWARNS += -Wuninitialized +CWARNS += -Wunknown-pragmas +CWARNS += -Wunused-function +CWARNS += -Wunused-label +CWARNS += -Wunused-parameter +CWARNS += -Wunused-value +CWARNS += -Wunused-variable +CWARNS += -Wmissing-prototypes + +#---------------------------Libs--------------------------- +LINKFLAGS = +LIBS = + +#---------------------------Compiler flags--------------------------- + +#32 bit machines, leave this out if your machine is 64 bit +CFLAGS += -m32 +CFLAGS += -g -UUSE_STDIO -D__GCC_POSIX__=1 +CFLAGS += -pthread +CFLAGS += -DDEBUG=1 + +# MAX_NUMBER_OF_TASKS = max pthreads used in the POSIX port. +# Default value is 64 (_POSIX_THREAD_THREADS_MAX), the minimum number required by POSIX. +CFLAGS += -DMAX_NUMBER_OF_TASKS=300 +CFLAGS += $(INCLUDE) $(CWARNS) + +#---------------------------Build--------------------------- +OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) + +all: $(MAIN) + +.PHONY: clean + +$(MAIN): $(OBJS_FILES) + +clean: + rm -f *.o $(MAIN) + + + diff --git a/Program/test/udpClient.c b/Program/test/udpClient.c new file mode 100644 index 0000000..87a6779 --- /dev/null +++ b/Program/test/udpClient.c @@ -0,0 +1,81 @@ +/* + * udpclient.c - A simple UDP client + * usage: udpclient + * https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 320 + +/* + * error - wrapper for perror + */ +void error(char *msg) { + perror(msg); + exit(0); +} + +int main(int argc, char **argv) { + int sockfd, portno, n; + int serverlen; + struct sockaddr_in serveraddr; + struct hostent *server; + char *hostname; + char buf[BUFSIZE]; + + /* check command line arguments */ + if (argc != 3) { + fprintf(stderr,"usage: %s \n", argv[0]); + exit(0); + } + hostname = argv[1]; + portno = atoi(argv[2]); + + /* socket: create the socket */ + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) + error("ERROR opening socket"); + + /* gethostbyname: get the server's DNS entry */ + server = gethostbyname(hostname); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host as %s\n", hostname); + exit(0); + } + + /* build the server's Internet address */ + bzero((char *) &serveraddr, sizeof(serveraddr)); + serveraddr.sin_family = AF_INET; + bcopy((char *)server->h_addr, (char *)&serveraddr.sin_addr.s_addr, server->h_length); + serveraddr.sin_port = htons(portno); + + int msg = "some stuff to send"; + /* get a message from the user */ + + memcpy(buf, msg, strnlen(msg, BUFSIZE)); + for (;;) { + //bzero(buf, BUFSIZE); + //printf("Please enter msg: "); + //fgets(buf, BUFSIZE, stdin); + + /* send the message to the server */ + serverlen = sizeof(serveraddr); + n = sendto(sockfd, buf, strlen(buf), 0, &serveraddr, serverlen); + if (n < 0) + error("ERROR in sendto"); + sleep(2); + /* print the server's reply */ + n = recvfrom(sockfd, buf, BUFSIZE, 0, &serveraddr, &serverlen); + if (n < 0) + error("ERROR in recvfrom"); + printf("Echo from server: %s\n", buf); + } + return 0; +} \ No newline at end of file From fc4c633d76aa1230a6638a3fda1d7a837b65da37 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 22 Feb 2019 16:41:08 -0700 Subject: [PATCH 006/400] thread client for forwarding procedures, and for local testing --- Program/include/port.h | 6 ++- Program/include/protocol_handler.h | 9 ++++ Program/src/main.c | 7 ++- Program/src/port.c | 71 ++++++++++++++++++++++++++++-- 4 files changed, 84 insertions(+), 9 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index c7114a7..c4f2317 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -14,8 +14,10 @@ Protocol_state *ssp_connectionless_server(char *port); void *ssp_connectionless_server_task(void *protocol_state); -void ssp_connectionless_client(char *host_name, char*port); +Client *ssp_connectionless_client(char *host_name, char*port); +void *ssp_connectionless_client_task(void *params); + void ssp_sendto(Client client); void ssp_cleanup(Protocol_state *state); - +void ssp_cleanup_client(Client *client); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 44c9e5b..c81ac0f 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -7,10 +7,19 @@ typedef struct client { int sfd; + char *msg; //this is type (struct sockaddr_in) in posix void *addr; int packet_len; + + char* host_name; + char* client_port; + + void *client_handle; + void *client_thread_attributes; + + } Client; diff --git a/Program/src/main.c b/Program/src/main.c index 37fab37..e80bdde 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -9,12 +9,11 @@ int main() { - Protocol_state* p_state = ssp_connectionless_server("1111"); + sleep(1); + Client *client = ssp_connectionless_client("127.0.0.1", "1111"); - sleep(2); - - ssp_connectionless_client("127.0.0.1", "1111"); + ssp_cleanup_client(client); ssp_cleanup(p_state); return 0; diff --git a/Program/src/port.c b/Program/src/port.c index 18205e3..0e94786 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -117,10 +117,60 @@ Protocol_state* ssp_connectionless_server(char *port) { #endif } +void *ssp_connectionless_client_task(void* params){ -void ssp_connectionless_client(char *host_name, char*port) { + Client *client = (Client*) params; + udpClient(client->host_name, client->client_port); + return NULL; +} + + +Client *ssp_connectionless_client(char *host_name, char *port) { #ifdef POSIX_PORT - udpClient(host_name, port); + int port_len = strnlen(port, 100) + 1; + int host_len = strnlen(host_name, 100) + 1; + + Client *client = calloc(sizeof(Client), 1); + checkAlloc(client, 1); + + client->host_name = calloc(sizeof(char), host_len); + checkAlloc(client->host_name, 1); + + client->client_port = calloc(sizeof(char), port_len); + checkAlloc(client->client_port, 1); + + pthread_t *handler = calloc(sizeof(pthread_t), 1); + checkAlloc(handler, 1); + + pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); + checkAlloc(attr, 1); + + strncpy(client->client_port, port, port_len); + strncpy(client->host_name, host_name, host_len); + + int err = pthread_attr_init(attr); + if (0 != err) + perror("pthread_init failed"); + + size_t stack_size = STACK_ALLOCATION; + err = pthread_attr_setstacksize(attr, stack_size); + + if (0 != err) + perror("ERROR pthread_attr_setstacksize %d"); + + if (EINVAL == err) { + printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + } + + err = pthread_create(handler, attr, ssp_connectionless_client_task, client); + if (0 != err) + perror("ERROR pthread_create"); + + + client->client_handle = handler; + client->client_thread_attributes = attr; + return client; + #endif } @@ -131,7 +181,6 @@ void ssp_cleanup(Protocol_state *state) { pthread_t * handle = (pthread_t*) state->server_handle; pthread_join(*handle, NULL); - free(state->server_handle); free(state->server_port); free(state->server_thread_attributes); @@ -139,4 +188,20 @@ void ssp_cleanup(Protocol_state *state) { #endif +} + +void ssp_cleanup_client(Client *client) { + + #ifdef POSIX_PORT + pthread_t * handle = (pthread_t*) client->client_handle; + + pthread_join(*handle, NULL); + free(client->host_name); + free(client->client_handle); + free(client->client_port); + free(client->client_thread_attributes); + free(client); + #endif + + } \ No newline at end of file From 9a32109ccb762fe486919bde34065e3b20ac059a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 23 Feb 2019 16:44:51 -0700 Subject: [PATCH 007/400] making client and server interactions better --- Program/include/packet.h | 10 +- Program/include/port.h | 6 +- Program/include/protocol_handler.h | 27 ++-- Program/include/server.h | 4 +- Program/include/utils.h | 18 +-- Program/src/main.c | 13 +- Program/src/makefile | 1 + Program/src/port.c | 251 ++++++++++++++++++----------- Program/src/protocol_handler.c | 12 +- Program/src/server.c | 71 +++++--- Program/src/utils.c | 41 +++-- 11 files changed, 288 insertions(+), 166 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 02f60f0..e05dd12 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -10,7 +10,7 @@ #define PACKET_MAX_LEN 524512 #define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes -typedef struct PDU_header{ +typedef struct pdu_header{ unsigned int version: 3; unsigned int PDU_type: 1; //0 File directive, 1 File Data, unsigned int direction: 1; //0 toward file receiver, 1 toward file sender @@ -27,8 +27,12 @@ typedef struct PDU_header{ void *source_id; void *transaction_seq_num; void *destination_id; -} PDU_header; - +} Pdu_header; +typedef struct packet { + Pdu_header header; + uint8_t *data; + uint8_t *crc; +} Packet; #endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index c4f2317..55618d1 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -14,10 +14,10 @@ Protocol_state *ssp_connectionless_server(char *port); void *ssp_connectionless_server_task(void *protocol_state); -Client *ssp_connectionless_client(char *host_name, char*port); +Client *ssp_connectionless_client(char *host_name, char*port, Protocol_state *p_state); void *ssp_connectionless_client_task(void *params); - -void ssp_sendto(Client client); +void ssp_printf(char*stuff, ...); +void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index c81ac0f..03da52a 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -1,41 +1,42 @@ #ifndef PROTOCOL_H #define PROTOCOL_H +#include "utils.h" - - - -typedef struct client { +typedef struct response { int sfd; - char *msg; //this is type (struct sockaddr_in) in posix void *addr; int packet_len; +} Response; - char* host_name; - char* client_port; +typedef struct client { + char *host_name; + char *client_port; void *client_handle; void *client_thread_attributes; - - + int is_active; } Client; typedef struct protocol_state { int packet_size; - - char* server_port; + char *server_port; void *server_handle; void *server_thread_attributes; + List *client_list; -} Protocol_state; + //temperary until client list works fully + Client *client; +} Protocol_state; -void packet_handler(void); +void packet_handler_server(Response res); +void packet_handler_client(Response res); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index 4fc3ab2..597d425 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -55,7 +55,9 @@ void udpSelectServer(char *port, int packet_len, ------------------------------------------------------------------------------*/ -void udpClient(char *hostname, char*port); +void udpClient(char *hostname, char*port, void *callbackParams, + int (*onRecv)(int sfd, char *msg, struct sockaddr_in client, void *callbackParams) +); #endif //SERVER_H diff --git a/Program/include/utils.h b/Program/include/utils.h index 5011bc8..051b80d 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -38,25 +38,25 @@ typedef struct NODE Purpose: This is a LIST struct that contains functions useful for doing linked list functionality. ------------------------------------------------------------------------------*/ -typedef struct LIST +typedef struct List { struct NODE *head; struct NODE *tail; - void (*add)(struct LIST *list, void *element); - int (*remove)(struct LIST *list, int (*f)(void *element, void *args), void *args); - void (*print)(struct LIST *list, void (*f)(void *element, void *args), void *args); - void (*free)(struct LIST *list, void (*f)(void *element)); + int (*add)(struct List *list, void *element); + int (*remove)(struct List *list, int (*f)(void *element, void *args), void *args); + void (*print)(struct List *list, void (*f)(void *element, void *args), void *args); + void (*free)(struct List *list, void (*f)(void *element)); //returns a void pointer that should be cast to the type - void *(*find)(struct LIST *list, int (*f)(void *element, void *args), void *args); -} LIST; + void *(*find)(struct List *list, int (*f)(void *element, void *args), void *args); +} List; /*------------------------------------------------------------------------------ Purpose: This function initializes a linked list LIST *. Perameters: empty is just for the compiler errors, TODO use it for something Return: returns a pointer to an initilized LIST * ------------------------------------------------------------------------------*/ -LIST *List(void); +List *linked_list(void); /*------------------------------------------------------------------------------ Purpose: This function checks to see if the memory is allocated, @@ -65,7 +65,7 @@ LIST *List(void); int notOkToFail: Return: returns nothing ------------------------------------------------------------------------------*/ -void checkAlloc(void *mem, int notOkToFail); +int checkAlloc(void *mem, int notOkToFail); /*------------------------------------------------------------------------------ Purpose: This function is used to make a configuration struct from the diff --git a/Program/src/main.c b/Program/src/main.c index e80bdde..8af6ab9 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -6,16 +6,21 @@ #include "port.h" #include #include "protocol_handler.h" +#include "utils.h" + + int main() { - Protocol_state* p_state = ssp_connectionless_server("1111"); - sleep(1); - Client *client = ssp_connectionless_client("127.0.0.1", "1111"); + Protocol_state *p_state = ssp_connectionless_server("1111"); + //p_state->client_list = linked_list(); + sleep(1); + Client *client = ssp_connectionless_client("127.0.0.1", "1111", p_state); + //p_state->client_list->add(p_state->client_list, client); + ssp_cleanup_client(client); ssp_cleanup(p_state); - return 0; } diff --git a/Program/src/makefile b/Program/src/makefile index 15987a1..605b0ff 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -7,6 +7,7 @@ CC = gcc CFILES += port.c CFILES += utils.c CFILES += server.c #used for poxix port +CFILES += protocol_handler.c #entrypoint MAIN = main diff --git a/Program/src/port.c b/Program/src/port.c index 0e94786..79cf119 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -13,8 +13,24 @@ #include #include #include + #include + #include + #endif +#include "protocol_handler.h" + + + +void ssp_printf(char*stuff, ...) { + #ifdef POSIX_PORT + va_list args; + va_start(args, stuff); + vfprintf(stdout, stuff, args); + va_end (args); + #endif +} + void ssp_error(char *msg) { @@ -24,49 +40,74 @@ void ssp_error(char *msg) { } -void ssp_sendto(Client client) { + + +void ssp_sendto(Response res) { #ifdef POSIX_PORT - struct sockaddr* addr = (struct sockaddr*) client.addr; - int n = sendto(client.sfd, client.msg, client.packet_len, 0, addr, sizeof(*addr)); + struct sockaddr* addr = (struct sockaddr*) res.addr; + int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); if (n < 0) ssp_error("ERROR in ssp_sendto"); #endif } -//this function is a callback when using my silly posix port -static int on_recv_posix(int sfd, char *msg, struct sockaddr_storage addr, void *other) { +//this function is a callback when using my posix port +static int on_recv_server(int sfd, char *msg, struct sockaddr_storage addr, void *other) { + + #ifdef POSIX_PORT Protocol_state *state = (Protocol_state *) other; struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; - Client new_client; - new_client.msg = "stuffffff"; - new_client.addr = posix_client; - new_client.sfd = sfd; - new_client.packet_len = state->packet_size; + Response res; + res.addr = posix_client; + res.sfd = sfd; + res.packet_len = state->packet_size; - printf("msg recv: %s\n", msg); - printf("addr %d port%d\n",ntohl(((struct in_addr*) posix_client)->s_addr), ntohs(posix_client->sin_port)); - ssp_sendto(new_client); + ssp_printf("Server received: %s\n", msg); + //printf("addr %d port%d\n",ntohl(((struct in_addr*) posix_client)->s_addr), ntohs(posix_client->sin_port)); + packet_handler_server(res); + return 0; - return 1; + #endif } -//this function is a callback when using my silly posix ports -static int on_time_out_posix(void *other) { - return 1; +static int on_recv_client(int sfd, char *msg, struct sockaddr_in addr, void *other) { + + #ifdef POSIX_PORT + + Protocol_state *p_state = (Protocol_state *) other; + struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + + Response res; + res.addr = posix_client; + res.sfd = sfd; + res.packet_len = p_state->packet_size; + + ssp_printf("Client received: %s\n", msg); + + packet_handler_client(res); + return 0; + + #endif } +//this function is a callback when using my posix ports +static int on_time_out_posix(void *other) { + return 0; +} + void *ssp_connectionless_server_task(void *params) { + Protocol_state* state = (Protocol_state*) params; #ifdef POSIX_PORT - udpSelectServer(state->server_port, PACKET_LEN, on_recv_posix, on_time_out_posix, state); + udpSelectServer(state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, state); #endif return NULL; @@ -75,132 +116,156 @@ void *ssp_connectionless_server_task(void *params) { Protocol_state* ssp_connectionless_server(char *port) { #ifdef POSIX_PORT - Protocol_state *state = calloc(sizeof(Protocol_state), 1); - state->packet_size = PACKET_LEN; - - pthread_t *handler = calloc(sizeof(pthread_t), 1); - checkAlloc(handler, 1); + Protocol_state *state = calloc(sizeof(Protocol_state), 1); + state->packet_size = PACKET_LEN; - pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); - checkAlloc(attr, 1); + pthread_t *handler = calloc(sizeof(pthread_t), 1); + checkAlloc(handler, 1); - state->server_port = calloc(sizeof(char), 10); - checkAlloc(state->server_port, 1); + pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); + checkAlloc(attr, 1); - strncpy (state->server_port, port, 10); + state->server_port = calloc(sizeof(char), 10); + checkAlloc(state->server_port, 1); - int err = pthread_attr_init(attr); - if (0 != err) - perror("pthread_init failed"); + strncpy (state->server_port, port, 10); + int err = pthread_attr_init(attr); + if (0 != err) + perror("pthread_init failed"); - size_t stack_size = STACK_ALLOCATION; - err = pthread_attr_setstacksize(attr, stack_size); - if (0 != err) - perror("ERROR pthread_attr_setstacksize %d"); + size_t stack_size = STACK_ALLOCATION; + err = pthread_attr_setstacksize(attr, stack_size); - if (EINVAL == err) { - printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); - } + if (0 != err) + perror("ERROR pthread_attr_setstacksize %d"); - err = pthread_create(handler, attr, ssp_connectionless_server_task, state); - if (0 != err) - perror("ERROR pthread_create"); + if (EINVAL == err) { + printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + } + err = pthread_create(handler, attr, ssp_connectionless_server_task, state); + if (0 != err) + perror("ERROR pthread_create"); - state->server_handle = handler; - state->server_thread_attributes = attr; - return state; + state->server_handle = handler; + state->server_thread_attributes = attr; + return state; #endif } + void *ssp_connectionless_client_task(void* params){ - Client *client = (Client*) params; - udpClient(client->host_name, client->client_port); + Protocol_state *p_state = (Protocol_state *) params; + + // TODO find a client function p_state->client_list->find() + + udpClient(p_state->client->host_name, p_state->client->client_port, p_state, on_recv_client); return NULL; } -Client *ssp_connectionless_client(char *host_name, char *port) { + +Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p_state) { #ifdef POSIX_PORT - int port_len = strnlen(port, 100) + 1; - int host_len = strnlen(host_name, 100) + 1; + int port_len = strnlen(port, 100) + 1; + int host_len = strnlen(host_name, 100) + 1; - Client *client = calloc(sizeof(Client), 1); - checkAlloc(client, 1); + Client *client = calloc(sizeof(Client), 1); + checkAlloc(client, 1); - client->host_name = calloc(sizeof(char), host_len); - checkAlloc(client->host_name, 1); + client->host_name = calloc(sizeof(char), host_len); + checkAlloc(client->host_name, 1); - client->client_port = calloc(sizeof(char), port_len); - checkAlloc(client->client_port, 1); + client->client_port = calloc(sizeof(char), port_len); + checkAlloc(client->client_port, 1); - pthread_t *handler = calloc(sizeof(pthread_t), 1); - checkAlloc(handler, 1); + pthread_t *handler = calloc(sizeof(pthread_t), 1); + checkAlloc(handler, 1); - pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); - checkAlloc(attr, 1); + pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); + checkAlloc(attr, 1); - strncpy(client->client_port, port, port_len); - strncpy(client->host_name, host_name, host_len); + strncpy(client->client_port, port, port_len); + strncpy(client->host_name, host_name, host_len); - int err = pthread_attr_init(attr); - if (0 != err) - perror("pthread_init failed"); + int err = pthread_attr_init(attr); + if (0 != err) + perror("pthread_init failed"); - size_t stack_size = STACK_ALLOCATION; - err = pthread_attr_setstacksize(attr, stack_size); + size_t stack_size = STACK_ALLOCATION; + err = pthread_attr_setstacksize(attr, stack_size); - if (0 != err) - perror("ERROR pthread_attr_setstacksize %d"); + if (0 != err) + perror("ERROR pthread_attr_setstacksize %d"); - if (EINVAL == err) { - printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); - } + if (EINVAL == err) { + printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + } - err = pthread_create(handler, attr, ssp_connectionless_client_task, client); - if (0 != err) - perror("ERROR pthread_create"); + client->client_handle = handler; + client->client_thread_attributes = attr; + //TODO make list work right + //p_state->client_list->add(p_state->client_list, client); + + + p_state->client = client; + err = pthread_create(handler, attr, ssp_connectionless_client_task, p_state); + if (0 != err) + perror("ERROR pthread_create"); - client->client_handle = handler; - client->client_thread_attributes = attr; - return client; + return client; #endif } -void ssp_cleanup(Protocol_state *state) { + +static void cleanup_list(void *client) { + + Client *client_pointer = (Client*) client; + ssp_cleanup_client(client_pointer); +} + + + +void ssp_cleanup(Protocol_state *p_state) { #ifdef POSIX_PORT - pthread_t * handle = (pthread_t*) state->server_handle; + pthread_t * handle = (pthread_t*) p_state->server_handle; + pthread_join(*handle, NULL); + + //p_state->client_list->free(p_state->client_list, cleanup_list); + + free(p_state->server_handle); + free(p_state->server_port); + free(p_state->server_thread_attributes); + free(p_state); - pthread_join(*handle, NULL); - free(state->server_handle); - free(state->server_port); - free(state->server_thread_attributes); - free(state); #endif } + + + void ssp_cleanup_client(Client *client) { - #ifdef POSIX_PORT - pthread_t * handle = (pthread_t*) client->client_handle; - - pthread_join(*handle, NULL); - free(client->host_name); - free(client->client_handle); - free(client->client_port); - free(client->client_thread_attributes); - free(client); +#ifdef POSIX_PORT + pthread_t * handle = (pthread_t*) client->client_handle; + + pthread_join(*handle, NULL); + free(client->host_name); + free(client->client_handle); + free(client->client_port); + free(client->client_thread_attributes); + free(client); #endif diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 8c997a6..a7ee5e8 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -1,13 +1,17 @@ #include "port.h" +#include "protocol_handler.h" +void packet_handler_server(Response res) { + res.msg = "shutupa you\n"; + ssp_sendto(res); +} - -void packet_handler() { - - printf("stuff\n"); +void packet_handler_client(Response res) { + res.msg = "noa youa shuta up!\n"; + ssp_sendto(res); } \ No newline at end of file diff --git a/Program/src/server.c b/Program/src/server.c index f6823b8..0eca8a3 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -143,7 +143,9 @@ void udpSelectServer(char* port, int packet_len, FD_ZERO(&masterReadFds); FD_SET(STDIN_FILENO, &masterReadFds); FD_SET(sfd, &masterReadFds); - char *buff = calloc(sizeof(char), new_packet_len); + + int buff_size = new_packet_len + 10; + char *buff = calloc(sizeof(char), buff_size); checkAlloc(buff, 1); struct sockaddr_storage *client; @@ -160,9 +162,11 @@ void udpSelectServer(char* port, int packet_len, fd_set readFds = masterReadFds; int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); - if (exit_now) + if (exit_now){ + printf("exiting server thread\n"); break; - + } + if (nrdy == -1) { perror("select"); @@ -188,8 +192,8 @@ void udpSelectServer(char* port, int packet_len, { perror("recv failed"); } - else if (count == sizeof(buff)) - { + else if (count >= buff_size) + { printf("packet too large\n"); continue; } @@ -209,16 +213,17 @@ void udpSelectServer(char* port, int packet_len, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void udpClient(char *hostname, char*port //,void *other, - //int (*onSend)(int sfd, struct sockaddr_storage client, void *other), - //int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), +void udpClient(char *hostname, char*port, void *callbackParams, + int (*onRecv)(int sfd, char *msg, struct sockaddr_in client, void *callbackParams) ) { - int sfd, n, port_val; - int serverlen; + int sfd, count, port_val, n; + socklen_t serverlen; struct sockaddr_in serveraddr; struct hostent *server; - char *buff = calloc(sizeof(char), new_packet_len); + + int buff_size = new_packet_len + 10; + char *buff = calloc(sizeof(char), buff_size); checkAlloc(buff, 1); prepareSignalHandler(); @@ -241,30 +246,44 @@ void udpClient(char *hostname, char*port //,void *other, bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); serveraddr.sin_port = htons(port_val); - char* msg = "some stuff to send"; - /* get a message from the user */ + char *msg = "first message?\n"; - memcpy(buff, msg, strnlen(msg, new_packet_len)); + serverlen = sizeof(serveraddr); + + /* send the message to the server */ + n = sendto(sfd, msg, (size_t) strnlen(msg, new_packet_len), 0, (struct sockaddr*)&serveraddr, serverlen); + if (n < 0) + perror("ERROR in sendto"); + for (;;) { if (exit_now) break; - /* send the message to the server */ - serverlen = sizeof(serveraddr); - n = sendto(sfd, buff, (size_t) strnlen(buff, new_packet_len), 0, (struct sockaddr*)&serveraddr, serverlen); - if (n < 0) - perror("ERROR in sendto"); + - sleep(2); + + sleep(1); /* print the server's reply */ - /* - n = recvfrom(sockfd, buf, BUFSIZE, 0, &serveraddr, &serverlen); - if (n < 0) - error("ERROR in recvfrom"); - printf("Echo from server: %s\n", buf); - */ + + count = recvfrom(sfd, buff, new_packet_len, MSG_DONTWAIT, (struct sockaddr*)&serveraddr, &serverlen); + + if (count == -1) + { + perror("recv failed"); + } + else if (count >= buff_size) + { + printf("packet too large\n"); + continue; + } + else + { + if (onRecv(sfd, buff, serveraddr, callbackParams) == -1) + printf("recv failed\n"); + } + } free(buff); close(sfd); diff --git a/Program/src/utils.c b/Program/src/utils.c index 1e39d32..3098440 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -18,13 +18,17 @@ to use for general functionality. #include //see header file -void checkAlloc(void *mem, int notOkToFail) +int checkAlloc(void *mem, int notOkToFail) { if (mem == NULL && notOkToFail) { perror("malloc"); exit(EXIT_FAILURE); } + else if(mem == NULL && !notOkToFail) { + return 1; + } + return 0; } //see header file @@ -117,7 +121,7 @@ static NODE *createNode(void *element) This function adds a new element into the linked list. returns nothing. ------------------------------------------------------------------------------*/ -static void addElement(LIST *list, void *element) +static int addElement(List *list, void *element) { NODE *newNode = createNode(element); @@ -128,6 +132,7 @@ static void addElement(LIST *list, void *element) tail->prev->next = newNode; tail->prev = newNode; + return 0; } /*------------------------------------------------------------------------------ @@ -135,7 +140,7 @@ static void addElement(LIST *list, void *element) to print out an element. ------------------------------------------------------------------------------*/ -static void printList(LIST *list, void (*f)(void *element, void *args), void *args) +static void printList(List *list, void (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; while (cur->next != NULL) @@ -151,7 +156,7 @@ static void printList(LIST *list, void (*f)(void *element, void *args), void *ar and -1 if item not found. ------------------------------------------------------------------------------*/ -static int removeElement(LIST *list, int (*f)(void *element, void *args), void *args) +static int removeElement(List *list, int (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; while (cur->next != NULL) @@ -176,7 +181,7 @@ static int removeElement(LIST *list, int (*f)(void *element, void *args), void * a function that frees and elemnent. Returns nothing, ------------------------------------------------------------------------------*/ -static void freeList(LIST *list, void (*f)(void *element)) +static void freeList(List *list, void (*f)(void *element)) { NODE *cur = list->head->next; while (cur->next != NULL) @@ -184,7 +189,6 @@ static void freeList(LIST *list, void (*f)(void *element)) NODE *n = cur; cur = cur->next; f(n->element); - free(n->element); free(n); } free(list->head); @@ -197,7 +201,7 @@ static void freeList(LIST *list, void (*f)(void *element)) failure. The return value should be cast to the element type. ------------------------------------------------------------------------------*/ -static void *findElement(LIST *list, int (*f)(void *element, void *args), void *args) +static void *findElement(List *list, int (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; @@ -215,10 +219,10 @@ static void *findElement(LIST *list, int (*f)(void *element, void *args), void * //see header file -LIST *List() +List *linked_list() { - LIST *newList = calloc(sizeof(LIST), 1); - checkAlloc(newList, 1); + List *newList = calloc(sizeof(List), 1); + checkAlloc(newList, 0); newList->head = createNode(NULL); newList->tail = createNode(NULL); @@ -237,3 +241,20 @@ LIST *List() return newList; } + + +//TODO write an array list +/* +int add_element_array_list(List *list, void *element) { +} + +List *array_list() { + + List *new_list = calloc(sizeof(List), 1); + if (checkAlloc(new_list, 0)); + return NULL; + +} + +*/ + From 4ab8fcd7a7dfe1978cbc7ae5c1d497e06b42dc8c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 25 Feb 2019 16:48:49 -0700 Subject: [PATCH 008/400] Add protocol specs --- Program/include/packet.h | 158 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 151 insertions(+), 7 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index e05dd12..ac487cf 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -10,6 +10,8 @@ #define PACKET_MAX_LEN 524512 #define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes + + typedef struct pdu_header{ unsigned int version: 3; unsigned int PDU_type: 1; //0 File directive, 1 File Data, @@ -22,17 +24,159 @@ typedef struct pdu_header{ unsigned int length_of_entity_IDs: 3; unsigned int reserved_bit_2: 1; unsigned int transaction_seq_num_len: 3; //number of octets in sequence number, 0 is one octet - //these are variable in size, and will get memory allocated based on the length variables above void *source_id; - void *transaction_seq_num; + void *transaction_sequence_number; void *destination_id; } Pdu_header; -typedef struct packet { - Pdu_header header; - uint8_t *data; - uint8_t *crc; -} Packet; +typedef struct originating_tranaction_id_message { + + unsigned int reserved_bit_0 : 1; + unsigned int length_of_entity_id : 3; + unsigned int reserved_bit_1 : 1; + unsigned int length_of_sequence_number: 3; + + //variable length of bits + void *source_id; + void *transaction_sequence_number; + +} Originating_tranaction_id_message; + + +/*------------------------------------------------------------------------------ + The following are the different TLV parameters and types associated + filestore_request: type 0x00 + value: struct filestore_request + filestore_response: type 0x01 + value: struct filestore_response + + //TODO + Messages to user. + Fault Handler overrides. + Flow Label. + +------------------------------------------------------------------------------*/ + + +typedef struct lv { + unsigned int length : 8; + // size is 8 * length + void *value; +} LV; + +typedef struct tlv { + unsigned int type : 8; + unsigned int length : 8; + // size is 8 * length + void *value; +} TLV; + + +//---------------------------filestore_request---------------------------------- +//action codes +#define CREATE_FILE 0x00 +#define DELETE_FILE 0x01 +#define RENAME_FILE 0x02 //second filename present +#define APPEND_FILE 0x03 //second filename present +#define REPLACE_FILE 0x04 //second filename present +#define CREATE_DIRECTORY 0x05 +#define REMOVE_DIRECTORY 0x06 +#define DENY_FILE 0x07 //delete if present +#define DENY_DIRECTORY 0x08 //delete if present + +// The type for this TLV is 0x00 +typedef struct filestore_request { + unsigned int action_code: 4; + unsigned int spare : 4; + LV first_file_name; + LV second_file_name; //only present in #RENAME_FILE, APPEND_FILE, REPLACE_FILE + + +} Filestore_request; + + +//---------------------------filestore_response--------------------------------- +#define SUCCESS 0x00 +#define CREATE_NOT_ALLOWED 0x01 +#define FILE_DOES_NOT_EXIST 0x01 +#define OLD_FILE_NAME_DOES_NOT_EXIST 0x01 +#define DELETE_NOT_ALLOWED 0x02 +#define NEW_FILE_NAME_ALREADY_EXISTS 0x02 +#define RENAME_NOT_ALLOWED 0x04 +#define FILE_NAME_1_DOES_NOT_EXIST 0x01 +#define FILE_NAME_2_DOES_NOT_EXIST 0x02 +#define APPEND_NOT_ALLOWED 0x04 +#define REPLACE_NOT_ALLOWED 0x04 +#define DIRECTORY_CANNOT_BE_CREATED 0x01 +#define DIRECTORY_DOES_NOT_EXIST 0x01 +#define NOT_PERFORMED 0x0F + + +// The type for this TLV is 0x01 +typedef struct filestore_response { + unsigned int action_code: 4; + unsigned int status_code : 4; + LV first_file_name; + LV second_file_name; //only present in #RENAME_FILE, APPEND_FILE, REPLACE_FILE + + LV filestore_message; + /*LV length field indicates zero length and LV value field is + omitted when there is no Filestore Message parameter present. */ + +} Filestore_response; + + + +/*------------------------------------------------------------------------------ + The following are the different PDUs, PDUs are what is included in the + data portion of the PDU_header these include: + + File directive PDUs: + File directive PDUs all start with a 1 byte directive code, + followed by one of the following various pdu types: + + - pdu_meta_data + + + +------------------------------------------------------------------------------*/ + +//directive_codes 00 - 03, and 0D-FF are reserved +#define EOF_PDU 0x04 +#define FINISHED_PDU 0x05 +#define ACK_PDU 0x06 +#define META_DATA_PDU 0x07 +#define NAK_PDU 0x08 +#define PROMPT_PDU 0x09 +#define KEEP_ALIVE_PDU 0x0C + + +typedef struct pdu_directive { + uint8_t directive_code; + void *pdu_type; +} Pdu_directive; + + +typedef struct pdu_meta_data { + + unsigned int segmentation_control : 1; //0 Record boundaries respeced, 1 not respected + unsigned int reserved_bits: 7; + unsigned int file_size : 32; //length of the file in octets, set all 0 for unbounded size + + LV source_file; + LV destination_file; + + /* + Options include: + Filestore requests, + Messages to user. + Fault Handler overrides. + Flow Label. + */ + + TLV *options; + +} Pdu_meta_data; #endif \ No newline at end of file From 061605d2a10b5a1f124691aa2dc64fa5456b4c91 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 25 Feb 2019 16:49:29 -0700 Subject: [PATCH 009/400] Add variable buffer sizes to client --- Program/include/protocol_handler.h | 29 ++++++-- Program/include/server.h | 12 ++-- Program/src/main.c | 9 +-- Program/src/port.c | 54 ++++++++------- Program/src/protocol_handler.c | 71 ++++++++++++++++++- Program/src/server.c | 73 ++++++++++++-------- Program/src/utils.c | 9 ++- Program/test/main.c | 107 +++++++++++++++++++++++++++++ 8 files changed, 289 insertions(+), 75 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 03da52a..3c302b4 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -2,41 +2,58 @@ #ifndef PROTOCOL_H #define PROTOCOL_H #include "utils.h" +#include "packet.h" typedef struct response { int sfd; char *msg; //this is type (struct sockaddr_in) in posix void *addr; - int packet_len; + //getting rid of this soon in favour of client based packet sizes + uint32_t packet_len; } Response; +typedef struct request { + uint8_t request_primitive; + uint32_t transaction_id; +} Request; + + typedef struct client { char *host_name; char *client_port; void *client_handle; void *client_thread_attributes; - int is_active; + uint32_t packet_len; + uint8_t is_active; + } Client; typedef struct protocol_state { - int packet_size; + uint32_t packet_size; char *server_port; void *server_handle; void *server_thread_attributes; - List *client_list; + List *client_list; //temperary until client list works fully Client *client; } Protocol_state; +int cleanup_list(void *element); +int list_remove(void *element, void *args); +void list_print(void *element, void *args); +int list_find(void *element, void *args); +void list_free(void *element); + + -void packet_handler_server(Response res); -void packet_handler_client(Response res); +void packet_handler_server(Response res, Protocol_state *p_state); +void packet_handler_client(Response res, Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index 597d425..829496c 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -49,15 +49,15 @@ void udpSelectServer(char *port, int packet_len, /*-----------------------------CALLBACK onTimeOut------------------------------- Purpose: This is a simple udp client - Perameters: hostname is the name of an address eg, 127.0.0.1, port is the port + Perameters: hostname is the name of an address eg, 127.0.0.1, port is the por + channel_size is the size of the channel in bytes eg, 1111 Return: None ------------------------------------------------------------------------------*/ +void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, + int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); -void udpClient(char *hostname, char*port, void *callbackParams, - int (*onRecv)(int sfd, char *msg, struct sockaddr_in client, void *callbackParams) -); - - + #endif //SERVER_H diff --git a/Program/src/main.c b/Program/src/main.c index 8af6ab9..f85c586 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -13,13 +13,14 @@ int main() { Protocol_state *p_state = ssp_connectionless_server("1111"); - //p_state->client_list = linked_list(); + p_state->client_list = linked_list(); sleep(1); - Client *client = ssp_connectionless_client("127.0.0.1", "1111", p_state); - //p_state->client_list->add(p_state->client_list, client); + //auto adds client to the client list + ssp_connectionless_client("127.0.0.1", "1111", p_state); - ssp_cleanup_client(client); + p_state->client_list->free(p_state->client_list, list_free); + ssp_cleanup(p_state); return 0; } diff --git a/Program/src/port.c b/Program/src/port.c index 79cf119..a671168 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -40,8 +40,6 @@ void ssp_error(char *msg) { } - - void ssp_sendto(Response res) { #ifdef POSIX_PORT @@ -58,24 +56,24 @@ static int on_recv_server(int sfd, char *msg, struct sockaddr_storage addr, void #ifdef POSIX_PORT - Protocol_state *state = (Protocol_state *) other; + Protocol_state *p_state = (Protocol_state *) other; struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; Response res; res.addr = posix_client; res.sfd = sfd; - res.packet_len = state->packet_size; + res.packet_len = p_state->packet_size; ssp_printf("Server received: %s\n", msg); //printf("addr %d port%d\n",ntohl(((struct in_addr*) posix_client)->s_addr), ntohs(posix_client->sin_port)); - packet_handler_server(res); + packet_handler_server(res, p_state); return 0; #endif } -static int on_recv_client(int sfd, char *msg, struct sockaddr_in addr, void *other) { +static int on_recv_client(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in addr, void *other) { #ifdef POSIX_PORT @@ -89,12 +87,31 @@ static int on_recv_client(int sfd, char *msg, struct sockaddr_in addr, void *oth ssp_printf("Client received: %s\n", msg); - packet_handler_client(res); + packet_handler_client(res, p_state); return 0; #endif } +static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { + + + #ifdef POSIX_PORT + Protocol_state *p_state = (Protocol_state *) other; + struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + + Response res; + res.addr = posix_client; + res.sfd = sfd; + res.packet_len = p_state->packet_size; + res.msg = "some shit\n"; + + ssp_sendto(res); + + return 0; + #endif + +} //this function is a callback when using my posix ports static int on_time_out_posix(void *other) { @@ -163,8 +180,7 @@ void *ssp_connectionless_client_task(void* params){ Protocol_state *p_state = (Protocol_state *) params; // TODO find a client function p_state->client_list->find() - - udpClient(p_state->client->host_name, p_state->client->client_port, p_state, on_recv_client); + udpClient(p_state->client->host_name, p_state->client->client_port, PACKET_LEN, p_state, p_state, on_send_client, on_recv_client); return NULL; } @@ -210,9 +226,8 @@ Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p client->client_handle = handler; client->client_thread_attributes = attr; - //TODO make list work right - //p_state->client_list->add(p_state->client_list, client); - + //add client to a new list of currently active clients + p_state->client_list->add(p_state->client_list, client); p_state->client = client; err = pthread_create(handler, attr, ssp_connectionless_client_task, p_state); @@ -226,38 +241,25 @@ Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p } -static void cleanup_list(void *client) { - - Client *client_pointer = (Client*) client; - ssp_cleanup_client(client_pointer); -} - - - void ssp_cleanup(Protocol_state *p_state) { #ifdef POSIX_PORT pthread_t * handle = (pthread_t*) p_state->server_handle; pthread_join(*handle, NULL); - //p_state->client_list->free(p_state->client_list, cleanup_list); - free(p_state->server_handle); free(p_state->server_port); free(p_state->server_thread_attributes); free(p_state); - #endif } - - void ssp_cleanup_client(Client *client) { -#ifdef POSIX_PORT + #ifdef POSIX_PORT pthread_t * handle = (pthread_t*) client->client_handle; pthread_join(*handle, NULL); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index a7ee5e8..2501e43 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -4,14 +4,79 @@ #include "protocol_handler.h" -void packet_handler_server(Response res) { + +int list_remove(void *element, void *args) { + + /* + int id = *(int *) args; + struct myStruct *st = (struct myStruct *)element; + + if (id == ((struct myStruct*) element)->id) { + free(st); + return 1; + + } + */ + + return 0; +} + +void list_print(void *element, void *args) { + +} + + +int list_find(void *element, void *args) { +/* + int id = *(int *) args; + if (id == ((struct myStruct*) element)->id) + return 1; + return 0; + */ +} + +void list_free(void *element) { + Client * client = (Client*) element; + ssp_cleanup_client(client); +} + +void packet_handler_server(Response res, Protocol_state *p_state) { + res.msg = "shutupa you\n"; ssp_sendto(res); } -void packet_handler_client(Response res) { +void packet_handler_client(Response res, Protocol_state *p_state) { res.msg = "noa youa shuta up!\n"; ssp_sendto(res); +} + +//Omission of source and destination filenames shall indicate that only Meta +//data will be delivered + +int put_request(char *dest_cfdp_id, + char *source_file_name, + char *destination_file_name, + uint8_t segmentation_control, + uint8_t fault_handler_overides, + uint8_t flow_lable, + uint8_t transmission_mode, + char* messages_to_user, + char* filestore_requests + ) { + + +} -} \ No newline at end of file +/* +(destination CFDP entity ID, +[source file name], +[destination file name], +[segmentation control], +[fault handler overrides], +[flow label], +[transmission mode], +[messages to user], +[filestore requests]) +*/ \ No newline at end of file diff --git a/Program/src/server.c b/Program/src/server.c index 0eca8a3..4dd5297 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -34,7 +34,6 @@ This is my file for server.c. It develops a udp server for select. static int exit_now = 0; -static int new_packet_len; //this code is reused from assignment 1, with small changes @@ -136,7 +135,6 @@ void udpSelectServer(char* port, int packet_len, void *other) { int sfd = prepareUdpHost(port); - new_packet_len = packet_len; prepareSignalHandler(); fd_set masterReadFds; @@ -144,7 +142,7 @@ void udpSelectServer(char* port, int packet_len, FD_SET(STDIN_FILENO, &masterReadFds); FD_SET(sfd, &masterReadFds); - int buff_size = new_packet_len + 10; + int buff_size = packet_len + 10; char *buff = calloc(sizeof(char), buff_size); checkAlloc(buff, 1); @@ -186,7 +184,7 @@ void udpSelectServer(char* port, int packet_len, { socklen_t client_len = sizeof(*client); - int count = recvfrom(sfd, buff, new_packet_len, 0, (struct sockaddr*)client, &client_len); + int count = recvfrom(sfd, buff, packet_len, 0, (struct sockaddr*)client, &client_len); if (count == -1) { @@ -213,8 +211,9 @@ void udpSelectServer(char* port, int packet_len, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void udpClient(char *hostname, char*port, void *callbackParams, - int (*onRecv)(int sfd, char *msg, struct sockaddr_in client, void *callbackParams) +void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, + int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams) ) { int sfd, count, port_val, n; @@ -222,8 +221,13 @@ void udpClient(char *hostname, char*port, void *callbackParams, struct sockaddr_in serveraddr; struct hostent *server; - int buff_size = new_packet_len + 10; - char *buff = calloc(sizeof(char), buff_size); + uint32_t *buff_size = malloc(sizeof(uint32_t)); + *buff_size = packet_len + 10; + + + uint32_t prev_buff_size = *buff_size; + + char *buff = calloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); prepareSignalHandler(); @@ -249,9 +253,9 @@ void udpClient(char *hostname, char*port, void *callbackParams, char *msg = "first message?\n"; serverlen = sizeof(serveraddr); - + /* send the message to the server */ - n = sendto(sfd, msg, (size_t) strnlen(msg, new_packet_len), 0, (struct sockaddr*)&serveraddr, serverlen); + n = sendto(sfd, msg, (size_t) strnlen(msg, packet_len), 0, (struct sockaddr*)&serveraddr, serverlen); if (n < 0) perror("ERROR in sendto"); @@ -260,31 +264,46 @@ void udpClient(char *hostname, char*port, void *callbackParams, if (exit_now) break; - - + if (*buff_size != prev_buff_size) { + prev_buff_size = *buff_size; + + if(checkAlloc(realloc(buff, *buff_size), 0)){ + prev_buff_size = *buff_size; + } + else { + printf("packet too large, cannot resize buffer\n"); + } + } sleep(1); /* print the server's reply */ + if (onSend(sfd, serveraddr, onSendParams)) + printf("send failed\n"); - count = recvfrom(sfd, buff, new_packet_len, MSG_DONTWAIT, (struct sockaddr*)&serveraddr, &serverlen); - if (count == -1) - { - perror("recv failed"); - } - else if (count >= buff_size) - { - printf("packet too large\n"); - continue; - } - else - { - if (onRecv(sfd, buff, serveraddr, callbackParams) == -1) - printf("recv failed\n"); - } + + count = recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, (struct sockaddr*)&serveraddr, &serverlen); + + if (count == -1) + { + perror("recv failed"); + } + else if (count >= *buff_size) + { + printf("packet too large\n"); + continue; + } + else + { + if (onRecv(sfd, buff, buff_size, serveraddr, onRecvParams) == -1) + printf("recv failed\n"); + } } + + free(buff_size); free(buff); close(sfd); } + diff --git a/Program/src/utils.c b/Program/src/utils.c index 3098440..8b1bf1f 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -26,9 +26,9 @@ int checkAlloc(void *mem, int notOkToFail) exit(EXIT_FAILURE); } else if(mem == NULL && !notOkToFail) { - return 1; + return 0; } - return 0; + return 1; } //see header file @@ -37,6 +37,7 @@ CONFIG *configuration(int argc, char **argv) int ch; CONFIG *conf = calloc(sizeof(CONFIG), 1); checkAlloc(conf, 1); + conf->numOfDecks = 2; conf->startingMoney = 100; conf->timer = 15; @@ -176,6 +177,8 @@ static int removeElement(List *list, int (*f)(void *element, void *args), void * return -1; } + + /*------------------------------------------------------------------------------ frees the linked list. Takes a free function that is a function pointer to a function that frees and elemnent. Returns nothing, @@ -243,7 +246,7 @@ List *linked_list() } -//TODO write an array list +//TODO write an array /* int add_element_array_list(List *list, void *element) { } diff --git a/Program/test/main.c b/Program/test/main.c index e69de29..c33be08 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -0,0 +1,107 @@ + + +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +struct myStruct { + int id; + int b; +}; + + +static int list_remove(void *element, void *args) { + + int id = *(int *) args; + struct myStruct *st = (struct myStruct *)element; + + if (id == ((struct myStruct*) element)->id) { + free(st); + return 1; + + } + return 0; +} + +static void list_print(void *element, void *args) { + + struct myStruct *st = (struct myStruct *)element; + + printf("list print: %d\n", st->id); + + +} +static int find(void *element, void *args) { + + int id = *(int *) args; + if (id == ((struct myStruct*) element)->id) + return 1; + return 0; +} + + +static void list_free(void *element) { + + free(element); +} + + +int main () { + + + List *list = linked_list(); + + +//static void *findElement(List *list, int (*f)(void *element, void *args), void *args) + + struct myStruct *st = malloc(sizeof(struct myStruct)); + struct myStruct *st2 = malloc(sizeof(struct myStruct)); + struct myStruct *st3 = malloc(sizeof(struct myStruct)); + + st->id = 1; + st->b = 2; + + st2->id = 2; + st2->b = 3; + + st3->id = 3; + st3->b = 4; + + list->add(list, st); + list->add(list, st2); + list->add(list, st3); + + + int id = 1; + struct myStruct *found = list->find(list, find, &id); + printf("found %d\n", found->b); + + id = 2; + found = list->find(list, find, &id); + printf("found %d\n", found->b); + + id = 3; + found = list->find(list, find, &id); + printf("found %d\n", found->b); + + + list->print(list, list_print, NULL); + + + list->remove(list, list_remove, &id); + + + list->print(list, list_print, NULL); + + + list->free(list, list_free); + + return 0; +} \ No newline at end of file From 151934149ac17af5cf1fb19f267c562cdb55e569 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 27 Feb 2019 06:16:35 -0700 Subject: [PATCH 010/400] Better linked list --- Program/include/utils.h | 7 ++-- Program/src/utils.c | 84 +++++++++++++++++++++++++++++++---------- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/Program/include/utils.h b/Program/include/utils.h index 051b80d..5f3ef54 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -29,6 +29,7 @@ typedef struct CONFIG ------------------------------------------------------------------------------*/ typedef struct NODE { + char *id; void *element; struct NODE *next; struct NODE *prev; @@ -42,13 +43,13 @@ typedef struct List { struct NODE *head; struct NODE *tail; - int (*add)(struct List *list, void *element); - int (*remove)(struct List *list, int (*f)(void *element, void *args), void *args); + int (*add)(struct List *list, void *element, char *id); + void *(*remove)(struct List *list, char *id, int (*f)(void *element, void *args), void *args); void (*print)(struct List *list, void (*f)(void *element, void *args), void *args); void (*free)(struct List *list, void (*f)(void *element)); //returns a void pointer that should be cast to the type - void *(*find)(struct List *list, int (*f)(void *element, void *args), void *args); + void *(*find)(struct List *list, char *id, int (*f)(void *element, void *args), void *args); } List; /*------------------------------------------------------------------------------ diff --git a/Program/src/utils.c b/Program/src/utils.c index 8b1bf1f..0bd8874 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -17,6 +17,11 @@ to use for general functionality. #include #include + + +#define MAX_LEN 255 +#define ID_LEN 10 + //see header file int checkAlloc(void *mem, int notOkToFail) { @@ -109,11 +114,21 @@ CONFIG *configuration(int argc, char **argv) new node. ------------------------------------------------------------------------------*/ -static NODE *createNode(void *element) +static NODE *createNode(void *element, char *id) { NODE *newNode = calloc(sizeof(NODE), 1); checkAlloc(newNode, 1); newNode->element = element; + + if (id == NULL) + { + newNode->id = NULL; + return newNode; + } + + newNode->id = calloc(sizeof(char), ID_LEN); + checkAlloc(newNode, 1); + strncpy(newNode->id, id, ID_LEN); return newNode; } @@ -122,10 +137,10 @@ static NODE *createNode(void *element) This function adds a new element into the linked list. returns nothing. ------------------------------------------------------------------------------*/ -static int addElement(List *list, void *element) +static int addElement(List *list, void *element, char *id) { - NODE *newNode = createNode(element); + NODE *newNode = createNode(element, id); NODE *tail = list->tail; newNode->next = tail; @@ -133,6 +148,7 @@ static int addElement(List *list, void *element) tail->prev->next = newNode; tail->prev = newNode; + return 0; } @@ -153,28 +169,46 @@ static void printList(List *list, void (*f)(void *element, void *args), void *ar /*------------------------------------------------------------------------------ - This function removes an element from the linked list, returns 1 if success - and -1 if item not found. + This function removes an element from the linked list, returns the element stored if success + and NULL if item not found. it can use either an id, or callback to find the + element (callback can be the find function) ------------------------------------------------------------------------------*/ -static int removeElement(List *list, int (*f)(void *element, void *args), void *args) +static void *removeElement(List *list, char *id, int (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = -1; while (cur->next != NULL) { - int found = f(cur->element, args); - if (found == 1) + + if (f != NULL) + found_with_func = f(cur->element, args); + + if(cur->id != NULL && id != NULL) + found_with_id = strncmp(id, cur->id, MAX_LEN); + + if (found_with_func || found_with_id == 0) { NODE *previous = cur->prev; NODE *next = cur->next; + previous->next = next; next->prev = previous; + + if (cur->id != NULL) { + free(cur->id); + } + + void *element = cur->element; + free(cur); - return 1; + + return element; } cur = cur->next; } - return -1; + return NULL; } @@ -187,10 +221,12 @@ static int removeElement(List *list, int (*f)(void *element, void *args), void * static void freeList(List *list, void (*f)(void *element)) { NODE *cur = list->head->next; - while (cur->next != NULL) + while (cur->next != NULL ) { NODE *n = cur; cur = cur->next; + if (n->id != NULL) + free(n->id); f(n->element); free(n); } @@ -201,25 +237,35 @@ static void freeList(List *list, void (*f)(void *element)) /*------------------------------------------------------------------------------ This function finds an element, returns and element on success and NULL on - failure. The return value should be cast to the element type. + failure. The return value should be cast to the element type. can search with + either a callback, or id ------------------------------------------------------------------------------*/ -static void *findElement(List *list, int (*f)(void *element, void *args), void *args) +static void *findElement(List *list, char *id, int (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = -1; + while (cur->next != NULL) { - int found = f(cur->element, args); - if (found == 1) - { + + if (f != NULL) + found_with_func = f(cur->element, args); + + if(cur->id != NULL && id != NULL) + found_with_id = strncmp(cur->id, id, MAX_LEN); + + if (found_with_func || found_with_id == 0) return cur->element; - } + cur = cur->next; } return NULL; } + //see header file List *linked_list() @@ -227,8 +273,8 @@ List *linked_list() List *newList = calloc(sizeof(List), 1); checkAlloc(newList, 0); - newList->head = createNode(NULL); - newList->tail = createNode(NULL); + newList->head = createNode(NULL, NULL); + newList->tail = createNode(NULL, NULL); NODE *tail = newList->tail; NODE *head = newList->head; From f6c9a849ec199f7982c5788b6e9e1f279a9e0568 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 3 Mar 2019 15:45:15 -0700 Subject: [PATCH 011/400] add some fund stuff to lists --- Program/include/list_callbacks.h | 15 ++++ Program/include/port.h | 3 + Program/include/protocol_handler.h | 41 +++++---- Program/src/utils.c | 135 ++++++++++++++++++++--------- 4 files changed, 137 insertions(+), 57 deletions(-) create mode 100644 Program/include/list_callbacks.h diff --git a/Program/include/list_callbacks.h b/Program/include/list_callbacks.h new file mode 100644 index 0000000..8798f67 --- /dev/null +++ b/Program/include/list_callbacks.h @@ -0,0 +1,15 @@ + + +#ifndef LIST_CALLBACKS_H +#define LIST_CALLBACKS_H + + + int client_cleanup_list(void *element); + int client_list_remove(void *element, void *args); + void client_list_print(void *element, void *args); + int client_list_find(void *element, void *args); + void client_list_free(void *element); + +#endif + + diff --git a/Program/include/port.h b/Program/include/port.h index 55618d1..2a4f562 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -17,6 +17,9 @@ void *ssp_connectionless_server_task(void *protocol_state); Client *ssp_connectionless_client(char *host_name, char*port, Protocol_state *p_state); void *ssp_connectionless_client_task(void *params); void ssp_printf(char*stuff, ...); + + +void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 3c302b4..da259fb 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -4,6 +4,7 @@ #include "utils.h" #include "packet.h" + typedef struct response { int sfd; char *msg; @@ -11,23 +12,43 @@ typedef struct response { void *addr; //getting rid of this soon in favour of client based packet sizes uint32_t packet_len; + } Response; +typedef enum Indication { + transaction, + put +} Indication; typedef struct request { - uint8_t request_primitive; + Indication type; uint32_t transaction_id; + char *dest_cfdp_id; + char *source_file_name; + char *destination_file_name; + uint8_t segmentation_control; + uint8_t fault_handler_overides; + uint8_t flow_lable; + uint8_t transmission_mode; + char* messages_to_user; + char* filestore_requests; } Request; + + typedef struct client { char *host_name; char *client_port; void *client_handle; void *client_thread_attributes; uint32_t packet_len; + + //this is a queue of requests that will be processed + List *requests; uint8_t is_active; + } Client; @@ -38,22 +59,12 @@ typedef struct protocol_state { void *server_thread_attributes; List *client_list; - //temperary until client list works fully - Client *client; - + Client *newClient; } Protocol_state; -int cleanup_list(void *element); -int list_remove(void *element, void *args); -void list_print(void *element, void *args); -int list_find(void *element, void *args); -void list_free(void *element); - - - -void packet_handler_server(Response res, Protocol_state *p_state); -void packet_handler_client(Response res, Protocol_state *p_state); - +void packet_handler_server(Response res, Request req, Protocol_state *p_state); +void packet_handler_client(Response res, Request req, Protocol_state *p_state); +void parse_packet(char* buff, Request req, Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/src/utils.c b/Program/src/utils.c index 0bd8874..f142305 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -109,38 +109,88 @@ CONFIG *configuration(int argc, char **argv) return conf; } + + /*------------------------------------------------------------------------------ This function creates a new node to add into the linked list, returns the - new node. + new node, or NULL if failed ------------------------------------------------------------------------------*/ -static NODE *createNode(void *element, char *id) +static NODE *createNode(void *element, uint32_t id) { NODE *newNode = calloc(sizeof(NODE), 1); - checkAlloc(newNode, 1); + if(!checkAlloc(newNode, 0)) + return NULL; + newNode->element = element; - - if (id == NULL) - { - newNode->id = NULL; - return newNode; - } - - newNode->id = calloc(sizeof(char), ID_LEN); - checkAlloc(newNode, 1); - strncpy(newNode->id, id, ID_LEN); + newNode->id = id; return newNode; } + + +/*------------------------------------------------------------------------------ + This function creates a new node to add into the linked list, returns the + new node. +------------------------------------------------------------------------------*/ + + +static void freeNode(NODE *node) { + free(node); +} + +static void *pop(List *list) { + + NODE *last_data_node = list->tail->prev; + if (last_data_node == NULL) + return NULL; + + void *element = last_data_node->element; + + NODE *prev = last_data_node->prev; + prev->next = list->tail; + + freeNode(last_data_node); + list->count--; + return element; +} + + +/*------------------------------------------------------------------------------ + This function creates a new node to add into the linked list, returns the + new node. +------------------------------------------------------------------------------*/ + +static int insert(List *list, void *element, uint32_t id) { + + NODE *head = list->head; + NODE *node = createNode(element, id); + if (node == NULL) { + return 0; + } + + node->next = head->next; + node->prev = head; + + head->next = node; + head->prev = NULL; + list->count++; + return 1; +} + /*------------------------------------------------------------------------------ - This function adds a new element into the linked list. returns nothing. + This function adds a new element into the linked list. returns 1 if success + 0 if failed. ------------------------------------------------------------------------------*/ -static int addElement(List *list, void *element, char *id) +static int addElement(List *list, void *element, uint32_t id) { NODE *newNode = createNode(element, id); + if (newNode == NULL) { + return 0; + } NODE *tail = list->tail; newNode->next = tail; @@ -149,7 +199,8 @@ static int addElement(List *list, void *element, char *id) tail->prev->next = newNode; tail->prev = newNode; - return 0; + list->count++; + return 1; } /*------------------------------------------------------------------------------ @@ -174,36 +225,30 @@ static void printList(List *list, void (*f)(void *element, void *args), void *ar element (callback can be the find function) ------------------------------------------------------------------------------*/ -static void *removeElement(List *list, char *id, int (*f)(void *element, void *args), void *args) +static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; int found_with_func = 0; - int found_with_id = -1; + int found_with_id = 0; while (cur->next != NULL) { - if (f != NULL) found_with_func = f(cur->element, args); - if(cur->id != NULL && id != NULL) - found_with_id = strncmp(id, cur->id, MAX_LEN); + if (id == cur->id) + found_with_id = 1; - if (found_with_func || found_with_id == 0) + if (found_with_func || found_with_id) { NODE *previous = cur->prev; NODE *next = cur->next; previous->next = next; next->prev = previous; - - if (cur->id != NULL) { - free(cur->id); - } - void *element = cur->element; - free(cur); - + freeNode(cur); + list->count--; return element; } cur = cur->next; @@ -225,10 +270,8 @@ static void freeList(List *list, void (*f)(void *element)) { NODE *n = cur; cur = cur->next; - if (n->id != NULL) - free(n->id); f(n->element); - free(n); + freeNode(n); } free(list->head); free(list->tail); @@ -241,12 +284,12 @@ static void freeList(List *list, void (*f)(void *element)) either a callback, or id ------------------------------------------------------------------------------*/ -static void *findElement(List *list, char *id, int (*f)(void *element, void *args), void *args) +static void *findElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; int found_with_func = 0; - int found_with_id = -1; + int found_with_id = 0; while (cur->next != NULL) { @@ -254,10 +297,10 @@ static void *findElement(List *list, char *id, int (*f)(void *element, void *arg if (f != NULL) found_with_func = f(cur->element, args); - if(cur->id != NULL && id != NULL) - found_with_id = strncmp(cur->id, id, MAX_LEN); + if(cur->id == id) + found_with_id = 1; - if (found_with_func || found_with_id == 0) + if (found_with_func || found_with_id) return cur->element; cur = cur->next; @@ -266,26 +309,34 @@ static void *findElement(List *list, char *id, int (*f)(void *element, void *arg } -//see header file +//see header file return NULL if fails List *linked_list() { List *newList = calloc(sizeof(List), 1); - checkAlloc(newList, 0); + if(!checkAlloc(newList, 0)) + return NULL; - newList->head = createNode(NULL, NULL); - newList->tail = createNode(NULL, NULL); + newList->head = createNode(NULL, 0); + if (newList->head == NULL) + return NULL; + newList->tail = createNode(NULL, 0); + if (newList->tail == NULL) + return NULL; + NODE *tail = newList->tail; NODE *head = newList->head; tail->prev = head; head->next = tail; - newList->add = addElement; + newList->push = addElement; newList->remove = removeElement; newList->print = printList; newList->free = freeList; + newList->insert = insert; + newList->pop = pop; newList->find = findElement; return newList; From fc3e7fa8afeddfed46017fe4032f0630b7ad4ba2 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 3 Mar 2019 15:46:29 -0700 Subject: [PATCH 012/400] update, add Request structs and propper multi thread sig int handlers --- Program/include/protocol_handler.h | 1 + Program/include/server.h | 4 ++ Program/include/utils.h | 12 +++--- Program/src/list_callbacks.c | 26 +++++++++++ Program/src/main.c | 42 +++++++++++++++--- Program/src/makefile | 1 + Program/src/port.c | 69 ++++++++++++++++++++++-------- Program/src/protocol_handler.c | 53 ++++++----------------- Program/src/server.c | 5 ++- 9 files changed, 144 insertions(+), 69 deletions(-) create mode 100644 Program/src/list_callbacks.c diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index da259fb..f8484b7 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -60,6 +60,7 @@ typedef struct protocol_state { List *client_list; Client *newClient; + } Protocol_state; diff --git a/Program/include/server.h b/Program/include/server.h index 829496c..c2e797a 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -55,6 +55,10 @@ void udpSelectServer(char *port, int packet_len, Return: None ------------------------------------------------------------------------------*/ + +int *prepareSignalHandler(void); + + void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); diff --git a/Program/include/utils.h b/Program/include/utils.h index 5f3ef54..bd505a7 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -29,7 +29,7 @@ typedef struct CONFIG ------------------------------------------------------------------------------*/ typedef struct NODE { - char *id; + uint32_t id; void *element; struct NODE *next; struct NODE *prev; @@ -43,13 +43,15 @@ typedef struct List { struct NODE *head; struct NODE *tail; - int (*add)(struct List *list, void *element, char *id); - void *(*remove)(struct List *list, char *id, int (*f)(void *element, void *args), void *args); + int count; + int (*push)(struct List *list, void *element, uint32_t id); + void *(*remove)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); void (*print)(struct List *list, void (*f)(void *element, void *args), void *args); void (*free)(struct List *list, void (*f)(void *element)); - + void *(*pop) (struct List *list); + int (*insert) (struct List *list, void *element, uint32_t id); //returns a void pointer that should be cast to the type - void *(*find)(struct List *list, char *id, int (*f)(void *element, void *args), void *args); + void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); } List; /*------------------------------------------------------------------------------ diff --git a/Program/src/list_callbacks.c b/Program/src/list_callbacks.c new file mode 100644 index 0000000..aea10f8 --- /dev/null +++ b/Program/src/list_callbacks.c @@ -0,0 +1,26 @@ + + +#include "list_callbacks.h" +#include "protocol_handler.h" +#include "stdlib.h" +#include "port.h" + +void client_list_free(void *element) { + Client *client = (Client * ) element; + + ssp_cleanup_client(client); +} + +void client_list_print(void *element, void *args) { + +} + + +int client_list_find(void *element, void *args) { +/* + int id = *(int *) args; + if (id == ((struct myStruct*) element)->id) + return 1; + return 0; + */ +} diff --git a/Program/src/main.c b/Program/src/main.c index f85c586..32ecfff 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -7,20 +7,52 @@ #include #include "protocol_handler.h" #include "utils.h" +#include "list_callbacks.h" +#include "server.h" - +static int *exit_now; int main() { + exit_now = prepareSignalHandler(); + Protocol_state *p_state = ssp_connectionless_server("1111"); p_state->client_list = linked_list(); + Client *new_client; + +/* + for (;;) { + if (*exit_now) { + break; + } + } +*/ - sleep(1); - //auto adds client to the client list - ssp_connectionless_client("127.0.0.1", "1111", p_state); - p_state->client_list->free(p_state->client_list, list_free); + new_client = ssp_connectionless_client("127.0.0.1", "1111", p_state); + + + Request *req = calloc(1, sizeof(Request)); + + req->transaction_id = 1; + //enumerations + req->type = put; + req->dest_cfdp_id = "1"; + req->source_file_name = "test.txt"; + req->destination_file_name = "test.txt"; + req->segmentation_control = 0; + req->fault_handler_overides = 0; + req->flow_lable = 0; + req->transmission_mode = 0; + req->messages_to_user = "sup"; + req->filestore_requests = NULL; + + List *requests = new_client->requests; + requests->insert(requests, req, 1); + + //will block on pthread_join + p_state->client_list->free(p_state->client_list, client_list_free); ssp_cleanup(p_state); return 0; } diff --git a/Program/src/makefile b/Program/src/makefile index 605b0ff..27518c9 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -8,6 +8,7 @@ CFILES += port.c CFILES += utils.c CFILES += server.c #used for poxix port CFILES += protocol_handler.c +CFILES += list_callbacks.c #entrypoint MAIN = main diff --git a/Program/src/port.c b/Program/src/port.c index a671168..71befb6 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -20,6 +20,11 @@ #include "protocol_handler.h" +void *ssp_alloc(uint32_t n_memb, size_t size) { + #ifdef POSIX_PORT + return calloc(n_memb, size); + #endif +} void ssp_printf(char*stuff, ...) { @@ -54,43 +59,48 @@ void ssp_sendto(Response res) { //this function is a callback when using my posix port static int on_recv_server(int sfd, char *msg, struct sockaddr_storage addr, void *other) { - #ifdef POSIX_PORT Protocol_state *p_state = (Protocol_state *) other; + + #ifdef POSIX_PORT struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + #endif Response res; res.addr = posix_client; res.sfd = sfd; res.packet_len = p_state->packet_size; + Request req; + + parse_packet(msg, req, p_state); ssp_printf("Server received: %s\n", msg); //printf("addr %d port%d\n",ntohl(((struct in_addr*) posix_client)->s_addr), ntohs(posix_client->sin_port)); - - packet_handler_server(res, p_state); + packet_handler_server(res, req, p_state); return 0; - #endif } static int on_recv_client(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in addr, void *other) { #ifdef POSIX_PORT + struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + #endif Protocol_state *p_state = (Protocol_state *) other; - struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; Response res; res.addr = posix_client; res.sfd = sfd; - res.packet_len = p_state->packet_size; + res.packet_len = *buff_size; - ssp_printf("Client received: %s\n", msg); + Request req; + parse_packet(msg, req, p_state); - packet_handler_client(res, p_state); + ssp_printf("Client received: %s\n", msg); + packet_handler_client(res, req, p_state); return 0; - #endif } static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { @@ -100,11 +110,20 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { Protocol_state *p_state = (Protocol_state *) other; struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + u_int32_t id = (uint32_t) addr.sin_addr.s_addr; + + Client *client = p_state->client_list->find(p_state->client_list, id, NULL, NULL); + + //printf("%ul\n", client->packet_len); + + Response res; res.addr = posix_client; res.sfd = sfd; res.packet_len = p_state->packet_size; - res.msg = "some shit\n"; + + + res.msg = "packets!\n"; ssp_sendto(res); @@ -180,7 +199,8 @@ void *ssp_connectionless_client_task(void* params){ Protocol_state *p_state = (Protocol_state *) params; // TODO find a client function p_state->client_list->find() - udpClient(p_state->client->host_name, p_state->client->client_port, PACKET_LEN, p_state, p_state, on_send_client, on_recv_client); + + udpClient(p_state->newClient->host_name, p_state->newClient->client_port, PACKET_LEN, p_state, p_state, on_send_client, on_recv_client); return NULL; } @@ -200,6 +220,8 @@ Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p client->client_port = calloc(sizeof(char), port_len); checkAlloc(client->client_port, 1); + client->requests = linked_list(); + pthread_t *handler = calloc(sizeof(pthread_t), 1); checkAlloc(handler, 1); @@ -227,9 +249,13 @@ Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p client->client_thread_attributes = attr; //add client to a new list of currently active clients - p_state->client_list->add(p_state->client_list, client); - - p_state->client = client; + p_state->client_list->push(p_state->client_list, client, atoi(host_name)); + + //TODO lock this + p_state->newClient = client; + + + err = pthread_create(handler, attr, ssp_connectionless_client_task, p_state); if (0 != err) perror("ERROR pthread_create"); @@ -257,18 +283,25 @@ void ssp_cleanup(Protocol_state *p_state) { } + +static void client_requests_free(void *element) { + Request *req = (Request *) element; + free(req); +} + void ssp_cleanup_client(Client *client) { + #ifdef POSIX_PORT - pthread_t * handle = (pthread_t*) client->client_handle; + pthread_t * handle = (pthread_t*) client->client_handle; + pthread_join(*handle, NULL); + #endif - pthread_join(*handle, NULL); + client->requests->free(client->requests, client_requests_free); free(client->host_name); free(client->client_handle); free(client->client_port); free(client->client_thread_attributes); free(client); - #endif - } \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2501e43..dca9454 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -4,58 +4,26 @@ #include "protocol_handler.h" - -int list_remove(void *element, void *args) { - - /* - int id = *(int *) args; - struct myStruct *st = (struct myStruct *)element; - - if (id == ((struct myStruct*) element)->id) { - free(st); - return 1; - - } - */ - - return 0; -} - -void list_print(void *element, void *args) { +void parse_packet(char* msg, Request req, Protocol_state *p_state) { } -int list_find(void *element, void *args) { -/* - int id = *(int *) args; - if (id == ((struct myStruct*) element)->id) - return 1; - return 0; - */ -} - -void list_free(void *element) { - Client * client = (Client*) element; - ssp_cleanup_client(client); -} - -void packet_handler_server(Response res, Protocol_state *p_state) { - - res.msg = "shutupa you\n"; +void packet_handler_server(Response res, Request req, Protocol_state *p_state) { + res.msg = "Server Received\n"; ssp_sendto(res); } -void packet_handler_client(Response res, Protocol_state *p_state) { - res.msg = "noa youa shuta up!\n"; +void packet_handler_client(Response res, Request req, Protocol_state *p_state) { + res.msg = "Client Received!\n"; ssp_sendto(res); -} +} //Omission of source and destination filenames shall indicate that only Meta //data will be delivered -int put_request(char *dest_cfdp_id, +put_request(char *dest_cfdp_id, char *source_file_name, char *destination_file_name, uint8_t segmentation_control, @@ -66,7 +34,14 @@ int put_request(char *dest_cfdp_id, char* filestore_requests ) { + Request *req = ssp_alloc(1, sizeof(Request)); + if (checkAlloc(req, 0)) { + ssp_error("cound't allocate mem for request\n"); + } + + + } /* diff --git a/Program/src/server.c b/Program/src/server.c index 4dd5297..79cf5d3 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -33,7 +33,7 @@ This is my file for server.c. It develops a udp server for select. #include -static int exit_now = 0; +static int exit_now; //this code is reused from assignment 1, with small changes @@ -113,7 +113,7 @@ static void interuptHandler(int signum) //see header file -static void prepareSignalHandler() +int *prepareSignalHandler() { struct sigaction actionData; sigemptyset(&actionData.sa_mask); @@ -125,6 +125,7 @@ static void prepareSignalHandler() perror("sigaction sigint failed\n"); exit(EXIT_FAILURE); } + return &exit_now; } From 7cd2ea00bc599afa23cc14181a9b6826e6c9e912 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 6 Mar 2019 08:47:12 -0700 Subject: [PATCH 013/400] Add Mib and some refactoring --- Program/include/mib.h | 97 ++++++++++++++++++++++++ Program/include/port.h | 11 ++- Program/include/protocol_handler.h | 35 +++++---- Program/include/server.h | 2 +- Program/src/main.c | 38 +++++----- Program/src/makefile | 1 + Program/src/mib.c | 36 +++++++++ Program/src/port.c | 114 ++++++++++++++--------------- Program/src/protocol_handler.c | 58 +++++++++++---- Program/src/server.c | 72 ++++++++++-------- 10 files changed, 327 insertions(+), 137 deletions(-) create mode 100644 Program/include/mib.h create mode 100644 Program/src/mib.c diff --git a/Program/include/mib.h b/Program/include/mib.h new file mode 100644 index 0000000..b7a0d75 --- /dev/null +++ b/Program/include/mib.h @@ -0,0 +1,97 @@ +//the management information base (MIB) + +//default faul handle +#include +#include + + + +#ifndef MIB_H +#define MIB_H + + +typedef struct local_entity { + unsigned int EOF_sent_indication : 1; + + unsigned int EOF_recv_indication : 1; + + //required + unsigned int file_segment_recv_indication : 1; + + //required when acting as receiving entity + unsigned int transaction_finished_indication : 1; + + //required when acting as receiving entity + unsigned int suspended_indication : 1; + + //required when acting as receiving entity + unsigned int resumed_indication : 1; + + //function pointer to default handler? + void *default_fault_handler; + + //TODO routing information, extended procedures only, list maybe? + +} Local_entity; + + +typedef struct remote_entity { + + //TODO probably add new UT layer specific stuff + uint32_t UT_address; + uint16_t UT_port; + + uint32_t cfdp_id; + + unsigned int one_way_light_time; + unsigned int total_round_trip_allowance; + unsigned int async_NAK_interval; + unsigned int async_keep_alive_interval; + unsigned int async_report_interval; + unsigned int immediate_nak_mode_enabled : 1; + unsigned int prompt_transmission_interval; + //acknowledged or unacknowledged + unsigned int default_transmission_mode: 1; + + //discard or retain (no idea what this is for yet) + unsigned int disposition_of_incomplete : 1; + + unsigned int CRC_required : 1; + //in octets + unsigned int max_file_segment_len; + //in octets + unsigned int keep_alive_discrepancy_limit; + + //Number of expirations + unsigned int positive_ack_timer_expiration_limit; + + //Number of expirations + unsigned int nak_timer_expiration_limit; + + //time limit + unsigned int transaction_inactivity_limit; + + /* + Start of transmission opportunity A signal produced by the operating environment. + End of transmission opportunity A signal produced by the operating environment. + Start of reception opportunity A signal produced by the operating environment. + End of reception opportunity A signal produced by the operating environment. + */ + + +} Remote_entity; + +typedef struct mib { + Local_entity server; + List *remote_entities; + +} MIB; + + +MIB *init_mib(void); +void free_mib(MIB *mib); +int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port); + + + +#endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index 2a4f562..1d9d6a1 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -14,7 +14,7 @@ Protocol_state *ssp_connectionless_server(char *port); void *ssp_connectionless_server_task(void *protocol_state); -Client *ssp_connectionless_client(char *host_name, char*port, Protocol_state *p_state); +Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); void *ssp_connectionless_client_task(void *params); void ssp_printf(char*stuff, ...); @@ -23,4 +23,13 @@ void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); + + + + + + + + +void ssp_free(void *pointer); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index f8484b7..a942eaf 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -3,7 +3,7 @@ #define PROTOCOL_H #include "utils.h" #include "packet.h" - +#include "mib.h" typedef struct response { int sfd; @@ -16,6 +16,7 @@ typedef struct response { } Response; typedef enum Indication { + none, transaction, put } Indication; @@ -32,22 +33,25 @@ typedef struct request { uint8_t transmission_mode; char* messages_to_user; char* filestore_requests; + char* buff; } Request; - - typedef struct client { - char *host_name; - char *client_port; + void *client_handle; void *client_thread_attributes; uint32_t packet_len; - //this is a queue of requests that will be processed - List *requests; - uint8_t is_active; + //this is a queue of user requests that will be going out + Request *outGoing_req; + Request *incoming_req; + uint32_t cfdp_id; + uint32_t unitdata_id; + uint32_t unitdata_port; + + uint8_t is_active; } Client; @@ -57,15 +61,18 @@ typedef struct protocol_state { char *server_port; void *server_handle; void *server_thread_attributes; - - List *client_list; + MIB *mib; Client *newClient; - + Request *current_server_request; + + } Protocol_state; -void packet_handler_server(Response res, Request req, Protocol_state *p_state); -void packet_handler_client(Response res, Request req, Protocol_state *p_state); -void parse_packet(char* buff, Request req, Protocol_state *p_state); +void packet_handler_server(Response res, Request *req, Protocol_state *p_state); +void parse_packet_server(char* buff, Request *req, Protocol_state *p_state); +void packet_handler_client(Response res, Request *req, Client *client, Protocol_state *p_state); +void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); +void parse_packet_client(char* buff, Request *req, Client *client, Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index c2e797a..7d5c6f0 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -43,7 +43,7 @@ int prepareUdpHost(char *port); ------------------------------------------------------------------------------*/ void udpSelectServer(char *port, int packet_len, - int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other); diff --git a/Program/src/main.c b/Program/src/main.c index 32ecfff..dee7b3b 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -9,6 +9,7 @@ #include "utils.h" #include "list_callbacks.h" #include "server.h" +#include "mib.h" static int *exit_now; @@ -17,24 +18,25 @@ int main() { exit_now = prepareSignalHandler(); Protocol_state *p_state = ssp_connectionless_server("1111"); - p_state->client_list = linked_list(); - Client *new_client; + MIB *mib = init_mib(); + p_state->mib = mib; -/* - for (;;) { - if (*exit_now) { - break; - } - } -*/ - + //setting host name for testing + char *host_name = "127.0.0.1"; + uint32_t addr[sizeof(uint32_t)]; + inet_pton(AF_INET, host_name, addr); + uint16_t port = 1111; + + + + //adding new cfdp entity to management information base + add_new_cfdp_entity(mib, 1, *addr, port); + Client *new_client = ssp_connectionless_client(1, p_state); + Request *req = new_client->outGoing_req; - new_client = ssp_connectionless_client("127.0.0.1", "1111", p_state); - - - Request *req = calloc(1, sizeof(Request)); + //build a request req->transaction_id = 1; //enumerations req->type = put; @@ -47,12 +49,10 @@ int main() { req->transmission_mode = 0; req->messages_to_user = "sup"; req->filestore_requests = NULL; - - List *requests = new_client->requests; - requests->insert(requests, req, 1); - + req->buff = calloc(new_client->packet_len, sizeof(char)); + //will block on pthread_join - p_state->client_list->free(p_state->client_list, client_list_free); + ssp_cleanup_client(new_client); ssp_cleanup(p_state); return 0; } diff --git a/Program/src/makefile b/Program/src/makefile index 27518c9..ef0da3d 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -9,6 +9,7 @@ CFILES += utils.c CFILES += server.c #used for poxix port CFILES += protocol_handler.c CFILES += list_callbacks.c +CFILES += mib.c #entrypoint MAIN = main diff --git a/Program/src/mib.c b/Program/src/mib.c new file mode 100644 index 0000000..b50be26 --- /dev/null +++ b/Program/src/mib.c @@ -0,0 +1,36 @@ + +#include "mib.h" +#include "utils.h" +#include "port.h" + + +MIB *init_mib() { + MIB *mib = ssp_alloc(1, sizeof(MIB)); + checkAlloc(mib, 1); + mib->remote_entities = linked_list(); + return mib; +} + + +static void free_mib_callback(void *element) { + ssp_free(element); +} + +void free_mib(MIB *mib){ + + mib->remote_entities->free(mib->remote_entities, free_mib_callback); + ssp_free(mib); +} + + +int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port){ + + Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); + checkAlloc(remote, 1); + + remote->UT_address = UT_address; + remote->cfdp_id = cfdp_id; + remote->UT_port = port; + + return mib->remote_entities->insert(mib->remote_entities, remote, cfdp_id); +} \ No newline at end of file diff --git a/Program/src/port.c b/Program/src/port.c index 71befb6..31006c3 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -57,7 +57,7 @@ void ssp_sendto(Response res) { //this function is a callback when using my posix port -static int on_recv_server(int sfd, char *msg, struct sockaddr_storage addr, void *other) { +static int on_recv_server(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage addr, void *other) { Protocol_state *p_state = (Protocol_state *) other; @@ -70,13 +70,12 @@ static int on_recv_server(int sfd, char *msg, struct sockaddr_storage addr, void res.addr = posix_client; res.sfd = sfd; res.packet_len = p_state->packet_size; - Request req; - - parse_packet(msg, req, p_state); - ssp_printf("Server received: %s\n", msg); - //printf("addr %d port%d\n",ntohl(((struct in_addr*) posix_client)->s_addr), ntohs(posix_client->sin_port)); - packet_handler_server(res, req, p_state); + //filles the request struct + parse_packet_server(msg, p_state->current_server_request, p_state); + + //ssp_printf("Server received: %s\n", msg); + packet_handler_server(res, p_state->current_server_request, p_state); return 0; } @@ -94,39 +93,31 @@ static int on_recv_client(int sfd, char *msg, uint32_t *buff_size, struct sockad res.sfd = sfd; res.packet_len = *buff_size; - Request req; - parse_packet(msg, req, p_state); + Client *client = p_state->newClient; + + //filles the request struct + parse_packet_client(msg, client->incoming_req, client, p_state); - ssp_printf("Client received: %s\n", msg); - packet_handler_client(res, req, p_state); + //ssp_printf("Client received: %s\n", msg); + packet_handler_client(res, client->incoming_req, client, p_state); return 0; } static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { - #ifdef POSIX_PORT Protocol_state *p_state = (Protocol_state *) other; struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; - u_int32_t id = (uint32_t) addr.sin_addr.s_addr; - - Client *client = p_state->client_list->find(p_state->client_list, id, NULL, NULL); - - //printf("%ul\n", client->packet_len); - + Client *client = p_state->newClient; Response res; res.addr = posix_client; res.sfd = sfd; - res.packet_len = p_state->packet_size; - - - res.msg = "packets!\n"; - - ssp_sendto(res); - + res.packet_len = client->packet_len; + user_request_handler(res, client->outGoing_req, client, p_state); + return 0; #endif @@ -185,7 +176,7 @@ Protocol_state* ssp_connectionless_server(char *port) { if (0 != err) perror("ERROR pthread_create"); - + state->current_server_request = calloc(1, sizeof(Request)); state->server_handle = handler; state->server_thread_attributes = attr; return state; @@ -197,30 +188,33 @@ Protocol_state* ssp_connectionless_server(char *port) { void *ssp_connectionless_client_task(void* params){ Protocol_state *p_state = (Protocol_state *) params; - - // TODO find a client function p_state->client_list->find() - udpClient(p_state->newClient->host_name, p_state->newClient->client_port, PACKET_LEN, p_state, p_state, on_send_client, on_recv_client); + char host_name[INET_ADDRSTRLEN]; + char port[10]; + //convert int to char * + snprintf(port, 10, "%d", p_state->newClient->unitdata_port); + + //convert uint id to char * + inet_ntop(AF_INET, &p_state->newClient->unitdata_id, host_name, INET_ADDRSTRLEN); + + udpClient(host_name, port, PACKET_LEN, p_state, p_state, on_send_client, on_recv_client); + return NULL; } -Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p_state) { +Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { #ifdef POSIX_PORT - int port_len = strnlen(port, 100) + 1; - int host_len = strnlen(host_name, 100) + 1; Client *client = calloc(sizeof(Client), 1); checkAlloc(client, 1); - client->host_name = calloc(sizeof(char), host_len); - checkAlloc(client->host_name, 1); + client->outGoing_req = calloc(1, (sizeof(Request))); + checkAlloc(client->outGoing_req, 1); - client->client_port = calloc(sizeof(char), port_len); - checkAlloc(client->client_port, 1); - - client->requests = linked_list(); + client->incoming_req = calloc(1, (sizeof(Request))); + checkAlloc(client->incoming_req, 1); pthread_t *handler = calloc(sizeof(pthread_t), 1); checkAlloc(handler, 1); @@ -228,9 +222,6 @@ Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); checkAlloc(attr, 1); - strncpy(client->client_port, port, port_len); - strncpy(client->host_name, host_name, host_len); - int err = pthread_attr_init(attr); if (0 != err) perror("pthread_init failed"); @@ -241,21 +232,23 @@ Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p if (0 != err) perror("ERROR pthread_attr_setstacksize %d"); - if (EINVAL == err) { + if (EINVAL == err) printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); - } client->client_handle = handler; client->client_thread_attributes = attr; + client->packet_len = PACKET_LEN; + client->cfdp_id = cfdp_id; + + List *entity_list = p_state->mib->remote_entities; + Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); - //add client to a new list of currently active clients - p_state->client_list->push(p_state->client_list, client, atoi(host_name)); + client->unitdata_port = remote->UT_port; + client->unitdata_id = remote->UT_address; //TODO lock this p_state->newClient = client; - - err = pthread_create(handler, attr, ssp_connectionless_client_task, p_state); if (0 != err) perror("ERROR pthread_create"); @@ -266,6 +259,11 @@ Client *ssp_connectionless_client(char *host_name, char *port, Protocol_state *p } +void ssp_cleanup_req(Request *req) { + + free(req->buff); + free(req); +} void ssp_cleanup(Protocol_state *p_state) { @@ -276,19 +274,13 @@ void ssp_cleanup(Protocol_state *p_state) { free(p_state->server_handle); free(p_state->server_port); free(p_state->server_thread_attributes); + free(p_state->current_server_request); free(p_state); #endif } - - -static void client_requests_free(void *element) { - Request *req = (Request *) element; - free(req); -} - void ssp_cleanup_client(Client *client) { @@ -296,12 +288,18 @@ void ssp_cleanup_client(Client *client) { pthread_t * handle = (pthread_t*) client->client_handle; pthread_join(*handle, NULL); #endif - - client->requests->free(client->requests, client_requests_free); - free(client->host_name); + ssp_cleanup_req(client->outGoing_req); + free(client->incoming_req); free(client->client_handle); - free(client->client_port); free(client->client_thread_attributes); free(client); +} + + +void ssp_free(void *pointer) { + #ifdef POSIX_PORT + free(pointer); + #endif + } \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index dca9454..f9dc8fd 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -2,28 +2,62 @@ #include "port.h" #include "protocol_handler.h" +#include "string.h" +#include "packet.h" +static void build_put_packet(char* packet, Request *req, Client* client) { + + Pdu_header header; + header.length_of_entity_IDs = 1; + header.destination_id = (uint8_t) client->cfdp_id; + header.source_id = 2; + memcpy(packet, &header, 100); -void parse_packet(char* msg, Request req, Protocol_state *p_state) { } +//fills the current request with packet data, responses from servers +void parse_packet_client(char* msg, Request *current_request, Client* client, Protocol_state *p_state) { + ssp_printf("server received %x\n", msg); +} - -void packet_handler_server(Response res, Request req, Protocol_state *p_state) { - res.msg = "Server Received\n"; - ssp_sendto(res); +//fills the current_request struct for the server, incomming requests +void parse_packet_server(char* msg, Request *current_request, Protocol_state *p_state) { + ssp_printf("server received %x\n", msg); } +//Server responses +void packet_handler_server(Response res, Request *current_request, Protocol_state *p_state) { + //res.msg = "Server Received\n"; + //ssp_sendto(res); +} -void packet_handler_client(Response res, Request req, Protocol_state *p_state) { - res.msg = "Client Received!\n"; - ssp_sendto(res); +//Client responses +void packet_handler_client(Response res, Request *req, Client* client, Protocol_state *p_state) { + //res.msg = "Client Received!\n"; + //ssp_sendto(res); } +//current user request, to send to client +void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { + + switch (req->type) + { + case put: + res.msg = req->buff; + build_put_packet(res.msg, client, req); + ssp_sendto(res); + break; + + default: + break; + } + +} + //Omission of source and destination filenames shall indicate that only Meta //data will be delivered -put_request(char *dest_cfdp_id, +void put_request(char *dest_cfdp_id, char *source_file_name, char *destination_file_name, uint8_t segmentation_control, @@ -31,17 +65,15 @@ put_request(char *dest_cfdp_id, uint8_t flow_lable, uint8_t transmission_mode, char* messages_to_user, - char* filestore_requests + char* filestore_requests ) { Request *req = ssp_alloc(1, sizeof(Request)); if (checkAlloc(req, 0)) { ssp_error("cound't allocate mem for request\n"); - } - + } - } /* diff --git a/Program/src/server.c b/Program/src/server.c index 79cf5d3..d3b8303 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -128,10 +128,23 @@ int *prepareSignalHandler() return &exit_now; } +static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buff_size) { + + if (*newBufferSize != *prev_buff_size) { + *buffer = realloc(*buffer, *newBufferSize); + + if(checkAlloc(*buffer, 0)){ + *prev_buff_size = *newBufferSize; + return 1; + } + return 0; + } + return 1; +} //see header file void udpSelectServer(char* port, int packet_len, - int (*onRecv)(int sfd, char *msg, struct sockaddr_storage client, void *other), + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other) { @@ -143,8 +156,15 @@ void udpSelectServer(char* port, int packet_len, FD_SET(STDIN_FILENO, &masterReadFds); FD_SET(sfd, &masterReadFds); - int buff_size = packet_len + 10; - char *buff = calloc(sizeof(char), buff_size); + uint32_t *buff_size = calloc(1, sizeof(uint32_t)); + checkAlloc(buff_size, 1); + + + *buff_size = packet_len + 10; + + uint32_t prev_buff_size = *buff_size; + + char *buff = calloc(sizeof(char), *buff_size); checkAlloc(buff, 1); struct sockaddr_storage *client; @@ -165,15 +185,17 @@ void udpSelectServer(char* port, int packet_len, printf("exiting server thread\n"); break; } - - if (nrdy == -1) - { + + if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ + printf("packet too large, cannot resize buffer\n"); + } + + if (nrdy == -1) { perror("select"); continue; } //timeout - if (nrdy == 0) - { + if (nrdy == 0) { if (onTimeOut(other) == -1) printf("timeout failed\n"); continue; @@ -191,18 +213,19 @@ void udpSelectServer(char* port, int packet_len, { perror("recv failed"); } - else if (count >= buff_size) + else if (count >= *buff_size) { printf("packet too large\n"); continue; } else { - if (onRecv(sfd, buff, *client, other) == -1) + if (onRecv(sfd, buff, buff_size, *client, other) == -1) printf("recv failed\n"); } } } + free(buff_size); free(client); free(buff); close(sfd); @@ -217,14 +240,15 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams) ) { - int sfd, count, port_val, n; + int sfd, count, port_val; socklen_t serverlen; struct sockaddr_in serveraddr; struct hostent *server; uint32_t *buff_size = malloc(sizeof(uint32_t)); - *buff_size = packet_len + 10; + checkAlloc(buff_size, 1); + *buff_size = packet_len + 10; uint32_t prev_buff_size = *buff_size; @@ -250,33 +274,19 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); serveraddr.sin_port = htons(port_val); - - char *msg = "first message?\n"; - serverlen = sizeof(serveraddr); - - /* send the message to the server */ - n = sendto(sfd, msg, (size_t) strnlen(msg, packet_len), 0, (struct sockaddr*)&serveraddr, serverlen); - if (n < 0) - perror("ERROR in sendto"); - for (;;) { if (exit_now) break; - if (*buff_size != prev_buff_size) { - prev_buff_size = *buff_size; - if(checkAlloc(realloc(buff, *buff_size), 0)){ - prev_buff_size = *buff_size; - } - else { - printf("packet too large, cannot resize buffer\n"); - } - + if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ + printf("packet too large, cannot resize buffer\n"); } + + sleep(1); /* print the server's reply */ if (onSend(sfd, serveraddr, onSendParams)) @@ -288,7 +298,7 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo if (count == -1) { - perror("recv failed"); + //perror("recv failed"); } else if (count >= *buff_size) { From f022dbe918fa597519900144896574f977cd8084 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 Mar 2019 09:58:12 -0600 Subject: [PATCH 014/400] Add ccsds id to server --- Program/include/mib.h | 1 - Program/include/protocol_handler.h | 3 +- Program/include/utils.h | 14 +++--- Program/src/main.c | 76 ++++++++++++++++++++++++++---- Program/src/mib.c | 2 +- Program/src/port.c | 6 +++ Program/src/utils.c | 59 +++++++---------------- 7 files changed, 100 insertions(+), 61 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index b7a0d75..5ec259e 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -40,7 +40,6 @@ typedef struct remote_entity { //TODO probably add new UT layer specific stuff uint32_t UT_address; uint16_t UT_port; - uint32_t cfdp_id; unsigned int one_way_light_time; diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index a942eaf..3d37d51 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -24,7 +24,7 @@ typedef enum Indication { typedef struct request { Indication type; uint32_t transaction_id; - char *dest_cfdp_id; + uint32_t dest_cfdp_id; char *source_file_name; char *destination_file_name; uint8_t segmentation_control; @@ -62,6 +62,7 @@ typedef struct protocol_state { void *server_handle; void *server_thread_attributes; MIB *mib; + uint32_t my_cfdp_id; Client *newClient; Request *current_server_request; diff --git a/Program/include/utils.h b/Program/include/utils.h index bd505a7..8f7620f 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -15,14 +15,12 @@ This file is the header file for utils.c Purpose: This struct if our configuration for this program, these elements are set with getopt ------------------------------------------------------------------------------*/ -typedef struct CONFIG +typedef struct config { - uint32_t numOfDecks; - uint32_t startingMoney; - int timer; - char *port; - uint32_t minBet; -} CONFIG; + unsigned int timer; + uint32_t client_cfdp_id; + uint32_t my_cfdp_id; +} Config; /*------------------------------------------------------------------------------ Purpose: This is a node for the link list bellow @@ -77,5 +75,5 @@ int checkAlloc(void *mem, int notOkToFail); char **argv: the arguments Return: CONFIG * ------------------------------------------------------------------------------*/ -CONFIG *configuration(int argc, char **argv); +Config *configuration(int argc, char **argv); #endif //UTILS_H diff --git a/Program/src/main.c b/Program/src/main.c index dee7b3b..ec9e2cb 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -11,36 +11,91 @@ #include "server.h" #include "mib.h" +#include "packet.h" + +//for itoa +#include +#include + + +//exit handler variable for the main thread static int *exit_now; -int main() { +static void p(void *element, void *args) { + + + Remote_entity *remote_entity = element; + ssp_printf("[\n id: %d\n remote_ut_address: %d:%d\n]\n", + remote_entity->cfdp_id, + remote_entity->UT_address, + remote_entity->UT_port + ); + +} + +int main(int argc, char** argv) { + + //exit handler for the main thread; exit_now = prepareSignalHandler(); - Protocol_state *p_state = ssp_connectionless_server("1111"); + + //get-opt configuration + Config *conf = configuration(argc, argv); + + + //Memory information base MIB *mib = init_mib(); - p_state->mib = mib; //setting host name for testing char *host_name = "127.0.0.1"; uint32_t addr[sizeof(uint32_t)]; inet_pton(AF_INET, host_name, addr); - uint16_t port = 1111; + + //adding new cfdp entities to management information base + add_new_cfdp_entity(mib, 1, *addr, 1111); + add_new_cfdp_entity(mib, 2, *addr, 1112); + add_new_cfdp_entity(mib, 3, *addr, 1113); + add_new_cfdp_entity(mib, 4, *addr, 1114); - //adding new cfdp entity to management information base - add_new_cfdp_entity(mib, 1, *addr, port); - Client *new_client = ssp_connectionless_client(1, p_state); - Request *req = new_client->outGoing_req; + //find server client + Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, conf->my_cfdp_id, NULL, NULL); + if (server_entity == NULL) { + printf("couldn't find entity\n"); + } + + + //connectionless server + char port[17]; + + snprintf(port, 17, "%u", server_entity->UT_port); + printf("%s\n", port); + + Protocol_state *p_state = ssp_connectionless_server(port); + //set this node's Id, this has to be hardcoded/assigned + p_state->my_cfdp_id = conf->my_cfdp_id; + p_state->mib = mib; + + //print entity data + mib->remote_entities->print(mib->remote_entities, p, NULL); + + + //create a client + Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + + + //give the client a new request to perform + Request *req = new_client->outGoing_req; //build a request req->transaction_id = 1; //enumerations req->type = put; - req->dest_cfdp_id = "1"; + req->dest_cfdp_id = conf->client_cfdp_id; req->source_file_name = "test.txt"; req->destination_file_name = "test.txt"; req->segmentation_control = 0; @@ -54,6 +109,9 @@ int main() { //will block on pthread_join ssp_cleanup_client(new_client); ssp_cleanup(p_state); + free(conf); + + return 0; } diff --git a/Program/src/mib.c b/Program/src/mib.c index b50be26..c3cb834 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -33,4 +33,4 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ remote->UT_port = port; return mib->remote_entities->insert(mib->remote_entities, remote, cfdp_id); -} \ No newline at end of file +} diff --git a/Program/src/port.c b/Program/src/port.c index 31006c3..fd26f6f 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -6,6 +6,8 @@ #include #include #include "utils.h" +#include "mib.h" + #ifdef POSIX_PORT #include @@ -265,12 +267,15 @@ void ssp_cleanup_req(Request *req) { free(req); } + + void ssp_cleanup(Protocol_state *p_state) { #ifdef POSIX_PORT pthread_t * handle = (pthread_t*) p_state->server_handle; pthread_join(*handle, NULL); + free_mib(p_state->mib); free(p_state->server_handle); free(p_state->server_port); free(p_state->server_thread_attributes); @@ -288,6 +293,7 @@ void ssp_cleanup_client(Client *client) { pthread_t * handle = (pthread_t*) client->client_handle; pthread_join(*handle, NULL); #endif + ssp_cleanup_req(client->outGoing_req); free(client->incoming_req); free(client->client_handle); diff --git a/Program/src/utils.c b/Program/src/utils.c index f142305..c945a18 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -37,68 +37,45 @@ int checkAlloc(void *mem, int notOkToFail) } //see header file -CONFIG *configuration(int argc, char **argv) +Config *configuration(int argc, char **argv) { int ch; - CONFIG *conf = calloc(sizeof(CONFIG), 1); + Config *conf = calloc(sizeof(Config), 1); checkAlloc(conf, 1); - conf->numOfDecks = 2; - conf->startingMoney = 100; conf->timer = 15; - conf->port = "4420"; - conf->minBet = 1; - int tmp; - while ((ch = getopt(argc, argv, "d: m: t: p: b: h")) != -1) + uint32_t tmp; + while ((ch = getopt(argc, argv, "t: i: c: h")) != -1) { switch (ch) { - case 'd': + case 't': tmp = strtol(optarg, NULL, 10); - if (0 < tmp && tmp < 11) - conf->numOfDecks = tmp; + conf->timer = tmp; break; - case 'm': + case 'i': tmp = strtol(optarg, NULL, 10); - if (0 < tmp) - conf->startingMoney = tmp; + conf->my_cfdp_id = tmp; break; - case 't': + case 'c': tmp = strtol(optarg, NULL, 10); - if (10 < tmp && tmp < 45) - conf->timer = tmp; - break; - - case 'p': - conf->port = optarg; - break; - - case 'b': - //tmp = strtol(optarg, NULL, 10); - //if (0 < tmp && tmp < 4294967296) - // conf->minBet = tmp; + conf->client_cfdp_id = tmp; break; case 'h': printf("\n-----------HELP MESSAGE------------\n"); printf("\nusage: %s [options] \n\n", basename(argv[0])); - printf("Options: %s%s%s%s%s\n", - "-d NumberOfDecks\n", - "-m StartingMoney\n", - "-t Timer(between 15 and 45 seconds)\n", - "-p PortNumber\n", + printf("Options: %s%s%s\n", + "-t timeout\n", + "-i my cfdp id for server\n", + "-c client id\n" "-h HelpMessage"); - printf("default number of decks is 2, but can change \n%s%s%s%s%s", - "if to something between 1 and 10. Default \n", - "starting money is 100, and is good as long as it\n", - "between 0 and 4294967296 (uint32 max). \n", - "Default for timer is 15 seconds. Default port number\n", - "is 4420\n"); + printf("Default port number mis 1111\n"); printf("\n---------------END----------------\n"); break; default: @@ -290,19 +267,19 @@ static void *findElement(List *list, uint32_t id, int (*f)(void *element, void * NODE *cur = list->head->next; int found_with_func = 0; int found_with_id = 0; - while (cur->next != NULL) { - if (f != NULL) found_with_func = f(cur->element, args); if(cur->id == id) found_with_id = 1; - if (found_with_func || found_with_id) + if (found_with_func || found_with_id){ return cur->element; + } + cur = cur->next; } return NULL; From b8d29ff284a74331688142bc5eea32183c9e7ee6 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 Mar 2019 10:22:56 -0600 Subject: [PATCH 015/400] comments are my editors friend --- Program/include/packet.h | 43 +++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index ac487cf..2e0703e 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -13,20 +13,45 @@ typedef struct pdu_header{ - unsigned int version: 3; - unsigned int PDU_type: 1; //0 File directive, 1 File Data, - unsigned int direction: 1; //0 toward file receiver, 1 toward file sender - unsigned int transmission_mode: 1; //0 acknowledged, 1 unacknowledged - unsigned int CRC_flag: 1; //0 crc not present, 1 crc present - unsigned int reserved_bit_0: 1; //set to 0 + unsigned int version: 3; + + //0 File directive, 1 File Data, + unsigned int PDU_type: 1; + + //0 toward file receiver, 1 toward file sender + unsigned int direction: 1; + + //0 acknowledged, 1 unacknowledged + unsigned int transmission_mode: 1; + + //0 crc not present, 1 crc present + unsigned int CRC_flag: 1; + + //set to 0 + unsigned int reserved_bit_0: 1; + + //data field length in octets unsigned int PDU_data_field_len: 16; - unsigned int reserved_bit_1: 1; //set to 0 + + //set to 0 + unsigned int reserved_bit_1: 1; + + //length of entity ids in octets unsigned int length_of_entity_IDs: 3; + + //set to 0 unsigned int reserved_bit_2: 1; - unsigned int transaction_seq_num_len: 3; //number of octets in sequence number, 0 is one octet - //these are variable in size, and will get memory allocated based on the length variables above + + //number of octets in sequence number, 0 is one octet + unsigned int transaction_seq_num_len: 3; + + //variable in size, and will get memory allocated based on the length variables above void *source_id; + + //variable in size, and will get memory allocated based on the length variables above void *transaction_sequence_number; + + //variable in size, and will get memory allocated based on the length variables above void *destination_id; } Pdu_header; From 4ace7ab9e2caf7472328919f80e20230fde2e994 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 Mar 2019 15:49:13 -0600 Subject: [PATCH 016/400] testing converting packets to structs --- Program/include/packet.h | 2 +- Program/include/protocol_handler.h | 7 ++++-- Program/src/main.c | 4 +-- Program/src/mib.c | 5 ++++ Program/src/port.c | 40 ++++++++++++++++++++++++++++-- Program/src/protocol_handler.c | 31 +++++++++++++++-------- 6 files changed, 71 insertions(+), 18 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 2e0703e..6115b1c 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -9,7 +9,7 @@ // PACKET_HEADER_LEN + data max size = (65536 * 8) #define PACKET_MAX_LEN 524512 #define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes - +#define PACKET_STATIC_HEADER_LEN 32 typedef struct pdu_header{ diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 3d37d51..ed82314 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -50,7 +50,10 @@ typedef struct client { uint32_t cfdp_id; uint32_t unitdata_id; uint32_t unitdata_port; - + + Remote_entity *mib_info; + Pdu_header *pdu_header; + uint8_t is_active; } Client; @@ -75,5 +78,5 @@ void parse_packet_server(char* buff, Request *req, Protocol_state *p_state); void packet_handler_client(Response res, Request *req, Client *client, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); void parse_packet_client(char* buff, Request *req, Client *client, Protocol_state *p_state); - +void build_pdu_header(char* packet, Request *req, Client* client, Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index ec9e2cb..47f5b49 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -70,9 +70,7 @@ int main(int argc, char** argv) { //connectionless server char port[17]; - snprintf(port, 17, "%u", server_entity->UT_port); - printf("%s\n", port); Protocol_state *p_state = ssp_connectionless_server(port); //set this node's Id, this has to be hardcoded/assigned @@ -81,7 +79,7 @@ int main(int argc, char** argv) { //print entity data - mib->remote_entities->print(mib->remote_entities, p, NULL); + //mib->remote_entities->print(mib->remote_entities, p, NULL); //create a client diff --git a/Program/src/mib.c b/Program/src/mib.c index c3cb834..6fa6c66 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -26,6 +26,11 @@ void free_mib(MIB *mib){ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port){ Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); + + remote->CRC_required = 0; + //these will be custom set by a config file + + remote ->max_file_segment_len = 1200; checkAlloc(remote, 1); remote->UT_address = UT_address; diff --git a/Program/src/port.c b/Program/src/port.c index fd26f6f..0a72df9 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -19,7 +19,6 @@ #include #endif - #include "protocol_handler.h" void *ssp_alloc(uint32_t n_memb, size_t size) { @@ -118,8 +117,8 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { res.addr = posix_client; res.sfd = sfd; res.packet_len = client->packet_len; + user_request_handler(res, client->outGoing_req, client, p_state); - return 0; #endif @@ -245,8 +244,41 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { List *entity_list = p_state->mib->remote_entities; Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); + if (remote == NULL) + ssp_printf("couldn't find entity in Remote_entity list\n"); + + client->unitdata_port = remote->UT_port; client->unitdata_id = remote->UT_address; + client->mib_info = remote; + + //building the pdu header here + client->pdu_header = ssp_alloc(1, sizeof(Pdu_header)); + checkAlloc(client->pdu_header, 1); + + + //these will need to be set with a config file + Pdu_header* header = client->pdu_header; + header->reserved_bit_0 = 0; + header->reserved_bit_1 = 0; + header->reserved_bit_2 = 0; + header->CRC_flag = client->mib_info->CRC_required; + header->direction = 1; + header->PDU_type = 0; + header->PDU_data_field_len = 1200; + header->transaction_seq_num_len = 3; + header->transaction_sequence_number = 0; + header->length_of_entity_IDs = 1; + + header->destination_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); + checkAlloc(header->destination_id, 1); + memcpy(header->destination_id, &remote->cfdp_id, header->length_of_entity_IDs); + + + header->source_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); + checkAlloc(header->source_id, 1); + memcpy(header->source_id, &p_state->my_cfdp_id, header->length_of_entity_IDs); + //TODO lock this p_state->newClient = client; @@ -298,6 +330,10 @@ void ssp_cleanup_client(Client *client) { free(client->incoming_req); free(client->client_handle); free(client->client_thread_attributes); + free(client->pdu_header->destination_id); + free(client->pdu_header->source_id); + free(client->pdu_header); + free(client); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index f9dc8fd..06c26c6 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -5,24 +5,32 @@ #include "string.h" #include "packet.h" -static void build_put_packet(char* packet, Request *req, Client* client) { + +void build_pdu_header(char* packet, Request *req, Client* client, Protocol_state *p_state) { + //4 is the header length before id variables + memcpy(packet, client->pdu_header, PACKET_STATIC_HEADER_LEN); + //memcpy(packet, "some other stuff\n", 5); + //memcpy(&packet[PACKET_STATIC_HEADER_LEN], client->pdu_header->destination_id, client->pdu_header->length_of_entity_IDs); + //memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs], client->pdu_header->destination_id, client->pdu_header->length_of_entity_IDs); - Pdu_header header; - header.length_of_entity_IDs = 1; - header.destination_id = (uint8_t) client->cfdp_id; - header.source_id = 2; - memcpy(packet, &header, 100); + +} +static void build_put_packet(char* packet, Request *req, Client* client, Protocol_state *p_state) { + } //fills the current request with packet data, responses from servers void parse_packet_client(char* msg, Request *current_request, Client* client, Protocol_state *p_state) { - ssp_printf("server received %x\n", msg); + ssp_printf("client received %x\n", msg); } //fills the current_request struct for the server, incomming requests void parse_packet_server(char* msg, Request *current_request, Protocol_state *p_state) { - ssp_printf("server received %x\n", msg); + Pdu_header *header = (Pdu_header *) msg; + + ssp_printf("server received %s\n", msg); + ssp_printf("length of Ids %d:\n", header->length_of_entity_IDs); } //Server responses @@ -40,11 +48,14 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ //current user request, to send to client void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { + res.msg = req->buff; + build_pdu_header(res.msg, req, client, p_state); + switch (req->type) { case put: - res.msg = req->buff; - build_put_packet(res.msg, client, req); + + build_put_packet(res.msg, req, client, p_state); ssp_sendto(res); break; From 66d0992134ed58ecb8a0cc61374469dc70640c84 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 16 Mar 2019 11:47:50 -0600 Subject: [PATCH 017/400] sending correctpdu headers --- Program/include/protocol_handler.h | 2 +- Program/src/main.c | 4 -- Program/src/port.c | 1 - Program/src/protocol_handler.c | 59 +++++++++++++++++++++++------- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index ed82314..fc770cc 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -78,5 +78,5 @@ void parse_packet_server(char* buff, Request *req, Protocol_state *p_state); void packet_handler_client(Response res, Request *req, Client *client, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); void parse_packet_client(char* buff, Request *req, Client *client, Protocol_state *p_state); -void build_pdu_header(char* packet, Request *req, Client* client, Protocol_state *p_state); + #endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index 47f5b49..c74f606 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -78,10 +78,6 @@ int main(int argc, char** argv) { p_state->mib = mib; - //print entity data - //mib->remote_entities->print(mib->remote_entities, p, NULL); - - //create a client Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); diff --git a/Program/src/port.c b/Program/src/port.c index 0a72df9..9224052 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -247,7 +247,6 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { if (remote == NULL) ssp_printf("couldn't find entity in Remote_entity list\n"); - client->unitdata_port = remote->UT_port; client->unitdata_id = remote->UT_address; client->mib_info = remote; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 06c26c6..33f7de1 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -6,20 +6,28 @@ #include "packet.h" -void build_pdu_header(char* packet, Request *req, Client* client, Protocol_state *p_state) { - //4 is the header length before id variables +static void build_pdu_header(char* packet, Client* client, Protocol_state *p_state) { memcpy(packet, client->pdu_header, PACKET_STATIC_HEADER_LEN); - //memcpy(packet, "some other stuff\n", 5); - //memcpy(&packet[PACKET_STATIC_HEADER_LEN], client->pdu_header->destination_id, client->pdu_header->length_of_entity_IDs); - //memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs], client->pdu_header->destination_id, client->pdu_header->length_of_entity_IDs); - + //copy variable length src id + memcpy(&packet[PACKET_STATIC_HEADER_LEN], + client->pdu_header->source_id, + client->pdu_header->length_of_entity_IDs); + + //copy variable length transaction number id + memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs], + &client->pdu_header->transaction_sequence_number, + client->pdu_header->transaction_seq_num_len); + + //copy variable length destination id + memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs + client->pdu_header->transaction_seq_num_len], + client->pdu_header->destination_id, + client->pdu_header->length_of_entity_IDs); } - -static void build_put_packet(char* packet, Request *req, Client* client, Protocol_state *p_state) { - +static void build_put_packet(char* packet, Request *req, Client* client, Protocol_state *p_state) { } + //fills the current request with packet data, responses from servers void parse_packet_client(char* msg, Request *current_request, Client* client, Protocol_state *p_state) { ssp_printf("client received %x\n", msg); @@ -28,9 +36,35 @@ void parse_packet_client(char* msg, Request *current_request, Client* client, Pr //fills the current_request struct for the server, incomming requests void parse_packet_server(char* msg, Request *current_request, Protocol_state *p_state) { Pdu_header *header = (Pdu_header *) msg; + + uint32_t source_id = 0; + memcpy(&source_id, &msg[PACKET_STATIC_HEADER_LEN], + header->length_of_entity_IDs); + + uint32_t transaction_sequence_number = 0; + memcpy(&transaction_sequence_number, &msg[PACKET_STATIC_HEADER_LEN + header->length_of_entity_IDs], + header->transaction_seq_num_len); + + uint32_t dest_id = 0; + memcpy(&dest_id, &msg[PACKET_STATIC_HEADER_LEN + header->length_of_entity_IDs + header->transaction_seq_num_len], + header->length_of_entity_IDs); + + if (p_state->my_cfdp_id != dest_id){ + ssp_printf("someone is sending packets here that are not for me\n"); + return; + } + + + + + + + ssp_printf("server received %s\n", msg); - ssp_printf("length of Ids %d:\n", header->length_of_entity_IDs); + ssp_printf("src id %u\n",source_id); + ssp_printf("dest id %d\n", dest_id); + ssp_printf("transaction sequence number %d\n", transaction_sequence_number); } //Server responses @@ -49,12 +83,11 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { res.msg = req->buff; - build_pdu_header(res.msg, req, client, p_state); + build_pdu_header(res.msg, client, p_state); switch (req->type) { case put: - build_put_packet(res.msg, req, client, p_state); ssp_sendto(res); break; @@ -83,8 +116,6 @@ void put_request(char *dest_cfdp_id, if (checkAlloc(req, 0)) { ssp_error("cound't allocate mem for request\n"); } - - } /* From 305a84a122eaf49c9719614e7a04f4ad59a4a64b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 18 Mar 2019 17:58:19 -0600 Subject: [PATCH 018/400] add some better documentation, changed some signededness, and func for packet debugging --- Program/include/packet.h | 34 ++++++++++++++---- Program/include/port.h | 8 ++--- Program/include/protocol_handler.h | 19 +++++----- Program/include/server.h | 10 +++--- Program/src/main.c | 6 ++-- Program/src/mib.c | 4 ++- Program/src/port.c | 41 +++++++++++++++------ Program/src/protocol_handler.c | 58 ++++++++++++++++++++++-------- Program/src/server.c | 20 +++++------ 9 files changed, 137 insertions(+), 63 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 6115b1c..d52c74f 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -161,7 +161,21 @@ typedef struct filestore_response { File directive PDUs all start with a 1 byte directive code, followed by one of the following various pdu types: - - pdu_meta_data + //not implemented + -END-OF-FILE PDU + -FINISHED PDU + -ACK PDU + -NAK PDU + -PROMPT PDU + -KEEP ALIVE PDU + + //implemented + -METADATA PDU + + Non directive PDUs (when the PDU type in the header is set to 1): + -FILE DATA PDU + + @@ -179,16 +193,16 @@ typedef struct filestore_response { typedef struct pdu_directive { uint8_t directive_code; - void *pdu_type; } Pdu_directive; typedef struct pdu_meta_data { - - unsigned int segmentation_control : 1; //0 Record boundaries respeced, 1 not respected + //0 Record boundaries respeced, 1 not respected + unsigned int segmentation_control : 1; unsigned int reserved_bits: 7; - unsigned int file_size : 32; //length of the file in octets, set all 0 for unbounded size - + + //length of the file in octets, set all 0 for unbounded size + unsigned int file_size : 32; LV source_file; LV destination_file; @@ -204,4 +218,12 @@ typedef struct pdu_meta_data { } Pdu_meta_data; + +typedef struct file_data_pdu_contents { + //in octets + uint32_t offset; + //variable sized + unsigned char *data; +} File_data_pdu_contents; + #endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index 1d9d6a1..5117d0b 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,21 +9,21 @@ #include "protocol_handler.h" -void ssp_error(char *msg); -Protocol_state *ssp_connectionless_server(char *port); +void ssp_error( char *msg); +Protocol_state *ssp_connectionless_server(unsigned char *port); void *ssp_connectionless_server_task(void *protocol_state); Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); void *ssp_connectionless_client_task(void *params); -void ssp_printf(char*stuff, ...); +void ssp_printf(char *stuff, ...); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); - +void ssp_print_hex(unsigned char *stuff, uint32_t size); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index fc770cc..e543083 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -7,7 +7,7 @@ typedef struct response { int sfd; - char *msg; + unsigned char *msg; //this is type (struct sockaddr_in) in posix void *addr; //getting rid of this soon in favour of client based packet sizes @@ -25,15 +25,15 @@ typedef struct request { Indication type; uint32_t transaction_id; uint32_t dest_cfdp_id; - char *source_file_name; - char *destination_file_name; + unsigned char *source_file_name; + unsigned char *destination_file_name; uint8_t segmentation_control; uint8_t fault_handler_overides; uint8_t flow_lable; uint8_t transmission_mode; - char* messages_to_user; - char* filestore_requests; - char* buff; + unsigned char* messages_to_user; + unsigned char* filestore_requests; + unsigned char* buff; } Request; @@ -47,6 +47,7 @@ typedef struct client { Request *outGoing_req; Request *incoming_req; + //can get rid of these, these are found in mib_info anyway uint32_t cfdp_id; uint32_t unitdata_id; uint32_t unitdata_port; @@ -61,7 +62,7 @@ typedef struct client { typedef struct protocol_state { uint32_t packet_size; - char *server_port; + unsigned char *server_port; void *server_handle; void *server_thread_attributes; MIB *mib; @@ -74,9 +75,9 @@ typedef struct protocol_state { void packet_handler_server(Response res, Request *req, Protocol_state *p_state); -void parse_packet_server(char* buff, Request *req, Protocol_state *p_state); +void parse_packet_server(unsigned char* buff, uint32_t packet_len, Request *req, Protocol_state *p_state); void packet_handler_client(Response res, Request *req, Client *client, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); -void parse_packet_client(char* buff, Request *req, Client *client, Protocol_state *p_state); +void parse_packet_client(unsigned char* buff, Request *req, Client *client, Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index 7d5c6f0..b0514f4 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -17,7 +17,7 @@ This file is the header file for server.c Perameters: char *port is the port number you want to run the host on Return: It returns a socket descriptor to a UDP ready port ------------------------------------------------------------------------------*/ -int prepareUdpHost(char *port); +int prepareUdpHost(unsigned char *port); /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. @@ -42,8 +42,8 @@ int prepareUdpHost(char *port); Return: None ------------------------------------------------------------------------------*/ -void udpSelectServer(char *port, int packet_len, - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), +void udpSelectServer(unsigned char *port, int packet_len, + int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other); @@ -59,9 +59,9 @@ void udpSelectServer(char *port, int packet_len, int *prepareSignalHandler(void); -void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, +void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); + int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); #endif //SERVER_H diff --git a/Program/src/main.c b/Program/src/main.c index c74f606..0809457 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -49,7 +49,7 @@ int main(int argc, char** argv) { //setting host name for testing - char *host_name = "127.0.0.1"; + unsigned char *host_name = "127.0.0.1"; uint32_t addr[sizeof(uint32_t)]; inet_pton(AF_INET, host_name, addr); @@ -69,7 +69,7 @@ int main(int argc, char** argv) { //connectionless server - char port[17]; + unsigned char port[17]; snprintf(port, 17, "%u", server_entity->UT_port); Protocol_state *p_state = ssp_connectionless_server(port); @@ -98,7 +98,7 @@ int main(int argc, char** argv) { req->transmission_mode = 0; req->messages_to_user = "sup"; req->filestore_requests = NULL; - req->buff = calloc(new_client->packet_len, sizeof(char)); + req->buff = calloc(new_client->packet_len, sizeof(unsigned char)); //will block on pthread_join ssp_cleanup_client(new_client); diff --git a/Program/src/mib.c b/Program/src/mib.c index 6fa6c66..1db2459 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -22,7 +22,7 @@ void free_mib(MIB *mib){ ssp_free(mib); } - +//these configure peers for their specific transmission configuration int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port){ Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); @@ -30,6 +30,8 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ remote->CRC_required = 0; //these will be custom set by a config file + remote->default_transmission_mode = 1; + remote ->max_file_segment_len = 1200; checkAlloc(remote, 1); diff --git a/Program/src/port.c b/Program/src/port.c index 9224052..fdeb994 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -28,7 +28,7 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { } -void ssp_printf(char*stuff, ...) { +void ssp_printf( char *stuff, ...) { #ifdef POSIX_PORT va_list args; va_start(args, stuff); @@ -37,6 +37,28 @@ void ssp_printf(char*stuff, ...) { #endif } +void ssp_print_hex(unsigned char *stuff, uint32_t size){ + + + uint32_t row_size = 32; + uint32_t number_of_rows = size / row_size; + uint32_t current_packet_index = 0; + ssp_printf("packet size: %u\n", size); + + for (unsigned int i = 0; i < number_of_rows; i+= 1) { + + for (unsigned int j = 0; j < row_size/4; j+= 1){ + ssp_printf("%x%x%x%x..", + stuff[current_packet_index++], + stuff[current_packet_index++], + stuff[current_packet_index++], + stuff[current_packet_index++]); + } + + ssp_printf("\n"); + } +} + void ssp_error(char *msg) { @@ -58,7 +80,7 @@ void ssp_sendto(Response res) { //this function is a callback when using my posix port -static int on_recv_server(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage addr, void *other) { +static int on_recv_server(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_storage addr, void *other) { Protocol_state *p_state = (Protocol_state *) other; @@ -73,7 +95,7 @@ static int on_recv_server(int sfd, char *msg, uint32_t *buff_size, struct sockad res.packet_len = p_state->packet_size; //filles the request struct - parse_packet_server(msg, p_state->current_server_request, p_state); + parse_packet_server(msg, res.packet_len, p_state->current_server_request, p_state); //ssp_printf("Server received: %s\n", msg); packet_handler_server(res, p_state->current_server_request, p_state); @@ -81,7 +103,7 @@ static int on_recv_server(int sfd, char *msg, uint32_t *buff_size, struct sockad } -static int on_recv_client(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in addr, void *other) { +static int on_recv_client(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_in addr, void *other) { #ifdef POSIX_PORT struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; @@ -99,7 +121,6 @@ static int on_recv_client(int sfd, char *msg, uint32_t *buff_size, struct sockad //filles the request struct parse_packet_client(msg, client->incoming_req, client, p_state); - //ssp_printf("Client received: %s\n", msg); packet_handler_client(res, client->incoming_req, client, p_state); return 0; @@ -142,7 +163,7 @@ void *ssp_connectionless_server_task(void *params) { } -Protocol_state* ssp_connectionless_server(char *port) { +Protocol_state* ssp_connectionless_server(unsigned char *port) { #ifdef POSIX_PORT Protocol_state *state = calloc(sizeof(Protocol_state), 1); state->packet_size = PACKET_LEN; @@ -153,7 +174,7 @@ Protocol_state* ssp_connectionless_server(char *port) { pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); checkAlloc(attr, 1); - state->server_port = calloc(sizeof(char), 10); + state->server_port = calloc(sizeof(unsigned char), 10); checkAlloc(state->server_port, 1); strncpy (state->server_port, port, 10); @@ -190,8 +211,8 @@ void *ssp_connectionless_client_task(void* params){ Protocol_state *p_state = (Protocol_state *) params; - char host_name[INET_ADDRSTRLEN]; - char port[10]; + unsigned char host_name[INET_ADDRSTRLEN]; + unsigned char port[10]; //convert int to char * snprintf(port, 10, "%d", p_state->newClient->unitdata_port); @@ -268,6 +289,7 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { header->transaction_seq_num_len = 3; header->transaction_sequence_number = 0; header->length_of_entity_IDs = 1; + header->transmission_mode = remote->default_transmission_mode; header->destination_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); checkAlloc(header->destination_id, 1); @@ -293,7 +315,6 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { } void ssp_cleanup_req(Request *req) { - free(req->buff); free(req); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 33f7de1..1cb9965 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -5,8 +5,10 @@ #include "string.h" #include "packet.h" +//returns the location in the packet where the next pointer for tthe packet will start after the header +static uint32_t build_pdu_header(Response res, Request *req, Client* client, Protocol_state *p_state) { + unsigned char *packet = res.msg; -static void build_pdu_header(char* packet, Client* client, Protocol_state *p_state) { memcpy(packet, client->pdu_header, PACKET_STATIC_HEADER_LEN); //copy variable length src id @@ -23,18 +25,39 @@ static void build_pdu_header(char* packet, Client* client, Protocol_state *p_sta memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs + client->pdu_header->transaction_seq_num_len], client->pdu_header->destination_id, client->pdu_header->length_of_entity_IDs); + + return PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs + client->pdu_header->transaction_seq_num_len; } -static void build_put_packet(char* packet, Request *req, Client* client, Protocol_state *p_state) { +static void build_put_packet_metadata(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { + + /* + Pdu_header *header = (Pdu_header *) res.msg; + + //set header to file directive + header->PDU_type = 1; + + //set directive + Pdu_directive *directive = &res.msg[start]; + directive->directive_code = META_DATA_PDU; + + //set metadata + Pdu_meta_data *meta_data = &res.msg[start + sizeof(directive)]; + */ + return; + } + + + //fills the current request with packet data, responses from servers -void parse_packet_client(char* msg, Request *current_request, Client* client, Protocol_state *p_state) { +void parse_packet_client(unsigned char *msg, Request *current_request, Client* client, Protocol_state *p_state) { ssp_printf("client received %x\n", msg); } //fills the current_request struct for the server, incomming requests -void parse_packet_server(char* msg, Request *current_request, Protocol_state *p_state) { +void parse_packet_server(unsigned char *msg, uint32_t packet_len, Request *current_request, Protocol_state *p_state) { Pdu_header *header = (Pdu_header *) msg; uint32_t source_id = 0; @@ -49,21 +72,26 @@ void parse_packet_server(char* msg, Request *current_request, Protocol_state *p_ memcpy(&dest_id, &msg[PACKET_STATIC_HEADER_LEN + header->length_of_entity_IDs + header->transaction_seq_num_len], header->length_of_entity_IDs); + ssp_printf("server received: "); + ssp_print_hex(msg, packet_len); + if (p_state->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for me\n"); return; } - - - - + //process file directive + if (header->PDU_type == 0) { + + } + - ssp_printf("server received %s\n", msg); + ssp_printf("src id %u\n",source_id); ssp_printf("dest id %d\n", dest_id); + ssp_printf("transaction sequence number %d\n", transaction_sequence_number); } @@ -83,12 +111,12 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { res.msg = req->buff; - build_pdu_header(res.msg, client, p_state); + uint32_t start = build_pdu_header(res, req, client, p_state); switch (req->type) { case put: - build_put_packet(res.msg, req, client, p_state); + build_put_packet_metadata(res, start, req, client, p_state); ssp_sendto(res); break; @@ -102,14 +130,14 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s //data will be delivered void put_request(char *dest_cfdp_id, - char *source_file_name, - char *destination_file_name, + unsigned char *source_file_name, + unsigned char *destination_file_name, uint8_t segmentation_control, uint8_t fault_handler_overides, uint8_t flow_lable, uint8_t transmission_mode, - char* messages_to_user, - char* filestore_requests + unsigned char* messages_to_user, + unsigned char* filestore_requests ) { Request *req = ssp_alloc(1, sizeof(Request)); diff --git a/Program/src/server.c b/Program/src/server.c index d3b8303..bffdb16 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -38,7 +38,7 @@ static int exit_now; //this code is reused from assignment 1, with small changes //see header file -int prepareUdpHost(char *port) +int prepareUdpHost(unsigned char *port) { struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); @@ -128,7 +128,7 @@ int *prepareSignalHandler() return &exit_now; } -static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buff_size) { +static int resizeBuff(unsigned char **buffer, uint32_t *newBufferSize, uint32_t *prev_buff_size) { if (*newBufferSize != *prev_buff_size) { *buffer = realloc(*buffer, *newBufferSize); @@ -143,8 +143,8 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf } //see header file -void udpSelectServer(char* port, int packet_len, - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), +void udpSelectServer(unsigned char* port, int packet_len, + int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other) { @@ -164,7 +164,7 @@ void udpSelectServer(char* port, int packet_len, uint32_t prev_buff_size = *buff_size; - char *buff = calloc(sizeof(char), *buff_size); + unsigned char *buff = calloc(sizeof(unsigned char), *buff_size); checkAlloc(buff, 1); struct sockaddr_storage *client; @@ -235,9 +235,9 @@ void udpSelectServer(char* port, int packet_len, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, +void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams) + int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams) ) { int sfd, count, port_val; @@ -252,7 +252,7 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo uint32_t prev_buff_size = *buff_size; - char *buff = calloc(sizeof(char), prev_buff_size); + unsigned char *buff = calloc(sizeof(unsigned char), prev_buff_size); checkAlloc(buff, 1); prepareSignalHandler(); @@ -269,10 +269,10 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo exit(0); } - bzero((char *) &serveraddr, sizeof(serveraddr)); + bzero((unsigned char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; - bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); + bcopy((unsigned char *)server->h_addr_list[0], (unsigned char *)&serveraddr.sin_addr.s_addr, server->h_length); serveraddr.sin_port = htons(port_val); serverlen = sizeof(serveraddr); From f638123255e79c0edfdc2f36c888a0bd0b935e41 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 20 Mar 2019 11:36:41 -0600 Subject: [PATCH 019/400] Building metadata packets --- Program/include/packet.h | 17 +++++-- Program/src/port.c | 22 +++----- Program/src/protocol_handler.c | 92 +++++++++++++++++++++++++--------- 3 files changed, 87 insertions(+), 44 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index d52c74f..a26da18 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -9,7 +9,7 @@ // PACKET_HEADER_LEN + data max size = (65536 * 8) #define PACKET_MAX_LEN 524512 #define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes -#define PACKET_STATIC_HEADER_LEN 32 +#define PACKET_STATIC_HEADER_LEN 4 //in bytes typedef struct pdu_header{ @@ -190,21 +190,30 @@ typedef struct filestore_response { #define PROMPT_PDU 0x09 #define KEEP_ALIVE_PDU 0x0C +#define SIZE_OF_DIRECTIVE_CODE 1 + typedef struct pdu_directive { uint8_t directive_code; } Pdu_directive; +/* +The segmentation control parameter + - shall indicate whether the file being delivered is to be segmented as an array of octets + or as an array of variable-length records; + - shall be omitted when local and remote file names are omitted. +*/ typedef struct pdu_meta_data { - //0 Record boundaries respeced, 1 not respected + //0 Record boundaries respeced (read as array of octets), 1 not respected (variable length) unsigned int segmentation_control : 1; + unsigned int reserved_bits: 7; //length of the file in octets, set all 0 for unbounded size unsigned int file_size : 32; - LV source_file; - LV destination_file; + LV source_file_name; + LV destination_file_name; /* Options include: diff --git a/Program/src/port.c b/Program/src/port.c index fdeb994..b63bdc5 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -21,6 +21,7 @@ #endif #include "protocol_handler.h" + void *ssp_alloc(uint32_t n_memb, size_t size) { #ifdef POSIX_PORT return calloc(n_memb, size); @@ -36,27 +37,18 @@ void ssp_printf( char *stuff, ...) { va_end (args); #endif } - +//size is the number of bytes we want to print void ssp_print_hex(unsigned char *stuff, uint32_t size){ - - uint32_t row_size = 32; - uint32_t number_of_rows = size / row_size; uint32_t current_packet_index = 0; - ssp_printf("packet size: %u\n", size); + ssp_printf("printing number of bytes: %u\n", size); - for (unsigned int i = 0; i < number_of_rows; i+= 1) { - - for (unsigned int j = 0; j < row_size/4; j+= 1){ - ssp_printf("%x%x%x%x..", - stuff[current_packet_index++], - stuff[current_packet_index++], - stuff[current_packet_index++], - stuff[current_packet_index++]); + for (unsigned int j = 0; j < size; j += 1) { + ssp_printf("%x.", + stuff[current_packet_index]); + current_packet_index += 1; } - ssp_printf("\n"); - } } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1cb9965..da253cc 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -6,11 +6,10 @@ #include "packet.h" //returns the location in the packet where the next pointer for tthe packet will start after the header -static uint32_t build_pdu_header(Response res, Request *req, Client* client, Protocol_state *p_state) { +static uint8_t build_pdu_header(Response res, Request *req, Client* client, Protocol_state *p_state) { unsigned char *packet = res.msg; - memcpy(packet, client->pdu_header, PACKET_STATIC_HEADER_LEN); - + //copy variable length src id memcpy(&packet[PACKET_STATIC_HEADER_LEN], client->pdu_header->source_id, @@ -20,32 +19,71 @@ static uint32_t build_pdu_header(Response res, Request *req, Client* client, Pro memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs], &client->pdu_header->transaction_sequence_number, client->pdu_header->transaction_seq_num_len); - + //copy variable length destination id memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs + client->pdu_header->transaction_seq_num_len], client->pdu_header->destination_id, - client->pdu_header->length_of_entity_IDs); + client->pdu_header->length_of_entity_IDs); + + uint8_t total_bytes = PACKET_STATIC_HEADER_LEN + + client->pdu_header->length_of_entity_IDs + + client->pdu_header->transaction_seq_num_len + + client->pdu_header->length_of_entity_IDs; - return PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs + client->pdu_header->transaction_seq_num_len; + return total_bytes; } -static void build_put_packet_metadata(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { - - /* +static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { Pdu_header *header = (Pdu_header *) res.msg; - + //set header to file directive header->PDU_type = 1; - //set directive - Pdu_directive *directive = &res.msg[start]; + uint8_t packet_index = start; + + //set directive 1 byte + Pdu_directive *directive = &res.msg[packet_index]; directive->directive_code = META_DATA_PDU; + packet_index += SIZE_OF_DIRECTIVE_CODE; + Pdu_meta_data *meta_data_packet = &res.msg[packet_index]; + + //1 bytes + meta_data_packet->segmentation_control = 0; + meta_data_packet->reserved_bits = 0; - //set metadata - Pdu_meta_data *meta_data = &res.msg[start + sizeof(directive)]; - */ - return; + //4 bytes + meta_data_packet->file_size = 1; + packet_index += 5; + + //variable length params + uint8_t src_file_name_length = 5; + uint8_t destination_file_length = 7; + char *src_file_name = "hero"; + char *destination_file_name = "thereo"; + + + //copy source length to packet (1 bytes) + memcpy(&res.msg[packet_index], &src_file_name_length, src_file_name_length); + packet_index++; + //copy source name to packet (length bytes) + memcpy(&res.msg[packet_index], src_file_name, src_file_name_length); + packet_index += src_file_name_length; + + + //copy length to packet (1 byte) + memcpy(&res.msg[packet_index], &destination_file_length, 1); + packet_index++; + + //copy destination name to packet (length bytes) + memcpy(&res.msg[packet_index], destination_file_name, destination_file_length); + packet_index += destination_file_length; + uint8_t total_bytes = packet_index - start; + + ssp_printf("------------printing_metadata_contents-----------\n"); + ssp_print_hex(&res.msg[start], total_bytes); + + return packet_index; } @@ -65,15 +103,18 @@ void parse_packet_server(unsigned char *msg, uint32_t packet_len, Request *curre header->length_of_entity_IDs); uint32_t transaction_sequence_number = 0; - memcpy(&transaction_sequence_number, &msg[PACKET_STATIC_HEADER_LEN + header->length_of_entity_IDs], + memcpy(&transaction_sequence_number, &msg[PACKET_STATIC_HEADER_LEN + + header->length_of_entity_IDs], header->transaction_seq_num_len); uint32_t dest_id = 0; - memcpy(&dest_id, &msg[PACKET_STATIC_HEADER_LEN + header->length_of_entity_IDs + header->transaction_seq_num_len], + memcpy(&dest_id, &msg[PACKET_STATIC_HEADER_LEN + + header->length_of_entity_IDs + + header->transaction_seq_num_len], header->length_of_entity_IDs); ssp_printf("server received: "); - ssp_print_hex(msg, packet_len); + if (p_state->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for me\n"); @@ -85,14 +126,12 @@ void parse_packet_server(unsigned char *msg, uint32_t packet_len, Request *curre } - + //ssp_printf("src id %u\n",source_id); + //ssp_printf("dest id %d\n", dest_id); + //ssp_printf("transaction sequence number %d\n", transaction_sequence_number); - - ssp_printf("src id %u\n",source_id); - ssp_printf("dest id %d\n", dest_id); - - ssp_printf("transaction sequence number %d\n", transaction_sequence_number); + memset(msg, 0, packet_len); } //Server responses @@ -112,6 +151,9 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s res.msg = req->buff; uint32_t start = build_pdu_header(res, req, client, p_state); + + ssp_printf("\n..................printing_header..................\n"); + ssp_print_hex(res.msg, start); switch (req->type) { From 0b3a960e36beb0fef79019d0a21bdf963c3f9bed Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 24 Mar 2019 12:53:30 -0600 Subject: [PATCH 020/400] getting ready to write incoming file data --- Program/include/filesystem_funcs.h | 18 +++ Program/include/packet.h | 2 +- Program/include/port.h | 12 +- Program/include/protocol_handler.h | 41 ++++++ Program/include/utils.h | 1 + Program/src/filesystem_funcs.c | 53 ++++++++ Program/src/main.c | 27 +--- Program/src/makefile | 1 + Program/src/port.c | 88 ++++++++++--- Program/src/protocol_handler.c | 201 +++++++++++++++++++---------- Program/src/utils.c | 15 ++- Program/test/main.c | 62 +++++---- Program/test/makefile | 5 +- 13 files changed, 379 insertions(+), 147 deletions(-) create mode 100644 Program/include/filesystem_funcs.h create mode 100644 Program/src/filesystem_funcs.c diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h new file mode 100644 index 0000000..9e7386c --- /dev/null +++ b/Program/include/filesystem_funcs.h @@ -0,0 +1,18 @@ + +#ifndef FILESYSTEM_FUNCS_H +#define FILESYSTEM_FUNCS_H +#include + +typedef struct file { + int fd; + uint32_t total_size; +} File; + +uint32_t get_file_size(unsigned char *source_file_name); + +//allocates space for a file pointer +File *create_file(unsigned char *source_file_name); +void free_file(void *file); + + +#endif diff --git a/Program/include/packet.h b/Program/include/packet.h index a26da18..9cf21f9 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -211,7 +211,7 @@ typedef struct pdu_meta_data { unsigned int reserved_bits: 7; //length of the file in octets, set all 0 for unbounded size - unsigned int file_size : 32; + uint32_t file_size; LV source_file_name; LV destination_file_name; diff --git a/Program/include/port.h b/Program/include/port.h index 5117d0b..d2ae0be 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -6,6 +6,7 @@ #define STACK_ALLOCATION 16384 #define POSIX_PORT 1 +#define MAX_PATH 255 #include "protocol_handler.h" @@ -18,17 +19,16 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); void *ssp_connectionless_client_task(void *params); void ssp_printf(char *stuff, ...); - +Request *init_request(uint32_t buff_len); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); void ssp_print_hex(unsigned char *stuff, uint32_t size); - - - - - +int ssp_open(char *pathname, int flags); +int ssp_read(int fd, unsigned char* buff, size_t size); +int ssp_lseek(int fd, int offset, int whence); +void ssp_error(char *error); void ssp_free(void *pointer); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index e543083..371cf85 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -4,6 +4,7 @@ #include "utils.h" #include "packet.h" #include "mib.h" +#include "filesystem_funcs.h" typedef struct response { int sfd; @@ -25,14 +26,22 @@ typedef struct request { Indication type; uint32_t transaction_id; uint32_t dest_cfdp_id; + + File *file; + uint32_t file_size; + unsigned char *source_file_name; unsigned char *destination_file_name; + uint8_t segmentation_control; uint8_t fault_handler_overides; uint8_t flow_lable; uint8_t transmission_mode; + unsigned char* messages_to_user; unsigned char* filestore_requests; + + uint32_t buff_len; unsigned char* buff; } Request; @@ -69,6 +78,8 @@ typedef struct protocol_state { uint32_t my_cfdp_id; Client *newClient; Request *current_server_request; + uint32_t transaction_id; + uint8_t verbose_level; } Protocol_state; @@ -80,4 +91,34 @@ void packet_handler_client(Response res, Request *req, Client *client, Protocol_ void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); void parse_packet_client(unsigned char* buff, Request *req, Client *client, Protocol_state *p_state); + +/* + unsigned char *source_file_name, + unsigned char *destination_file_name, + uint8_t segmentation_control, + uint8_t fault_handler_overides, + uint8_t flow_lable, + uint8_t transmission_mode, + unsigned char* messages_to_user, + unsigned char* filestore_requests, + Client *client, + Protocol_state *p_state +*/ +//returns -1 on error +int put_request( + unsigned char *source_file_name, + unsigned char *destination_file_name, + uint8_t segmentation_control, + uint8_t fault_handler_overides, + uint8_t flow_lable, + uint8_t transmission_mode, + unsigned char* messages_to_user, + unsigned char* filestore_requests, + Client *client, + Protocol_state *p_state + ); + + + + #endif \ No newline at end of file diff --git a/Program/include/utils.h b/Program/include/utils.h index 8f7620f..9d5466e 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -20,6 +20,7 @@ typedef struct config unsigned int timer; uint32_t client_cfdp_id; uint32_t my_cfdp_id; + uint8_t verbose_level; } Config; /*------------------------------------------------------------------------------ diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c new file mode 100644 index 0000000..fba6c13 --- /dev/null +++ b/Program/src/filesystem_funcs.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + + +uint32_t get_file_size(unsigned char *source_file_name) { + + int fd = ssp_open(source_file_name, 0); + if (fd == -1){ + return -1; + } + + int bytes = ssp_lseek(fd, 0, 2); + if (bytes == -1){ + return -1; + } + + ssp_lseek(fd, 0, 0); + + if (ssp_close(fd) == -1){ + return -1; + } + + return bytes; +} + + +File *create_file(unsigned char *source_file_name) { + + int fd = ssp_open(source_file_name, O_RDWR | O_CREAT); + if (fd == -1){ + ssp_error("couldn't open file\n"); + return NULL; + } + + uint32_t total_size = get_file_size(source_file_name); + if (total_size == -1){ + ssp_error("couldn't get file size\n"); + return NULL; + } + + File *file = ssp_alloc(1, sizeof(File)); + file->fd = fd; + file->total_size = total_size; + + return file; + +} + +void free_file(void *file) { + ssp_free(file); +} \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index 0809457..8b42609 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -21,18 +21,17 @@ //exit handler variable for the main thread static int *exit_now; - +/* static void p(void *element, void *args) { - Remote_entity *remote_entity = element; ssp_printf("[\n id: %d\n remote_ut_address: %d:%d\n]\n", remote_entity->cfdp_id, remote_entity->UT_address, remote_entity->UT_port ); - } +*/ int main(int argc, char** argv) { @@ -61,7 +60,7 @@ int main(int argc, char** argv) { add_new_cfdp_entity(mib, 4, *addr, 1114); - //find server client + //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, conf->my_cfdp_id, NULL, NULL); if (server_entity == NULL) { printf("couldn't find entity\n"); @@ -76,30 +75,14 @@ int main(int argc, char** argv) { //set this node's Id, this has to be hardcoded/assigned p_state->my_cfdp_id = conf->my_cfdp_id; p_state->mib = mib; + p_state->verbose_level = conf->verbose_level; //create a client Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - //give the client a new request to perform - Request *req = new_client->outGoing_req; - - //build a request - req->transaction_id = 1; - //enumerations - req->type = put; - req->dest_cfdp_id = conf->client_cfdp_id; - req->source_file_name = "test.txt"; - req->destination_file_name = "test.txt"; - req->segmentation_control = 0; - req->fault_handler_overides = 0; - req->flow_lable = 0; - req->transmission_mode = 0; - req->messages_to_user = "sup"; - req->filestore_requests = NULL; - req->buff = calloc(new_client->packet_len, sizeof(unsigned char)); - //will block on pthread_join ssp_cleanup_client(new_client); ssp_cleanup(p_state); diff --git a/Program/src/makefile b/Program/src/makefile index ef0da3d..8d06563 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -10,6 +10,7 @@ CFILES += server.c #used for poxix port CFILES += protocol_handler.c CFILES += list_callbacks.c CFILES += mib.c +CFILES += filesystem_funcs.c #entrypoint MAIN = main diff --git a/Program/src/port.c b/Program/src/port.c index b63bdc5..8a39d87 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -7,7 +7,7 @@ #include #include "utils.h" #include "mib.h" - +#include "filesystem_funcs.h" #ifdef POSIX_PORT #include @@ -17,10 +17,24 @@ #include #include #include + #include #endif #include "protocol_handler.h" +int ssp_read(int fd, unsigned char* buff, size_t size) { + #ifdef POSIX_PORT + return read(fd, buff, size); + #endif + +} + +//SEEK_END 2 SEEK_CUR 1 SEEK_SET 0 +int ssp_lseek(int fd, int offset, int whence) { + #ifdef POSIX_PORT + return lseek(fd, offset, whence); + #endif +} void *ssp_alloc(uint32_t n_memb, size_t size) { #ifdef POSIX_PORT @@ -28,6 +42,18 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { #endif } +int ssp_open(char *pathname, int flags) { + #ifdef POSIX_PORT + return open(pathname, flags); + #endif +} + +int ssp_close(int fd) { + #ifdef POSIX_PORT + return close(fd); + #endif + +} void ssp_printf( char *stuff, ...) { #ifdef POSIX_PORT @@ -35,6 +61,13 @@ void ssp_printf( char *stuff, ...) { va_start(args, stuff); vfprintf(stdout, stuff, args); va_end (args); + fflush(stdout); + #endif +} + +void ssp_error(char *error){ + #ifdef POSIX_PORT + perror(error); #endif } //size is the number of bytes we want to print @@ -51,15 +84,6 @@ void ssp_print_hex(unsigned char *stuff, uint32_t size){ ssp_printf("\n"); } - -void ssp_error(char *msg) { - - #ifdef POSIX_PORT - perror(msg); - #endif - -} - void ssp_sendto(Response res) { #ifdef POSIX_PORT @@ -71,6 +95,7 @@ void ssp_sendto(Response res) { } + //this function is a callback when using my posix port static int on_recv_server(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_storage addr, void *other) { @@ -138,7 +163,7 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { } //this function is a callback when using my posix ports -static int on_time_out_posix(void *other) { +static int on_time_out_posix(void *other) { return 0; } @@ -146,6 +171,7 @@ static int on_time_out_posix(void *other) { void *ssp_connectionless_server_task(void *params) { Protocol_state* state = (Protocol_state*) params; + state->transaction_id = 0; #ifdef POSIX_PORT udpSelectServer(state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, state); @@ -190,7 +216,8 @@ Protocol_state* ssp_connectionless_server(unsigned char *port) { if (0 != err) perror("ERROR pthread_create"); - state->current_server_request = calloc(1, sizeof(Request)); + state->current_server_request = init_request(state->packet_size); + state->server_handle = handler; state->server_thread_attributes = attr; return state; @@ -224,11 +251,8 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { Client *client = calloc(sizeof(Client), 1); checkAlloc(client, 1); - client->outGoing_req = calloc(1, (sizeof(Request))); - checkAlloc(client->outGoing_req, 1); - - client->incoming_req = calloc(1, (sizeof(Request))); - checkAlloc(client->incoming_req, 1); + client->outGoing_req = init_request(PACKET_LEN); + client->incoming_req = init_request(PACKET_LEN); pthread_t *handler = calloc(sizeof(pthread_t), 1); checkAlloc(handler, 1); @@ -306,7 +330,31 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { } -void ssp_cleanup_req(Request *req) { + +Request *init_request(uint32_t buff_len) { + + Request *req = calloc(1, sizeof(Request)); + + req->source_file_name = ssp_alloc(MAX_PATH, sizeof(char)); + checkAlloc(req->source_file_name, 1); + + req->destination_file_name = ssp_alloc(MAX_PATH, sizeof(char)); + checkAlloc(req->destination_file_name, 1); + + + req->file = NULL; + req->buff_len = buff_len; + req->buff = ssp_alloc(buff_len, sizeof(char)); + checkAlloc(req->buff, 1); + return req; +} + +static void ssp_cleanup_req(Request *req) { + if (req->file != NULL) + free_file(req->file); + + free(req->source_file_name); + free(req->destination_file_name); free(req->buff); free(req); } @@ -319,11 +367,11 @@ void ssp_cleanup(Protocol_state *p_state) { pthread_t * handle = (pthread_t*) p_state->server_handle; pthread_join(*handle, NULL); + ssp_cleanup_req(p_state->current_server_request); free_mib(p_state->mib); free(p_state->server_handle); free(p_state->server_port); free(p_state->server_thread_attributes); - free(p_state->current_server_request); free(p_state); #endif @@ -339,7 +387,7 @@ void ssp_cleanup_client(Client *client) { #endif ssp_cleanup_req(client->outGoing_req); - free(client->incoming_req); + ssp_cleanup_req(client->incoming_req); free(client->client_handle); free(client->client_thread_attributes); free(client->pdu_header->destination_id); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index da253cc..6fccf9a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -36,8 +36,8 @@ static uint8_t build_pdu_header(Response res, Request *req, Client* client, Prot static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { Pdu_header *header = (Pdu_header *) res.msg; - //set header to file directive - header->PDU_type = 1; + //set header to file directive 0 is directive, 1 is data + header->PDU_type = 0; uint8_t packet_index = start; @@ -48,18 +48,18 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * Pdu_meta_data *meta_data_packet = &res.msg[packet_index]; //1 bytes - meta_data_packet->segmentation_control = 0; + meta_data_packet->segmentation_control = req->segmentation_control; meta_data_packet->reserved_bits = 0; //4 bytes - meta_data_packet->file_size = 1; + meta_data_packet->file_size = req->file_size; packet_index += 5; //variable length params - uint8_t src_file_name_length = 5; - uint8_t destination_file_length = 7; - char *src_file_name = "hero"; - char *destination_file_name = "thereo"; + uint8_t src_file_name_length = strnlen(req->source_file_name, MAX_PATH); + uint8_t destination_file_length = strnlen(req->destination_file_name, MAX_PATH); + char *src_file_name = req->source_file_name; + char *destination_file_name = req->destination_file_name; //copy source length to packet (1 bytes) @@ -78,15 +78,87 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * memcpy(&res.msg[packet_index], destination_file_name, destination_file_length); packet_index += destination_file_length; uint8_t total_bytes = packet_index - start; + return packet_index; +} - ssp_printf("------------printing_metadata_contents-----------\n"); - ssp_print_hex(&res.msg[start], total_bytes); - return packet_index; + +//Omission of source and destination filenames shall indicate that only Meta +//data will be delivered +int put_request(unsigned char *source_file_name, + unsigned char *destination_file_name, + uint8_t segmentation_control, + uint8_t fault_handler_overides, + uint8_t flow_lable, + uint8_t transmission_mode, + unsigned char* messages_to_user, + unsigned char* filestore_requests, + Client *client, + Protocol_state *p_state + ) { + + + uint32_t file_size = get_file_size(source_file_name); + + if (file_size == -1) + return -1; + + //give the client a new request to perform + Request *req = client->outGoing_req; + + //build a request + req->transaction_id = p_state->transaction_id++; + //enumeration + req->type = put; + req->dest_cfdp_id = client->cfdp_id; + req->file_size = file_size; + + memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + + req->segmentation_control = segmentation_control; + req->fault_handler_overides = fault_handler_overides; + req->flow_lable = flow_lable; + req->transmission_mode = transmission_mode; + req->messages_to_user = messages_to_user; + req->filestore_requests = filestore_requests; } +static void process_file_request(Request *req) { + + //check if file exists, if it doesn't create it + + req->file = create_file(req->destination_file_name); +} + + + + +static void fill_request(unsigned char *packet, Request *req_to_fill) { + + Pdu_meta_data *meta_data = packet; + req_to_fill->segmentation_control = meta_data->segmentation_control; + + uint8_t packet_index = 4; + + uint32_t file_size = (uint32_t)packet[packet_index]; + req_to_fill->file_size = file_size; + packet_index++; + + uint8_t file_name_len = packet[packet_index]; + packet_index++; + + memcpy(req_to_fill->source_file_name, &packet[packet_index], file_name_len); + packet_index += file_name_len + 1; + + file_name_len = packet[packet_index]; + memcpy(req_to_fill->destination_file_name, &packet[packet_index], file_name_len); + packet_index += file_name_len; + + return; +} //fills the current request with packet data, responses from servers @@ -95,43 +167,59 @@ void parse_packet_client(unsigned char *msg, Request *current_request, Client* c } //fills the current_request struct for the server, incomming requests -void parse_packet_server(unsigned char *msg, uint32_t packet_len, Request *current_request, Protocol_state *p_state) { - Pdu_header *header = (Pdu_header *) msg; +void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *current_request, Protocol_state *p_state) { + + uint8_t packet_index = PACKET_STATIC_HEADER_LEN; + Pdu_header *header = (Pdu_header *) packet; uint32_t source_id = 0; - memcpy(&source_id, &msg[PACKET_STATIC_HEADER_LEN], - header->length_of_entity_IDs); + memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); + packet_index += header->length_of_entity_IDs; uint32_t transaction_sequence_number = 0; - memcpy(&transaction_sequence_number, &msg[PACKET_STATIC_HEADER_LEN - + header->length_of_entity_IDs], - header->transaction_seq_num_len); + memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); + packet_index += header->transaction_seq_num_len; uint32_t dest_id = 0; - memcpy(&dest_id, &msg[PACKET_STATIC_HEADER_LEN - + header->length_of_entity_IDs - + header->transaction_seq_num_len], - header->length_of_entity_IDs); + memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); + packet_index += header->length_of_entity_IDs; - ssp_printf("server received: "); - + + if (p_state->verbose_level == 3) { + ssp_printf("------------printing_header_received------------\n"); + ssp_print_hex(packet, packet_index); + } if (p_state->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for me\n"); return; } - //process file directive - if (header->PDU_type == 0) { - + //process file data + if (header->PDU_type == 1) { + if (p_state->verbose_level == 3) + ssp_printf("receiving data\n"); + + return; } + current_request->dest_cfdp_id = source_id; + Pdu_directive *directive = &packet[packet_index]; + packet_index++; + + switch (directive->directive_code) + { + case META_DATA_PDU: + fill_request(&packet[packet_index], current_request); + process_file_request(current_request); + + break; - //ssp_printf("src id %u\n",source_id); - //ssp_printf("dest id %d\n", dest_id); - //ssp_printf("transaction sequence number %d\n", transaction_sequence_number); + default: + break; + } - memset(msg, 0, packet_len); + memset(packet, 0, packet_len); } //Server responses @@ -149,53 +237,28 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ //current user request, to send to client void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { + if (req->type == none) + return; + + res.msg = req->buff; uint32_t start = build_pdu_header(res, req, client, p_state); - - ssp_printf("\n..................printing_header..................\n"); - ssp_print_hex(res.msg, start); switch (req->type) { case put: - build_put_packet_metadata(res, start, req, client, p_state); + start = build_put_packet_metadata(res, start, req, client, p_state); + + if (p_state->verbose_level == 3) { + ssp_printf("------------sending_a_put_request------------\n"); + ssp_print_hex(res.msg, start); + } + ssp_sendto(res); + //req->type = none; break; - default: break; } -} - -//Omission of source and destination filenames shall indicate that only Meta -//data will be delivered - -void put_request(char *dest_cfdp_id, - unsigned char *source_file_name, - unsigned char *destination_file_name, - uint8_t segmentation_control, - uint8_t fault_handler_overides, - uint8_t flow_lable, - uint8_t transmission_mode, - unsigned char* messages_to_user, - unsigned char* filestore_requests - ) { - - Request *req = ssp_alloc(1, sizeof(Request)); - if (checkAlloc(req, 0)) { - ssp_error("cound't allocate mem for request\n"); - } -} - -/* -(destination CFDP entity ID, -[source file name], -[destination file name], -[segmentation control], -[fault handler overrides], -[flow label], -[transmission mode], -[messages to user], -[filestore requests]) -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/Program/src/utils.c b/Program/src/utils.c index c945a18..ba2ac57 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -25,6 +25,7 @@ to use for general functionality. //see header file int checkAlloc(void *mem, int notOkToFail) { + if (mem == NULL && notOkToFail) { perror("malloc"); @@ -36,6 +37,7 @@ int checkAlloc(void *mem, int notOkToFail) return 1; } + //see header file Config *configuration(int argc, char **argv) { @@ -44,9 +46,10 @@ Config *configuration(int argc, char **argv) checkAlloc(conf, 1); conf->timer = 15; + conf->verbose_level = 0; uint32_t tmp; - while ((ch = getopt(argc, argv, "t: i: c: h")) != -1) + while ((ch = getopt(argc, argv, "t: i: c: v: h")) != -1) { switch (ch) { @@ -59,6 +62,11 @@ Config *configuration(int argc, char **argv) tmp = strtol(optarg, NULL, 10); conf->my_cfdp_id = tmp; break; + + case 'v': + tmp = strtol(optarg, NULL, 10); + conf->verbose_level = (uint8_t) tmp; + break; case 'c': tmp = strtol(optarg, NULL, 10); @@ -69,10 +77,11 @@ Config *configuration(int argc, char **argv) case 'h': printf("\n-----------HELP MESSAGE------------\n"); printf("\nusage: %s [options] \n\n", basename(argv[0])); - printf("Options: %s%s%s\n", + printf("Options: %s%s%s%s\n", "-t timeout\n", "-i my cfdp id for server\n", - "-c client id\n" + "-c client id\n", + "-v verbose level (1-3)" "-h HelpMessage"); printf("Default port number mis 1111\n"); diff --git a/Program/test/main.c b/Program/test/main.c index c33be08..7c44fd1 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -33,7 +33,6 @@ static int list_remove(void *element, void *args) { static void list_print(void *element, void *args) { struct myStruct *st = (struct myStruct *)element; - printf("list print: %d\n", st->id); @@ -48,18 +47,30 @@ static int find(void *element, void *args) { static void list_free(void *element) { - free(element); } int main () { + char **ptr,*ptr1,*ptr2,*ptr3; - List *list = linked_list(); + ptr = malloc(sizeof(char*) * 2); + ptr1 = malloc(1); + ptr2 = malloc(1); + + *ptr1 = 'h'; + *ptr2 = 'i'; + + ptr[0] = ptr1; + ptr[1] = ptr2; + printf("%c%c\n", *ptr[0], *ptr[1]); -//static void *findElement(List *list, int (*f)(void *element, void *args), void *args) + + /* + List *list = linked_list(); + //static void *findElement(List *list, int (*f)(void *element, void *args), void *args) struct myStruct *st = malloc(sizeof(struct myStruct)); struct myStruct *st2 = malloc(sizeof(struct myStruct)); @@ -70,38 +81,41 @@ int main () { st2->id = 2; st2->b = 3; - + st3->id = 3; st3->b = 4; - list->add(list, st); - list->add(list, st2); - list->add(list, st3); + list->push(list, st, 1); + list->push(list, st2, 2); + list->push(list, st3, 3); - - int id = 1; - struct myStruct *found = list->find(list, find, &id); - printf("found %d\n", found->b); - - id = 2; - found = list->find(list, find, &id); - printf("found %d\n", found->b); - - id = 3; - found = list->find(list, find, &id); - printf("found %d\n", found->b); + list->pop(list); + list->print(list, list_print, NULL); + printf("\n\n"); - list->print(list, list_print, NULL); + list->insert(list, st3, 3); + list->print(list, list_print, NULL); + //list_free(list->pop(list)); + + int id = 1; + struct myStruct *found = list->find(list, 1, NULL, NULL); + printf("found %d\n", found->id); - list->remove(list, list_remove, &id); + id = 2; + found = list->find(list, 2, find, &id); + printf("found %d\n", found->id); + found = list->find(list, 3, NULL, NULL); + printf("found %d\n", found->id); - list->print(list, list_print, NULL); + free(list->remove(list, "3", NULL, NULL)); + free(list->remove(list, "2", NULL, NULL)); + list->print(list, list_print, NULL); list->free(list, list_free); - + */ return 0; } \ No newline at end of file diff --git a/Program/test/makefile b/Program/test/makefile index dabb7f1..9a8deba 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -4,10 +4,11 @@ INCLUDE += -I$(PROJDIR)/include CC = gcc #---------------------------File Names--------------------------- -#CFILES += udpClient.c +CFILES += $(PROJDIR)/src/utils.c +#VPATH = (PROJDIR)/src #entrypoint -MAIN = udpClient +MAIN = main #---------------------------Compiler Warnings--------------------------- CWARNS += -W From ed8f8fad4e2eb33d86e0975e8e6084cbe83debfc Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 25 Mar 2019 17:31:45 -0600 Subject: [PATCH 021/400] sending data packets, TODO write data, send EOF packet --- Program/include/filesystem_funcs.h | 4 +- Program/include/protocol_handler.h | 6 +- Program/src/filesystem_funcs.c | 34 ++++++ Program/src/port.c | 3 +- Program/src/protocol_handler.c | 186 ++++++++++++++++++++--------- 5 files changed, 175 insertions(+), 58 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 9e7386c..77ff381 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -6,6 +6,7 @@ typedef struct file { int fd; uint32_t total_size; + } File; uint32_t get_file_size(unsigned char *source_file_name); @@ -13,6 +14,7 @@ uint32_t get_file_size(unsigned char *source_file_name); //allocates space for a file pointer File *create_file(unsigned char *source_file_name); void free_file(void *file); - +int does_file_exist(unsigned char *source_file_name); +get_offset(File *file, void *buff, uint32_t buf_size, uint32_t offset); #endif diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 371cf85..208de55 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -19,7 +19,11 @@ typedef struct response { typedef enum Indication { none, transaction, - put + put, + + //sending data + sending_data + } Indication; typedef struct request { diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index fba6c13..4bb11fe 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -3,6 +3,7 @@ #include #include +#include uint32_t get_file_size(unsigned char *source_file_name) { @@ -48,6 +49,39 @@ File *create_file(unsigned char *source_file_name) { } + +int does_file_exist(unsigned char *source_file_name) { + + int fd = ssp_open(source_file_name, O_RDWR); + if (fd == -1){ + return 0; + } + if (ssp_close(fd) == -1){ + return -1; + } + + return 1; +} + + +int get_offset(File *file, void *buff, uint32_t buf_size, uint32_t offset) { + + + if (offset >= file->total_size) + return -1; + + ssp_lseek(file->fd, SEEK_SET, (int) offset); + + int bytes = ssp_read(file->fd, buff, buf_size); + + if (bytes == -1) + return -1; + + return bytes; + +} + + void free_file(void *file) { ssp_free(file); } \ No newline at end of file diff --git a/Program/src/port.c b/Program/src/port.c index 8a39d87..e58eb5d 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -44,7 +44,8 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { int ssp_open(char *pathname, int flags) { #ifdef POSIX_PORT - return open(pathname, flags); + //open with read and write permissions + return open(pathname, flags, 0666); #endif } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 6fccf9a..054790a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -5,6 +5,10 @@ #include "string.h" #include "packet.h" + + + + //returns the location in the packet where the next pointer for tthe packet will start after the header static uint8_t build_pdu_header(Response res, Request *req, Client* client, Protocol_state *p_state) { unsigned char *packet = res.msg; @@ -81,59 +85,40 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * return packet_index; } - - - -//Omission of source and destination filenames shall indicate that only Meta -//data will be delivered -int put_request(unsigned char *source_file_name, - unsigned char *destination_file_name, - uint8_t segmentation_control, - uint8_t fault_handler_overides, - uint8_t flow_lable, - uint8_t transmission_mode, - unsigned char* messages_to_user, - unsigned char* filestore_requests, - Client *client, - Protocol_state *p_state - ) { - - - uint32_t file_size = get_file_size(source_file_name); +//requires a req->file to be created +//returns 1 on end of file +static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { - if (file_size == -1) - return -1; + uint32_t packet_index = start; + File_data_pdu_contents *packet_offset = &res.msg[packet_index]; - //give the client a new request to perform - Request *req = client->outGoing_req; + //4 bytes + packet_offset->offset = 1; + packet_index += 4; - //build a request - req->transaction_id = p_state->transaction_id++; - //enumeration - req->type = put; - req->dest_cfdp_id = client->cfdp_id; - req->file_size = file_size; + uint32_t data_size = client->packet_len - packet_index; - memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); - memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + //fill the rest of the packet with data + int bytes = get_offset(req->file, &res.msg[packet_index], data_size, 0); - req->segmentation_control = segmentation_control; - req->fault_handler_overides = fault_handler_overides; - req->flow_lable = flow_lable; - req->transmission_mode = transmission_mode; - req->messages_to_user = messages_to_user; - req->filestore_requests = filestore_requests; + if (bytes < data_size) + return 1; + return 0; } - +//TODO write file data static void process_file_request(Request *req) { //check if file exists, if it doesn't create it - - req->file = create_file(req->destination_file_name); -} + //printf("%s\n", req->destination_file_name); + //printf("%d\n", get_file_size(req->destination_file_name)); + if (does_file_exist(req->destination_file_name)) + return; + if (req->file == NULL) + req->file = create_file(req->destination_file_name); +} static void fill_request(unsigned char *packet, Request *req_to_fill) { @@ -161,11 +146,42 @@ static void fill_request(unsigned char *packet, Request *req_to_fill) { } +/*------------------------------------------------------------------------------ + + REMOTE SIDE + aka: handles responses from server + +------------------------------------------------------------------------------*/ + + + //fills the current request with packet data, responses from servers void parse_packet_client(unsigned char *msg, Request *current_request, Client* client, Protocol_state *p_state) { ssp_printf("client received %x\n", msg); } + +//Client responses +void packet_handler_client(Response res, Request *req, Client* client, Protocol_state *p_state) { + //res.msg = "Client Received!\n"; + //ssp_sendto(res); +} + + +/*------------------------------------------------------------------------------ + + SERVER SIDE + aka: handles responses from remote + +------------------------------------------------------------------------------*/ + +//Server responses +void packet_handler_server(Response res, Request *current_request, Protocol_state *p_state) { + //res.msg = "Server Received\n"; + //ssp_sendto(res); +} + + //fills the current_request struct for the server, incomming requests void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *current_request, Protocol_state *p_state) { @@ -222,26 +238,26 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu memset(packet, 0, packet_len); } -//Server responses -void packet_handler_server(Response res, Request *current_request, Protocol_state *p_state) { - //res.msg = "Server Received\n"; - //ssp_sendto(res); -} -//Client responses -void packet_handler_client(Response res, Request *req, Client* client, Protocol_state *p_state) { - //res.msg = "Client Received!\n"; - //ssp_sendto(res); -} -//current user request, to send to client + +/*------------------------------------------------------------------------------ + + USER STUFF + aka: request from person + +------------------------------------------------------------------------------*/ + + +//current user request, to send to remote void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { if (req->type == none) return; - res.msg = req->buff; + memset(res.msg, 0, client->packet_len); + uint32_t start = build_pdu_header(res, req, client, p_state); switch (req->type) @@ -255,10 +271,70 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s } ssp_sendto(res); - //req->type = none; + req->type = sending_data; + break; + case sending_data: + + if (build_data_packet(res, start, req, client, p_state) && p_state->verbose_level == 3) + ssp_printf("reached end of file\n"); + + if (p_state->verbose_level == 3) { + ssp_printf("------------sending_a_data_packets-----------\n"); + ssp_print_hex(res.msg, start); + } + ssp_sendto(res); + default: break; } -} \ No newline at end of file +} + + + + + + + +//Omission of source and destination filenames shall indicate that only Meta +//data will be delivered +int put_request(unsigned char *source_file_name, + unsigned char *destination_file_name, + uint8_t segmentation_control, + uint8_t fault_handler_overides, + uint8_t flow_lable, + uint8_t transmission_mode, + unsigned char* messages_to_user, + unsigned char* filestore_requests, + Client *client, + Protocol_state *p_state + ) { + + uint32_t file_size = get_file_size(source_file_name); + + if (file_size == -1) + return -1; + + //give the client a new request to perform + Request *req = client->outGoing_req; + req->file = create_file(source_file_name); + //build a request + req->transaction_id = p_state->transaction_id++; + //enumeration + req->type = put; + req->dest_cfdp_id = client->cfdp_id; + req->file_size = file_size; + + memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + + req->segmentation_control = segmentation_control; + req->fault_handler_overides = fault_handler_overides; + req->flow_lable = flow_lable; + req->transmission_mode = transmission_mode; + req->messages_to_user = messages_to_user; + req->filestore_requests = filestore_requests; +} + + From 130d60c4bb66ac63c0818a935f9195e56e565669 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 27 Mar 2019 13:50:35 -0600 Subject: [PATCH 022/400] writing partial data packets --- Program/include/filesystem_funcs.h | 3 +- Program/include/port.h | 2 +- Program/src/filesystem_funcs.c | 44 +++++++++--- Program/src/port.c | 8 ++- Program/src/protocol_handler.c | 107 ++++++++++++++++++----------- 5 files changed, 110 insertions(+), 54 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 77ff381..4240890 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -15,6 +15,7 @@ uint32_t get_file_size(unsigned char *source_file_name); File *create_file(unsigned char *source_file_name); void free_file(void *file); int does_file_exist(unsigned char *source_file_name); -get_offset(File *file, void *buff, uint32_t buf_size, uint32_t offset); +int get_offset(File *file, void *buff, uint32_t buf_size, int offset); +int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); #endif diff --git a/Program/include/port.h b/Program/include/port.h index d2ae0be..3c904d6 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -29,7 +29,7 @@ int ssp_open(char *pathname, int flags); int ssp_read(int fd, unsigned char* buff, size_t size); int ssp_lseek(int fd, int offset, int whence); void ssp_error(char *error); - +int ssp_write(int fd, const void *buf, size_t count); void ssp_free(void *pointer); #endif \ No newline at end of file diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 4bb11fe..d3fe5d4 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -27,14 +27,23 @@ uint32_t get_file_size(unsigned char *source_file_name) { } + + + + File *create_file(unsigned char *source_file_name) { int fd = ssp_open(source_file_name, O_RDWR | O_CREAT); if (fd == -1){ - ssp_error("couldn't open file\n"); - return NULL; + ssp_error("couldn't create file\n"); + fd = ssp_open(source_file_name, O_RDWR); + if (fd == -1) { + ssp_error("count not open file\n"); + return NULL; + } } + uint32_t total_size = get_file_size(source_file_name); if (total_size == -1){ ssp_error("couldn't get file size\n"); @@ -64,23 +73,40 @@ int does_file_exist(unsigned char *source_file_name) { } -int get_offset(File *file, void *buff, uint32_t buf_size, uint32_t offset) { - +int get_offset(File *file, void *buff, uint32_t buf_size, int offset) { if (offset >= file->total_size) return -1; - ssp_lseek(file->fd, SEEK_SET, (int) offset); + ssp_lseek(file->fd, SEEK_SET, offset); int bytes = ssp_read(file->fd, buff, buf_size); - - if (bytes == -1) - return -1; - + if (bytes == -1){ + ssp_error("Could not read\n"); + } + return bytes; } +int write_offset(File *file, void *buff, uint32_t size, uint32_t offset) { + + if (file == NULL) { + ssp_error("Could not write, File struct is not created\n"); + return -1; + } + + ssp_lseek(file->fd, SEEK_SET, (int) offset); + int bytes = ssp_write(file->fd, buff, (size_t) size); + + if (bytes == -1){ + ssp_error("Could not write\n"); + } + if (bytes < size && bytes >= 0){ + ssp_error("did not write all the bytes, this could be because the disk is full\n"); + } + return bytes; +} void free_file(void *file) { ssp_free(file); diff --git a/Program/src/port.c b/Program/src/port.c index e58eb5d..7a62f52 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -2,7 +2,6 @@ #include "packet.h" #include "server.h" #include "port.h" - #include #include #include "utils.h" @@ -22,6 +21,13 @@ #endif #include "protocol_handler.h" +int ssp_write(int fd, const void *buf, size_t count) { + #ifdef POSIX_PORT + return write(fd, buf, count); + #endif +} + + int ssp_read(int fd, unsigned char* buff, size_t size) { #ifdef POSIX_PORT return read(fd, buff, size); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 054790a..fa2e4fb 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -88,58 +88,76 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * //requires a req->file to be created //returns 1 on end of file static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { - + Pdu_header *header = (Pdu_header *) res.msg; + //set header to file directive 0 is directive, 1 is data + header->PDU_type = 1; + uint32_t packet_index = start; File_data_pdu_contents *packet_offset = &res.msg[packet_index]; + //4 bytes - packet_offset->offset = 1; + packet_offset->offset = 0; packet_index += 4; uint32_t data_size = client->packet_len - packet_index; //fill the rest of the packet with data - int bytes = get_offset(req->file, &res.msg[packet_index], data_size, 0); + int bytes = get_offset(req->file, &res.msg[packet_index], data_size, packet_offset->offset); if (bytes < data_size) return 1; + return 0; } -//TODO write file data -static void process_file_request(Request *req) { +//TODO This needs more work, file handling when files already exist ect +static int process_file_request(Request *req) { - //check if file exists, if it doesn't create it - //printf("%s\n", req->destination_file_name); - //printf("%d\n", get_file_size(req->destination_file_name)); + if (does_file_exist(req->destination_file_name)){ + ssp_error("file already exists, overwriting it\n"); + req->file = create_file(req->destination_file_name); + return 1; + } + if (req->file == NULL) { + ssp_printf("%s\n", req->destination_file_name); + req->file = create_file(req->destination_file_name); + } + return 1; +} - if (does_file_exist(req->destination_file_name)) - return; - if (req->file == NULL) - req->file = create_file(req->destination_file_name); +static void write_packet_data_to_file(char *data_packet, uint32_t packet_len, File *file) { + File_data_pdu_contents *packet = data_packet; + uint32_t offset = 0; + memcpy(&offset, data_packet, 4); + + //ssp_printf("packet offset received: %d\n", packet->offset); + int bytes = write_offset(file, &data_packet[4], packet_len - 4, offset); } -static void fill_request(unsigned char *packet, Request *req_to_fill) { +static void fill_request(unsigned char *meta_data_packet, Request *req_to_fill) { - Pdu_meta_data *meta_data = packet; + Pdu_meta_data *meta_data = meta_data_packet; req_to_fill->segmentation_control = meta_data->segmentation_control; uint8_t packet_index = 4; - uint32_t file_size = (uint32_t)packet[packet_index]; + uint32_t file_size = (uint32_t)meta_data_packet[packet_index]; req_to_fill->file_size = file_size; packet_index++; - uint8_t file_name_len = packet[packet_index]; + uint8_t file_name_len = meta_data_packet[packet_index]; packet_index++; - - memcpy(req_to_fill->source_file_name, &packet[packet_index], file_name_len); + + + memcpy(req_to_fill->source_file_name, &meta_data_packet[packet_index], file_name_len); + packet_index += file_name_len + 1; + file_name_len = meta_data_packet[packet_index]; + memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); - file_name_len = packet[packet_index]; - memcpy(req_to_fill->destination_file_name, &packet[packet_index], file_name_len); packet_index += file_name_len; return; @@ -213,9 +231,12 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu //process file data if (header->PDU_type == 1) { - if (p_state->verbose_level == 3) - ssp_printf("receiving data\n"); - + if (current_request->file == NULL) { + ssp_printf("why is file null?\n"); + return; + } + + write_packet_data_to_file(&packet[packet_index], packet_len, current_request->file); return; } @@ -229,6 +250,7 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu fill_request(&packet[packet_index], current_request); process_file_request(current_request); + break; default: @@ -262,28 +284,29 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s switch (req->type) { - case put: - start = build_put_packet_metadata(res, start, req, client, p_state); - - if (p_state->verbose_level == 3) { - ssp_printf("------------sending_a_put_request------------\n"); - ssp_print_hex(res.msg, start); - } + case sending_data: + if (build_data_packet(res, start, req, client, p_state)) + ssp_printf("reached end of file\n"); + + if (p_state->verbose_level == 3) { + ssp_printf("------------sending_a_data_packets-----------\n"); + ssp_print_hex(res.msg, start); + } + ssp_sendto(res); + break; - ssp_sendto(res); - req->type = sending_data; + case put: + start = build_put_packet_metadata(res, start, req, client, p_state); + + if (p_state->verbose_level == 3) { + ssp_printf("------------sending_a_put_request------------\n"); + ssp_print_hex(res.msg, start); + } + ssp_sendto(res); + req->type = sending_data; break; - case sending_data: - - if (build_data_packet(res, start, req, client, p_state) && p_state->verbose_level == 3) - ssp_printf("reached end of file\n"); - - if (p_state->verbose_level == 3) { - ssp_printf("------------sending_a_data_packets-----------\n"); - ssp_print_hex(res.msg, start); - } - ssp_sendto(res); + default: break; From f887638362377521bd4b9cfdbdd24b179a866774 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 27 Mar 2019 19:54:12 -0600 Subject: [PATCH 023/400] Add EOF packet struct, and make packets propperly variable --- Program/include/packet.h | 29 +++++++++++++++++++++++++++++ Program/include/protocol_handler.h | 1 + Program/src/main.c | 2 ++ Program/src/port.c | 6 +++--- Program/src/protocol_handler.c | 26 +++++++++++++++++--------- Program/src/server.c | 3 --- 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 9cf21f9..d04ea4f 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -235,4 +235,33 @@ typedef struct file_data_pdu_contents { unsigned char *data; } File_data_pdu_contents; + +typedef struct pdu_eof { + unsigned int condition_code : 4; + unsigned int spare : 4; + uint32_t checksum; + /* In octets. This value shall be the total number of file data octets + transmitted by the sender, regardless of the condition code + (i.e., it shall be supplied even if the condition code is other than + ‘No error’). */ + uint32_t file_size; + + /* + Omitted if condition code is ‘No error’. Otherwise, entity ID in the + TLV is the ID of the entity at which transaction cancellation was + initiated.*/ + TLV fault_location; + +} Pdu_eof; + + + + + + + + + + + #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 208de55..b1e803a 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -8,6 +8,7 @@ typedef struct response { int sfd; + //this is a pointer to buff in a request unsigned char *msg; //this is type (struct sockaddr_in) in posix void *addr; diff --git a/Program/src/main.c b/Program/src/main.c index 8b42609..6e716c3 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -80,6 +80,8 @@ int main(int argc, char** argv) { //create a client Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + + put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); diff --git a/Program/src/port.c b/Program/src/port.c index 7a62f52..666c028 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -224,7 +224,6 @@ Protocol_state* ssp_connectionless_server(unsigned char *port) { perror("ERROR pthread_create"); state->current_server_request = init_request(state->packet_size); - state->server_handle = handler; state->server_thread_attributes = attr; return state; @@ -300,7 +299,9 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { checkAlloc(client->pdu_header, 1); - //these will need to be set with a config file + //these will need to be set with a config file, or dynamically based on the + //packet being sent + Pdu_header* header = client->pdu_header; header->reserved_bit_0 = 0; header->reserved_bit_1 = 0; @@ -318,7 +319,6 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { checkAlloc(header->destination_id, 1); memcpy(header->destination_id, &remote->cfdp_id, header->length_of_entity_IDs); - header->source_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); checkAlloc(header->source_id, 1); memcpy(header->source_id, &p_state->my_cfdp_id, header->length_of_entity_IDs); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index fa2e4fb..1e0604b 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -81,7 +81,11 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * //copy destination name to packet (length bytes) memcpy(&res.msg[packet_index], destination_file_name, destination_file_length); packet_index += destination_file_length; + uint8_t total_bytes = packet_index - start; + + //mark the size of the packet + header->PDU_data_field_len = total_bytes; return packet_index; } @@ -92,19 +96,21 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli //set header to file directive 0 is directive, 1 is data header->PDU_type = 1; - uint32_t packet_index = start; + uint16_t packet_index = start; File_data_pdu_contents *packet_offset = &res.msg[packet_index]; - - //4 bytes + //4 bytes is the size of the offset paramater packet_offset->offset = 0; packet_index += 4; - uint32_t data_size = client->packet_len - packet_index; + uint16_t data_size = client->packet_len - packet_index; //fill the rest of the packet with data int bytes = get_offset(req->file, &res.msg[packet_index], data_size, packet_offset->offset); + //add bytes read, and the packet offset to the data_field length + header->PDU_data_field_len = bytes + 4; + if (bytes < data_size) return 1; @@ -127,13 +133,12 @@ static int process_file_request(Request *req) { } -static void write_packet_data_to_file(char *data_packet, uint32_t packet_len, File *file) { +static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { File_data_pdu_contents *packet = data_packet; - uint32_t offset = 0; - memcpy(&offset, data_packet, 4); + uint32_t offset = packet->offset; //ssp_printf("packet offset received: %d\n", packet->offset); - int bytes = write_offset(file, &data_packet[4], packet_len - 4, offset); + int bytes = write_offset(file, &data_packet[4], data_len - 4, offset); } @@ -218,6 +223,9 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; + uint16_t packet_data_len = header->PDU_data_field_len; + + ssp_printf("packet data length %d\n", packet_data_len); if (p_state->verbose_level == 3) { ssp_printf("------------printing_header_received------------\n"); @@ -236,7 +244,7 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu return; } - write_packet_data_to_file(&packet[packet_index], packet_len, current_request->file); + write_packet_data_to_file(&packet[packet_index], packet_data_len, current_request->file); return; } diff --git a/Program/src/server.c b/Program/src/server.c index bffdb16..8753a07 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -281,19 +281,16 @@ void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void if (exit_now) break; - if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ printf("packet too large, cannot resize buffer\n"); } - sleep(1); /* print the server's reply */ if (onSend(sfd, serveraddr, onSendParams)) printf("send failed\n"); - count = recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, (struct sockaddr*)&serveraddr, &serverlen); if (count == -1) From 95274d01ea054c9e294ca9ed39214b254585b9ae Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 28 Mar 2019 09:53:26 -0600 Subject: [PATCH 024/400] Add Eof packet --- Program/include/packet.h | 23 ++++++++++++ Program/include/protocol_handler.h | 2 +- Program/src/protocol_handler.c | 60 +++++++++++++++++++++++++----- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index d04ea4f..c9b75e8 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -192,6 +192,29 @@ typedef struct filestore_response { #define SIZE_OF_DIRECTIVE_CODE 1 +//condition codes: + +#define COND_NO_ERROR 0x00 +/* +‘0000’ No error +‘0001’ Positive ACK limit reached +‘0010’ Keep alive limit reached +‘0011’ Invalid transmission mode +‘0100’ Filestore rejection +‘0101’ File checksum failure +‘0110’ File size error +‘0111’ NAK limit reached +‘1000’ Inactivity detected +‘1001’ Invalid file structure +‘1010’ Check limit reached +‘1011’ – ‘1101’ +CCSDS 727.0-B-4 +Condition +(reserved) +‘1110’ Suspend.request received +‘1111’ Cancel.request received +*/ + typedef struct pdu_directive { uint8_t directive_code; diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index b1e803a..5f162b9 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -21,7 +21,7 @@ typedef enum Indication { none, transaction, put, - + eof, //sending data sending_data diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1e0604b..f346905 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -117,6 +117,42 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli return 0; } +static void build_eof_packet(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { + + Pdu_header *header = (Pdu_header *) res.msg; + //set header to file directive 0 is directive, 1 is data + header->PDU_type = 0; + + uint8_t packet_index = (uint8_t) start; + Pdu_directive *directive = &res.msg[packet_index]; + directive->directive_code = EOF_PDU; + packet_index++; + + Pdu_eof *packet = &res.msg[packet_index]; + + //this will be need to set from the req struct probably. + //4 bits, + packet->condition_code = COND_NO_ERROR; + //4 bits reserved bits + packet->spare = 0; + packet_index++; + + //4 bytes + packet->file_size = req->file_size; + packet_index += 4; + + //TODO checksum procedures + packet->checksum = 0; + packet_index += 4; + + + //TODO addTLV fault_location + + header->PDU_data_field_len = packet_index - start; + +} + + //TODO This needs more work, file handling when files already exist ect static int process_file_request(Request *req) { @@ -134,6 +170,9 @@ static int process_file_request(Request *req) { static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { + if(file == NULL) + ssp_error("file struct is null, can't write to file"); + File_data_pdu_contents *packet = data_packet; uint32_t offset = packet->offset; @@ -239,11 +278,6 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu //process file data if (header->PDU_type == 1) { - if (current_request->file == NULL) { - ssp_printf("why is file null?\n"); - return; - } - write_packet_data_to_file(&packet[packet_index], packet_data_len, current_request->file); return; } @@ -257,10 +291,12 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu case META_DATA_PDU: fill_request(&packet[packet_index], current_request); process_file_request(current_request); - - break; + case EOF_PDU: + ssp_printf("received EOF pdu\n"); + + break; default: break; } @@ -292,10 +328,16 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s switch (req->type) { + case eof: + build_eof_packet(res, start, req, client, p_state); + ssp_sendto(res); + req->type = none; + break; + case sending_data: if (build_data_packet(res, start, req, client, p_state)) - ssp_printf("reached end of file\n"); - + req->type = eof; + if (p_state->verbose_level == 3) { ssp_printf("------------sending_a_data_packets-----------\n"); ssp_print_hex(res.msg, start); From 3d56e063708a4ae305067bc853eb53dd2416cd85 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 29 Mar 2019 07:44:48 -0600 Subject: [PATCH 025/400] Add checksum function --- Program/include/filesystem_funcs.h | 2 ++ Program/include/protocol_handler.h | 5 ++++- Program/src/filesystem_funcs.c | 36 ++++++++++++++++++++++++------ Program/src/main.c | 2 +- Program/src/port.c | 2 -- Program/src/protocol_handler.c | 31 +++++++++++++++---------- Program/test/main.c | 8 +++++-- 7 files changed, 61 insertions(+), 25 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 4240890..92c3dae 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -5,6 +5,7 @@ typedef struct file { int fd; + uint32_t next_offset_to_send; uint32_t total_size; } File; @@ -17,5 +18,6 @@ void free_file(void *file); int does_file_exist(unsigned char *source_file_name); int get_offset(File *file, void *buff, uint32_t buf_size, int offset); int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); +uint32_t calc_check_sum(char *data, uint32_t length); #endif diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 5f162b9..227690e 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -29,7 +29,7 @@ typedef enum Indication { typedef struct request { Indication type; - uint32_t transaction_id; + uint64_t transaction_sequence_number; uint32_t dest_cfdp_id; File *file; @@ -83,7 +83,10 @@ typedef struct protocol_state { uint32_t my_cfdp_id; Client *newClient; Request *current_server_request; + + //lock this uint32_t transaction_id; + uint8_t verbose_level; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index d3fe5d4..ec560bc 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -1,8 +1,8 @@ #include -#include +#include "port.h" +#include "filesystem_funcs.h" #include #include - #include uint32_t get_file_size(unsigned char *source_file_name) { @@ -26,11 +26,6 @@ uint32_t get_file_size(unsigned char *source_file_name) { return bytes; } - - - - - File *create_file(unsigned char *source_file_name) { int fd = ssp_open(source_file_name, O_RDWR | O_CREAT); @@ -52,6 +47,7 @@ File *create_file(unsigned char *source_file_name) { File *file = ssp_alloc(1, sizeof(File)); file->fd = fd; + file->next_offset_to_send = 0; file->total_size = total_size; return file; @@ -110,4 +106,30 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset) { void free_file(void *file) { ssp_free(file); +} + + + +uint32_t calc_check_sum(char *data, uint32_t length) { + uint8_t remaining_bytes = length % 4; + uint32_t check_sum = 0; + + for (unsigned int i = 0; i < length; i+= 4){ + check_sum += *((uint32_t *) &data[i]); + } + + if (remaining_bytes){ + uint8_t last_chunk[4]; + memset(last_chunk, 0, 4); + + uint32_t end = length - remaining_bytes; + + for (uint8_t i = 0; i < remaining_bytes; i++) { + last_chunk[i] = data[end + i];; + } + + check_sum += *((uint32_t*) &last_chunk); + } + + return check_sum; } \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index 6e716c3..d416163 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -71,7 +71,7 @@ int main(int argc, char** argv) { unsigned char port[17]; snprintf(port, 17, "%u", server_entity->UT_port); - Protocol_state *p_state = ssp_connectionless_server(port); + Protocol_state *p_state = ssp_connectionless_server(port); //set this node's Id, this has to be hardcoded/assigned p_state->my_cfdp_id = conf->my_cfdp_id; p_state->mib = mib; diff --git a/Program/src/port.c b/Program/src/port.c index 666c028..32b6256 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -309,9 +309,7 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { header->CRC_flag = client->mib_info->CRC_required; header->direction = 1; header->PDU_type = 0; - header->PDU_data_field_len = 1200; header->transaction_seq_num_len = 3; - header->transaction_sequence_number = 0; header->length_of_entity_IDs = 1; header->transmission_mode = remote->default_transmission_mode; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index f346905..5d1ddee 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -21,7 +21,7 @@ static uint8_t build_pdu_header(Response res, Request *req, Client* client, Prot //copy variable length transaction number id memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs], - &client->pdu_header->transaction_sequence_number, + &req->transaction_sequence_number, client->pdu_header->transaction_seq_num_len); //copy variable length destination id @@ -92,6 +92,12 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * //requires a req->file to be created //returns 1 on end of file static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { + + if (req->file->next_offset_to_send > req->file->total_size){ + ssp_error("cant send an offset past the file's length\n"); + return -1; + } + Pdu_header *header = (Pdu_header *) res.msg; //set header to file directive 0 is directive, 1 is data header->PDU_type = 1; @@ -99,14 +105,15 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli uint16_t packet_index = start; File_data_pdu_contents *packet_offset = &res.msg[packet_index]; - //4 bytes is the size of the offset paramater - packet_offset->offset = 0; + //4 bytes is the size of the offset paramater TODO set offset + packet_offset->offset = req->file->next_offset_to_send; packet_index += 4; uint16_t data_size = client->packet_len - packet_index; //fill the rest of the packet with data int bytes = get_offset(req->file, &res.msg[packet_index], data_size, packet_offset->offset); + req->file->next_offset_to_send += bytes; //add bytes read, and the packet offset to the data_field length header->PDU_data_field_len = bytes + 4; @@ -147,14 +154,13 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* //TODO addTLV fault_location - header->PDU_data_field_len = packet_index - start; } //TODO This needs more work, file handling when files already exist ect -static int process_file_request(Request *req) { +static int process_file_request_metadata(Request *req) { if (does_file_exist(req->destination_file_name)){ ssp_error("file already exists, overwriting it\n"); @@ -181,7 +187,7 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil } -static void fill_request(unsigned char *meta_data_packet, Request *req_to_fill) { +static void fill_request_pdu_metadata(unsigned char *meta_data_packet, Request *req_to_fill) { Pdu_meta_data *meta_data = meta_data_packet; req_to_fill->segmentation_control = meta_data->segmentation_control; @@ -254,6 +260,7 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; + //TODO the transaction number should get the request from data structure hosting requests uint32_t transaction_sequence_number = 0; memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); packet_index += header->transaction_seq_num_len; @@ -264,18 +271,17 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu uint16_t packet_data_len = header->PDU_data_field_len; - ssp_printf("packet data length %d\n", packet_data_len); if (p_state->verbose_level == 3) { ssp_printf("------------printing_header_received------------\n"); ssp_print_hex(packet, packet_index); + ssp_printf("packet data length %d, sequence number %d\n", packet_data_len, transaction_sequence_number); } if (p_state->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for me\n"); return; } - //process file data if (header->PDU_type == 1) { write_packet_data_to_file(&packet[packet_index], packet_data_len, current_request->file); @@ -289,11 +295,12 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu switch (directive->directive_code) { case META_DATA_PDU: - fill_request(&packet[packet_index], current_request); - process_file_request(current_request); + fill_request_pdu_metadata(&packet[packet_index], current_request); + process_file_request_metadata(current_request); break; case EOF_PDU: + ssp_printf("received EOF pdu\n"); break; @@ -392,8 +399,8 @@ int put_request(unsigned char *source_file_name, //give the client a new request to perform Request *req = client->outGoing_req; req->file = create_file(source_file_name); - //build a request - req->transaction_id = p_state->transaction_id++; + //build a request + req->transaction_sequence_number = p_state->transaction_id++; //enumeration req->type = put; req->dest_cfdp_id = client->cfdp_id; diff --git a/Program/test/main.c b/Program/test/main.c index 7c44fd1..427899d 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -1,7 +1,6 @@ #include "utils.h" - #include #include #include @@ -10,6 +9,7 @@ #include #include #include +#include "filesystem_funcs.h" struct myStruct { int id; @@ -53,6 +53,10 @@ static void list_free(void *element) { int main () { + char *packet = "hello world"; + uint32_t checksum = calc_check_sum(packet, 10); + printf("%d\n", checksum); + /* char **ptr,*ptr1,*ptr2,*ptr3; ptr = malloc(sizeof(char*) * 2); @@ -68,7 +72,7 @@ int main () { printf("%c%c\n", *ptr[0], *ptr[1]); - /* + List *list = linked_list(); //static void *findElement(List *list, int (*f)(void *element, void *args), void *args) From 30e55fb7719246fe1739ed4b961f625a67f2defb Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 31 Mar 2019 14:34:07 -0600 Subject: [PATCH 026/400] close file on EOF --- Program/include/filesystem_funcs.h | 9 +++++--- Program/include/protocol_handler.h | 8 +++---- Program/src/filesystem_funcs.c | 29 +++++++++++++++++++---- Program/src/protocol_handler.c | 37 ++++++++++++++++++++++-------- Program/src/server.c | 1 - Program/test/main.c | 5 ++++ 6 files changed, 66 insertions(+), 23 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 92c3dae..3b22753 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -3,21 +3,24 @@ #define FILESYSTEM_FUNCS_H #include + typedef struct file { int fd; uint32_t next_offset_to_send; uint32_t total_size; + uint32_t partial_checksum; } File; -uint32_t get_file_size(unsigned char *source_file_name); +uint32_t get_file_size(char *source_file_name); //allocates space for a file pointer -File *create_file(unsigned char *source_file_name); +File *create_file(char *source_file_name); void free_file(void *file); -int does_file_exist(unsigned char *source_file_name); +int does_file_exist(char *source_file_name); int get_offset(File *file, void *buff, uint32_t buf_size, int offset); int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); uint32_t calc_check_sum(char *data, uint32_t length); +uint32_t check_sum_file(File *file, uint16_t stack_buffer); #endif diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 227690e..b196e4c 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -114,14 +114,14 @@ void parse_packet_client(unsigned char* buff, Request *req, Client *client, Prot */ //returns -1 on error int put_request( - unsigned char *source_file_name, - unsigned char *destination_file_name, + char *source_file_name, + char *destination_file_name, uint8_t segmentation_control, uint8_t fault_handler_overides, uint8_t flow_lable, uint8_t transmission_mode, - unsigned char* messages_to_user, - unsigned char* filestore_requests, + char* messages_to_user, + char* filestore_requests, Client *client, Protocol_state *p_state ); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index ec560bc..b7e0341 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -5,7 +5,7 @@ #include #include -uint32_t get_file_size(unsigned char *source_file_name) { +uint32_t get_file_size(char *source_file_name) { int fd = ssp_open(source_file_name, 0); if (fd == -1){ @@ -26,7 +26,7 @@ uint32_t get_file_size(unsigned char *source_file_name) { return bytes; } -File *create_file(unsigned char *source_file_name) { +File *create_file(char *source_file_name) { int fd = ssp_open(source_file_name, O_RDWR | O_CREAT); if (fd == -1){ @@ -46,16 +46,18 @@ File *create_file(unsigned char *source_file_name) { } File *file = ssp_alloc(1, sizeof(File)); + file->fd = fd; file->next_offset_to_send = 0; file->total_size = total_size; - + file->partial_checksum = 0; + return file; } -int does_file_exist(unsigned char *source_file_name) { +int does_file_exist(char *source_file_name) { int fd = ssp_open(source_file_name, O_RDWR); if (fd == -1){ @@ -68,7 +70,7 @@ int does_file_exist(unsigned char *source_file_name) { return 1; } - +//modifys the seek location, returns bytes read int get_offset(File *file, void *buff, uint32_t buf_size, int offset) { if (offset >= file->total_size) @@ -132,4 +134,21 @@ uint32_t calc_check_sum(char *data, uint32_t length) { } return check_sum; +} + + +//stack buffer is the size of the packet length +uint32_t check_sum_file(File *file, uint16_t stack_buffer) { + + char buff[stack_buffer]; + uint32_t checksum = 0; + uint32_t bytes_read = 0; + for (int i = 0; i < file->total_size; i++) { + + bytes_read = get_offset(file, buff, stack_buffer, (int) stack_buffer); + if (bytes_read > 0) + checksum += calc_check_sum(buff, bytes_read); + } + + return checksum; } \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 5d1ddee..600bd80 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -113,11 +113,16 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli //fill the rest of the packet with data int bytes = get_offset(req->file, &res.msg[packet_index], data_size, packet_offset->offset); + + //calculate checksum for data packet, this is used to calculate in transit checksums + req->file->partial_checksum += calc_check_sum(&res.msg[packet_index], data_size); + req->file->next_offset_to_send += bytes; //add bytes read, and the packet offset to the data_field length header->PDU_data_field_len = bytes + 4; + if (bytes < data_size) return 1; @@ -145,20 +150,30 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* packet_index++; //4 bytes - packet->file_size = req->file_size; + packet->file_size = req->file->total_size; packet_index += 4; //TODO checksum procedures - packet->checksum = 0; + packet->checksum = req->file->partial_checksum; packet_index += 4; - //TODO addTLV fault_location header->PDU_data_field_len = packet_index - start; } +static void process_pdu_eof(char *packet, Request *req) { + + Pdu_eof *eof_packet = (Pdu_eof *) packet; + if (eof_packet->checksum == req->file->partial_checksum) { + ssp_printf("File received\n", req->file->partial_checksum); + if (ssp_close(req->file->fd) == -1) + ssp_error("could not close file\n"); + + } +} + //TODO This needs more work, file handling when files already exist ect static int process_file_request_metadata(Request *req) { @@ -179,11 +194,14 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil if(file == NULL) ssp_error("file struct is null, can't write to file"); + File_data_pdu_contents *packet = data_packet; uint32_t offset = packet->offset; //ssp_printf("packet offset received: %d\n", packet->offset); + int bytes = write_offset(file, &data_packet[4], data_len - 4, offset); + file->partial_checksum += calc_check_sum(&data_packet[4], data_len - 4); } @@ -271,7 +289,6 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu uint16_t packet_data_len = header->PDU_data_field_len; - if (p_state->verbose_level == 3) { ssp_printf("------------printing_header_received------------\n"); ssp_print_hex(packet, packet_index); @@ -300,8 +317,8 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu break; case EOF_PDU: - - ssp_printf("received EOF pdu\n"); + process_pdu_eof(&packet[packet_index], current_request); + break; default: @@ -379,14 +396,14 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s //Omission of source and destination filenames shall indicate that only Meta //data will be delivered -int put_request(unsigned char *source_file_name, - unsigned char *destination_file_name, +int put_request(char *source_file_name, + char *destination_file_name, uint8_t segmentation_control, uint8_t fault_handler_overides, uint8_t flow_lable, uint8_t transmission_mode, - unsigned char* messages_to_user, - unsigned char* filestore_requests, + char* messages_to_user, + char* filestore_requests, Client *client, Protocol_state *p_state ) { diff --git a/Program/src/server.c b/Program/src/server.c index 8753a07..b58fcc1 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -285,7 +285,6 @@ void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void printf("packet too large, cannot resize buffer\n"); } - sleep(1); /* print the server's reply */ if (onSend(sfd, serveraddr, onSendParams)) printf("send failed\n"); diff --git a/Program/test/main.c b/Program/test/main.c index 427899d..e61b5d7 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -56,6 +56,11 @@ int main () { char *packet = "hello world"; uint32_t checksum = calc_check_sum(packet, 10); printf("%d\n", checksum); + + File *file = create_file("test2.txt"); + + checksum = check_sum_file(file, file->total_size, 20000); + printf("%d\n", checksum); /* char **ptr,*ptr1,*ptr2,*ptr3; From f5d805a9425ff50aa85f2a0590f29d0eca1a984c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 2 Apr 2019 17:43:59 -0600 Subject: [PATCH 027/400] Staging before wokring on pdu file size bug --- Program/include/filesystem_funcs.h | 11 ++- Program/include/port.h | 2 +- Program/include/utils.h | 6 ++ Program/src/filesystem_funcs.c | 119 ++++++++++++++++++++++++++--- Program/src/main.c | 2 +- Program/src/protocol_handler.c | 65 ++++++++++++---- Program/src/utils.c | 65 ++++++++++++++-- Program/test/main.c | 37 ++++++++- 8 files changed, 270 insertions(+), 37 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 3b22753..f531ba3 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -3,24 +3,31 @@ #define FILESYSTEM_FUNCS_H #include +typedef struct offset { + uint32_t start; + uint32_t end; +} Offset; + typedef struct file { int fd; uint32_t next_offset_to_send; uint32_t total_size; uint32_t partial_checksum; + uint32_t eof_checksum; + List *missing_offsets; } File; uint32_t get_file_size(char *source_file_name); //allocates space for a file pointer -File *create_file(char *source_file_name); +File *create_file(char *source_file_name, int clear_file_contents); void free_file(void *file); int does_file_exist(char *source_file_name); int get_offset(File *file, void *buff, uint32_t buf_size, int offset); int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); uint32_t calc_check_sum(char *data, uint32_t length); uint32_t check_sum_file(File *file, uint16_t stack_buffer); - +void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end); #endif diff --git a/Program/include/port.h b/Program/include/port.h index 3c904d6..972cad0 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -30,6 +30,6 @@ int ssp_read(int fd, unsigned char* buff, size_t size); int ssp_lseek(int fd, int offset, int whence); void ssp_error(char *error); int ssp_write(int fd, const void *buf, size_t count); - +int ssp_close(int fd); void ssp_free(void *pointer); #endif \ No newline at end of file diff --git a/Program/include/utils.h b/Program/include/utils.h index 9d5466e..08ccdbe 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -49,8 +49,11 @@ typedef struct List void (*free)(struct List *list, void (*f)(void *element)); void *(*pop) (struct List *list); int (*insert) (struct List *list, void *element, uint32_t id); + int (*insertAt)(struct List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args); //returns a void pointer that should be cast to the type void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + struct NODE *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + } List; /*------------------------------------------------------------------------------ @@ -77,4 +80,7 @@ int checkAlloc(void *mem, int notOkToFail); Return: CONFIG * ------------------------------------------------------------------------------*/ Config *configuration(int argc, char **argv); + +NODE *createNode(void *element, uint32_t id); + #endif //UTILS_H diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index b7e0341..399b37e 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -4,6 +4,10 @@ #include #include #include +#include "utils.h" +#include "string.h" + + uint32_t get_file_size(char *source_file_name) { @@ -26,9 +30,14 @@ uint32_t get_file_size(char *source_file_name) { return bytes; } -File *create_file(char *source_file_name) { +File *create_file(char *source_file_name, int clear_file_contents) { - int fd = ssp_open(source_file_name, O_RDWR | O_CREAT); + int fd = 0; + if (clear_file_contents){ + fd = ssp_open(source_file_name, O_RDWR | O_CREAT | O_TRUNC); + }else { + fd = ssp_open(source_file_name, O_RDWR | O_CREAT); + } if (fd == -1){ ssp_error("couldn't create file\n"); fd = ssp_open(source_file_name, O_RDWR); @@ -45,13 +54,17 @@ File *create_file(char *source_file_name) { return NULL; } + //ssp_printf("file size: %u\n", total_size); + File *file = ssp_alloc(1, sizeof(File)); file->fd = fd; + file->eof_checksum = 0; file->next_offset_to_send = 0; file->total_size = total_size; file->partial_checksum = 0; - + file->missing_offsets = linked_list(); + return file; } @@ -101,13 +114,18 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset) { ssp_error("Could not write\n"); } if (bytes < size && bytes >= 0){ - ssp_error("did not write all the bytes, this could be because the disk is full\n"); + ssp_error("did not write all the bytes, this could be because the disk is full, or the file that was sent is empty!\n"); } return bytes; } void free_file(void *file) { - ssp_free(file); + + File *f = (File *) file; + + f->missing_offsets->free(f->missing_offsets, ssp_free); + + ssp_free(f); } @@ -115,8 +133,8 @@ void free_file(void *file) { uint32_t calc_check_sum(char *data, uint32_t length) { uint8_t remaining_bytes = length % 4; uint32_t check_sum = 0; - - for (unsigned int i = 0; i < length; i+= 4){ + uint32_t end = length - 4; + for (unsigned int i = 0; i < end; i+= 4){ check_sum += *((uint32_t *) &data[i]); } @@ -124,7 +142,7 @@ uint32_t calc_check_sum(char *data, uint32_t length) { uint8_t last_chunk[4]; memset(last_chunk, 0, 4); - uint32_t end = length - remaining_bytes; + end = length - remaining_bytes; for (uint8_t i = 0; i < remaining_bytes; i++) { last_chunk[i] = data[end + i];; @@ -151,4 +169,87 @@ uint32_t check_sum_file(File *file, uint16_t stack_buffer) { } return checksum; -} \ No newline at end of file +} + +static int *find_nak(void *element, void* args) { + + Offset *offset_in_list = (Offset *) element; + Offset *offset_to_insert = (Offset *) args; + + if (offset_to_insert->start >= offset_in_list->start && + offset_to_insert->end <= offset_in_list->end) { + return 1; + } + + return 0; +} + +//ack is 1, nak is 0 +void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end) { + + List * nak_list = file->missing_offsets; + + Offset offset_to_insert; + offset_to_insert.start = offset_start; + offset_to_insert.end = offset_end; + + NODE * node = nak_list->findNode(nak_list, 0, find_nak, &offset_to_insert); + if (node == NULL){ + ssp_printf("no begining node for receive_offset, can't add new offset\n"); + return; + } + + Offset *offset_in_list = (Offset *) node->element; + ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); + + //insert new node + if (offset_to_insert.start >= offset_in_list->start && offset_to_insert.end <= offset_in_list->end) { + + //remove node if both start and end are equal + if (offset_to_insert.start == offset_in_list->start && offset_to_insert.end == offset_in_list->end) { + ssp_printf("removing node\n"); + node->next->prev = node->prev; + node->prev->next = node->next; + ssp_free(node->element); + ssp_free(node); + nak_list->count--; + return; + } + + //if new offset is in the start, simply change the list's node's start + else if (offset_to_insert.start == offset_in_list->start && offset_to_insert.start < offset_in_list->end) { + offset_in_list->start = offset_to_insert.end; + return; + } + + + ssp_printf("adding new node\n"); + + Offset *new_offset = ssp_alloc(1, sizeof(Offset)); + new_offset->start = offset_start; + new_offset->end = offset_end; + + uint32_t tmp = new_offset->start; + new_offset->start = offset_in_list->start; + offset_in_list->start = new_offset->end; + + new_offset->end = tmp; + + NODE *cur = node; + NODE *new = createNode(new_offset, new_offset->start); + + new->next = cur; + new->prev = cur->prev; + new->prev->next = new; + cur->prev = new; + nak_list->count++; + + } + +} + +void get_missing_offset(File *file) { + + + +} diff --git a/Program/src/main.c b/Program/src/main.c index d416163..7f56186 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -82,7 +82,7 @@ int main(int argc, char** argv) { Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + put_request("test.txt", "delivered_file.txt", 0, 0, 0, 1, NULL, NULL, new_client, p_state); //will block on pthread_join diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 600bd80..a191643 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -42,7 +42,6 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * //set header to file directive 0 is directive, 1 is data header->PDU_type = 0; - uint8_t packet_index = start; //set directive 1 byte @@ -86,6 +85,10 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * //mark the size of the packet header->PDU_data_field_len = total_bytes; + + + ssp_print_hex(meta_data_packet, total_bytes); + return packet_index; } @@ -113,9 +116,12 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli //fill the rest of the packet with data int bytes = get_offset(req->file, &res.msg[packet_index], data_size, packet_offset->offset); - + if (bytes <= 0){ + ssp_error("could not get offset, this could because the file is empty!\n"); + return -1; + } //calculate checksum for data packet, this is used to calculate in transit checksums - req->file->partial_checksum += calc_check_sum(&res.msg[packet_index], data_size); + req->file->partial_checksum += calc_check_sum(&res.msg[packet_index], bytes); req->file->next_offset_to_send += bytes; @@ -162,12 +168,22 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* } +static void print(void *args) { + Offset * o = (Offset *) args; + ssp_printf("start: %u, end: %u\n", o->start, o->end); +} static void process_pdu_eof(char *packet, Request *req) { Pdu_eof *eof_packet = (Pdu_eof *) packet; if (eof_packet->checksum == req->file->partial_checksum) { - ssp_printf("File received\n", req->file->partial_checksum); + + /*ssp_printf("received checksum: %u\n", req->file->partial_checksum); + ssp_printf("actual checksum: %u\n", eof_packet->checksum); + ssp_printf("missing offsets after file received count: %u\n", req->file->missing_offsets->count); + req->file->missing_offsets->print(req->file->missing_offsets, print, NULL);*/ + req->file->eof_checksum = eof_packet->checksum; + if (ssp_close(req->file->fd) == -1) ssp_error("could not close file\n"); @@ -179,13 +195,22 @@ static int process_file_request_metadata(Request *req) { if (does_file_exist(req->destination_file_name)){ ssp_error("file already exists, overwriting it\n"); - req->file = create_file(req->destination_file_name); - return 1; + req->file = create_file(req->destination_file_name, 1); } if (req->file == NULL) { - ssp_printf("%s\n", req->destination_file_name); - req->file = create_file(req->destination_file_name); + ssp_printf("creating file: %s\n", req->destination_file_name); + req->file = create_file(req->destination_file_name, 1); } + + //add offset for naks + Offset *offset = ssp_alloc(1, sizeof(Offset)); + offset->end = req->file_size; + offset->start = 0; + ssp_printf("%u\n", req->file_size); + req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); + + req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); + return 1; } @@ -196,12 +221,18 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil File_data_pdu_contents *packet = data_packet; - uint32_t offset = packet->offset; + uint32_t offset_start = packet->offset; + uint32_t offset_end = offset_start + data_len - 4; //ssp_printf("packet offset received: %d\n", packet->offset); - int bytes = write_offset(file, &data_packet[4], data_len - 4, offset); - file->partial_checksum += calc_check_sum(&data_packet[4], data_len - 4); + int bytes = write_offset(file, &data_packet[4], data_len - 4, offset_start); + if (bytes <= 0) + return; + + file->partial_checksum += calc_check_sum(&data_packet[4], bytes); + + receive_offset(file, 0, offset_start, offset_end); } @@ -211,22 +242,23 @@ static void fill_request_pdu_metadata(unsigned char *meta_data_packet, Request * req_to_fill->segmentation_control = meta_data->segmentation_control; uint8_t packet_index = 4; - uint32_t file_size = (uint32_t)meta_data_packet[packet_index]; + req_to_fill->file_size = file_size; + ssp_printf("received filesize: %u\n", file_size); packet_index++; uint8_t file_name_len = meta_data_packet[packet_index]; packet_index++; - memcpy(req_to_fill->source_file_name, &meta_data_packet[packet_index], file_name_len); - packet_index += file_name_len + 1; + file_name_len = meta_data_packet[packet_index]; memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); packet_index += file_name_len; + ssp_print_hex(meta_data_packet, packet_index); return; } @@ -415,11 +447,14 @@ int put_request(char *source_file_name, //give the client a new request to perform Request *req = client->outGoing_req; - req->file = create_file(source_file_name); + req->file = create_file(source_file_name, 0); + //build a request req->transaction_sequence_number = p_state->transaction_id++; + //enumeration req->type = put; + req->dest_cfdp_id = client->cfdp_id; req->file_size = file_size; diff --git a/Program/src/utils.c b/Program/src/utils.c index ba2ac57..3228443 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -16,6 +16,7 @@ to use for general functionality. #include #include #include +#include "port.h" @@ -102,7 +103,7 @@ Config *configuration(int argc, char **argv) new node, or NULL if failed ------------------------------------------------------------------------------*/ -static NODE *createNode(void *element, uint32_t id) +NODE *createNode(void *element, uint32_t id) { NODE *newNode = calloc(sizeof(NODE), 1); if(!checkAlloc(newNode, 0)) @@ -123,7 +124,7 @@ static NODE *createNode(void *element, uint32_t id) static void freeNode(NODE *node) { - free(node); + ssp_free(node); } static void *pop(List *list) { @@ -144,8 +145,8 @@ static void *pop(List *list) { /*------------------------------------------------------------------------------ - This function creates a new node to add into the linked list, returns the - new node. + This function creates a new node to add into the beginning of the + linked list, returns the new node. ------------------------------------------------------------------------------*/ static int insert(List *list, void *element, uint32_t id) { @@ -170,7 +171,7 @@ static int insert(List *list, void *element, uint32_t id) { 0 if failed. ------------------------------------------------------------------------------*/ -static int addElement(List *list, void *element, uint32_t id) +static int push(List *list, void *element, uint32_t id) { NODE *newNode = createNode(element, id); @@ -294,7 +295,56 @@ static void *findElement(List *list, uint32_t id, int (*f)(void *element, void * return NULL; } +static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args) { + + NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = 0; + while (cur->next != NULL) + { + if (f != NULL) + found_with_func = f(cur->element, args); + + if(cur->id == id) + found_with_id = 1; + + if (found_with_func || found_with_id) { + NODE *new = createNode(element, id); + new->next = cur; + new->prev = cur->prev; + new->prev->next = new; + cur->prev = new; + list->count++; + } + + cur = cur->next; + } +} + + +static NODE * findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { + + NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = 0; + while (cur->next != NULL) + { + if (f != NULL) + found_with_func = f(cur->element, args); + + if(cur->id == id) + found_with_id = 1; + if (found_with_func || found_with_id){ + return cur; + + } + + cur = cur->next; + } + return NULL; + +} //see header file return NULL if fails List *linked_list() @@ -317,14 +367,15 @@ List *linked_list() tail->prev = head; head->next = tail; - newList->push = addElement; + newList->push = push; newList->remove = removeElement; newList->print = printList; newList->free = freeList; newList->insert = insert; newList->pop = pop; newList->find = findElement; - + newList->insertAt = insertAt; + newList->findNode = findNode; return newList; } diff --git a/Program/test/main.c b/Program/test/main.c index e61b5d7..93ce4f9 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -10,6 +10,7 @@ #include #include #include "filesystem_funcs.h" +#include "port.h" struct myStruct { int id; @@ -32,8 +33,8 @@ static int list_remove(void *element, void *args) { static void list_print(void *element, void *args) { - struct myStruct *st = (struct myStruct *)element; - printf("list print: %d\n", st->id); + Offset *offset = (Offset *) element; + printf("missing offsets:start:%u end:%u\n", offset->start, offset->end); } @@ -52,7 +53,39 @@ static void list_free(void *element) { int main () { + + + + File *file = create_file("test.txt"); + ssp_printf("file size: %u\n", file->total_size); + + uint32_t data_size = PACKET_LEN - 4; + uint32_t data_start = 0; + uint32_t data_end = data_size; + + /*test sequence of files + for (int i=0; i < file->total_size; i+= data_size) { + data_start = i; + data_end = data_size + i; + //ssp_printf("i:%d\n", data_end); + receive_offset(file, 0, data_start, data_end); + } + + receive_offset(file, 0, 48516, 48833); + */ + + + + + //doesnt do this edge case because, would never request it? + + file->missing_offsets->print(file->missing_offsets, list_print, NULL); + + free_file(file); + + + /* char *packet = "hello world"; uint32_t checksum = calc_check_sum(packet, 10); printf("%d\n", checksum); From 1c156b4fd8954a823d5534b69e6069d004a7196b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 2 Apr 2019 19:44:54 -0600 Subject: [PATCH 028/400] fixed network byte order bug, more will be out there, use htonl, ntohl --- Program/src/filesystem_funcs.c | 8 +++----- Program/src/protocol_handler.c | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 399b37e..031b8f6 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -200,14 +200,14 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off } Offset *offset_in_list = (Offset *) node->element; - ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); + //ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); //insert new node if (offset_to_insert.start >= offset_in_list->start && offset_to_insert.end <= offset_in_list->end) { //remove node if both start and end are equal if (offset_to_insert.start == offset_in_list->start && offset_to_insert.end == offset_in_list->end) { - ssp_printf("removing node\n"); + //ssp_printf("removing node\n"); node->next->prev = node->prev; node->prev->next = node->next; ssp_free(node->element); @@ -222,9 +222,7 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off return; } - - ssp_printf("adding new node\n"); - + //ssp_printf("adding new node\n"); Offset *new_offset = ssp_alloc(1, sizeof(Offset)); new_offset->start = offset_start; new_offset->end = offset_end; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index a191643..d3afec9 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -53,18 +53,20 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * //1 bytes meta_data_packet->segmentation_control = req->segmentation_control; meta_data_packet->reserved_bits = 0; - - //4 bytes - meta_data_packet->file_size = req->file_size; - packet_index += 5; + packet_index++; + //4 bytes + uint32_t network_bytes = htonl(req->file_size); + network_bytes = network_bytes; + memcpy(&res.msg[packet_index], &network_bytes, sizeof(uint32_t)); + packet_index += 4; + //variable length params uint8_t src_file_name_length = strnlen(req->source_file_name, MAX_PATH); uint8_t destination_file_length = strnlen(req->destination_file_name, MAX_PATH); char *src_file_name = req->source_file_name; char *destination_file_name = req->destination_file_name; - //copy source length to packet (1 bytes) memcpy(&res.msg[packet_index], &src_file_name_length, src_file_name_length); packet_index++; @@ -72,7 +74,6 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * memcpy(&res.msg[packet_index], src_file_name, src_file_name_length); packet_index += src_file_name_length; - //copy length to packet (1 byte) memcpy(&res.msg[packet_index], &destination_file_length, 1); packet_index++; @@ -87,7 +88,7 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * header->PDU_data_field_len = total_bytes; - ssp_print_hex(meta_data_packet, total_bytes); + ssp_print_hex(&res.msg[start], total_bytes); return packet_index; } @@ -241,20 +242,21 @@ static void fill_request_pdu_metadata(unsigned char *meta_data_packet, Request * Pdu_meta_data *meta_data = meta_data_packet; req_to_fill->segmentation_control = meta_data->segmentation_control; - uint8_t packet_index = 4; - uint32_t file_size = (uint32_t)meta_data_packet[packet_index]; + uint8_t packet_index = 1; + uint32_t *network_bytes = (uint32_t*) &meta_data_packet[packet_index]; + uint32_t file_size = ntohl(*network_bytes); req_to_fill->file_size = file_size; - ssp_printf("received filesize: %u\n", file_size); - packet_index++; + packet_index += 4; uint8_t file_name_len = meta_data_packet[packet_index]; packet_index++; memcpy(req_to_fill->source_file_name, &meta_data_packet[packet_index], file_name_len); - packet_index += file_name_len + 1; + packet_index += file_name_len; file_name_len = meta_data_packet[packet_index]; + packet_index++; memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); packet_index += file_name_len; From 8415bcc426750a44b44d86de7ada9198249a352e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Apr 2019 09:26:48 -0600 Subject: [PATCH 029/400] Fixing 16 bytes and above network byte order --- Program/src/protocol_handler.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index d3afec9..353a951 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -88,7 +88,7 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * header->PDU_data_field_len = total_bytes; - ssp_print_hex(&res.msg[start], total_bytes); + //ssp_print_hex(&res.msg[start], total_bytes); return packet_index; } @@ -129,7 +129,6 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli //add bytes read, and the packet offset to the data_field length header->PDU_data_field_len = bytes + 4; - if (bytes < data_size) return 1; @@ -157,7 +156,7 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* packet_index++; //4 bytes - packet->file_size = req->file->total_size; + packet->file_size = ntohl(req->file->total_size); packet_index += 4; //TODO checksum procedures @@ -166,6 +165,7 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* //TODO addTLV fault_location header->PDU_data_field_len = packet_index - start; + ssp_print_hex(&res.msg[start], packet_index); } @@ -179,15 +179,21 @@ static void process_pdu_eof(char *packet, Request *req) { Pdu_eof *eof_packet = (Pdu_eof *) packet; if (eof_packet->checksum == req->file->partial_checksum) { - /*ssp_printf("received checksum: %u\n", req->file->partial_checksum); - ssp_printf("actual checksum: %u\n", eof_packet->checksum); - ssp_printf("missing offsets after file received count: %u\n", req->file->missing_offsets->count); - req->file->missing_offsets->print(req->file->missing_offsets, print, NULL);*/ + //ssp_printf("received checksum: %u\n", req->file->partial_checksum); + //ssp_printf("actual checksum: %u\n", eof_packet->checksum); + uint32_t file_size = ntohl(eof_packet->file_size); + + ssp_printf("received filesize eof: %u\n", file_size); + + //ssp_printf("missing offsets after file received eof: count: %u\n", req->file->missing_offsets->count); + //req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); req->file->eof_checksum = eof_packet->checksum; if (ssp_close(req->file->fd) == -1) ssp_error("could not close file\n"); + ssp_print_hex(packet, 19); + } } @@ -207,11 +213,7 @@ static int process_file_request_metadata(Request *req) { Offset *offset = ssp_alloc(1, sizeof(Offset)); offset->end = req->file_size; offset->start = 0; - ssp_printf("%u\n", req->file_size); req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); - - req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); - return 1; } @@ -260,7 +262,7 @@ static void fill_request_pdu_metadata(unsigned char *meta_data_packet, Request * memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); packet_index += file_name_len; - ssp_print_hex(meta_data_packet, packet_index); + //ssp_print_hex(meta_data_packet, packet_index); return; } From 6abc8a25465a53700238855d1aadbe1b892b993d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Apr 2019 09:31:31 -0600 Subject: [PATCH 030/400] byte order fixed save for checksum, because that works well. --- Program/src/protocol_handler.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 353a951..89eb087 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -85,7 +85,7 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * uint8_t total_bytes = packet_index - start; //mark the size of the packet - header->PDU_data_field_len = total_bytes; + header->PDU_data_field_len = htons(total_bytes); //ssp_print_hex(&res.msg[start], total_bytes); @@ -127,7 +127,7 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli req->file->next_offset_to_send += bytes; //add bytes read, and the packet offset to the data_field length - header->PDU_data_field_len = bytes + 4; + header->PDU_data_field_len = htons(bytes + 4); if (bytes < data_size) return 1; @@ -164,7 +164,7 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* packet_index += 4; //TODO addTLV fault_location - header->PDU_data_field_len = packet_index - start; + header->PDU_data_field_len = htons(packet_index - start); ssp_print_hex(&res.msg[start], packet_index); } @@ -323,7 +323,7 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; - uint16_t packet_data_len = header->PDU_data_field_len; + uint16_t packet_data_len = ntohs(header->PDU_data_field_len); if (p_state->verbose_level == 3) { ssp_printf("------------printing_header_received------------\n"); From 14a21808e42ae0757e471ed44d831fc66448ca6b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Apr 2019 10:24:37 -0600 Subject: [PATCH 031/400] preparing for some refactoring to do NAKs --- Program/include/packet.h | 2 +- Program/src/main.c | 6 +++--- Program/src/port.c | 10 ++++++++++ Program/src/protocol_handler.c | 9 ++++++--- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index c9b75e8..e3af8ab 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -253,7 +253,7 @@ typedef struct pdu_meta_data { typedef struct file_data_pdu_contents { //in octets - uint32_t offset; + unsigned int offset: 32; //variable sized unsigned char *data; } File_data_pdu_contents; diff --git a/Program/src/main.c b/Program/src/main.c index 7f56186..90fbeaf 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -81,9 +81,9 @@ int main(int argc, char** argv) { //create a client Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - - put_request("test.txt", "delivered_file.txt", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - + //send via acknoleged mode + put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + //put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); //will block on pthread_join ssp_cleanup_client(new_client); diff --git a/Program/src/port.c b/Program/src/port.c index 32b6256..c108e6a 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -171,6 +171,16 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { //this function is a callback when using my posix ports static int on_time_out_posix(void *other) { + + + Protocol_state *p_state = (Protocol_state*) other; + + #ifdef POSIX_PORT + + //p_state->current_server_request->file->missing_offsets->print(p_state->current_server_request->file->missing_offsets, printf, NULL) + + + #endif return 0; } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 89eb087..6dc708a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -165,7 +165,6 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* //TODO addTLV fault_location header->PDU_data_field_len = htons(packet_index - start); - ssp_print_hex(&res.msg[start], packet_index); } @@ -186,7 +185,7 @@ static void process_pdu_eof(char *packet, Request *req) { ssp_printf("received filesize eof: %u\n", file_size); //ssp_printf("missing offsets after file received eof: count: %u\n", req->file->missing_offsets->count); - //req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); + req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); req->file->eof_checksum = eof_packet->checksum; if (ssp_close(req->file->fd) == -1) @@ -234,7 +233,6 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil return; file->partial_checksum += calc_check_sum(&data_packet[4], bytes); - receive_offset(file, 0, offset_start, offset_end); } @@ -296,6 +294,11 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ aka: handles responses from remote ------------------------------------------------------------------------------*/ +void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state) { + + + +} //Server responses void packet_handler_server(Response res, Request *current_request, Protocol_state *p_state) { From aa060a75926c003b4a4f8325aea6219952bf1238 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Apr 2019 12:28:21 -0600 Subject: [PATCH 032/400] commiting before refactoring --- Program/include/protocol_handler.h | 8 ++++++-- Program/src/port.c | 25 ++++++++++++++++--------- Program/src/protocol_handler.c | 12 ++++++++++++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index b196e4c..60af8ae 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -27,6 +27,7 @@ typedef enum Indication { } Indication; +//incoming requests spin up requests typedef struct request { Indication type; uint64_t transaction_sequence_number; @@ -48,9 +49,12 @@ typedef struct request { uint32_t buff_len; unsigned char* buff; -} Request; + //handler for sending responses back + Response res; +} Request; +//outgoing requests spin up client threads typedef struct client { void *client_handle; @@ -98,7 +102,7 @@ void parse_packet_server(unsigned char* buff, uint32_t packet_len, Request *req, void packet_handler_client(Response res, Request *req, Client *client, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); void parse_packet_client(unsigned char* buff, Request *req, Client *client, Protocol_state *p_state); - +void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); /* unsigned char *source_file_name, diff --git a/Program/src/port.c b/Program/src/port.c index c108e6a..47a11de 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -92,8 +92,9 @@ void ssp_print_hex(unsigned char *stuff, uint32_t size){ } void ssp_sendto(Response res) { - + #ifdef POSIX_PORT + struct sockaddr* addr = (struct sockaddr*) res.addr; int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); if (n < 0) @@ -111,14 +112,18 @@ static int on_recv_server(int sfd, unsigned char *msg, uint32_t *buff_size, stru #ifdef POSIX_PORT struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + memcpy(p_state->current_server_request->res.addr, posix_client, sizeof(struct sockaddr_in)); + #endif + p_state->current_server_request->res.sfd = sfd; + p_state->current_server_request->res.packet_len = p_state->packet_size; Response res; res.addr = posix_client; res.sfd = sfd; res.packet_len = p_state->packet_size; - //filles the request struct + //filles the request struct, in the future get request based on id parse_packet_server(msg, res.packet_len, p_state->current_server_request, p_state); //ssp_printf("Server received: %s\n", msg); @@ -142,7 +147,7 @@ static int on_recv_client(int sfd, unsigned char *msg, uint32_t *buff_size, stru Client *client = p_state->newClient; - //filles the request struct + //fills the request struct parse_packet_client(msg, client->incoming_req, client, p_state); packet_handler_client(res, client->incoming_req, client, p_state); @@ -172,15 +177,13 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { //this function is a callback when using my posix ports static int on_time_out_posix(void *other) { - Protocol_state *p_state = (Protocol_state*) other; + if(p_state->current_server_request->transaction_sequence_number = 0) + return 0; - #ifdef POSIX_PORT + Response res = p_state->current_server_request->res; + on_server_time_out(res, p_state->current_server_request, p_state); - //p_state->current_server_request->file->missing_offsets->print(p_state->current_server_request->file->missing_offsets, printf, NULL) - - - #endif return 0; } @@ -360,6 +363,9 @@ Request *init_request(uint32_t buff_len) { req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); + + req->res.addr = ssp_alloc(1, sizeof(struct sockaddr_in)); + checkAlloc(req->buff, 1); return req; } @@ -368,6 +374,7 @@ static void ssp_cleanup_req(Request *req) { if (req->file != NULL) free_file(req->file); + free(req->res.addr); free(req->source_file_name); free(req->destination_file_name); free(req->buff); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 6dc708a..8aa6a6d 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -294,8 +294,20 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ aka: handles responses from remote ------------------------------------------------------------------------------*/ + +static void request_missing_offsets(Response res, Request *current_request){ +} + + void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state) { + //build_pdu_header(res, current_request, p_state->newClient, p_state); + + //res.msg = current_request->buff; + //memset(res.msg, 0, p_state->newClient->packet_len); + + //request_missing_offset(); + current_request->file->missing_offsets->print(p_state->current_server_request->file->missing_offsets, print, NULL); } From fe933bb6fb09bd6476230b228b1decb89d8cd7a5 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Apr 2019 12:57:02 -0600 Subject: [PATCH 033/400] add pdu function to MIB --- Program/include/protocol_handler.h | 5 +++ Program/src/mib.c | 61 ++++++++++++++++++++++++++++++ Program/src/port.c | 32 ++-------------- Program/src/protocol_handler.c | 37 +++++++++--------- 4 files changed, 89 insertions(+), 46 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 60af8ae..554acc3 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -48,8 +48,13 @@ typedef struct request { unsigned char* filestore_requests; uint32_t buff_len; + + //buffer for making packets unsigned char* buff; + //header for building response packets + Pdu_header *pdu_header; + //handler for sending responses back Response res; } Request; diff --git a/Program/src/mib.c b/Program/src/mib.c index 1db2459..e1d9dfb 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -2,6 +2,7 @@ #include "mib.h" #include "utils.h" #include "port.h" +#include MIB *init_mib() { @@ -41,3 +42,63 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ return mib->remote_entities->insert(mib->remote_entities, remote, cfdp_id); } + + +Pdu_header *get_header_from_mid(MIB *mib, uint32_t cfdp_id){ + + Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, cfdp_id, NULL, NULL); + if (remote == NULL) { + return NULL; + } + + Pdu_header *pdu_header = ssp_alloc(1, sizeof(Pdu_header)); + checkAlloc(pdu_header, 1); + + pdu_header->reserved_bit_0 = 0; + pdu_header->reserved_bit_1 = 0; + pdu_header->reserved_bit_2 = 0; + pdu_header->CRC_flag = remote->CRC_required; + pdu_header->direction = 1; + pdu_header->PDU_type = 0; + pdu_header->transaction_seq_num_len = 3; + pdu_header->length_of_entity_IDs = 1; + pdu_header->transmission_mode = remote->default_transmission_mode; + + pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); + checkAlloc(pdu_header->destination_id, 1); + memcpy(pdu_header->destination_id, &remote->cfdp_id, pdu_header->length_of_entity_IDs); + + pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); + checkAlloc(pdu_header->source_id, 1); + memcpy(pdu_header->source_id, &cfdp_id, pdu_header->length_of_entity_IDs); + return pdu_header; +} + +/* + //building the pdu header here + client->pdu_header = ssp_alloc(1, sizeof(Pdu_header)); + checkAlloc(client->pdu_header, 1); + + + //these will need to be set with a config file, or dynamically based on the + //packet being sent + + Pdu_header* header = client->pdu_header; + header->reserved_bit_0 = 0; + header->reserved_bit_1 = 0; + header->reserved_bit_2 = 0; + header->CRC_flag = client->mib_info->CRC_required; + header->direction = 1; + header->PDU_type = 0; + header->transaction_seq_num_len = 3; + header->length_of_entity_IDs = 1; + header->transmission_mode = remote->default_transmission_mode; + + header->destination_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); + checkAlloc(header->destination_id, 1); + memcpy(header->destination_id, &remote->cfdp_id, header->length_of_entity_IDs); + + header->source_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); + checkAlloc(header->source_id, 1); + memcpy(header->source_id, &p_state->my_cfdp_id, header->length_of_entity_IDs); + */ \ No newline at end of file diff --git a/Program/src/port.c b/Program/src/port.c index 47a11de..26d5f5c 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -303,37 +303,11 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { if (remote == NULL) ssp_printf("couldn't find entity in Remote_entity list\n"); + //TODO clean this up, we don't need multiple instances of UT_ports etc client->unitdata_port = remote->UT_port; client->unitdata_id = remote->UT_address; client->mib_info = remote; - - //building the pdu header here - client->pdu_header = ssp_alloc(1, sizeof(Pdu_header)); - checkAlloc(client->pdu_header, 1); - - - //these will need to be set with a config file, or dynamically based on the - //packet being sent - - Pdu_header* header = client->pdu_header; - header->reserved_bit_0 = 0; - header->reserved_bit_1 = 0; - header->reserved_bit_2 = 0; - header->CRC_flag = client->mib_info->CRC_required; - header->direction = 1; - header->PDU_type = 0; - header->transaction_seq_num_len = 3; - header->length_of_entity_IDs = 1; - header->transmission_mode = remote->default_transmission_mode; - - header->destination_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); - checkAlloc(header->destination_id, 1); - memcpy(header->destination_id, &remote->cfdp_id, header->length_of_entity_IDs); - - header->source_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); - checkAlloc(header->source_id, 1); - memcpy(header->source_id, &p_state->my_cfdp_id, header->length_of_entity_IDs); - + client->pdu_header = get_header_from_mid(p_state->mib, cfdp_id); //TODO lock this p_state->newClient = client; @@ -415,7 +389,7 @@ void ssp_cleanup_client(Client *client) { free(client->pdu_header->destination_id); free(client->pdu_header->source_id); free(client->pdu_header); - + free(client); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 8aa6a6d..1402f88 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -10,29 +10,31 @@ //returns the location in the packet where the next pointer for tthe packet will start after the header -static uint8_t build_pdu_header(Response res, Request *req, Client* client, Protocol_state *p_state) { - unsigned char *packet = res.msg; - memcpy(packet, client->pdu_header, PACKET_STATIC_HEADER_LEN); +static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, Pdu_header *pdu_header) { + memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); + uint32_t packet_index = PACKET_STATIC_HEADER_LEN; //copy variable length src id - memcpy(&packet[PACKET_STATIC_HEADER_LEN], - client->pdu_header->source_id, - client->pdu_header->length_of_entity_IDs); - + memcpy(&packet[packet_index], + pdu_header->source_id, + pdu_header->length_of_entity_IDs); + packet_index += pdu_header->length_of_entity_IDs; + //copy variable length transaction number id - memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs], - &req->transaction_sequence_number, - client->pdu_header->transaction_seq_num_len); + memcpy(&packet[packet_index], + &transaction_sequence_number, + pdu_header->transaction_seq_num_len); + packet_index += pdu_header->transaction_seq_num_len; //copy variable length destination id - memcpy(&packet[PACKET_STATIC_HEADER_LEN + client->pdu_header->length_of_entity_IDs + client->pdu_header->transaction_seq_num_len], - client->pdu_header->destination_id, - client->pdu_header->length_of_entity_IDs); + memcpy(&packet[packet_index], + pdu_header->destination_id, + pdu_header->length_of_entity_IDs); uint8_t total_bytes = PACKET_STATIC_HEADER_LEN - + client->pdu_header->length_of_entity_IDs - + client->pdu_header->transaction_seq_num_len - + client->pdu_header->length_of_entity_IDs; + + pdu_header->length_of_entity_IDs + + pdu_header->transaction_seq_num_len + + pdu_header->length_of_entity_IDs; return total_bytes; } @@ -399,7 +401,8 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s res.msg = req->buff; memset(res.msg, 0, client->packet_len); - uint32_t start = build_pdu_header(res, req, client, p_state); + + uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, client->pdu_header); switch (req->type) { From f74f2262ec8c87594ed6dc080e4abedd38e3104f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Apr 2019 16:13:22 -0600 Subject: [PATCH 034/400] those compiler warnings --- Program/include/mib.h | 5 +- Program/include/port.h | 6 +- Program/include/protocol_handler.h | 22 ++--- Program/include/server.h | 10 +-- Program/src/filesystem_funcs.c | 8 +- Program/src/main.c | 6 +- Program/src/makefile | 4 +- Program/src/mib.c | 4 +- Program/src/port.c | 49 ++++++----- Program/src/protocol_handler.c | 137 +++++++++++++++++++++++------ Program/src/server.c | 20 ++--- Program/src/utils.c | 1 + 12 files changed, 178 insertions(+), 94 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 5ec259e..4d3dfc0 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -3,7 +3,7 @@ //default faul handle #include #include - +#include "protocol_handler.h" #ifndef MIB_H @@ -90,7 +90,6 @@ typedef struct mib { MIB *init_mib(void); void free_mib(MIB *mib); int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port); - - +Pdu_header *get_header_from_mib(MIB *mib, uint32_t cfdp_id); #endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index 972cad0..83554aa 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -11,7 +11,7 @@ void ssp_error( char *msg); -Protocol_state *ssp_connectionless_server(unsigned char *port); +Protocol_state *ssp_connectionless_server(char *port); void *ssp_connectionless_server_task(void *protocol_state); @@ -24,9 +24,9 @@ void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); -void ssp_print_hex(unsigned char *stuff, uint32_t size); +void ssp_print_hex(char *stuff, uint32_t size); int ssp_open(char *pathname, int flags); -int ssp_read(int fd, unsigned char* buff, size_t size); +int ssp_read(int fd, char* buff, size_t size); int ssp_lseek(int fd, int offset, int whence); void ssp_error(char *error); int ssp_write(int fd, const void *buf, size_t count); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 554acc3..970f713 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -9,7 +9,7 @@ typedef struct response { int sfd; //this is a pointer to buff in a request - unsigned char *msg; + char *msg; //this is type (struct sockaddr_in) in posix void *addr; //getting rid of this soon in favour of client based packet sizes @@ -36,25 +36,25 @@ typedef struct request { File *file; uint32_t file_size; - unsigned char *source_file_name; - unsigned char *destination_file_name; + char *source_file_name; + char *destination_file_name; uint8_t segmentation_control; uint8_t fault_handler_overides; uint8_t flow_lable; uint8_t transmission_mode; - unsigned char* messages_to_user; - unsigned char* filestore_requests; + char* messages_to_user; + char* filestore_requests; uint32_t buff_len; //buffer for making packets - unsigned char* buff; + char* buff; //header for building response packets Pdu_header *pdu_header; - + //handler for sending responses back Response res; } Request; @@ -85,7 +85,7 @@ typedef struct client { typedef struct protocol_state { uint32_t packet_size; - unsigned char *server_port; + char *server_port; void *server_handle; void *server_thread_attributes; MIB *mib; @@ -94,7 +94,7 @@ typedef struct protocol_state { Request *current_server_request; //lock this - uint32_t transaction_id; + uint32_t transaction_sequence_number; uint8_t verbose_level; @@ -103,10 +103,10 @@ typedef struct protocol_state { void packet_handler_server(Response res, Request *req, Protocol_state *p_state); -void parse_packet_server(unsigned char* buff, uint32_t packet_len, Request *req, Protocol_state *p_state); +void parse_packet_server(char* buff, uint32_t packet_len, Request *req, Protocol_state *p_state); void packet_handler_client(Response res, Request *req, Client *client, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); -void parse_packet_client(unsigned char* buff, Request *req, Client *client, Protocol_state *p_state); +void parse_packet_client(char* buff, Request *req, Client *client, Protocol_state *p_state); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); /* diff --git a/Program/include/server.h b/Program/include/server.h index b0514f4..7d5c6f0 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -17,7 +17,7 @@ This file is the header file for server.c Perameters: char *port is the port number you want to run the host on Return: It returns a socket descriptor to a UDP ready port ------------------------------------------------------------------------------*/ -int prepareUdpHost(unsigned char *port); +int prepareUdpHost(char *port); /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. @@ -42,8 +42,8 @@ int prepareUdpHost(unsigned char *port); Return: None ------------------------------------------------------------------------------*/ -void udpSelectServer(unsigned char *port, int packet_len, - int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), +void udpSelectServer(char *port, int packet_len, + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other); @@ -59,9 +59,9 @@ void udpSelectServer(unsigned char *port, int packet_len, int *prepareSignalHandler(void); -void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void *onSendParams, void *onRecvParams, +void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); #endif //SERVER_H diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 031b8f6..6a11de6 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -171,7 +171,7 @@ uint32_t check_sum_file(File *file, uint16_t stack_buffer) { return checksum; } -static int *find_nak(void *element, void* args) { +static int find_nak(void *element, void* args) { Offset *offset_in_list = (Offset *) element; Offset *offset_to_insert = (Offset *) args; @@ -244,10 +244,4 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off } -} - -void get_missing_offset(File *file) { - - - } diff --git a/Program/src/main.c b/Program/src/main.c index 90fbeaf..8c38ec4 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -48,7 +48,7 @@ int main(int argc, char** argv) { //setting host name for testing - unsigned char *host_name = "127.0.0.1"; + char *host_name = "127.0.0.1"; uint32_t addr[sizeof(uint32_t)]; inet_pton(AF_INET, host_name, addr); @@ -68,7 +68,7 @@ int main(int argc, char** argv) { //connectionless server - unsigned char port[17]; + char port[17]; snprintf(port, 17, "%u", server_entity->UT_port); Protocol_state *p_state = ssp_connectionless_server(port); @@ -82,7 +82,7 @@ int main(int argc, char** argv) { Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); //send via acknoleged mode - put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + put_request("test.txt", "delivered_file.txt", 0, 0, 0, 1, NULL, NULL, new_client, p_state); //put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); //will block on pthread_join diff --git a/Program/src/makefile b/Program/src/makefile index 8d06563..9e29e1c 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -31,7 +31,9 @@ CWARNS += -Wuninitialized CWARNS += -Wunknown-pragmas CWARNS += -Wunused-function CWARNS += -Wunused-label -CWARNS += -Wunused-parameter +#CWARNS += -Wunused-parameter +CWARNS += -Wno-unused-parameter + CWARNS += -Wunused-value CWARNS += -Wunused-variable CWARNS += -Wmissing-prototypes diff --git a/Program/src/mib.c b/Program/src/mib.c index e1d9dfb..39665ec 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -3,7 +3,7 @@ #include "utils.h" #include "port.h" #include - +#include "string.h" MIB *init_mib() { MIB *mib = ssp_alloc(1, sizeof(MIB)); @@ -44,7 +44,7 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ } -Pdu_header *get_header_from_mid(MIB *mib, uint32_t cfdp_id){ +Pdu_header *get_header_from_mib(MIB *mib, uint32_t cfdp_id){ Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, cfdp_id, NULL, NULL); if (remote == NULL) { diff --git a/Program/src/port.c b/Program/src/port.c index 26d5f5c..b440bde 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -28,7 +28,7 @@ int ssp_write(int fd, const void *buf, size_t count) { } -int ssp_read(int fd, unsigned char* buff, size_t size) { +int ssp_read(int fd, char* buff, size_t size) { #ifdef POSIX_PORT return read(fd, buff, size); #endif @@ -78,12 +78,12 @@ void ssp_error(char *error){ #endif } //size is the number of bytes we want to print -void ssp_print_hex(unsigned char *stuff, uint32_t size){ +void ssp_print_hex(char *stuff, uint32_t size){ uint32_t current_packet_index = 0; ssp_printf("printing number of bytes: %u\n", size); - for (unsigned int j = 0; j < size; j += 1) { + for (int j = 0; j < size; j += 1) { ssp_printf("%x.", stuff[current_packet_index]); current_packet_index += 1; @@ -105,7 +105,7 @@ void ssp_sendto(Response res) { //this function is a callback when using my posix port -static int on_recv_server(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_storage addr, void *other) { +static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_storage addr, void *other) { Protocol_state *p_state = (Protocol_state *) other; @@ -124,7 +124,7 @@ static int on_recv_server(int sfd, unsigned char *msg, uint32_t *buff_size, stru res.packet_len = p_state->packet_size; //filles the request struct, in the future get request based on id - parse_packet_server(msg, res.packet_len, p_state->current_server_request, p_state); + parse_packet_server(packet, res.packet_len, p_state->current_server_request, p_state); //ssp_printf("Server received: %s\n", msg); packet_handler_server(res, p_state->current_server_request, p_state); @@ -132,7 +132,7 @@ static int on_recv_server(int sfd, unsigned char *msg, uint32_t *buff_size, stru } -static int on_recv_client(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_in addr, void *other) { +static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_in addr, void *other) { #ifdef POSIX_PORT struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; @@ -148,7 +148,7 @@ static int on_recv_client(int sfd, unsigned char *msg, uint32_t *buff_size, stru Client *client = p_state->newClient; //fills the request struct - parse_packet_client(msg, client->incoming_req, client, p_state); + parse_packet_client(packet, client->incoming_req, client, p_state); packet_handler_client(res, client->incoming_req, client, p_state); return 0; @@ -178,7 +178,7 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { static int on_time_out_posix(void *other) { Protocol_state *p_state = (Protocol_state*) other; - if(p_state->current_server_request->transaction_sequence_number = 0) + if(p_state->current_server_request->transaction_sequence_number == 0) return 0; Response res = p_state->current_server_request->res; @@ -190,18 +190,18 @@ static int on_time_out_posix(void *other) { void *ssp_connectionless_server_task(void *params) { - Protocol_state* state = (Protocol_state*) params; - state->transaction_id = 0; + Protocol_state* p_state = (Protocol_state*) params; + p_state->transaction_sequence_number = 1; #ifdef POSIX_PORT - udpSelectServer(state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, state); + udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, p_state); #endif return NULL; } -Protocol_state* ssp_connectionless_server(unsigned char *port) { +Protocol_state* ssp_connectionless_server(char *port) { #ifdef POSIX_PORT Protocol_state *state = calloc(sizeof(Protocol_state), 1); state->packet_size = PACKET_LEN; @@ -212,10 +212,10 @@ Protocol_state* ssp_connectionless_server(unsigned char *port) { pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); checkAlloc(attr, 1); - state->server_port = calloc(sizeof(unsigned char), 10); + state->server_port = calloc(sizeof(char), 10); checkAlloc(state->server_port, 1); - strncpy (state->server_port, port, 10); + strncpy ((char*)state->server_port, port, 10); int err = pthread_attr_init(attr); if (0 != err) @@ -249,8 +249,8 @@ void *ssp_connectionless_client_task(void* params){ Protocol_state *p_state = (Protocol_state *) params; - unsigned char host_name[INET_ADDRSTRLEN]; - unsigned char port[10]; + char host_name[INET_ADDRSTRLEN]; + char port[10]; //convert int to char * snprintf(port, 10, "%d", p_state->newClient->unitdata_port); @@ -307,7 +307,7 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { client->unitdata_port = remote->UT_port; client->unitdata_id = remote->UT_address; client->mib_info = remote; - client->pdu_header = get_header_from_mid(p_state->mib, cfdp_id); + client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id); //TODO lock this p_state->newClient = client; @@ -344,10 +344,20 @@ Request *init_request(uint32_t buff_len) { return req; } + +static void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { + free(pdu_header->destination_id); + free(pdu_header->source_id); + free(pdu_header); +} + static void ssp_cleanup_req(Request *req) { if (req->file != NULL) free_file(req->file); + if (req->pdu_header != NULL) + ssp_cleanup_pdu_header(req->pdu_header); + free(req->res.addr); free(req->source_file_name); free(req->destination_file_name); @@ -374,6 +384,7 @@ void ssp_cleanup(Protocol_state *p_state) { } + void ssp_cleanup_client(Client *client) { @@ -386,9 +397,7 @@ void ssp_cleanup_client(Client *client) { ssp_cleanup_req(client->incoming_req); free(client->client_handle); free(client->client_thread_attributes); - free(client->pdu_header->destination_id); - free(client->pdu_header->source_id); - free(client->pdu_header); + ssp_cleanup_pdu_header(client->pdu_header); free(client); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1402f88..947e6e2 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -1,5 +1,5 @@ - +#include "mib.h" #include "port.h" #include "protocol_handler.h" #include "string.h" @@ -47,10 +47,10 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * uint8_t packet_index = start; //set directive 1 byte - Pdu_directive *directive = &res.msg[packet_index]; + Pdu_directive *directive = (Pdu_directive *) &res.msg[packet_index]; directive->directive_code = META_DATA_PDU; packet_index += SIZE_OF_DIRECTIVE_CODE; - Pdu_meta_data *meta_data_packet = &res.msg[packet_index]; + Pdu_meta_data *meta_data_packet = (Pdu_meta_data *) &res.msg[packet_index]; //1 bytes meta_data_packet->segmentation_control = req->segmentation_control; @@ -109,7 +109,7 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli header->PDU_type = 1; uint16_t packet_index = start; - File_data_pdu_contents *packet_offset = &res.msg[packet_index]; + File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &res.msg[packet_index]; //4 bytes is the size of the offset paramater TODO set offset packet_offset->offset = req->file->next_offset_to_send; @@ -144,11 +144,11 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* header->PDU_type = 0; uint8_t packet_index = (uint8_t) start; - Pdu_directive *directive = &res.msg[packet_index]; + Pdu_directive *directive = (Pdu_directive *) &res.msg[packet_index]; directive->directive_code = EOF_PDU; packet_index++; - Pdu_eof *packet = &res.msg[packet_index]; + Pdu_eof *packet = (Pdu_eof *) &res.msg[packet_index]; //this will be need to set from the req struct probably. //4 bits, @@ -170,7 +170,7 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* } -static void print(void *args) { +void print(void *element, void *args) { Offset * o = (Offset *) args; ssp_printf("start: %u, end: %u\n", o->start, o->end); } @@ -193,8 +193,6 @@ static void process_pdu_eof(char *packet, Request *req) { if (ssp_close(req->file->fd) == -1) ssp_error("could not close file\n"); - ssp_print_hex(packet, 19); - } } @@ -214,17 +212,59 @@ static int process_file_request_metadata(Request *req) { Offset *offset = ssp_alloc(1, sizeof(Offset)); offset->end = req->file_size; offset->start = 0; + + //transmission mode 1 is unacknowledged, therefor no offsets + if (req->transmission_mode == 1) + return 1; + req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); + return 1; } +static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state) { + + uint8_t packet_index = PACKET_STATIC_HEADER_LEN; + Pdu_header *header = (Pdu_header *) packet; + + uint32_t source_id = 0; + memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); + packet_index += header->length_of_entity_IDs; + + //TODO the transaction number should get the request from data structure hosting requests + uint32_t transaction_sequence_number = 0; + memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); + packet_index += header->transaction_seq_num_len; + + uint32_t dest_id = 0; + memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); + packet_index += header->length_of_entity_IDs; + + uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + + if (p_state->verbose_level == 3) { + ssp_printf("------------printing_header_received------------\n"); + ssp_print_hex(packet, packet_index); + ssp_printf("packet data length %d, sequence number %d\n", packet_data_len, transaction_sequence_number); + } + + if (p_state->my_cfdp_id != dest_id){ + ssp_printf("someone is sending packets here that are not for me\n"); + return -1; + } + + req->transmission_mode = header->transmission_mode; + req->dest_cfdp_id = source_id; + req->transaction_sequence_number = transaction_sequence_number; + +} static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { if(file == NULL) ssp_error("file struct is null, can't write to file"); - File_data_pdu_contents *packet = data_packet; + File_data_pdu_contents *packet = (File_data_pdu_contents *)data_packet; uint32_t offset_start = packet->offset; uint32_t offset_end = offset_start + data_len - 4; @@ -235,13 +275,17 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil return; file->partial_checksum += calc_check_sum(&data_packet[4], bytes); + + if (file->missing_offsets->count == 0) + return; + receive_offset(file, 0, offset_start, offset_end); } -static void fill_request_pdu_metadata(unsigned char *meta_data_packet, Request *req_to_fill) { +static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) { - Pdu_meta_data *meta_data = meta_data_packet; + Pdu_meta_data *meta_data = (Pdu_meta_data *) meta_data_packet; req_to_fill->segmentation_control = meta_data->segmentation_control; uint8_t packet_index = 1; @@ -278,8 +322,15 @@ static void fill_request_pdu_metadata(unsigned char *meta_data_packet, Request * //fills the current request with packet data, responses from servers -void parse_packet_client(unsigned char *msg, Request *current_request, Client* client, Protocol_state *p_state) { - ssp_printf("client received %x\n", msg); +void parse_packet_client(char *packet, Request *req, Client* client, Protocol_state *p_state) { + ssp_printf("client received %x\n", packet); + + process_pdu_header(packet, req, p_state); + //ssp_printf("client sequence number %u\n", req->transaction_sequence_number); + //ssp_printf("client transmission mode %u\n", req->transmission_mode); + //ssp_printf("client request type %u\n", req->type); + + //ssp_print_hex(packet, 10); } @@ -297,20 +348,30 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ ------------------------------------------------------------------------------*/ -static void request_missing_offsets(Response res, Request *current_request){ +static void request_missing_offsets(Response res, Request *req){ + } -void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state) { +void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { - //build_pdu_header(res, current_request, p_state->newClient, p_state); - - //res.msg = current_request->buff; - //memset(res.msg, 0, p_state->newClient->packet_len); + res.msg = req->buff; + if (req->file->missing_offsets->count > 0) { + req->file->missing_offsets->print(p_state->current_server_request->file->missing_offsets, print, NULL); + request_missing_offsets(res, req); + return; + } //request_missing_offset(); - current_request->file->missing_offsets->print(p_state->current_server_request->file->missing_offsets, print, NULL); + + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->pdu_header); + //ssp_printf("server sequence number %u\n", req->transaction_sequence_number); + //ssp_printf("server transmission mode %u\n", req->transmission_mode); + //ssp_printf("server request type %u\n", req->type); + ssp_printf("p_state->current_server_request->transaction_sequence number %u\n", p_state->current_server_request->transaction_sequence_number); + ssp_sendto(res); + } @@ -322,7 +383,7 @@ void packet_handler_server(Response res, Request *current_request, Protocol_stat //fills the current_request struct for the server, incomming requests -void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *current_request, Protocol_state *p_state) { +void parse_packet_server(char *packet, uint32_t packet_len, Request *req, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; @@ -352,25 +413,41 @@ void parse_packet_server(unsigned char *packet, uint32_t packet_len, Request *cu ssp_printf("someone is sending packets here that are not for me\n"); return; } + + req->transmission_mode = header->transmission_mode; + req->dest_cfdp_id = source_id; + req->transaction_sequence_number = transaction_sequence_number; + + if (process_pdu_header(packet, req, p_state) == -1){ + return; + } + + ssp_printf("received p_state->current_server_request->transaction_sequence number %u\n", p_state->current_server_request->transaction_sequence_number); + //process file data if (header->PDU_type == 1) { - write_packet_data_to_file(&packet[packet_index], packet_data_len, current_request->file); + write_packet_data_to_file(&packet[packet_index], packet_data_len, req->file); return; } - current_request->dest_cfdp_id = source_id; - Pdu_directive *directive = &packet[packet_index]; + + //set header for responding later + if (req->pdu_header == NULL){ + req->pdu_header = get_header_from_mib(p_state->mib, source_id); + } + + Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; packet_index++; switch (directive->directive_code) { case META_DATA_PDU: - fill_request_pdu_metadata(&packet[packet_index], current_request); - process_file_request_metadata(current_request); + fill_request_pdu_metadata(&packet[packet_index], req); + process_file_request_metadata(req); break; case EOF_PDU: - process_pdu_eof(&packet[packet_index], current_request); + process_pdu_eof(&packet[packet_index], req); break; @@ -471,8 +548,9 @@ int put_request(char *source_file_name, Request *req = client->outGoing_req; req->file = create_file(source_file_name, 0); + //build a request - req->transaction_sequence_number = p_state->transaction_id++; + req->transaction_sequence_number = p_state->transaction_sequence_number++; //enumeration req->type = put; @@ -489,6 +567,7 @@ int put_request(char *source_file_name, req->transmission_mode = transmission_mode; req->messages_to_user = messages_to_user; req->filestore_requests = filestore_requests; + return 0; } diff --git a/Program/src/server.c b/Program/src/server.c index b58fcc1..df71162 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -38,7 +38,7 @@ static int exit_now; //this code is reused from assignment 1, with small changes //see header file -int prepareUdpHost(unsigned char *port) +int prepareUdpHost(char *port) { struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); @@ -128,7 +128,7 @@ int *prepareSignalHandler() return &exit_now; } -static int resizeBuff(unsigned char **buffer, uint32_t *newBufferSize, uint32_t *prev_buff_size) { +static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buff_size) { if (*newBufferSize != *prev_buff_size) { *buffer = realloc(*buffer, *newBufferSize); @@ -143,8 +143,8 @@ static int resizeBuff(unsigned char **buffer, uint32_t *newBufferSize, uint32_t } //see header file -void udpSelectServer(unsigned char* port, int packet_len, - int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), +void udpSelectServer(char* port, int packet_len, + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), void *other) { @@ -164,7 +164,7 @@ void udpSelectServer(unsigned char* port, int packet_len, uint32_t prev_buff_size = *buff_size; - unsigned char *buff = calloc(sizeof(unsigned char), *buff_size); + char *buff = calloc(sizeof(char), *buff_size); checkAlloc(buff, 1); struct sockaddr_storage *client; @@ -235,9 +235,9 @@ void udpSelectServer(unsigned char* port, int packet_len, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void *onSendParams, void *onRecvParams, +void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, unsigned char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams) + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams) ) { int sfd, count, port_val; @@ -252,7 +252,7 @@ void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void uint32_t prev_buff_size = *buff_size; - unsigned char *buff = calloc(sizeof(unsigned char), prev_buff_size); + char *buff = calloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); prepareSignalHandler(); @@ -269,10 +269,10 @@ void udpClient(unsigned char *hostname, unsigned char*port, int packet_len, void exit(0); } - bzero((unsigned char *) &serveraddr, sizeof(serveraddr)); + bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; - bcopy((unsigned char *)server->h_addr_list[0], (unsigned char *)&serveraddr.sin_addr.s_addr, server->h_length); + bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); serveraddr.sin_port = htons(port_val); serverlen = sizeof(serveraddr); diff --git a/Program/src/utils.c b/Program/src/utils.c index 3228443..83ae836 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -319,6 +319,7 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme cur = cur->next; } + return -1; } From 753d72c623bf7f0c4cc5d85fa48139e6881347df Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 6 Apr 2019 10:00:43 -0600 Subject: [PATCH 035/400] Working Naks --- Program/include/filesystem_funcs.h | 1 + Program/include/packet.h | 23 ++-- Program/include/protocol_handler.h | 3 +- Program/include/utils.h | 4 + Program/src/filesystem_funcs.c | 12 +- Program/src/main.c | 15 ++- Program/src/port.c | 9 +- Program/src/protocol_handler.c | 201 +++++++++++++++++++++-------- Program/src/utils.c | 3 +- Program/test/makefile | 7 +- 10 files changed, 194 insertions(+), 84 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index f531ba3..674af36 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -2,6 +2,7 @@ #ifndef FILESYSTEM_FUNCS_H #define FILESYSTEM_FUNCS_H #include +#include "utils.h" typedef struct offset { uint32_t start; diff --git a/Program/include/packet.h b/Program/include/packet.h index e3af8ab..93fd095 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -1,9 +1,9 @@ -#include #ifndef PACKET_H #define PACKET_H - +#include +#include "filesystem_funcs.h" #define PACKET_HEADER_LEN 224 // PACKET_HEADER_LEN + data max size = (65536 * 8) @@ -278,12 +278,19 @@ typedef struct pdu_eof { } Pdu_eof; - - - - - - +/* + start_scope is the begining of the nak requests + end_scope is the end + segments are +*/ +typedef struct pdu_nak { + unsigned int start_scope : 32; + uint32_t end_scope; + + //number of Nak_segments + uint64_t segment_requests; + Offset *segments; +} Pdu_nak; diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 970f713..a591663 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -104,9 +104,8 @@ typedef struct protocol_state { void packet_handler_server(Response res, Request *req, Protocol_state *p_state); void parse_packet_server(char* buff, uint32_t packet_len, Request *req, Protocol_state *p_state); -void packet_handler_client(Response res, Request *req, Client *client, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); -void parse_packet_client(char* buff, Request *req, Client *client, Protocol_state *p_state); +void parse_packet_client(char* buff, Response res, Request *req, Client *client, Protocol_state *p_state); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); /* diff --git a/Program/include/utils.h b/Program/include/utils.h index 08ccdbe..609e0af 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -81,6 +81,10 @@ int checkAlloc(void *mem, int notOkToFail); ------------------------------------------------------------------------------*/ Config *configuration(int argc, char **argv); +//https://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c +#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) + NODE *createNode(void *element, uint32_t id); #endif //UTILS_H diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 6a11de6..7372736 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -86,14 +86,18 @@ int does_file_exist(char *source_file_name) { //modifys the seek location, returns bytes read int get_offset(File *file, void *buff, uint32_t buf_size, int offset) { - if (offset >= file->total_size) + if (offset >= file->total_size){ + ssp_error("offset greater than file size\n"); return -1; + } - ssp_lseek(file->fd, SEEK_SET, offset); + if (ssp_lseek(file->fd, offset, SEEK_SET) == -1){ + ssp_error("could'nt set offset\n"); + } int bytes = ssp_read(file->fd, buff, buf_size); if (bytes == -1){ - ssp_error("Could not read\n"); + ssp_error("Could not read anything from file\n"); } return bytes; @@ -107,7 +111,7 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset) { return -1; } - ssp_lseek(file->fd, SEEK_SET, (int) offset); + ssp_lseek(file->fd, (int) offset, SEEK_SET); int bytes = ssp_write(file->fd, buff, (size_t) size); if (bytes == -1){ diff --git a/Program/src/main.c b/Program/src/main.c index 8c38ec4..2fd2e7e 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -38,20 +38,21 @@ int main(int argc, char** argv) { //exit handler for the main thread; exit_now = prepareSignalHandler(); - //get-opt configuration Config *conf = configuration(argc, argv); + if (conf->my_cfdp_id == 0 || conf->client_cfdp_id == 0){ + ssp_printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); + return 1; + } //Memory information base MIB *mib = init_mib(); - //setting host name for testing char *host_name = "127.0.0.1"; uint32_t addr[sizeof(uint32_t)]; inet_pton(AF_INET, host_name, addr); - //adding new cfdp entities to management information base add_new_cfdp_entity(mib, 1, *addr, 1111); @@ -59,6 +60,7 @@ int main(int argc, char** argv) { add_new_cfdp_entity(mib, 3, *addr, 1113); add_new_cfdp_entity(mib, 4, *addr, 1114); + //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, conf->my_cfdp_id, NULL, NULL); @@ -77,13 +79,14 @@ int main(int argc, char** argv) { p_state->mib = mib; p_state->verbose_level = conf->verbose_level; + //create a client Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - //send via acknoleged mode - put_request("test.txt", "delivered_file.txt", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - //put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + //send via acknoleged mode //0 acknowledged, 1 unacknowledged + //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); //will block on pthread_join ssp_cleanup_client(new_client); diff --git a/Program/src/port.c b/Program/src/port.c index b440bde..0b48844 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -144,13 +144,10 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct soc res.addr = posix_client; res.sfd = sfd; res.packet_len = *buff_size; - Client *client = p_state->newClient; - + res.msg = client->outGoing_req->buff; //fills the request struct - parse_packet_client(packet, client->incoming_req, client, p_state); - - packet_handler_client(res, client->incoming_req, client, p_state); + parse_packet_client(packet, res, client->outGoing_req, client, p_state); return 0; } @@ -271,7 +268,6 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { checkAlloc(client, 1); client->outGoing_req = init_request(PACKET_LEN); - client->incoming_req = init_request(PACKET_LEN); pthread_t *handler = calloc(sizeof(pthread_t), 1); checkAlloc(handler, 1); @@ -394,7 +390,6 @@ void ssp_cleanup_client(Client *client) { #endif ssp_cleanup_req(client->outGoing_req); - ssp_cleanup_req(client->incoming_req); free(client->client_handle); free(client->client_thread_attributes); ssp_cleanup_pdu_header(client->pdu_header); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 947e6e2..ef96b40 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -10,9 +10,12 @@ //returns the location in the packet where the next pointer for tthe packet will start after the header -static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, Pdu_header *pdu_header) { +static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); uint32_t packet_index = PACKET_STATIC_HEADER_LEN; + + Pdu_header *header = (Pdu_header *)packet; + header->transmission_mode = transmission_mode; //copy variable length src id memcpy(&packet[packet_index], @@ -94,6 +97,37 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * return packet_index; } +static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client, Protocol_state *p_state) { + + if (offset > req->file->total_size) { + return -1; + } + + Pdu_header *header = (Pdu_header *) packet; + //set header to file directive 0 is directive, 1 is data + header->PDU_type = 1; + + uint16_t packet_index = start; + File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; + packet_offset->offset = offset; + + //4 bytes is the size of the offset paramater + packet_index += 4; + uint16_t data_size = client->packet_len - packet_index; + //fill the rest of the packet with data + int bytes = get_offset(req->file, &packet[packet_index], data_size, offset); + if (bytes <= 0){ + ssp_error("could not get offset, this could because the file is empty!\n"); + return -1; + } + + //add bytes read, and the packet offset to the data_field length + header->PDU_data_field_len = htons(bytes + 4); + if (bytes < data_size) + return 1; + +} + //requires a req->file to be created //returns 1 on end of file @@ -111,21 +145,21 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli uint16_t packet_index = start; File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &res.msg[packet_index]; - //4 bytes is the size of the offset paramater TODO set offset + //4 bytes is the size of the offset paramater packet_offset->offset = req->file->next_offset_to_send; packet_index += 4; uint16_t data_size = client->packet_len - packet_index; //fill the rest of the packet with data - int bytes = get_offset(req->file, &res.msg[packet_index], data_size, packet_offset->offset); + int bytes = get_offset(req->file, &res.msg[packet_index], data_size, req->file->next_offset_to_send); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); return -1; } + //calculate checksum for data packet, this is used to calculate in transit checksums req->file->partial_checksum += calc_check_sum(&res.msg[packet_index], bytes); - req->file->next_offset_to_send += bytes; //add bytes read, and the packet offset to the data_field length @@ -170,11 +204,55 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* } + void print(void *element, void *args) { - Offset * o = (Offset *) args; + Offset * o = (Offset *) element; ssp_printf("start: %u, end: %u\n", o->start, o->end); } + + +struct offset_holder { + Offset *offsets; + int i; +}; + + +static void fill_nak_array(void *element, void *args){ + struct offset_holder *holder = (struct offset_holder *)args; + + Offset *offset = (Offset *)element; + + holder->offsets[holder->i].start = htonl(offset->start); + holder->offsets[holder->i].end = htonl(offset->end); + + ssp_printf("offset: start:%u, end:%u\n", offset->start, offset->end); + holder->i++; +} + +void build_nak_packet(char *packet, uint32_t start, Request *req) { + + packet[start] = NAK_PDU; + uint32_t packet_index = start + 1; + Pdu_nak *pdu_nak = (Pdu_nak *) &packet[packet_index]; + uint64_t count = req->file->missing_offsets->count; + + //fill offset array with all missing offsets [holder.offsets] + struct offset_holder holder; + holder.offsets = ssp_alloc(count, sizeof(Offset)); + holder.i = 0; + + req->file->missing_offsets->print(req->file->missing_offsets, fill_nak_array, &holder); + + pdu_nak->start_scope = holder.offsets[0].start;; + pdu_nak->end_scope = holder.offsets[holder.i-1].end;; + pdu_nak->segment_requests = htonll(count); + packet_index+=16; + + memcpy(&packet[packet_index], holder.offsets, sizeof(Offset) * count); + ssp_free(holder.offsets); +} + static void process_pdu_eof(char *packet, Request *req) { Pdu_eof *eof_packet = (Pdu_eof *) packet; @@ -184,12 +262,18 @@ static void process_pdu_eof(char *packet, Request *req) { //ssp_printf("actual checksum: %u\n", eof_packet->checksum); uint32_t file_size = ntohl(eof_packet->file_size); - ssp_printf("received filesize eof: %u\n", file_size); + ssp_printf("received eof packet, filesize: %u\n", file_size); //ssp_printf("missing offsets after file received eof: count: %u\n", req->file->missing_offsets->count); req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); + req->file->eof_checksum = eof_packet->checksum; + + //if transmission mode unacknowledged, close file + if (req->transmission_mode == 0) + return; + if (ssp_close(req->file->fd) == -1) ssp_error("could not close file\n"); @@ -200,14 +284,15 @@ static void process_pdu_eof(char *packet, Request *req) { static int process_file_request_metadata(Request *req) { if (does_file_exist(req->destination_file_name)){ - ssp_error("file already exists, overwriting it\n"); + //ssp_error("file already exists, overwriting it\n"); req->file = create_file(req->destination_file_name, 1); } if (req->file == NULL) { - ssp_printf("creating file: %s\n", req->destination_file_name); + //ssp_printf("creating file: %s\n", req->destination_file_name); req->file = create_file(req->destination_file_name, 1); } + ssp_printf("received metadata packet\n"); //add offset for naks Offset *offset = ssp_alloc(1, sizeof(Offset)); offset->end = req->file_size; @@ -217,6 +302,7 @@ static int process_file_request_metadata(Request *req) { if (req->transmission_mode == 1) return 1; + ssp_printf("mode acknowledged, building offset map\n"); req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); return 1; @@ -240,12 +326,10 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; - uint16_t packet_data_len = ntohs(header->PDU_data_field_len); - if (p_state->verbose_level == 3) { ssp_printf("------------printing_header_received------------\n"); ssp_print_hex(packet, packet_index); - ssp_printf("packet data length %d, sequence number %d\n", packet_data_len, transaction_sequence_number); + ssp_printf("packet data length %d, sequence number %d\n", transaction_sequence_number); } if (p_state->my_cfdp_id != dest_id){ @@ -256,6 +340,8 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state req->transmission_mode = header->transmission_mode; req->dest_cfdp_id = source_id; req->transaction_sequence_number = transaction_sequence_number; + + return packet_index; } @@ -271,8 +357,10 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil //ssp_printf("packet offset received: %d\n", packet->offset); int bytes = write_offset(file, &data_packet[4], data_len - 4, offset_start); - if (bytes <= 0) + if (bytes <= 0) { + ssp_error("no new data was written\n"); return; + } file->partial_checksum += calc_check_sum(&data_packet[4], bytes); @@ -322,25 +410,47 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi //fills the current request with packet data, responses from servers -void parse_packet_client(char *packet, Request *req, Client* client, Protocol_state *p_state) { - ssp_printf("client received %x\n", packet); +void parse_packet_client(char *packet, Response res, Request *req, Client* client, Protocol_state *p_state) { + + + uint32_t packet_index = process_pdu_header(packet, req, p_state); + Pdu_header *header = (Pdu_header *) packet; + uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + if (packet[packet_index] == NAK_PDU){ + ssp_printf("client received nak\n"); + packet_index += 1; + Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; + uint32_t ostart = ntohl(nak->start_scope); + uint32_t oend = ntohl(nak->end_scope); + uint64_t segments = ntohll(nak->segment_requests); + + if (req->buff == NULL){ + ssp_printf("req->buff is null\n"); + } + if (client->pdu_header == NULL){ + ssp_printf("pdu_header is null\n"); + } + + uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, client->pdu_header); + + + //for (int i = 0; i < segments; i++){ + build_nak_response(req->buff, outgoing_packet_index, ostart, req, client, p_state) ; + ssp_sendto(res); + //} + - process_pdu_header(packet, req, p_state); - //ssp_printf("client sequence number %u\n", req->transaction_sequence_number); - //ssp_printf("client transmission mode %u\n", req->transmission_mode); - //ssp_printf("client request type %u\n", req->type); + + //ssp_printf("req sequence nubmer: %u\n", req->transaction_sequence_number); + //uint32_t outgoing_packet_index = build_pdu_header(req->buff, client->outGoing_req->transaction_sequence_number, 0, client->outGoing_req->pdu_header); + //ssp_sendto(client->outGoing_req->res); + //ssp_printf("client received start: %u, end: %u\n", ostart, oend); + //ssp_print_hex(packet, 40); - //ssp_print_hex(packet, 10); + } } -//Client responses -void packet_handler_client(Response res, Request *req, Client* client, Protocol_state *p_state) { - //res.msg = "Client Received!\n"; - //ssp_sendto(res); -} - - /*------------------------------------------------------------------------------ SERVER SIDE @@ -348,31 +458,17 @@ void packet_handler_client(Response res, Request *req, Client* client, Protocol_ ------------------------------------------------------------------------------*/ -static void request_missing_offsets(Response res, Request *req){ - -} - - void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { + //ssp_printf("time out missing packet count:%d\n", req->file->missing_offsets->count); res.msg = req->buff; if (req->file->missing_offsets->count > 0) { - req->file->missing_offsets->print(p_state->current_server_request->file->missing_offsets, print, NULL); - request_missing_offsets(res, req); + memset(res.msg, 0, res.packet_len); + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); + build_nak_packet(res.msg, start, req); + ssp_sendto(res); return; - } - - //request_missing_offset(); - - uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->pdu_header); - //ssp_printf("server sequence number %u\n", req->transaction_sequence_number); - //ssp_printf("server transmission mode %u\n", req->transmission_mode); - //ssp_printf("server request type %u\n", req->type); - ssp_printf("p_state->current_server_request->transaction_sequence number %u\n", p_state->current_server_request->transaction_sequence_number); - - ssp_sendto(res); - - + } } //Server responses @@ -385,9 +481,11 @@ void packet_handler_server(Response res, Request *current_request, Protocol_stat //fills the current_request struct for the server, incomming requests void parse_packet_server(char *packet, uint32_t packet_len, Request *req, Protocol_state *p_state) { + uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; + //most of this can be replaced with the process header func uint32_t source_id = 0; memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; @@ -418,18 +516,12 @@ void parse_packet_server(char *packet, uint32_t packet_len, Request *req, Protoc req->dest_cfdp_id = source_id; req->transaction_sequence_number = transaction_sequence_number; - if (process_pdu_header(packet, req, p_state) == -1){ - return; - } - - ssp_printf("received p_state->current_server_request->transaction_sequence number %u\n", p_state->current_server_request->transaction_sequence_number); - //process file data if (header->PDU_type == 1) { + write_packet_data_to_file(&packet[packet_index], packet_data_len, req->file); return; } - //set header for responding later if (req->pdu_header == NULL){ @@ -478,8 +570,7 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s res.msg = req->buff; memset(res.msg, 0, client->packet_len); - - uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, client->pdu_header); + uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); switch (req->type) { diff --git a/Program/src/utils.c b/Program/src/utils.c index 83ae836..c36c6e3 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -48,6 +48,8 @@ Config *configuration(int argc, char **argv) conf->timer = 15; conf->verbose_level = 0; + conf->client_cfdp_id = 0; + conf->my_cfdp_id = 0; uint32_t tmp; while ((ch = getopt(argc, argv, "t: i: c: v: h")) != -1) @@ -72,7 +74,6 @@ Config *configuration(int argc, char **argv) case 'c': tmp = strtol(optarg, NULL, 10); conf->client_cfdp_id = tmp; - break; case 'h': diff --git a/Program/test/makefile b/Program/test/makefile index 9a8deba..5e8dea5 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -5,7 +5,12 @@ CC = gcc #---------------------------File Names--------------------------- CFILES += $(PROJDIR)/src/utils.c -#VPATH = (PROJDIR)/src +CFILES += $(PROJDIR)/src/filesystem_funcs.c +CFILES += $(PROJDIR)/src/port.c +CFILES += $(PROJDIR)/src/server.c +CFILES += $(PROJDIR)/src/protocol_handler.c +CFILES += $(PROJDIR)/src/list_callbacks.c +CFILES += $(PROJDIR)/src/mib.c #entrypoint MAIN = main From 3de98f4d51e9cea0c62cc362e5e8bab4eccc36fd Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 7 Apr 2019 19:32:05 -0600 Subject: [PATCH 036/400] Demoable --- Program/include/mib.h | 2 +- Program/include/packet.h | 25 +++++- Program/include/port.h | 3 + Program/include/protocol_handler.h | 4 +- Program/include/server.h | 2 +- Program/src/filesystem_funcs.c | 3 + Program/src/main.c | 37 +++------ Program/src/mib.c | 6 +- Program/src/port.c | 60 ++++++++++++-- Program/src/protocol_handler.c | 127 ++++++++++++++++++----------- Program/src/server.c | 7 ++ 11 files changed, 193 insertions(+), 83 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 4d3dfc0..d0d3808 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -90,6 +90,6 @@ typedef struct mib { MIB *init_mib(void); void free_mib(MIB *mib); int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port); -Pdu_header *get_header_from_mib(MIB *mib, uint32_t cfdp_id); +Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); #endif \ No newline at end of file diff --git a/Program/include/packet.h b/Program/include/packet.h index 93fd095..e937a0f 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -189,7 +189,6 @@ typedef struct filestore_response { #define NAK_PDU 0x08 #define PROMPT_PDU 0x09 #define KEEP_ALIVE_PDU 0x0C - #define SIZE_OF_DIRECTIVE_CODE 1 //condition codes: @@ -294,4 +293,28 @@ typedef struct pdu_nak { + +//file_status codes +#define FILE_DISCARDED_DELIBERATELY 1 +#define FILE_DISCARDED_DUE_TO_REJECTION 2 +#define FILE_RETAINED_SUCCESSFULLY 3 +#define FILE_STATUS_UNREPORTED 4 + + +typedef struct pdu_finished { + unsigned int condition_code : 4; + + // 0 generated by waypoint 1 generated by end system. + unsigned int end_system_status : 1; + + //0 data complete, 1 data incomplete + unsigned int delivery_code : 1; + + //see above + unsigned int file_status : 2; + TLV file_store_responses; + TLV fault_location; + +}Pdu_finished; + #endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index 83554aa..7e47553 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -32,4 +32,7 @@ void ssp_error(char *error); int ssp_write(int fd, const void *buf, size_t count); int ssp_close(int fd); void ssp_free(void *pointer); + +void reset_request(Request *req); + #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index a591663..181c819 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -18,6 +18,7 @@ typedef struct response { } Response; typedef enum Indication { + finished, none, transaction, put, @@ -102,8 +103,7 @@ typedef struct protocol_state { } Protocol_state; -void packet_handler_server(Response res, Request *req, Protocol_state *p_state); -void parse_packet_server(char* buff, uint32_t packet_len, Request *req, Protocol_state *p_state); +void parse_packet_server(char* buff, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); void parse_packet_client(char* buff, Response res, Request *req, Client *client, Protocol_state *p_state); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); diff --git a/Program/include/server.h b/Program/include/server.h index 7d5c6f0..6d2bfd3 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -45,6 +45,7 @@ int prepareUdpHost(char *port); void udpSelectServer(char *port, int packet_len, int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), void *other); /*-----------------------------CALLBACK onTimeOut------------------------------- @@ -58,7 +59,6 @@ void udpSelectServer(char *port, int packet_len, int *prepareSignalHandler(void); - void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 7372736..8d0b94e 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -13,17 +13,20 @@ uint32_t get_file_size(char *source_file_name) { int fd = ssp_open(source_file_name, 0); if (fd == -1){ + ssp_error("could not open file\n"); return -1; } int bytes = ssp_lseek(fd, 0, 2); if (bytes == -1){ + ssp_error("could not seek file for file size\n"); return -1; } ssp_lseek(fd, 0, 0); if (ssp_close(fd) == -1){ + ssp_error("could not close file\n"); return -1; } diff --git a/Program/src/main.c b/Program/src/main.c index 2fd2e7e..88e521d 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -21,18 +21,6 @@ //exit handler variable for the main thread static int *exit_now; -/* -static void p(void *element, void *args) { - - Remote_entity *remote_entity = element; - ssp_printf("[\n id: %d\n remote_ut_address: %d:%d\n]\n", - remote_entity->cfdp_id, - remote_entity->UT_address, - remote_entity->UT_port - ); -} -*/ - int main(int argc, char** argv) { //exit handler for the main thread; @@ -41,7 +29,7 @@ int main(int argc, char** argv) { //get-opt configuration Config *conf = configuration(argc, argv); - if (conf->my_cfdp_id == 0 || conf->client_cfdp_id == 0){ + if (conf->my_cfdp_id == 0){ ssp_printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } @@ -60,15 +48,12 @@ int main(int argc, char** argv) { add_new_cfdp_entity(mib, 3, *addr, 1113); add_new_cfdp_entity(mib, 4, *addr, 1114); - - //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, conf->my_cfdp_id, NULL, NULL); if (server_entity == NULL) { printf("couldn't find entity\n"); } - //connectionless server char port[17]; snprintf(port, 17, "%u", server_entity->UT_port); @@ -79,17 +64,21 @@ int main(int argc, char** argv) { p_state->mib = mib; p_state->verbose_level = conf->verbose_level; - - //create a client - Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + + if (conf->client_cfdp_id != 0){ + + ssp_printf("input a src file:\n"); + Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - //send via acknoleged mode //0 acknowledged, 1 unacknowledged - //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + //send via acknoleged mode //0 acknowledged, 1 unacknowledged + //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + //put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + + //will block on pthread_join + ssp_cleanup_client(new_client); + } - //will block on pthread_join - ssp_cleanup_client(new_client); ssp_cleanup(p_state); free(conf); diff --git a/Program/src/mib.c b/Program/src/mib.c index 39665ec..2e160a8 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -44,9 +44,9 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ } -Pdu_header *get_header_from_mib(MIB *mib, uint32_t cfdp_id){ +Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ - Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, cfdp_id, NULL, NULL); + Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, dest_id, NULL, NULL); if (remote == NULL) { return NULL; } @@ -70,7 +70,7 @@ Pdu_header *get_header_from_mib(MIB *mib, uint32_t cfdp_id){ pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); checkAlloc(pdu_header->source_id, 1); - memcpy(pdu_header->source_id, &cfdp_id, pdu_header->length_of_entity_IDs); + memcpy(pdu_header->source_id, &source_id, pdu_header->length_of_entity_IDs); return pdu_header; } diff --git a/Program/src/port.c b/Program/src/port.c index 0b48844..d2f5c65 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -124,10 +124,10 @@ static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, struct soc res.packet_len = p_state->packet_size; //filles the request struct, in the future get request based on id - parse_packet_server(packet, res.packet_len, p_state->current_server_request, p_state); + parse_packet_server(packet, res.packet_len, res, p_state->current_server_request, p_state); //ssp_printf("Server received: %s\n", msg); - packet_handler_server(res, p_state->current_server_request, p_state); + //packet_handler_server(res, p_state->current_server_request, p_state); return 0; } @@ -185,13 +185,52 @@ static int on_time_out_posix(void *other) { } +//this function is just for posix fun +static int on_stdin(void *other) { + + Protocol_state *p_state = (Protocol_state *) other; + Request *req = p_state->newClient->outGoing_req; + + char input[MAX_PATH]; + fgets(input, MAX_PATH, stdin); + input[strlen(input)-1]='\0'; + + if (req->type == none){ + if (strnlen(req->source_file_name, MAX_PATH) == 0){ + if (get_file_size(input) == -1){ + ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); + return 0; + } + memcpy(p_state->newClient->outGoing_req->source_file_name, input, MAX_PATH); + ssp_printf("Enter a destination file name:\n"); + } + else if (strnlen(req->destination_file_name, MAX_PATH) == 0){ + memcpy(p_state->newClient->outGoing_req->destination_file_name, input, MAX_PATH); + ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", p_state->newClient->outGoing_req->source_file_name, p_state->newClient->outGoing_req->destination_file_name, p_state->newClient->cfdp_id); + ssp_printf("cancel connection mode (yes):\n"); + } + else if (strncmp(input, "yes", 3) == 0){ + ssp_printf("sending file connectionless\n"); + put_request(p_state->newClient->outGoing_req->source_file_name, p_state->newClient->outGoing_req->destination_file_name, 0, 0, 0, 1, NULL, NULL, p_state->newClient, p_state); + } + else { + ssp_printf("sending file connected\n"); + put_request(p_state->newClient->outGoing_req->source_file_name, p_state->newClient->outGoing_req->destination_file_name, 0, 0, 0, 0, NULL, NULL, p_state->newClient, p_state); + } + } + + return 0; + +} + + void *ssp_connectionless_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; #ifdef POSIX_PORT - udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, p_state); + udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, p_state); #endif return NULL; @@ -303,8 +342,9 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { client->unitdata_port = remote->UT_port; client->unitdata_id = remote->UT_address; client->mib_info = remote; - client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id); + client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); + //TODO lock this p_state->newClient = client; @@ -318,6 +358,16 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { } +void reset_request(Request *req){ + memset(req->source_file_name, 0, MAX_PATH); + memset(req->destination_file_name, 0, MAX_PATH); + memset(req->buff, 0, req->buff_len); + memset(req->res.addr, 0, sizeof(struct sockaddr_in)); + free_file(req->file); + + req->type = none; + +} Request *init_request(uint32_t buff_len) { @@ -335,7 +385,7 @@ Request *init_request(uint32_t buff_len) { req->buff = ssp_alloc(buff_len, sizeof(char)); req->res.addr = ssp_alloc(1, sizeof(struct sockaddr_in)); - + req->type = none; checkAlloc(req->buff, 1); return req; } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index ef96b40..44ce7b8 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -5,9 +5,10 @@ #include "string.h" #include "packet.h" - - - +//for progress bar +#include "unistd.h" +#include "stdio.h" +#include "stddef.h" //returns the location in the packet where the next pointer for tthe packet will start after the header static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { @@ -42,6 +43,26 @@ static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_numb return total_bytes; } +static uint8_t build_finished_packet(char *packet, uint32_t start, Request *req) { + + uint32_t packet_index = start; + uint32_t data_len = 0; + + Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; + directive->directive_code = FINISHED_PDU; + packet_index++; + + Pdu_finished *pdu_finished = (Pdu_finished *) &packet[packet_index]; + pdu_finished->condition_code = COND_NO_ERROR; + pdu_finished->delivery_code = 0; + pdu_finished->file_status = FILE_RETAINED_SUCCESSFULLY; + + data_len = 8; + packet_index += 8; + return data_len; +} + + static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { Pdu_header *header = (Pdu_header *) res.msg; @@ -92,9 +113,6 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * //mark the size of the packet header->PDU_data_field_len = htons(total_bytes); - - //ssp_print_hex(&res.msg[start], total_bytes); - return packet_index; } static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client, Protocol_state *p_state) { @@ -204,20 +222,16 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* } - void print(void *element, void *args) { Offset * o = (Offset *) element; ssp_printf("start: %u, end: %u\n", o->start, o->end); } - - struct offset_holder { Offset *offsets; int i; }; - static void fill_nak_array(void *element, void *args){ struct offset_holder *holder = (struct offset_holder *)args; @@ -226,7 +240,7 @@ static void fill_nak_array(void *element, void *args){ holder->offsets[holder->i].start = htonl(offset->start); holder->offsets[holder->i].end = htonl(offset->end); - ssp_printf("offset: start:%u, end:%u\n", offset->start, offset->end); + //ssp_printf("sending offset: start:%u, end:%u\n", offset->start, offset->end); holder->i++; } @@ -258,13 +272,10 @@ static void process_pdu_eof(char *packet, Request *req) { Pdu_eof *eof_packet = (Pdu_eof *) packet; if (eof_packet->checksum == req->file->partial_checksum) { - //ssp_printf("received checksum: %u\n", req->file->partial_checksum); - //ssp_printf("actual checksum: %u\n", eof_packet->checksum); uint32_t file_size = ntohl(eof_packet->file_size); ssp_printf("received eof packet, filesize: %u\n", file_size); - //ssp_printf("missing offsets after file received eof: count: %u\n", req->file->missing_offsets->count); req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); req->file->eof_checksum = eof_packet->checksum; @@ -333,7 +344,7 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state } if (p_state->my_cfdp_id != dest_id){ - ssp_printf("someone is sending packets here that are not for me\n"); + ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", p_state->my_cfdp_id, dest_id); return -1; } @@ -346,15 +357,14 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state } static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { - if(file == NULL) + if(file == NULL) { ssp_error("file struct is null, can't write to file"); + ssp_printf("dropped metadata packet :( we have no fix for this yet\n " ); - + } File_data_pdu_contents *packet = (File_data_pdu_contents *)data_packet; uint32_t offset_start = packet->offset; uint32_t offset_end = offset_start + data_len - 4; - - //ssp_printf("packet offset received: %d\n", packet->offset); int bytes = write_offset(file, &data_packet[4], data_len - 4, offset_start); if (bytes <= 0) { @@ -394,7 +404,6 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); packet_index += file_name_len; - //ssp_print_hex(meta_data_packet, packet_index); return; } @@ -408,16 +417,42 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi ------------------------------------------------------------------------------*/ +//taken from https://gist.github.com/amullins83/24b5ef48657c08c4005a8fab837b7499 + +void print_progress(size_t count, size_t max) +{ + const char prefix[] = "Progress: ["; + const char suffix[] = "]"; + const size_t prefix_length = sizeof(prefix) - 1; + const size_t suffix_length = sizeof(suffix) - 1; + char *buffer = ssp_alloc(max + prefix_length + suffix_length + 1, 1); // +1 for \0 + size_t i = 0; + + strcpy(buffer, prefix); + for (; i < max; ++i) + { + buffer[prefix_length + i] = i < count ? '#' : ' '; + } + + strcpy(&buffer[prefix_length + i], suffix); + printf("\b%c[2K\r%s\n", 27, buffer); + fflush(stdout); + ssp_free(buffer); +} + //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, Response res, Request *req, Client* client, Protocol_state *p_state) { uint32_t packet_index = process_pdu_header(packet, req, p_state); + if (packet_index == -1) + return; + Pdu_header *header = (Pdu_header *) packet; uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + if (packet[packet_index] == NAK_PDU){ - ssp_printf("client received nak\n"); packet_index += 1; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; uint32_t ostart = ntohl(nak->start_scope); @@ -432,21 +467,23 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien } uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, client->pdu_header); - - + //for (int i = 0; i < segments; i++){ build_nak_response(req->buff, outgoing_packet_index, ostart, req, client, p_state) ; + print_progress(ostart/1000, req->file_size/1000); ssp_sendto(res); + + //send another EOF + req->type = eof; //} - - - //ssp_printf("req sequence nubmer: %u\n", req->transaction_sequence_number); - //uint32_t outgoing_packet_index = build_pdu_header(req->buff, client->outGoing_req->transaction_sequence_number, 0, client->outGoing_req->pdu_header); - //ssp_sendto(client->outGoing_req->res); - //ssp_printf("client received start: %u, end: %u\n", ostart, oend); - //ssp_print_hex(packet, 40); + } else if (packet[packet_index] == FINISHED_PDU) { + if (req->type != finished) { + print_progress(req->file_size/1000, req->file_size/1000); + ssp_printf("file successfully sent\n"); + } + req->type = finished; } } @@ -459,27 +496,28 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien ------------------------------------------------------------------------------*/ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { - //ssp_printf("time out missing packet count:%d\n", req->file->missing_offsets->count); res.msg = req->buff; + //req->pdu_header is broken + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); + if (req->file->missing_offsets->count > 0) { - memset(res.msg, 0, res.packet_len); - uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); build_nak_packet(res.msg, start, req); ssp_sendto(res); return; + } + + if (req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { + Pdu_header *header = (Pdu_header *) res.msg; + uint32_t dest_id = 0; + memcpy(&dest_id, &header->destination_id, header->length_of_entity_IDs); + build_finished_packet(res.msg, start, req); + ssp_sendto(res); } } -//Server responses -void packet_handler_server(Response res, Request *current_request, Protocol_state *p_state) { - //res.msg = "Server Received\n"; - //ssp_sendto(res); -} - - //fills the current_request struct for the server, incomming requests -void parse_packet_server(char *packet, uint32_t packet_len, Request *req, Protocol_state *p_state) { +void parse_packet_server(char *packet, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -518,14 +556,13 @@ void parse_packet_server(char *packet, uint32_t packet_len, Request *req, Protoc //process file data if (header->PDU_type == 1) { - write_packet_data_to_file(&packet[packet_index], packet_data_len, req->file); return; } //set header for responding later if (req->pdu_header == NULL){ - req->pdu_header = get_header_from_mib(p_state->mib, source_id); + req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); } Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; @@ -540,8 +577,6 @@ void parse_packet_server(char *packet, uint32_t packet_len, Request *req, Protoc case EOF_PDU: process_pdu_eof(&packet[packet_index], req); - - break; default: break; @@ -639,7 +674,6 @@ int put_request(char *source_file_name, Request *req = client->outGoing_req; req->file = create_file(source_file_name, 0); - //build a request req->transaction_sequence_number = p_state->transaction_sequence_number++; @@ -658,6 +692,7 @@ int put_request(char *source_file_name, req->transmission_mode = transmission_mode; req->messages_to_user = messages_to_user; req->filestore_requests = filestore_requests; + return 0; } diff --git a/Program/src/server.c b/Program/src/server.c index df71162..0ac0a5a 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -146,6 +146,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf void udpSelectServer(char* port, int packet_len, int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_storage client, void *other), int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), void *other) { int sfd = prepareUdpHost(port); @@ -200,6 +201,11 @@ void udpSelectServer(char* port, int packet_len, printf("timeout failed\n"); continue; } + + if (FD_ISSET(STDIN_FILENO, &readFds)) { + onStdIn(other); + continue; + } //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html // good article! @@ -208,6 +214,7 @@ void udpSelectServer(char* port, int packet_len, socklen_t client_len = sizeof(*client); int count = recvfrom(sfd, buff, packet_len, 0, (struct sockaddr*)client, &client_len); + if (count == -1) { From ff04811630790475225d9d46e7a40ac98f0ef1c2 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 15 Apr 2019 11:59:20 -0600 Subject: [PATCH 037/400] refactoring, going to do process_header function next --- Program/src/main.c | 7 +++--- Program/src/port.c | 3 ++- Program/src/protocol_handler.c | 41 ++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index 88e521d..5646279 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -58,7 +58,8 @@ int main(int argc, char** argv) { char port[17]; snprintf(port, 17, "%u", server_entity->UT_port); - Protocol_state *p_state = ssp_connectionless_server(port); + Protocol_state *p_state = ssp_connectionless_server(port); + //set this node's Id, this has to be hardcoded/assigned p_state->my_cfdp_id = conf->my_cfdp_id; p_state->mib = mib; @@ -68,12 +69,12 @@ int main(int argc, char** argv) { if (conf->client_cfdp_id != 0){ - ssp_printf("input a src file:\n"); + //ssp_printf("input a src file:\n"); Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - //put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); //will block on pthread_join ssp_cleanup_client(new_client); diff --git a/Program/src/port.c b/Program/src/port.c index d2f5c65..6434035 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -188,6 +188,7 @@ static int on_time_out_posix(void *other) { //this function is just for posix fun static int on_stdin(void *other) { + /* Protocol_state *p_state = (Protocol_state *) other; Request *req = p_state->newClient->outGoing_req; @@ -218,7 +219,7 @@ static int on_stdin(void *other) { put_request(p_state->newClient->outGoing_req->source_file_name, p_state->newClient->outGoing_req->destination_file_name, 0, 0, 0, 0, NULL, NULL, p_state->newClient, p_state); } } - + */ return 0; } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 44ce7b8..e3f608f 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -232,6 +232,7 @@ struct offset_holder { int i; }; +//this is a callback for building nak_array server side static void fill_nak_array(void *element, void *args){ struct offset_holder *holder = (struct offset_holder *)args; @@ -239,8 +240,6 @@ static void fill_nak_array(void *element, void *args){ holder->offsets[holder->i].start = htonl(offset->start); holder->offsets[holder->i].end = htonl(offset->end); - - //ssp_printf("sending offset: start:%u, end:%u\n", offset->start, offset->end); holder->i++; } @@ -455,9 +454,10 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien if (packet[packet_index] == NAK_PDU){ packet_index += 1; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; - uint32_t ostart = ntohl(nak->start_scope); - uint32_t oend = ntohl(nak->end_scope); + uint32_t offset_first = ntohl(nak->start_scope); + uint32_t offset_last = ntohl(nak->end_scope); uint64_t segments = ntohll(nak->segment_requests); + packet_index += 16; if (req->buff == NULL){ ssp_printf("req->buff is null\n"); @@ -467,20 +467,35 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien } uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, client->pdu_header); - - //for (int i = 0; i < segments; i++){ - build_nak_response(req->buff, outgoing_packet_index, ostart, req, client, p_state) ; - print_progress(ostart/1000, req->file_size/1000); - ssp_sendto(res); + uint32_t offset_start = 0; + uint32_t offset_end = 0; + + + printf("number of segments to resend: %u\n", segments); + for (int i = 0; i < segments; i++){ + //outgoing_packet_index + memcpy(&offset_start, &packet[packet_index], 4); + offset_start = ntohl(offset_start); + packet_index += 4; + memcpy(&offset_end, &packet[packet_index], 4); + offset_end = ntohl(offset_end); + packet_index += 4; + + printf("offset sending first %u last %u\n", offset_start, offset_end); + printf("first %u and end %u\n", offset_first, offset_last); + + build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client, p_state); + + ssp_sendto(res); //send another EOF req->type = eof; - //} + } } else if (packet[packet_index] == FINISHED_PDU) { if (req->type != finished) { - print_progress(req->file_size/1000, req->file_size/1000); + //print_progress(req->file_size/1000, req->file_size/1000); ssp_printf("file successfully sent\n"); } req->type = finished; @@ -498,7 +513,6 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { res.msg = req->buff; - //req->pdu_header is broken uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); if (req->file->missing_offsets->count > 0) { @@ -519,6 +533,9 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { //fills the current_request struct for the server, incomming requests void parse_packet_server(char *packet, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state) { + uint32_t packet_index_start = process_pdu_header(packet, req, p_state); + + uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; From 1188359d7f7289f1cf0e44a292275ffc9a059177 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 15 Apr 2019 14:28:39 -0600 Subject: [PATCH 038/400] add ringbuffer file, move all parsing of header into process_pdu_header() --- Program/include/packet.h | 4 + Program/include/protocol_handler.h | 14 +- Program/include/ringbuf.h | 243 ++++++++++++++++++++ Program/src/makefile | 1 + Program/src/port.c | 34 +-- Program/src/protocol_handler.c | 79 +++---- Program/src/ringbuf.c | 347 +++++++++++++++++++++++++++++ 7 files changed, 655 insertions(+), 67 deletions(-) create mode 100644 Program/include/ringbuf.h create mode 100644 Program/src/ringbuf.c diff --git a/Program/include/packet.h b/Program/include/packet.h index e937a0f..f3ae6a5 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -181,6 +181,10 @@ typedef struct filestore_response { ------------------------------------------------------------------------------*/ + +#define DIRECTIVE 0 +#define DATA 1 + //directive_codes 00 - 03, and 0D-FF are reserved #define EOF_PDU 0x04 #define FINISHED_PDU 0x05 diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 181c819..6d8630c 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -40,14 +40,20 @@ typedef struct request { char *source_file_name; char *destination_file_name; + uint32_t packet_data_len; + uint8_t segmentation_control; uint8_t fault_handler_overides; uint8_t flow_lable; uint8_t transmission_mode; + + + char* messages_to_user; char* filestore_requests; + //sets the buffer length, for making packets uint32_t buff_len; //buffer for making packets @@ -66,10 +72,8 @@ typedef struct client { void *client_handle; void *client_thread_attributes; uint32_t packet_len; - - //this is a queue of user requests that will be going out - Request *outGoing_req; - Request *incoming_req; + + Request *req; //can get rid of these, these are found in mib_info anyway uint32_t cfdp_id; @@ -92,6 +96,8 @@ typedef struct protocol_state { MIB *mib; uint32_t my_cfdp_id; Client *newClient; + List* request_list; + Request *current_server_request; //lock this diff --git a/Program/include/ringbuf.h b/Program/include/ringbuf.h new file mode 100644 index 0000000..c72bfae --- /dev/null +++ b/Program/include/ringbuf.h @@ -0,0 +1,243 @@ +#ifndef INCLUDED_RINGBUF_H +#define INCLUDED_RINGBUF_H + +/* + * ringbuf.h - C ring buffer (FIFO) interface. + * + * Written in 2011 by Drew Hess . + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +/* + * A byte-addressable ring buffer FIFO implementation. + * + * The ring buffer's head pointer points to the starting location + * where data should be written when copying data *into* the buffer + * (e.g., with ringbuf_read). The ring buffer's tail pointer points to + * the starting location where data should be read when copying data + * *from* the buffer (e.g., with ringbuf_write). + */ + +#include +#include + +typedef struct ringbuf_t *ringbuf_t; + +/* + * Create a new ring buffer with the given capacity (usable + * bytes). Note that the actual internal buffer size may be one or + * more bytes larger than the usable capacity, for bookkeeping. + * + * Returns the new ring buffer object, or 0 if there's not enough + * memory to fulfill the request for the given capacity. + */ +ringbuf_t +ringbuf_new(size_t capacity); + +/* + * The size of the internal buffer, in bytes. One or more bytes may be + * unusable in order to distinguish the "buffer full" state from the + * "buffer empty" state. + * + * For the usable capacity of the ring buffer, use the + * ringbuf_capacity function. + */ +size_t +ringbuf_buffer_size(const struct ringbuf_t *rb); + +/* + * Deallocate a ring buffer, and, as a side effect, set the pointer to + * 0. + */ +void +ringbuf_free(ringbuf_t *rb); + +/* + * Reset a ring buffer to its initial state (empty). + */ +void +ringbuf_reset(ringbuf_t rb); + +/* + * The usable capacity of the ring buffer, in bytes. Note that this + * value may be less than the ring buffer's internal buffer size, as + * returned by ringbuf_buffer_size. + */ +size_t +ringbuf_capacity(const struct ringbuf_t *rb); + +/* + * The number of free/available bytes in the ring buffer. This value + * is never larger than the ring buffer's usable capacity. + */ +size_t +ringbuf_bytes_free(const struct ringbuf_t *rb); + +/* + * The number of bytes currently being used in the ring buffer. This + * value is never larger than the ring buffer's usable capacity. + */ +size_t +ringbuf_bytes_used(const struct ringbuf_t *rb); + +int +ringbuf_is_full(const struct ringbuf_t *rb); + +int +ringbuf_is_empty(const struct ringbuf_t *rb); + +/* + * Const access to the head and tail pointers of the ring buffer. + */ +const void * +ringbuf_tail(const struct ringbuf_t *rb); + +const void * +ringbuf_head(const struct ringbuf_t *rb); + +/* + * Locate the first occurrence of character c (converted to an + * unsigned char) in ring buffer rb, beginning the search at offset + * bytes from the ring buffer's tail pointer. The function returns the + * offset of the character from the ring buffer's tail pointer, if + * found. If c does not occur in the ring buffer, the function returns + * the number of bytes used in the ring buffer. + * + * Note that the offset parameter and the returned offset are logical + * offsets from the tail pointer, not necessarily linear offsets. + */ +size_t +ringbuf_findchr(const struct ringbuf_t *rb, int c, size_t offset); + +/* + * Beginning at ring buffer dst's head pointer, fill the ring buffer + * with a repeating sequence of len bytes, each of value c (converted + * to an unsigned char). len can be as large as you like, but the + * function will never write more than ringbuf_buffer_size(dst) bytes + * in a single invocation, since that size will cause all bytes in the + * ring buffer to be written exactly once each. + * + * Note that if len is greater than the number of free bytes in dst, + * the ring buffer will overflow. When an overflow occurs, the state + * of the ring buffer is guaranteed to be consistent, including the + * head and tail pointers; old data will simply be overwritten in FIFO + * fashion, as needed. However, note that, if calling the function + * results in an overflow, the value of the ring buffer's tail pointer + * may be different than it was before the function was called. + * + * Returns the actual number of bytes written to dst: len, if + * len < ringbuf_buffer_size(dst), else ringbuf_buffer_size(dst). + */ +size_t +ringbuf_memset(ringbuf_t dst, int c, size_t len); + +/* + * Copy n bytes from a contiguous memory area src into the ring buffer + * dst. Returns the ring buffer's new head pointer. + * + * It is possible to copy more data from src than is available in the + * buffer; i.e., it's possible to overflow the ring buffer using this + * function. When an overflow occurs, the state of the ring buffer is + * guaranteed to be consistent, including the head and tail pointers; + * old data will simply be overwritten in FIFO fashion, as + * needed. However, note that, if calling the function results in an + * overflow, the value of the ring buffer's tail pointer may be + * different than it was before the function was called. + */ +void * +ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count); + +/* + * This convenience function calls read(2) on the file descriptor fd, + * using the ring buffer rb as the destination buffer for the read, + * and returns the value returned by read(2). It will only call + * read(2) once, and may return a short count. + * + * It is possible to read more data from the file descriptor than is + * available in the buffer; i.e., it's possible to overflow the ring + * buffer using this function. When an overflow occurs, the state of + * the ring buffer is guaranteed to be consistent, including the head + * and tail pointers: old data will simply be overwritten in FIFO + * fashion, as needed. However, note that, if calling the function + * results in an overflow, the value of the ring buffer's tail pointer + * may be different than it was before the function was called. + */ +ssize_t +ringbuf_read(int fd, ringbuf_t rb, size_t count); + +/* + * Copy n bytes from the ring buffer src, starting from its tail + * pointer, into a contiguous memory area dst. Returns the value of + * src's tail pointer after the copy is finished. + * + * Note that this copy is destructive with respect to the ring buffer: + * the n bytes copied from the ring buffer are no longer available in + * the ring buffer after the copy is complete, and the ring buffer + * will have n more free bytes than it did before the function was + * called. + * + * This function will *not* allow the ring buffer to underflow. If + * count is greater than the number of bytes used in the ring buffer, + * no bytes are copied, and the function will return 0. + */ +void * +ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count); + +/* + * This convenience function calls write(2) on the file descriptor fd, + * using the ring buffer rb as the source buffer for writing (starting + * at the ring buffer's tail pointer), and returns the value returned + * by write(2). It will only call write(2) once, and may return a + * short count. + * + * Note that this copy is destructive with respect to the ring buffer: + * any bytes written from the ring buffer to the file descriptor are + * no longer available in the ring buffer after the copy is complete, + * and the ring buffer will have N more free bytes than it did before + * the function was called, where N is the value returned by the + * function (unless N is < 0, in which case an error occurred and no + * bytes were written). + * + * This function will *not* allow the ring buffer to underflow. If + * count is greater than the number of bytes used in the ring buffer, + * no bytes are written to the file descriptor, and the function will + * return 0. + */ +ssize_t +ringbuf_write(int fd, ringbuf_t rb, size_t count); + +/* + * Copy count bytes from ring buffer src, starting from its tail + * pointer, into ring buffer dst. Returns dst's new head pointer after + * the copy is finished. + * + * Note that this copy is destructive with respect to the ring buffer + * src: any bytes copied from src into dst are no longer available in + * src after the copy is complete, and src will have 'count' more free + * bytes than it did before the function was called. + * + * It is possible to copy more data from src than is available in dst; + * i.e., it's possible to overflow dst using this function. When an + * overflow occurs, the state of dst is guaranteed to be consistent, + * including the head and tail pointers; old data will simply be + * overwritten in FIFO fashion, as needed. However, note that, if + * calling the function results in an overflow, the value dst's tail + * pointer may be different than it was before the function was + * called. + * + * It is *not* possible to underflow src; if count is greater than the + * number of bytes used in src, no bytes are copied, and the function + * returns 0. + */ +void * +ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count); + +#endif /* INCLUDED_RINGBUF_H */ diff --git a/Program/src/makefile b/Program/src/makefile index 9e29e1c..e69ee1e 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -11,6 +11,7 @@ CFILES += protocol_handler.c CFILES += list_callbacks.c CFILES += mib.c CFILES += filesystem_funcs.c +CFILES += ringbuf.c #entrypoint MAIN = main diff --git a/Program/src/port.c b/Program/src/port.c index 6434035..c1cbfb7 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -123,11 +123,7 @@ static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, struct soc res.sfd = sfd; res.packet_len = p_state->packet_size; - //filles the request struct, in the future get request based on id parse_packet_server(packet, res.packet_len, res, p_state->current_server_request, p_state); - - //ssp_printf("Server received: %s\n", msg); - //packet_handler_server(res, p_state->current_server_request, p_state); return 0; } @@ -145,9 +141,9 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct soc res.sfd = sfd; res.packet_len = *buff_size; Client *client = p_state->newClient; - res.msg = client->outGoing_req->buff; - //fills the request struct - parse_packet_client(packet, res, client->outGoing_req, client, p_state); + res.msg = client->req->buff; + + parse_packet_client(packet, res, client->req, client, p_state); return 0; } @@ -165,7 +161,7 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { res.sfd = sfd; res.packet_len = client->packet_len; - user_request_handler(res, client->outGoing_req, client, p_state); + user_request_handler(res, client->req, client, p_state); return 0; #endif @@ -190,7 +186,7 @@ static int on_stdin(void *other) { /* Protocol_state *p_state = (Protocol_state *) other; - Request *req = p_state->newClient->outGoing_req; + Request *req = p_state->newClient->req; char input[MAX_PATH]; fgets(input, MAX_PATH, stdin); @@ -202,21 +198,21 @@ static int on_stdin(void *other) { ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); return 0; } - memcpy(p_state->newClient->outGoing_req->source_file_name, input, MAX_PATH); + memcpy(p_state->newClient->req->source_file_name, input, MAX_PATH); ssp_printf("Enter a destination file name:\n"); } else if (strnlen(req->destination_file_name, MAX_PATH) == 0){ - memcpy(p_state->newClient->outGoing_req->destination_file_name, input, MAX_PATH); - ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", p_state->newClient->outGoing_req->source_file_name, p_state->newClient->outGoing_req->destination_file_name, p_state->newClient->cfdp_id); + memcpy(p_state->newClient->req->destination_file_name, input, MAX_PATH); + ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, p_state->newClient->cfdp_id); ssp_printf("cancel connection mode (yes):\n"); } else if (strncmp(input, "yes", 3) == 0){ ssp_printf("sending file connectionless\n"); - put_request(p_state->newClient->outGoing_req->source_file_name, p_state->newClient->outGoing_req->destination_file_name, 0, 0, 0, 1, NULL, NULL, p_state->newClient, p_state); + put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 1, NULL, NULL, p_state->newClient, p_state); } else { ssp_printf("sending file connected\n"); - put_request(p_state->newClient->outGoing_req->source_file_name, p_state->newClient->outGoing_req->destination_file_name, 0, 0, 0, 0, NULL, NULL, p_state->newClient, p_state); + put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 0, NULL, NULL, p_state->newClient, p_state); } } */ @@ -254,6 +250,9 @@ Protocol_state* ssp_connectionless_server(char *port) { strncpy ((char*)state->server_port, port, 10); + + state->request_list = linked_list(); + int err = pthread_attr_init(attr); if (0 != err) perror("pthread_init failed"); @@ -276,6 +275,8 @@ Protocol_state* ssp_connectionless_server(char *port) { state->current_server_request = init_request(state->packet_size); state->server_handle = handler; state->server_thread_attributes = attr; + + return state; #endif @@ -307,7 +308,7 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { Client *client = calloc(sizeof(Client), 1); checkAlloc(client, 1); - client->outGoing_req = init_request(PACKET_LEN); + client->req = init_request(PACKET_LEN); pthread_t *handler = calloc(sizeof(pthread_t), 1); checkAlloc(handler, 1); @@ -420,6 +421,7 @@ void ssp_cleanup(Protocol_state *p_state) { pthread_t * handle = (pthread_t*) p_state->server_handle; pthread_join(*handle, NULL); + p_state->request_list->free( p_state->request_list, ssp_cleanup_req); ssp_cleanup_req(p_state->current_server_request); free_mib(p_state->mib); free(p_state->server_handle); @@ -440,7 +442,7 @@ void ssp_cleanup_client(Client *client) { pthread_join(*handle, NULL); #endif - ssp_cleanup_req(client->outGoing_req); + ssp_cleanup_req(client->req); free(client->client_handle); free(client->client_thread_attributes); ssp_cleanup_pdu_header(client->pdu_header); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e3f608f..ef3d039 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -12,6 +12,7 @@ //returns the location in the packet where the next pointer for tthe packet will start after the header static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { + memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); uint32_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -66,8 +67,7 @@ static uint8_t build_finished_packet(char *packet, uint32_t start, Request *req) static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { Pdu_header *header = (Pdu_header *) res.msg; - //set header to file directive 0 is directive, 1 is data - header->PDU_type = 0; + header->PDU_type = DIRECTIVE; uint8_t packet_index = start; //set directive 1 byte @@ -122,8 +122,7 @@ static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, } Pdu_header *header = (Pdu_header *) packet; - //set header to file directive 0 is directive, 1 is data - header->PDU_type = 1; + header->PDU_type = DATA; uint16_t packet_index = start; File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; @@ -212,8 +211,6 @@ static void build_eof_packet(Response res, uint32_t start, Request *req, Client* //4 bytes packet->file_size = ntohl(req->file->total_size); packet_index += 4; - - //TODO checksum procedures packet->checksum = req->file->partial_checksum; packet_index += 4; @@ -227,12 +224,13 @@ void print(void *element, void *args) { ssp_printf("start: %u, end: %u\n", o->start, o->end); } + +//this is a callback for building nak_array server side struct offset_holder { Offset *offsets; int i; }; -//this is a callback for building nak_array server side static void fill_nak_array(void *element, void *args){ struct offset_holder *holder = (struct offset_holder *)args; @@ -318,6 +316,7 @@ static int process_file_request_metadata(Request *req) { return 1; } +//sets destination id in request as the incomming source id, sets transaction number static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -347,10 +346,13 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state return -1; } + uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + + req->packet_data_len = packet_data_len; req->transmission_mode = header->transmission_mode; req->dest_cfdp_id = source_id; req->transaction_sequence_number = transaction_sequence_number; - + return packet_index; } @@ -359,6 +361,7 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil if(file == NULL) { ssp_error("file struct is null, can't write to file"); ssp_printf("dropped metadata packet :( we have no fix for this yet\n " ); + return; } File_data_pdu_contents *packet = (File_data_pdu_contents *)data_packet; @@ -513,8 +516,16 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { res.msg = req->buff; + if (req->buff == NULL) { + ssp_printf("req buffer is null, couldn't process timeout request\n"); + } + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); + if (req->file == NULL) { + ssp_printf("file is null, couldn't process timeout request\n"); + return; + } if (req->file->missing_offsets->count > 0) { build_nak_packet(res.msg, start, req); ssp_sendto(res); @@ -533,53 +544,27 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { //fills the current_request struct for the server, incomming requests void parse_packet_server(char *packet, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state) { - uint32_t packet_index_start = process_pdu_header(packet, req, p_state); - - - - uint8_t packet_index = PACKET_STATIC_HEADER_LEN; - Pdu_header *header = (Pdu_header *) packet; - - //most of this can be replaced with the process header func - uint32_t source_id = 0; - memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); - packet_index += header->length_of_entity_IDs; - - //TODO the transaction number should get the request from data structure hosting requests - uint32_t transaction_sequence_number = 0; - memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); - packet_index += header->transaction_seq_num_len; - - uint32_t dest_id = 0; - memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); - packet_index += header->length_of_entity_IDs; + uint32_t packet_index = process_pdu_header(packet, req, p_state); + if (packet_index == -1) + return; - uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + Pdu_header *header = (Pdu_header *) packet; if (p_state->verbose_level == 3) { ssp_printf("------------printing_header_received------------\n"); ssp_print_hex(packet, packet_index); - ssp_printf("packet data length %d, sequence number %d\n", packet_data_len, transaction_sequence_number); - } - - if (p_state->my_cfdp_id != dest_id){ - ssp_printf("someone is sending packets here that are not for me\n"); - return; + ssp_printf("packet data length %d, sequence number %d\n", req->packet_data_len, req->transaction_sequence_number); } - req->transmission_mode = header->transmission_mode; - req->dest_cfdp_id = source_id; - req->transaction_sequence_number = transaction_sequence_number; - //process file data if (header->PDU_type == 1) { - write_packet_data_to_file(&packet[packet_index], packet_data_len, req->file); + write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); return; } //set header for responding later if (req->pdu_header == NULL){ - req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); + req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); } Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; @@ -620,6 +605,11 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s return; res.msg = req->buff; + + if (res.msg == NULL) { + ssp_printf("req->buff is null, couldn't process user request\n"); + return; + } memset(res.msg, 0, client->packet_len); uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); @@ -663,11 +653,6 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s } - - - - - //Omission of source and destination filenames shall indicate that only Meta //data will be delivered int put_request(char *source_file_name, @@ -688,7 +673,7 @@ int put_request(char *source_file_name, return -1; //give the client a new request to perform - Request *req = client->outGoing_req; + Request *req = client->req; req->file = create_file(source_file_name, 0); //build a request diff --git a/Program/src/ringbuf.c b/Program/src/ringbuf.c new file mode 100644 index 0000000..b18ddb6 --- /dev/null +++ b/Program/src/ringbuf.c @@ -0,0 +1,347 @@ +/* + * ringbuf.c - C ring buffer (FIFO) implementation. + * + * Written in 2011 by Drew Hess . + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to + * the public domain worldwide. This software is distributed without + * any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#include "ringbuf.h" + +#include +#include +#include +#include +#include +#include +#include + +/* + * The code is written for clarity, not cleverness or performance, and + * contains many assert()s to enforce invariant assumptions and catch + * bugs. Feel free to optimize the code and to remove asserts for use + * in your own projects, once you're comfortable that it functions as + * intended. + */ + +struct ringbuf_t +{ + uint8_t *buf; + uint8_t *head, *tail; + size_t size; +}; + +ringbuf_t +ringbuf_new(size_t capacity) +{ + ringbuf_t rb = malloc(sizeof(struct ringbuf_t)); + if (rb) { + + /* One byte is used for detecting the full condition. */ + rb->size = capacity + 1; + rb->buf = malloc(rb->size); + if (rb->buf) + ringbuf_reset(rb); + else { + free(rb); + return 0; + } + } + return rb; +} + +size_t +ringbuf_buffer_size(const struct ringbuf_t *rb) +{ + return rb->size; +} + +void +ringbuf_reset(ringbuf_t rb) +{ + rb->head = rb->tail = rb->buf; +} + +void +ringbuf_free(ringbuf_t *rb) +{ + assert(rb && *rb); + free((*rb)->buf); + free(*rb); + *rb = 0; +} + +size_t +ringbuf_capacity(const struct ringbuf_t *rb) +{ + return ringbuf_buffer_size(rb) - 1; +} + +/* + * Return a pointer to one-past-the-end of the ring buffer's + * contiguous buffer. You shouldn't normally need to use this function + * unless you're writing a new ringbuf_* function. + */ +static const uint8_t * +ringbuf_end(const struct ringbuf_t *rb) +{ + return rb->buf + ringbuf_buffer_size(rb); +} + +size_t +ringbuf_bytes_free(const struct ringbuf_t *rb) +{ + if (rb->head >= rb->tail) + return ringbuf_capacity(rb) - (rb->head - rb->tail); + else + return rb->tail - rb->head - 1; +} + +size_t +ringbuf_bytes_used(const struct ringbuf_t *rb) +{ + return ringbuf_capacity(rb) - ringbuf_bytes_free(rb); +} + +int +ringbuf_is_full(const struct ringbuf_t *rb) +{ + return ringbuf_bytes_free(rb) == 0; +} + +int +ringbuf_is_empty(const struct ringbuf_t *rb) +{ + return ringbuf_bytes_free(rb) == ringbuf_capacity(rb); +} + +const void * +ringbuf_tail(const struct ringbuf_t *rb) +{ + return rb->tail; +} + +const void * +ringbuf_head(const struct ringbuf_t *rb) +{ + return rb->head; +} + +/* + * Given a ring buffer rb and a pointer to a location within its + * contiguous buffer, return the a pointer to the next logical + * location in the ring buffer. + */ +static uint8_t * +ringbuf_nextp(ringbuf_t rb, const uint8_t *p) +{ + /* + * The assert guarantees the expression (++p - rb->buf) is + * non-negative; therefore, the modulus operation is safe and + * portable. + */ + assert((p >= rb->buf) && (p < ringbuf_end(rb))); + return rb->buf + ((++p - rb->buf) % ringbuf_buffer_size(rb)); +} + +size_t +ringbuf_findchr(const struct ringbuf_t *rb, int c, size_t offset) +{ + const uint8_t *bufend = ringbuf_end(rb); + size_t bytes_used = ringbuf_bytes_used(rb); + if (offset >= bytes_used) + return bytes_used; + + const uint8_t *start = rb->buf + + (((rb->tail - rb->buf) + offset) % ringbuf_buffer_size(rb)); + assert(bufend > start); + size_t n = MIN(bufend - start, bytes_used - offset); + const uint8_t *found = memchr(start, c, n); + if (found) + return offset + (found - start); + else + return ringbuf_findchr(rb, c, offset + n); +} + +size_t +ringbuf_memset(ringbuf_t dst, int c, size_t len) +{ + const uint8_t *bufend = ringbuf_end(dst); + size_t nwritten = 0; + size_t count = MIN(len, ringbuf_buffer_size(dst)); + int overflow = count > ringbuf_bytes_free(dst); + + while (nwritten != count) { + + /* don't copy beyond the end of the buffer */ + assert(bufend > dst->head); + size_t n = MIN(bufend - dst->head, count - nwritten); + memset(dst->head, c, n); + dst->head += n; + nwritten += n; + + /* wrap? */ + if (dst->head == bufend) + dst->head = dst->buf; + } + + if (overflow) { + dst->tail = ringbuf_nextp(dst, dst->head); + assert(ringbuf_is_full(dst)); + } + + return nwritten; +} + +void * +ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count) +{ + const uint8_t *u8src = src; + const uint8_t *bufend = ringbuf_end(dst); + int overflow = count > ringbuf_bytes_free(dst); + size_t nread = 0; + + while (nread != count) { + /* don't copy beyond the end of the buffer */ + assert(bufend > dst->head); + size_t n = MIN(bufend - dst->head, count - nread); + memcpy(dst->head, u8src + nread, n); + dst->head += n; + nread += n; + + /* wrap? */ + if (dst->head == bufend) + dst->head = dst->buf; + } + + if (overflow) { + dst->tail = ringbuf_nextp(dst, dst->head); + assert(ringbuf_is_full(dst)); + } + + return dst->head; +} + +ssize_t +ringbuf_read(int fd, ringbuf_t rb, size_t count) +{ + const uint8_t *bufend = ringbuf_end(rb); + size_t nfree = ringbuf_bytes_free(rb); + + /* don't write beyond the end of the buffer */ + assert(bufend > rb->head); + count = MIN(bufend - rb->head, count); + ssize_t n = read(fd, rb->head, count); + if (n > 0) { + assert(rb->head + n <= bufend); + rb->head += n; + + /* wrap? */ + if (rb->head == bufend) + rb->head = rb->buf; + + /* fix up the tail pointer if an overflow occurred */ + if (n > nfree) { + rb->tail = ringbuf_nextp(rb, rb->head); + assert(ringbuf_is_full(rb)); + } + } + + return n; +} + +void * +ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count) +{ + size_t bytes_used = ringbuf_bytes_used(src); + if (count > bytes_used) + return 0; + + uint8_t *u8dst = dst; + const uint8_t *bufend = ringbuf_end(src); + size_t nwritten = 0; + while (nwritten != count) { + assert(bufend > src->tail); + size_t n = MIN(bufend - src->tail, count - nwritten); + memcpy(u8dst + nwritten, src->tail, n); + src->tail += n; + nwritten += n; + + /* wrap ? */ + if (src->tail == bufend) + src->tail = src->buf; + } + + assert(count + ringbuf_bytes_used(src) == bytes_used); + return src->tail; +} + +ssize_t +ringbuf_write(int fd, ringbuf_t rb, size_t count) +{ + size_t bytes_used = ringbuf_bytes_used(rb); + if (count > bytes_used) + return 0; + + const uint8_t *bufend = ringbuf_end(rb); + assert(bufend > rb->head); + count = MIN(bufend - rb->tail, count); + ssize_t n = write(fd, rb->tail, count); + if (n > 0) { + assert(rb->tail + n <= bufend); + rb->tail += n; + + /* wrap? */ + if (rb->tail == bufend) + rb->tail = rb->buf; + + assert(n + ringbuf_bytes_used(rb) == bytes_used); + } + + return n; +} + +void * +ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count) +{ + size_t src_bytes_used = ringbuf_bytes_used(src); + if (count > src_bytes_used) + return 0; + int overflow = count > ringbuf_bytes_free(dst); + + const uint8_t *src_bufend = ringbuf_end(src); + const uint8_t *dst_bufend = ringbuf_end(dst); + size_t ncopied = 0; + while (ncopied != count) { + assert(src_bufend > src->tail); + size_t nsrc = MIN(src_bufend - src->tail, count - ncopied); + assert(dst_bufend > dst->head); + size_t n = MIN(dst_bufend - dst->head, nsrc); + memcpy(dst->head, src->tail, n); + src->tail += n; + dst->head += n; + ncopied += n; + + /* wrap ? */ + if (src->tail == src_bufend) + src->tail = src->buf; + if (dst->head == dst_bufend) + dst->head = dst->buf; + } + + assert(count + ringbuf_bytes_used(src) == src_bytes_used); + + if (overflow) { + dst->tail = ringbuf_nextp(dst, dst->head); + assert(ringbuf_is_full(dst)); + } + + return dst->head; +} From c026f7271f35e32898b7ebe15e7f4ec7a69792fc Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 15 Apr 2019 14:45:05 -0600 Subject: [PATCH 039/400] move more stuff to parse header function --- Program/src/protocol_handler.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index ef3d039..7c1e960 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -550,12 +550,6 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques Pdu_header *header = (Pdu_header *) packet; - if (p_state->verbose_level == 3) { - ssp_printf("------------printing_header_received------------\n"); - ssp_print_hex(packet, packet_index); - ssp_printf("packet data length %d, sequence number %d\n", req->packet_data_len, req->transaction_sequence_number); - } - //process file data if (header->PDU_type == 1) { write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); From f5e3b2c617e473f61322fb32bd9c2ba379cf96f6 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 30 Apr 2019 13:20:01 -0600 Subject: [PATCH 040/400] Add tests for EOF_pdu, and fix bug in EOF response --- Program/include/packet.h | 31 +++++- Program/include/protocol_handler.h | 4 + Program/src/makefile | 4 + Program/src/protocol_handler.c | 163 ++++++++++++++++------------- Program/test/main.c | 79 ++++++++++++-- Program/test/makefile | 6 +- Program/test/packet_tests.c | 69 ++++++++++++ Program/test/packet_tests.h | 19 ++++ Program/test/test.c | 75 +++++++++++++ Program/test/test.h | 11 ++ 10 files changed, 377 insertions(+), 84 deletions(-) create mode 100644 Program/test/packet_tests.c create mode 100644 Program/test/packet_tests.h create mode 100644 Program/test/test.c create mode 100644 Program/test/test.h diff --git a/Program/include/packet.h b/Program/include/packet.h index f3ae6a5..0a37948 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -281,11 +281,11 @@ typedef struct pdu_eof { } Pdu_eof; -/* + /* start_scope is the begining of the nak requests end_scope is the end segments are -*/ + */ typedef struct pdu_nak { unsigned int start_scope : 32; uint32_t end_scope; @@ -296,6 +296,33 @@ typedef struct pdu_nak { } Pdu_nak; +#define ACK_FINISHED_WAYPOINT 0 +#define ACK_FINISHED_END 1 +#define ACK_OTHER 0 + +typedef struct pdu_ack { + //Directive code of the acknowledged PDU. + unsigned int directive_code : 4; + + /* + Values depend on directive code. For ACK of Finished PDU: binary ‘0000’ + if Finished PDU is generated by waypoint, binary ‘0001’ if Finished + PDU is generated by end system. (NOTE: this discrimination is + meaningful if the Extended Procedures are implemented.) + Binary ‘0000’ for ACKs of all other file directives. + */ + + unsigned int directive_subtype_code : 4; + + //Condition code of the acknowledged PDU. + unsigned int condition_code : 4; + unsigned int spare : 2; + + //Status of the transaction in the context of the entity that is issuing the acknowledgment. + unsigned int transaction_status : 2; + +} Pdu_ack; + //file_status codes diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 6d8630c..58622bb 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -1,6 +1,7 @@ #ifndef PROTOCOL_H #define PROTOCOL_H + #include "utils.h" #include "packet.h" #include "mib.h" @@ -114,6 +115,9 @@ void user_request_handler(Response res, Request *req, Client *client, Protocol_s void parse_packet_client(char* buff, Response res, Request *req, Client *client, Protocol_state *p_state); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); +uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); +uint8_t build_ack_eof_pdu (char *packet, uint32_t start, Request *req); + /* unsigned char *source_file_name, unsigned char *destination_file_name, diff --git a/Program/src/makefile b/Program/src/makefile index e69ee1e..498d3ff 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -13,6 +13,10 @@ CFILES += mib.c CFILES += filesystem_funcs.c CFILES += ringbuf.c +#----------------------------test files------------------------- +CFILES += $(PROJDIR)/test/test.c +INCLUDE += -I$(PROJDIR)/test + #entrypoint MAIN = main diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 7c1e960..f7aa7d9 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -5,13 +5,8 @@ #include "string.h" #include "packet.h" -//for progress bar -#include "unistd.h" -#include "stdio.h" -#include "stddef.h" - //returns the location in the packet where the next pointer for tthe packet will start after the header -static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { +uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); uint32_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -44,13 +39,12 @@ static uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_numb return total_bytes; } -static uint8_t build_finished_packet(char *packet, uint32_t start, Request *req) { +static uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { uint32_t packet_index = start; uint32_t data_len = 0; - Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; - directive->directive_code = FINISHED_PDU; + packet[packet_index] = FINISHED_PDU; packet_index++; Pdu_finished *pdu_finished = (Pdu_finished *) &packet[packet_index]; @@ -115,7 +109,7 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * return packet_index; } -static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client, Protocol_state *p_state) { +static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { if (offset > req->file->total_size) { return -1; @@ -264,6 +258,19 @@ void build_nak_packet(char *packet, uint32_t start, Request *req) { ssp_free(holder.offsets); } +//returns number of bytes added, (the data field length) returns length +uint8_t build_ack_eof_pdu (char *packet, uint32_t start, Request *req) { + + packet[start] = ACK_PDU; + uint32_t packet_index = start + 1; + Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; + pdu_ack->directive_code = EOF_PDU; + pdu_ack->directive_subtype_code = ACK_FINISHED_END; + pdu_ack->condition_code = COND_NO_ERROR; + packet_index += 2; + return packet_index - start; +} + static void process_pdu_eof(char *packet, Request *req) { Pdu_eof *eof_packet = (Pdu_eof *) packet; @@ -272,19 +279,17 @@ static void process_pdu_eof(char *packet, Request *req) { uint32_t file_size = ntohl(eof_packet->file_size); ssp_printf("received eof packet, filesize: %u\n", file_size); - - req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); + req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); req->file->eof_checksum = eof_packet->checksum; - - + //if transmission mode unacknowledged, close file - if (req->transmission_mode == 0) + if (req->transmission_mode == 0) { return; - + } + if (ssp_close(req->file->fd) == -1) ssp_error("could not close file\n"); - } } @@ -410,52 +415,31 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi return; } +uint8_t ack_response(char *packet, uint32_t packet_index, Request *req, Response res, Client *client){ -/*------------------------------------------------------------------------------ - - REMOTE SIDE - aka: handles responses from server - -------------------------------------------------------------------------------*/ - - -//taken from https://gist.github.com/amullins83/24b5ef48657c08c4005a8fab837b7499 + Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; + ssp_printf("received ack!\n"); + if (pdu_ack->directive_code == EOF_PDU) { + ssp_printf("received eof ack!\n"); -void print_progress(size_t count, size_t max) -{ - const char prefix[] = "Progress: ["; - const char suffix[] = "]"; - const size_t prefix_length = sizeof(prefix) - 1; - const size_t suffix_length = sizeof(suffix) - 1; - char *buffer = ssp_alloc(max + prefix_length + suffix_length + 1, 1); // +1 for \0 - size_t i = 0; + } + else if (pdu_ack->directive_code == FINISHED_PDU) { + ssp_printf("received finished ack\n"); - strcpy(buffer, prefix); - for (; i < max; ++i) - { - buffer[prefix_length + i] = i < count ? '#' : ' '; - } + } - strcpy(&buffer[prefix_length + i], suffix); - printf("\b%c[2K\r%s\n", 27, buffer); - fflush(stdout); - ssp_free(buffer); } +/*------------------------------------------------------------------------------ -//fills the current request with packet data, responses from servers -void parse_packet_client(char *packet, Response res, Request *req, Client* client, Protocol_state *p_state) { - - - uint32_t packet_index = process_pdu_header(packet, req, p_state); - if (packet_index == -1) - return; + REMOTE SIDE + aka: handles responses from server + +------------------------------------------------------------------------------*/ - Pdu_header *header = (Pdu_header *) packet; - uint16_t packet_data_len = ntohs(header->PDU_data_field_len); - if (packet[packet_index] == NAK_PDU){ - packet_index += 1; +static int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { + uint32_t packet_index = start; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; uint32_t offset_first = ntohl(nak->start_scope); uint32_t offset_last = ntohl(nak->end_scope); @@ -470,11 +454,9 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien } uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, client->pdu_header); - uint32_t offset_start = 0; uint32_t offset_end = 0; - printf("number of segments to resend: %u\n", segments); for (int i = 0; i < segments; i++){ //outgoing_packet_index @@ -488,20 +470,46 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien printf("offset sending first %u last %u\n", offset_start, offset_end); printf("first %u and end %u\n", offset_first, offset_last); - build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client, p_state); - + build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); ssp_sendto(res); - //send another EOF - req->type = eof; } + + return packet_index; - } else if (packet[packet_index] == FINISHED_PDU) { +} - if (req->type != finished) { - //print_progress(req->file_size/1000, req->file_size/1000); - ssp_printf("file successfully sent\n"); - } - req->type = finished; + +//fills the current request with packet data, responses from servers +void parse_packet_client(char *packet, Response res, Request *req, Client* client, Protocol_state *p_state) { + + + uint32_t packet_index = process_pdu_header(packet, req, p_state); + if (packet_index == -1) + return; + + Pdu_header *header = (Pdu_header *) packet; + uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + uint8_t directive = packet[packet_index]; + packet_index += 1; + + switch(directive) { + case FINISHED_PDU: + if (req->type != finished) { + //print_progress(req->file_size/1000, req->file_size/1000); + ssp_printf("file successfully received\n"); + } + req->type = finished; + break; + case NAK_PDU: + nak_response(packet, packet_index, req, res, client); + req->type = eof; + break; + case ACK_PDU: + ack_response(packet, packet_index, req, res, client); + + break; + default: + break; } } @@ -521,24 +529,33 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { } uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); - + uint16_t data_len = 0; + Pdu_header *pdu_header = (Pdu_header *) &res.msg; + if (req->file == NULL) { ssp_printf("file is null, couldn't process timeout request\n"); return; } + if (req->file->missing_offsets->count > 0) { build_nak_packet(res.msg, start, req); ssp_sendto(res); return; } - + + //received EOF + if (req->file->eof_checksum) { + data_len = build_ack_eof_pdu(res.msg, start, req); + ssp_sendto(res); + return; + } + + //received Finished if (req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { - Pdu_header *header = (Pdu_header *) res.msg; - uint32_t dest_id = 0; - memcpy(&dest_id, &header->destination_id, header->length_of_entity_IDs); - build_finished_packet(res.msg, start, req); + data_len = build_finished_pdu(res.msg, start, req); ssp_sendto(res); - } + return; + } } //fills the current_request struct for the server, incomming requests diff --git a/Program/test/main.c b/Program/test/main.c index 93ce4f9..1fa74ab 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -11,6 +11,9 @@ #include #include "filesystem_funcs.h" #include "port.h" +#include "test.h" +#include "mib.h" +#include "packet_tests.h" struct myStruct { int id; @@ -54,8 +57,75 @@ static void list_free(void *element) { int main () { + + MIB *mib = init_mib(); + + //setting host name for testing + char *host_name = "127.0.0.1"; + uint32_t addr[sizeof(uint32_t)]; + inet_pton(AF_INET, host_name, addr); + //adding new cfdp entities to management information base + add_new_cfdp_entity(mib, 1315, *addr, 1111); + add_new_cfdp_entity(mib, 2222, *addr, 1112); + + //find server client in mib + Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, 1, NULL, NULL); + if (server_entity == NULL) { + printf("couldn't find entity\n"); + } + + + Pdu_header *header = get_header_from_mib(mib, 2222, 1315); + + packet_tests(header); + + free_mib(mib); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /*test sequence of files File *file = create_file("test.txt"); ssp_printf("file size: %u\n", file->total_size); @@ -63,7 +133,6 @@ int main () { uint32_t data_start = 0; uint32_t data_end = data_size; - /*test sequence of files for (int i=0; i < file->total_size; i+= data_size) { data_start = i; data_end = data_size + i; @@ -72,11 +141,7 @@ int main () { } receive_offset(file, 0, 48516, 48833); - */ - - - - + /* //doesnt do this edge case because, would never request it? @@ -84,8 +149,6 @@ int main () { free_file(file); - - /* char *packet = "hello world"; uint32_t checksum = calc_check_sum(packet, 10); printf("%d\n", checksum); diff --git a/Program/test/makefile b/Program/test/makefile index 5e8dea5..7ba8469 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -1,6 +1,8 @@ PROJDIR = $(CURDIR)/.. INCLUDE += -I$(PROJDIR)/include +INCLUDE += -I$(PROJDIR)/test + CC = gcc #---------------------------File Names--------------------------- @@ -11,6 +13,8 @@ CFILES += $(PROJDIR)/src/server.c CFILES += $(PROJDIR)/src/protocol_handler.c CFILES += $(PROJDIR)/src/list_callbacks.c CFILES += $(PROJDIR)/src/mib.c +CFILES += $(PROJDIR)/test/packet_tests.c +CFILES += $(PROJDIR)/test/test.c #entrypoint MAIN = main @@ -38,7 +42,7 @@ CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = -LIBS = +LIBS = -pthread #---------------------------Compiler flags--------------------------- diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c new file mode 100644 index 0000000..8468d88 --- /dev/null +++ b/Program/test/packet_tests.c @@ -0,0 +1,69 @@ + + +#include "protocol_handler.h" +#include "test.h" +#include "utils.h" +#include + + +int test_build_ack_eof_pdu(char *packet, uint32_t start) { + //empty request + printf("testing eof ack creation\n"); + + Request *req; + uint8_t len = build_ack_eof_pdu (packet, start, req); + + Pdu_directive *pdu_d = &packet[start]; + ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); + + Pdu_ack *ack = (Pdu_ack *)&packet[start + 1]; + ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack->directive_code); + ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack->condition_code); + ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack->directive_subtype_code, ACK_FINISHED_END); +} + +int test_build_pdu_header_header(char *packet, Pdu_header *header, uint64_t sequence_number) { + + + printf("testing header creation\n"); + uint8_t length = build_pdu_header(packet, sequence_number, 0, header); + uint32_t packet_index = PACKET_STATIC_HEADER_LEN; + + ASSERT_EQUALS_INT("packet length: ", length, 9); + ASSERT_EQUALS_STR("packet source id ", &packet[packet_index], header->source_id, header->length_of_entity_IDs); + packet_index += header->length_of_entity_IDs; + + ASSERT_NOT_EQUALS_INT("transaction_sequence_number correctly placed ", &packet[packet_index], sequence_number); + packet_index += header->transaction_seq_num_len; + + ASSERT_NOT_EQUALS_STR("packet destination not equal to source id ", &packet[packet_index], header->source_id, header->length_of_entity_IDs); + ASSERT_EQUALS_STR("packet destination id ", &packet[packet_index], header->destination_id, header->length_of_entity_IDs); + + packet_index += header->length_of_entity_IDs; + Pdu_header *new_header = packet; + + ASSERT_EQUALS_INT("CRC = CRC", header->CRC_flag, new_header->CRC_flag); + ASSERT_EQUALS_INT("direction = direction", header->direction, new_header->direction); + ASSERT_EQUALS_INT("length_of_entity_IDs = length_of_entity_IDs ", header->length_of_entity_IDs, new_header->length_of_entity_IDs); + ASSERT_EQUALS_INT("PDU data_field_len = PDU_data_field_len ", header->PDU_data_field_len, new_header->PDU_data_field_len); + ASSERT_EQUALS_INT("PDU_type = PDU_type", header->PDU_type, new_header->PDU_type); + ASSERT_EQUALS_INT("reserved_bit_0 = reserved_bit_0 ", header->reserved_bit_0, new_header->reserved_bit_0); + ASSERT_EQUALS_INT("reserved_bit_1 = reserved_bit_1 ", header->reserved_bit_1, new_header->reserved_bit_1); + ASSERT_EQUALS_INT("reserved_bit_2 = reserved_bit_2 ", header->reserved_bit_2, new_header->reserved_bit_2); + ASSERT_EQUALS_INT("version = version", header->version, new_header->version); + ASSERT_EQUALS_INT("transaction_seq_num_len = transaction_seq_num_len ", header->transaction_seq_num_len, new_header->transaction_seq_num_len); + ASSERT_EQUALS_INT("transmission_mode = transmission_mode ", 0, new_header->transmission_mode); + ASSERT_EQUALS_INT("total header length equal ", packet_index, length); + + return packet_index; +} + +int packet_tests(Pdu_header *header) { + + printf("starting Packet Tests (creating and changing packet values)\n"); + char *packet = calloc(2000, sizeof(char)); + uint64_t sequence_number = 12345663234; + int packet_index = test_build_pdu_header_header(packet, header, sequence_number); + test_build_ack_eof_pdu(packet, packet_index); + +} \ No newline at end of file diff --git a/Program/test/packet_tests.h b/Program/test/packet_tests.h new file mode 100644 index 0000000..3e64ff2 --- /dev/null +++ b/Program/test/packet_tests.h @@ -0,0 +1,19 @@ + +#ifndef PACKET_TEST_H +#define PACKET_TEST_H + + +#include "protocol_handler.h" + + + + + + +int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); +int packet_tests(Pdu_header *header); + + + + +#endif \ No newline at end of file diff --git a/Program/test/test.c b/Program/test/test.c new file mode 100644 index 0000000..102495b --- /dev/null +++ b/Program/test/test.c @@ -0,0 +1,75 @@ + +#include "test.h" + +#include "utils.h" +#include + +int test_num = 0; + +void ASSERT_EQUALS_INT(char* description, int val1, int val2) { + + test_num++; + if (val1 == val2){ + printf("\033[0;32m"); + printf("%s", description); + printf("pass # %d\n", test_num); + } + else { + printf("\033[0;31m"); + printf("%s", description); + printf("fail # %d\n", test_num); + } + printf("\033[0m"); +} + + +void ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { + + test_num++; + if (val1 == val2){ + printf("\033[0;31m"); + printf("%s", description); + printf("fail # %d\n", test_num); + } + else { + printf("\033[0;32m"); + printf("%s", description); + printf("pass # %d\n", test_num); + } + printf("\033[0m"); +} + + +void ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { + + test_num++; + if (!memcmp(val1, val2, size)) { + printf("\033[0;32m"); + printf("%s", description); + printf("pass # %d\n", test_num); + + } else { + printf("\033[0;31m"); + printf("%s", description); + printf("fail # %d\n", test_num); + + } + printf("\033[0m"); +} + +void ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { + + test_num++; + if (!memcmp(val1, val2, size)) { + + printf("\033[0;31m"); + printf("%s", description); + printf("fail # %d\n", test_num); + + } else { + printf("\033[0;32m"); + printf("%s", description); + printf("pass # %d\n", test_num); + } + printf("\033[0m"); +} diff --git a/Program/test/test.h b/Program/test/test.h new file mode 100644 index 0000000..80cc065 --- /dev/null +++ b/Program/test/test.h @@ -0,0 +1,11 @@ + +#ifndef PACKET_TEST_H +#define PACKET_TEST_H +#include + +void ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size); +void ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2); +void ASSERT_EQUALS_INT(char* description, int val1, int val2); +void ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) ; + +#endif \ No newline at end of file From 393116adc7e3e0ef43e3f7d7468d055967ebf8be Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 2 May 2019 11:36:48 -0600 Subject: [PATCH 041/400] Add tests for finished pdu, directive for lost metadata --- Program/include/changeNotes | 1 + Program/include/packet.h | 5 ++ Program/include/protocol_handler.h | 5 +- Program/src/protocol_handler.c | 73 +++++++++++++++--------------- Program/src/server.c | 1 - Program/test/packet_tests.c | 16 +++++++ 6 files changed, 62 insertions(+), 39 deletions(-) create mode 100644 Program/include/changeNotes diff --git a/Program/include/changeNotes b/Program/include/changeNotes new file mode 100644 index 0000000..d5350b9 --- /dev/null +++ b/Program/include/changeNotes @@ -0,0 +1 @@ +added PDU_NAK_METADATA directive, due to spec not containing room for missing metadata packet \ No newline at end of file diff --git a/Program/include/packet.h b/Program/include/packet.h index 0a37948..f68ecd1 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -194,6 +194,7 @@ typedef struct filestore_response { #define PROMPT_PDU 0x09 #define KEEP_ALIVE_PDU 0x0C #define SIZE_OF_DIRECTIVE_CODE 1 +#define NAK_METADATA 0x0d //condition codes: @@ -280,6 +281,10 @@ typedef struct pdu_eof { } Pdu_eof; + //currently, empty, only need the directive code +typedef struct pdu_nak_metadata{ + +} Pdu_nak_metadata /* start_scope is the begining of the nak requests diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 58622bb..4397e55 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -48,8 +48,9 @@ typedef struct request { uint8_t flow_lable; uint8_t transmission_mode; - - + uint8_t received_metadata; + uint8_t received_eof; + uint8_t received_finished; char* messages_to_user; char* filestore_requests; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index f7aa7d9..2dbd705 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -44,16 +44,19 @@ static uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { uint32_t packet_index = start; uint32_t data_len = 0; - packet[packet_index] = FINISHED_PDU; + Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; + directive->directive_code = FINISHED_PDU; packet_index++; + data_len++; + //one byte Pdu_finished *pdu_finished = (Pdu_finished *) &packet[packet_index]; pdu_finished->condition_code = COND_NO_ERROR; pdu_finished->delivery_code = 0; pdu_finished->file_status = FILE_RETAINED_SUCCESSFULLY; - - data_len = 8; - packet_index += 8; + data_len += 1; + packet_index += 1; + return data_len; } @@ -258,13 +261,11 @@ void build_nak_packet(char *packet, uint32_t start, Request *req) { ssp_free(holder.offsets); } -//returns number of bytes added, (the data field length) returns length -uint8_t build_ack_eof_pdu (char *packet, uint32_t start, Request *req) { - +uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { packet[start] = ACK_PDU; uint32_t packet_index = start + 1; Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; - pdu_ack->directive_code = EOF_PDU; + pdu_ack->directive_code = type; pdu_ack->directive_subtype_code = ACK_FINISHED_END; pdu_ack->condition_code = COND_NO_ERROR; packet_index += 2; @@ -340,12 +341,6 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; - if (p_state->verbose_level == 3) { - ssp_printf("------------printing_header_received------------\n"); - ssp_print_hex(packet, packet_index); - ssp_printf("packet data length %d, sequence number %d\n", transaction_sequence_number); - } - if (p_state->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", p_state->my_cfdp_id, dest_id); return -1; @@ -415,21 +410,23 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi return; } -uint8_t ack_response(char *packet, uint32_t packet_index, Request *req, Response res, Client *client){ +uint8_t ack_response(char *packet, uint32_t packet_index, Request *req){ Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; ssp_printf("received ack!\n"); if (pdu_ack->directive_code == EOF_PDU) { - ssp_printf("received eof ack!\n"); + + ssp_printf("received eof ack!\n"); } else if (pdu_ack->directive_code == FINISHED_PDU) { + req->type = finished; ssp_printf("received finished ack\n"); } - } + /*------------------------------------------------------------------------------ REMOTE SIDE @@ -495,8 +492,7 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien switch(directive) { case FINISHED_PDU: if (req->type != finished) { - //print_progress(req->file_size/1000, req->file_size/1000); - ssp_printf("file successfully received\n"); + ssp_printf("file successfully sent\n"); } req->type = finished; break; @@ -505,9 +501,10 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien req->type = eof; break; case ACK_PDU: - ack_response(packet, packet_index, req, res, client); - + ack_response(packet, packet_index, req); break; + + default: break; } @@ -524,6 +521,10 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { res.msg = req->buff; + + if (req->type == finished) + return; + if (req->buff == NULL) { ssp_printf("req buffer is null, couldn't process timeout request\n"); } @@ -537,6 +538,7 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { return; } + //send missing NAKS if (req->file->missing_offsets->count > 0) { build_nak_packet(res.msg, start, req); ssp_sendto(res); @@ -545,17 +547,17 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { //received EOF if (req->file->eof_checksum) { - data_len = build_ack_eof_pdu(res.msg, start, req); + data_len = build_ack(res.msg, start, EOF_PDU, req); ssp_sendto(res); - return; } - //received Finished + //send Finished if (req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { data_len = build_finished_pdu(res.msg, start, req); ssp_sendto(res); - return; } + + } //fills the current_request struct for the server, incomming requests @@ -591,6 +593,10 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques case EOF_PDU: process_pdu_eof(&packet[packet_index], req); break; + + case ACK_PDU: + ack_response(packet, packet_index, req); + default: break; } @@ -624,6 +630,7 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s memset(res.msg, 0, client->packet_len); uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + uint32_t data_len = 0; switch (req->type) { @@ -636,26 +643,20 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s case sending_data: if (build_data_packet(res, start, req, client, p_state)) req->type = eof; - - if (p_state->verbose_level == 3) { - ssp_printf("------------sending_a_data_packets-----------\n"); - ssp_print_hex(res.msg, start); - } ssp_sendto(res); break; case put: start = build_put_packet_metadata(res, start, req, client, p_state); - - if (p_state->verbose_level == 3) { - ssp_printf("------------sending_a_put_request------------\n"); - ssp_print_hex(res.msg, start); - } - ssp_sendto(res); req->type = sending_data; break; + case finished: + data_len = build_ack(res.msg, start, FINISHED_PDU, req); + ssp_sendto(res); + req->type = none; + break; default: break; diff --git a/Program/src/server.c b/Program/src/server.c index 0ac0a5a..dabbd86 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -292,7 +292,6 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo printf("packet too large, cannot resize buffer\n"); } - /* print the server's reply */ if (onSend(sfd, serveraddr, onSendParams)) printf("send failed\n"); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 8468d88..dce7969 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -5,6 +5,22 @@ #include "utils.h" #include +int test_build_ack_finished_pdu(char *packet, uint32_t start) { + printf("testing finished ack creation\n"); + Request *req; + uint8_t len = test_build_ack_finished_pdu (packet, start, req); + + Pdu_directive *pdu_d = &packet[start]; + ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); + + Pdu_ack *ack = (Pdu_ack *)&packet[start + 1]; + ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack->directive_code); + ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack->condition_code); + ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack->directive_subtype_code, ACK_FINISHED_END); + + + +} int test_build_ack_eof_pdu(char *packet, uint32_t start) { //empty request From 9f406fb6065e0b4f4e1d6703da66e6c9b009f749 Mon Sep 17 00:00:00 2001 From: Evan G Date: Thu, 2 May 2019 15:33:56 -0600 Subject: [PATCH 042/400] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d9184c4..1fc7ca2 100644 --- a/README.md +++ b/README.md @@ -1 +1,8 @@ -# CMPT496_SpaceNetworking \ No newline at end of file +This is not finished! - currently working on it! + +This is a FTP protocol that adheres to the CCSDS (Consultative Committee for Space Data Systems) spec for sending files into space. This project is being built for a student lead space initiative at the Univerity of Alberta called ABsat. + +I want to eventually make it opensource, but there is a lot of work to do before it is in any condition for use. + +if you want to get in contact with me +email me at evangiese77@gmail.com From f67e27a748fdd7bba83511f69558979b8d01a956 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 10 May 2019 11:50:44 -0600 Subject: [PATCH 043/400] Fix createtempfile --- Program/include/filesystem_funcs.h | 3 + Program/include/packet.h | 2 +- Program/src/filesystem_funcs.c | 10 + Program/src/protocol_handler.c | 283 +++++++++++++++++------------ 4 files changed, 183 insertions(+), 115 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 674af36..f340323 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -4,6 +4,8 @@ #include #include "utils.h" +#define TEMP_FILESIZE 20000 + typedef struct offset { uint32_t start; uint32_t end; @@ -31,4 +33,5 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); uint32_t calc_check_sum(char *data, uint32_t length); uint32_t check_sum_file(File *file, uint16_t stack_buffer); void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end); +File *create_temp_file(uint64_t transaction_sequence_num); #endif diff --git a/Program/include/packet.h b/Program/include/packet.h index f68ecd1..d669424 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -284,7 +284,7 @@ typedef struct pdu_eof { //currently, empty, only need the directive code typedef struct pdu_nak_metadata{ -} Pdu_nak_metadata +} Pdu_nak_metadata; /* start_scope is the begining of the nak requests diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 8d0b94e..f06f283 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -252,3 +252,13 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off } } + +File *create_temp_file(uint64_t transaction_sequence_num) { + + char temp[75]; + snprintf(temp, 75, "%s%llu", "temp_", transaction_sequence_num); + File *file = create_file(temp, 1); + file->total_size = TEMP_FILESIZE; + +} + diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2dbd705..c9586e2 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -4,8 +4,15 @@ #include "protocol_handler.h" #include "string.h" #include "packet.h" +#include "filesystem_funcs.h" +/*------------------------------------------------------------------------------ + + creating packets + +------------------------------------------------------------------------------*/ //returns the location in the packet where the next pointer for tthe packet will start after the header + uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); @@ -271,34 +278,66 @@ uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { packet_index += 2; return packet_index - start; } +uint8_t build_nak_metadata(char *packet, uint32_t start, Request *req) { + uint8_t data_len = 1; + packet[start] = NAK_METADATA; + return data_len; +} -static void process_pdu_eof(char *packet, Request *req) { - Pdu_eof *eof_packet = (Pdu_eof *) packet; - if (eof_packet->checksum == req->file->partial_checksum) { - uint32_t file_size = ntohl(eof_packet->file_size); +/*------------------------------------------------------------------------------ - ssp_printf("received eof packet, filesize: %u\n", file_size); + bundled requests - req->file->missing_offsets->print(req->file->missing_offsets, print, NULL); - req->file->eof_checksum = eof_packet->checksum; - - //if transmission mode unacknowledged, close file - if (req->transmission_mode == 0) { - return; - } - - if (ssp_close(req->file->fd) == -1) - ssp_error("could not close file\n"); +------------------------------------------------------------------------------*/ + +void request_metadata(Request *req, Response res) { + + res.msg = req->buff; + ssp_printf("sending request for new metadata packet\n"); + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); + uint16_t data_len = 0; + data_len = build_nak_metadata(res.msg, start, req); + ssp_sendto(res); + return; +} + + + +/*------------------------------------------------------------------------------ + + Processing Packets + +------------------------------------------------------------------------------*/ + +static void process_pdu_eof(char *packet, Request *req, Response res) { + + Pdu_eof *eof_packet = (Pdu_eof *) packet; + + if (!req->received_metadata && req->file == NULL) { + req->file = create_temp_file(req->transaction_sequence_number); + request_metadata(req, res); + req->file->total_size = ntohl(eof_packet->file_size); + } + + req->received_eof = 1; + req->file->eof_checksum = eof_packet->checksum; + + //if transmission mode unacknowledged, close file + if (req->transmission_mode == 0) { + return; } + + if (ssp_close(req->file->fd) == -1) + ssp_error("could not close file\n"); } //TODO This needs more work, file handling when files already exist ect static int process_file_request_metadata(Request *req) { if (does_file_exist(req->destination_file_name)){ - //ssp_error("file already exists, overwriting it\n"); + //ssp_error("file already exists, overwriting it\n"); COPY TEMP FILE TO THIS FILE req->file = create_file(req->destination_file_name, 1); } if (req->file == NULL) { @@ -306,7 +345,8 @@ static int process_file_request_metadata(Request *req) { req->file = create_file(req->destination_file_name, 1); } - ssp_printf("received metadata packet\n"); + req->received_metadata = 1; + //add offset for naks Offset *offset = ssp_alloc(1, sizeof(Offset)); offset->end = req->file_size; @@ -358,12 +398,13 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state } static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { + + if(file == NULL) { ssp_error("file struct is null, can't write to file"); - ssp_printf("dropped metadata packet :( we have no fix for this yet\n " ); return; - } + File_data_pdu_contents *packet = (File_data_pdu_contents *)data_packet; uint32_t offset_start = packet->offset; uint32_t offset_end = offset_start + data_len - 4; @@ -410,21 +451,6 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi return; } -uint8_t ack_response(char *packet, uint32_t packet_index, Request *req){ - - Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; - ssp_printf("received ack!\n"); - if (pdu_ack->directive_code == EOF_PDU) { - - - ssp_printf("received eof ack!\n"); - } - else if (pdu_ack->directive_code == FINISHED_PDU) { - req->type = finished; - ssp_printf("received finished ack\n"); - - } -} /*------------------------------------------------------------------------------ @@ -453,8 +479,7 @@ static int nak_response(char *packet, uint32_t start, Request *req, Response res uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, client->pdu_header); uint32_t offset_start = 0; uint32_t offset_end = 0; - - printf("number of segments to resend: %u\n", segments); + for (int i = 0; i < segments; i++){ //outgoing_packet_index memcpy(&offset_start, &packet[packet_index], 4); @@ -479,38 +504,90 @@ static int nak_response(char *packet, uint32_t start, Request *req, Response res //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, Response res, Request *req, Client* client, Protocol_state *p_state) { - uint32_t packet_index = process_pdu_header(packet, req, p_state); if (packet_index == -1) return; Pdu_header *header = (Pdu_header *) packet; - uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + uint16_t incoming_packet_data_len = ntohs(header->PDU_data_field_len); uint8_t directive = packet[packet_index]; packet_index += 1; + //respond + uint32_t data_len, start = 0; switch(directive) { case FINISHED_PDU: - if (req->type != finished) { - ssp_printf("file successfully sent\n"); - } - req->type = finished; + ssp_printf("received finished pdu\n"); + req->received_finished = 1; + req->type = none; + start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + data_len = build_ack(res.msg, packet_index, FINISHED_PDU, req); + ssp_sendto(res); break; case NAK_PDU: + req->received_metadata = 1; nak_response(packet, packet_index, req, res, client); - req->type = eof; break; case ACK_PDU: - ack_response(packet, packet_index, req); + if (packet[packet_index] == EOF_PDU) { + ssp_printf("received Eof ack\n"); + req->received_eof = 1; + } + break; + case NAK_METADATA: + ssp_printf("resending metadata\n"); + start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + data_len = build_put_packet_metadata(res, packet_index, req, client, p_state); + ssp_sendto(res); break; - - default: break; } } +//current user request, to send to remote +void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { + + if (req->type == none) + return; + + res.msg = req->buff; + + if (res.msg == NULL) { + ssp_printf("req->buff is null, couldn't process user request\n"); + return; + } + memset(res.msg, 0, client->packet_len); + + uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + uint32_t data_len = 0; + + switch (req->type) + { + case eof: + req->type = none; + build_eof_packet(res, start, req, client, p_state); + ssp_sendto(res); + break; + + case sending_data: + if (build_data_packet(res, start, req, client, p_state)) + req->type = eof; + ssp_sendto(res); + break; + + case put: + start = build_put_packet_metadata(res, start, req, client, p_state); + ssp_sendto(res); + req->type = sending_data; + break; + + default: + break; + } + +} /*------------------------------------------------------------------------------ SERVER SIDE @@ -522,42 +599,46 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { res.msg = req->buff; - if (req->type == finished) + if (req->type == none) return; - - if (req->buff == NULL) { + + if (req->buff == NULL) ssp_printf("req buffer is null, couldn't process timeout request\n"); - } + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); uint16_t data_len = 0; Pdu_header *pdu_header = (Pdu_header *) &res.msg; - - if (req->file == NULL) { - ssp_printf("file is null, couldn't process timeout request\n"); + + //send request for metadata + if (!req->received_metadata) { + ssp_printf("sending request for new metadata packet\n"); + data_len = build_nak_metadata(res.msg, start, req); + ssp_sendto(res); return; } //send missing NAKS if (req->file->missing_offsets->count > 0) { + ssp_printf("sending Nak data\n"); build_nak_packet(res.msg, start, req); ssp_sendto(res); return; } //received EOF - if (req->file->eof_checksum) { + if (req->received_eof) { + ssp_printf("sending eof ack\n"); data_len = build_ack(res.msg, start, EOF_PDU, req); ssp_sendto(res); } //send Finished if (req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { + ssp_printf("sending finsihed pdu\n"); data_len = build_finished_pdu(res.msg, start, req); ssp_sendto(res); } - - } //fills the current_request struct for the server, incomming requests @@ -567,18 +648,24 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques if (packet_index == -1) return; - Pdu_header *header = (Pdu_header *) packet; + Pdu_header *header = (Pdu_header *) packet; + + //set header for responding + if (req->pdu_header == NULL){ + req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); + } //process file data if (header->PDU_type == 1) { + if (!req->received_metadata) { + request_metadata(req, res); + return; + } + //this will only write data if first received a metadata packet write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); return; } - //set header for responding later - if (req->pdu_header == NULL){ - req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); - } Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; packet_index++; @@ -586,17 +673,35 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques switch (directive->directive_code) { case META_DATA_PDU: + if (req->received_metadata) + break; + + req->type = put; + ssp_printf("received metadata packet\n"); fill_request_pdu_metadata(&packet[packet_index], req); process_file_request_metadata(req); break; case EOF_PDU: - process_pdu_eof(&packet[packet_index], req); + if (req->received_eof) + break;; + + if (!req->received_metadata) + request_metadata(req, res); + + //this sshould probably just set variables for use later for calculating checksums + ssp_printf("received eof packet\n"); + process_pdu_eof(&packet[packet_index], req, res); + break; case ACK_PDU: - ack_response(packet, packet_index, req); - + ssp_printf("received Ack\n"); + if (packet[packet_index]== FINISHED_PDU) { + ssp_printf("received finished packet\n"); + req->received_finished = 1; + } + break; default: break; } @@ -615,54 +720,6 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques ------------------------------------------------------------------------------*/ -//current user request, to send to remote -void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { - - if (req->type == none) - return; - - res.msg = req->buff; - - if (res.msg == NULL) { - ssp_printf("req->buff is null, couldn't process user request\n"); - return; - } - memset(res.msg, 0, client->packet_len); - - uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - uint32_t data_len = 0; - - switch (req->type) - { - case eof: - build_eof_packet(res, start, req, client, p_state); - ssp_sendto(res); - req->type = none; - break; - - case sending_data: - if (build_data_packet(res, start, req, client, p_state)) - req->type = eof; - ssp_sendto(res); - break; - - case put: - start = build_put_packet_metadata(res, start, req, client, p_state); - ssp_sendto(res); - req->type = sending_data; - break; - - case finished: - data_len = build_ack(res.msg, start, FINISHED_PDU, req); - ssp_sendto(res); - req->type = none; - break; - - default: - break; - } - -} //Omission of source and destination filenames shall indicate that only Meta @@ -709,5 +766,3 @@ int put_request(char *source_file_name, return 0; } - - From 9889a344e7dd76786aba4fbb8245fb5a37de355d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 16 May 2019 06:01:36 -0600 Subject: [PATCH 044/400] resending finished packets, fixed bug where server didn't receive acks --- Program/include/mib.h | 2 +- Program/include/port.h | 2 -- Program/include/protocol_handler.h | 4 ++++ Program/src/port.c | 14 +++++++----- Program/src/protocol_handler.c | 35 ++++++++++++++++++++---------- 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index d0d3808..a14ee53 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -3,7 +3,7 @@ //default faul handle #include #include -#include "protocol_handler.h" +#include "packet.h" #ifndef MIB_H diff --git a/Program/include/port.h b/Program/include/port.h index 7e47553..8652a29 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -1,6 +1,4 @@ -#include "packet.h" - #ifndef PORT_H #define PORT_H diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 4397e55..4b9f137 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -50,7 +50,11 @@ typedef struct request { uint8_t received_metadata; uint8_t received_eof; + //counter for resending eof packets == 3 + uint8_t resent_eof; uint8_t received_finished; + //counter for resending finished packets == 3 + uint8_t resent_finished; char* messages_to_user; char* filestore_requests; diff --git a/Program/src/port.c b/Program/src/port.c index c1cbfb7..9988621 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -150,20 +150,22 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct soc static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { + #ifdef POSIX_PORT Protocol_state *p_state = (Protocol_state *) other; - struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; - + struct sockaddr_in* client_addr = (struct sockaddr_in*) &addr; + #endif + + Response res; Client *client = p_state->newClient; - - Response res; - res.addr = posix_client; res.sfd = sfd; res.packet_len = client->packet_len; + res.msg = client->req->buff; + res.addr = client_addr; user_request_handler(res, client->req, client, p_state); return 0; - #endif + } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index c9586e2..c1ee390 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -51,8 +51,7 @@ static uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { uint32_t packet_index = start; uint32_t data_len = 0; - Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; - directive->directive_code = FINISHED_PDU; + packet[packet_index] = FINISHED_PDU; packet_index++; data_len++; @@ -63,7 +62,7 @@ static uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { pdu_finished->file_status = FILE_RETAINED_SUCCESSFULLY; data_len += 1; packet_index += 1; - + return data_len; } @@ -272,6 +271,7 @@ uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { packet[start] = ACK_PDU; uint32_t packet_index = start + 1; Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; + pdu_ack->directive_code = type; pdu_ack->directive_subtype_code = ACK_FINISHED_END; pdu_ack->condition_code = COND_NO_ERROR; @@ -519,7 +519,7 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien case FINISHED_PDU: ssp_printf("received finished pdu\n"); req->received_finished = 1; - req->type = none; + req->type = finished; start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); data_len = build_ack(res.msg, packet_index, FINISHED_PDU, req); ssp_sendto(res); @@ -552,8 +552,6 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s if (req->type == none) return; - res.msg = req->buff; - if (res.msg == NULL) { ssp_printf("req->buff is null, couldn't process user request\n"); return; @@ -583,6 +581,18 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s req->type = sending_data; break; + case finished: + if (req->resent_finished == 3) { + req->type = none; + break; + } + start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + data_len = build_ack(res.msg, start, FINISHED_PDU, req); + ssp_sendto(res); + req->resent_finished++; + ssp_print_hex(&res.msg[start], 10); + break; + default: break; } @@ -626,18 +636,20 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { return; } - //received EOF - if (req->received_eof) { + //received EOF, send back 3 eof packets + if (req->received_eof && req->resent_eof < 3) { ssp_printf("sending eof ack\n"); data_len = build_ack(res.msg, start, EOF_PDU, req); ssp_sendto(res); + req->resent_eof++; } - //send Finished - if (req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { + //send Finished, send back 3 finished packets + if (req->resent_finished < 3 && req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { ssp_printf("sending finsihed pdu\n"); data_len = build_finished_pdu(res.msg, start, req); ssp_sendto(res); + req->resent_finished++; } } @@ -697,7 +709,8 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques case ACK_PDU: ssp_printf("received Ack\n"); - if (packet[packet_index]== FINISHED_PDU) { + Pdu_ack* ack_packet = (Pdu_ack *) &packet[packet_index]; + if (ack_packet->directive_code == FINISHED_PDU) { ssp_printf("received finished packet\n"); req->received_finished = 1; } From b0dad14827f90ea5ac3739105c8afbb197d2ae99 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 16 May 2019 09:33:33 -0600 Subject: [PATCH 045/400] Add Nak unit test for single offset --- Program/include/packet.h | 2 +- Program/include/port.h | 4 ++ Program/include/protocol_handler.h | 6 ++- Program/src/filesystem_funcs.c | 3 -- Program/src/port.c | 33 ++++++++------- Program/src/protocol_handler.c | 10 +++-- Program/test/main.c | 1 + Program/test/packet_tests.c | 65 +++++++++++++++++++++++++++--- Program/test/test.c | 16 ++++---- 9 files changed, 100 insertions(+), 40 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index d669424..01c6def 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -292,7 +292,7 @@ typedef struct pdu_nak_metadata{ segments are */ typedef struct pdu_nak { - unsigned int start_scope : 32; + uint32_t start_scope; uint32_t end_scope; //number of Nak_segments diff --git a/Program/include/port.h b/Program/include/port.h index 8652a29..1635b23 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -22,6 +22,7 @@ void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); +void ssp_cleanup_req(Request *req); void ssp_print_hex(char *stuff, uint32_t size); int ssp_open(char *pathname, int flags); int ssp_read(int fd, char* buff, size_t size); @@ -31,6 +32,9 @@ int ssp_write(int fd, const void *buf, size_t count); int ssp_close(int fd); void ssp_free(void *pointer); + + +void ssp_cleanup_pdu_header(Pdu_header *pdu_header); void reset_request(Request *req); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 4b9f137..7e09ff8 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -114,14 +114,16 @@ typedef struct protocol_state { } Protocol_state; - +//for use void parse_packet_server(char* buff, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); void parse_packet_client(char* buff, Response res, Request *req, Client *client, Protocol_state *p_state); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); +//for testing uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); -uint8_t build_ack_eof_pdu (char *packet, uint32_t start, Request *req); +uint8_t build_ack (char *packet, uint32_t start, uint8_t type, Request *req); +int process_file_request_metadata(Request *req); /* unsigned char *source_file_name, diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index f06f283..1c63037 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -57,8 +57,6 @@ File *create_file(char *source_file_name, int clear_file_contents) { return NULL; } - //ssp_printf("file size: %u\n", total_size); - File *file = ssp_alloc(1, sizeof(File)); file->fd = fd; @@ -129,7 +127,6 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset) { void free_file(void *file) { File *f = (File *) file; - f->missing_offsets->free(f->missing_offsets, ssp_free); ssp_free(f); diff --git a/Program/src/port.c b/Program/src/port.c index 9988621..7eec637 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -395,24 +395,24 @@ Request *init_request(uint32_t buff_len) { } -static void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { - free(pdu_header->destination_id); - free(pdu_header->source_id); - free(pdu_header); +void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { + ssp_free(pdu_header->destination_id); + ssp_free(pdu_header->source_id); + ssp_free(pdu_header); } -static void ssp_cleanup_req(Request *req) { +void ssp_cleanup_req(Request *req) { if (req->file != NULL) free_file(req->file); if (req->pdu_header != NULL) ssp_cleanup_pdu_header(req->pdu_header); - free(req->res.addr); - free(req->source_file_name); - free(req->destination_file_name); - free(req->buff); - free(req); + ssp_free(req->res.addr); + ssp_free(req->source_file_name); + ssp_free(req->destination_file_name); + ssp_free(req->buff); + ssp_free(req); } @@ -426,10 +426,10 @@ void ssp_cleanup(Protocol_state *p_state) { p_state->request_list->free( p_state->request_list, ssp_cleanup_req); ssp_cleanup_req(p_state->current_server_request); free_mib(p_state->mib); - free(p_state->server_handle); - free(p_state->server_port); - free(p_state->server_thread_attributes); - free(p_state); + ssp_free(p_state->server_handle); + ssp_free(p_state->server_port); + ssp_free(p_state->server_thread_attributes); + ssp_free(p_state); #endif @@ -445,8 +445,8 @@ void ssp_cleanup_client(Client *client) { #endif ssp_cleanup_req(client->req); - free(client->client_handle); - free(client->client_thread_attributes); + ssp_free(client->client_handle); + ssp_free(client->client_thread_attributes); ssp_cleanup_pdu_header(client->pdu_header); free(client); @@ -458,5 +458,4 @@ void ssp_free(void *pointer) { #ifdef POSIX_PORT free(pointer); #endif - } \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index c1ee390..7c89f72 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -244,7 +244,7 @@ static void fill_nak_array(void *element, void *args){ holder->i++; } -void build_nak_packet(char *packet, uint32_t start, Request *req) { +uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet[start] = NAK_PDU; uint32_t packet_index = start + 1; @@ -265,6 +265,10 @@ void build_nak_packet(char *packet, uint32_t start, Request *req) { memcpy(&packet[packet_index], holder.offsets, sizeof(Offset) * count); ssp_free(holder.offsets); + + packet_index += sizeof(Offset) * count; + + return packet_index - start; } uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { @@ -334,7 +338,7 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { } //TODO This needs more work, file handling when files already exist ect -static int process_file_request_metadata(Request *req) { +int process_file_request_metadata(Request *req) { if (does_file_exist(req->destination_file_name)){ //ssp_error("file already exists, overwriting it\n"); COPY TEMP FILE TO THIS FILE @@ -701,7 +705,7 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques if (!req->received_metadata) request_metadata(req, res); - //this sshould probably just set variables for use later for calculating checksums + //this should probably just set variables for use later for calculating checksums ssp_printf("received eof packet\n"); process_pdu_eof(&packet[packet_index], req, res); diff --git a/Program/test/main.c b/Program/test/main.c index 1fa74ab..2f8e1a1 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -82,6 +82,7 @@ int main () { packet_tests(header); free_mib(mib); + ssp_cleanup_pdu_header(header); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index dce7969..693a3e8 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -1,14 +1,64 @@ -#include "protocol_handler.h" #include "test.h" #include "utils.h" #include +#include "filesystem_funcs.h" +#include "port.h" + + +static int test_build_nak_packet(char* packet, uint32_t start) { + printf("testing nak creation\n"); + Request *req = init_request(5000); + + + req->file_size = 100000; + memcpy(req->destination_file_name, "testestest", 15); + memcpy(req->source_file_name, "someotherfile", 15); + + process_file_request_metadata(req); + + + + uint64_t count = req->file->missing_offsets->count; + ssp_printf("missing offset number=%u\n", count); + + uint32_t data_len = build_nak_packet(packet, start, req); + + ASSERT_EQUALS_INT("NAK directive code set", packet[start], NAK_PDU); + //25 = start_scope + end_scope + 1 offset + 1byte NAK_PDU code + ASSERT_EQUALS_INT("length of packet", 25, data_len); + uint32_t packet_index = start + 1; + Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; + + uint32_t start_scope = ntohl(nak->start_scope); + uint32_t end_scope = ntohl(nak->end_scope); + + ASSERT_EQUALS_INT("start offset == 0 ", start_scope, 0); + ASSERT_EQUALS_INT("end scope == 100000 ", end_scope, 100000); + + uint64_t number_of_segments = ntohll(nak->segment_requests); + ASSERT_EQUALS_INT("number of segments == 1 ", number_of_segments, 1); + + Offset offset[count]; + memcpy(offset, &nak->segments, sizeof(Offset) * count); + start_scope = ntohl(offset->start); + end_scope = ntohl(offset->end); + + ASSERT_EQUALS_INT("start offset == 0 ", start_scope, 0); + ASSERT_EQUALS_INT("end scope == 100000 ", end_scope, 100000); + + + + ssp_print_hex(&packet[start], data_len); + + ssp_cleanup_req(req); + return 1; +} int test_build_ack_finished_pdu(char *packet, uint32_t start) { printf("testing finished ack creation\n"); Request *req; - uint8_t len = test_build_ack_finished_pdu (packet, start, req); Pdu_directive *pdu_d = &packet[start]; ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); @@ -17,17 +67,15 @@ int test_build_ack_finished_pdu(char *packet, uint32_t start) { ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack->directive_code); ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack->condition_code); ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack->directive_subtype_code, ACK_FINISHED_END); - - - } + int test_build_ack_eof_pdu(char *packet, uint32_t start) { //empty request printf("testing eof ack creation\n"); Request *req; - uint8_t len = build_ack_eof_pdu (packet, start, req); + uint8_t len = build_ack (packet, start, EOF_PDU, req); Pdu_directive *pdu_d = &packet[start]; ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); @@ -81,5 +129,10 @@ int packet_tests(Pdu_header *header) { uint64_t sequence_number = 12345663234; int packet_index = test_build_pdu_header_header(packet, header, sequence_number); test_build_ack_eof_pdu(packet, packet_index); + test_build_nak_packet(packet, packet_index); + + + + ssp_free(packet); } \ No newline at end of file diff --git a/Program/test/test.c b/Program/test/test.c index 102495b..0598157 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -12,12 +12,12 @@ void ASSERT_EQUALS_INT(char* description, int val1, int val2) { if (val1 == val2){ printf("\033[0;32m"); printf("%s", description); - printf("pass # %d\n", test_num); + printf(" pass # %d\n", test_num); } else { printf("\033[0;31m"); printf("%s", description); - printf("fail # %d\n", test_num); + printf(" fail # %d\n", test_num); } printf("\033[0m"); } @@ -29,12 +29,12 @@ void ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { if (val1 == val2){ printf("\033[0;31m"); printf("%s", description); - printf("fail # %d\n", test_num); + printf(" fail # %d\n", test_num); } else { printf("\033[0;32m"); printf("%s", description); - printf("pass # %d\n", test_num); + printf(" pass # %d\n", test_num); } printf("\033[0m"); } @@ -46,12 +46,12 @@ void ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) if (!memcmp(val1, val2, size)) { printf("\033[0;32m"); printf("%s", description); - printf("pass # %d\n", test_num); + printf(" pass # %d\n", test_num); } else { printf("\033[0;31m"); printf("%s", description); - printf("fail # %d\n", test_num); + printf(" fail # %d\n", test_num); } printf("\033[0m"); @@ -64,12 +64,12 @@ void ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t si printf("\033[0;31m"); printf("%s", description); - printf("fail # %d\n", test_num); + printf(" fail # %d\n", test_num); } else { printf("\033[0;32m"); printf("%s", description); - printf("pass # %d\n", test_num); + printf(" pass # %d\n", test_num); } printf("\033[0m"); } From e3fb15c6d2670a7ee8eb3f817f79fec3e07e8cbb Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 22 May 2019 06:02:01 -0600 Subject: [PATCH 046/400] testing naks, quit client when completed --- Program/include/protocol_handler.h | 4 +- Program/src/filesystem_funcs.c | 11 ++-- Program/src/main.c | 1 + Program/src/port.c | 10 ++++ Program/src/protocol_handler.c | 18 +++--- Program/src/utils.c | 7 ++- Program/test/main.c | 1 - Program/test/packet_tests.c | 89 ++++++++++++++++++++++++++++-- 8 files changed, 115 insertions(+), 26 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 7e09ff8..0e264c9 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -120,11 +120,13 @@ void user_request_handler(Response res, Request *req, Client *client, Protocol_s void parse_packet_client(char* buff, Response res, Request *req, Client *client, Protocol_state *p_state); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); + //for testing uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_ack (char *packet, uint32_t start, uint8_t type, Request *req); int process_file_request_metadata(Request *req); - +int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client); +void set_data_length(char*packet, uint16_t data_len); /* unsigned char *source_file_name, unsigned char *destination_file_name, diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 1c63037..0c44f66 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -179,9 +179,8 @@ static int find_nak(void *element, void* args) { Offset *offset_in_list = (Offset *) element; Offset *offset_to_insert = (Offset *) args; - - if (offset_to_insert->start >= offset_in_list->start && - offset_to_insert->end <= offset_in_list->end) { + + if (offset_to_insert->start >= offset_in_list->start && offset_to_insert->end <= offset_in_list->end) { return 1; } @@ -197,10 +196,10 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off offset_to_insert.start = offset_start; offset_to_insert.end = offset_end; - NODE * node = nak_list->findNode(nak_list, 0, find_nak, &offset_to_insert); + NODE * node = nak_list->findNode(nak_list, -1, find_nak, &offset_to_insert); if (node == NULL){ - ssp_printf("no begining node for receive_offset, can't add new offset\n"); - return; + ssp_printf("no begining node for receive_offset, or offset we already received, can't add new offset\n"); + return; } Offset *offset_in_list = (Offset *) node->element; diff --git a/Program/src/main.c b/Program/src/main.c index 5646279..7eadc4b 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -78,6 +78,7 @@ int main(int argc, char** argv) { //will block on pthread_join ssp_cleanup_client(new_client); + ssp_printf("client disconnected\n"); } ssp_cleanup(p_state); diff --git a/Program/src/port.c b/Program/src/port.c index 7eec637..f391aa7 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -91,6 +91,16 @@ void ssp_print_hex(char *stuff, uint32_t size){ ssp_printf("\n"); } + +void ssp_thread_cancel(void *thread_handle) { + #ifdef POSIX_PORT + pthread_t * handle = (pthread_t*) thread_handle; + pthread_cancel(*handle); + #endif + +} + + void ssp_sendto(Response res) { #ifdef POSIX_PORT diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 7c89f72..181a77a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -244,6 +244,8 @@ static void fill_nak_array(void *element, void *args){ holder->i++; } + + uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet[start] = NAK_PDU; @@ -307,7 +309,10 @@ void request_metadata(Request *req, Response res) { return; } - +void set_data_length(char*packet, uint16_t data_len){ + Pdu_header *header = (Pdu_header*) packet; + header->PDU_data_field_len = data_len; +} /*------------------------------------------------------------------------------ @@ -465,7 +470,7 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi ------------------------------------------------------------------------------*/ -static int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { +int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; uint32_t offset_first = ntohl(nak->start_scope); @@ -521,12 +526,8 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien switch(directive) { case FINISHED_PDU: - ssp_printf("received finished pdu\n"); req->received_finished = 1; req->type = finished; - start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - data_len = build_ack(res.msg, packet_index, FINISHED_PDU, req); - ssp_sendto(res); break; case NAK_PDU: req->received_metadata = 1; @@ -587,20 +588,19 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s case finished: if (req->resent_finished == 3) { - req->type = none; + ssp_printf("file successfully sent\n"); + ssp_thread_cancel(client->client_handle); break; } start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); data_len = build_ack(res.msg, start, FINISHED_PDU, req); ssp_sendto(res); req->resent_finished++; - ssp_print_hex(&res.msg[start], 10); break; default: break; } - } /*------------------------------------------------------------------------------ diff --git a/Program/src/utils.c b/Program/src/utils.c index c36c6e3..737be63 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -283,7 +283,7 @@ static void *findElement(List *list, uint32_t id, int (*f)(void *element, void * if (f != NULL) found_with_func = f(cur->element, args); - if(cur->id == id) + if(id != -1 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id){ @@ -306,7 +306,7 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme if (f != NULL) found_with_func = f(cur->element, args); - if(cur->id == id) + if(id != -1 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id) { @@ -326,6 +326,7 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme static NODE * findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { + NODE *cur = list->head->next; int found_with_func = 0; int found_with_id = 0; @@ -334,7 +335,7 @@ static NODE * findNode(List *list, uint32_t id, int (*f)(void *element, void *ar if (f != NULL) found_with_func = f(cur->element, args); - if(cur->id == id) + if(id != -1 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id){ diff --git a/Program/test/main.c b/Program/test/main.c index 2f8e1a1..f8a45fe 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -1,5 +1,4 @@ - #include "utils.h" #include #include diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 693a3e8..7d72cd9 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -1,4 +1,5 @@ +#define TESTING 1 #include "test.h" #include "utils.h" @@ -6,9 +7,28 @@ #include "filesystem_funcs.h" #include "port.h" +#define PACKET_TEST_SIZE 2000 + + +static int test_respond_to_naks(char *packet, uint32_t packet_index) { + + + Request *req = init_request(5000); + nak_response(packet, packet_index, req); + + + + +} + + +static void nak_print(void *element, void *args){ + Offset *offset = (Offset *)element; + ssp_printf("start: %u end: %u\n", offset->start, offset->end); +} static int test_build_nak_packet(char* packet, uint32_t start) { - printf("testing nak creation\n"); + printf("testing nak creation 1 \n"); Request *req = init_request(5000); @@ -17,8 +37,6 @@ static int test_build_nak_packet(char* packet, uint32_t start) { memcpy(req->source_file_name, "someotherfile", 15); process_file_request_metadata(req); - - uint64_t count = req->file->missing_offsets->count; ssp_printf("missing offset number=%u\n", count); @@ -48,9 +66,68 @@ static int test_build_nak_packet(char* packet, uint32_t start) { ASSERT_EQUALS_INT("start offset == 0 ", start_scope, 0); ASSERT_EQUALS_INT("end scope == 100000 ", end_scope, 100000); + //add a bunch more + printf("testing nak creation 2 \n"); + + receive_offset(req->file, 0, 1250, 5000); + receive_offset(req->file, 0, 6000, 9000); + receive_offset(req->file, 0, 10000, 15000); + data_len = build_nak_packet(packet, start, req); + set_data_length(packet, data_len); - ssp_print_hex(&packet[start], data_len); + number_of_segments = ntohll(nak->segment_requests); + + ASSERT_EQUALS_INT("number of segments == 4 ", number_of_segments, 4); + + start_scope = ntohl(nak->start_scope); + end_scope = ntohl(nak->end_scope); + ASSERT_EQUALS_INT("correct packet start", start_scope, 0); + ASSERT_EQUALS_INT("correct packet end", end_scope, 100000); + packet_index += 16; + + //outgoing_packet_index + memcpy(&start_scope, &packet[packet_index], 4); + start_scope = ntohl(start_scope); + packet_index += 4; + memcpy(&end_scope, &packet[packet_index], 4); + end_scope = ntohl(end_scope); + packet_index += 4; + ASSERT_EQUALS_INT("correct packet offset 0 start", start_scope, 0); + ASSERT_EQUALS_INT("correct packet offset 0 end", end_scope, 1250); + + memcpy(&start_scope, &packet[packet_index], 4); + start_scope = ntohl(start_scope); + packet_index += 4; + memcpy(&end_scope, &packet[packet_index], 4); + end_scope = ntohl(end_scope); + packet_index += 4; + ASSERT_EQUALS_INT("correct packet offset 1 start", start_scope, 5000); + ASSERT_EQUALS_INT("correct packet offset 1 end", end_scope, 6000); + + memcpy(&start_scope, &packet[packet_index], 4); + start_scope = ntohl(start_scope); + packet_index += 4; + memcpy(&end_scope, &packet[packet_index], 4); + end_scope = ntohl(end_scope); + packet_index += 4; + ASSERT_EQUALS_INT("correct packet offset 2 start", start_scope, 9000); + ASSERT_EQUALS_INT("correct packet offset 2 end", end_scope, 10000); + + memcpy(&start_scope, &packet[packet_index], 4); + start_scope = ntohl(start_scope); + packet_index += 4; + memcpy(&end_scope, &packet[packet_index], 4); + end_scope = ntohl(end_scope); + packet_index += 4; + ASSERT_EQUALS_INT("correct packet offset 3 start", start_scope, 15000); + ASSERT_EQUALS_INT("correct packet offset 3 end", end_scope, 100000); + + Pdu_header *header = (Pdu_header*) packet; + ssp_printf("datalen %u\n", header->PDU_data_field_len); + ssp_printf("datalen %u\n", data_len); + + ASSERT_EQUALS_INT("correct packet data_len", data_len, header->PDU_data_field_len); ssp_cleanup_req(req); return 1; @@ -125,12 +202,12 @@ int test_build_pdu_header_header(char *packet, Pdu_header *header, uint64_t sequ int packet_tests(Pdu_header *header) { printf("starting Packet Tests (creating and changing packet values)\n"); - char *packet = calloc(2000, sizeof(char)); + char *packet = calloc(PACKET_TEST_SIZE, sizeof(char)); uint64_t sequence_number = 12345663234; int packet_index = test_build_pdu_header_header(packet, header, sequence_number); test_build_ack_eof_pdu(packet, packet_index); test_build_nak_packet(packet, packet_index); - + test_respond_to_naks(packet, packet_index); ssp_free(packet); From 41a5b363d4fc179e3d09e2706c5191741a6bc9b3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 23 May 2019 09:13:59 -0600 Subject: [PATCH 047/400] quick update before merging back to master --- Program/include/protocol_handler.h | 49 ++++++++++++++------------- Program/src/port.c | 26 +++++++-------- Program/src/protocol_handler.c | 53 ++++++++++++++++-------------- Program/test/packet_tests.c | 18 +++++++--- 4 files changed, 79 insertions(+), 67 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 0e264c9..383837d 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -72,6 +72,28 @@ typedef struct request { Response res; } Request; + +typedef struct protocol_state { + uint32_t packet_size; + char *server_port; + void *server_handle; + void *server_thread_attributes; + MIB *mib; + uint32_t my_cfdp_id; + + List* request_list; + + Request *current_server_request; + + //lock this + uint32_t transaction_sequence_number; + + uint8_t verbose_level; + + +} Protocol_state; + + //outgoing requests spin up client threads typedef struct client { @@ -90,34 +112,15 @@ typedef struct client { Pdu_header *pdu_header; uint8_t is_active; - -} Client; - - -typedef struct protocol_state { - uint32_t packet_size; - char *server_port; - void *server_handle; - void *server_thread_attributes; - MIB *mib; - uint32_t my_cfdp_id; - Client *newClient; - List* request_list; - - Request *current_server_request; - - //lock this - uint32_t transaction_sequence_number; + Protocol_state *p_state; - uint8_t verbose_level; - +} Client; -} Protocol_state; //for use void parse_packet_server(char* buff, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state); -void user_request_handler(Response res, Request *req, Client *client, Protocol_state *p_state); -void parse_packet_client(char* buff, Response res, Request *req, Client *client, Protocol_state *p_state); +void user_request_handler(Response res, Request *req, Client *client); +void parse_packet_client(char* buff, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); diff --git a/Program/src/port.c b/Program/src/port.c index f391aa7..7a38e3a 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -95,8 +95,8 @@ void ssp_print_hex(char *stuff, uint32_t size){ void ssp_thread_cancel(void *thread_handle) { #ifdef POSIX_PORT pthread_t * handle = (pthread_t*) thread_handle; - pthread_cancel(*handle); #endif + pthread_cancel(*handle); } @@ -144,16 +144,15 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct soc struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; #endif - Protocol_state *p_state = (Protocol_state *) other; + Client *client = (Client *) other; Response res; res.addr = posix_client; res.sfd = sfd; res.packet_len = *buff_size; - Client *client = p_state->newClient; res.msg = client->req->buff; - parse_packet_client(packet, res, client->req, client, p_state); + parse_packet_client(packet, res, client->req, client); return 0; } @@ -162,18 +161,17 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { #ifdef POSIX_PORT - Protocol_state *p_state = (Protocol_state *) other; struct sockaddr_in* client_addr = (struct sockaddr_in*) &addr; #endif Response res; - Client *client = p_state->newClient; + Client *client = (Client *) other; res.sfd = sfd; res.packet_len = client->packet_len; res.msg = client->req->buff; res.addr = client_addr; - user_request_handler(res, client->req, client, p_state); + user_request_handler(res, client->req, client); return 0; @@ -297,17 +295,17 @@ Protocol_state* ssp_connectionless_server(char *port) { void *ssp_connectionless_client_task(void* params){ - Protocol_state *p_state = (Protocol_state *) params; + Client *client = (Client *) params; char host_name[INET_ADDRSTRLEN]; char port[10]; //convert int to char * - snprintf(port, 10, "%d", p_state->newClient->unitdata_port); + snprintf(port, 10, "%d", client->unitdata_port); //convert uint id to char * - inet_ntop(AF_INET, &p_state->newClient->unitdata_id, host_name, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &client->unitdata_id, host_name, INET_ADDRSTRLEN); - udpClient(host_name, port, PACKET_LEN, p_state, p_state, on_send_client, on_recv_client); + udpClient(host_name, port, PACKET_LEN, client, client, on_send_client, on_recv_client); return NULL; } @@ -358,11 +356,9 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { client->mib_info = remote; client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); - - //TODO lock this - p_state->newClient = client; + client->p_state = p_state; - err = pthread_create(handler, attr, ssp_connectionless_client_task, p_state); + err = pthread_create(handler, attr, ssp_connectionless_client_task, client); if (0 != err) perror("ERROR pthread_create"); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 181a77a..b516d3d 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -67,7 +67,8 @@ static uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { } -static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { +static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req +) { Pdu_header *header = (Pdu_header *) res.msg; header->PDU_type = DIRECTIVE; @@ -151,36 +152,36 @@ static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, //requires a req->file to be created //returns 1 on end of file -static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { +static uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { - if (req->file->next_offset_to_send > req->file->total_size){ + if (file->next_offset_to_send > file->total_size){ ssp_error("cant send an offset past the file's length\n"); return -1; } - Pdu_header *header = (Pdu_header *) res.msg; + Pdu_header *header = (Pdu_header *) packet; //set header to file directive 0 is directive, 1 is data header->PDU_type = 1; uint16_t packet_index = start; - File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &res.msg[packet_index]; + File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; //4 bytes is the size of the offset paramater - packet_offset->offset = req->file->next_offset_to_send; + packet_offset->offset = file->next_offset_to_send; packet_index += 4; - uint16_t data_size = client->packet_len - packet_index; + uint16_t data_size = length - packet_index; //fill the rest of the packet with data - int bytes = get_offset(req->file, &res.msg[packet_index], data_size, req->file->next_offset_to_send); + int bytes = get_offset(file, &packet[packet_index], data_size, file->next_offset_to_send); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); return -1; } //calculate checksum for data packet, this is used to calculate in transit checksums - req->file->partial_checksum += calc_check_sum(&res.msg[packet_index], bytes); - req->file->next_offset_to_send += bytes; + file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); + file->next_offset_to_send += bytes; //add bytes read, and the packet offset to the data_field length header->PDU_data_field_len = htons(bytes + 4); @@ -191,30 +192,30 @@ static uint8_t build_data_packet(Response res, uint32_t start, Request *req, Cli return 0; } -static void build_eof_packet(Response res, uint32_t start, Request *req, Client* client, Protocol_state *p_state) { +static void build_eof_packet(char *packet, uint32_t start, Request *req) { - Pdu_header *header = (Pdu_header *) res.msg; + Pdu_header *header = (Pdu_header *) packet; //set header to file directive 0 is directive, 1 is data header->PDU_type = 0; uint8_t packet_index = (uint8_t) start; - Pdu_directive *directive = (Pdu_directive *) &res.msg[packet_index]; + Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; directive->directive_code = EOF_PDU; packet_index++; - Pdu_eof *packet = (Pdu_eof *) &res.msg[packet_index]; + Pdu_eof *eof_packet = (Pdu_eof *) &packet[packet_index]; //this will be need to set from the req struct probably. //4 bits, - packet->condition_code = COND_NO_ERROR; + eof_packet->condition_code = COND_NO_ERROR; //4 bits reserved bits - packet->spare = 0; + eof_packet->spare = 0; packet_index++; //4 bytes - packet->file_size = ntohl(req->file->total_size); + eof_packet->file_size = ntohl(req->file->total_size); packet_index += 4; - packet->checksum = req->file->partial_checksum; + eof_packet->checksum = req->file->partial_checksum; packet_index += 4; //TODO addTLV fault_location @@ -511,9 +512,9 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien //fills the current request with packet data, responses from servers -void parse_packet_client(char *packet, Response res, Request *req, Client* client, Protocol_state *p_state) { +void parse_packet_client(char *packet, Response res, Request *req, Client* client) { - uint32_t packet_index = process_pdu_header(packet, req, p_state); + uint32_t packet_index = process_pdu_header(packet, req, client->p_state); if (packet_index == -1) return; @@ -542,7 +543,8 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien case NAK_METADATA: ssp_printf("resending metadata\n"); start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - data_len = build_put_packet_metadata(res, packet_index, req, client, p_state); + data_len = build_put_packet_metadata(res, packet_index, req); + set_data_length(res.msg, data_len); ssp_sendto(res); break; default: @@ -552,7 +554,7 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien //current user request, to send to remote -void user_request_handler(Response res, Request *req, Client* client, Protocol_state *p_state) { +void user_request_handler(Response res, Request *req, Client* client) { if (req->type == none) return; @@ -570,18 +572,19 @@ void user_request_handler(Response res, Request *req, Client* client, Protocol_s { case eof: req->type = none; - build_eof_packet(res, start, req, client, p_state); + build_eof_packet(res.msg, start, req); ssp_sendto(res); break; case sending_data: - if (build_data_packet(res, start, req, client, p_state)) + if (build_data_packet(res.msg, start, req->file, client->packet_len)) req->type = eof; ssp_sendto(res); + break; case put: - start = build_put_packet_metadata(res, start, req, client, p_state); + start = build_put_packet_metadata(res, start, req); ssp_sendto(res); req->type = sending_data; break; diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 7d72cd9..90b7eeb 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -11,14 +11,24 @@ static int test_respond_to_naks(char *packet, uint32_t packet_index) { - - Request *req = init_request(5000); - nak_response(packet, packet_index, req); - + ssp_cleanup_req(req); + +} +static int test_respond_metadata_request() { + + //ssp_printf("input a src file:\n"); + Client *client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + + //send via acknoleged mode //0 acknowledged, 1 unacknowledged + //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, client, p_state); + uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + uint32_t data_len = build_put_packet_metadata(res, packet_index, req, client, p_state); + set_data_length(res.msg, data_len); } From b5726edc286eda56528a4ef9550108de6a4af458 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 24 May 2019 15:18:04 -0600 Subject: [PATCH 048/400] bug smashes, lost eof's, weird utils.c list bugs --- Program/include/filesystem_funcs.h | 8 +- Program/include/packet.h | 12 +- Program/include/port.h | 2 + Program/include/protocol_handler.h | 2 + Program/src/filesystem_funcs.c | 59 ++++++++-- Program/src/port.c | 6 + Program/src/protocol_handler.c | 171 +++++++++++++++++------------ Program/src/utils.c | 19 +++- 8 files changed, 185 insertions(+), 94 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index f340323..751c7e0 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -4,7 +4,7 @@ #include #include "utils.h" -#define TEMP_FILESIZE 20000 +#define TEMP_FILESIZE 10000000 typedef struct offset { uint32_t start; @@ -14,6 +14,7 @@ typedef struct offset { typedef struct file { int fd; + uint8_t is_temp; uint32_t next_offset_to_send; uint32_t total_size; uint32_t partial_checksum; @@ -32,6 +33,7 @@ int get_offset(File *file, void *buff, uint32_t buf_size, int offset); int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); uint32_t calc_check_sum(char *data, uint32_t length); uint32_t check_sum_file(File *file, uint16_t stack_buffer); -void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end); -File *create_temp_file(uint64_t transaction_sequence_num); +int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end); +File *create_temp_file(char *file_name); +int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); #endif diff --git a/Program/include/packet.h b/Program/include/packet.h index 01c6def..d18ac60 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -194,7 +194,9 @@ typedef struct filestore_response { #define PROMPT_PDU 0x09 #define KEEP_ALIVE_PDU 0x0C #define SIZE_OF_DIRECTIVE_CODE 1 -#define NAK_METADATA 0x0d + +//custom, for missing metadata and eof +#define NAK_DIRECTIVE 0x0d //condition codes: @@ -281,10 +283,12 @@ typedef struct pdu_eof { } Pdu_eof; - //currently, empty, only need the directive code -typedef struct pdu_nak_metadata{ -} Pdu_nak_metadata; +//custom, nak missing other directives, like metadata and eof +typedef struct pdu_nak_directive{ + uint8_t directive; + +} pdu_nak_directive; /* start_scope is the begining of the nak requests diff --git a/Program/include/port.h b/Program/include/port.h index 1635b23..cdfa8ab 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -32,7 +32,9 @@ int ssp_write(int fd, const void *buf, size_t count); int ssp_close(int fd); void ssp_free(void *pointer); +int ssp_rename(const char *old, const char *new); +void ssp_thread_cancel(void *thread_handle); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); void reset_request(Request *req); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 383837d..0f0c0b2 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -55,6 +55,8 @@ typedef struct request { uint8_t received_finished; //counter for resending finished packets == 3 uint8_t resent_finished; + //bool for sending first blast of data packets + uint8_t sent_first_data_round; char* messages_to_user; char* filestore_requests; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 0c44f66..9b1cc91 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -188,7 +188,7 @@ static int find_nak(void *element, void* args) { } //ack is 1, nak is 0 -void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end) { +int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end) { List * nak_list = file->missing_offsets; @@ -203,14 +203,26 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off } Offset *offset_in_list = (Offset *) node->element; - //ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); + ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); + + if (offset_in_list->start == offset_in_list->end) { + ssp_printf("removing node\n"); + node->next->prev = node->prev; + node->prev->next = node->next; + ssp_free(node->element); + ssp_free(node); + nak_list->count--; + } + + if (offset_to_insert.start > offset_to_insert.end) + return; //insert new node if (offset_to_insert.start >= offset_in_list->start && offset_to_insert.end <= offset_in_list->end) { //remove node if both start and end are equal if (offset_to_insert.start == offset_in_list->start && offset_to_insert.end == offset_in_list->end) { - //ssp_printf("removing node\n"); + ssp_printf("removing node\n"); node->next->prev = node->prev; node->prev->next = node->next; ssp_free(node->element); @@ -225,7 +237,6 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off return; } - //ssp_printf("adding new node\n"); Offset *new_offset = ssp_alloc(1, sizeof(Offset)); new_offset->start = offset_start; new_offset->end = offset_end; @@ -244,17 +255,45 @@ void receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t off new->prev->next = new; cur->prev = new; nak_list->count++; - } +} +File *create_temp_file(char *file_name) { + File *file = create_file(file_name, 1); + file->is_temp = 1; + + ssp_printf("mode acknowledged, building offset map\n"); + Offset *offset = ssp_alloc(1, sizeof(Offset)); + offset->end = TEMP_FILESIZE; + offset->start = 0; + file->missing_offsets->insert(file->missing_offsets, offset, TEMP_FILESIZE); + return file; } -File *create_temp_file(uint64_t transaction_sequence_num) { +static int print_nak(void *element, void* args) { - char temp[75]; - snprintf(temp, 75, "%s%llu", "temp_", transaction_sequence_num); - File *file = create_file(temp, 1); - file->total_size = TEMP_FILESIZE; + Offset *offset_in_list = (Offset *) element; + ssp_printf("start: %u, end: %u\n", offset_in_list->start, offset_in_list->end); + return 0; } + +int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file) { + + //ssp_printf("renaming %s to: %s", temp, destination_file_name); + ssp_rename(temp, destination_file_name); + + //file->missing_offsets->print(file->missing_offsets, print_nak, NULL); + Offset* offset = (Offset*)file->missing_offsets->pop(file->missing_offsets); + if (offset == NULL) { + ssp_printf("no last node to pop\n"); + return -1; + } + + + offset->end = file_size; + file->missing_offsets->push(file->missing_offsets, offset, file_size); + file->is_temp = 0; + +} diff --git a/Program/src/port.c b/Program/src/port.c index 7a38e3a..d092d49 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -21,6 +21,12 @@ #endif #include "protocol_handler.h" +int ssp_rename(const char *old, const char *new) { + #ifdef POSIX_PORT + return rename(old, new); + #endif +} + int ssp_write(int fd, const void *buf, size_t count) { #ifdef POSIX_PORT return write(fd, buf, count); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index b516d3d..9bb4831 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -6,6 +6,9 @@ #include "packet.h" #include "filesystem_funcs.h" +//snprintf +#include + /*------------------------------------------------------------------------------ creating packets @@ -122,7 +125,7 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { if (offset > req->file->total_size) { - return -1; + return 1; } Pdu_header *header = (Pdu_header *) packet; @@ -139,7 +142,7 @@ static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, int bytes = get_offset(req->file, &packet[packet_index], data_size, offset); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); - return -1; + return 1; } //add bytes read, and the packet offset to the data_field length @@ -147,6 +150,7 @@ static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, if (bytes < data_size) return 1; + return 0; } @@ -156,7 +160,7 @@ static uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint3 if (file->next_offset_to_send > file->total_size){ ssp_error("cant send an offset past the file's length\n"); - return -1; + return 1; } Pdu_header *header = (Pdu_header *) packet; @@ -176,7 +180,7 @@ static uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint3 int bytes = get_offset(file, &packet[packet_index], data_size, file->next_offset_to_send); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); - return -1; + return 1; } //calculate checksum for data packet, this is used to calculate in transit checksums @@ -223,12 +227,6 @@ static void build_eof_packet(char *packet, uint32_t start, Request *req) { } -void print(void *element, void *args) { - Offset * o = (Offset *) element; - ssp_printf("start: %u, end: %u\n", o->start, o->end); -} - - //this is a callback for building nak_array server side struct offset_holder { Offset *offsets; @@ -247,7 +245,7 @@ static void fill_nak_array(void *element, void *args){ -uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { +static uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet[start] = NAK_PDU; uint32_t packet_index = start + 1; @@ -261,8 +259,10 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { req->file->missing_offsets->print(req->file->missing_offsets, fill_nak_array, &holder); - pdu_nak->start_scope = holder.offsets[0].start;; - pdu_nak->end_scope = holder.offsets[holder.i-1].end;; + pdu_nak->start_scope = holder.offsets[0].start; + pdu_nak->end_scope = holder.offsets[holder.i-1].end; + + pdu_nak->segment_requests = htonll(count); packet_index+=16; @@ -285,13 +285,18 @@ uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { packet_index += 2; return packet_index - start; } -uint8_t build_nak_metadata(char *packet, uint32_t start, Request *req) { - uint8_t data_len = 1; - packet[start] = NAK_METADATA; + +static uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { + uint8_t data_len = 2; + packet[start] = NAK_DIRECTIVE; + packet[start + 1] = directive; return data_len; } - +void set_data_length(char*packet, uint16_t data_len){ + Pdu_header *header = (Pdu_header*) packet; + header->PDU_data_field_len = data_len; +} /*------------------------------------------------------------------------------ @@ -299,21 +304,19 @@ uint8_t build_nak_metadata(char *packet, uint32_t start, Request *req) { ------------------------------------------------------------------------------*/ -void request_metadata(Request *req, Response res) { +static void request_metadata(Request *req, Response res) { res.msg = req->buff; ssp_printf("sending request for new metadata packet\n"); uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); uint16_t data_len = 0; - data_len = build_nak_metadata(res.msg, start, req); + data_len = build_nak_directive(res.msg, start, META_DATA_PDU); + set_data_length(res.msg, data_len); ssp_sendto(res); return; } -void set_data_length(char*packet, uint16_t data_len){ - Pdu_header *header = (Pdu_header*) packet; - header->PDU_data_field_len = data_len; -} + /*------------------------------------------------------------------------------ @@ -325,48 +328,45 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { Pdu_eof *eof_packet = (Pdu_eof *) packet; - if (!req->received_metadata && req->file == NULL) { - req->file = create_temp_file(req->transaction_sequence_number); + if (!req->received_metadata) { request_metadata(req, res); - req->file->total_size = ntohl(eof_packet->file_size); } + if (req->file == NULL) { + snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); + req->file = create_temp_file(req->source_file_name); + } + req->received_eof = 1; req->file->eof_checksum = eof_packet->checksum; + req->file->total_size = ntohl(eof_packet->file_size); - //if transmission mode unacknowledged, close file - if (req->transmission_mode == 0) { - return; - } - - if (ssp_close(req->file->fd) == -1) - ssp_error("could not close file\n"); } //TODO This needs more work, file handling when files already exist ect int process_file_request_metadata(Request *req) { - if (does_file_exist(req->destination_file_name)){ - //ssp_error("file already exists, overwriting it\n"); COPY TEMP FILE TO THIS FILE - req->file = create_file(req->destination_file_name, 1); - } - if (req->file == NULL) { - //ssp_printf("creating file: %s\n", req->destination_file_name); + char temp[75]; + req->received_metadata = 1; + + if (req->file == NULL) req->file = create_file(req->destination_file_name, 1); - } - req->received_metadata = 1; + else if (req->file->is_temp) { + snprintf(temp, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); + change_tempfile_to_actual(temp, req->destination_file_name, req->file_size, req->file); + return 1; + } - //add offset for naks - Offset *offset = ssp_alloc(1, sizeof(Offset)); - offset->end = req->file_size; - offset->start = 0; - //transmission mode 1 is unacknowledged, therefor no offsets if (req->transmission_mode == 1) return 1; + ssp_printf("mode acknowledged, building offset map\n"); + Offset *offset = ssp_alloc(1, sizeof(Offset)); + offset->end = req->file_size; + offset->start = 0; req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); return 1; @@ -518,12 +518,10 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien if (packet_index == -1) return; - Pdu_header *header = (Pdu_header *) packet; - uint16_t incoming_packet_data_len = ntohs(header->PDU_data_field_len); + //Pdu_header *header = (Pdu_header *) packet; + //uint16_t incoming_packet_data_len = ntohs(header->PDU_data_field_len); uint8_t directive = packet[packet_index]; packet_index += 1; - //respond - uint32_t data_len, start = 0; switch(directive) { case FINISHED_PDU: @@ -540,18 +538,35 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien req->received_eof = 1; } break; - case NAK_METADATA: - ssp_printf("resending metadata\n"); - start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - data_len = build_put_packet_metadata(res, packet_index, req); - set_data_length(res.msg, data_len); - ssp_sendto(res); + case NAK_DIRECTIVE: + switch (packet[packet_index]) + { + case META_DATA_PDU: + ssp_printf("resending metadata\n"); + req->type = put; + break; + + case EOF_PDU: + ssp_printf("resending eof\n"); + req->type = eof; + break; + + default: + break; + } + break; default: break; } } +static void check_req_status(Request *req, Client *client) { + if (req->resent_finished == 3) { + ssp_printf("file successfully sent\n"); + ssp_thread_cancel(client->client_handle); + } +} //current user request, to send to remote void user_request_handler(Response res, Request *req, Client* client) { @@ -568,6 +583,7 @@ void user_request_handler(Response res, Request *req, Client* client) { uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); uint32_t data_len = 0; + check_req_status(req, client); switch (req->type) { case eof: @@ -577,10 +593,15 @@ void user_request_handler(Response res, Request *req, Client* client) { break; case sending_data: - if (build_data_packet(res.msg, start, req->file, client->packet_len)) + if (req->sent_first_data_round == 1) + return; + + if (build_data_packet(res.msg, start, req->file, client->packet_len)) { req->type = eof; + req->sent_first_data_round = 1; + + } ssp_sendto(res); - break; case put: @@ -590,13 +611,8 @@ void user_request_handler(Response res, Request *req, Client* client) { break; case finished: - if (req->resent_finished == 3) { - ssp_printf("file successfully sent\n"); - ssp_thread_cancel(client->client_handle); - break; - } - start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); data_len = build_ack(res.msg, start, FINISHED_PDU, req); + set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_finished++; break; @@ -615,26 +631,31 @@ void user_request_handler(Response res, Request *req, Client* client) { void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { res.msg = req->buff; - if (req->type == none) return; if (req->buff == NULL) ssp_printf("req buffer is null, couldn't process timeout request\n"); - uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); uint16_t data_len = 0; - Pdu_header *pdu_header = (Pdu_header *) &res.msg; + //Pdu_header *pdu_header = (Pdu_header *) &res.msg; //send request for metadata if (!req->received_metadata) { ssp_printf("sending request for new metadata packet\n"); - data_len = build_nak_metadata(res.msg, start, req); + data_len = build_nak_directive(res.msg, start, META_DATA_PDU); + //set_data_length(res.msg, data_len); ssp_sendto(res); return; } + //send missing eofs + if (!req->received_eof) { + build_nak_directive(res.msg, start, EOF_PDU); + ssp_sendto(res); + } + //send missing NAKS if (req->file->missing_offsets->count > 0) { ssp_printf("sending Nak data\n"); @@ -642,11 +663,12 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { ssp_sendto(res); return; } - + //received EOF, send back 3 eof packets if (req->received_eof && req->resent_eof < 3) { ssp_printf("sending eof ack\n"); data_len = build_ack(res.msg, start, EOF_PDU, req); + //set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_eof++; } @@ -655,6 +677,7 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { if (req->resent_finished < 3 && req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { ssp_printf("sending finsihed pdu\n"); data_len = build_finished_pdu(res.msg, start, req); + //set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_finished++; } @@ -677,10 +700,13 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques //process file data if (header->PDU_type == 1) { if (!req->received_metadata) { + if (req->file == NULL) { + snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); + ssp_printf("haven't received metadata yet, building temperary file %s\n", req->source_file_name); + req->file = create_temp_file(req->source_file_name); + } request_metadata(req, res); - return; } - //this will only write data if first received a metadata packet write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); return; } @@ -688,7 +714,6 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; packet_index++; - switch (directive->directive_code) { case META_DATA_PDU: @@ -770,7 +795,7 @@ int put_request(char *source_file_name, //enumeration req->type = put; - + req->dest_cfdp_id = client->cfdp_id; req->file_size = file_size; diff --git a/Program/src/utils.c b/Program/src/utils.c index 737be63..a5fc124 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -130,17 +130,20 @@ static void freeNode(NODE *node) { static void *pop(List *list) { + if (list->count == 0) + return; + NODE *last_data_node = list->tail->prev; if (last_data_node == NULL) return NULL; - - void *element = last_data_node->element; NODE *prev = last_data_node->prev; prev->next = list->tail; + list->tail->prev = prev; - freeNode(last_data_node); list->count--; + void *element = last_data_node->element; + freeNode(last_data_node); return element; } @@ -157,12 +160,14 @@ static int insert(List *list, void *element, uint32_t id) { if (node == NULL) { return 0; } + if (list->count == 0) { + list->tail->prev = node; + } node->next = head->next; node->prev = head; head->next = node; - head->prev = NULL; list->count++; return 1; } @@ -186,6 +191,10 @@ static int push(List *list, void *element, uint32_t id) tail->prev->next = newNode; tail->prev = newNode; + + if (list->count == 0) { + list->head->next = newNode; + } list->count++; return 1; @@ -368,7 +377,9 @@ List *linked_list() NODE *head = newList->head; tail->prev = head; + tail->next = NULL; head->next = tail; + head->prev = NULL; newList->push = push; newList->remove = removeElement; From 23295e73c612a9a3b9e34010be06b7b48ed70019 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 25 May 2019 11:07:12 -0600 Subject: [PATCH 049/400] quick update before refactoring --- Program/include/port.h | 2 +- Program/include/protocol_handler.h | 2 ++ Program/src/main.c | 5 ++++- Program/src/port.c | 6 +++++- Program/src/protocol_handler.c | 6 +++--- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index cdfa8ab..b869963 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -22,7 +22,7 @@ void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); -void ssp_cleanup_req(Request *req); +void ssp_cleanup_req(void *request); void ssp_print_hex(char *stuff, uint32_t size); int ssp_open(char *pathname, int flags); int ssp_read(int fd, char* buff, size_t size); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 0f0c0b2..159c58b 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -104,6 +104,7 @@ typedef struct client { uint32_t packet_len; Request *req; + List *req_queue; //can get rid of these, these are found in mib_info anyway uint32_t cfdp_id; @@ -132,6 +133,7 @@ uint8_t build_ack (char *packet, uint32_t start, uint8_t type, Request *req); int process_file_request_metadata(Request *req); int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client); void set_data_length(char*packet, uint16_t data_len); +uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); /* unsigned char *source_file_name, unsigned char *destination_file_name, diff --git a/Program/src/main.c b/Program/src/main.c index 7eadc4b..89523df 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -74,7 +74,10 @@ int main(int argc, char** argv) { //send via acknoleged mode //0 acknowledged, 1 unacknowledged //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + //will block on pthread_join ssp_cleanup_client(new_client); diff --git a/Program/src/port.c b/Program/src/port.c index d092d49..f4f7240 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -325,6 +325,7 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { checkAlloc(client, 1); client->req = init_request(PACKET_LEN); + client->req_queue = linked_list(); pthread_t *handler = calloc(sizeof(pthread_t), 1); checkAlloc(handler, 1); @@ -413,7 +414,9 @@ void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header); } -void ssp_cleanup_req(Request *req) { +void ssp_cleanup_req(void *request) { + + Request *req = (Request *) request; if (req->file != NULL) free_file(req->file); @@ -456,6 +459,7 @@ void ssp_cleanup_client(Client *client) { pthread_join(*handle, NULL); #endif + client->req_queue->free(client->req_queue, ssp_cleanup_req); ssp_cleanup_req(client->req); ssp_free(client->client_handle); ssp_free(client->client_thread_attributes); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 9bb4831..2c8a655 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -243,9 +243,7 @@ static void fill_nak_array(void *element, void *args){ holder->i++; } - - -static uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { +uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet[start] = NAK_PDU; uint32_t packet_index = start + 1; @@ -809,5 +807,7 @@ int put_request(char *source_file_name, req->messages_to_user = messages_to_user; req->filestore_requests = filestore_requests; + client->req_queue->insert(client->req_queue, req, p_state->transaction_sequence_number); + return 0; } From 32bbdbc58020623f91e8c241aef1dba114edb2bc Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 26 May 2019 12:35:48 -0600 Subject: [PATCH 050/400] reverted some code, figuring out what happeneds when req === NULL --- Program/include/list_callbacks.h | 15 ------ Program/include/protocol_handler.h | 69 +--------------------------- Program/include/requests.h | 73 ++++++++++++++++++++++++++++++ Program/src/filesystem_funcs.c | 1 - Program/src/list_callbacks.c | 26 ----------- Program/src/main.c | 8 ++-- Program/src/makefile | 2 +- Program/src/port.c | 52 +++++++++++++++------ Program/src/protocol_handler.c | 73 +++++------------------------- Program/src/requests.c | 59 ++++++++++++++++++++++++ Program/src/utils.c | 13 ++---- Program/test/main.c | 34 ++++++++------ 12 files changed, 213 insertions(+), 212 deletions(-) delete mode 100644 Program/include/list_callbacks.h create mode 100644 Program/include/requests.h delete mode 100644 Program/src/list_callbacks.c create mode 100644 Program/src/requests.c diff --git a/Program/include/list_callbacks.h b/Program/include/list_callbacks.h deleted file mode 100644 index 8798f67..0000000 --- a/Program/include/list_callbacks.h +++ /dev/null @@ -1,15 +0,0 @@ - - -#ifndef LIST_CALLBACKS_H -#define LIST_CALLBACKS_H - - - int client_cleanup_list(void *element); - int client_list_remove(void *element, void *args); - void client_list_print(void *element, void *args); - int client_list_find(void *element, void *args); - void client_list_free(void *element); - -#endif - - diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 159c58b..e995c22 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -6,74 +6,7 @@ #include "packet.h" #include "mib.h" #include "filesystem_funcs.h" - -typedef struct response { - int sfd; - //this is a pointer to buff in a request - char *msg; - //this is type (struct sockaddr_in) in posix - void *addr; - //getting rid of this soon in favour of client based packet sizes - uint32_t packet_len; - -} Response; - -typedef enum Indication { - finished, - none, - transaction, - put, - eof, - //sending data - sending_data - -} Indication; - -//incoming requests spin up requests -typedef struct request { - Indication type; - uint64_t transaction_sequence_number; - uint32_t dest_cfdp_id; - - File *file; - uint32_t file_size; - - char *source_file_name; - char *destination_file_name; - - uint32_t packet_data_len; - - uint8_t segmentation_control; - uint8_t fault_handler_overides; - uint8_t flow_lable; - uint8_t transmission_mode; - - uint8_t received_metadata; - uint8_t received_eof; - //counter for resending eof packets == 3 - uint8_t resent_eof; - uint8_t received_finished; - //counter for resending finished packets == 3 - uint8_t resent_finished; - //bool for sending first blast of data packets - uint8_t sent_first_data_round; - - char* messages_to_user; - char* filestore_requests; - - //sets the buffer length, for making packets - uint32_t buff_len; - - //buffer for making packets - char* buff; - - //header for building response packets - Pdu_header *pdu_header; - - //handler for sending responses back - Response res; -} Request; - +#include "requests.h" typedef struct protocol_state { uint32_t packet_size; diff --git a/Program/include/requests.h b/Program/include/requests.h new file mode 100644 index 0000000..0727e1d --- /dev/null +++ b/Program/include/requests.h @@ -0,0 +1,73 @@ + +#ifndef REQUESTS_H +#define REQUESTS_H + +#include "stdint.h" +typedef struct response { + int sfd; + //this is a pointer to buff in a request + char *msg; + //this is type (struct sockaddr_in) in posix + void *addr; + //getting rid of this soon in favour of client based packet sizes + uint32_t packet_len; + +} Response; + +typedef enum Indication { + finished, + none, + transaction, + put, + eof, + //sending data + sending_data + +} Indication; + +//incoming requests spin up requests +typedef struct request { + Indication type; + uint64_t transaction_sequence_number; + uint32_t dest_cfdp_id; + + File *file; + uint32_t file_size; + + char *source_file_name; + char *destination_file_name; + + uint32_t packet_data_len; + + uint8_t segmentation_control; + uint8_t fault_handler_overides; + uint8_t flow_lable; + uint8_t transmission_mode; + + uint8_t received_metadata; + uint8_t received_eof; + //counter for resending eof packets == 3 + uint8_t resent_eof; + uint8_t received_finished; + //counter for resending finished packets == 3 + uint8_t resent_finished; + //bool for sending first blast of data packets + uint8_t sent_first_data_round; + + char* messages_to_user; + char* filestore_requests; + + //sets the buffer length, for making packets + uint32_t buff_len; + + //buffer for making packets + char* buff; + + //header for building response packets + Pdu_header *pdu_header; + + //handler for sending responses back + Response res; +} Request; + +#endif \ No newline at end of file diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 9b1cc91..ba54b61 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -128,7 +128,6 @@ void free_file(void *file) { File *f = (File *) file; f->missing_offsets->free(f->missing_offsets, ssp_free); - ssp_free(f); } diff --git a/Program/src/list_callbacks.c b/Program/src/list_callbacks.c deleted file mode 100644 index aea10f8..0000000 --- a/Program/src/list_callbacks.c +++ /dev/null @@ -1,26 +0,0 @@ - - -#include "list_callbacks.h" -#include "protocol_handler.h" -#include "stdlib.h" -#include "port.h" - -void client_list_free(void *element) { - Client *client = (Client * ) element; - - ssp_cleanup_client(client); -} - -void client_list_print(void *element, void *args) { - -} - - -int client_list_find(void *element, void *args) { -/* - int id = *(int *) args; - if (id == ((struct myStruct*) element)->id) - return 1; - return 0; - */ -} diff --git a/Program/src/main.c b/Program/src/main.c index 89523df..5857a94 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -7,7 +7,6 @@ #include #include "protocol_handler.h" #include "utils.h" -#include "list_callbacks.h" #include "server.h" #include "mib.h" @@ -66,21 +65,20 @@ int main(int argc, char** argv) { p_state->verbose_level = conf->verbose_level; //create a client - if (conf->client_cfdp_id != 0){ //ssp_printf("input a src file:\n"); Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged - //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + //put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); //will block on pthread_join ssp_cleanup_client(new_client); + ssp_printf("segfault here?\n"); ssp_printf("client disconnected\n"); } diff --git a/Program/src/makefile b/Program/src/makefile index 498d3ff..4004d1f 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -8,10 +8,10 @@ CFILES += port.c CFILES += utils.c CFILES += server.c #used for poxix port CFILES += protocol_handler.c -CFILES += list_callbacks.c CFILES += mib.c CFILES += filesystem_funcs.c CFILES += ringbuf.c +CFILES += requests.c #----------------------------test files------------------------- CFILES += $(PROJDIR)/test/test.c diff --git a/Program/src/port.c b/Program/src/port.c index f4f7240..2b33fdd 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -151,12 +151,16 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct soc #endif Client *client = (Client *) other; - + /* + if (client->req == NULL) + return; + */ Response res; res.addr = posix_client; res.sfd = sfd; res.packet_len = *buff_size; res.msg = client->req->buff; + parse_packet_client(packet, res, client->req, client); return 0; @@ -172,6 +176,20 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { Response res; Client *client = (Client *) other; + + + /* + client->req = client->req_queue->pop(client->req_queue); + if (client->req == NULL) { + client->req = client->req_queue->pop(client->req_queue); + ssp_printf("popping new request\n"); + } + if (client->req == NULL){ + ssp_printf("client->req == null\n"); + return; + } + */ + res.sfd = sfd; res.packet_len = client->packet_len; res.msg = client->req->buff; @@ -179,8 +197,6 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { user_request_handler(res, client->req, client); return 0; - - } //this function is a callback when using my posix ports @@ -324,7 +340,7 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { Client *client = calloc(sizeof(Client), 1); checkAlloc(client, 1); - client->req = init_request(PACKET_LEN); + client->req = NULL; client->req_queue = linked_list(); pthread_t *handler = calloc(sizeof(pthread_t), 1); @@ -351,6 +367,7 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { client->packet_len = PACKET_LEN; client->cfdp_id = cfdp_id; + List *entity_list = p_state->mib->remote_entities; Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); @@ -417,17 +434,23 @@ void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { void ssp_cleanup_req(void *request) { Request *req = (Request *) request; + + if (req == NULL) + return; if (req->file != NULL) free_file(req->file); - if (req->pdu_header != NULL) ssp_cleanup_pdu_header(req->pdu_header); - - ssp_free(req->res.addr); - ssp_free(req->source_file_name); - ssp_free(req->destination_file_name); - ssp_free(req->buff); + if (req->res.addr != NULL) + ssp_free(req->res.addr); + if (req->source_file_name != NULL) + ssp_free(req->source_file_name); + if (req->destination_file_name != NULL) + ssp_free(req->destination_file_name); + if (req->buff != NULL) + ssp_free(req->buff); ssp_free(req); + } @@ -438,7 +461,9 @@ void ssp_cleanup(Protocol_state *p_state) { pthread_t * handle = (pthread_t*) p_state->server_handle; pthread_join(*handle, NULL); - p_state->request_list->free( p_state->request_list, ssp_cleanup_req); + #endif + + p_state->request_list->free(p_state->request_list, ssp_cleanup_req); ssp_cleanup_req(p_state->current_server_request); free_mib(p_state->mib); ssp_free(p_state->server_handle); @@ -446,8 +471,6 @@ void ssp_cleanup(Protocol_state *p_state) { ssp_free(p_state->server_thread_attributes); ssp_free(p_state); - #endif - } @@ -459,7 +482,10 @@ void ssp_cleanup_client(Client *client) { pthread_join(*handle, NULL); #endif + ssp_printf("segfault, \n"); client->req_queue->free(client->req_queue, ssp_cleanup_req); + + ssp_printf("segfault, \n"); ssp_cleanup_req(client->req); ssp_free(client->client_handle); ssp_free(client->client_thread_attributes); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2c8a655..296c2c4 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -5,6 +5,8 @@ #include "string.h" #include "packet.h" #include "filesystem_funcs.h" +#include "requests.h" + //snprintf #include @@ -390,6 +392,8 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state packet_index += header->length_of_entity_IDs; if (p_state->my_cfdp_id != dest_id){ + + ssp_printf("sequence number: %u should be %u\n", p_state->my_cfdp_id, transaction_sequence_number); ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", p_state->my_cfdp_id, dest_id); return -1; } @@ -525,10 +529,12 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien case FINISHED_PDU: req->received_finished = 1; req->type = finished; + ssp_printf("received finished pdu\n"); break; case NAK_PDU: req->received_metadata = 1; nak_response(packet, packet_index, req, res, client); + ssp_printf("received Nak pdu\n"); break; case ACK_PDU: if (packet[packet_index] == EOF_PDU) { @@ -561,15 +567,16 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien static void check_req_status(Request *req, Client *client) { if (req->resent_finished == 3) { - ssp_printf("file successfully sent\n"); - ssp_thread_cancel(client->client_handle); + req->type = none; + //ssp_cleanup_req(client->req); + //client->req = NULL; } } //current user request, to send to remote void user_request_handler(Response res, Request *req, Client* client) { - if (req->type == none) + if (req == NULL || req->type == none) return; if (res.msg == NULL) { @@ -613,6 +620,7 @@ void user_request_handler(Response res, Request *req, Client* client) { set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_finished++; + break; default: @@ -752,62 +760,3 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques memset(packet, 0, packet_len); } - - - -/*------------------------------------------------------------------------------ - - USER STUFF - aka: request from person - -------------------------------------------------------------------------------*/ - - - - -//Omission of source and destination filenames shall indicate that only Meta -//data will be delivered -int put_request(char *source_file_name, - char *destination_file_name, - uint8_t segmentation_control, - uint8_t fault_handler_overides, - uint8_t flow_lable, - uint8_t transmission_mode, - char* messages_to_user, - char* filestore_requests, - Client *client, - Protocol_state *p_state - ) { - - uint32_t file_size = get_file_size(source_file_name); - - if (file_size == -1) - return -1; - - //give the client a new request to perform - Request *req = client->req; - req->file = create_file(source_file_name, 0); - - //build a request - req->transaction_sequence_number = p_state->transaction_sequence_number++; - - //enumeration - req->type = put; - - req->dest_cfdp_id = client->cfdp_id; - req->file_size = file_size; - - memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); - memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); - - req->segmentation_control = segmentation_control; - req->fault_handler_overides = fault_handler_overides; - req->flow_lable = flow_lable; - req->transmission_mode = transmission_mode; - req->messages_to_user = messages_to_user; - req->filestore_requests = filestore_requests; - - client->req_queue->insert(client->req_queue, req, p_state->transaction_sequence_number); - - return 0; -} diff --git a/Program/src/requests.c b/Program/src/requests.c new file mode 100644 index 0000000..1005811 --- /dev/null +++ b/Program/src/requests.c @@ -0,0 +1,59 @@ + + +/*------------------------------------------------------------------------------ + + USER STUFF + aka: request from person + +------------------------------------------------------------------------------*/ +#include "stdint.h" +#include "protocol_handler.h" +#include "port.h" +#include + +//Omission of source and destination filenames shall indicate that only Meta +//data will be delivered +int put_request(char *source_file_name, + char *destination_file_name, + uint8_t segmentation_control, + uint8_t fault_handler_overides, + uint8_t flow_lable, + uint8_t transmission_mode, + char* messages_to_user, + char* filestore_requests, + Client *client, + Protocol_state *p_state + ) { + + uint32_t file_size = get_file_size(source_file_name); + + if (file_size == -1) + return -1; + + //give the client a new request to perform + Request *req = init_request(client->packet_len); + req->file = create_file(source_file_name, 0); + + //build a request + req->transaction_sequence_number = p_state->transaction_sequence_number++; + + //enumeration + req->type = put; + + req->dest_cfdp_id = client->cfdp_id; + req->file_size = file_size; + + memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + + req->segmentation_control = segmentation_control; + req->fault_handler_overides = fault_handler_overides; + req->flow_lable = flow_lable; + req->transmission_mode = transmission_mode; + req->messages_to_user = messages_to_user; + req->filestore_requests = filestore_requests; + + //client->req_queue->insert(client->req_queue, req, p_state->transaction_sequence_number); + client->req = req; + return 0; +} diff --git a/Program/src/utils.c b/Program/src/utils.c index a5fc124..822f584 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -131,12 +131,10 @@ static void freeNode(NODE *node) { static void *pop(List *list) { if (list->count == 0) - return; - - NODE *last_data_node = list->tail->prev; - if (last_data_node == NULL) return NULL; + NODE *last_data_node = list->tail->prev; + NODE *prev = last_data_node->prev; prev->next = list->tail; list->tail->prev = prev; @@ -160,11 +158,9 @@ static int insert(List *list, void *element, uint32_t id) { if (node == NULL) { return 0; } - if (list->count == 0) { - list->tail->prev = node; - } node->next = head->next; + node->next->prev = node; node->prev = head; head->next = node; @@ -263,7 +259,8 @@ static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void static void freeList(List *list, void (*f)(void *element)) { NODE *cur = list->head->next; - while (cur->next != NULL ) + + while (cur->next != NULL && cur->element != NULL) { NODE *n = cur; cur = cur->next; diff --git a/Program/test/main.c b/Program/test/main.c index f8a45fe..f9b78cd 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -50,6 +50,7 @@ static int find(void *element, void *args) { static void list_free(void *element) { + free(element); } @@ -57,7 +58,6 @@ static void list_free(void *element) { int main () { - MIB *mib = init_mib(); //setting host name for testing @@ -78,16 +78,22 @@ int main () { Pdu_header *header = get_header_from_mib(mib, 2222, 1315); - packet_tests(header); - free_mib(mib); - ssp_cleanup_pdu_header(header); + //packet_tests(header); + + request_test_list_storage(); + free_mib(mib); + ssp_cleanup_pdu_header(header); + + + + @@ -172,7 +178,7 @@ int main () { printf("%c%c\n", *ptr[0], *ptr[1]); - + */ List *list = linked_list(); //static void *findElement(List *list, int (*f)(void *element, void *args), void *args) @@ -190,15 +196,15 @@ int main () { st3->id = 3; st3->b = 4; - list->push(list, st, 1); - list->push(list, st2, 2); + list->insert(list, st, 1); + list->insert(list, st2, 2); list->push(list, st3, 3); - - list->pop(list); + list->push(list, list->pop(list), list->count); list->print(list, list_print, NULL); printf("\n\n"); + /* list->insert(list, st3, 3); list->print(list, list_print, NULL); @@ -215,12 +221,14 @@ int main () { found = list->find(list, 3, NULL, NULL); printf("found %d\n", found->id); - free(list->remove(list, "3", NULL, NULL)); - free(list->remove(list, "2", NULL, NULL)); + void * element = list->pop(list); + //free(list->remove(list, "3", NULL, NULL)); + //free(list->remove(list, "2", NULL, NULL)); - list->print(list, list_print, NULL); + list->print(list, list_print, NULL); + */ list->free(list, list_free); - */ + return 0; } \ No newline at end of file From 51c3bdb4bd30d83e486445d5f26b86207c5c2b41 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 26 May 2019 15:04:06 -0600 Subject: [PATCH 051/400] basic reset of requests --- Program/include/protocol_handler.h | 22 +++------------ Program/include/requests.h | 3 ++ Program/src/main.c | 5 ++-- Program/src/port.c | 45 ++++++++++++++---------------- Program/src/protocol_handler.c | 30 +++++++++++++++----- Program/src/requests.c | 5 ++-- Program/test/packet_tests.c | 13 +-------- Program/test/request_tests.c | 37 ++++++++++++++++++++++++ Program/test/request_tests.h | 15 ++++++++++ 9 files changed, 109 insertions(+), 66 deletions(-) create mode 100644 Program/test/request_tests.c create mode 100644 Program/test/request_tests.h diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index e995c22..f805899 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -24,7 +24,7 @@ typedef struct protocol_state { uint32_t transaction_sequence_number; uint8_t verbose_level; - + uint32_t timeout; } Protocol_state; @@ -67,20 +67,9 @@ int process_file_request_metadata(Request *req); int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client); void set_data_length(char*packet, uint16_t data_len); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); -/* - unsigned char *source_file_name, - unsigned char *destination_file_name, - uint8_t segmentation_control, - uint8_t fault_handler_overides, - uint8_t flow_lable, - uint8_t transmission_mode, - unsigned char* messages_to_user, - unsigned char* filestore_requests, - Client *client, - Protocol_state *p_state -*/ -//returns -1 on error -int put_request( + + +Request *put_request( char *source_file_name, char *destination_file_name, uint8_t segmentation_control, @@ -93,7 +82,4 @@ int put_request( Protocol_state *p_state ); - - - #endif \ No newline at end of file diff --git a/Program/include/requests.h b/Program/include/requests.h index 0727e1d..54da508 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -3,6 +3,8 @@ #define REQUESTS_H #include "stdint.h" +#include "protocol_handler.h" + typedef struct response { int sfd; //this is a pointer to buff in a request @@ -70,4 +72,5 @@ typedef struct request { Response res; } Request; + #endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index 5857a94..b6182a5 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -9,7 +9,7 @@ #include "utils.h" #include "server.h" #include "mib.h" - +#include "requests.h" #include "packet.h" //for itoa @@ -72,13 +72,12 @@ int main(int argc, char** argv) { //send via acknoleged mode //0 acknowledged, 1 unacknowledged put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); //put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - //will block on pthread_join ssp_cleanup_client(new_client); - ssp_printf("segfault here?\n"); ssp_printf("client disconnected\n"); } diff --git a/Program/src/port.c b/Program/src/port.c index 2b33fdd..ed10275 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -151,16 +151,14 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct soc #endif Client *client = (Client *) other; - /* if (client->req == NULL) - return; - */ + return 0; + Response res; res.addr = posix_client; res.sfd = sfd; res.packet_len = *buff_size; res.msg = client->req->buff; - parse_packet_client(packet, res, client->req, client); return 0; @@ -176,19 +174,8 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { Response res; Client *client = (Client *) other; - - - /* - client->req = client->req_queue->pop(client->req_queue); - if (client->req == NULL) { - client->req = client->req_queue->pop(client->req_queue); - ssp_printf("popping new request\n"); - } - if (client->req == NULL){ - ssp_printf("client->req == null\n"); - return; - } - */ + if (client->req == NULL) + return 0; res.sfd = sfd; res.packet_len = client->packet_len; @@ -282,7 +269,6 @@ Protocol_state* ssp_connectionless_server(char *port) { strncpy ((char*)state->server_port, port, 10); - state->request_list = linked_list(); int err = pthread_attr_init(attr); @@ -300,7 +286,7 @@ Protocol_state* ssp_connectionless_server(char *port) { printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); } - err = pthread_create(handler, attr, ssp_connectionless_server_task, state); + err = pthread_create(handler, attr, ssp_connectionless_server_task, state); if (0 != err) perror("ERROR pthread_create"); @@ -397,8 +383,22 @@ void reset_request(Request *req){ memset(req->destination_file_name, 0, MAX_PATH); memset(req->buff, 0, req->buff_len); memset(req->res.addr, 0, sizeof(struct sockaddr_in)); - free_file(req->file); - + req->dest_cfdp_id = 0; + req->fault_handler_overides = 0; + req->file_size = 0; + req->flow_lable = 0; + req->received_eof = 0; + req->received_finished = 0; + req->received_metadata = 0; + req->resent_eof = 0; + req->resent_finished = 0; + req->segmentation_control = 0; + req->transaction_sequence_number = 0; + req->transmission_mode = 1; + req->type = none; + if (req->file != NULL) + free_file(req->file); + req->file = NULL; req->type = none; } @@ -482,10 +482,7 @@ void ssp_cleanup_client(Client *client) { pthread_join(*handle, NULL); #endif - ssp_printf("segfault, \n"); client->req_queue->free(client->req_queue, ssp_cleanup_req); - - ssp_printf("segfault, \n"); ssp_cleanup_req(client->req); ssp_free(client->client_handle); ssp_free(client->client_thread_attributes); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 296c2c4..c750960 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -357,11 +357,6 @@ int process_file_request_metadata(Request *req) { change_tempfile_to_actual(temp, req->destination_file_name, req->file_size, req->file); return 1; } - - //transmission mode 1 is unacknowledged, therefor no offsets - if (req->transmission_mode == 1) - return 1; - ssp_printf("mode acknowledged, building offset map\n"); Offset *offset = ssp_alloc(1, sizeof(Offset)); @@ -398,6 +393,7 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state return -1; } + uint16_t packet_data_len = ntohs(header->PDU_data_field_len); req->packet_data_len = packet_data_len; @@ -592,6 +588,7 @@ void user_request_handler(Response res, Request *req, Client* client) { switch (req->type) { case eof: + ssp_printf("sending eof\n"); req->type = none; build_eof_packet(res.msg, start, req); ssp_sendto(res); @@ -600,22 +597,25 @@ void user_request_handler(Response res, Request *req, Client* client) { case sending_data: if (req->sent_first_data_round == 1) return; - + + if (build_data_packet(res.msg, start, req->file, client->packet_len)) { req->type = eof; req->sent_first_data_round = 1; - + ssp_printf("sending data blast\n"); } ssp_sendto(res); break; case put: + ssp_printf("sending metadata\n"); start = build_put_packet_metadata(res, start, req); ssp_sendto(res); req->type = sending_data; break; case finished: + ssp_printf("sending finished packet\n"); data_len = build_ack(res.msg, start, FINISHED_PDU, req); set_data_length(res.msg, data_len); ssp_sendto(res); @@ -647,6 +647,12 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { uint16_t data_len = 0; //Pdu_header *pdu_header = (Pdu_header *) &res.msg; + if (req->resent_finished == 3) { + reset_request(req); + ssp_printf("file sent, resetting request\n"); + return; + } + //send request for metadata if (!req->received_metadata) { ssp_printf("sending request for new metadata packet\n"); @@ -662,6 +668,7 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { ssp_sendto(res); } + ssp_printf("missing offsets %u\n", req->file->missing_offsets->count); //send missing NAKS if (req->file->missing_offsets->count > 0) { ssp_printf("sending Nak data\n"); @@ -686,6 +693,15 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { //set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_finished++; + return; + } + + uint32_t time = p_state->timeout++; + ssp_printf("timeout %u\n", time); + if (time == 20) { + p_state->timeout = 0; + reset_request(req); + ssp_printf("timeout, resetting request\n"); } } diff --git a/Program/src/requests.c b/Program/src/requests.c index 1005811..27b8bd7 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -13,7 +13,7 @@ //Omission of source and destination filenames shall indicate that only Meta //data will be delivered -int put_request(char *source_file_name, +Request *put_request(char *source_file_name, char *destination_file_name, uint8_t segmentation_control, uint8_t fault_handler_overides, @@ -55,5 +55,6 @@ int put_request(char *source_file_name, //client->req_queue->insert(client->req_queue, req, p_state->transaction_sequence_number); client->req = req; - return 0; + + return req; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 90b7eeb..3162b8c 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -6,6 +6,7 @@ #include #include "filesystem_funcs.h" #include "port.h" +#include "protocol_handler.h" #define PACKET_TEST_SIZE 2000 @@ -18,17 +19,6 @@ static int test_respond_to_naks(char *packet, uint32_t packet_index) { } static int test_respond_metadata_request() { - - //ssp_printf("input a src file:\n"); - Client *client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - - //send via acknoleged mode //0 acknowledged, 1 unacknowledged - //put_request("test.txt", "delivered_file.txt", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 0, NULL, NULL, client, p_state); - - uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - uint32_t data_len = build_put_packet_metadata(res, packet_index, req, client, p_state); - set_data_length(res.msg, data_len); } @@ -41,7 +31,6 @@ static int test_build_nak_packet(char* packet, uint32_t start) { printf("testing nak creation 1 \n"); Request *req = init_request(5000); - req->file_size = 100000; memcpy(req->destination_file_name, "testestest", 15); memcpy(req->source_file_name, "someotherfile", 15); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c new file mode 100644 index 0000000..ef44ca6 --- /dev/null +++ b/Program/test/request_tests.c @@ -0,0 +1,37 @@ +#include "protocol_handler.h" +#include "port.h" +#include "requests.h" +#include "string.h" + + +static void list_print(void *element, void *args) { + + Request *req = (Request *) element; + ssp_printf("%s\n", req->source_file_name); +} + + +void request_test_list_storage() { + Request *req = init_request(5000); + List *list = linked_list(); + + req->file = create_file("testfile.txt", 0); + memcpy(req->source_file_name, "stuff", 6); + list->insert(list, req, 1); + + Request *req2 = init_request(5000); + req2->file = create_file("testfile.txt", 0); + memcpy(req2->source_file_name, "stuff2", 7); + list->insert(list, req2, 2); + + Request *req3 = init_request(5000); + req3->file = create_file("testfile.txt", 0); + memcpy(req3->source_file_name, "stuff3", 7); + list->insert(list, req3, 3); + + + ssp_cleanup_req(list->pop(list)); + list->print(list, list_print, NULL); + list->free(list, ssp_cleanup_req); + +} \ No newline at end of file diff --git a/Program/test/request_tests.h b/Program/test/request_tests.h new file mode 100644 index 0000000..00e9932 --- /dev/null +++ b/Program/test/request_tests.h @@ -0,0 +1,15 @@ + +#ifndef PACKET_TEST_H +#define PACKET_TEST_H + + + + + + +void request_test_list_storage(); + + + + +#endif \ No newline at end of file From d7dcf4ba5fc1ca7ef8ac38e66709709fa7df977f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 27 May 2019 12:25:02 -0600 Subject: [PATCH 052/400] Update, fixed nak receive algo --- Program/include/filesystem_funcs.h | 2 +- Program/src/filesystem_funcs.c | 68 +++++++++++++----------------- Program/src/main.c | 8 +++- Program/src/protocol_handler.c | 28 ++++++------ Program/test/filesystem_tests.c | 31 ++++++++++++++ Program/test/main.c | 7 ++- 6 files changed, 87 insertions(+), 57 deletions(-) create mode 100644 Program/test/filesystem_tests.c diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 751c7e0..93a8e4b 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -4,7 +4,7 @@ #include #include "utils.h" -#define TEMP_FILESIZE 10000000 +#define TEMP_FILESIZE 1000 typedef struct offset { uint32_t start; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index ba54b61..e483553 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -179,7 +179,8 @@ static int find_nak(void *element, void* args) { Offset *offset_in_list = (Offset *) element; Offset *offset_to_insert = (Offset *) args; - if (offset_to_insert->start >= offset_in_list->start && offset_to_insert->end <= offset_in_list->end) { + if (offset_to_insert->start >= offset_in_list->start && offset_to_insert->start <= offset_in_list->end + && offset_to_insert->end <= offset_in_list->end && offset_to_insert->end >= offset_in_list->start) { return 1; } @@ -204,57 +205,48 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs Offset *offset_in_list = (Offset *) node->element; ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); - if (offset_in_list->start == offset_in_list->end) { + //remove node if both start and end are equal + if (offset_to_insert.start == offset_in_list->start && offset_to_insert.end == offset_in_list->end) { ssp_printf("removing node\n"); node->next->prev = node->prev; node->prev->next = node->next; ssp_free(node->element); ssp_free(node); nak_list->count--; + return 1; } - if (offset_to_insert.start > offset_to_insert.end) - return; - - //insert new node - if (offset_to_insert.start >= offset_in_list->start && offset_to_insert.end <= offset_in_list->end) { - - //remove node if both start and end are equal - if (offset_to_insert.start == offset_in_list->start && offset_to_insert.end == offset_in_list->end) { - ssp_printf("removing node\n"); - node->next->prev = node->prev; - node->prev->next = node->next; - ssp_free(node->element); - ssp_free(node); - nak_list->count--; - return; - } - - //if new offset is in the start, simply change the list's node's start - else if (offset_to_insert.start == offset_in_list->start && offset_to_insert.start < offset_in_list->end) { - offset_in_list->start = offset_to_insert.end; - return; - } + //if new offset is in the start, change the list's node's start + if (offset_to_insert.start == offset_in_list->start && offset_to_insert.start < offset_in_list->end) { + offset_in_list->start = offset_to_insert.end; + return 1; + } - Offset *new_offset = ssp_alloc(1, sizeof(Offset)); - new_offset->start = offset_start; - new_offset->end = offset_end; + if (offset_start == offset_in_list->end) + ssp_printf("END NODE CREATED\n"); - uint32_t tmp = new_offset->start; - new_offset->start = offset_in_list->start; - offset_in_list->start = new_offset->end; + Offset *new_offset = ssp_alloc(1, sizeof(Offset)); - new_offset->end = tmp; + new_offset->start = offset_in_list->start; + offset_in_list->start = offset_end; + new_offset->end = offset_start; - NODE *cur = node; - NODE *new = createNode(new_offset, new_offset->start); + NODE *cur = node; + NODE *new = createNode(new_offset, new_offset->start); - new->next = cur; - new->prev = cur->prev; - new->prev->next = new; - cur->prev = new; - nak_list->count++; + new->next = cur; + new->prev = cur->prev; + new->prev->next = new; + cur->prev = new; + nak_list->count++; + + //remove end node + if (offset_in_list->start == offset_in_list->end){ + ssp_printf("removing last node\n"); + ssp_free(nak_list->pop(nak_list)); } + + } File *create_temp_file(char *file_name) { diff --git a/Program/src/main.c b/Program/src/main.c index b6182a5..c450785 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -71,8 +71,14 @@ int main(int argc, char** argv) { Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged - put_request("pic.jpeg", "remote_pic.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + if (conf->client_cfdp_id == 1) + put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + + if (conf->client_cfdp_id == 2) + put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + + //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); //put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index c750960..aa1c887 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -562,8 +562,12 @@ void parse_packet_client(char *packet, Response res, Request *req, Client* clien } static void check_req_status(Request *req, Client *client) { - if (req->resent_finished == 3) { + if (req->resent_finished >= 3){ req->type = none; + } + if (req->resent_finished == 3) { + ssp_printf("file successfully sent\n"); + req->resent_finished = 4; //ssp_cleanup_req(client->req); //client->req = NULL; } @@ -598,7 +602,6 @@ void user_request_handler(Response res, Request *req, Client* client) { if (req->sent_first_data_round == 1) return; - if (build_data_packet(res.msg, start, req->file, client->packet_len)) { req->type = eof; req->sent_first_data_round = 1; @@ -620,7 +623,6 @@ void user_request_handler(Response res, Request *req, Client* client) { set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_finished++; - break; default: @@ -675,6 +677,16 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { build_nak_packet(res.msg, start, req); ssp_sendto(res); return; + + } else { + if (req->file->eof_checksum == req->file->partial_checksum){ + ssp_printf("sending finsihed pdu\n"); + data_len = build_finished_pdu(res.msg, start, req); + //set_data_length(res.msg, data_len); + ssp_sendto(res); + req->resent_finished++; + return; + } } //received EOF, send back 3 eof packets @@ -686,16 +698,6 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { req->resent_eof++; } - //send Finished, send back 3 finished packets - if (req->resent_finished < 3 && req->file->eof_checksum == req->file->partial_checksum && req->file->missing_offsets->count == 0) { - ssp_printf("sending finsihed pdu\n"); - data_len = build_finished_pdu(res.msg, start, req); - //set_data_length(res.msg, data_len); - ssp_sendto(res); - req->resent_finished++; - return; - } - uint32_t time = p_state->timeout++; ssp_printf("timeout %u\n", time); if (time == 20) { diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c new file mode 100644 index 0000000..2085256 --- /dev/null +++ b/Program/test/filesystem_tests.c @@ -0,0 +1,31 @@ +#include "filesystem_funcs.h" +#include "filesystem_tests.h" + + + +static void nak_print(void *element, void *args){ + Offset *offset = (Offset *)element; + ssp_printf("start: %u end: %u\n", offset->start, offset->end); +} + + + +static receive_offset_tests(){ + + File *file = create_temp_file("temp_test"); + + receive_offset(file, 0, 5, 50); + + file->missing_offsets->print(file->missing_offsets, nak_print, 0); + receive_offset(file, 0, 100, 1000); + + file->missing_offsets->print(file->missing_offsets, nak_print, 0); + receive_offset(file, 0, 50, 100); + file->missing_offsets->print(file->missing_offsets, nak_print, 0); + + +} + +int file_system_tests() { + receive_offset_tests(); +} \ No newline at end of file diff --git a/Program/test/main.c b/Program/test/main.c index f9b78cd..145f9da 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -13,6 +13,7 @@ #include "test.h" #include "mib.h" #include "packet_tests.h" +#include "filesystem_tests.h" struct myStruct { int id; @@ -80,8 +81,8 @@ int main () { //packet_tests(header); - - request_test_list_storage(); + file_system_tests(); + //request_test_list_storage(); @@ -201,8 +202,6 @@ int main () { list->push(list, st3, 3); list->push(list, list->pop(list), list->count); - list->print(list, list_print, NULL); - printf("\n\n"); /* list->insert(list, st3, 3); From 87abed9fd50f74593097d11015cfe69d80b7c250 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 27 May 2019 13:11:09 -0600 Subject: [PATCH 053/400] Add data_len to each packet --- Program/include/protocol_handler.h | 2 +- Program/src/filesystem_funcs.c | 4 +-- Program/src/protocol_handler.c | 56 +++++++++++++++++++----------- Program/test/filesystem_tests.h | 11 ++++++ 4 files changed, 50 insertions(+), 23 deletions(-) create mode 100644 Program/test/filesystem_tests.h diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index f805899..ab1740c 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -67,7 +67,7 @@ int process_file_request_metadata(Request *req); int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client); void set_data_length(char*packet, uint16_t data_len); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); - +uint16_t get_data_length(char*packet); Request *put_request( char *source_file_name, diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index e483553..97e00b3 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -199,7 +199,7 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs NODE * node = nak_list->findNode(nak_list, -1, find_nak, &offset_to_insert); if (node == NULL){ ssp_printf("no begining node for receive_offset, or offset we already received, can't add new offset\n"); - return; + return 0; } Offset *offset_in_list = (Offset *) node->element; @@ -245,7 +245,7 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs ssp_printf("removing last node\n"); ssp_free(nak_list->pop(nak_list)); } - + return 1; } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index aa1c887..d960476 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -68,12 +68,12 @@ static uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { data_len += 1; packet_index += 1; + set_data_length(packet, data_len); return data_len; } -static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req -) { +static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req) { Pdu_header *header = (Pdu_header *) res.msg; header->PDU_type = DIRECTIVE; @@ -117,10 +117,8 @@ static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request * memcpy(&res.msg[packet_index], destination_file_name, destination_file_length); packet_index += destination_file_length; - uint8_t total_bytes = packet_index - start; - - //mark the size of the packet - header->PDU_data_field_len = htons(total_bytes); + uint8_t data_len = packet_index - start; + set_data_length(res.msg, data_len); return packet_index; } @@ -147,8 +145,9 @@ static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, return 1; } - //add bytes read, and the packet offset to the data_field length - header->PDU_data_field_len = htons(bytes + 4); + uint16_t data_len = bytes + 4; + set_data_length(packet, data_len); + if (bytes < data_size) return 1; @@ -189,8 +188,10 @@ static uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint3 file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); file->next_offset_to_send += bytes; + //add bytes read, and the packet offset to the data_field length - header->PDU_data_field_len = htons(bytes + 4); + uint16_t data_len = bytes + 4; + set_data_length(packet, data_len); if (bytes < data_size) return 1; @@ -225,7 +226,8 @@ static void build_eof_packet(char *packet, uint32_t start, Request *req) { packet_index += 4; //TODO addTLV fault_location - header->PDU_data_field_len = htons(packet_index - start); + uint16_t data_len = htons(packet_index - start); + set_data_length(packet, data_len); } @@ -271,7 +273,10 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet_index += sizeof(Offset) * count; - return packet_index - start; + uint16_t data_len = packet_index - start; + set_data_length(packet, data_len); + + return data_len; } uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { @@ -283,19 +288,29 @@ uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { pdu_ack->directive_subtype_code = ACK_FINISHED_END; pdu_ack->condition_code = COND_NO_ERROR; packet_index += 2; - return packet_index - start; + uint16_t data_len = packet_index - start; + set_data_length(packet, data_len); + + return data_len; } static uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { uint8_t data_len = 2; packet[start] = NAK_DIRECTIVE; packet[start + 1] = directive; + + set_data_length(packet, data_len); return data_len; } void set_data_length(char*packet, uint16_t data_len){ Pdu_header *header = (Pdu_header*) packet; - header->PDU_data_field_len = data_len; + header->PDU_data_field_len = htons(data_len);; +} + +uint16_t get_data_length(char*packet) { + Pdu_header *header = (Pdu_header*) packet; + return ntohs(header->PDU_data_field_len); } /*------------------------------------------------------------------------------ @@ -311,7 +326,6 @@ static void request_metadata(Request *req, Response res) { uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); uint16_t data_len = 0; data_len = build_nak_directive(res.msg, start, META_DATA_PDU); - set_data_length(res.msg, data_len); ssp_sendto(res); return; } @@ -417,6 +431,9 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil uint32_t offset_start = packet->offset; uint32_t offset_end = offset_start + data_len - 4; + if (!receive_offset(file, 0, offset_start, offset_end)) + return; + int bytes = write_offset(file, &data_packet[4], data_len - 4, offset_start); if (bytes <= 0) { ssp_error("no new data was written\n"); @@ -428,7 +445,6 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil if (file->missing_offsets->count == 0) return; - receive_offset(file, 0, offset_start, offset_end); } @@ -620,7 +636,6 @@ void user_request_handler(Response res, Request *req, Client* client) { case finished: ssp_printf("sending finished packet\n"); data_len = build_ack(res.msg, start, FINISHED_PDU, req); - set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_finished++; break; @@ -659,14 +674,13 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { if (!req->received_metadata) { ssp_printf("sending request for new metadata packet\n"); data_len = build_nak_directive(res.msg, start, META_DATA_PDU); - //set_data_length(res.msg, data_len); ssp_sendto(res); return; } //send missing eofs if (!req->received_eof) { - build_nak_directive(res.msg, start, EOF_PDU); + data_len = build_nak_directive(res.msg, start, EOF_PDU); ssp_sendto(res); } @@ -679,21 +693,23 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { return; } else { + if (req->file->eof_checksum == req->file->partial_checksum){ ssp_printf("sending finsihed pdu\n"); data_len = build_finished_pdu(res.msg, start, req); - //set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_finished++; return; } + else { + ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); + } } //received EOF, send back 3 eof packets if (req->received_eof && req->resent_eof < 3) { ssp_printf("sending eof ack\n"); data_len = build_ack(res.msg, start, EOF_PDU, req); - //set_data_length(res.msg, data_len); ssp_sendto(res); req->resent_eof++; } diff --git a/Program/test/filesystem_tests.h b/Program/test/filesystem_tests.h new file mode 100644 index 0000000..c9684f3 --- /dev/null +++ b/Program/test/filesystem_tests.h @@ -0,0 +1,11 @@ +#ifndef FILESYSTEM_TESTS_H +#define FILESYSTEM_TESTS_H + + +#define TEMP_FILESIZE 1000 +int file_system_tests(); + + + + +#endif \ No newline at end of file From 903f6f0cd7f6bd5d81c31243c7afab708eeaefa7 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 29 May 2019 13:11:24 -0600 Subject: [PATCH 054/400] refactor port.c to tasks --- Program/include/mib.h | 1 + Program/include/port.h | 19 +- Program/include/protocol_handler.h | 2 - Program/include/requests.h | 4 +- Program/include/server.h | 4 +- Program/include/tasks.h | 33 +++ Program/include/utils.h | 1 + Program/src/filesystem_funcs.c | 6 +- Program/src/main.c | 1 + Program/src/makefile | 1 + Program/src/mib.c | 6 + Program/src/port.c | 403 +++-------------------------- Program/src/protocol_handler.c | 38 +-- Program/src/requests.c | 78 +++++- Program/src/server.c | 13 +- 15 files changed, 199 insertions(+), 411 deletions(-) create mode 100644 Program/include/tasks.h diff --git a/Program/include/mib.h b/Program/include/mib.h index a14ee53..12e40f5 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -91,5 +91,6 @@ MIB *init_mib(void); void free_mib(MIB *mib); int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port); Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); +void ssp_cleanup_pdu_header(Pdu_header *pdu_header); #endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index b869963..03fb2c8 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -4,26 +4,22 @@ #define STACK_ALLOCATION 16384 #define POSIX_PORT 1 +#define FREE_RTOS_PORT 1 + + #define MAX_PATH 255 #include "protocol_handler.h" void ssp_error( char *msg); -Protocol_state *ssp_connectionless_server(char *port); -void *ssp_connectionless_server_task(void *protocol_state); - -Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); -void *ssp_connectionless_client_task(void *params); void ssp_printf(char *stuff, ...); Request *init_request(uint32_t buff_len); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); -void ssp_cleanup(Protocol_state *state); -void ssp_cleanup_client(Client *client); -void ssp_cleanup_req(void *request); -void ssp_print_hex(char *stuff, uint32_t size); +void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); + int ssp_open(char *pathname, int flags); int ssp_read(int fd, char* buff, size_t size); int ssp_lseek(int fd, int offset, int whence); @@ -31,12 +27,9 @@ void ssp_error(char *error); int ssp_write(int fd, const void *buf, size_t count); int ssp_close(int fd); void ssp_free(void *pointer); +void ssp_thread_join(void *thread_handle); int ssp_rename(const char *old, const char *new); - -void ssp_thread_cancel(void *thread_handle); - -void ssp_cleanup_pdu_header(Pdu_header *pdu_header); void reset_request(Request *req); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index ab1740c..0a397d0 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -12,7 +12,6 @@ typedef struct protocol_state { uint32_t packet_size; char *server_port; void *server_handle; - void *server_thread_attributes; MIB *mib; uint32_t my_cfdp_id; @@ -33,7 +32,6 @@ typedef struct protocol_state { typedef struct client { void *client_handle; - void *client_thread_attributes; uint32_t packet_len; Request *req; diff --git a/Program/include/requests.h b/Program/include/requests.h index 54da508..4b46152 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -72,5 +72,7 @@ typedef struct request { Response res; } Request; - +void ssp_cleanup_req(void *request); +Request *init_request(uint32_t buff_len); +void reset_request(Request *req); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index 6d2bfd3..53239f1 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -43,7 +43,7 @@ int prepareUdpHost(char *port); ------------------------------------------------------------------------------*/ void udpSelectServer(char *port, int packet_len, - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_storage client, void *other), + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, void *addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), void *other); @@ -61,7 +61,7 @@ int *prepareSignalHandler(void); void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams)); + int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, void* addr, void *onRecvParams)); #endif //SERVER_H diff --git a/Program/include/tasks.h b/Program/include/tasks.h new file mode 100644 index 0000000..f8b2f2c --- /dev/null +++ b/Program/include/tasks.h @@ -0,0 +1,33 @@ + +#ifndef SSP_TASKS_H +#define SSP_TASKS_H + + + +#include "protocol_handler.h" + + +void ssp_cleanup(Protocol_state *state); +void ssp_cleanup_client(Client *client); +void ssp_cleanup_req(void *request); +Protocol_state *ssp_connectionless_server(char *port); +Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); +void *ssp_connectionless_client_task(void *params); + + + + + + + + + + + + + + + + + +#endif \ No newline at end of file diff --git a/Program/include/utils.h b/Program/include/utils.h index 609e0af..28af650 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -86,5 +86,6 @@ Config *configuration(int argc, char **argv); #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) NODE *createNode(void *element, uint32_t id); +void ssp_print_hex(char *stuff, int size); #endif //UTILS_H diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 97e00b3..bf79638 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -261,14 +261,14 @@ File *create_temp_file(char *file_name) { return file; } +/* static int print_nak(void *element, void* args) { Offset *offset_in_list = (Offset *) element; ssp_printf("start: %u, end: %u\n", offset_in_list->start, offset_in_list->end); - return 0; } - +*/ int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file) { @@ -286,5 +286,5 @@ int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t offset->end = file_size; file->missing_offsets->push(file->missing_offsets, offset, file_size); file->is_temp = 0; - + return 0; } diff --git a/Program/src/main.c b/Program/src/main.c index c450785..a4726de 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -11,6 +11,7 @@ #include "mib.h" #include "requests.h" #include "packet.h" +#include "tasks.h" //for itoa #include diff --git a/Program/src/makefile b/Program/src/makefile index 4004d1f..9b31178 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -12,6 +12,7 @@ CFILES += mib.c CFILES += filesystem_funcs.c CFILES += ringbuf.c CFILES += requests.c +CFILES += tasks.c #----------------------------test files------------------------- CFILES += $(PROJDIR)/test/test.c diff --git a/Program/src/mib.c b/Program/src/mib.c index 2e160a8..95dc832 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -74,6 +74,12 @@ Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ return pdu_header; } +void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { + ssp_free(pdu_header->destination_id); + ssp_free(pdu_header->source_id); + ssp_free(pdu_header); +} + /* //building the pdu header here client->pdu_header = ssp_alloc(1, sizeof(Pdu_header)); diff --git a/Program/src/port.c b/Program/src/port.c index ed10275..1dce586 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -21,6 +21,12 @@ #endif #include "protocol_handler.h" + + +/*------------------------------------------------------------------------------ + File system port functions, these are used to interchange different + File systems +------------------------------------------------------------------------------*/ int ssp_rename(const char *old, const char *new) { #ifdef POSIX_PORT return rename(old, new); @@ -48,12 +54,6 @@ int ssp_lseek(int fd, int offset, int whence) { #endif } -void *ssp_alloc(uint32_t n_memb, size_t size) { - #ifdef POSIX_PORT - return calloc(n_memb, size); - #endif -} - int ssp_open(char *pathname, int flags) { #ifdef POSIX_PORT //open with read and write permissions @@ -65,46 +65,13 @@ int ssp_close(int fd) { #ifdef POSIX_PORT return close(fd); #endif - -} - -void ssp_printf( char *stuff, ...) { - #ifdef POSIX_PORT - va_list args; - va_start(args, stuff); - vfprintf(stdout, stuff, args); - va_end (args); - fflush(stdout); - #endif -} - -void ssp_error(char *error){ - #ifdef POSIX_PORT - perror(error); - #endif } -//size is the number of bytes we want to print -void ssp_print_hex(char *stuff, uint32_t size){ - - uint32_t current_packet_index = 0; - ssp_printf("printing number of bytes: %u\n", size); - - for (int j = 0; j < size; j += 1) { - ssp_printf("%x.", - stuff[current_packet_index]); - current_packet_index += 1; - } - ssp_printf("\n"); -} - -void ssp_thread_cancel(void *thread_handle) { - #ifdef POSIX_PORT - pthread_t * handle = (pthread_t*) thread_handle; - #endif - pthread_cancel(*handle); -} +/*------------------------------------------------------------------------------ + Network port functions, these are used to interchange different network + stacks +------------------------------------------------------------------------------*/ void ssp_sendto(Response res) { @@ -120,381 +87,83 @@ void ssp_sendto(Response res) { -//this function is a callback when using my posix port -static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_storage addr, void *other) { - Protocol_state *p_state = (Protocol_state *) other; - #ifdef POSIX_PORT - struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; - memcpy(p_state->current_server_request->res.addr, posix_client, sizeof(struct sockaddr_in)); - #endif - p_state->current_server_request->res.sfd = sfd; - p_state->current_server_request->res.packet_len = p_state->packet_size; - Response res; - res.addr = posix_client; - res.sfd = sfd; - res.packet_len = p_state->packet_size; - parse_packet_server(packet, res.packet_len, res, p_state->current_server_request, p_state); - return 0; +/*------------------------------------------------------------------------------ + Std lib functions, for custom memory allocation, and stdio +------------------------------------------------------------------------------*/ -} - -static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_in addr, void *other) { - +void *ssp_alloc(uint32_t n_memb, size_t size) { #ifdef POSIX_PORT - struct sockaddr_in* posix_client = (struct sockaddr_in*) &addr; + return calloc(n_memb, size); #endif - - Client *client = (Client *) other; - if (client->req == NULL) - return 0; - - Response res; - res.addr = posix_client; - res.sfd = sfd; - res.packet_len = *buff_size; - res.msg = client->req->buff; - - parse_packet_client(packet, res, client->req, client); - return 0; - } -static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { - - +void ssp_free(void *pointer) { #ifdef POSIX_PORT - struct sockaddr_in* client_addr = (struct sockaddr_in*) &addr; + free(pointer); #endif - - Response res; - Client *client = (Client *) other; - if (client->req == NULL) - return 0; - - res.sfd = sfd; - res.packet_len = client->packet_len; - res.msg = client->req->buff; - res.addr = client_addr; - - user_request_handler(res, client->req, client); - return 0; -} - -//this function is a callback when using my posix ports -static int on_time_out_posix(void *other) { - - Protocol_state *p_state = (Protocol_state*) other; - if(p_state->current_server_request->transaction_sequence_number == 0) - return 0; - - Response res = p_state->current_server_request->res; - on_server_time_out(res, p_state->current_server_request, p_state); - - return 0; -} - - -//this function is just for posix fun -static int on_stdin(void *other) { - - /* - Protocol_state *p_state = (Protocol_state *) other; - Request *req = p_state->newClient->req; - - char input[MAX_PATH]; - fgets(input, MAX_PATH, stdin); - input[strlen(input)-1]='\0'; - - if (req->type == none){ - if (strnlen(req->source_file_name, MAX_PATH) == 0){ - if (get_file_size(input) == -1){ - ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); - return 0; - } - memcpy(p_state->newClient->req->source_file_name, input, MAX_PATH); - ssp_printf("Enter a destination file name:\n"); - } - else if (strnlen(req->destination_file_name, MAX_PATH) == 0){ - memcpy(p_state->newClient->req->destination_file_name, input, MAX_PATH); - ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, p_state->newClient->cfdp_id); - ssp_printf("cancel connection mode (yes):\n"); - } - else if (strncmp(input, "yes", 3) == 0){ - ssp_printf("sending file connectionless\n"); - put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 1, NULL, NULL, p_state->newClient, p_state); - } - else { - ssp_printf("sending file connected\n"); - put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 0, NULL, NULL, p_state->newClient, p_state); - } - } - */ - return 0; - } - -void *ssp_connectionless_server_task(void *params) { - - Protocol_state* p_state = (Protocol_state*) params; - p_state->transaction_sequence_number = 1; - +void ssp_error(char *error){ #ifdef POSIX_PORT - udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, p_state); + perror(error); #endif - - return NULL; } - -Protocol_state* ssp_connectionless_server(char *port) { +void ssp_printf( char *stuff, ...) { #ifdef POSIX_PORT - Protocol_state *state = calloc(sizeof(Protocol_state), 1); - state->packet_size = PACKET_LEN; - - pthread_t *handler = calloc(sizeof(pthread_t), 1); - checkAlloc(handler, 1); - - pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); - checkAlloc(attr, 1); - - state->server_port = calloc(sizeof(char), 10); - checkAlloc(state->server_port, 1); - - strncpy ((char*)state->server_port, port, 10); - - state->request_list = linked_list(); - - int err = pthread_attr_init(attr); - if (0 != err) - perror("pthread_init failed"); - - - size_t stack_size = STACK_ALLOCATION; - err = pthread_attr_setstacksize(attr, stack_size); - - if (0 != err) - perror("ERROR pthread_attr_setstacksize %d"); - - if (EINVAL == err) { - printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); - } - - err = pthread_create(handler, attr, ssp_connectionless_server_task, state); - if (0 != err) - perror("ERROR pthread_create"); - - state->current_server_request = init_request(state->packet_size); - state->server_handle = handler; - state->server_thread_attributes = attr; - - - return state; - + va_list args; + va_start(args, stuff); + vfprintf(stdout, stuff, args); + va_end (args); + fflush(stdout); #endif } - -void *ssp_connectionless_client_task(void* params){ - - Client *client = (Client *) params; - - char host_name[INET_ADDRSTRLEN]; - char port[10]; - //convert int to char * - snprintf(port, 10, "%d", client->unitdata_port); - - //convert uint id to char * - inet_ntop(AF_INET, &client->unitdata_id, host_name, INET_ADDRSTRLEN); - - udpClient(host_name, port, PACKET_LEN, client, client, on_send_client, on_recv_client); - - return NULL; -} - +void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params) { -Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { #ifdef POSIX_PORT - - Client *client = calloc(sizeof(Client), 1); - checkAlloc(client, 1); - - client->req = NULL; - client->req_queue = linked_list(); - - pthread_t *handler = calloc(sizeof(pthread_t), 1); + pthread_t *handler = ssp_alloc(sizeof(pthread_t), 1); checkAlloc(handler, 1); - pthread_attr_t *attr = calloc(sizeof(pthread_attr_t), 1); + pthread_attr_t *attr = ssp_alloc(sizeof(pthread_attr_t), 1); checkAlloc(attr, 1); int err = pthread_attr_init(attr); if (0 != err) perror("pthread_init failed"); - size_t stack_size = STACK_ALLOCATION; + err = pthread_attr_setstacksize(attr, stack_size); if (0 != err) perror("ERROR pthread_attr_setstacksize %d"); - if (EINVAL == err) + if (EINVAL == err) { printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + } - client->client_handle = handler; - client->client_thread_attributes = attr; - client->packet_len = PACKET_LEN; - client->cfdp_id = cfdp_id; - - - List *entity_list = p_state->mib->remote_entities; - Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); - - if (remote == NULL) - ssp_printf("couldn't find entity in Remote_entity list\n"); - - //TODO clean this up, we don't need multiple instances of UT_ports etc - client->unitdata_port = remote->UT_port; - client->unitdata_id = remote->UT_address; - client->mib_info = remote; - client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); - - client->p_state = p_state; - - err = pthread_create(handler, attr, ssp_connectionless_client_task, client); + err = pthread_create(handler, attr, thread_func, params); if (0 != err) perror("ERROR pthread_create"); - - return client; + ssp_free(attr); #endif -} - -void reset_request(Request *req){ - memset(req->source_file_name, 0, MAX_PATH); - memset(req->destination_file_name, 0, MAX_PATH); - memset(req->buff, 0, req->buff_len); - memset(req->res.addr, 0, sizeof(struct sockaddr_in)); - req->dest_cfdp_id = 0; - req->fault_handler_overides = 0; - req->file_size = 0; - req->flow_lable = 0; - req->received_eof = 0; - req->received_finished = 0; - req->received_metadata = 0; - req->resent_eof = 0; - req->resent_finished = 0; - req->segmentation_control = 0; - req->transaction_sequence_number = 0; - req->transmission_mode = 1; - req->type = none; - if (req->file != NULL) - free_file(req->file); - req->file = NULL; - req->type = none; - -} - -Request *init_request(uint32_t buff_len) { - - Request *req = calloc(1, sizeof(Request)); - - req->source_file_name = ssp_alloc(MAX_PATH, sizeof(char)); - checkAlloc(req->source_file_name, 1); - - req->destination_file_name = ssp_alloc(MAX_PATH, sizeof(char)); - checkAlloc(req->destination_file_name, 1); - - - req->file = NULL; - req->buff_len = buff_len; - req->buff = ssp_alloc(buff_len, sizeof(char)); - - req->res.addr = ssp_alloc(1, sizeof(struct sockaddr_in)); - req->type = none; - checkAlloc(req->buff, 1); - return req; -} - - -void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { - ssp_free(pdu_header->destination_id); - ssp_free(pdu_header->source_id); - ssp_free(pdu_header); -} - -void ssp_cleanup_req(void *request) { - - Request *req = (Request *) request; - - if (req == NULL) - return; - if (req->file != NULL) - free_file(req->file); - if (req->pdu_header != NULL) - ssp_cleanup_pdu_header(req->pdu_header); - if (req->res.addr != NULL) - ssp_free(req->res.addr); - if (req->source_file_name != NULL) - ssp_free(req->source_file_name); - if (req->destination_file_name != NULL) - ssp_free(req->destination_file_name); - if (req->buff != NULL) - ssp_free(req->buff); - ssp_free(req); + return handler; } - - -void ssp_cleanup(Protocol_state *p_state) { - +void ssp_thread_join(void *thread_handle) { #ifdef POSIX_PORT - pthread_t * handle = (pthread_t*) p_state->server_handle; - pthread_join(*handle, NULL); - - #endif - - p_state->request_list->free(p_state->request_list, ssp_cleanup_req); - ssp_cleanup_req(p_state->current_server_request); - free_mib(p_state->mib); - ssp_free(p_state->server_handle); - ssp_free(p_state->server_port); - ssp_free(p_state->server_thread_attributes); - ssp_free(p_state); - -} - - -void ssp_cleanup_client(Client *client) { - - - #ifdef POSIX_PORT - pthread_t * handle = (pthread_t*) client->client_handle; + pthread_t * handle = (pthread_t*) thread_handle; pthread_join(*handle, NULL); #endif - - client->req_queue->free(client->req_queue, ssp_cleanup_req); - ssp_cleanup_req(client->req); - ssp_free(client->client_handle); - ssp_free(client->client_thread_attributes); - ssp_cleanup_pdu_header(client->pdu_header); - - free(client); - -} - -void ssp_free(void *pointer) { - #ifdef POSIX_PORT - free(pointer); - #endif } \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index d960476..296f6ae 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -324,8 +324,7 @@ static void request_metadata(Request *req, Response res) { res.msg = req->buff; ssp_printf("sending request for new metadata packet\n"); uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); - uint16_t data_len = 0; - data_len = build_nak_directive(res.msg, start, META_DATA_PDU); + build_nak_directive(res.msg, start, META_DATA_PDU); ssp_sendto(res); return; } @@ -602,7 +601,6 @@ void user_request_handler(Response res, Request *req, Client* client) { memset(res.msg, 0, client->packet_len); uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - uint32_t data_len = 0; check_req_status(req, client); switch (req->type) @@ -635,7 +633,7 @@ void user_request_handler(Response res, Request *req, Client* client) { case finished: ssp_printf("sending finished packet\n"); - data_len = build_ack(res.msg, start, FINISHED_PDU, req); + build_ack(res.msg, start, FINISHED_PDU, req); ssp_sendto(res); req->resent_finished++; break; @@ -651,6 +649,17 @@ void user_request_handler(Response res, Request *req, Client* client) { ------------------------------------------------------------------------------*/ +static void reset_timeout(Protocol_state *p_state, Request *req) { + + uint32_t time = p_state->timeout++; + ssp_printf("timeout %u\n", time); + if (time == 20) { + p_state->timeout = 0; + reset_request(req); + ssp_printf("timeout, resetting request\n"); + } +} + void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { res.msg = req->buff; @@ -660,8 +669,9 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { if (req->buff == NULL) ssp_printf("req buffer is null, couldn't process timeout request\n"); + reset_timeout(p_state, req); + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); - uint16_t data_len = 0; //Pdu_header *pdu_header = (Pdu_header *) &res.msg; if (req->resent_finished == 3) { @@ -673,14 +683,14 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { //send request for metadata if (!req->received_metadata) { ssp_printf("sending request for new metadata packet\n"); - data_len = build_nak_directive(res.msg, start, META_DATA_PDU); + build_nak_directive(res.msg, start, META_DATA_PDU); ssp_sendto(res); return; } //send missing eofs if (!req->received_eof) { - data_len = build_nak_directive(res.msg, start, EOF_PDU); + build_nak_directive(res.msg, start, EOF_PDU); ssp_sendto(res); } @@ -696,7 +706,7 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { if (req->file->eof_checksum == req->file->partial_checksum){ ssp_printf("sending finsihed pdu\n"); - data_len = build_finished_pdu(res.msg, start, req); + build_finished_pdu(res.msg, start, req); ssp_sendto(res); req->resent_finished++; return; @@ -709,18 +719,12 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { //received EOF, send back 3 eof packets if (req->received_eof && req->resent_eof < 3) { ssp_printf("sending eof ack\n"); - data_len = build_ack(res.msg, start, EOF_PDU, req); + build_ack(res.msg, start, EOF_PDU, req); ssp_sendto(res); req->resent_eof++; } - uint32_t time = p_state->timeout++; - ssp_printf("timeout %u\n", time); - if (time == 20) { - p_state->timeout = 0; - reset_request(req); - ssp_printf("timeout, resetting request\n"); - } + } //fills the current_request struct for the server, incomming requests @@ -737,6 +741,8 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); } + //will protbably have to timeout different clients? how does that work with ddos? + p_state->timeout = 0; //process file data if (header->PDU_type == 1) { if (!req->received_metadata) { diff --git a/Program/src/requests.c b/Program/src/requests.c index 27b8bd7..79ae10a 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -9,7 +9,83 @@ #include "stdint.h" #include "protocol_handler.h" #include "port.h" +#include "utils.h" #include +#include "tasks.h" + +void ssp_cleanup_req(void *request) { + + Request *req = (Request *) request; + + if (req == NULL) + return; + if (req->file != NULL) + free_file(req->file); + if (req->pdu_header != NULL) + ssp_cleanup_pdu_header(req->pdu_header); + if (req->res.addr != NULL) + ssp_free(req->res.addr); + if (req->source_file_name != NULL) + ssp_free(req->source_file_name); + if (req->destination_file_name != NULL) + ssp_free(req->destination_file_name); + if (req->buff != NULL) + ssp_free(req->buff); + ssp_free(req); + +} + + +void reset_request(Request *req){ + memset(req->source_file_name, 0, MAX_PATH); + memset(req->destination_file_name, 0, MAX_PATH); + memset(req->buff, 0, req->buff_len); + memset(req->res.addr, 0, sizeof(struct sockaddr_in)); + req->dest_cfdp_id = 0; + req->fault_handler_overides = 0; + req->file_size = 0; + req->flow_lable = 0; + req->received_eof = 0; + req->received_finished = 0; + req->received_metadata = 0; + req->resent_eof = 0; + req->resent_finished = 0; + req->segmentation_control = 0; + req->transaction_sequence_number = 0; + req->transmission_mode = 1; + req->type = none; + if (req->file != NULL) + free_file(req->file); + + if (req->pdu_header != NULL) { + ssp_cleanup_pdu_header(req->pdu_header); + req->pdu_header = NULL; + } + req->file = NULL; + req->type = none; + +} + + +Request *init_request(uint32_t buff_len) { + + Request *req = ssp_alloc(1, sizeof(Request)); + + req->source_file_name = ssp_alloc(MAX_PATH, sizeof(char)); + checkAlloc(req->source_file_name, 1); + + req->destination_file_name = ssp_alloc(MAX_PATH, sizeof(char)); + checkAlloc(req->destination_file_name, 1); + + req->file = NULL; + req->buff_len = buff_len; + req->buff = ssp_alloc(buff_len, sizeof(char)); + + req->res.addr = ssp_alloc(1, sizeof(struct sockaddr_in)); + req->type = none; + checkAlloc(req->buff, 1); + return req; +} //Omission of source and destination filenames shall indicate that only Meta //data will be delivered @@ -28,7 +104,7 @@ Request *put_request(char *source_file_name, uint32_t file_size = get_file_size(source_file_name); if (file_size == -1) - return -1; + return NULL; //give the client a new request to perform Request *req = init_request(client->packet_len); diff --git a/Program/src/server.c b/Program/src/server.c index dabbd86..0c0434f 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -32,7 +32,6 @@ This is my file for server.c. It develops a udp server for select. #include #include - static int exit_now; @@ -40,6 +39,7 @@ static int exit_now; //see header file int prepareUdpHost(char *port) { + struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; @@ -144,7 +144,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf //see header file void udpSelectServer(char* port, int packet_len, - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_storage client, void *other), + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), void *other) @@ -213,7 +213,7 @@ void udpSelectServer(char* port, int packet_len, { socklen_t client_len = sizeof(*client); - int count = recvfrom(sfd, buff, packet_len, 0, (struct sockaddr*)client, &client_len); + int count = recvfrom(sfd, buff, packet_len, 0, (void *) client, &client_len); if (count == -1) @@ -227,7 +227,7 @@ void udpSelectServer(char* port, int packet_len, } else { - if (onRecv(sfd, buff, buff_size, *client, other) == -1) + if (onRecv(sfd, buff, buff_size, (void*) client, other) == -1) printf("recv failed\n"); } } @@ -244,7 +244,7 @@ void udpSelectServer(char* port, int packet_len, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, struct sockaddr_in client, void *onRecvParams) + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *onRecvParams) ) { int sfd, count, port_val; @@ -309,7 +309,7 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo } else { - if (onRecv(sfd, buff, buff_size, serveraddr, onRecvParams) == -1) + if (onRecv(sfd, buff, buff_size, (void *)&serveraddr, onRecvParams) == -1) printf("recv failed\n"); } @@ -320,3 +320,4 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo close(sfd); } + From ab5b634789d425c316c2ad6bfb21617a6d69eccb Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 29 May 2019 13:11:40 -0600 Subject: [PATCH 055/400] add tasks to last commit --- Program/src/tasks.c | 239 ++++++++++++++++++++++++++++++++++++++++++++ Program/src/utils.c | 26 +++-- 2 files changed, 251 insertions(+), 14 deletions(-) create mode 100644 Program/src/tasks.c diff --git a/Program/src/tasks.c b/Program/src/tasks.c new file mode 100644 index 0000000..58d6479 --- /dev/null +++ b/Program/src/tasks.c @@ -0,0 +1,239 @@ + + + +#include "protocol_handler.h" +#include "tasks.h" +#include "server.h" +#include "port.h" +#include +#include "mib.h" +#include "filesystem_funcs.h" + +/*------------------------------------------------------------------------------ + + Callbacks for the tasks bellow + +------------------------------------------------------------------------------*/ +//this function is a callback when using my posix port +static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other) { + + Protocol_state *p_state = (Protocol_state *) other; + Response res; + res.addr = addr; + res.sfd = sfd; + res.packet_len = p_state->packet_size; + p_state->current_server_request->res = res; + + parse_packet_server(packet, res.packet_len, res, p_state->current_server_request, p_state); + return 0; + +} + +static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other) { + + + Client *client = (Client *) other; + if (client->req == NULL) + return 0; + + Response res; + res.addr = addr; + res.sfd = sfd; + res.packet_len = *buff_size; + res.msg = client->req->buff; + + parse_packet_client(packet, res, client->req, client); + return 0; + +} + +static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { + + + #ifdef POSIX_PORT + struct sockaddr_in* client_addr = (struct sockaddr_in*) &addr; + #endif + + Response res; + Client *client = (Client *) other; + if (client->req == NULL) + return 0; + + res.sfd = sfd; + res.packet_len = client->packet_len; + res.msg = client->req->buff; + res.addr = client_addr; + + user_request_handler(res, client->req, client); + return 0; +} + +//this function is a callback when using my posix ports +static int on_time_out_posix(void *other) { + + Protocol_state *p_state = (Protocol_state*) other; + if(p_state->current_server_request->transaction_sequence_number == 0) + return 0; + + Response res = p_state->current_server_request->res; + on_server_time_out(res, p_state->current_server_request, p_state); + + return 0; +} + + +//this function is just for posix fun +static int on_stdin(void *other) { + + /* + Protocol_state *p_state = (Protocol_state *) other; + Request *req = p_state->newClient->req; + + char input[MAX_PATH]; + fgets(input, MAX_PATH, stdin); + input[strlen(input)-1]='\0'; + + if (req->type == none){ + if (strnlen(req->source_file_name, MAX_PATH) == 0){ + if (get_file_size(input) == -1){ + ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); + return 0; + } + memcpy(p_state->newClient->req->source_file_name, input, MAX_PATH); + ssp_printf("Enter a destination file name:\n"); + } + else if (strnlen(req->destination_file_name, MAX_PATH) == 0){ + memcpy(p_state->newClient->req->destination_file_name, input, MAX_PATH); + ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, p_state->newClient->cfdp_id); + ssp_printf("cancel connection mode (yes):\n"); + } + else if (strncmp(input, "yes", 3) == 0){ + ssp_printf("sending file connectionless\n"); + put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 1, NULL, NULL, p_state->newClient, p_state); + } + else { + ssp_printf("sending file connected\n"); + put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 0, NULL, NULL, p_state->newClient, p_state); + } + } + */ + return 0; + +} + + +/*------------------------------------------------------------------------------ + + Tasks + +------------------------------------------------------------------------------*/ +void *ssp_connectionless_server_task(void *params) { + + Protocol_state* p_state = (Protocol_state*) params; + p_state->transaction_sequence_number = 1; + + #ifdef POSIX_PORT + udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, p_state); + #endif + + return NULL; +} + + +Protocol_state* ssp_connectionless_server(char *port) { + + Protocol_state *state = ssp_alloc(sizeof(Protocol_state), 1); + state->packet_size = PACKET_LEN; + + state->server_port = ssp_alloc(sizeof(char), 10); + checkAlloc(state->server_port, 1); + strncpy ((char*)state->server_port, port, 10); + + state->request_list = linked_list(); + + state->current_server_request = init_request(state->packet_size); + state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, state); + return state; + +} + + +void *ssp_connectionless_client_task(void* params){ + + Client *client = (Client *) params; + + char host_name[INET_ADDRSTRLEN]; + char port[10]; + //convert int to char * + snprintf(port, 10, "%d", client->unitdata_port); + + //convert uint id to char * + inet_ntop(AF_INET, &client->unitdata_id, host_name, INET_ADDRSTRLEN); + + udpClient(host_name, port, PACKET_LEN, client, client, on_send_client, on_recv_client); + + return NULL; +} + + + +Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { + + + Client *client = ssp_alloc(sizeof(Client), 1); + checkAlloc(client, 1); + + client->req = NULL; + client->req_queue = linked_list(); + client->packet_len = PACKET_LEN; + client->cfdp_id = cfdp_id; + + + List *entity_list = p_state->mib->remote_entities; + Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); + + if (remote == NULL) + ssp_printf("couldn't find entity in Remote_entity list\n"); + + //TODO clean this up, we don't need multiple instances of UT_ports etc + client->unitdata_port = remote->UT_port; + client->unitdata_id = remote->UT_address; + client->mib_info = remote; + + client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); + client->p_state = p_state; + + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); + return client; +} + +/*------------------------------------------------------------------------------ + + free functions + +------------------------------------------------------------------------------*/ + + + +void ssp_cleanup(Protocol_state *p_state) { + + ssp_thread_join(p_state->server_handle); + p_state->request_list->free(p_state->request_list, ssp_cleanup_req); + ssp_cleanup_req(p_state->current_server_request); + free_mib(p_state->mib); + ssp_free(p_state->server_handle); + ssp_free(p_state->server_port); + ssp_free(p_state); + +} + + +void ssp_cleanup_client(Client *client) { + + ssp_thread_join(client->client_handle); + client->req_queue->free(client->req_queue, ssp_cleanup_req); + ssp_cleanup_req(client->req); + ssp_free(client->client_handle); + ssp_cleanup_pdu_header(client->pdu_header); + ssp_free(client); +} diff --git a/Program/src/utils.c b/Program/src/utils.c index 822f584..4c79d50 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -391,18 +391,16 @@ List *linked_list() } -//TODO write an array -/* -int add_element_array_list(List *list, void *element) { -} - -List *array_list() { - - List *new_list = calloc(sizeof(List), 1); - if (checkAlloc(new_list, 0)); - return NULL; - -} - -*/ +//size is the number of bytes we want to print +void ssp_print_hex(char *stuff, int size){ + + uint32_t current_packet_index = 0; + ssp_printf("printing number of bytes: %u\n", size); + for (int j = 0; j < size; j += 1) { + ssp_printf("%x.", + stuff[current_packet_index]); + current_packet_index += 1; + } + ssp_printf("\n"); +} From 34181263ec20ccb3a61ef5c213591332a2e4be87 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 29 May 2019 14:28:01 -0600 Subject: [PATCH 056/400] simplify init function, add new file_delivery_app file for static linking soon --- Program/include/file_delivery_app.h | 12 +++++++ Program/include/tasks.h | 20 ++--------- Program/src/file_delivery_app.c | 50 ++++++++++++++++++++++++++++ Program/src/main.c | 39 +++------------------- Program/src/makefile | 2 ++ Program/src/remote_pic1.jpeg | Bin 0 -> 150033 bytes Program/src/tasks.c | 13 ++++---- 7 files changed, 78 insertions(+), 58 deletions(-) create mode 100644 Program/include/file_delivery_app.h create mode 100644 Program/src/file_delivery_app.c create mode 100644 Program/src/remote_pic1.jpeg diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h new file mode 100644 index 0000000..911e79b --- /dev/null +++ b/Program/include/file_delivery_app.h @@ -0,0 +1,12 @@ + + + +#ifndef FTP_APP_H +#define FTP_APP_H +#include "protocol_handler.h" + +Protocol_state *init_ftp(uint32_t my_cfdp_address); + + + +#endif \ No newline at end of file diff --git a/Program/include/tasks.h b/Program/include/tasks.h index f8b2f2c..340f0a3 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -7,27 +7,13 @@ #include "protocol_handler.h" -void ssp_cleanup(Protocol_state *state); void ssp_cleanup_client(Client *client); void ssp_cleanup_req(void *request); -Protocol_state *ssp_connectionless_server(char *port); +void ssp_connectionless_server(Protocol_state *p_state); + +void ssp_cleanup_p_state(Protocol_state *p_state); Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); void *ssp_connectionless_client_task(void *params); - - - - - - - - - - - - - - - #endif \ No newline at end of file diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c new file mode 100644 index 0000000..5e5e6b1 --- /dev/null +++ b/Program/src/file_delivery_app.c @@ -0,0 +1,50 @@ + +#include "mib.h" +#include "protocol_handler.h" +#include "port.h" +#include "stddef.h" +#include "stdint.h" +#include "string.h" +#include "file_delivery_app.h" + +Protocol_state *init_ftp(uint32_t my_cfdp_address) { + + //Memory information base + MIB *mib = init_mib(); + + //setting host name for testing + char *host_name = "127.0.0.1"; + uint32_t addr[sizeof(uint32_t)]; + inet_pton(AF_INET, host_name, addr); + + //adding new cfdp entities to management information base + add_new_cfdp_entity(mib, 1, *addr, 1111); + add_new_cfdp_entity(mib, 2, *addr, 1112); + add_new_cfdp_entity(mib, 3, *addr, 1113); + add_new_cfdp_entity(mib, 4, *addr, 1114); + + //find server client in mib + Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); + if (server_entity == NULL) { + printf("couldn't find your id in the information base\n"); + } + + char port[20]; + snprintf(port, 20, "%u", server_entity->UT_port); + + Protocol_state *p_state = ssp_alloc(sizeof(Protocol_state), 1); + p_state->packet_size = PACKET_LEN; + p_state->my_cfdp_id = my_cfdp_address; + p_state->mib = mib; + + + p_state->server_port = ssp_alloc(sizeof(char), 10); + checkAlloc(p_state->server_port, 1); + + strncpy ((char*)p_state->server_port, port, 10); + + p_state->request_list = linked_list(); + p_state->current_server_request = init_request(p_state->packet_size); + + return p_state; +} \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index a4726de..71ce915 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -12,7 +12,7 @@ #include "requests.h" #include "packet.h" #include "tasks.h" - +#include "file_delivery_app.h" //for itoa #include #include @@ -33,37 +33,8 @@ int main(int argc, char** argv) { ssp_printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } - - //Memory information base - MIB *mib = init_mib(); - - //setting host name for testing - char *host_name = "127.0.0.1"; - uint32_t addr[sizeof(uint32_t)]; - inet_pton(AF_INET, host_name, addr); - - //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111); - add_new_cfdp_entity(mib, 2, *addr, 1112); - add_new_cfdp_entity(mib, 3, *addr, 1113); - add_new_cfdp_entity(mib, 4, *addr, 1114); - - //find server client in mib - Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, conf->my_cfdp_id, NULL, NULL); - if (server_entity == NULL) { - printf("couldn't find entity\n"); - } - - //connectionless server - char port[17]; - snprintf(port, 17, "%u", server_entity->UT_port); - - Protocol_state *p_state = ssp_connectionless_server(port); - - //set this node's Id, this has to be hardcoded/assigned - p_state->my_cfdp_id = conf->my_cfdp_id; - p_state->mib = mib; - p_state->verbose_level = conf->verbose_level; + Protocol_state *p_state = init_ftp(conf->my_cfdp_id); + ssp_connectionless_server(p_state); //create a client if (conf->client_cfdp_id != 0){ @@ -88,8 +59,8 @@ int main(int argc, char** argv) { ssp_printf("client disconnected\n"); } - ssp_cleanup(p_state); - free(conf); + ssp_cleanup_p_state(p_state); + ssp_free(conf); return 0; diff --git a/Program/src/makefile b/Program/src/makefile index 9b31178..edb327c 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -13,6 +13,7 @@ CFILES += filesystem_funcs.c CFILES += ringbuf.c CFILES += requests.c CFILES += tasks.c +CFILES += file_delivery_app.c #----------------------------test files------------------------- CFILES += $(PROJDIR)/test/test.c @@ -65,6 +66,7 @@ CFLAGS += $(INCLUDE) $(CWARNS) OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) all: $(MAIN) + mv *.o ../obj .PHONY: clean diff --git a/Program/src/remote_pic1.jpeg b/Program/src/remote_pic1.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8c727e085507309e22d0059687c15e4d884930d0 GIT binary patch literal 150033 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 +#include +#include #include "file_delivery_app.h" +#include "tasks.h" +#include Protocol_state *init_ftp(uint32_t my_cfdp_address) { @@ -26,7 +28,7 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); if (server_entity == NULL) { - printf("couldn't find your id in the information base\n"); + ssp_printf("couldn't find your id in the information base\n"); } char port[20]; @@ -47,4 +49,44 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { p_state->current_server_request = init_request(p_state->packet_size); return p_state; -} \ No newline at end of file +} + + + +void ssp_connectionless_server(Protocol_state *p_state) { + + + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); +} + + + +Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { + + + Client *client = ssp_alloc(sizeof(Client), 1); + checkAlloc(client, 1); + + client->req = NULL; + client->req_queue = linked_list(); + client->packet_len = PACKET_LEN; + client->cfdp_id = cfdp_id; + + + List *entity_list = p_state->mib->remote_entities; + Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); + + if (remote == NULL) + ssp_printf("couldn't find entity in Remote_entity list\n"); + + //TODO clean this up, we don't need multiple instances of UT_ports etc + client->unitdata_port = remote->UT_port; + client->unitdata_id = remote->UT_address; + client->mib_info = remote; + + client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); + client->p_state = p_state; + + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); + return client; +} diff --git a/Program/src/main.c b/Program/src/main.c index 71ce915..3028730 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -55,11 +55,13 @@ int main(int argc, char** argv) { //put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); //will block on pthread_join - ssp_cleanup_client(new_client); + + ssp_thread_join(new_client->client_handle); ssp_printf("client disconnected\n"); } - ssp_cleanup_p_state(p_state); + ssp_thread_join(p_state->server_handle); + ssp_free(conf); diff --git a/Program/src/makefile b/Program/src/makefile index edb327c..a3af8ef 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -16,8 +16,6 @@ CFILES += tasks.c CFILES += file_delivery_app.c #----------------------------test files------------------------- -CFILES += $(PROJDIR)/test/test.c -INCLUDE += -I$(PROJDIR)/test #entrypoint MAIN = main @@ -65,8 +63,8 @@ CFLAGS += $(INCLUDE) $(CWARNS) #---------------------------Build--------------------------- OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) -all: $(MAIN) - mv *.o ../obj +all: $(MAIN) + ar -rsc file_delivery_app.a $(OBJS_FILES) .PHONY: clean diff --git a/Program/src/port.c b/Program/src/port.c index 1dce586..cfd6e20 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -164,6 +164,7 @@ void ssp_thread_join(void *thread_handle) { #ifdef POSIX_PORT pthread_t * handle = (pthread_t*) thread_handle; pthread_join(*handle, NULL); + ssp_free(thread_handle); #endif } \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 296f6ae..bebb774 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -583,6 +583,7 @@ static void check_req_status(Request *req, Client *client) { if (req->resent_finished == 3) { ssp_printf("file successfully sent\n"); req->resent_finished = 4; + client->close = 1; //ssp_cleanup_req(client->req); //client->req = NULL; } diff --git a/Program/src/requests.c b/Program/src/requests.c index 79ae10a..767f976 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -23,8 +23,6 @@ void ssp_cleanup_req(void *request) { free_file(req->file); if (req->pdu_header != NULL) ssp_cleanup_pdu_header(req->pdu_header); - if (req->res.addr != NULL) - ssp_free(req->res.addr); if (req->source_file_name != NULL) ssp_free(req->source_file_name); if (req->destination_file_name != NULL) @@ -81,7 +79,6 @@ Request *init_request(uint32_t buff_len) { req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); - req->res.addr = ssp_alloc(1, sizeof(struct sockaddr_in)); req->type = none; checkAlloc(req->buff, 1); return req; diff --git a/Program/src/server.c b/Program/src/server.c index 0c0434f..91ec3e0 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -147,6 +147,8 @@ void udpSelectServer(char* port, int packet_len, int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), void *other) { int sfd = prepareUdpHost(port); @@ -172,6 +174,7 @@ void udpSelectServer(char* port, int packet_len, client = calloc(sizeof(struct sockaddr_storage), 1); checkAlloc(client, 1); + for (;;) { struct timeval timeout = { @@ -182,11 +185,12 @@ void udpSelectServer(char* port, int packet_len, fd_set readFds = masterReadFds; int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); - if (exit_now){ + + if (exit_now || checkExit(other)){ printf("exiting server thread\n"); break; } - + if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ printf("packet too large, cannot resize buffer\n"); } @@ -236,16 +240,19 @@ void udpSelectServer(char* port, int packet_len, free(client); free(buff); close(sfd); + onExit(other); } //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, +void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *onRecvParams) -) { + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params)) +{ int sfd, count, port_val; socklen_t serverlen; @@ -285,7 +292,7 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo for (;;) { - if (exit_now) + if (exit_now || checkExit(checkExitParams)) break; if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ @@ -318,6 +325,7 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo free(buff_size); free(buff); close(sfd); + onExit(onExitParams); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 58ecc5b..9f53144 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -8,6 +8,7 @@ #include #include "mib.h" #include "filesystem_funcs.h" +#include /*------------------------------------------------------------------------------ @@ -81,6 +82,32 @@ static int on_time_out_posix(void *other) { return 0; } +static int check_exit_server(void *params) { + Protocol_state *p_state = (Protocol_state*) params; + if (p_state->close) + return 1; + return 0; +} + +static int check_exit_client(void *params) { + Client *client = (Client*) params; + if (client->close) + return 1; + return 0; +} + +static void on_exit_client (void *params) { + Client *client = (Client*) params; + ssp_cleanup_client(client); +} + +static void on_exit_server (void *params) { + Protocol_state *p_state = (Protocol_state*) params; + ssp_cleanup_p_state(p_state); +} + + + //this function is just for posix fun static int on_stdin(void *other) { @@ -133,28 +160,12 @@ void *ssp_connectionless_server_task(void *params) { p_state->transaction_sequence_number = 1; #ifdef POSIX_PORT - udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, p_state); + udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); #endif return NULL; } - -void ssp_connectionless_server(Protocol_state *p_state) { - /* - Protocol_state *state = ssp_alloc(sizeof(Protocol_state), 1); - state->packet_size = PACKET_LEN; - - state->server_port = ssp_alloc(sizeof(char), 10); - checkAlloc(state->server_port, 1); - strncpy ((char*)state->server_port, port, 10); - - state->request_list = linked_list(); - state->current_server_request = init_request(state->packet_size); - */ - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); -} - void *ssp_connectionless_client_task(void* params){ @@ -167,44 +178,15 @@ void *ssp_connectionless_client_task(void* params){ //convert uint id to char * inet_ntop(AF_INET, &client->unitdata_id, host_name, INET_ADDRSTRLEN); - - udpClient(host_name, port, PACKET_LEN, client, client, on_send_client, on_recv_client); + #ifdef POSIX_PORT + udpClient(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + #endif return NULL; } -Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { - - - Client *client = ssp_alloc(sizeof(Client), 1); - checkAlloc(client, 1); - - client->req = NULL; - client->req_queue = linked_list(); - client->packet_len = PACKET_LEN; - client->cfdp_id = cfdp_id; - - - List *entity_list = p_state->mib->remote_entities; - Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); - - if (remote == NULL) - ssp_printf("couldn't find entity in Remote_entity list\n"); - - //TODO clean this up, we don't need multiple instances of UT_ports etc - client->unitdata_port = remote->UT_port; - client->unitdata_id = remote->UT_address; - client->mib_info = remote; - - client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); - client->p_state = p_state; - - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); - return client; -} - /*------------------------------------------------------------------------------ free functions @@ -215,12 +197,9 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { void ssp_cleanup_p_state(Protocol_state *p_state) { - - ssp_thread_join(p_state->server_handle); p_state->request_list->free(p_state->request_list, ssp_cleanup_req); ssp_cleanup_req(p_state->current_server_request); free_mib(p_state->mib); - ssp_free(p_state->server_handle); ssp_free(p_state->server_port); ssp_free(p_state); @@ -228,11 +207,8 @@ void ssp_cleanup_p_state(Protocol_state *p_state) { void ssp_cleanup_client(Client *client) { - - ssp_thread_join(client->client_handle); client->req_queue->free(client->req_queue, ssp_cleanup_req); ssp_cleanup_req(client->req); - ssp_free(client->client_handle); ssp_cleanup_pdu_header(client->pdu_header); ssp_free(client); } From d939bf636bd42681d4b73f6d37a4f01af03f1e50 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 19 Jun 2019 13:47:17 -0600 Subject: [PATCH 058/400] moved process_pdu_header down a level, for finding requests --- Program/include/protocol_handler.h | 4 ++-- Program/src/main.c | 7 ------- Program/src/protocol_handler.c | 22 +++++++++++++++------- Program/src/tasks.c | 9 ++++++++- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index a153f6c..3f16a6f 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -58,11 +58,11 @@ typedef struct client { //for use -void parse_packet_server(char* buff, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state); +void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); - +int process_pdu_header(char*packet, Request *req, Protocol_state *p_state); //for testing uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); diff --git a/Program/src/main.c b/Program/src/main.c index 3028730..bf90302 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -45,17 +45,10 @@ int main(int argc, char** argv) { //send via acknoleged mode //0 acknowledged, 1 unacknowledged if (conf->client_cfdp_id == 1) put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - if (conf->client_cfdp_id == 2) put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - - //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - //put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - - //will block on pthread_join - ssp_thread_join(new_client->client_handle); ssp_printf("client disconnected\n"); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index bebb774..5870925 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -381,7 +381,7 @@ int process_file_request_metadata(Request *req) { } //sets destination id in request as the incomming source id, sets transaction number -static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state) { +int process_pdu_header(char*packet, Request *req, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; @@ -414,6 +414,12 @@ static int process_pdu_header(char*packet, Request *req, Protocol_state *p_state req->dest_cfdp_id = source_id; req->transaction_sequence_number = transaction_sequence_number; + + //set header for responding + if (req->pdu_header == NULL){ + req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); + } + return packet_index; } @@ -729,18 +735,22 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { } //fills the current_request struct for the server, incomming requests -void parse_packet_server(char *packet, uint32_t packet_len, Response res, Request *req, Protocol_state *p_state) { - +void parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state) { +/* uint32_t packet_index = process_pdu_header(packet, req, p_state); if (packet_index == -1) return; - Pdu_header *header = (Pdu_header *) packet; - //set header for responding if (req->pdu_header == NULL){ req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); } +*/ + + if (packet_index == 0) + return; + + Pdu_header *header = (Pdu_header *) packet; //will protbably have to timeout different clients? how does that work with ddos? p_state->timeout = 0; @@ -797,7 +807,5 @@ void parse_packet_server(char *packet, uint32_t packet_len, Response res, Reques default: break; } - - memset(packet, 0, packet_len); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 9f53144..8d5e002 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -25,7 +25,14 @@ static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr res.packet_len = p_state->packet_size; p_state->current_server_request->res = res; - parse_packet_server(packet, res.packet_len, res, p_state->current_server_request, p_state); + + uint32_t packet_index = process_pdu_header(packet, p_state->current_server_request, p_state); + if (packet_index == -1) + return; + + parse_packet_server(packet, packet_index, res, p_state->current_server_request, p_state); + + memset(packet, 0, res.packet_len); return 0; } From ce8150cce38f0df23ba06f61f566a9272768de91 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 20 Jun 2019 17:28:32 -0600 Subject: [PATCH 059/400] Server can theoretically handle multiple requests --- Program/include/protocol_handler.h | 8 ++-- Program/include/requests.h | 3 ++ Program/src/file_delivery_app.a | Bin 151170 -> 152318 bytes Program/src/file_delivery_app.c | 9 ++--- Program/src/pic.jpeg | Bin 0 -> 150033 bytes Program/src/port.c | 10 +---- Program/src/protocol_handler.c | 62 ++++++++++++++++++----------- Program/src/requests.c | 14 ++++--- Program/src/tasks.c | 42 +++++++++++-------- Program/src/utils.c | 3 +- 10 files changed, 85 insertions(+), 66 deletions(-) create mode 100644 Program/src/pic.jpeg diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 3f16a6f..170a99e 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -17,7 +17,7 @@ typedef struct protocol_state { List* request_list; - Request *current_server_request; + Request *current_request; //lock this uint32_t transaction_sequence_number; @@ -37,8 +37,8 @@ typedef struct client { void *client_handle; uint32_t packet_len; - Request *req; - List *req_queue; + Request *current_request; + List *request_list; //can get rid of these, these are found in mib_info anyway uint32_t cfdp_id; @@ -62,7 +62,7 @@ void parse_packet_server(char* buff, uint32_t packet_index, Response res, Reques void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); -int process_pdu_header(char*packet, Request *req, Protocol_state *p_state); +int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_state *p_state); //for testing uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); diff --git a/Program/include/requests.h b/Program/include/requests.h index 4b46152..91e5755 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -41,6 +41,9 @@ typedef struct request { uint32_t packet_data_len; + //check to see if this request is empty + uint8_t is_active; + uint8_t segmentation_control; uint8_t fault_handler_overides; uint8_t flow_lable; diff --git a/Program/src/file_delivery_app.a b/Program/src/file_delivery_app.a index 4283d633a53ef5066ca68a1c066d28817a0ff4f3..d3b21022f9840944b73efa7347a16e00a5c3d552 100644 GIT binary patch delta 36925 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

Q(?|JkL0cx4ZqGmPBKM>XrSl|;r=Lluk7_ff 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 SY0p<+lqFhEfv646_5T123!i}i diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index b60be2f..6dcdc30 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -46,16 +46,13 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { strncpy ((char*)p_state->server_port, port, 10); p_state->request_list = linked_list(); - p_state->current_server_request = init_request(p_state->packet_size); - + p_state->current_request = NULL; return p_state; } void ssp_connectionless_server(Protocol_state *p_state) { - - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); } @@ -67,8 +64,8 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { Client *client = ssp_alloc(sizeof(Client), 1); checkAlloc(client, 1); - client->req = NULL; - client->req_queue = linked_list(); + client->current_request = NULL; + client->request_list = linked_list(); client->packet_len = PACKET_LEN; client->cfdp_id = cfdp_id; diff --git a/Program/src/pic.jpeg b/Program/src/pic.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8c727e085507309e22d0059687c15e4d884930d0 GIT binary patch literal 150033 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

u;b_%m1w>npTOZ22dacFAZgy8!w)SVc47OD( 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 z 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 +} //sets destination id in request as the incomming source id, sets transaction number -int process_pdu_header(char*packet, Request *req, Protocol_state *p_state) { +int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; @@ -400,25 +404,47 @@ int process_pdu_header(char*packet, Request *req, Protocol_state *p_state) { packet_index += header->length_of_entity_IDs; if (p_state->my_cfdp_id != dest_id){ - ssp_printf("sequence number: %u should be %u\n", p_state->my_cfdp_id, transaction_sequence_number); ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", p_state->my_cfdp_id, dest_id); - return -1; + return 0; } - uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + Request *request = *req; + + //if packet is from the same request, don't' change current request + if (request != NULL && request->transaction_sequence_number == transaction_sequence_number){ + request->packet_data_len = packet_data_len; + return packet_index; + } - req->packet_data_len = packet_data_len; - req->transmission_mode = header->transmission_mode; - req->dest_cfdp_id = source_id; - req->transaction_sequence_number = transaction_sequence_number; + //look for active request in list + Request *found_req = request_list->find(request_list, transaction_sequence_number, NULL, NULL); + if (found_req == NULL) + { + ssp_printf("no current active requests, looking for new one\n"); + found_req = request_list->find(request_list, 0, find_first_empty_request, NULL); - //set header for responding - if (req->pdu_header == NULL){ - req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); - } + //use already initialized one if can + if (found_req == NULL) { + found_req = init_request(p_state->packet_size); + ssp_printf("no inactive requests, inserting new one\n"); + } + + //Make new request and add it + found_req->packet_data_len = packet_data_len; + found_req->transmission_mode = header->transmission_mode; + found_req->dest_cfdp_id = source_id; + found_req->transaction_sequence_number = transaction_sequence_number; + found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); + found_req->is_active = 1; + request_list->push(request_list, found_req, transaction_sequence_number); + } + + *req = found_req; + + ssp_printf("Transaction number in process header% d\n", (*req)->transaction_sequence_number); return packet_index; @@ -533,7 +559,7 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, Response res, Request *req, Client* client) { - uint32_t packet_index = process_pdu_header(packet, req, client->p_state); + uint32_t packet_index = process_pdu_header(packet, &req, client->request_list, client->p_state); if (packet_index == -1) return; @@ -736,16 +762,6 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { //fills the current_request struct for the server, incomming requests void parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state) { -/* - uint32_t packet_index = process_pdu_header(packet, req, p_state); - if (packet_index == -1) - return; - - //set header for responding - if (req->pdu_header == NULL){ - req->pdu_header = get_header_from_mib(p_state->mib, req->dest_cfdp_id, p_state->my_cfdp_id); - } -*/ if (packet_index == 0) return; diff --git a/Program/src/requests.c b/Program/src/requests.c index 767f976..b747530 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -15,10 +15,11 @@ void ssp_cleanup_req(void *request) { + if (request == NULL) + return; + Request *req = (Request *) request; - if (req == NULL) - return; if (req->file != NULL) free_file(req->file); if (req->pdu_header != NULL) @@ -29,7 +30,8 @@ void ssp_cleanup_req(void *request) { ssp_free(req->destination_file_name); if (req->buff != NULL) ssp_free(req->buff); - ssp_free(req); + if (req != NULL) + ssp_free(req); } @@ -78,7 +80,7 @@ Request *init_request(uint32_t buff_len) { req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); - + req->is_active = 0; req->type = none; checkAlloc(req->buff, 1); return req; @@ -112,7 +114,7 @@ Request *put_request(char *source_file_name, //enumeration req->type = put; - + req->is_active = 1; req->dest_cfdp_id = client->cfdp_id; req->file_size = file_size; @@ -127,7 +129,7 @@ Request *put_request(char *source_file_name, req->filestore_requests = filestore_requests; //client->req_queue->insert(client->req_queue, req, p_state->transaction_sequence_number); - client->req = req; + client->current_request = req; return req; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 8d5e002..7d9df18 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -23,14 +23,19 @@ static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr res.addr = addr; res.sfd = sfd; res.packet_len = p_state->packet_size; - p_state->current_server_request->res = res; + Request **request_container = &p_state->current_request; - uint32_t packet_index = process_pdu_header(packet, p_state->current_server_request, p_state); - if (packet_index == -1) - return; + uint32_t packet_index = process_pdu_header(packet, request_container, p_state->request_list, p_state); - parse_packet_server(packet, packet_index, res, p_state->current_server_request, p_state); + if (packet_index == 0) + return -1; + + + ssp_printf("Transaction number % d\n", (*request_container)->transaction_sequence_number); + (*request_container)->res = res; + + parse_packet_server(packet, packet_index, res, (*request_container), p_state); memset(packet, 0, res.packet_len); return 0; @@ -41,16 +46,16 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr Client *client = (Client *) other; - if (client->req == NULL) + if (client->current_request == NULL) return 0; Response res; res.addr = addr; res.sfd = sfd; res.packet_len = *buff_size; - res.msg = client->req->buff; + res.msg = client->current_request->buff; - parse_packet_client(packet, res, client->req, client); + parse_packet_client(packet, res, client->current_request, client); return 0; } @@ -64,15 +69,15 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { Response res; Client *client = (Client *) other; - if (client->req == NULL) + if (client->current_request == NULL) return 0; res.sfd = sfd; res.packet_len = client->packet_len; - res.msg = client->req->buff; + res.msg = client->current_request->buff; res.addr = client_addr; - user_request_handler(res, client->req, client); + user_request_handler(res, client->current_request, client); return 0; } @@ -80,11 +85,14 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { static int on_time_out_posix(void *other) { Protocol_state *p_state = (Protocol_state*) other; - if(p_state->current_server_request->transaction_sequence_number == 0) + if(p_state->current_request == NULL) + return 0; + + if(p_state->current_request->transaction_sequence_number == 0) return 0; - Response res = p_state->current_server_request->res; - on_server_time_out(res, p_state->current_server_request, p_state); + Response res = p_state->current_request->res; + on_server_time_out(res, p_state->current_request, p_state); return 0; } @@ -205,7 +213,7 @@ void *ssp_connectionless_client_task(void* params){ void ssp_cleanup_p_state(Protocol_state *p_state) { p_state->request_list->free(p_state->request_list, ssp_cleanup_req); - ssp_cleanup_req(p_state->current_server_request); + //ssp_cleanup_req(p_state->current_request); free_mib(p_state->mib); ssp_free(p_state->server_port); ssp_free(p_state); @@ -214,8 +222,8 @@ void ssp_cleanup_p_state(Protocol_state *p_state) { void ssp_cleanup_client(Client *client) { - client->req_queue->free(client->req_queue, ssp_cleanup_req); - ssp_cleanup_req(client->req); + client->request_list->free(client->request_list, ssp_cleanup_req); + ssp_cleanup_req(client->current_request); ssp_cleanup_pdu_header(client->pdu_header); ssp_free(client); } diff --git a/Program/src/utils.c b/Program/src/utils.c index 4c79d50..33bc138 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -260,8 +260,9 @@ static void freeList(List *list, void (*f)(void *element)) { NODE *cur = list->head->next; - while (cur->next != NULL && cur->element != NULL) + while (cur->next != NULL) { + ssp_printf("%d\n", cur->id); NODE *n = cur; cur = cur->next; f(n->element); From 25abceaf4caebcb0f61b4b3674371af7262a527c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 21 Jun 2019 08:48:01 -0600 Subject: [PATCH 060/400] Add tests, why not --- Program/src/main.c | 4 +- Program/src/protocol_handler.c | 4 +- Program/src/tasks.c | 1 - Program/test/filesystem_tests.c | 1 - Program/test/main.c | 218 ++------------------------ Program/test/makefile | 13 +- Program/test/packet_tests.c | 16 +- Program/test/protocol_handler_tests.c | 35 +++++ Program/test/protocol_handler_tests.h | 7 + Program/test/utils.c | 143 +++++++++++++++++ 10 files changed, 225 insertions(+), 217 deletions(-) create mode 100644 Program/test/protocol_handler_tests.c create mode 100644 Program/test/protocol_handler_tests.h create mode 100644 Program/test/utils.c diff --git a/Program/src/main.c b/Program/src/main.c index bf90302..dbb285a 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -43,10 +43,10 @@ int main(int argc, char** argv) { Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged - if (conf->client_cfdp_id == 1) + if (conf->my_cfdp_id == 2) put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - if (conf->client_cfdp_id == 2) + if (conf->my_cfdp_id == 3) put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); ssp_thread_join(new_client->client_handle); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 6686a2b..b044361 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -384,7 +384,9 @@ static int find_first_empty_request(void *element, void *args) { Request *req = (Request *) element; return !req->is_active; } -//sets destination id in request as the incomming source id, sets transaction number +/*creates a request struct if there is none for the incomming request based on transaction sequence number or +finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet +where the data portion is, returns 0 on fail*/ int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 7d9df18..429293d 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -213,7 +213,6 @@ void *ssp_connectionless_client_task(void* params){ void ssp_cleanup_p_state(Protocol_state *p_state) { p_state->request_list->free(p_state->request_list, ssp_cleanup_req); - //ssp_cleanup_req(p_state->current_request); free_mib(p_state->mib); ssp_free(p_state->server_port); ssp_free(p_state); diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 2085256..a41851c 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -23,7 +23,6 @@ static receive_offset_tests(){ receive_offset(file, 0, 50, 100); file->missing_offsets->print(file->missing_offsets, nak_print, 0); - } int file_system_tests() { diff --git a/Program/test/main.c b/Program/test/main.c index 145f9da..db158b5 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -14,220 +14,30 @@ #include "mib.h" #include "packet_tests.h" #include "filesystem_tests.h" +#include "file_delivery_app.h" +#include "protocol_handler_tests.h" -struct myStruct { - int id; - int b; -}; +Protocol_state *init_test() { +Protocol_state *p_state = init_ftp(1); +ssp_connectionless_server(p_state); +ssp_cleanup_p_state(p_state); -static int list_remove(void *element, void *args) { - - int id = *(int *) args; - struct myStruct *st = (struct myStruct *)element; - - if (id == ((struct myStruct*) element)->id) { - free(st); - return 1; - - } - return 0; -} - -static void list_print(void *element, void *args) { - - Offset *offset = (Offset *) element; - printf("missing offsets:start:%u end:%u\n", offset->start, offset->end); - - -} -static int find(void *element, void *args) { - - int id = *(int *) args; - if (id == ((struct myStruct*) element)->id) - return 1; - return 0; -} - - -static void list_free(void *element) { - - free(element); } - int main () { + //init_test(); - MIB *mib = init_mib(); - - //setting host name for testing - char *host_name = "127.0.0.1"; - uint32_t addr[sizeof(uint32_t)]; - inet_pton(AF_INET, host_name, addr); - - //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1315, *addr, 1111); - add_new_cfdp_entity(mib, 2222, *addr, 1112); - - //find server client in mib - Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, 1, NULL, NULL); - if (server_entity == NULL) { - printf("couldn't find entity\n"); - } - - - Pdu_header *header = get_header_from_mib(mib, 2222, 1315); - - + //Pdu_header *header = get_header_from_mib(mib, 2222, 1315); //packet_tests(header); - file_system_tests(); + //file_system_tests(); //request_test_list_storage(); + //free_mib(mib); + //ssp_cleanup_pdu_header(header); + int error = 0; + error = protocol_handler_test(); - - - - - free_mib(mib); - ssp_cleanup_pdu_header(header); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /*test sequence of files - File *file = create_file("test.txt"); - ssp_printf("file size: %u\n", file->total_size); - - uint32_t data_size = PACKET_LEN - 4; - uint32_t data_start = 0; - uint32_t data_end = data_size; - - for (int i=0; i < file->total_size; i+= data_size) { - data_start = i; - data_end = data_size + i; - //ssp_printf("i:%d\n", data_end); - receive_offset(file, 0, data_start, data_end); - } - - receive_offset(file, 0, 48516, 48833); - /* - - //doesnt do this edge case because, would never request it? - - file->missing_offsets->print(file->missing_offsets, list_print, NULL); - - free_file(file); - - char *packet = "hello world"; - uint32_t checksum = calc_check_sum(packet, 10); - printf("%d\n", checksum); - - File *file = create_file("test2.txt"); - - checksum = check_sum_file(file, file->total_size, 20000); - printf("%d\n", checksum); - /* - char **ptr,*ptr1,*ptr2,*ptr3; - - ptr = malloc(sizeof(char*) * 2); - ptr1 = malloc(1); - ptr2 = malloc(1); - - *ptr1 = 'h'; - *ptr2 = 'i'; - - ptr[0] = ptr1; - ptr[1] = ptr2; - - printf("%c%c\n", *ptr[0], *ptr[1]); - - */ - - List *list = linked_list(); - //static void *findElement(List *list, int (*f)(void *element, void *args), void *args) - - struct myStruct *st = malloc(sizeof(struct myStruct)); - struct myStruct *st2 = malloc(sizeof(struct myStruct)); - struct myStruct *st3 = malloc(sizeof(struct myStruct)); - - st->id = 1; - st->b = 2; - - st2->id = 2; - st2->b = 3; - - st3->id = 3; - st3->b = 4; - - list->insert(list, st, 1); - list->insert(list, st2, 2); - list->push(list, st3, 3); - - list->push(list, list->pop(list), list->count); - - /* - list->insert(list, st3, 3); - list->print(list, list_print, NULL); - - //list_free(list->pop(list)); - - int id = 1; - struct myStruct *found = list->find(list, 1, NULL, NULL); - printf("found %d\n", found->id); - - id = 2; - found = list->find(list, 2, find, &id); - printf("found %d\n", found->id); - - found = list->find(list, 3, NULL, NULL); - printf("found %d\n", found->id); - - void * element = list->pop(list); - //free(list->remove(list, "3", NULL, NULL)); - //free(list->remove(list, "2", NULL, NULL)); - - - list->print(list, list_print, NULL); - */ - list->free(list, list_free); - - return 0; + return 0; } \ No newline at end of file diff --git a/Program/test/makefile b/Program/test/makefile index 7ba8469..77a75c5 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -11,11 +11,15 @@ CFILES += $(PROJDIR)/src/filesystem_funcs.c CFILES += $(PROJDIR)/src/port.c CFILES += $(PROJDIR)/src/server.c CFILES += $(PROJDIR)/src/protocol_handler.c -CFILES += $(PROJDIR)/src/list_callbacks.c CFILES += $(PROJDIR)/src/mib.c CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c - +CFILES += $(PROJDIR)/test/request_tests.c +CFILES += $(PROJDIR)/test/filesystem_tests.c +CFILES += $(PROJDIR)/test/protocol_handler_tests.c +CFILES += $(PROJDIR)/src/requests.c +CFILES += $(PROJDIR)/src/tasks.c +CFILES += $(PROJDIR)/src/file_delivery_app.c #entrypoint MAIN = main @@ -35,8 +39,8 @@ CWARNS += -Wuninitialized CWARNS += -Wunknown-pragmas CWARNS += -Wunused-function CWARNS += -Wunused-label -CWARNS += -Wunused-parameter -CWARNS += -Wunused-value +#CWARNS += -Wunused-parameter +#CWARNS += -Wunused-value CWARNS += -Wunused-variable CWARNS += -Wmissing-prototypes @@ -61,6 +65,7 @@ CFLAGS += $(INCLUDE) $(CWARNS) OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) all: $(MAIN) + mv *.o ./obj .PHONY: clean diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 3162b8c..36702a7 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -16,9 +16,13 @@ static int test_respond_to_naks(char *packet, uint32_t packet_index) { ssp_cleanup_req(req); + return 0; + } static int test_respond_metadata_request() { + + return 0; } @@ -123,13 +127,11 @@ static int test_build_nak_packet(char* packet, uint32_t start) { ASSERT_EQUALS_INT("correct packet offset 3 end", end_scope, 100000); Pdu_header *header = (Pdu_header*) packet; - ssp_printf("datalen %u\n", header->PDU_data_field_len); - ssp_printf("datalen %u\n", data_len); - ASSERT_EQUALS_INT("correct packet data_len", data_len, header->PDU_data_field_len); + ASSERT_EQUALS_INT("correct packet data_len", data_len, ntohs(header->PDU_data_field_len)); ssp_cleanup_req(req); - return 1; + return 0; } int test_build_ack_finished_pdu(char *packet, uint32_t start) { @@ -143,6 +145,9 @@ int test_build_ack_finished_pdu(char *packet, uint32_t start) { ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack->directive_code); ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack->condition_code); ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack->directive_subtype_code, ACK_FINISHED_END); + + + return 0; } @@ -160,6 +165,8 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack->directive_code); ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack->condition_code); ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack->directive_subtype_code, ACK_FINISHED_END); + + return 0; } int test_build_pdu_header_header(char *packet, Pdu_header *header, uint64_t sequence_number) { @@ -210,5 +217,6 @@ int packet_tests(Pdu_header *header) { ssp_free(packet); + return 0; } \ No newline at end of file diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c new file mode 100644 index 0000000..e7c95df --- /dev/null +++ b/Program/test/protocol_handler_tests.c @@ -0,0 +1,35 @@ + + +#include "protocol_handler.h" +#include "stdlib.h" +#include "mib.h" + +static char *build_mock_packet(Protocol_state *p_state, uint32_t id) { + + char *packet = calloc(sizeof(char*), 2000); + Pdu_header *pdu_header = get_header_from_mib(p_state->mib, 1, id); + build_pdu_header(packet, 1, 0, pdu_header); + return packet; +} + +static int test_process_pdu_header() { + + + Protocol_state *p_state = init_ftp(1); + Request **req_container = &p_state->current_request; + + char *packet = build_mock_packet(p_state, 2); + process_pdu_header(packet, req_container, p_state->request_list, p_state); + + + + free(packet); + ssp_cleanup_p_state(p_state); +} + + +int protocol_handler_test() { + int error = 0; + error = test_process_pdu_header(); + return error; +} \ No newline at end of file diff --git a/Program/test/protocol_handler_tests.h b/Program/test/protocol_handler_tests.h new file mode 100644 index 0000000..8a3a9a5 --- /dev/null +++ b/Program/test/protocol_handler_tests.h @@ -0,0 +1,7 @@ + +#ifndef PROTOCL_HANDLER_TEST_H +#define PROTOCL_HANDLER_TEST_H + + + int protocol_handler_test(); +#endif diff --git a/Program/test/utils.c b/Program/test/utils.c new file mode 100644 index 0000000..d9cc988 --- /dev/null +++ b/Program/test/utils.c @@ -0,0 +1,143 @@ + +/* +struct myStruct { + int id; + int b; +}; + + +static int list_remove(void *element, void *args) { + + int id = *(int *) args; + struct myStruct *st = (struct myStruct *)element; + + if (id == ((struct myStruct*) element)->id) { + free(st); + return 1; + + } + return 0; +} + +static void list_print(void *element, void *args) { + + Offset *offset = (Offset *) element; + printf("missing offsets:start:%u end:%u\n", offset->start, offset->end); + + +} +static int find(void *element, void *args) { + + int id = *(int *) args; + if (id == ((struct myStruct*) element)->id) + return 1; + return 0; +} + + +static void list_free(void *element) { + + free(element); +} +*/ + + + + + /*test sequence of files + File *file = create_file("test.txt"); + ssp_printf("file size: %u\n", file->total_size); + + uint32_t data_size = PACKET_LEN - 4; + uint32_t data_start = 0; + uint32_t data_end = data_size; + + for (int i=0; i < file->total_size; i+= data_size) { + data_start = i; + data_end = data_size + i; + //ssp_printf("i:%d\n", data_end); + receive_offset(file, 0, data_start, data_end); + } + + receive_offset(file, 0, 48516, 48833); + /* + + //doesnt do this edge case because, would never request it? + + file->missing_offsets->print(file->missing_offsets, list_print, NULL); + + free_file(file); + + char *packet = "hello world"; + uint32_t checksum = calc_check_sum(packet, 10); + printf("%d\n", checksum); + + File *file = create_file("test2.txt"); + + checksum = check_sum_file(file, file->total_size, 20000); + printf("%d\n", checksum); + /* + char **ptr,*ptr1,*ptr2,*ptr3; + + ptr = malloc(sizeof(char*) * 2); + ptr1 = malloc(1); + ptr2 = malloc(1); + + *ptr1 = 'h'; + *ptr2 = 'i'; + + ptr[0] = ptr1; + ptr[1] = ptr2; + + printf("%c%c\n", *ptr[0], *ptr[1]); + + + + List *list = linked_list(); + //static void *findElement(List *list, int (*f)(void *element, void *args), void *args) + + struct myStruct *st = malloc(sizeof(struct myStruct)); + struct myStruct *st2 = malloc(sizeof(struct myStruct)); + struct myStruct *st3 = malloc(sizeof(struct myStruct)); + + st->id = 1; + st->b = 2; + + st2->id = 2; + st2->b = 3; + + st3->id = 3; + st3->b = 4; + + list->insert(list, st, 1); + list->insert(list, st2, 2); + list->push(list, st3, 3); + + list->push(list, list->pop(list), list->count); + + /* + list->insert(list, st3, 3); + list->print(list, list_print, NULL); + + //list_free(list->pop(list)); + + int id = 1; + struct myStruct *found = list->find(list, 1, NULL, NULL); + printf("found %d\n", found->id); + + id = 2; + found = list->find(list, 2, find, &id); + printf("found %d\n", found->id); + + found = list->find(list, 3, NULL, NULL); + printf("found %d\n", found->id); + + void * element = list->pop(list); + //free(list->remove(list, "3", NULL, NULL)); + //free(list->remove(list, "2", NULL, NULL)); + + + list->print(list, list_print, NULL); + + list->free(list, list_free); + */ \ No newline at end of file From a722a7cf73e778dc99c793a6a4c372095b3f5f9f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 21 Jun 2019 14:37:22 -0600 Subject: [PATCH 061/400] Tidy up tests a little bit, add multiple server files should work --- Program/src/protocol_handler.c | 33 ++++++++++-- Program/src/utils.c | 9 ++-- Program/test/filesystem_tests.c | 4 +- Program/test/main.c | 5 +- Program/test/packet_tests.c | 26 +++++++-- Program/test/protocol_handler_tests.c | 13 ++++- Program/test/request_tests.c | 77 ++++++++++++++++++++++++++- Program/test/request_tests.h | 3 +- 8 files changed, 151 insertions(+), 19 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index b044361..289f183 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -380,10 +380,29 @@ int process_file_request_metadata(Request *req) { return 1; } + + + + static int find_first_empty_request(void *element, void *args) { Request *req = (Request *) element; return !req->is_active; } + +//for finding the struct in the list +struct request_search_params { + uint32_t source_id; + uint32_t transaction_sequence_number; +}; + +//for finding the struct in the list +static int find_request(void *element, void *args) { + Request *req = (Request *) element; + struct request_search_params *params = (struct request_search_params *) args; + if (req->dest_cfdp_id == params->source_id && req->transaction_sequence_number == params->transaction_sequence_number) + return 1; + return 0; +} /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns 0 on fail*/ @@ -415,13 +434,21 @@ int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_ Request *request = *req; //if packet is from the same request, don't' change current request - if (request != NULL && request->transaction_sequence_number == transaction_sequence_number){ + if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ request->packet_data_len = packet_data_len; return packet_index; } //look for active request in list - Request *found_req = request_list->find(request_list, transaction_sequence_number, NULL, NULL); + struct request_search_params params = { + source_id, + transaction_sequence_number, + }; + + + + Request *found_req = request_list->find(request_list, 0, find_request, ¶ms); + if (found_req == NULL) { @@ -446,8 +473,6 @@ int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_ *req = found_req; - ssp_printf("Transaction number in process header% d\n", (*req)->transaction_sequence_number); - return packet_index; } diff --git a/Program/src/utils.c b/Program/src/utils.c index 33bc138..57e8734 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -262,7 +262,6 @@ static void freeList(List *list, void (*f)(void *element)) while (cur->next != NULL) { - ssp_printf("%d\n", cur->id); NODE *n = cur; cur = cur->next; f(n->element); @@ -290,14 +289,12 @@ static void *findElement(List *list, uint32_t id, int (*f)(void *element, void * if (f != NULL) found_with_func = f(cur->element, args); - if(id != -1 && cur->id == id) + if(id != 0 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id){ return cur->element; - } - cur = cur->next; } return NULL; @@ -313,7 +310,7 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme if (f != NULL) found_with_func = f(cur->element, args); - if(id != -1 && cur->id == id) + if(id != 0 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id) { @@ -342,7 +339,7 @@ static NODE * findNode(List *list, uint32_t id, int (*f)(void *element, void *ar if (f != NULL) found_with_func = f(cur->element, args); - if(id != -1 && cur->id == id) + if(id != 0 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id){ diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index a41851c..7b537c2 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -26,5 +26,7 @@ static receive_offset_tests(){ } int file_system_tests() { - receive_offset_tests(); + int error = 0; + error = receive_offset_tests(); + return error; } \ No newline at end of file diff --git a/Program/test/main.c b/Program/test/main.c index db158b5..a232539 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -36,8 +36,11 @@ int main () { //free_mib(mib); //ssp_cleanup_pdu_header(header); int error = 0; - error = protocol_handler_test(); + error = request_tests(); + error = protocol_handler_test(); + error = packet_tests(); + //error = file_system_tests(); return 0; } \ No newline at end of file diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 36702a7..d9076a5 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -7,6 +7,7 @@ #include "filesystem_funcs.h" #include "port.h" #include "protocol_handler.h" +#include "mib.h" #define PACKET_TEST_SIZE 2000 @@ -205,17 +206,36 @@ int test_build_pdu_header_header(char *packet, Pdu_header *header, uint64_t sequ return packet_index; } -int packet_tests(Pdu_header *header) { +int packet_tests() { printf("starting Packet Tests (creating and changing packet values)\n"); + + //Memory information base + MIB *mib = init_mib(); + + //setting host name for testing + char *host_name = "127.0.0.1"; + uint32_t addr[sizeof(uint32_t)]; + inet_pton(AF_INET, host_name, addr); + + //adding new cfdp entities to management information base + add_new_cfdp_entity(mib, 1, *addr, 1111); + add_new_cfdp_entity(mib, 2, *addr, 1112); + add_new_cfdp_entity(mib, 3, *addr, 1113); + add_new_cfdp_entity(mib, 4, *addr, 1114); + + Pdu_header *pdu_header = get_header_from_mib(mib, 1, 2); + + char *packet = calloc(PACKET_TEST_SIZE, sizeof(char)); uint64_t sequence_number = 12345663234; - int packet_index = test_build_pdu_header_header(packet, header, sequence_number); + int packet_index = test_build_pdu_header_header(packet, pdu_header, sequence_number); test_build_ack_eof_pdu(packet, packet_index); test_build_nak_packet(packet, packet_index); test_respond_to_naks(packet, packet_index); - + free_mib(mib); + ssp_cleanup_pdu_header(pdu_header); ssp_free(packet); return 0; diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index e7c95df..d132d00 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -3,12 +3,14 @@ #include "protocol_handler.h" #include "stdlib.h" #include "mib.h" +#include "test.h" static char *build_mock_packet(Protocol_state *p_state, uint32_t id) { char *packet = calloc(sizeof(char*), 2000); Pdu_header *pdu_header = get_header_from_mib(p_state->mib, 1, id); build_pdu_header(packet, 1, 0, pdu_header); + ssp_cleanup_pdu_header(pdu_header); return packet; } @@ -18,12 +20,21 @@ static int test_process_pdu_header() { Protocol_state *p_state = init_ftp(1); Request **req_container = &p_state->current_request; + //test 1 char *packet = build_mock_packet(p_state, 2); process_pdu_header(packet, req_container, p_state->request_list, p_state); - + ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); + ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 2); + //test 2 + char *packet2 = build_mock_packet(p_state, 3); + process_pdu_header(packet2, req_container, p_state->request_list, p_state); + ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); + ASSERT_NOT_EQUALS_INT("souce id should not equal", (*req_container)->dest_cfdp_id, 2); + ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 3); free(packet); + free(packet2); ssp_cleanup_p_state(p_state); } diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index ef44ca6..d7c7a6f 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -2,14 +2,82 @@ #include "port.h" #include "requests.h" #include "string.h" +#include "test.h" +static void list_print_id(void *element, void *args) { + Request *req = (Request *) element; + printf("id: %d trans number: %d\n", req->dest_cfdp_id, req->transaction_sequence_number); +} + +//for finding the struct in the list +struct request_search_params { + uint32_t source_id; + uint32_t transaction_sequence_number; +}; + +//for finding the struct in the list +static int find_request(void *element, void *args) { + Request *req = (Request *) element; + struct request_search_params *params = (struct request_search_params *) args; + if (req->dest_cfdp_id = params->source_id && req->transaction_sequence_number == params->transaction_sequence_number) + return 1; + return 0; +} + static void list_print(void *element, void *args) { Request *req = (Request *) element; ssp_printf("%s\n", req->source_file_name); } +int request_finding_test() { + + List *list = linked_list(); + + Request *req = init_request(2000); + req->dest_cfdp_id = 1; + req->transaction_sequence_number = 1; + list->push(list, req, req->dest_cfdp_id); + + Request *req2 = init_request(2000); + req2->dest_cfdp_id = 3; + req2->transaction_sequence_number = 1; + list->push(list, req2, req2->dest_cfdp_id); + + Request *req3 = init_request(2000); + req3->dest_cfdp_id = 2; + req3->transaction_sequence_number = 2; + list->push(list, req3, req3->dest_cfdp_id); + + + struct request_search_params params = { + req->dest_cfdp_id, + req->transaction_sequence_number, + }; + + Request *found = list->find(list, 0, find_request, ¶ms); + params.source_id = 3; + params.transaction_sequence_number = 1; + Request *found2 = list->find(list, 0, find_request, ¶ms); + params.source_id = 2; + params.transaction_sequence_number = 2; + Request *found3 = list->find(list, 0, find_request, ¶ms); + + if (found == NULL) { + ssp_printf("CAN't FIND request IS NULL\n"); + list->free(list, ssp_cleanup_req); + return 1; + } + + ASSERT_EQUALS_INT("finding test, should equal", req->dest_cfdp_id, found->dest_cfdp_id); + ASSERT_EQUALS_INT("finding test, should equal", req2->dest_cfdp_id, found2->dest_cfdp_id); + ASSERT_EQUALS_INT("finding test, should equal", req3->dest_cfdp_id, found3->dest_cfdp_id); + + list->free(list, ssp_cleanup_req); + return 0; +} + void request_test_list_storage() { Request *req = init_request(5000); @@ -29,9 +97,16 @@ void request_test_list_storage() { memcpy(req3->source_file_name, "stuff3", 7); list->insert(list, req3, 3); - ssp_cleanup_req(list->pop(list)); list->print(list, list_print, NULL); list->free(list, ssp_cleanup_req); +} + + +int request_tests() { + + int error = 0; + error = request_finding_test(); + return 0; } \ No newline at end of file diff --git a/Program/test/request_tests.h b/Program/test/request_tests.h index 00e9932..b3e05f5 100644 --- a/Program/test/request_tests.h +++ b/Program/test/request_tests.h @@ -6,8 +6,7 @@ - -void request_test_list_storage(); +int request_tests(); From 27a04a333f39c65021f65e5208f162ca43829852 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 23 Jun 2019 08:57:13 -0600 Subject: [PATCH 062/400] server can receive multiple files, add start.sh to simulate packetloss --- Program/include/protocol_handler.h | 5 +-- Program/include/requests.h | 5 +++ Program/include/server.h | 2 +- Program/src/protocol_handler.c | 60 ++++++++++++------------------ Program/src/requests.c | 8 +++- Program/src/server.c | 4 +- Program/src/start.sh | 1 + Program/src/tasks.c | 37 ++++++++++++------ 8 files changed, 68 insertions(+), 54 deletions(-) create mode 100644 Program/src/start.sh diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 170a99e..e56fa5b 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -23,7 +23,6 @@ typedef struct protocol_state { uint32_t transaction_sequence_number; uint8_t verbose_level; - uint32_t timeout; //bool for exiting the server thread uint8_t close; @@ -61,8 +60,8 @@ typedef struct client { void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, Response res, Request *req, Client *client); -void on_server_time_out(Response res, Request *current_request, Protocol_state *p_state); -int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_state *p_state); +void on_server_time_out(Response res, Request *current_request); +int process_pdu_header(char*packet, Response res, Request **req, List *request_list, Protocol_state *p_state); //for testing uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); diff --git a/Program/include/requests.h b/Program/include/requests.h index 91e5755..b2ed4ff 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -12,6 +12,8 @@ typedef struct response { //this is type (struct sockaddr_in) in posix void *addr; //getting rid of this soon in favour of client based packet sizes + + size_t size_of_addr; uint32_t packet_len; } Response; @@ -44,6 +46,9 @@ typedef struct request { //check to see if this request is empty uint8_t is_active; + //timeout + uint8_t timeout; + uint8_t segmentation_control; uint8_t fault_handler_overides; uint8_t flow_lable; diff --git a/Program/include/server.h b/Program/include/server.h index ba198f2..6bad2b9 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -43,7 +43,7 @@ int prepareUdpHost(char *port); ------------------------------------------------------------------------------*/ void udpSelectServer(char* port, int packet_len, - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other), + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), int (*checkExit)(void *other), diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 289f183..c233070 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -381,14 +381,6 @@ int process_file_request_metadata(Request *req) { } - - - -static int find_first_empty_request(void *element, void *args) { - Request *req = (Request *) element; - return !req->is_active; -} - //for finding the struct in the list struct request_search_params { uint32_t source_id; @@ -406,7 +398,7 @@ static int find_request(void *element, void *args) { /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns 0 on fail*/ -int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_state *p_state) { +int process_pdu_header(char*packet, Response res, Request **req, List *request_list, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; @@ -425,7 +417,6 @@ int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_ packet_index += header->length_of_entity_IDs; if (p_state->my_cfdp_id != dest_id){ - ssp_printf("sequence number: %u should be %u\n", p_state->my_cfdp_id, transaction_sequence_number); ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", p_state->my_cfdp_id, dest_id); return 0; } @@ -445,30 +436,32 @@ int process_pdu_header(char*packet, Request **req, List *request_list, Protocol_ transaction_sequence_number, }; - - Request *found_req = request_list->find(request_list, 0, find_request, ¶ms); if (found_req == NULL) { - - ssp_printf("no current active requests, looking for new one\n"); - found_req = request_list->find(request_list, 0, find_first_empty_request, NULL); - - //use already initialized one if can - if (found_req == NULL) { - found_req = init_request(p_state->packet_size); - ssp_printf("no inactive requests, inserting new one\n"); - } - + found_req = init_request(p_state->packet_size); + ssp_printf("incoming new request\n"); //Make new request and add it found_req->packet_data_len = packet_data_len; found_req->transmission_mode = header->transmission_mode; + found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); found_req->is_active = 1; + + ssp_printf("addr length %d\n", res.size_of_addr); + + found_req->res.addr = ssp_alloc(res.size_of_addr, 1); + memcpy(found_req->res.addr, res.addr, res.size_of_addr); + + found_req->res.packet_len = p_state->packet_size; + found_req->res.sfd = res.sfd; + found_req->res.msg = found_req->buff; request_list->push(request_list, found_req, transaction_sequence_number); + ssp_printf("source id: %d transaction sequence numer :%d\n", source_id, transaction_sequence_number); + } *req = found_req; @@ -586,7 +579,7 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, Response res, Request *req, Client* client) { - uint32_t packet_index = process_pdu_header(packet, &req, client->request_list, client->p_state); + uint32_t packet_index = process_pdu_header(packet, res, &req, client->request_list, client->p_state); if (packet_index == -1) return; @@ -643,8 +636,6 @@ static void check_req_status(Request *req, Client *client) { ssp_printf("file successfully sent\n"); req->resent_finished = 4; client->close = 1; - //ssp_cleanup_req(client->req); - //client->req = NULL; } } @@ -709,28 +700,28 @@ void user_request_handler(Response res, Request *req, Client* client) { ------------------------------------------------------------------------------*/ -static void reset_timeout(Protocol_state *p_state, Request *req) { +static void reset_timeout(Request *req) { - uint32_t time = p_state->timeout++; - ssp_printf("timeout %u\n", time); + uint8_t time = req->timeout++; + ssp_printf("timeout %u for id: %u sequence: %u\n", time, req->dest_cfdp_id, req->transaction_sequence_number); if (time == 20) { - p_state->timeout = 0; + req->timeout = 0; reset_request(req); ssp_printf("timeout, resetting request\n"); } } -void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { +void on_server_time_out(Response res, Request *req) { - res.msg = req->buff; if (req->type == none) return; if (req->buff == NULL) ssp_printf("req buffer is null, couldn't process timeout request\n"); - reset_timeout(p_state, req); + reset_timeout(req); + ssp_printf("source id: %d transaction sequence numer :%d\n", req->dest_cfdp_id, req->transaction_sequence_number); uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); //Pdu_header *pdu_header = (Pdu_header *) &res.msg; @@ -775,7 +766,6 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); } } - //received EOF, send back 3 eof packets if (req->received_eof && req->resent_eof < 3) { ssp_printf("sending eof ack\n"); @@ -783,8 +773,6 @@ void on_server_time_out(Response res, Request *req, Protocol_state *p_state) { ssp_sendto(res); req->resent_eof++; } - - } //fills the current_request struct for the server, incomming requests @@ -796,7 +784,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_header *header = (Pdu_header *) packet; //will protbably have to timeout different clients? how does that work with ddos? - p_state->timeout = 0; + req->timeout = 0; //process file data if (header->PDU_type == 1) { if (!req->received_metadata) { diff --git a/Program/src/requests.c b/Program/src/requests.c index b747530..39106eb 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -30,6 +30,8 @@ void ssp_cleanup_req(void *request) { ssp_free(req->destination_file_name); if (req->buff != NULL) ssp_free(req->buff); + if (req->res.addr != NULL) + ssp_free(req->res.addr); if (req != NULL) ssp_free(req); @@ -37,6 +39,9 @@ void ssp_cleanup_req(void *request) { void reset_request(Request *req){ + + req->is_active = 0; +/* memset(req->source_file_name, 0, MAX_PATH); memset(req->destination_file_name, 0, MAX_PATH); memset(req->buff, 0, req->buff_len); @@ -54,6 +59,7 @@ void reset_request(Request *req){ req->transaction_sequence_number = 0; req->transmission_mode = 1; req->type = none; + req->is_active = 0; if (req->file != NULL) free_file(req->file); @@ -63,7 +69,7 @@ void reset_request(Request *req){ } req->file = NULL; req->type = none; - + */ } diff --git a/Program/src/server.c b/Program/src/server.c index 91ec3e0..00e07a7 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -144,7 +144,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf //see header file void udpSelectServer(char* port, int packet_len, - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other), + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), int (*checkExit)(void *other), @@ -231,7 +231,7 @@ void udpSelectServer(char* port, int packet_len, } else { - if (onRecv(sfd, buff, buff_size, (void*) client, other) == -1) + if (onRecv(sfd, buff, buff_size, (void*) client, sizeof(struct sockaddr), other) == -1) printf("recv failed\n"); } } diff --git a/Program/src/start.sh b/Program/src/start.sh new file mode 100644 index 0000000..d5cac58 --- /dev/null +++ b/Program/src/start.sh @@ -0,0 +1 @@ +sudo tc qdisc add dev lo root netem loss 10% diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 429293d..bb5ced8 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -16,25 +16,23 @@ ------------------------------------------------------------------------------*/ //this function is a callback when using my posix port -static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other) { +static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { Protocol_state *p_state = (Protocol_state *) other; Response res; res.addr = addr; res.sfd = sfd; res.packet_len = p_state->packet_size; + res.size_of_addr = size_of_addr; Request **request_container = &p_state->current_request; - uint32_t packet_index = process_pdu_header(packet, request_container, p_state->request_list, p_state); + uint32_t packet_index = process_pdu_header(packet, res, request_container, p_state->request_list, p_state); + p_state->current_request = (*request_container); if (packet_index == 0) return -1; - - ssp_printf("Transaction number % d\n", (*request_container)->transaction_sequence_number); - (*request_container)->res = res; - parse_packet_server(packet, packet_index, res, (*request_container), p_state); memset(packet, 0, res.packet_len); @@ -81,6 +79,27 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { return 0; } + +static int timeout_remove_request(void *request, void *args) { + Request *req = (Request *) request; + Request *req2 = (Request *) args; + if (req->dest_cfdp_id == req2->dest_cfdp_id && req->transaction_sequence_number == req2->transaction_sequence_number) + return 1; + return 0; +} + +static void timeout_check(void *request, void *args) { + Request *req = (Request *) request; + List *req_list = (List *) args; + + on_server_time_out(req->res, req); + + if (!req->is_active) { + Request *removed = req_list->remove(req_list, 0, timeout_remove_request, req); + ssp_cleanup_req(removed); + } + +} //this function is a callback when using my posix ports static int on_time_out_posix(void *other) { @@ -88,11 +107,7 @@ static int on_time_out_posix(void *other) { if(p_state->current_request == NULL) return 0; - if(p_state->current_request->transaction_sequence_number == 0) - return 0; - - Response res = p_state->current_request->res; - on_server_time_out(res, p_state->current_request, p_state); + p_state->request_list->print(p_state->request_list, timeout_check, p_state->request_list); return 0; } From 73fa7a0b0a544437bb557922823807431d60874e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 23 Jun 2019 14:37:09 -0600 Subject: [PATCH 063/400] fixed bug where server would segfault after removing file. --- Program/include/protocol_handler.h | 2 +- Program/include/server.h | 2 +- Program/include/utils.h | 1 + Program/src/main.c | 13 ++++--- Program/src/protocol_handler.c | 13 ++----- Program/src/requests.c | 3 +- Program/src/server.c | 4 +-- Program/src/tasks.c | 57 ++++++++++++++++++++++-------- Program/src/utils.c | 21 +++++------ 9 files changed, 71 insertions(+), 45 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index e56fa5b..6f11ebb 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -59,7 +59,7 @@ typedef struct client { //for use void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client); -void parse_packet_client(char* buff, Response res, Request *req, Client *client); +void parse_packet_client(char* buff, uint32_t packet_index, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request); int process_pdu_header(char*packet, Response res, Request **req, List *request_list, Protocol_state *p_state); diff --git a/Program/include/server.h b/Program/include/server.h index 6bad2b9..bef6340 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -63,7 +63,7 @@ int *prepareSignalHandler(void); void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *onRecvParams) , + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); diff --git a/Program/include/utils.h b/Program/include/utils.h index 28af650..a473af3 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -53,6 +53,7 @@ typedef struct List //returns a void pointer that should be cast to the type void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); struct NODE *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + void (*freeNode)(NODE *node); } List; diff --git a/Program/src/main.c b/Program/src/main.c index dbb285a..32b8a81 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -34,8 +34,9 @@ int main(int argc, char** argv) { return 1; } Protocol_state *p_state = init_ftp(conf->my_cfdp_id); + ssp_connectionless_server(p_state); - + //create a client if (conf->client_cfdp_id != 0){ @@ -43,18 +44,20 @@ int main(int argc, char** argv) { Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged - if (conf->my_cfdp_id == 2) + if (conf->my_cfdp_id == 2) { put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - - if (conf->my_cfdp_id == 3) put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + } + if (conf->my_cfdp_id == 3) + put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + + ssp_thread_join(new_client->client_handle); ssp_printf("client disconnected\n"); } ssp_thread_join(p_state->server_handle); - ssp_free(conf); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index c233070..68d5b26 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -438,6 +438,7 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l Request *found_req = request_list->find(request_list, 0, find_request, ¶ms); + //server side, receiving requests if (found_req == NULL) { found_req = init_request(p_state->packet_size); @@ -450,17 +451,13 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); found_req->is_active = 1; - - ssp_printf("addr length %d\n", res.size_of_addr); - found_req->res.addr = ssp_alloc(res.size_of_addr, 1); memcpy(found_req->res.addr, res.addr, res.size_of_addr); - + found_req->res.packet_len = p_state->packet_size; found_req->res.sfd = res.sfd; found_req->res.msg = found_req->buff; request_list->push(request_list, found_req, transaction_sequence_number); - ssp_printf("source id: %d transaction sequence numer :%d\n", source_id, transaction_sequence_number); } @@ -577,11 +574,8 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien //fills the current request with packet data, responses from servers -void parse_packet_client(char *packet, Response res, Request *req, Client* client) { +void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { - uint32_t packet_index = process_pdu_header(packet, res, &req, client->request_list, client->p_state); - if (packet_index == -1) - return; //Pdu_header *header = (Pdu_header *) packet; //uint16_t incoming_packet_data_len = ntohs(header->PDU_data_field_len); @@ -635,7 +629,6 @@ static void check_req_status(Request *req, Client *client) { if (req->resent_finished == 3) { ssp_printf("file successfully sent\n"); req->resent_finished = 4; - client->close = 1; } } diff --git a/Program/src/requests.c b/Program/src/requests.c index 39106eb..f445362 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -134,8 +134,7 @@ Request *put_request(char *source_file_name, req->messages_to_user = messages_to_user; req->filestore_requests = filestore_requests; - //client->req_queue->insert(client->req_queue, req, p_state->transaction_sequence_number); - client->current_request = req; + client->request_list->insert(client->request_list, req, p_state->transaction_sequence_number); return req; } diff --git a/Program/src/server.c b/Program/src/server.c index 00e07a7..ff98327 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -249,7 +249,7 @@ void udpSelectServer(char* port, int packet_len, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *onRecvParams) , + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) { @@ -316,7 +316,7 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo } else { - if (onRecv(sfd, buff, buff_size, (void *)&serveraddr, onRecvParams) == -1) + if (onRecv(sfd, buff, buff_size, (void *)&serveraddr, sizeof(struct sockaddr), onRecvParams) == -1) printf("recv failed\n"); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index bb5ced8..4024c2a 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -40,42 +40,70 @@ static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr } -static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other) { +static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { Client *client = (Client *) other; - if (client->current_request == NULL) - return 0; Response res; res.addr = addr; res.sfd = sfd; - res.packet_len = *buff_size; - res.msg = client->current_request->buff; - - parse_packet_client(packet, res, client->current_request, client); + res.packet_len = client->packet_len; + res.size_of_addr = size_of_addr; + + Request **request_container = &client->current_request; + + uint32_t packet_index = process_pdu_header(packet, res, request_container, client->request_list, client->p_state); + if (packet_index == -1) { + ssp_printf("error parsing header\n"); + return -1; + } + + client->current_request = (*request_container); + client->current_request->res = res; + ssp_printf("server transaction number %d and Id %d\n", (*request_container)->transaction_sequence_number, (*request_container)->dest_cfdp_id); + + parse_packet_client(packet, packet_index, res, (*request_container), client); + memset(packet, 0, res.packet_len); return 0; } + +static struct user_request_check_params { + Response res; + Client *client; +}; + +static void user_request_check(void *request, void *args) { + Request * req = (Request *) request; + struct user_request_check_params* params = (struct user_request_check_params *) args; + + params->res.msg = req->buff; + user_request_handler(params->res, req, params->client); +} + static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { #ifdef POSIX_PORT struct sockaddr_in* client_addr = (struct sockaddr_in*) &addr; #endif - + Response res; Client *client = (Client *) other; - if (client->current_request == NULL) - return 0; res.sfd = sfd; res.packet_len = client->packet_len; - res.msg = client->current_request->buff; res.addr = client_addr; + + struct user_request_check_params params = { + res, + client + }; - user_request_handler(res, client->current_request, client); + client->request_list->print(client->request_list, user_request_check, ¶ms); + return 0; } @@ -95,8 +123,9 @@ static void timeout_check(void *request, void *args) { on_server_time_out(req->res, req); if (!req->is_active) { - Request *removed = req_list->remove(req_list, 0, timeout_remove_request, req); - ssp_cleanup_req(removed); + Request *remove_this = req_list->remove(req_list, 0, timeout_remove_request, req); + ssp_cleanup_req(remove_this); + } } diff --git a/Program/src/utils.c b/Program/src/utils.c index 57e8734..d3b6098 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -125,7 +125,8 @@ NODE *createNode(void *element, uint32_t id) static void freeNode(NODE *node) { - ssp_free(node); + if (node != NULL) + ssp_free(node); } static void *pop(List *list) { @@ -204,16 +205,18 @@ static int push(List *list, void *element, uint32_t id) static void printList(List *list, void (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; + NODE *next; while (cur->next != NULL) { + next = cur->next; f(cur->element, args); - cur = cur->next; + cur = next; } } /*------------------------------------------------------------------------------ - This function removes an element from the linked list, returns the element stored if success + This function removes an element from the linked list, returns the node stored if success and NULL if item not found. it can use either an id, or callback to find the element (callback can be the find function) ------------------------------------------------------------------------------*/ @@ -238,10 +241,10 @@ static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void previous->next = next; next->prev = previous; + + list->count--; void *element = cur->element; - freeNode(cur); - list->count--; return element; } cur = cur->next; @@ -328,9 +331,8 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme } -static NODE * findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { +static NODE *findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { - NODE *cur = list->head->next; int found_with_func = 0; int found_with_id = 0; @@ -344,13 +346,10 @@ static NODE * findNode(List *list, uint32_t id, int (*f)(void *element, void *ar if (found_with_func || found_with_id){ return cur; - } - cur = cur->next; } return NULL; - } //see header file return NULL if fails @@ -385,6 +384,8 @@ List *linked_list() newList->find = findElement; newList->insertAt = insertAt; newList->findNode = findNode; + newList->freeNode = freeNode; + return newList; } From d600d637db7f71c5725a5ba9870ead41b3bb0b16 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 26 Jun 2019 12:52:29 -0600 Subject: [PATCH 064/400] multiple files per client --- Program/include/packet.h | 2 +- Program/include/protocol_handler.h | 1 + Program/src/filesystem_funcs.c | 2 + Program/src/port.c | 1 - Program/src/protocol_handler.c | 30 ++- Program/src/requests.c | 4 +- Program/src/tasks.c | 9 +- Program/test/packet_tests.c | 26 +++ Program/test/protocol_handler_tests.c | 11 +- Program/test/testfile | 318 ++++++++++++++++++++++++++ 10 files changed, 384 insertions(+), 20 deletions(-) create mode 100644 Program/test/testfile diff --git a/Program/include/packet.h b/Program/include/packet.h index d18ac60..12a2c51 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -259,7 +259,7 @@ typedef struct pdu_meta_data { typedef struct file_data_pdu_contents { //in octets - unsigned int offset: 32; + uint32_t offset; //variable sized unsigned char *data; } File_data_pdu_contents; diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 6f11ebb..598dbb0 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -62,6 +62,7 @@ void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, uint32_t packet_index, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request); int process_pdu_header(char*packet, Response res, Request **req, List *request_list, Protocol_state *p_state); +uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); //for testing uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index bf79638..0713057 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -198,6 +198,8 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs NODE * node = nak_list->findNode(nak_list, -1, find_nak, &offset_to_insert); if (node == NULL){ + + ssp_printf("trying to receive offset start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end); ssp_printf("no begining node for receive_offset, or offset we already received, can't add new offset\n"); return 0; } diff --git a/Program/src/port.c b/Program/src/port.c index ec953c4..3d74608 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -76,7 +76,6 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { #ifdef POSIX_PORT - struct sockaddr* addr = (struct sockaddr*) res.addr; int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); if (n < 0) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 68d5b26..53ad827 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -157,7 +157,8 @@ static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, //requires a req->file to be created //returns 1 on end of file -static uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { +//length is the total size of the packet +uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { if (file->next_offset_to_send > file->total_size){ ssp_error("cant send an offset past the file's length\n"); @@ -174,7 +175,7 @@ static uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint3 //4 bytes is the size of the offset paramater packet_offset->offset = file->next_offset_to_send; packet_index += 4; - + uint16_t data_size = length - packet_index; //fill the rest of the packet with data @@ -391,10 +392,13 @@ struct request_search_params { static int find_request(void *element, void *args) { Request *req = (Request *) element; struct request_search_params *params = (struct request_search_params *) args; - if (req->dest_cfdp_id == params->source_id && req->transaction_sequence_number == params->transaction_sequence_number) - return 1; + if (req->dest_cfdp_id == params->source_id && req->transaction_sequence_number == params->transaction_sequence_number){ + return 1; + } return 0; } + + /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns 0 on fail*/ @@ -436,7 +440,7 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l transaction_sequence_number, }; - Request *found_req = request_list->find(request_list, 0, find_request, ¶ms); + Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); //server side, receiving requests if (found_req == NULL) @@ -460,7 +464,6 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l request_list->push(request_list, found_req, transaction_sequence_number); } - *req = found_req; return packet_index; @@ -476,6 +479,7 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, Fil } File_data_pdu_contents *packet = (File_data_pdu_contents *)data_packet; + uint32_t offset_start = packet->offset; uint32_t offset_end = offset_start + data_len - 4; @@ -704,6 +708,11 @@ static void reset_timeout(Request *req) { } } +static void print_offsets(void *element, void *args) { + + Offset *off = (Offset *) element; + ssp_printf("missing offset start: %d end:%d\n", off->start, off->end); +} void on_server_time_out(Response res, Request *req) { if (req->type == none) @@ -714,8 +723,8 @@ void on_server_time_out(Response res, Request *req) { reset_timeout(req); - ssp_printf("source id: %d transaction sequence numer :%d\n", req->dest_cfdp_id, req->transaction_sequence_number); uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); + //Pdu_header *pdu_header = (Pdu_header *) &res.msg; if (req->resent_finished == 3) { @@ -750,7 +759,7 @@ void on_server_time_out(Response res, Request *req) { if (req->file->eof_checksum == req->file->partial_checksum){ ssp_printf("sending finsihed pdu\n"); - build_finished_pdu(res.msg, start, req); + build_finished_pdu(res.msg, start, req); ssp_sendto(res); req->resent_finished++; return; @@ -776,6 +785,9 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_header *header = (Pdu_header *) packet; + uint16_t len = get_data_length(packet); + ssp_printf("packet data length %d\n", len); + //will protbably have to timeout different clients? how does that work with ddos? req->timeout = 0; //process file data @@ -788,7 +800,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ } request_metadata(req, res); } - write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); + write_packet_data_to_file(&packet[packet_index], len, req->file); return; } diff --git a/Program/src/requests.c b/Program/src/requests.c index f445362..f580fbe 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -134,7 +134,9 @@ Request *put_request(char *source_file_name, req->messages_to_user = messages_to_user; req->filestore_requests = filestore_requests; - client->request_list->insert(client->request_list, req, p_state->transaction_sequence_number); + req->res.addr = ssp_alloc(sizeof(uint64_t), 1); + + client->request_list->insert(client->request_list, req, 0); return req; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 4024c2a..e1f678b 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -58,12 +58,10 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr ssp_printf("error parsing header\n"); return -1; } - - client->current_request = (*request_container); - client->current_request->res = res; - ssp_printf("server transaction number %d and Id %d\n", (*request_container)->transaction_sequence_number, (*request_container)->dest_cfdp_id); - + + res.msg = (*request_container)->buff; parse_packet_client(packet, packet_index, res, (*request_container), client); + memset(packet, 0, res.packet_len); return 0; @@ -266,7 +264,6 @@ void ssp_cleanup_p_state(Protocol_state *p_state) { void ssp_cleanup_client(Client *client) { client->request_list->free(client->request_list, ssp_cleanup_req); - ssp_cleanup_req(client->current_request); ssp_cleanup_pdu_header(client->pdu_header); ssp_free(client); } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index d9076a5..638666e 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -8,6 +8,7 @@ #include "port.h" #include "protocol_handler.h" #include "mib.h" +#include "file_delivery_app.h" #define PACKET_TEST_SIZE 2000 @@ -26,6 +27,26 @@ static int test_respond_metadata_request() { return 0; } +test_build_data_packet(char *packet, uint32_t packet_index){ + + File *file = create_file("testfile", 0); + + build_data_packet(packet, packet_index, file, 1000); + + ASSERT_EQUALS_INT("test proper datapacket offset set", (uint64_t)packet[packet_index], 0); + ASSERT_EQUALS_STR("test proper datapacket creation", &packet[packet_index + 4], "tempfileyo", 10); + + ASSERT_EQUALS_INT("should equal 100", packet_index + 87 + 4, 100); + build_data_packet(packet, packet_index, file, 1000); + + uint32_t offset_in_packet = 0; + memcpy(&offset_in_packet, &packet[packet_index], 4); + ssp_printf("offset size %u\n", offset_in_packet); + ASSERT_EQUALS_INT("test proper datapacket offset set", offset_in_packet, 987); + + free_file(file); +} + static void nak_print(void *element, void *args){ Offset *offset = (Offset *)element; @@ -234,6 +255,11 @@ int packet_tests() { test_build_nak_packet(packet, packet_index); test_respond_to_naks(packet, packet_index); + + memset(packet, 0, PACKET_TEST_SIZE); + packet_index = test_build_pdu_header_header(packet, pdu_header, sequence_number); + test_build_data_packet(packet, packet_index); + free_mib(mib); ssp_cleanup_pdu_header(pdu_header); ssp_free(packet); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index d132d00..1bf7bb0 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -20,15 +20,22 @@ static int test_process_pdu_header() { Protocol_state *p_state = init_ftp(1); Request **req_container = &p_state->current_request; + Response res; + int addr = 16; + res.addr = &addr; + res.sfd = 1; + res.packet_len = p_state->packet_size; + res.size_of_addr = 16; + //test 1 char *packet = build_mock_packet(p_state, 2); - process_pdu_header(packet, req_container, p_state->request_list, p_state); + process_pdu_header(packet, res, req_container, p_state->request_list, p_state); ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 2); //test 2 char *packet2 = build_mock_packet(p_state, 3); - process_pdu_header(packet2, req_container, p_state->request_list, p_state); + process_pdu_header(packet2, res, req_container, p_state->request_list, p_state); ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); ASSERT_NOT_EQUALS_INT("souce id should not equal", (*req_container)->dest_cfdp_id, 2); ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 3); diff --git a/Program/test/testfile b/Program/test/testfile new file mode 100644 index 0000000..2c98633 --- /dev/null +++ b/Program/test/testfile @@ -0,0 +1,318 @@ +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo + +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo + +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo + +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo + +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo + +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo + +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo + +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo +tempfileyo From f10a3e8ce226c13e2fa47eb22d52105741647752 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 27 Jun 2019 10:43:02 -0600 Subject: [PATCH 065/400] bit of cleanup, remove isactive variable in favour of req->type == none --- Program/include/requests.h | 3 -- Program/src/filesystem_funcs.c | 7 ++--- Program/src/main.c | 29 ++++++++++---------- Program/src/protocol_handler.c | 50 +++++++++++++--------------------- Program/src/requests.c | 32 ---------------------- Program/src/server.c | 1 - Program/src/tasks.c | 47 ++++++++++++++++++-------------- 7 files changed, 63 insertions(+), 106 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index b2ed4ff..d6093cf 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -43,9 +43,6 @@ typedef struct request { uint32_t packet_data_len; - //check to see if this request is empty - uint8_t is_active; - //timeout uint8_t timeout; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 0713057..4059d84 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -205,11 +205,11 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs } Offset *offset_in_list = (Offset *) node->element; - ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); + //ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); //remove node if both start and end are equal if (offset_to_insert.start == offset_in_list->start && offset_to_insert.end == offset_in_list->end) { - ssp_printf("removing node\n"); + //ssp_printf("removing node\n"); node->next->prev = node->prev; node->prev->next = node->next; ssp_free(node->element); @@ -224,9 +224,6 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs return 1; } - if (offset_start == offset_in_list->end) - ssp_printf("END NODE CREATED\n"); - Offset *new_offset = ssp_alloc(1, sizeof(Offset)); new_offset->start = offset_in_list->start; diff --git a/Program/src/main.c b/Program/src/main.c index 32b8a81..f883dab 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -3,19 +3,22 @@ #include #include #include -#include "port.h" #include + +//Have to include these files + +//for types #include "protocol_handler.h" +//for conf #include "utils.h" -#include "server.h" -#include "mib.h" +//for put request #include "requests.h" -#include "packet.h" -#include "tasks.h" +//for main app #include "file_delivery_app.h" -//for itoa -#include -#include +//for signal handler, because its nice +#include "server.h" +//for ssp_thread_join, can use p_thread join on linux +#include "port.h" //exit handler variable for the main thread @@ -30,7 +33,7 @@ int main(int argc, char** argv) { Config *conf = configuration(argc, argv); if (conf->my_cfdp_id == 0){ - ssp_printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); + printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } Protocol_state *p_state = init_ftp(conf->my_cfdp_id); @@ -46,19 +49,17 @@ int main(int argc, char** argv) { //send via acknoleged mode //0 acknowledged, 1 unacknowledged if (conf->my_cfdp_id == 2) { put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); } if (conf->my_cfdp_id == 3) put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); - - ssp_thread_join(new_client->client_handle); - ssp_printf("client disconnected\n"); + printf("client disconnected\n"); } ssp_thread_join(p_state->server_handle); - ssp_free(conf); + free(conf); return 0; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 53ad827..cca2d64 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -425,12 +425,13 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l return 0; } - uint16_t packet_data_len = ntohs(header->PDU_data_field_len); + uint16_t len = get_data_length(packet); + Request *request = *req; //if packet is from the same request, don't' change current request - if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ - request->packet_data_len = packet_data_len; + if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ + (*req)->packet_data_len = len; return packet_index; } @@ -448,29 +449,29 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l found_req = init_request(p_state->packet_size); ssp_printf("incoming new request\n"); //Make new request and add it - found_req->packet_data_len = packet_data_len; found_req->transmission_mode = header->transmission_mode; found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); - found_req->is_active = 1; + found_req->type = put; found_req->res.addr = ssp_alloc(res.size_of_addr, 1); memcpy(found_req->res.addr, res.addr, res.size_of_addr); - found_req->res.packet_len = p_state->packet_size; found_req->res.sfd = res.sfd; found_req->res.msg = found_req->buff; request_list->push(request_list, found_req, transaction_sequence_number); } + + found_req->packet_data_len = len; *req = found_req; return packet_index; } -static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { +static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { if(file == NULL) { @@ -540,8 +541,8 @@ static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fi int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; - uint32_t offset_first = ntohl(nak->start_scope); - uint32_t offset_last = ntohl(nak->end_scope); + //uint32_t offset_first = ntohl(nak->start_scope); + //uint32_t offset_last = ntohl(nak->end_scope); uint64_t segments = ntohll(nak->segment_requests); packet_index += 16; @@ -564,10 +565,6 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien memcpy(&offset_end, &packet[packet_index], 4); offset_end = ntohl(offset_end); packet_index += 4; - - printf("offset sending first %u last %u\n", offset_start, offset_end); - printf("first %u and end %u\n", offset_first, offset_last); - build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); ssp_sendto(res); } @@ -639,15 +636,13 @@ static void check_req_status(Request *req, Client *client) { //current user request, to send to remote void user_request_handler(Response res, Request *req, Client* client) { - if (req == NULL || req->type == none) + if (req == NULL) return; if (res.msg == NULL) { ssp_printf("req->buff is null, couldn't process user request\n"); return; } - memset(res.msg, 0, client->packet_len); - uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req, client); @@ -700,7 +695,7 @@ void user_request_handler(Response res, Request *req, Client* client) { static void reset_timeout(Request *req) { uint8_t time = req->timeout++; - ssp_printf("timeout %u for id: %u sequence: %u\n", time, req->dest_cfdp_id, req->transaction_sequence_number); + //ssp_printf("timeout %u for id: %u sequence: %u\n", time, req->dest_cfdp_id, req->transaction_sequence_number); if (time == 20) { req->timeout = 0; reset_request(req); @@ -715,17 +710,15 @@ static void print_offsets(void *element, void *args) { } void on_server_time_out(Response res, Request *req) { - if (req->type == none) + if (req == NULL) return; - - if (req->buff == NULL) - ssp_printf("req buffer is null, couldn't process timeout request\n"); reset_timeout(req); - uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); + if (req->transmission_mode == 1) + return; - //Pdu_header *pdu_header = (Pdu_header *) &res.msg; + uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); if (req->resent_finished == 3) { reset_request(req); @@ -743,11 +736,10 @@ void on_server_time_out(Response res, Request *req) { //send missing eofs if (!req->received_eof) { - build_nak_directive(res.msg, start, EOF_PDU); + build_nak_directive(res.msg, start, EOF_PDU); ssp_sendto(res); } - ssp_printf("missing offsets %u\n", req->file->missing_offsets->count); //send missing NAKS if (req->file->missing_offsets->count > 0) { ssp_printf("sending Nak data\n"); @@ -785,11 +777,8 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_header *header = (Pdu_header *) packet; - uint16_t len = get_data_length(packet); - ssp_printf("packet data length %d\n", len); - - //will protbably have to timeout different clients? how does that work with ddos? req->timeout = 0; + //process file data if (header->PDU_type == 1) { if (!req->received_metadata) { @@ -800,7 +789,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ } request_metadata(req, res); } - write_packet_data_to_file(&packet[packet_index], len, req->file); + write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); return; } @@ -826,7 +815,6 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ if (!req->received_metadata) request_metadata(req, res); - //this should probably just set variables for use later for calculating checksums ssp_printf("received eof packet\n"); process_pdu_eof(&packet[packet_index], req, res); diff --git a/Program/src/requests.c b/Program/src/requests.c index f580fbe..33d4a50 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -39,37 +39,7 @@ void ssp_cleanup_req(void *request) { void reset_request(Request *req){ - - req->is_active = 0; -/* - memset(req->source_file_name, 0, MAX_PATH); - memset(req->destination_file_name, 0, MAX_PATH); - memset(req->buff, 0, req->buff_len); - memset(req->res.addr, 0, sizeof(struct sockaddr_in)); - req->dest_cfdp_id = 0; - req->fault_handler_overides = 0; - req->file_size = 0; - req->flow_lable = 0; - req->received_eof = 0; - req->received_finished = 0; - req->received_metadata = 0; - req->resent_eof = 0; - req->resent_finished = 0; - req->segmentation_control = 0; - req->transaction_sequence_number = 0; - req->transmission_mode = 1; - req->type = none; - req->is_active = 0; - if (req->file != NULL) - free_file(req->file); - - if (req->pdu_header != NULL) { - ssp_cleanup_pdu_header(req->pdu_header); - req->pdu_header = NULL; - } - req->file = NULL; req->type = none; - */ } @@ -86,7 +56,6 @@ Request *init_request(uint32_t buff_len) { req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); - req->is_active = 0; req->type = none; checkAlloc(req->buff, 1); return req; @@ -120,7 +89,6 @@ Request *put_request(char *source_file_name, //enumeration req->type = put; - req->is_active = 1; req->dest_cfdp_id = client->cfdp_id; req->file_size = file_size; diff --git a/Program/src/server.c b/Program/src/server.c index ff98327..f0ca9ab 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -152,7 +152,6 @@ void udpSelectServer(char* port, int packet_len, void *other) { int sfd = prepareUdpHost(port); - prepareSignalHandler(); fd_set masterReadFds; FD_ZERO(&masterReadFds); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index e1f678b..68a89e0 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -67,8 +67,25 @@ static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr } +static int remove_request(void *request, void *args) { + Request *req = (Request *) request; + Request *req2 = (Request *) args; + if (req->dest_cfdp_id == req2->dest_cfdp_id && req->transaction_sequence_number == req2->transaction_sequence_number) + return 1; + return 0; +} + +static void remove_request_check(void *request, void *args) { + Request *req = (Request *) request; + List *req_list = (List *) args; -static struct user_request_check_params { + if (req->type == none) { + Request *remove_this = req_list->remove(req_list, 0, remove_request, req); + ssp_cleanup_req(remove_this); + } +} + +struct user_request_check_params { Response res; Client *client; }; @@ -78,7 +95,10 @@ static void user_request_check(void *request, void *args) { struct user_request_check_params* params = (struct user_request_check_params *) args; params->res.msg = req->buff; + + memset(params->res.msg, 0, params->client->packet_len); user_request_handler(params->res, req, params->client); + remove_request_check(request, params->client->request_list); } static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { @@ -90,7 +110,10 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { Response res; Client *client = (Client *) other; - + if (client->request_list->count == 0){ + return 0; + } + res.sfd = sfd; res.packet_len = client->packet_len; res.addr = client_addr; @@ -102,30 +125,14 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { client->request_list->print(client->request_list, user_request_check, ¶ms); - return 0; -} - - -static int timeout_remove_request(void *request, void *args) { - Request *req = (Request *) request; - Request *req2 = (Request *) args; - if (req->dest_cfdp_id == req2->dest_cfdp_id && req->transaction_sequence_number == req2->transaction_sequence_number) - return 1; + return 0; } static void timeout_check(void *request, void *args) { Request *req = (Request *) request; - List *req_list = (List *) args; - on_server_time_out(req->res, req); - - if (!req->is_active) { - Request *remove_this = req_list->remove(req_list, 0, timeout_remove_request, req); - ssp_cleanup_req(remove_this); - - } - + remove_request_check(request, args); } //this function is a callback when using my posix ports static int on_time_out_posix(void *other) { From bdad4e18d0c83fbc825abd1544996fc87d307f8d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 15 Aug 2019 11:31:14 -0600 Subject: [PATCH 066/400] remove buffer file, change print to iterate in List --- Program/include/protocol_handler.h | 2 +- Program/include/ringbuf.h | 243 -------------------- Program/include/utils.h | 2 +- Program/src/file_delivery_app.a | Bin 152318 -> 154770 bytes Program/src/makefile | 1 - Program/src/protocol_handler.c | 14 +- Program/src/remote_pic2.jpeg | Bin 0 -> 150033 bytes Program/src/requests.c | 1 + Program/src/ringbuf.c | 347 ----------------------------- Program/src/tasks.c | 4 +- Program/src/utils.c | 4 +- 11 files changed, 14 insertions(+), 604 deletions(-) delete mode 100644 Program/include/ringbuf.h create mode 100644 Program/src/remote_pic2.jpeg delete mode 100644 Program/src/ringbuf.c diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 598dbb0..88c648b 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -66,7 +66,7 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len //for testing uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); -uint8_t build_ack (char *packet, uint32_t start, uint8_t type, Request *req); +uint8_t build_ack (char *packet, uint32_t start, uint8_t type); int process_file_request_metadata(Request *req); int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client); void set_data_length(char*packet, uint16_t data_len); diff --git a/Program/include/ringbuf.h b/Program/include/ringbuf.h deleted file mode 100644 index c72bfae..0000000 --- a/Program/include/ringbuf.h +++ /dev/null @@ -1,243 +0,0 @@ -#ifndef INCLUDED_RINGBUF_H -#define INCLUDED_RINGBUF_H - -/* - * ringbuf.h - C ring buffer (FIFO) interface. - * - * Written in 2011 by Drew Hess . - * - * To the extent possible under law, the author(s) have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. - * - * You should have received a copy of the CC0 Public Domain Dedication - * along with this software. If not, see - * . - */ - -/* - * A byte-addressable ring buffer FIFO implementation. - * - * The ring buffer's head pointer points to the starting location - * where data should be written when copying data *into* the buffer - * (e.g., with ringbuf_read). The ring buffer's tail pointer points to - * the starting location where data should be read when copying data - * *from* the buffer (e.g., with ringbuf_write). - */ - -#include -#include - -typedef struct ringbuf_t *ringbuf_t; - -/* - * Create a new ring buffer with the given capacity (usable - * bytes). Note that the actual internal buffer size may be one or - * more bytes larger than the usable capacity, for bookkeeping. - * - * Returns the new ring buffer object, or 0 if there's not enough - * memory to fulfill the request for the given capacity. - */ -ringbuf_t -ringbuf_new(size_t capacity); - -/* - * The size of the internal buffer, in bytes. One or more bytes may be - * unusable in order to distinguish the "buffer full" state from the - * "buffer empty" state. - * - * For the usable capacity of the ring buffer, use the - * ringbuf_capacity function. - */ -size_t -ringbuf_buffer_size(const struct ringbuf_t *rb); - -/* - * Deallocate a ring buffer, and, as a side effect, set the pointer to - * 0. - */ -void -ringbuf_free(ringbuf_t *rb); - -/* - * Reset a ring buffer to its initial state (empty). - */ -void -ringbuf_reset(ringbuf_t rb); - -/* - * The usable capacity of the ring buffer, in bytes. Note that this - * value may be less than the ring buffer's internal buffer size, as - * returned by ringbuf_buffer_size. - */ -size_t -ringbuf_capacity(const struct ringbuf_t *rb); - -/* - * The number of free/available bytes in the ring buffer. This value - * is never larger than the ring buffer's usable capacity. - */ -size_t -ringbuf_bytes_free(const struct ringbuf_t *rb); - -/* - * The number of bytes currently being used in the ring buffer. This - * value is never larger than the ring buffer's usable capacity. - */ -size_t -ringbuf_bytes_used(const struct ringbuf_t *rb); - -int -ringbuf_is_full(const struct ringbuf_t *rb); - -int -ringbuf_is_empty(const struct ringbuf_t *rb); - -/* - * Const access to the head and tail pointers of the ring buffer. - */ -const void * -ringbuf_tail(const struct ringbuf_t *rb); - -const void * -ringbuf_head(const struct ringbuf_t *rb); - -/* - * Locate the first occurrence of character c (converted to an - * unsigned char) in ring buffer rb, beginning the search at offset - * bytes from the ring buffer's tail pointer. The function returns the - * offset of the character from the ring buffer's tail pointer, if - * found. If c does not occur in the ring buffer, the function returns - * the number of bytes used in the ring buffer. - * - * Note that the offset parameter and the returned offset are logical - * offsets from the tail pointer, not necessarily linear offsets. - */ -size_t -ringbuf_findchr(const struct ringbuf_t *rb, int c, size_t offset); - -/* - * Beginning at ring buffer dst's head pointer, fill the ring buffer - * with a repeating sequence of len bytes, each of value c (converted - * to an unsigned char). len can be as large as you like, but the - * function will never write more than ringbuf_buffer_size(dst) bytes - * in a single invocation, since that size will cause all bytes in the - * ring buffer to be written exactly once each. - * - * Note that if len is greater than the number of free bytes in dst, - * the ring buffer will overflow. When an overflow occurs, the state - * of the ring buffer is guaranteed to be consistent, including the - * head and tail pointers; old data will simply be overwritten in FIFO - * fashion, as needed. However, note that, if calling the function - * results in an overflow, the value of the ring buffer's tail pointer - * may be different than it was before the function was called. - * - * Returns the actual number of bytes written to dst: len, if - * len < ringbuf_buffer_size(dst), else ringbuf_buffer_size(dst). - */ -size_t -ringbuf_memset(ringbuf_t dst, int c, size_t len); - -/* - * Copy n bytes from a contiguous memory area src into the ring buffer - * dst. Returns the ring buffer's new head pointer. - * - * It is possible to copy more data from src than is available in the - * buffer; i.e., it's possible to overflow the ring buffer using this - * function. When an overflow occurs, the state of the ring buffer is - * guaranteed to be consistent, including the head and tail pointers; - * old data will simply be overwritten in FIFO fashion, as - * needed. However, note that, if calling the function results in an - * overflow, the value of the ring buffer's tail pointer may be - * different than it was before the function was called. - */ -void * -ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count); - -/* - * This convenience function calls read(2) on the file descriptor fd, - * using the ring buffer rb as the destination buffer for the read, - * and returns the value returned by read(2). It will only call - * read(2) once, and may return a short count. - * - * It is possible to read more data from the file descriptor than is - * available in the buffer; i.e., it's possible to overflow the ring - * buffer using this function. When an overflow occurs, the state of - * the ring buffer is guaranteed to be consistent, including the head - * and tail pointers: old data will simply be overwritten in FIFO - * fashion, as needed. However, note that, if calling the function - * results in an overflow, the value of the ring buffer's tail pointer - * may be different than it was before the function was called. - */ -ssize_t -ringbuf_read(int fd, ringbuf_t rb, size_t count); - -/* - * Copy n bytes from the ring buffer src, starting from its tail - * pointer, into a contiguous memory area dst. Returns the value of - * src's tail pointer after the copy is finished. - * - * Note that this copy is destructive with respect to the ring buffer: - * the n bytes copied from the ring buffer are no longer available in - * the ring buffer after the copy is complete, and the ring buffer - * will have n more free bytes than it did before the function was - * called. - * - * This function will *not* allow the ring buffer to underflow. If - * count is greater than the number of bytes used in the ring buffer, - * no bytes are copied, and the function will return 0. - */ -void * -ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count); - -/* - * This convenience function calls write(2) on the file descriptor fd, - * using the ring buffer rb as the source buffer for writing (starting - * at the ring buffer's tail pointer), and returns the value returned - * by write(2). It will only call write(2) once, and may return a - * short count. - * - * Note that this copy is destructive with respect to the ring buffer: - * any bytes written from the ring buffer to the file descriptor are - * no longer available in the ring buffer after the copy is complete, - * and the ring buffer will have N more free bytes than it did before - * the function was called, where N is the value returned by the - * function (unless N is < 0, in which case an error occurred and no - * bytes were written). - * - * This function will *not* allow the ring buffer to underflow. If - * count is greater than the number of bytes used in the ring buffer, - * no bytes are written to the file descriptor, and the function will - * return 0. - */ -ssize_t -ringbuf_write(int fd, ringbuf_t rb, size_t count); - -/* - * Copy count bytes from ring buffer src, starting from its tail - * pointer, into ring buffer dst. Returns dst's new head pointer after - * the copy is finished. - * - * Note that this copy is destructive with respect to the ring buffer - * src: any bytes copied from src into dst are no longer available in - * src after the copy is complete, and src will have 'count' more free - * bytes than it did before the function was called. - * - * It is possible to copy more data from src than is available in dst; - * i.e., it's possible to overflow dst using this function. When an - * overflow occurs, the state of dst is guaranteed to be consistent, - * including the head and tail pointers; old data will simply be - * overwritten in FIFO fashion, as needed. However, note that, if - * calling the function results in an overflow, the value dst's tail - * pointer may be different than it was before the function was - * called. - * - * It is *not* possible to underflow src; if count is greater than the - * number of bytes used in src, no bytes are copied, and the function - * returns 0. - */ -void * -ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count); - -#endif /* INCLUDED_RINGBUF_H */ diff --git a/Program/include/utils.h b/Program/include/utils.h index a473af3..6525e83 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -45,7 +45,7 @@ typedef struct List int count; int (*push)(struct List *list, void *element, uint32_t id); void *(*remove)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); - void (*print)(struct List *list, void (*f)(void *element, void *args), void *args); + void (*iterate)(struct List *list, void (*f)(void *element, void *args), void *args); void (*free)(struct List *list, void (*f)(void *element)); void *(*pop) (struct List *list); int (*insert) (struct List *list, void *element, uint32_t id); diff --git a/Program/src/file_delivery_app.a b/Program/src/file_delivery_app.a index d3b21022f9840944b73efa7347a16e00a5c3d552..7685da14d7ec31d84d973b6b4762d1c3b90bbd92 100644 GIT binary patch delta 63375 zcmb@v34ByV);50Y_D%QgEonL-=`4_iP6%tlz6wE!EP@2t1!WBcWD^LuVWR;h29(%3 z?PyeRcgA(1f{vrOf+H#}qqxnupn#y_jw|2u)IA-*dFTDU_x=ByANQ$q>eQ)Ir|Q;Kb# z)%iE$KmH$+W2pc3f9$^ySo5@@{{Q^H?NdYjSN}i0!%$s$`49iij(;$I_dnjYxUl&< z^|bQOnYm)-^rbUrpHsae{(x&_e3mEOoPA#NkFNf%`0F>Mn={XgclVs4X2)lETB|v@ zMw+kmT&UtVp3}j6yg2bdp;_8I&D&b3Nb@pZx+}K9HVg|b09W;#X&8aOf%=PP7)IRX z1WaYWkDzIKUPY{Fd2%2LC?_a)kunU|=@2!Gi+MFusM1wK+4h~mv8Uqq2<2rCsEVuPAW0ZRuw0jtKbxy%0 zGMvHoFvyjCCWDRS<}75eBQDk+X6t$#s#0>%)D1fYs-t#F-&~+~QM@6wq>QYTK}RU) zL2`E?eC`~>>#c@TBeZDwJj3h1A3-a)7gula zUR>?qWQIc@;Ti~j2aVoVZy_8qTu+fm&ww7cwHVh{ZtHQxc$OgSgPxdi1wwunUm0o3 zP#E9M7l4y?0}}c+GuO1AaPe)S&(p4;z#Uqkni}rY0-wWV-~AK_tVgnI{NIg&{lWQQ z`@g4z5lqF!|FdKG0P=rf*bc_-hot{k5`o}_(C+_@;ZU%OW*ucXBRmC4{e~hD315k; zUuhyQd?{6#nkWdznZ(jWG~AQAQZ!K-ewLZIHPJczcWSfMAHgdR$8xF8r)~z-Gu(sf z0*WU04c|$1Ax#Vn-^!S<+Ju;j@RcMo73+U!IET8k)DRG-hKJ(nkEq+h8y4O|1$pXW z5W~awGflC&1p=eOdzq$-LfyrT@!^A{x{@*`hrcFKrip3cA4!yJVn*0tiMp$gAT}p_ zKXv!e#?^$=8PiLxL>3DT*GQBvP&x@o)2*do@ixdfmxaDQ@H6Oue>2M-Oi+1j3&Tc` zZNq;HyaSpAmQkd_315sP z{vkT-qQ+oXHjOkl(gZI@b}=LEVTRW;>$E%+Bv`M5a}Z3;VG>_01WG_=8J=7~+QY~z zHJ6;sMg-G}%##szTWlX`8z3Bt>fm6g40W$2cN2qsbZ`uV0~n0FuaLjGejJokfL2X+ zKu>l68r1cy4YSe6nE;j(VKy#ACZB_!yBs>yDvDG>I2BG+O*w9)9ZBg`RF1USWl*eE zbwGsKXl19jBr+TAoHWK=ct;Eg%*Hu6-&4oMWm>c*uX@=sLtWyiS!lFjM%2=l0ocH- z+*T(fiSz?QEqW8dB@8vyAS!zzb6P|nn2po&a~9F4C2VtMV~r76LBV-!kL}t1RMQ5g z>A*DeoHWpTfI>4aflybi_W{a$t(i0er89DOB37MAaxy|4wA`nZW3y0avIn9UE~Y=v z{76%l5xJ3(qZCq10xPDPq8`I2SXR9pT=sW#`d;c9!w6WMx7bisNng0FAxN29LGM+N z`7ZvKP`qg@^`NhG_}an}iuI!yt#nFq4aBnRXj4CwHl|G+N)Kr{R8-*rrW(jp`N(Po zMSGCC1pj%@tERV-S!q5Cc^6A1l$CvUOBz(Qk^4BwPE;|WMMVxCt*~~2L{LXpluUJU zs=#vG*6AZ8&^iv%s3>*N(T*8sIXZ+76$P_u=Ypz(UvLrbE>Cc$wD}& zEqi~8FRoris##?oQl77ny=h#SIJc*{B>R+cL&r@&b^gNYq16lLudH5ne$}!iE0)Y& zvM|y0dQ}p?IdVj`i(i+0b71-W3#z9tnLB;voH@(ly>t2`E;&hMbt|h`vZ%VOdgaW; zWvBc{Rb|jQZ`sU6Wy_b%ZvIQoVJk6uvnp4#FutDfQ2(oWw{5^tO z1)q-lI}VN&(piY@DyVA|^l+gk2+k5*BFKj^)71<9LGV_=2L%5n$VUm~-xA#GV9fYR z7{3Yn**qW^5iAz$F37Hm@uLN&2+k6mFIX#hiQq=T#|59#7$4p#9Q#CAhXsEYbhB9? zt5$*>Ad&7PI6`o|;B>(Sg0+HtSSxs)LjtD1PVim_W5!kycwQpj5d28+u;6ckz0q}0 z(Lf>;pC zA@nq%&k_23!OI1&6}*|a5DEV(j28s=2!2FF{BJ@Ba33?{T)|=@;>QSmwqT9$VXvVO z4iO=@K5_E}YE1JLU3Mw8DL$#}8*`JL*xuI6Ogyn#1yasKH?}kJ%4*fl?Ft&kvnsxM zer6)|Viiz3;!l>hR~7MnSid0p+Pq+5&_mIKuDT(din3rV!p_9st z-_$Ln?v3Byt-X36{uZv2<419QHr~E_dlik3!F6|hRre9DUOjrpZ$78J+SYuq`^#p^ zYTH;5N_@~+WyiDnwTge#Yl@oHJg|2cm3H`Gw4w5FLxo*m`7HwRC4E{4>%q{xb=zxS zi(k{{>ZlEYja5e*D((6zyP@)fh6)Svb%z2+Yd_dO{@0^N>z)n8NA?|}%Hp^6Ep7Gj zFPhV$WJmn{zIDoo&+NAe*RT8Gd5Lh__`d#qRnK_AfMV0F;!6i)#m^oPQt!u?4Ctu- z62E@H;Mg|Yzx7pthRQ=5&^@Gu?D(BX5?e(S3uIy_j*7wGWwsG0hzJRSZ? z%arQydQ@M16-o`Av(N(St2*oOAGLfr!VPEr^1?F{>OUD5zc*kf3dSfqK5bx7t%)xf z*g@SCzh+>ex~2J%f!C<`>4Q4Q&P2hw=LXk{l;*}+YK75qYP*GIzg#rC=wCh zmAG0;6M4Q8W?^cgz;_{&Sel6X*ne6nnke;MPQtB;&OVNhEnBUHbh$5=<+pr_uTedH zdr1ToP44Tvmg+*980eeEjKYd9Nfo~CBr+AfIn;NU>ax@*5U2W1#np%ve3xDVH-@=vD^T>)=l0oKmlYgTZy@&~<@N5actw zmEp+*gs#WMolB1SJ`#8$;~-_e3!^;Q)eQDR#d~sAAs7zX|KMXho#TA_Egk#~eB0i$ zf$a47p&8JP^*UKa}C&FY45z%cJ-g2)Gqz(_6zMQ!GQl`$Xh_W6`Iyj@TR zZvm^+@^&MmkP^1{OoodX4q((@3N$$w^tNNrb|Ki)+kq|LTLOl+6D9G^Pm#_HTV6aW zpq`$!y?j;h#=4#a`GA*GIo>ip$wS_)Ok92s!WrI2$?x_$!jX)nOO_hm?)wqW^FGbQ zJ(#w@dmqC+TcIj0_~6iAWT-Uw?93U)_|a|$mBrCZRuWaF4~wss)G?k`n%Jl&~ym<`{-aN1_vFzA(Wj4cOr&az|MT!KA;@CtbDxtoUZ6syfI~GIFf7vW@8|4 zb}e41t0arl=H%Q@3&x7^H94=)f-_pm(w41Tb=NeX*Y9Wx7UM>8Ea;xJAiGO^^r?k0 zC)0qFX?NYP@ZuJ18&GHT{7U ztQ{-*1F7eB$mav8<|19qF|7c_it1|q$Z1!Ti*+S`%+`;IkYZiOdmU; zGtV!bBy)<{^QyzrFpJqItM8pQgce@HPEx(Z(ckHmYZ`;^Bd`?ZS1%<^g>^5n_kj}} z>t1rw+m3OsBz5bYc01HUqmUi5dXUy}(CK*jK1V$xM0=68=s`!LrQPzN?oZIE-9JkxW`YydOss26QKsPy5Y@yMf z&k41b2|4g}^iOZmzgF}Y>(|hFC)u3hGigRcQl&22CMWNOMhTxDD#l@P7j11FwdrhQ zP6|A3Y+7+n2I&e2PSJwTQ?N_?^AR~yv`ZE_;tP$^MeNr)6$hNjrvuEOiB!>0o1xF24Lz90Rqniv1<^iF;6D{r(Iek|EhwMap?dAXyUk{s40yV4dJ^NJQtcuh2t{r<7|H(TN#Kz#DabS(aI z9bbSKd1E&OlFz^v0T|(`jMq$hEXH!1hRX;8leY`$Owh^OlXM%<$?kx35$L1`Nb{{O z*>95W3p!bL(nCNe%SoEg7nCbiKhVgS2*#}V{gWHi^!R`&`9o%d=5yQmx%lnZSa}?c zPSD^j;QU<1xd^|bbr=Q#PW={4FM zM~CS3!V?&Ha)3^@2P)tjU~&jXy5dCnc=ptG$vY)pIrZ202WF0M`SPXHmoCG%(z(qw z)6P_}N73O}c#6Elj;Gu(UIY4~c#A}zNcuD&>6xVQ?B$CJ`OgafHQ}F*8;<;OK*~1> zy+!Ede3-REpAKaFOF*kTUSj^`1dPuG6+28Qasw%NmC)A+tuTV4A@hllTMVS!cchWQ z&q8}Jw6RJtYy_HU@_mR%H$(7Apx2D=JbPYYFT+@e(SjEiGypBocM5&4rkks#KkbTz z5wCD_je{k`vjvw5UMP5(V56X(ON9L0q~YFe!rvkIrr;+M|Eth8N<#T8VkTTw;sgvm zrwE0WLRX34bfN17?-YDQ@Oi;kiBSB3&|eB>!zC;jT}3=qa01c9_+*JNF3=3as293f z@KwPN1P=@TKtzUac$12|5kZd-dYsU+gsvC7U9g!LL&B#RK*GOE#2&#<1-}>kg$Ox6 z#y-rjSa677mEf5~$jujemEhHan+5L&#;E8~GLT@WM7$~ZmEcjq2u2T-YfnVFUV^6x zjuo6CIF|_dTA|kpUMc(={l?i^(KdwUC`dlD2`j_l%%XEMfVjiJExu6**xx?sMUPYlCW9yHc}mU1(&)* z*2Z-Y{dV+d)zOD{0XDANMq>Xv@dwWBt7_v1&Mj7_$J3T&sy^|OWyLBSAGPcyuYL64 z4G>!piWe+zXO8(bez>-^r!OXtHy!BSJahRSsw2(PlghU>R94B*6!X|xvOgbqCAg)Vb9Wlxx{-GNMxP1kZ7&1HL<(3Z>r3_H`c zA?m&iU9(~CM3ig8g9u{g_8R806V^I2x8`IE{tgxQDIKgW#hm!KOnzE>jBtDht?*uc^VtI>Um-P$7wl@lMtzQ`q zc<*HFZw!aLFHq(v!x=t44=~|NBI4sx0!;Xl$n(Wqa1UmDNfr41i7RG&Nko0?U_NGi zNtF6#GRCcm&c69H#a0}tmHRB%iwWOdAbR>%Fw^9OFTe1&O!%%L5mt9VPlc~N)94A` z7-oF8(S+oTFTWaL#+MK8VLlFYFys3Xh~d6Rm}{|q?H}d4nT6=0zJ$PdAJ-{h!k5Hk z-@PQtG%?Nh5Q%b4%<%n{L~_D6he>{%=qp{Mws#C+Ahra-T^BE)@Byd z`!vnk!XU!ba|;V>dArB+FBsHz0>Wwh+KKtzBMkqA;uTJ~d;G!+imOgRY|7aL6YU6DMhVQ}Q)NXh`gpBVm#pF)3#FhB8TCO;|pT(^LCt!uGZC!Rx90H5Krk z%tQmsFeF003TRCosI_JI4l(8=la@t%kB}H-)*+ufObD-lxZ9%rX=_kbSV%>K!neYw zp(s;?cf!n&o>UHhMO*cxa`++!2gGP%n=uf!T1ECkN$wZ8w9;R2a-TrLR=Mn;3^N5H zt=c|?$P7E&H-zTly$Gyu|7RHOZDM!;Ka5#MMj$-+BnrGkLxyN4c;7+F@W~8Y-reM% z!rbf_rH3tOQ8(f^btAPpNBT4^ZDeGG$K2l{JoY%@GaTWLsJ8GpW@CGMpy7nazl?Ce z>p@Y%6BrJ$05f+}$+;|a1>WKG0Os0|zxLM( z-rnA`nZ-&+T>(|Ea{Lvf>hsEx&^B^bgnPUQ;oOfY&`SqrP}@MhMdWh%WOyj6r|tA* zD~#|cRz&Vz7Gom4oV${`=Ig?J!U_m4Wl3^>jTc|i?j)?GGr}dz)bMtoF{O?H&w>%| z$gu5QM_m`vUVIU=ncYS2f-v8Rue+pO;1n=2^7G;O+(`VPOFDPE5SeVqh-?GL+l;(3 z+6_R^@D8A0r#q2}<-Hp+8C|Jk&?Gt6qU9##_iTm1 zuJ<-*Yu(#1wlTio($W~eK&p1+q(HA>wEHIvQ$MbS`p+2Ev<8Fk=rWM%N8TB(#(QGX z!SG6wyek&1g$vY=)Pc#^=mzAWeq@cf8gGk5^|BfvH^-uSLS4wFSTx43yGiNmV$q(= z^QS)|PgmnLv8bNM{`nZQuQydYjQ&@`XJ5tH4g=IHLi~pbG@)KWbS@c31=c& z$jK$WDV&V0D(S~!Ds>ur4p-yjv6AUznCcv~3(T39=vir(dK-C}jpIw+Kyg%x+M&te zB^@B8e2N{o*;rB12B-q@ck8<3P@)xG(Td(`rAhjtRdKw{+M?LE%;oCVaP<E{HoWxNddyAd_9=xZs-A(Y`d~T8G@U+Huey#6hba2PMQo ztD|3<@h8^i#ok2js>!1Z{@&^$U9>GU)YbUx>LOjVJ6SSR_39#Bw7VVK9#~zJhSsI- zq1CR&ovTYXLRANp?yI0-6n#h2Zlv9C=<1@Mjw83P)?!8xz9M4fW%FN<&eizF>Y@i( zN!!Ghi;JG6dmeRE>{{LNCX|j-Tt)Y?S-j)a)kCX`bk)A=i0xht0k_5RL#HEbrgh}s zgaqt&R8xW;=IU%!$4=gC>}NzLvcBq^%Cw@o#6sCd=Oc9KitQ{Sl(36bO{9wE##>$1 zdc;*sTk}uYU96)%qyD#OcMUT(8?pNCTgvEu033s|Sna86xzzFGJ+Y#!<|UW?)9jRd z@u48g&<{!P!hhaz$=^4y!!(}x{RI2=`jqCq_0K3ZKYn+^6xBEG+EAt1$H#9N)_lu` z)h_pv#b;E{UfDc))8DQC`Mh;==C#{ZV!nl0`Y--)-N|gNEz`LpE_YpK)up(mTh9!6 ze#nj?diK{a3Lvrv|C4=3i#(@)KWg5YaJ$r!_$${>P0lhA|a170+ZmGG0Q&bl)0cZzu+K!rcC5 zAm#2PAF~h-5!)KZ)5Jc8afsL#i|>g2@C-tm_0E9{Ig`bNQ-CbVWkPQd`W_-Y@T&0H z*eMs_^9kv~K+>GBqU(DKo=k+xtD6&>mv~|ypodW*OhFUTqQ4W`Lf=7tSg=sATyU`9 z>4IkoUMP5l;2#C=65J~IJkdl=zb=fA1ivQY?)^b%H^MZewP2J8L%Rq)P;k89*%H4< z=nDnw1+Nplg=n6Fb(zB0A^4JxFpT$vJ}CH|@QpObpftgW&BN~gSec7`iA@)&BKKza zda^4Xswp!6;==?}N&Kci-)1gNJGKHcKKGtd)ir+AJ?+iw+F&ZHB>vBPO3iI;5;Hog z68CO2k{`^(hK{NzKJngC_YO3!p}xd>piO@#OkR~>7U`9H+oNas;odP=@i^?h_UcG{ z$$iV>Pj&B*u0M4esBZknZG(YzZsNy}R9|dTOBf5{FTao*f926oq>Y|dDmYquqFC?dZy$X{#U@Q0S9d5+ zC%WV*)Qr(E+O8kHzhQKse)ORR1f~QU5b*YUv9^yU?S>InL+zo4mDZCqvVLc`!}XPW z>i2XzQeXLA!-PEzqu;CF?cIsxmY!|srO_E|qg>syc~j4xeioM^>MW-@S;lYJ9*h;# zS3b~C8Lh9pr=ha6zVfc>Eg95YxwqT)=PRGG8Y&;EuY6-i<+Ie&Q29pMBNeXQ`|CdN zq&>1d?UB(>HB5L&{T-8PRcCChe6~u;kF}M@1dYn4c2w>>F8TKTDaR7WT2k-)eQL<* zw7ZT=`=7GLRG#Dd-)G%Wc~=A1dhY7?^osTk6LyiV2*Kbpsy5bPs1P$+QfgNncm#ga z75h+9OIDa(;F)HG+_B^h1D>6XZ`5SJ1TF}CXU|R?Wy{g8%E#O z?bZ5M>W_F2qaKR1EEb+V+wbYx)>=*4)(KD7R~4i^Qu)+@;W1=~NLF9v&U!3}MLkrM zZk+Jm85`p_phr1lfpN6<9zBIwU%9((^=>0=-EX=o?rNZ&E!H#kP+((S9u&4Pbv+nx zWZeg<9);Mwz6xtscRuErySsjf6{{a>H%xdIQF?jo@llL{w}yvwJlqz5+s2;JqFgJi zuc|=W9r*IaazxPF7pUJ$jA|GiX_$aTw!0fDMxCgmVKj0;^&t204HMud1cp+uYM>4e z*Zv4JOxVdP!@O+L8FZqSD4dpYgvv(HjeazkOn{I;(m1lc%W)H0gVeYtjvs zf%?jwXteNx+U@vkflAhN-4RvmXYNbwhVudk#~~Qcda49Vp$9$Ht!yXke4wFXAZj(N zUCr;QEoIe)7PQ3GtN2Y%^^0w%r{(V1QK?(`JIwD9*lMqM8)II^hX>JIe>J9@PCSpOp>EvT#9rEpXHvEPLE(k@?$ zP78r$-hP#P(k`C`3f_S$JH;9%pa}%j?zBgY^_4%=AqX%3P*fk4bxcO+#+ zYqtA zF06TfzM_k@DY+>8_|E?scK&s%^Nh5$egxrjG^8w@9k+b8WOsmjdm1VW8qOEEK}$d8_EyFA&;3%b+eez?pN_|> zu;4&PBt$wCq3b}Ewl+tT1r5XTz(HxWaTNo{qB-wvDg4^)E6|%FPx>2y=PSCh#cZq_ zcf3{L#QsyJoHo-b=AD>A4F7$yhd$G{QPO|^sVv$ijJAz~Q?&B)M;@=8<>3u#El4@O zFp&Ixb~1KA0(hm%#wy%3dGWtJU(y|9l;mi8{n#k(!!@ga$f#|v+f$U~Ip$Y9*x-+= z&G?OIiT0xznGGY+k9^yJ{t7+!#!U~vGBn9}*^a_;r@2i8N2|!&e{xH^V8ddq3`8XD zUs^#^ZrqVyp-mg;sx6i@^3c`UzIuGI5A18H;0|lI*ACMX3yt`eovmXFJa~vq*L@TX z{ttdQaBYi*j?hq^_Q-@EaAVMuczEy6|G%ZD;T55ViU_uxtlNI^aBabturYq?&eo^q z9ea-bHzt^l3Di@C=a-`}geUoAtqmJ+c1B`UHDllZrNJZdv07bU)#bo7$s6Yc)qKif zV8S)PE$!Y(3LmVP?F2gwG*>wWoCG-(C%vC`$+61#4=$DDPSaXn)#;$MDZcB4cEj>? zJ!9w2A>BnrQR#=!<=1^+uSJg_9W=~GO{T58QX3wHPtZrrLxN=I6OD%+>li}>M*%2A z)rp00B90rd;Q1ZJKAe`0={TdK`)~R}-+Nj;yWob3f`+qfjEvRW+DBve$G+7rKfonF z$qv1~GIp3xDQp;m{kU=UqYA@3^kyFRX4Z-+2Y4g_G$zaAjHd8>Vjr)omCLh_d0(C? z+RSLx{`Z}1b)$(U`}PCd9jBx{601N(rLDU+Nz-Sw|K(dibpPX@>oV#*`32>_$P+!& zv4^*Q$AAeT$2SMZ=#-D0kTU+(i+QD-?LVf>c?2KyZaV1Mgc`?#YGd`0sb`<{j1kY- z^^bV^OT${vUp#xsqWO#GaU&_V@Sa;+y?li){_#r-qPl9j(`{_^D% zS~7R;^6C`@%U8@?wxWMQ@tlI{#dG=>&xybDNiJs&KVT^xFly#jG&U-i&4 z%U#M_C!tt=o`;aKhfDMP>*51m8xUK8Qif7qzYLsUDW)P)-bqIgSuO&ka%Mi|V@9TO zCMRVtgMm*G47uBIu09Pbs@?e?F-5RDTPuXohRH&Ef%YyY3?L<){$cY7aXNIjHzXH3vRD*2?;|zD@_MkxUZgAXX+%Xgi z!X<{gycn?=!N=ivcehapN7A^W*xjA0*YbiVBQJLkrY#6=LfPE0o>w3u8a&Dby{V`) zcryI#?sFgbor5k>I>R!u?Qiu-)RwId@D`r_dB=s z0cEI&d9~Vx87o|IL2~Zz4yPe2N52k96sNeuESi>0Cisa7xGC95z!207p)8A@6zhbr zHj6&cqL4a+%xd`GpaXtaq7y9Ur}Pl3fgW)LKcdygmueHD!dw{GiWjK=SUcn)5H8lQ zyFWb?u;69e!@;3r^veDP=ANRRyycY-ItiSz(JQRI2j_+29nA0Ry1RYvez)Rm_d zUtp{tzv_F!G{Fw?+yqZL!-3#C)RMt)C|FMU)(mF^G1rFuU(^_ZVJ{-JYZDs1C*lSx z5M>(-*=eI;S~?FPutPnNz;d-Q(oJZ$(>1B`jPx-0cBVt-8tE6Hnb_G5nPa41$+US6 znQf#mMRT5LnCA84ARHrVt=9as(d5;QCfCblO7m4l}3ES`m}=l zh-81u;@H7G;Mm_WjQgKuJ3112SkJUQlP6r*N_~lN*3(R8TZ;W@L^njYqCz7Qi_k#q z#6*mRq{U!nenHJ%H4VJ1O!Uhcc0e5jk=>h(BB-=!R-TbfrkyHu#E3-E!0a@w+KOnq zGc;jGKBEOWik1b8%+GXtQGalw{bg|#VusyO^@Al5t|qZNiE%wxs?MU0Uvcd+^*L>e zWZ+R^m+K@USk0R%^G9aUO>qxUmJd2DyRYK6&1_u<{f}AArC#<>hmKhhDb_F%$dF%Za*gbj)HGe_ z93#6@-wd-vH9YtU9AwYdezF{=%}F}#X|{v8>S1IW=tn)?U=#98?~Nqh)Rxxs5d7qI z?qk)~NPiNA^~!yW+uBcIxsP#MFNnc&Ub&HRU;hTZUb&HTjNn$}<;{0mxa%^Cw&NO| zz;(D(cuTHBR>8MmmbZg$O+ikqdpo`bkKifDw4KPegMYx)+l3|uf&uu>t8eH~aEXe) z@^)sd3pICRbYA)$Xky;(QksI`QRL+9K{A^DDk|06OQK5C$5ClthiqG#zLS#u9kNYn zunn^xNV0RVFWRto5X0rcESflk;hw=<<~6j(L=b(0KhlU{j2LLRPN$J$`TZkf(fnCh z!7y$o%c{LKo?bVCcjGSgPGHw+8?8r=IN9({;;N582SjH0>^xumv3J_XW`N}j9RV*8 z)l99_z2P$_t>^1Y2*5Y)pyy_)$ z4J&suQl=O#rt-CI5Bb0$XqoIQ+=AOB$S%uQL^TFFNIc?v?LJ4?3Ua}iFUtA|1o@=# zl~6vUyBA-3@-uYz;_JXU%82e>d>t9i3;qKo_I0LALGTr3P__%+!(D>>$l@EsaMvIY67yBixbk2j%IX`!aL?c}W;~RJ_6_cWo|tbKBL)WXs55*c z??g5gX*?*$H#!f=hNACSh%DR|AAznrSj^LF=+a9-NB#bj0&pW=3H<>oHG+MRfj>x{ zR`8D~j6aokhn>b&;!mS^AUF%T`1MI*p;(Yh>HT3glZ@cWxcW0rflx$0y!=^IniqWA z1V5W4D+oRXulVyAE`(WZb#CikD0C?l-`|!CpaWmw(%E112^0n2L&5w}8e!-L<}apB z%gL*KjG5Vv5v4RDpzlk+zAr<;E-0{H*K0;_I>TLalpx}x3394ggmo7S$gyUT5i}^GUPRhqk%O$oJoPS!;gSB#RZb;{ zG?H*mB^V#Mg@hbR5LpCu0XdW)vVw#hN)Wk_M0dqbW=`aKx=Kzpi%f{opk9g#GjRyk zBHD0$;1P-hHnW()Tjv}5(ZT|^u)tRERr2qs2Ac<%T?rmmxgp-(4i@e9vcDpi z725U!6e#}(w2r`F^&uGfd>RHSR7?|XX~hs7k@`6N6}+68q-Nq0T(5)IBWbW+2hTvE zom0zf6B!Oc+5*GV8<3jGs9bUazo5*vI*>FE3 zR2tDIXhc6(AI)1x$8!9L)hJL^s1HlpVP>HedNpm+B@lCL*kL+0kc168Ovi?dDBm$u z>{WA@ws?tAaw%M-P8f-tK@7%&tiQ%sxyw6jZ2I|{W*KJIjS{wf@lYiZk05D^@--MPMTlD zK2EJRDQPxFoYGuoI_{qazkCH(mvDW6I@kOW-%ZD9bJjbGVa~Z)6Y@74Rp*K-%P2gD zg*e%KI2{iF+!(6qN2GG<`(*Qk`aW4Ql=?ndjFtL6S&YqdayVIXC~)d`7#+Z~(UxG( zEDO`dWW#(4d3~#M{RiHuoLt-JT)7^uNY`4MLVI8(sivuLZ&9p0stN3*SGgt? zq|-*N=vSq|LLJpNE!tu?5B2^3kzzu#afaia zy&^ovan2_~)1y8p>RQcCh4sJE!%ZKewL0~Ftu}@A?o{lx z%DI=>+)(e=DvGk+i#Un^%_lf3+Ua1fReTb=8nG5qdoH0p=W2X3=5#pMsXJr3Fr%Wd z3kNc4bGbw@`T*&h#r%qB89i~UkVD%qtj2kP_b86zU5$^$q8wkU`=r*Yq9-%)R>i&- z3mT)>u@WDb*x{%G)^5i=Z1U@4y6pU#zMP4g2B8aZx}5cTQ$|adlO(P7y6E+yZibWD z6^aSbM4+A7mYzp#^R;sB9qXlUsH-63cy7KZc@Ig46L0lY0VPiJxt#udbUnP%S;R zo?7T}EbN=K&}jm(e#&|1;B|W-H&xtvEebnFI##Nwv@KWDH^E8QY5Uf-=*>M* zZ?3ddtB7wql8$QiZO}$yYob0b@KJXD=rqf)rJM(6E(eEdukxfD+?AZ=i? zU23e{Iob=Y{E6kX5%cQ^KQCg3sZ7oW^aARUYnhC_LdV&*&?QN z(S7n3>5{u}22V*`z%lHu6AZh@$?fbin;qJ{`_lFOS5x)@yQpR-az>f%tRJb?hKZd| zC(Z0OfGuh@&0GnC_W@PYh@7OEt4}arSxx zvJZbEq1pxt!-njx)NgV?sSqP>RyvvkpphIZEW*n!Qh` zhTc*QPJwzS8!m6mnCk09&T%s6=TJ3eoV8OG)aX2~`M%Pw< zaJF{t=gD0-wW0J>I}Xn2!Z`-j+VNn>@n9s9%uwG(IZoulvKyOYhx)44eNk`OLBo~W z-#;K_M7rM}^auR$U7tUe))QMx9j1xfwKOsCI+YuL;ER2ol3(s<;gc}`Wt8Mq{NKY8 z$*&#mb<8w*{&6?S>ez4qhrOTX@z;qu*NpEPft!NXJb zy3O+Rl~dNoAN)FU$`-q5o#xKP)igVY-7oz0nkVfSH`^!KMfjiIXs4USxYpT?_cs33 zKJVtW6d&b&%>8$}-8{Q+YE9hzO?P#F{G@M2_c;x5F8eKBU90R(lyr}Dy8`x2gY3)f z; zCAh~elCF_lscv&v5YMu33}!pLQyKtpzWLH=2K%8geYBexwda&1I`I6dYv#Y1ipJN+x6wKA%bxW-IRrPM3 z@!c|Xbl-0?-P7?`4CZuizVgQmW%1OR`0k&w{R^iro_Wsnnah^VJiqyqpAM+BrOTGg zu3o-;`qDYI(=ol+y!V&2>VyM{6OERc8PsQH;EZB^eO{hu+^za0{$-ib_y@nO3{D?0 zX8NjSFl0JDMkmTs%&zgequKFWj`nJeMTH`< zoxWsFb>gcOGxyp%G2~f1XSyVL_!V`7`k(JLNX$1?_pJ|^>S2}0@tTpXms;u#72CiY zBY8$n<98cXTh0J8g zBnP}AGbWgFsbsaX32}8C3{~v<9Ka_}gRNIt22>&ZF zz@zee|AJuh#q!_O>{I`yrZXOG52q(Cx<$2(aji)51-d0I%4D9Vi)7Hu6_823y|>6D z%`E+QGjD@@a*m)yo;s@>oh%AhN?-KxSlcqP-1 z20oKaC}*1@ImRQs0(5dTO`0tz`Hnz(J>rwC zlk|0~kbDuRz}ujcRZRLb(8=l{eFU_g7E0s?%yo$wK2?x- zHeiNSR^nWr%1>!olNUDqMwjDgI`x#_(IbzedF;;& z(8*U4>RWnTJkxWfZ}P|2dE?^a8SoU>swIC+u=#iNpFk%^oXp_y-^IW9JNnh%(QkoH zz8=J=VE^v~xWps*qXArentX|&dt68=47tWb}+@JJG986Vj$lvryJdvg@NDL0C-Z8w&8YUhDcrP=2 z#W;rsXq7mB@_@KsXuUcLH+)Z2G3E4M)j{9Gqb`}AE2GJ;fSpzcY`r6P#M{2$(?sYy zB*=n-ju{gW;7+YY#7-Eu5}|M%kP7*Mn>)I=$IXjDCuhQ~E@%osrsKpA<@qs-^6P+< zYXDO22O`o3QXD=Hb0S~wbt^-)E(L>%ZXiYtV+)Xq!Wa^BN7e{pH^bm&XUg$IHs!dF zopN_F9wpX$+<^QF&v>5Z#Q5 zSz;(y0R|QD9l<&YeFl&T-xu5~c$o1})G7ePOnwwdxsIe^U_T;UeKk;fj5ydZ{tTr4 zNYF93Es*qiLDWB8{xBFserP2Y<6Vx5I{~SfAHmGt*ak>G>To~#Lr~YGA@?h3$W6g* zWSxxjg^4iaMk4eb1=65&+~X{8HjoCC#t@)_u0XcRS;SKe<5J>K!$?T{jS~Mbu?%nL zKq~qiNJT}MTc=AG5|QD(f-eFo_bQNbUd&`uuB%{diUc+QX~@;2QIflazE9{kfUNsa zx}%_n;Bq3`!refY@NYz9_zaL4w#jhxwgXb{1fW@ojhGHUX3Ud_%N>TXQRv5oep=|a zh5nb&ijytvG4BmzM&&>jpf8XaO=LU_nI`coCH^9be}M7rQ2!?80-4YTGT|vilxP*u z?20Oo_!}jDtHkdV{>#Eo&2rKe1F5eQY3Mr{X!e335?@amhFt~p#bEhkj2Moi9Dz)@ zi!>5`2xJLA1+s*E9cDZ?z%sr7NJS+;#xEj`Dyj!k-?c!>-$1&rVQdxpZ$f_#jIpF$ zvLOH*0c3(Pq>*4Q(Cls)Ye@IQ?FnT3y`&NUPvNKMIQ(oN`2&O=BJ?C6J#a2*=(&kB z48JW0_dhNF6$~nN;=93ePS zaH`-U!3&VTPLRY6LN^LF3EnMupWrisFA44u{8;b{!5;U~$RQy49(aqGE|@RaNwANDG2;|rOcmrV875pV z7!zy|+~soOd2|!yJ{J5%kjEg9-&U}rU~fULL}5J7!%?jNGlj88@I1k_f^k7ENnpYU z1-A?8gQ3Cyr_i4Z{vzm4anj`ob`b1Ej3MC=VVo{FM{v2|9|Ug~%^&t;Ls62b1k7#V|vF;?&_!3Bb=1RDesg0~4iB>1f0tAhU&JS3?~LzI7)De;C#XJ1?vU>DEKGAM+Bb{d|mKk!EXdzI0i^( z%yVmKKwH6%g8IA@@GFHLFF0FpncyXYn*?tZyi1VB2vGla!CiuT^eizV_6p;$;4gwU zhGtBdA=pl^OmL9kXu)ZMHG*6%!}MzeHwbb87x}RVB=EQ(U)LCMM385ukq!yA5iAw# zCpcKJQgD*s*@F6@P3Wl=`Vt3Y#ztZMQSf%b2L=Bo_=4a+1V0q~T<}N16pRsRFpugX zwh`e~6}0|Dz>hieRjm!mK#(CY=S61*W*?tiY+XToN|j|BG#a)l@3j|%!Ro+r&E;>1G1&Vs`P z&k*DSJ<8PzUMhGMSE(_AFABulh#>_r$V6z304xJXPMA^ zpP+ob@UIg(cBcfM7ko(s4hsFVpot+76_yd9XprD|!Ko5|zR>l8n}mO}(DwtM|I zOc*~2rrqoDzP1cwPu666~a<5vn^ zCU~vjLxRr;z9zU|@EaoXF)^B@o>qcoKz;vL3Zse$!6ib+1UC!bDe;d8{juPWf;@np z>AMh-(Mf{Cg+EE?xq>TswlxJ;i@*knxIyqwf{zJ4M??m12>r3(*MbUfO1gxCc|^$b zRgC=pf+GYcXUY9PPZ%o&FB9BEgo2xezEAK)K~5c0@jk)t1yk@YL4KxS9+8F!-A`~> zOac=G7YHsTB0(~Kqwwz*+kpd$H#}knOUmnTd zD0qY5-GW;MpA&pt@I%2b1^KQ?J$}5#>H9xN2hht!`I1S&vjoo(JYVoi!Rv@f zcdO733i1;*)4wG6uHXT|ABbKEV03KYd&8PsGbd3}qRv~q9@@AGjkD3j_XN3Fm~^?| zc){}o?-JxI66FpH=HX3*^l&0NgK0$EvrCDYiBO)oM9ofAwO22jK^5QKH8YIL(qDHV zfJtbKT~z$=pE5a5UxMJXHP%fIdzm1u1{wq(PvlQGg6Jtu0lu=gV z$%|C3*{KcBTXG;X{zO^G-5G}|edJ1%uU187YGM5FpG(YeAx|FzL++eH@beO(e6z^Aw#Iq-XD0^aoB1gPcp?8jF+JaGXJ%IL81lsR`DUoY-j&X5 zK8?WxRTq(V{|*0{OY+w{F}Q zvUwL_rYRS>+DgMXhjz%1as2u5561H}^zfGw5758B1fGmu$))a0CN44p6EI25 zYLZ_vcog*UX8r;*4}(WsrtHTOKa5#^&eIV7d+>UCZX{^HDGtCoxXke9h?$*?euMv}S@ywugW49eb;J z*lr5W>UQ^mQrBiGhzv*Gt_{?leI|qaR_W}bc89Egd;pe*6C&1II>>L{)*iaXGc@sH zxf&3=65){bdI!k(2SUH~&LiNUkRfn_dy$d#F(ZQ?GU;9heFMP_rLc zDg0G5uV4d$mj6?R3n^jypJup-;ee55ah0}<8dBOJh}p6oi0+xvfgi&BS0gf|6GaVw z4oZ^JnPJP%8HN;R+qC}$%5@e^Yu>QK|nsX4Ypc_?`W1RVjUI5SDGzJS3%+zObOJ zbjj1KM&y@fu?QiuSGNc;zLh4)hfE!1su5&ftv29kjjIzi9h~rAT9WFJM6urtvuIj2 znSg(@GW^e$1PmdEz2vg!NwJp^)@IQM+IC3sGal?f{&c|aN_2w7KE#Ju4fKd3_;01^ zfv7OIZnWYB>Mzp{nFPYc`c3KYcxW*gzO9H0xzi@V<>~kci>~h2PURtBx{uqb3{m&7 zoyyZl9^0wR4`FWE;E0{doB?zn+o^nznvd;N=1Je~BQzh{7ugu%oww@>70x7NQrX{|D77d)GpYv;;j+?2?Uq@A)VvMl;{0#1K_H_F5Xs@%U)6c&Y z=_zCO8U9%emopskb86Egn>>dwZObN4|H}~Y$R^K+7(TYia|Ov`n>_ys%VM6EU7r5e zsc0ZG=QQzWywRlbbyG(bO}RGnURKPtQ1>gy4UgI>)mf z(4kQ0g!7TBZ1VI>dWSo%(=0Z{G>Zw+EIQ2$Sg8;*Ll$?DXL7fj8r=rhkx-$Uc#M1& zTd^ALLlEoUjmU3|DI>`fBmU0Fru#r;b2FjBNI=VFT?Boqj84buXhgV?T;*0H<-_=Y6SHed#goa&AUBx-t5xMDGhpQ>DLd;Wtzt8h zVtuuf+mbd;b_c{k^2VC4~;;4do42&GFj~RmF{5ZiM&)) zi?W%7Kgz16Hrfl`kUMcnLKP*p?@;ZwuIYonsOc$zy{7S8qE$aN?7#oJaJyR8m~HLX zUtQ%&d~}l9_rF+GcK8(4I`RG>b#3D76pT-|491`CzIZ}(>&gnXD<#G!5a+jU66A^# z(vJwTL6PPYhWL))r-Hu;`sfA3X9^Yxb`@O0nnC;;K|aDk$BY|<@h8DY1-ZnE3G`P2 z;HN@=Cup&9!A}?D&PdYT1WytiAvjTRrl9^UjS;A)3K1A1I7RqeFG0Drf>#S}7QA2ZQ6lubDfC{! zuLTXS-+oiQ5TmiQ}zs%zq3r>XYln*sd-(RP#yslAD^QL25)_b{hpV(KUe zeVd4pQ-BG=-x7ZY$84LC*gZ;>m?JYdI!~mIM!Hdn{L!kt`Xw=pFekAD;2w`jgZB*% zt<8aL65B_s;jZ4jx^q;m)+X*RG&>}gu2HF57o4tkrdT+;b!ei`cr|TG?}iCDh3}9Y z-gO=Bq?Xf{^bt+Z9?#i^G8+dLfW@OhD=d9-D-Pazuff2#+hFk zi5U}A2kUtxO#EqrN~pGplPBV@Dc<}SJARWtBXRRYm7{tlZknLlB;J~+)~RWUvnHug zTmLjkU8hP{EIXg4Hmz8KlbvQ)&tF-6;sH*@wa)oXwTVGf)Y%#OPef9F;mqYL3KnB! ztPe{c&Q!xD^~IPHw+4Qenuu%QCfvb%#_^ZV0VjTVoj4OLoaJOA7OxY0)B`wx!VAC( zP%bWXZF!xzK5^ffs$JK|;13+pv_?y(d;*GpZ|EAW(VdILt_k4DYr{i{qi3qptYNSw z<*lzEWAiUcrR-6-+Mgu`O;y9%wuPpYcXrSw{0$OBq_W3K`M5uWof5ZBRfXB#gX4Av z{(&h_<}T!D&koci-k+-4#M&bo=OS@sTc8RN?oN!x%N!W)&J0_Dv&eS__<`9BcU?g7 zz|~Y;b{E2-07uO3a;{g)2=JSyyPJX7j&GFn#s$9P})k98xX=~uxlt& zjUaU&H#~P+OTh>~L$21TLz3tPMzJI(B)E@UJ#yCxzT{LYa^O&%e-lv#^ls~4U}&>g zX004jZiKZRgOW@~_rDp;RuH1s^>|(9^lvglAroF+Mor6cfqIS(+!kMiT&z!be||>y zb3BT3khrraV7d}7ou#tc{S50o0UpNW=lW3`f|LV)A9n~+AT!}PTeXYrM64%+d4~c6 znW#0x8G+|;^<**;&%fb#+NH~XeX2S1Pi;mT?*OthvY`nqM3(HI5eJn3mh9^+}rgHj?I`K&ojkmFQ$oG8wmq=FFUpJ;P7l06Fdgj(nk$ ziKVd!XVuh`4jIVS3n-qV+s(#N*#l|VGxRlfYG!j8tJ=Y)U^Z4|_h1=baf&oPyBj4x zcBsj@`VUSYa3rVY>ObB6nM2Jm@+LFG2Wj?l{=tX2Oxe^MPq7HQ5cMGM4tO}idmu?! zPIk>s21^~o9&)G^MwT8k-@-B^VAXqCP2$-Zs#I-Hd_F@JmDiw_BBwL?dZ%tiMb2RP*E`}?_U+8Go<24k zr)J-n7(7$8E8>$o7kjHW@Kps{j*T{jNOTs6><6i!exe$Qcn`*oBU3t;ipl z`$ETdJCdfGr;vf{4T)Z}R8gR&MakrDiP^JMyS`d%GP6RP&emhq*$xFe9;eEYB;SQ! z`AAbuTrLpl;YvI)OXcJSX=s%8Jb}nIbbb?;15n_bS!#glmMEKzo$(+~pRKYzT7O1$ zVogG|M49G=+{A;(!_cT4CWyY!hr?YQ?kE*)XKl{vNX3oqxAtZrhVt|l0B#?x+ zC=e771QZb!@BtJepz=^av?_y&0)h$-a;#E8MXlGjrN$~&w5X`~Xz_uHO7VqCl~!ui zwsOC3?{y{#?fu>V|DInm-(G94{XWmV*Io;!h>ef-av&2@g@p-^CL-f&8IOvt22%c3 z@_WKgIFRzM#+nN+R!dZB2x?D@J4<<@0#^z8f{zG3CHO}{PEb((OF?~;0&Vkr24)NL z(k4Ankds)XM;J`$%_w9{mx#H7oTnjQD`o+2B#p}6F8l`tw+g-@_@3aGg7kjEbox^Z z`LsvtnQs@3c+k}egKlK>2Zhl3(+YwMg}zE~jo|Hq4+uUfs1>u2?ipZ`Me_H+SCN-{lfoFFpP7C zawSBh8z^|Z@J|t1t5-oTCG-s@K4sk}g1?rC=Y)Pk@I%1^fU7@H<>U)tzU%C@humW`3LVgcHbP(3! z@M=Xw{9ro8JtMgc7doFaoVXky21xIX^`JI}N6 z*|rUx`sW^pt5HU2Z?6m{kjQTq0V9D79P z^dk+Gk&&G(>wrq{X((0I{+TIN<@G7Sf)AR5e5^dK?qrphK~0z*bM0Gd{Wnu;l--~| zKy9m!|43K6x*1=f4`eIlce+uPr)b0_9L}0eh-IBZaKoHR3+IIMaP@~(j1xj(J31Dn zgu~G%2`a*yZAh==RB-hrY-jN~8;(V3W;81tn!@z>jq0Zk_l$n z2iK{w?H*tSZZ~n`icavIoAH|VncwSXb(5OyKYugY)9fE0oaE=N2Xyxbu2*B##r_IX zgZzirt1H!Ezrk0P9nWP!-G7T(^SB!S*k=D`^Bi9tZAX7Vq-}M{xYio~KTl0I_q_(?cW0>B>lZ|J#jfl7C)U6~fV$+kDX` z1;b>u&8f#QkrA2D4Y$HDFHir+E$Se)G=B9Pwb&lhOJ7Y(aqaxeTuo>7;?)#^M+EDt zkiTt-Dzy)H$y`n~CHiuzEkWZ$yqvOT^uj8sKP81TuND{3CY(aNq&n#Z)18&LN^Q>S zsC@t1W_6-HppRZD-CpTqrL=G4ikQ`I*(?5SPpF&EST+0*yp&wCZDFnnVFIURGUtjz z*1~LX4lg?!y63zQ`4h0M6Pc- zr2YD=3L9(NG);jgDvq$?{D51C)8S&=C3*0&;(-~Ov%ta(O$0T^)Xc+NOasy+G^S|y zqzGNha0Rbb+s>laa_ByuSyeoTdB2$pOOSlc&#d@zxj4jc=Zv-O>zN>&Rfoi!%Gs!k zjws4a<&RkbejN|sP|7R;w?hgsq&+TS4~^=upZ^>_&mG!p&(Ow>RpP_1*^% z!L5o?*_`st`k0Z~&!Re6pD>uz--erq;|hzvKoq7?hEMVNG-!*cQ~__*`^f?_gqSG_h*!^ z`yIkLZWi*1)bmR;-{sD|NJB^b2D42y2p78pDASv1OWc|KqK)*S21~iSkqP=SqiXkL zR<1uaT58?tOfcX^gk`qr=MZVHf7sCWy5*7Z6R2e*%qHZJy*VSq`1YD4A2R<%nI;5T zR;s;L~#PiOfEVe{0obMCGnzJb#e=gStbOfCzDXBLmq(33ddgmw2t} z>7|tJ30SAZX%=mN4^oC*PT@s!SwhU6ibT;ohF!N27i~13;T-oE%6DKm->txJv?H_R z7&2S%v zWA01*?awfluK$a*8_*uV34Z**8gUbH%{u|%R@R7Df!E3!@efGb${KMMuK(8Nh^L_E zTUjHnLgp>jh~1x)?4qk>g)XCL*eciw-(?q>|w zkRNkT#;;f-c2oR(5Oc&X-$xv?bnRY1zFE3<>sXd7T|bKxqQyS38)y4u>AC}xv@Bis zWo|7?*Uz)|nU!moAAYb;jP~Oi=j@3XD0aKDre^8d9mK-S(zUyVl?axuA7fFc%tzsY zed4v?xSZp6CU6|E)0YEr8qdm%ePXsLQH)5~C;k-Sb_>o;&9LH56IfQeISXc5@x(6> z47;zO5^>LrI@i?VIe!G-bvb(+*S8#)Fy^vhJZ}Rs>PQ`*z=Uxn(iWTvL95_a{HlWU zz_1Io3FAU-!nh!UlrUk8R8Z#We2~@R%sXrt(@U~DmZg_6A4{Kq@v;{Y47;DBlz2G@ z(RFzt$15qG!+IDBS*!_`}t))zf%P+Th-8~4Gr`(Sy)Ig%b zrJdM#FNQ1Kz6|$fxXR^~81KVywL6mC(U0M7?jfe_&v18lYy{z>8Ln|Tdl?_daIO0V zD|#%$JzRbw#s@Rp(@ofNo(bST4p+$0Mg#+nXrc{7QhK>o4rX8guaoR8SR zgfYjECXCsgkudKtp^5CGlNwM?Vg}N}gmDC)UTzsGk>9`g*l^HV4|k*x<> zY#3{KcOtS*V;ta~m|&z>uBY2+i(YYX`0tSH_;`m(09Vayvy zB+Rek&}Q^qVn8PZlX_z1cvj+VRC5LXVTlTN>LQ+L>Uj1erdf-4uBl;$3K#LDQp1@s zCdP|+TB#9+8d<~>OPye-VW}dXTWX{s8;f{Ws8J@H!Xlm)>O?~o7qQROXqF9|vPEo& z8pDRzYs-(~C7@1b)9tkri?xZm(^zL{ZJstv!tfGyz}r|L{% z%Oq|viD5K&4a@2NXNV_tlFyN%vo4^!k-?nNZz#iQ1B-HMgEo=^gDD`;HzvmpuA?&8z0er_m|XhdBLkO)A9*#TLb>L`PsQgtEB(8msCx9)4{p^RWGZ~BR0mm&U_~{ zcTFh2Pp^IICc7rjuF2ns zW9?0`S+T8;zXH>S&2>A~Kb4<5&>rT`dQElJ^RUg$ui-1!-|@P7`3U1kZ>WD|bWCW+ zsKS5j59+i3|F61c|BtFprPzIKCTu@76Sl=*H{w4ShK$T<#sE$U;-=z17}-obCWh@D zCJ%l|r8fRnzLq3Bo*!S9Q_v3gEF~oE2t8 zgCp0D`Io+>hMyhOngUCMSYR%uk=6r)S~LExR`D$C!6Rs{;Rh|C{C2;}v%9qa@CdQb z{Lyc#8`HaP%d@9l;_rQ1O~#uRWZ=%h$_B>s@D&0K40ktJGxhql2^2Tn{DvqR@MR%!rCX z%*ewPOaIHgfHtl^euK~t^KHZ~*dIkK!Jc`cKNOm)t;`qq3yZoQ93(|kusqULc5hIc&0lpq?B9-X;+b3I0}4@9akWAB5(l9MgRv z_%}h$kCM+JB31~}SP$tzf?RASeVUEFU|>DQhIohI6N1|X-w@m*xL=U38cY|(l}OAL z>@3(r@L0jof|CVj)87pf>Yd%df`DL^&{Usf!oh+k3Q}c~{GSQV71ZV@!M|4Mn*?tc)H}fuuXlp;`hQL$UK4yz zkY7hE;ID!|3C3~rAitxaUa|n)Q|N($BLv3_E*8`)6_CFHw7&ki-o^~?5&WIt%YttU z?i18Y7m)u^XfEe6eP_Y$f;68-KCS-{>1TvES@2v(uK$aKu|)7X!S#Z73O*(Hg5VoO zT+1H`{b#{{2s*fXvOro5B320Y796Tg5hLPcVbDVh1f z{#t0g;~VL4u3@Gfuj@plAI=*Uumm*U{D!6H-B+NUmDsp0c9I)ut{q<3G@crs|vp!DuG#PRP}!94VHtm6r9LlJo~PR z`45ayrS|WOjN;%oMH$7x$U!{Qc3Xb=SXCCTz-N;`8X<27o}@WwA)eS)dp+yC8_&!? z8(qS^71Sl{=wG)_HG~E<)TeJhzq+CJIEdotqkpTdPIzrWcUkCCjp$B|`nid)=ePS9 zE04wSLcVHvzV_7#kDZ@Ti4abt55f8N%HhyL+zZP2+a3SE))STUmz<=I>N{4~41RT2 z4&VPDD)~RxvFmxQ-7Y_i0khy%cjegq@GQD=?15DXOmbHtFv>mpl|_9?Ul?9>DIAX; zST!lOYE*dT!G;}Z-pcPAc5B7W-K)m#S^0*u1HMqBoZGX$%HqqRb@le*^dEj#kly-C ztOhQ}sUAvi%W6>#e3Qa=Dn{b^^xa4>o(|p*ii7t<{^3)g=1_Zza#L75(CLsG9d}TB zL_f50Tv#tlcy^-Mm zzmi&sa0tz%58cD7&OX%CyHk2qqEqTQJ&x?JL)uL%`U?%8aCrW>!}G@+oizb$lH6pw@Lv zKlM~s)z!c4Q}uemr+7s<<@yy<4Y;`ffr^IxD?h_RVMl-WXR2qx?+^*kxm2eByojCz z{L}V3eXc(Az5S|ds_CMO=3P_*8@AdL>#U|}Gny`nTNN{)^^P^5eEf^&)e~?VLpC_V zDvADa^HH}8d2_)*4{JQI7DVeHSPPng+YQ!$;y5D#kKuuWrJ&=%3{@~3ECr=FZxY&q ztlF*x(e7MkE$Aua9_oh%X4Zl(K!Q*a9t`4n^%$16`X1IGoJC`Lp}&)Jr03OL$RoN9 zQlW9o5-UdI0hN?DD@OeGkQJlfkZV?qR-xTy#VB+Wf?372%wj8KBc1ml7#o1vh9h05 zIOr_%FaJUnch84lWHCRk+?>c;ixJ~3VS;ybkT2Mg-OI`C??3kiwjXXrujE8_ZDSU+ zjT3oqEP|*m=MSuRwN zbmowHmrT}!9dJa8+En;!3UV0OBmYCA3J{f>8bJa6AbaYMN5aQ|2yuX;1KCBftC3f6 ztliUKbGa#|D_}WX=#3edt`3*MV!7 z*YQl-vf6Y4+T^rsl)N65b5bokB~NE`%TCEpQD3LUrE3#oYk2kO)uz>`tyyvjqwOH@ z(_pTmhZ#05T^%mkI)O{qb*$Zh*VsZfEf)7mBRK!_c-xM*?3CmOPCT@O?RkqGb=WWZtM6SvalobDveMoEYJhvH_Vq?6A|o7E=gBUZ?)HaX9* z!NF=1KbGRB^gtG7wJCn;NgUwX;S`!s3clrVo*{l3PfJ;Dil5O9La}m0<|krz`YXSI zp@|PsT*Bj6$DGR%oyhqfVb`HnVk`4zf3kv9p^9jS9>)|C<+Xt%83j}Wv9&W404 zXhLRf*Ofj5AL~j?mFWB+i|2gg#6;IBw7?n3J7%Jk`B)Cmw1jbu>8wOAC(1cmuEQ%f zQAzn6XDn-5MSi}sADo17jp=ZvB4J!(I&tJ?Tqu?}FHqjN#&jN~jB$(srGUFQ4 zf!%E@VO(Q6Uqdp{_#}SoohZ`|Ww?*C7&58EFt%oZLu-2p;~LZ99V2lfl>p7UQey0# zs0!DWI0Y05^Lh*Y$SytUYedBU32wQY_&vLHA9~JpnWyDcp#ayo#&qt5pxeqdrrVC< zZpwKLHF9&9Aji?3Y;$?ar1(Ydv*0X>lTVLWFMn&9=YfPSkk#KLM z2>rmsooNLwHU>YnZYjU2ol8(>*SN;iCzxB2Vy0nJSQQJ4nMzc%60W{#U47N&IGoIJ zYbl@ae9LeTh6|nTEUS+B7wevL>)CT94s{INUVO_dHxAZh6@492q144}!hrV> zj)Y%Ce$lItAjV0Bb>81-8_gMkN_*cmAF`b3zIM2AobT}2~8P}K&bVw}k zCk}CrLn9NOagCXz#agCW= zLqc3*CVdj(8Z)_@Tc61=`pG=#litLQS;;nvt8j*qvA&2&1kH}7E3avs7k zd3UnGVP^#S_cVb`*O>X>MZ&b-7vBaJ>#g4t$>o3^^)3dY_yP9v5S5w2s1sD#PXfh zSx=fr)nG`?)>8EI+=XX6R>gSAQ>x@+1k{(jw=YKzHEY2;AlP*rgE}I`9Y&=(`vWHT zF{O3rAN4f_u~u11zX$4@M>RFxbSVklrR@y;Y(P6!Ngq^EeZVqHQ07cs=HC%-%G434 zTdA(kQxQJ~`DLv((5zn9rRaC{DDz{J%DM8Ye#OtnDlKygWps0X zB{C-K`%EWXV3nT-S#=lRN=%BYGb!#u3c7=|O#3&R_M>&??))j=Gtt_*rXGeUnLbbC626e7&jOLMv4<8tqlrF&P&UCh1mHvoZ4RSQ;Yz(ed=2lg?C*+QxRt0`+H?qAmGJ(8 z&1cA@Y60Gg8KXPAD_;-PEN%&csRJ_@vsi$3jTu9Q)dft&jcF)ifu-j0)V9|)nm(P+ z-qEL+9-~X&(I@Z(ob1f9{EINgU!Bd_jMcgZ126+=nsIiUW(XzCIL9<&R;kW(3KJQh zQOv&lWS%i6(XNE)%*~lRPim8=rr?fLGCkR3I-~Sc)?^%?Kk(pI&21+&;FK1zJ5LQd z&??iKG$YtgoVmJ4SO2?AQ6t(EC6ttOg2`lR=}>+BkCcL~iqBa@4YPa^|6D*-8#c5L z#zaTpZ0+iCOlmk}9235=s~UD!D~jVavi$`?9S^SzeLF{3AO`DT22rp)O(&J13? z8N9Pf>v+HEcc;#DLMc^G0=HcgF?RcqVI<6IciW8aQF*K~4^~@kFsG1aW~!Ulrn-5V z>P}@_^4ioluT6a=F5g_%9n1wF)$Q1(y2Wj(t0y<0dEqzqSB+_JdC&BMj=BD@AJm`I z-M-Foy5OZ$`}p!t{85$RR;8)Ls5~wsm%`TOG574oFRFd?fGifPbg5bls(`b|MzF!98mJ01OKTZ{iUO$(^0 zSNc!*;TyVv@?w*Zbgx;|uRx58OAm{U=qLT(qF+qQKMClu2y}()oweN<0Qx;mY=E0rT+-Y-~tbcR6b&P*u zmVIR#ZIu3D^g=KH^1*hu=5Y}_^ncir=#P)u4;s@1L8F6ysSm;E!BH{$us<6Uo!oPf z;w72UE1~YmGc6kq8xa-UY1+uVZDgtuKLh{44K5=i`YCo(i*`y09nGu zcqCcWLgj&Hnm))|@gH~_{sZq3f5=_fb+h^|Xphw%XXk3yJj{h>j*XA|)<+1FN4SAz z&ML-Nfey|f(o|sy&Jxn2K?i3C>2p8_X9DRtpo38dJ=NluK`_J=xE^#cnxr>^4n~jk zqo9M)BE1cCFgm1P2OSIsXkXF87Idjf{Q5W=UHF!&_t!AA6hG|?Al-6=tU~`cuHDKb zmw!2WYC;&xqAf?R?O9*9ka|ftj3EvVjt8f!gM)O<5p*w=-d)}~Mb)L?$hBQ-W-FS> zI7J^Er0F;zIC3z&oCyyOdIzJLO>j`2dkKSsuBi5b4n9V5VQSB!zD@Am0fydHT!OP; zCQ^~+jCyb|!vUa!&kx3*aYX#oBWOA;pQ1f4o@;U0 zsR<9M>E}1$_RG}iKit-#YWgKwX!-?B)8;Ok&xcamQfEz@JL7_;i~MJ@u_^3l(Y*W_ zmzX+SbTOWQEPl$oMa;=B8E(hY>F7|uHpd?0Z_Kf4L}9KBUzg~Ncscel0mBu>Za}ya z*9mD{a6F}L$h{?U-7#pC8v=Cj5;B}LZtqKp-7wcdM7oE8c6V4O12X?E=xgRfWvX~N zUe-@Uz`;MKLAf9N5+DV*KEwo%l8=nuA=ctQWHO8c8NUX|^beBX1J@<7r)5#uit%3n z=}4$u*re+KB!4u}Ng?4(M$}`5Kq9CtMfx_OpBMUNp*b^SH(;x&@c$xw>Rix?Ob!w0 zI{;Zwwa`6;9s^{BPX(qJpz=L&n&2!!P9)Ji){Q{+2$iLnA(f-p<Gk`T1f}d0HXk6*UftGcvAPrctBEJDr zo=Q=a|CsT|7-cBRgS7BEwWmP6hrK5VLwlp0V3A;@;PHZ5s}FKos}HEP`hcA0W%@0G zF9>SoJ@C0%jq&>hsiaOC4-#TZ`~4)Nn_+0bZKTHtJyGy{!HWg261+k1R>6A&X@`^f zaEBG~WkF7tlI9e@qDJVC!k{G{M&t^f8aDJff{O&N6ue&W7lL;SJ}S6f@O43+m(2f5 z!5@ezFk%>gMidBE3icHoCdd<#a$GkgUMRR!aJAqqf_Do(BB(Xlk?s|t-vg$Y(HFwd z+Ipb1wjNL`>jBGf!ceZK;6Oo~pqf8k@EpPO1TPl6O7I3jp0CXBz6i#j0iLkL?Si`m z_X&P2_@iJXYUFbTwc8e??y9iw)*kAB?!IK5g)NWUhV5Ts%fdS9~f0gik!Mg+>7JN$ZMZsNy z9|?XX_;R2@DY&EqI3DbivC6mkXu^HwxY_*es}(^-$3JLVqs!t>9sU z*!#ix00?TWJz$y8^z}#nF@h%uo+>y+@Df3-ya)MPg}z7dF~Q#nY9&6%y{&1C|2~QM zMvzVeS+J8Z*io=duwHPG;E94~2vV1X>9yMy;1Z!%3Em=jH<8!>W5RewaHrtAf}aU~ zD+rAST|l;A2f?m_Jp}25kQJFFI7d*sZvp=r(E9q<{#(G>T2v!Qeuh8_K$oTPs6SdnFB%CRXMS{x&Zy+N6mqOn!_@v-=iQgskp9BvI{wVPd zW=vUdfncRzt#-SD0*(>JD8X|D=Mxcsz0kJ_{+Hm3f^Q3cCHNO2((%KC1!oI(7aSs( z3jDK75XR30mk6#VBBPsyzFY8N;r~wPor3!X|1PL7qsa7~iKs}e;6Q^ZYostv7n~uu zRPYAD`viYYM20(seot_};CF&y=vJ`6TtPaTBz>$P9wk`6#wCS{>I|3B)Jm7sI=-7A z|0e|Z2wHe?A-`O3q~I*U6@tGK+#$GM&_!CNuNRyksNbjYk+Yg~KD+>IVgS2Cwh)a| z1bfCM>A&nvQoJMxfHf&rMpo3!=0(cl`i~8Mx zEy>%;jcFxUM(yOIA``&+DPr6x)Z@jMa}F#n%eYY(AJryjG#HaJ2mr9xGNO{&_6L%l8g2 zSVvrlx~XhBhc-xqp!Gu1w1r_FLEOtGjB`Yej>XiV9{d8x*5!W7)8$+n-9QXS7}oql3t%aGtq$fW-QVW#IO^H>9|@KbT`4GzZf|BzrH_i=aa zo#9`?2I!+*4b`}Zw?`7D!r{f78=ZIo5;a zO+ekU-YY{8C0+r@=E`E$$BfM8S4Y+-3~E0YFwF61gpFa2eN5q9;2*5C3sTe~h?Fvt zijj{3L)2M_lriYOj4Hwm2hG-ceJEK&Nz3Ejj7TlRVefH7iWv^?2Zno6O~LhUfMBGK z-~Tz@9OM(J?~8E0Hw{&bG@OMn^deJm>k#R6A&6q{NecC5;u4P=dLn(e#8&PtWrBXp zsM@2NQKUa74Qf4_zKaZa3t>@=RWz#Q0QuO;a91 z2PxEqAPdu~i~0vKI}wxHg;s)S#Awr1*Ml8!M2p%~crgVz4D1mj$X2zH*@URv*BQ?rPh5Kg#+UZyFv$Ut_H zTLuQ~a8P-&m6=!X2aH72C`Ni)(F;+d80kHSG|@bk=6XYMB}9#4q<0qOjbfzN8?n)j z%#nJL@3X|kID?~wG<)vyQJRDu4$idX{Q#ns9gg)XJ@2hz*nGOKo84(lZ`87tVGVv0 zv@)#0&%0KJHE5qZ)}rZ1<8j8YhSqdE-T$_m-Mfk(!?6Kppl0rK_<^a6`&kPbE#$5Mek{bYuKkT?=t)vlNcwtUJvw|n8ffnB_k#=ynmu`ViLpK#Ii(5 zv5eu2lA=eO=z&R$EByX7XcK1vT5Ml@=+UZR+$bY@Jagmvf`*X`T7`_~aWbGI?ZyU1E-pY{6mYuGD!2^4s(|0JZIuzJ zCx=y8riypw?0{PeaoD(c1TF9i9DM%8OPP=5-He~OQAYGep&{||ec-qruabBr<#W7Z z*0zfLeD5)E;zk+K(^HW~8PVg4Z(J*_m3UWE-Y6q_oCb;;Wkhc>Iy^4Qh+aPuMj6rL zlw#Z{BYLx$kx@p}4t?TA8PR(k)r}ivMDG}8I&dc{RO@Lw6-F7++r)y6GNShi8)lRd zJ;k&}8PSWP+*EuRTQk7BkQo_eM30wg{KUu6KBJ5nA6tWDR7RvudL+!tH}oXC^rXdz zaBIPZkqauvc)hNL=s)^oI4unxn^g6TdMm5p9hGCRw4@{#2RT8K36=LTAcb6A6z+JoBECyQCXxY`GzPx23Fg&Sxg zj%Q4ug~-_}*ulFEg*GOs&;fHJwIGHi-$GxwS_v^_jYuBPS{17O$nJz>2@@5o??H@A zE@XWIEyPDj1X_sPyzK^Bh%1;~poMrNi9ic+J&8aI@jLcJpoB;*F1N4p*Vo(Gsa$q~ zyNRvy#!~7I1}*Ojw(U-~GwfYV{yiK6Dj#x>KqOp_Ok&%>Vs#xp2Fc}+9rY=Orub>* zJ4F2iMlt7I-9{6>f`t#&;cU$9r7Ukb3(0;Q<#{V~a0SG@l{&Z@ZOzuohp{e5cn-b= zpnS+rg6wgOI*Odmn^2${^csR(+RMkk+CZucpEha`Pg`i|bm0lA2Jr-iQc(%76V-S+ zyt3DhEcpp1o9blBYApF9t5q7(aT7~) z?iD8YVS%1cPWt@=kNfj_+y98ZPC0AQ|BFsdb8%mLv+cvu$cN2$4X`JutSMO9o8f1_ z289Y(9$DU^D)PZVySr8udHdhAM6UOLKFI#4jlM@k^A&^blK+F2NArdu_DM1Ssu8L% z#m70f2+-;k@fg7q1Wy&ziz0|$EcDfaHww~91=H`r*+KkV@F&4I2AKSgf~5viR!?Ej zL>2{jEfBTE8{iC~7YJS@xK?nJ;KPDkjc58-1@{PkB}mgyjOU{syFbn992s3T15+A; zM+*)YoFF(|@FKx01=k2}6nsGNNN+Q*3;%s$3I%^IjBf?0`OXT_93+ujRfu|V1lUVx zu9TBMR*574zj_ZJ)~ zNF{yBb8j8-TtR-Kk)|zs;xa)fZ(~&kj19t|rAyMZ08ZQ{xKnVqpk5q7{6V4lu1fhB zuVG-mAaCrXYXt`g4ig;5T{RRqOBgiGMwlf2KAozqJH!hH`7e|15gytLu`LzE+ zOl3=;gP=BLfQSa62MLZ6JWX(#;2gnA1+NuM3vLp8Q1D5?7Y(MYH-+&h!LJ4XAsE9$ ziZ$&ZSSna2c&y+k!P5n&3(gnRKJAgubwc|ZG5&gW1Q8EN#1n$t$D_MY@UUPQvgGFo z77JDj_7)s0I7)Da;5AV-4AHP-H|wE8FwjvJ`D?R)t0*>ALL_+JZ@|a-`iqqcvlx~ vYxvDB7zs<8?%wXt8*f)dmX<&T%TCw!Dph;^XTT{uP>aT+&cT6au|EDAwIn@8 delta 61040 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 A-v9sr diff --git a/Program/src/makefile b/Program/src/makefile index a3af8ef..a488915 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -10,7 +10,6 @@ CFILES += server.c #used for poxix port CFILES += protocol_handler.c CFILES += mib.c CFILES += filesystem_funcs.c -CFILES += ringbuf.c CFILES += requests.c CFILES += tasks.c CFILES += file_delivery_app.c diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index cca2d64..24ae20f 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -260,7 +260,7 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { holder.offsets = ssp_alloc(count, sizeof(Offset)); holder.i = 0; - req->file->missing_offsets->print(req->file->missing_offsets, fill_nak_array, &holder); + req->file->missing_offsets->iterate(req->file->missing_offsets, fill_nak_array, &holder); pdu_nak->start_scope = holder.offsets[0].start; pdu_nak->end_scope = holder.offsets[holder.i-1].end; @@ -280,7 +280,7 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { return data_len; } -uint8_t build_ack(char*packet, uint32_t start, uint8_t type, Request *req) { +uint8_t build_ack(char*packet, uint32_t start, uint8_t type) { packet[start] = ACK_PDU; uint32_t packet_index = start + 1; Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; @@ -643,7 +643,7 @@ void user_request_handler(Response res, Request *req, Client* client) { ssp_printf("req->buff is null, couldn't process user request\n"); return; } - uint32_t start = build_pdu_header(res.msg, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req, client); switch (req->type) @@ -651,7 +651,7 @@ void user_request_handler(Response res, Request *req, Client* client) { case eof: ssp_printf("sending eof\n"); req->type = none; - build_eof_packet(res.msg, start, req); + build_eof_packet(req->buff, start, req); ssp_sendto(res); break; @@ -659,7 +659,7 @@ void user_request_handler(Response res, Request *req, Client* client) { if (req->sent_first_data_round == 1) return; - if (build_data_packet(res.msg, start, req->file, client->packet_len)) { + if (build_data_packet(req->buff, start, req->file, client->packet_len)) { req->type = eof; req->sent_first_data_round = 1; ssp_printf("sending data blast\n"); @@ -676,7 +676,7 @@ void user_request_handler(Response res, Request *req, Client* client) { case finished: ssp_printf("sending finished packet\n"); - build_ack(res.msg, start, FINISHED_PDU, req); + build_ack(req->buff, start, FINISHED_PDU); ssp_sendto(res); req->resent_finished++; break; @@ -763,7 +763,7 @@ void on_server_time_out(Response res, Request *req) { //received EOF, send back 3 eof packets if (req->received_eof && req->resent_eof < 3) { ssp_printf("sending eof ack\n"); - build_ack(res.msg, start, EOF_PDU, req); + build_ack(res.msg, start, EOF_PDU); ssp_sendto(res); req->resent_eof++; } diff --git a/Program/src/remote_pic2.jpeg b/Program/src/remote_pic2.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8c727e085507309e22d0059687c15e4d884930d0 GIT binary patch literal 150033 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

u;b_%m1w>npTOZ22dacFAZgy8!w)SVc47OD( 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 z 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.addr); if (req != NULL) ssp_free(req); + request = NULL; } diff --git a/Program/src/ringbuf.c b/Program/src/ringbuf.c deleted file mode 100644 index b18ddb6..0000000 --- a/Program/src/ringbuf.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * ringbuf.c - C ring buffer (FIFO) implementation. - * - * Written in 2011 by Drew Hess . - * - * To the extent possible under law, the author(s) have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. - * - * You should have received a copy of the CC0 Public Domain Dedication - * along with this software. If not, see - * . - */ - -#include "ringbuf.h" - -#include -#include -#include -#include -#include -#include -#include - -/* - * The code is written for clarity, not cleverness or performance, and - * contains many assert()s to enforce invariant assumptions and catch - * bugs. Feel free to optimize the code and to remove asserts for use - * in your own projects, once you're comfortable that it functions as - * intended. - */ - -struct ringbuf_t -{ - uint8_t *buf; - uint8_t *head, *tail; - size_t size; -}; - -ringbuf_t -ringbuf_new(size_t capacity) -{ - ringbuf_t rb = malloc(sizeof(struct ringbuf_t)); - if (rb) { - - /* One byte is used for detecting the full condition. */ - rb->size = capacity + 1; - rb->buf = malloc(rb->size); - if (rb->buf) - ringbuf_reset(rb); - else { - free(rb); - return 0; - } - } - return rb; -} - -size_t -ringbuf_buffer_size(const struct ringbuf_t *rb) -{ - return rb->size; -} - -void -ringbuf_reset(ringbuf_t rb) -{ - rb->head = rb->tail = rb->buf; -} - -void -ringbuf_free(ringbuf_t *rb) -{ - assert(rb && *rb); - free((*rb)->buf); - free(*rb); - *rb = 0; -} - -size_t -ringbuf_capacity(const struct ringbuf_t *rb) -{ - return ringbuf_buffer_size(rb) - 1; -} - -/* - * Return a pointer to one-past-the-end of the ring buffer's - * contiguous buffer. You shouldn't normally need to use this function - * unless you're writing a new ringbuf_* function. - */ -static const uint8_t * -ringbuf_end(const struct ringbuf_t *rb) -{ - return rb->buf + ringbuf_buffer_size(rb); -} - -size_t -ringbuf_bytes_free(const struct ringbuf_t *rb) -{ - if (rb->head >= rb->tail) - return ringbuf_capacity(rb) - (rb->head - rb->tail); - else - return rb->tail - rb->head - 1; -} - -size_t -ringbuf_bytes_used(const struct ringbuf_t *rb) -{ - return ringbuf_capacity(rb) - ringbuf_bytes_free(rb); -} - -int -ringbuf_is_full(const struct ringbuf_t *rb) -{ - return ringbuf_bytes_free(rb) == 0; -} - -int -ringbuf_is_empty(const struct ringbuf_t *rb) -{ - return ringbuf_bytes_free(rb) == ringbuf_capacity(rb); -} - -const void * -ringbuf_tail(const struct ringbuf_t *rb) -{ - return rb->tail; -} - -const void * -ringbuf_head(const struct ringbuf_t *rb) -{ - return rb->head; -} - -/* - * Given a ring buffer rb and a pointer to a location within its - * contiguous buffer, return the a pointer to the next logical - * location in the ring buffer. - */ -static uint8_t * -ringbuf_nextp(ringbuf_t rb, const uint8_t *p) -{ - /* - * The assert guarantees the expression (++p - rb->buf) is - * non-negative; therefore, the modulus operation is safe and - * portable. - */ - assert((p >= rb->buf) && (p < ringbuf_end(rb))); - return rb->buf + ((++p - rb->buf) % ringbuf_buffer_size(rb)); -} - -size_t -ringbuf_findchr(const struct ringbuf_t *rb, int c, size_t offset) -{ - const uint8_t *bufend = ringbuf_end(rb); - size_t bytes_used = ringbuf_bytes_used(rb); - if (offset >= bytes_used) - return bytes_used; - - const uint8_t *start = rb->buf + - (((rb->tail - rb->buf) + offset) % ringbuf_buffer_size(rb)); - assert(bufend > start); - size_t n = MIN(bufend - start, bytes_used - offset); - const uint8_t *found = memchr(start, c, n); - if (found) - return offset + (found - start); - else - return ringbuf_findchr(rb, c, offset + n); -} - -size_t -ringbuf_memset(ringbuf_t dst, int c, size_t len) -{ - const uint8_t *bufend = ringbuf_end(dst); - size_t nwritten = 0; - size_t count = MIN(len, ringbuf_buffer_size(dst)); - int overflow = count > ringbuf_bytes_free(dst); - - while (nwritten != count) { - - /* don't copy beyond the end of the buffer */ - assert(bufend > dst->head); - size_t n = MIN(bufend - dst->head, count - nwritten); - memset(dst->head, c, n); - dst->head += n; - nwritten += n; - - /* wrap? */ - if (dst->head == bufend) - dst->head = dst->buf; - } - - if (overflow) { - dst->tail = ringbuf_nextp(dst, dst->head); - assert(ringbuf_is_full(dst)); - } - - return nwritten; -} - -void * -ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count) -{ - const uint8_t *u8src = src; - const uint8_t *bufend = ringbuf_end(dst); - int overflow = count > ringbuf_bytes_free(dst); - size_t nread = 0; - - while (nread != count) { - /* don't copy beyond the end of the buffer */ - assert(bufend > dst->head); - size_t n = MIN(bufend - dst->head, count - nread); - memcpy(dst->head, u8src + nread, n); - dst->head += n; - nread += n; - - /* wrap? */ - if (dst->head == bufend) - dst->head = dst->buf; - } - - if (overflow) { - dst->tail = ringbuf_nextp(dst, dst->head); - assert(ringbuf_is_full(dst)); - } - - return dst->head; -} - -ssize_t -ringbuf_read(int fd, ringbuf_t rb, size_t count) -{ - const uint8_t *bufend = ringbuf_end(rb); - size_t nfree = ringbuf_bytes_free(rb); - - /* don't write beyond the end of the buffer */ - assert(bufend > rb->head); - count = MIN(bufend - rb->head, count); - ssize_t n = read(fd, rb->head, count); - if (n > 0) { - assert(rb->head + n <= bufend); - rb->head += n; - - /* wrap? */ - if (rb->head == bufend) - rb->head = rb->buf; - - /* fix up the tail pointer if an overflow occurred */ - if (n > nfree) { - rb->tail = ringbuf_nextp(rb, rb->head); - assert(ringbuf_is_full(rb)); - } - } - - return n; -} - -void * -ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count) -{ - size_t bytes_used = ringbuf_bytes_used(src); - if (count > bytes_used) - return 0; - - uint8_t *u8dst = dst; - const uint8_t *bufend = ringbuf_end(src); - size_t nwritten = 0; - while (nwritten != count) { - assert(bufend > src->tail); - size_t n = MIN(bufend - src->tail, count - nwritten); - memcpy(u8dst + nwritten, src->tail, n); - src->tail += n; - nwritten += n; - - /* wrap ? */ - if (src->tail == bufend) - src->tail = src->buf; - } - - assert(count + ringbuf_bytes_used(src) == bytes_used); - return src->tail; -} - -ssize_t -ringbuf_write(int fd, ringbuf_t rb, size_t count) -{ - size_t bytes_used = ringbuf_bytes_used(rb); - if (count > bytes_used) - return 0; - - const uint8_t *bufend = ringbuf_end(rb); - assert(bufend > rb->head); - count = MIN(bufend - rb->tail, count); - ssize_t n = write(fd, rb->tail, count); - if (n > 0) { - assert(rb->tail + n <= bufend); - rb->tail += n; - - /* wrap? */ - if (rb->tail == bufend) - rb->tail = rb->buf; - - assert(n + ringbuf_bytes_used(rb) == bytes_used); - } - - return n; -} - -void * -ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count) -{ - size_t src_bytes_used = ringbuf_bytes_used(src); - if (count > src_bytes_used) - return 0; - int overflow = count > ringbuf_bytes_free(dst); - - const uint8_t *src_bufend = ringbuf_end(src); - const uint8_t *dst_bufend = ringbuf_end(dst); - size_t ncopied = 0; - while (ncopied != count) { - assert(src_bufend > src->tail); - size_t nsrc = MIN(src_bufend - src->tail, count - ncopied); - assert(dst_bufend > dst->head); - size_t n = MIN(dst_bufend - dst->head, nsrc); - memcpy(dst->head, src->tail, n); - src->tail += n; - dst->head += n; - ncopied += n; - - /* wrap ? */ - if (src->tail == src_bufend) - src->tail = src->buf; - if (dst->head == dst_bufend) - dst->head = dst->buf; - } - - assert(count + ringbuf_bytes_used(src) == src_bytes_used); - - if (overflow) { - dst->tail = ringbuf_nextp(dst, dst->head); - assert(ringbuf_is_full(dst)); - } - - return dst->head; -} diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 68a89e0..bb0a7a9 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -123,7 +123,7 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { client }; - client->request_list->print(client->request_list, user_request_check, ¶ms); + client->request_list->iterate(client->request_list, user_request_check, ¶ms); return 0; @@ -141,7 +141,7 @@ static int on_time_out_posix(void *other) { if(p_state->current_request == NULL) return 0; - p_state->request_list->print(p_state->request_list, timeout_check, p_state->request_list); + p_state->request_list->iterate(p_state->request_list, timeout_check, p_state->request_list); return 0; } diff --git a/Program/src/utils.c b/Program/src/utils.c index d3b6098..1ae1d36 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -202,7 +202,7 @@ static int push(List *list, void *element, uint32_t id) to print out an element. ------------------------------------------------------------------------------*/ -static void printList(List *list, void (*f)(void *element, void *args), void *args) +static void iterate(List *list, void (*f)(void *element, void *args), void *args) { NODE *cur = list->head->next; NODE *next; @@ -377,7 +377,7 @@ List *linked_list() newList->push = push; newList->remove = removeElement; - newList->print = printList; + newList->iterate = iterate; newList->free = freeList; newList->insert = insert; newList->pop = pop; From 95d0918b7ba744bfd89902edbd60f3ba17ca1e91 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 15 Aug 2019 12:00:42 -0600 Subject: [PATCH 067/400] removed list from utils, adding list tests --- Program/.gitignore | 2 + Program/include/filesystem_funcs.h | 2 +- Program/include/list.h | 47 +++++ Program/include/protocol_handler.h | 2 +- Program/include/utils.h | 41 ---- Program/src/file_delivery_app.a | Bin 154770 -> 159160 bytes Program/src/filesystem_funcs.c | 2 +- Program/src/list.c | 296 +++++++++++++++++++++++++++++ Program/src/makefile | 2 +- Program/src/mib.c | 1 + Program/src/utils.c | 290 ---------------------------- Program/test/filesystem_tests.c | 6 +- Program/test/list_tests.c | 15 ++ Program/test/list_tests.h | 10 + Program/test/main.c | 15 +- Program/test/makefile | 4 +- Program/test/packet_tests.c | 2 +- Program/test/request_tests.c | 2 +- 18 files changed, 391 insertions(+), 348 deletions(-) create mode 100644 Program/.gitignore create mode 100644 Program/include/list.h create mode 100644 Program/src/list.c create mode 100644 Program/test/list_tests.c create mode 100644 Program/test/list_tests.h diff --git a/Program/.gitignore b/Program/.gitignore new file mode 100644 index 0000000..151a620 --- /dev/null +++ b/Program/.gitignore @@ -0,0 +1,2 @@ +*.o +*.a \ No newline at end of file diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 93a8e4b..db5ebfa 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -2,7 +2,7 @@ #ifndef FILESYSTEM_FUNCS_H #define FILESYSTEM_FUNCS_H #include -#include "utils.h" +#include "list.h" #define TEMP_FILESIZE 1000 diff --git a/Program/include/list.h b/Program/include/list.h new file mode 100644 index 0000000..f2b6bcc --- /dev/null +++ b/Program/include/list.h @@ -0,0 +1,47 @@ + +#include +#ifndef LIST_H +#define LIST_H +/*------------------------------------------------------------------------------ + Purpose: This is a node for the link list bellow +------------------------------------------------------------------------------*/ +typedef struct NODE +{ + uint32_t id; + void *element; + struct NODE *next; + struct NODE *prev; +} NODE; + +/*------------------------------------------------------------------------------ + Purpose: This is a LIST struct that contains functions useful for + doing linked list functionality. +------------------------------------------------------------------------------*/ +typedef struct List +{ + struct NODE *head; + struct NODE *tail; + int count; + int (*push)(struct List *list, void *element, uint32_t id); + void *(*remove)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + void (*iterate)(struct List *list, void (*f)(void *element, void *args), void *args); + void (*free)(struct List *list, void (*f)(void *element)); + void *(*pop) (struct List *list); + int (*insert) (struct List *list, void *element, uint32_t id); + int (*insertAt)(struct List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args); + //returns a void pointer that should be cast to the type + void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + struct NODE *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + void (*freeNode)(NODE *node); + +} List; + +NODE *createNode(void *element, uint32_t id); +/*------------------------------------------------------------------------------ + Purpose: This function initializes a linked list LIST *. + Perameters: empty is just for the compiler errors, TODO use it for something + Return: returns a pointer to an initilized LIST * +------------------------------------------------------------------------------*/ +List *linked_list(void); + +#endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 88c648b..cf8f546 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -2,7 +2,7 @@ #ifndef PROTOCOL_H #define PROTOCOL_H -#include "utils.h" +#include "list.h" #include "packet.h" #include "mib.h" #include "filesystem_funcs.h" diff --git a/Program/include/utils.h b/Program/include/utils.h index 6525e83..54a1db7 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -23,46 +23,6 @@ typedef struct config uint8_t verbose_level; } Config; -/*------------------------------------------------------------------------------ - Purpose: This is a node for the link list bellow -------------------------------------------------------------------------------*/ -typedef struct NODE -{ - uint32_t id; - void *element; - struct NODE *next; - struct NODE *prev; -} NODE; - -/*------------------------------------------------------------------------------ - Purpose: This is a LIST struct that contains functions useful for - doing linked list functionality. -------------------------------------------------------------------------------*/ -typedef struct List -{ - struct NODE *head; - struct NODE *tail; - int count; - int (*push)(struct List *list, void *element, uint32_t id); - void *(*remove)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); - void (*iterate)(struct List *list, void (*f)(void *element, void *args), void *args); - void (*free)(struct List *list, void (*f)(void *element)); - void *(*pop) (struct List *list); - int (*insert) (struct List *list, void *element, uint32_t id); - int (*insertAt)(struct List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args); - //returns a void pointer that should be cast to the type - void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); - struct NODE *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); - void (*freeNode)(NODE *node); - -} List; - -/*------------------------------------------------------------------------------ - Purpose: This function initializes a linked list LIST *. - Perameters: empty is just for the compiler errors, TODO use it for something - Return: returns a pointer to an initilized LIST * -------------------------------------------------------------------------------*/ -List *linked_list(void); /*------------------------------------------------------------------------------ Purpose: This function checks to see if the memory is allocated, @@ -86,7 +46,6 @@ Config *configuration(int argc, char **argv); #define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) -NODE *createNode(void *element, uint32_t id); void ssp_print_hex(char *stuff, int size); #endif //UTILS_H diff --git a/Program/src/file_delivery_app.a b/Program/src/file_delivery_app.a index 7685da14d7ec31d84d973b6b4762d1c3b90bbd92..7629c1ffe8f5b4cef3630127eb2245b7fb9ecadd 100644 GIT binary patch delta 25015 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 delta 22157 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 diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 4059d84..263ba3d 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -6,7 +6,7 @@ #include #include "utils.h" #include "string.h" - +#include "list.h" uint32_t get_file_size(char *source_file_name) { diff --git a/Program/src/list.c b/Program/src/list.c new file mode 100644 index 0000000..40af636 --- /dev/null +++ b/Program/src/list.c @@ -0,0 +1,296 @@ + + +#include "list.h" +#include +#include +#include + +/*------------------------------------------------------------------------------ + This function creates a new node to add into the linked list, returns the + new node, or NULL if failed +------------------------------------------------------------------------------*/ + +NODE *createNode(void *element, uint32_t id) +{ + NODE *newNode = calloc(sizeof(NODE), 1); + if(!checkAlloc(newNode, 0)) + return NULL; + + newNode->element = element; + newNode->id = id; + return newNode; +} + + + + +/*------------------------------------------------------------------------------ + This function creates a new node to add into the linked list, returns the + new node. +------------------------------------------------------------------------------*/ + + +static void freeNode(NODE *node) { + if (node != NULL) + free(node); +} + +static void *pop(List *list) { + + if (list->count == 0) + return NULL; + + NODE *last_data_node = list->tail->prev; + + NODE *prev = last_data_node->prev; + prev->next = list->tail; + list->tail->prev = prev; + + list->count--; + void *element = last_data_node->element; + freeNode(last_data_node); + return element; +} + + +/*------------------------------------------------------------------------------ + This function creates a new node to add into the beginning of the + linked list, returns the new node. +------------------------------------------------------------------------------*/ + +static int insert(List *list, void *element, uint32_t id) { + + NODE *head = list->head; + NODE *node = createNode(element, id); + if (node == NULL) { + return 0; + } + + node->next = head->next; + node->next->prev = node; + node->prev = head; + + head->next = node; + list->count++; + return 1; +} + +/*------------------------------------------------------------------------------ + This function adds a new element into the linked list. returns 1 if success + 0 if failed. +------------------------------------------------------------------------------*/ + +static int push(List *list, void *element, uint32_t id) +{ + + NODE *newNode = createNode(element, id); + if (newNode == NULL) { + return 0; + } + NODE *tail = list->tail; + + newNode->next = tail; + newNode->prev = tail->prev; + + tail->prev->next = newNode; + tail->prev = newNode; + + if (list->count == 0) { + list->head->next = newNode; + } + + list->count++; + return 1; +} + +/*------------------------------------------------------------------------------ + This function will print out the list if given a callback that is designed + to print out an element. +------------------------------------------------------------------------------*/ + +static void iterate(List *list, void (*f)(void *element, void *args), void *args) +{ + NODE *cur = list->head->next; + NODE *next; + while (cur->next != NULL) + { + next = cur->next; + f(cur->element, args); + cur = next; + } +} + + +/*------------------------------------------------------------------------------ + This function removes an element from the linked list, returns the node stored if success + and NULL if item not found. it can use either an id, or callback to find the + element (callback can be the find function) +------------------------------------------------------------------------------*/ + +static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) +{ + NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = 0; + while (cur->next != NULL) + { + if (f != NULL) + found_with_func = f(cur->element, args); + + if (id == cur->id) + found_with_id = 1; + + if (found_with_func || found_with_id) + { + NODE *previous = cur->prev; + NODE *next = cur->next; + + previous->next = next; + next->prev = previous; + + list->count--; + void *element = cur->element; + freeNode(cur); + return element; + } + cur = cur->next; + } + return NULL; +} + + + +/*------------------------------------------------------------------------------ + frees the linked list. Takes a free function that is a function pointer to + a function that frees and elemnent. Returns nothing, +------------------------------------------------------------------------------*/ + +static void freeList(List *list, void (*f)(void *element)) +{ + NODE *cur = list->head->next; + + while (cur->next != NULL) + { + NODE *n = cur; + cur = cur->next; + f(n->element); + freeNode(n); + } + free(list->head); + free(list->tail); + free(list); +} + +/*------------------------------------------------------------------------------ + This function finds an element, returns and element on success and NULL on + failure. The return value should be cast to the element type. can search with + either a callback, or id +------------------------------------------------------------------------------*/ + +static void *findElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) +{ + + NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = 0; + while (cur->next != NULL) + { + if (f != NULL) + found_with_func = f(cur->element, args); + + if(id != 0 && cur->id == id) + found_with_id = 1; + + if (found_with_func || found_with_id){ + return cur->element; + } + cur = cur->next; + } + return NULL; +} + +static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args) { + + NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = 0; + while (cur->next != NULL) + { + if (f != NULL) + found_with_func = f(cur->element, args); + + if(id != 0 && cur->id == id) + found_with_id = 1; + + if (found_with_func || found_with_id) { + NODE *new = createNode(element, id); + new->next = cur; + new->prev = cur->prev; + new->prev->next = new; + cur->prev = new; + list->count++; + } + + cur = cur->next; + } + return -1; +} + + +static NODE *findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { + + NODE *cur = list->head->next; + int found_with_func = 0; + int found_with_id = 0; + while (cur->next != NULL) + { + if (f != NULL) + found_with_func = f(cur->element, args); + + if(id != 0 && cur->id == id) + found_with_id = 1; + + if (found_with_func || found_with_id){ + return cur; + } + cur = cur->next; + } + return NULL; +} +//see header file return NULL if fails + +List *linked_list() +{ + List *newList = calloc(sizeof(List), 1); + if(!checkAlloc(newList, 0)) + return NULL; + + newList->head = createNode(NULL, 0); + if (newList->head == NULL) + return NULL; + + newList->tail = createNode(NULL, 0); + if (newList->tail == NULL) + return NULL; + + NODE *tail = newList->tail; + NODE *head = newList->head; + + tail->prev = head; + tail->next = NULL; + head->next = tail; + head->prev = NULL; + + newList->push = push; + newList->remove = removeElement; + newList->iterate = iterate; + newList->free = freeList; + newList->insert = insert; + newList->pop = pop; + newList->find = findElement; + newList->insertAt = insertAt; + newList->findNode = findNode; + newList->freeNode = freeNode; + + return newList; +} diff --git a/Program/src/makefile b/Program/src/makefile index a488915..67b0cd7 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -13,7 +13,7 @@ CFILES += filesystem_funcs.c CFILES += requests.c CFILES += tasks.c CFILES += file_delivery_app.c - +CFILES += list.c #----------------------------test files------------------------- #entrypoint diff --git a/Program/src/mib.c b/Program/src/mib.c index 95dc832..29c4c5d 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -4,6 +4,7 @@ #include "port.h" #include #include "string.h" +#include "list.h" MIB *init_mib() { MIB *mib = ssp_alloc(1, sizeof(MIB)); diff --git a/Program/src/utils.c b/Program/src/utils.c index 1ae1d36..cc12629 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -99,296 +99,6 @@ Config *configuration(int argc, char **argv) -/*------------------------------------------------------------------------------ - This function creates a new node to add into the linked list, returns the - new node, or NULL if failed -------------------------------------------------------------------------------*/ - -NODE *createNode(void *element, uint32_t id) -{ - NODE *newNode = calloc(sizeof(NODE), 1); - if(!checkAlloc(newNode, 0)) - return NULL; - - newNode->element = element; - newNode->id = id; - return newNode; -} - - - - -/*------------------------------------------------------------------------------ - This function creates a new node to add into the linked list, returns the - new node. -------------------------------------------------------------------------------*/ - - -static void freeNode(NODE *node) { - if (node != NULL) - ssp_free(node); -} - -static void *pop(List *list) { - - if (list->count == 0) - return NULL; - - NODE *last_data_node = list->tail->prev; - - NODE *prev = last_data_node->prev; - prev->next = list->tail; - list->tail->prev = prev; - - list->count--; - void *element = last_data_node->element; - freeNode(last_data_node); - return element; -} - - -/*------------------------------------------------------------------------------ - This function creates a new node to add into the beginning of the - linked list, returns the new node. -------------------------------------------------------------------------------*/ - -static int insert(List *list, void *element, uint32_t id) { - - NODE *head = list->head; - NODE *node = createNode(element, id); - if (node == NULL) { - return 0; - } - - node->next = head->next; - node->next->prev = node; - node->prev = head; - - head->next = node; - list->count++; - return 1; -} - -/*------------------------------------------------------------------------------ - This function adds a new element into the linked list. returns 1 if success - 0 if failed. -------------------------------------------------------------------------------*/ - -static int push(List *list, void *element, uint32_t id) -{ - - NODE *newNode = createNode(element, id); - if (newNode == NULL) { - return 0; - } - NODE *tail = list->tail; - - newNode->next = tail; - newNode->prev = tail->prev; - - tail->prev->next = newNode; - tail->prev = newNode; - - if (list->count == 0) { - list->head->next = newNode; - } - - list->count++; - return 1; -} - -/*------------------------------------------------------------------------------ - This function will print out the list if given a callback that is designed - to print out an element. -------------------------------------------------------------------------------*/ - -static void iterate(List *list, void (*f)(void *element, void *args), void *args) -{ - NODE *cur = list->head->next; - NODE *next; - while (cur->next != NULL) - { - next = cur->next; - f(cur->element, args); - cur = next; - } -} - - -/*------------------------------------------------------------------------------ - This function removes an element from the linked list, returns the node stored if success - and NULL if item not found. it can use either an id, or callback to find the - element (callback can be the find function) -------------------------------------------------------------------------------*/ - -static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) -{ - NODE *cur = list->head->next; - int found_with_func = 0; - int found_with_id = 0; - while (cur->next != NULL) - { - if (f != NULL) - found_with_func = f(cur->element, args); - - if (id == cur->id) - found_with_id = 1; - - if (found_with_func || found_with_id) - { - NODE *previous = cur->prev; - NODE *next = cur->next; - - previous->next = next; - next->prev = previous; - - list->count--; - void *element = cur->element; - freeNode(cur); - return element; - } - cur = cur->next; - } - return NULL; -} - - - -/*------------------------------------------------------------------------------ - frees the linked list. Takes a free function that is a function pointer to - a function that frees and elemnent. Returns nothing, -------------------------------------------------------------------------------*/ - -static void freeList(List *list, void (*f)(void *element)) -{ - NODE *cur = list->head->next; - - while (cur->next != NULL) - { - NODE *n = cur; - cur = cur->next; - f(n->element); - freeNode(n); - } - free(list->head); - free(list->tail); - free(list); -} - -/*------------------------------------------------------------------------------ - This function finds an element, returns and element on success and NULL on - failure. The return value should be cast to the element type. can search with - either a callback, or id -------------------------------------------------------------------------------*/ - -static void *findElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) -{ - - NODE *cur = list->head->next; - int found_with_func = 0; - int found_with_id = 0; - while (cur->next != NULL) - { - if (f != NULL) - found_with_func = f(cur->element, args); - - if(id != 0 && cur->id == id) - found_with_id = 1; - - if (found_with_func || found_with_id){ - return cur->element; - } - cur = cur->next; - } - return NULL; -} - -static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args) { - - NODE *cur = list->head->next; - int found_with_func = 0; - int found_with_id = 0; - while (cur->next != NULL) - { - if (f != NULL) - found_with_func = f(cur->element, args); - - if(id != 0 && cur->id == id) - found_with_id = 1; - - if (found_with_func || found_with_id) { - NODE *new = createNode(element, id); - new->next = cur; - new->prev = cur->prev; - new->prev->next = new; - cur->prev = new; - list->count++; - } - - cur = cur->next; - } - return -1; -} - - -static NODE *findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { - - NODE *cur = list->head->next; - int found_with_func = 0; - int found_with_id = 0; - while (cur->next != NULL) - { - if (f != NULL) - found_with_func = f(cur->element, args); - - if(id != 0 && cur->id == id) - found_with_id = 1; - - if (found_with_func || found_with_id){ - return cur; - } - cur = cur->next; - } - return NULL; -} -//see header file return NULL if fails - -List *linked_list() -{ - List *newList = calloc(sizeof(List), 1); - if(!checkAlloc(newList, 0)) - return NULL; - - newList->head = createNode(NULL, 0); - if (newList->head == NULL) - return NULL; - - newList->tail = createNode(NULL, 0); - if (newList->tail == NULL) - return NULL; - - NODE *tail = newList->tail; - NODE *head = newList->head; - - tail->prev = head; - tail->next = NULL; - head->next = tail; - head->prev = NULL; - - newList->push = push; - newList->remove = removeElement; - newList->iterate = iterate; - newList->free = freeList; - newList->insert = insert; - newList->pop = pop; - newList->find = findElement; - newList->insertAt = insertAt; - newList->findNode = findNode; - newList->freeNode = freeNode; - - return newList; -} - //size is the number of bytes we want to print void ssp_print_hex(char *stuff, int size){ diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 7b537c2..a12e4d0 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -16,12 +16,12 @@ static receive_offset_tests(){ receive_offset(file, 0, 5, 50); - file->missing_offsets->print(file->missing_offsets, nak_print, 0); + file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); receive_offset(file, 0, 100, 1000); - file->missing_offsets->print(file->missing_offsets, nak_print, 0); + file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); receive_offset(file, 0, 50, 100); - file->missing_offsets->print(file->missing_offsets, nak_print, 0); + file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); } diff --git a/Program/test/list_tests.c b/Program/test/list_tests.c new file mode 100644 index 0000000..00d91c3 --- /dev/null +++ b/Program/test/list_tests.c @@ -0,0 +1,15 @@ + + + +#include "list.h" +#include "list_tests.h" + +int list_tests() { + + List *list = linked_list(); + + + + + +} \ No newline at end of file diff --git a/Program/test/list_tests.h b/Program/test/list_tests.h new file mode 100644 index 0000000..69fdaca --- /dev/null +++ b/Program/test/list_tests.h @@ -0,0 +1,10 @@ +#ifndef LIST_TESTS_H +#define LIST_TESTS_H + + +int list_tests(); + + + + +#endif \ No newline at end of file diff --git a/Program/test/main.c b/Program/test/main.c index a232539..6b49b44 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -1,5 +1,4 @@ -#include "utils.h" #include #include #include @@ -16,12 +15,13 @@ #include "filesystem_tests.h" #include "file_delivery_app.h" #include "protocol_handler_tests.h" +#include "list_tests.h" Protocol_state *init_test() { -Protocol_state *p_state = init_ftp(1); -ssp_connectionless_server(p_state); -ssp_cleanup_p_state(p_state); + Protocol_state *p_state = init_ftp(1); + ssp_connectionless_server(p_state); + ssp_cleanup_p_state(p_state); } @@ -37,9 +37,10 @@ int main () { //ssp_cleanup_pdu_header(header); int error = 0; - error = request_tests(); - error = protocol_handler_test(); - error = packet_tests(); + //error = request_tests(); + //error = protocol_handler_test(); + //error = packet_tests(); + error = list_tests(); //error = file_system_tests(); return 0; diff --git a/Program/test/makefile b/Program/test/makefile index 77a75c5..35b582f 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -17,9 +17,12 @@ CFILES += $(PROJDIR)/test/test.c CFILES += $(PROJDIR)/test/request_tests.c CFILES += $(PROJDIR)/test/filesystem_tests.c CFILES += $(PROJDIR)/test/protocol_handler_tests.c + +CFILES += $(PROJDIR)/test/list_tests.c CFILES += $(PROJDIR)/src/requests.c CFILES += $(PROJDIR)/src/tasks.c CFILES += $(PROJDIR)/src/file_delivery_app.c +CFILES += $(PROJDIR)/src/list.c #entrypoint MAIN = main @@ -65,7 +68,6 @@ CFLAGS += $(INCLUDE) $(CWARNS) OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) all: $(MAIN) - mv *.o ./obj .PHONY: clean diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 638666e..bf71129 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -178,7 +178,7 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { printf("testing eof ack creation\n"); Request *req; - uint8_t len = build_ack (packet, start, EOF_PDU, req); + uint8_t len = build_ack (packet, start, EOF_PDU); Pdu_directive *pdu_d = &packet[start]; ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index d7c7a6f..bf3020b 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -98,7 +98,7 @@ void request_test_list_storage() { list->insert(list, req3, 3); ssp_cleanup_req(list->pop(list)); - list->print(list, list_print, NULL); + list->iterate(list, list_print, NULL); list->free(list, ssp_cleanup_req); } From 4779470aacc71f6d2d701731d2349719d9a4b553 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 16 Aug 2019 12:15:33 -0600 Subject: [PATCH 068/400] Starting list tests --- Program/test/list_tests.c | 43 +++++++++++++++++++++++++++++++++++++-- Program/test/test.c | 2 -- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/Program/test/list_tests.c b/Program/test/list_tests.c index 00d91c3..36a6b14 100644 --- a/Program/test/list_tests.c +++ b/Program/test/list_tests.c @@ -4,12 +4,51 @@ #include "list.h" #include "list_tests.h" +#include "protocol_handler.h" +#include "requests.h" + +#include "stdio.h" +#include "test.h" +#include "stdlib.h" +#include "string.h" + +void print_list(void *element, void *args) { + Request *r = (Request *) element; + printf("source file name: %s\n", r->source_file_name); +} + +void free_all(void *element){ + ssp_cleanup_req((Request *)element); +} int list_tests() { List *list = linked_list(); - + Request *r = init_request(10000); + Request *r2 = init_request(10000); + memcpy(r->source_file_name, "mybestfriend", 12); + memcpy(r2->source_file_name, "secondrequest", 12); - + list->push(list, r, 1); + ASSERT_EQUALS_INT("should equal 1", 1, list->count); + + Request *r3 = (Request *) list->pop(list); + ASSERT_EQUALS_STR("should equal mybestfriend", "mybestfriend", r3->source_file_name, 12); + ASSERT_EQUALS_INT("should equal 0", 0, list->count); + + list->push(list, r2, 1); + list->push(list, r, 2); + ASSERT_EQUALS_INT("should equal 2", 2, list->count); + + //test removals + Request *r4 = list->remove(list, 1, NULL, NULL); + ASSERT_EQUALS_INT("should equal 1", 1, list->count); + ASSERT_EQUALS_STR("should equal secondrequest", "secondrequest", r4->source_file_name, 12); + + list->push(list, r4, 0); + list->iterate(list, print_list, NULL); + list->free(list, free_all); + + return 0; } \ No newline at end of file diff --git a/Program/test/test.c b/Program/test/test.c index 0598157..c5dd822 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -1,7 +1,5 @@ #include "test.h" - -#include "utils.h" #include int test_num = 0; From 982c1678c86083fd2324bfd4937ffbc2caa863f3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 16 Aug 2019 13:07:59 -0600 Subject: [PATCH 069/400] add clean_up type, this is because some packets trail in, --- Program/include/requests.h | 3 +- Program/include/types.h | 226 +++++++++++++++++++++++++++++++++ Program/src/mib.c | 30 +---- Program/src/protocol_handler.c | 12 +- Program/src/requests.c | 1 - Program/src/tasks.c | 3 +- 6 files changed, 238 insertions(+), 37 deletions(-) create mode 100644 Program/include/types.h diff --git a/Program/include/requests.h b/Program/include/requests.h index d6093cf..247ce80 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -25,7 +25,8 @@ typedef enum Indication { put, eof, //sending data - sending_data + sending_data, + clean_up } Indication; diff --git a/Program/include/types.h b/Program/include/types.h new file mode 100644 index 0000000..e3cf81e --- /dev/null +++ b/Program/include/types.h @@ -0,0 +1,226 @@ +#ifndef SSP_TYPES_H +#define SSP_TYPES_H + +#include "stdint.h" +#include "packet.h" +#include "list.h" + +#include + + +typedef struct offset { + uint32_t start; + uint32_t end; +} Offset; + + +typedef struct file { + int fd; + uint8_t is_temp; + uint32_t next_offset_to_send; + uint32_t total_size; + uint32_t partial_checksum; + uint32_t eof_checksum; + List *missing_offsets; + +} File; + + +typedef struct local_entity { + unsigned int EOF_sent_indication : 1; + + unsigned int EOF_recv_indication : 1; + + //required + unsigned int file_segment_recv_indication : 1; + + //required when acting as receiving entity + unsigned int transaction_finished_indication : 1; + + //required when acting as receiving entity + unsigned int suspended_indication : 1; + + //required when acting as receiving entity + unsigned int resumed_indication : 1; + + //function pointer to default handler? + void *default_fault_handler; + + //TODO routing information, extended procedures only, list maybe? + +} Local_entity; + + +typedef struct remote_entity { + + //TODO probably add new UT layer specific stuff + uint32_t UT_address; + uint16_t UT_port; + uint32_t cfdp_id; + + unsigned int one_way_light_time; + unsigned int total_round_trip_allowance; + unsigned int async_NAK_interval; + unsigned int async_keep_alive_interval; + unsigned int async_report_interval; + unsigned int immediate_nak_mode_enabled : 1; + unsigned int prompt_transmission_interval; + //acknowledged or unacknowledged + unsigned int default_transmission_mode: 1; + + //discard or retain (no idea what this is for yet) + unsigned int disposition_of_incomplete : 1; + + unsigned int CRC_required : 1; + //in octets + unsigned int max_file_segment_len; + //in octets + unsigned int keep_alive_discrepancy_limit; + + //Number of expirations + unsigned int positive_ack_timer_expiration_limit; + + //Number of expirations + unsigned int nak_timer_expiration_limit; + + //time limit + unsigned int transaction_inactivity_limit; + + /* + Start of transmission opportunity A signal produced by the operating environment. + End of transmission opportunity A signal produced by the operating environment. + Start of reception opportunity A signal produced by the operating environment. + End of reception opportunity A signal produced by the operating environment. + */ + + +} Remote_entity; + +typedef struct mib { + Local_entity server; + List *remote_entities; + +} MIB; + +typedef struct protocol_state { + uint32_t packet_size; + char *server_port; + void *server_handle; + MIB *mib; + uint32_t my_cfdp_id; + + List* request_list; + + Request *current_request; + + //lock this + uint32_t transaction_sequence_number; + + uint8_t verbose_level; + + //bool for exiting the server thread + uint8_t close; + +} Protocol_state; + + +//outgoing requests spin up client threads +typedef struct client { + + void *client_handle; + uint32_t packet_len; + + Request *current_request; + List *request_list; + + //can get rid of these, these are found in mib_info anyway + uint32_t cfdp_id; + uint32_t unitdata_id; + uint32_t unitdata_port; + + Remote_entity *mib_info; + Pdu_header *pdu_header; + + Protocol_state *p_state; + + //bool for exiting the client thread + uint8_t close; + + +} Client; + +typedef struct response { + int sfd; + //this is a pointer to buff in a request + char *msg; + //this is type (struct sockaddr_in) in posix + void *addr; + //getting rid of this soon in favour of client based packet sizes + + size_t size_of_addr; + uint32_t packet_len; + +} Response; + +typedef enum Indication { + finished, + none, + transaction, + put, + eof, + //sending data + sending_data, + clean_up + +} Indication; + +//incoming requests spin up requests +typedef struct request { + Indication type; + uint64_t transaction_sequence_number; + uint32_t dest_cfdp_id; + + File *file; + uint32_t file_size; + + char *source_file_name; + char *destination_file_name; + + uint32_t packet_data_len; + + //timeout + uint8_t timeout; + + uint8_t segmentation_control; + uint8_t fault_handler_overides; + uint8_t flow_lable; + uint8_t transmission_mode; + + uint8_t received_metadata; + uint8_t received_eof; + //counter for resending eof packets == 3 + uint8_t resent_eof; + uint8_t received_finished; + //counter for resending finished packets == 3 + uint8_t resent_finished; + //bool for sending first blast of data packets + uint8_t sent_first_data_round; + + char* messages_to_user; + char* filestore_requests; + + //sets the buffer length, for making packets + uint32_t buff_len; + + //buffer for making packets + char* buff; + + //header for building response packets + Pdu_header *pdu_header; + + //handler for sending responses back + Response res; +} Request; + +#endif + diff --git a/Program/src/mib.c b/Program/src/mib.c index 29c4c5d..ed20eac 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -24,7 +24,7 @@ void free_mib(MIB *mib){ ssp_free(mib); } -//these configure peers for their specific transmission configuration +//these configure peers for their specific transmission configuration, should be read in on a config file int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port){ Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); @@ -81,31 +81,3 @@ void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header); } -/* - //building the pdu header here - client->pdu_header = ssp_alloc(1, sizeof(Pdu_header)); - checkAlloc(client->pdu_header, 1); - - - //these will need to be set with a config file, or dynamically based on the - //packet being sent - - Pdu_header* header = client->pdu_header; - header->reserved_bit_0 = 0; - header->reserved_bit_1 = 0; - header->reserved_bit_2 = 0; - header->CRC_flag = client->mib_info->CRC_required; - header->direction = 1; - header->PDU_type = 0; - header->transaction_seq_num_len = 3; - header->length_of_entity_IDs = 1; - header->transmission_mode = remote->default_transmission_mode; - - header->destination_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); - checkAlloc(header->destination_id, 1); - memcpy(header->destination_id, &remote->cfdp_id, header->length_of_entity_IDs); - - header->source_id = ssp_alloc(header->length_of_entity_IDs, sizeof(u_int8_t)); - checkAlloc(header->source_id, 1); - memcpy(header->source_id, &p_state->my_cfdp_id, header->length_of_entity_IDs); - */ \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 24ae20f..7ebc7a2 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -429,6 +429,7 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l Request *request = *req; + //if packet is from the same request, don't' change current request if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ (*req)->packet_data_len = len; @@ -698,8 +699,8 @@ static void reset_timeout(Request *req) { //ssp_printf("timeout %u for id: %u sequence: %u\n", time, req->dest_cfdp_id, req->transaction_sequence_number); if (time == 20) { req->timeout = 0; - reset_request(req); - ssp_printf("timeout, resetting request\n"); + req->type = clean_up; + ssp_printf("timeout, cleaning up request\n"); } } @@ -715,14 +716,17 @@ void on_server_time_out(Response res, Request *req) { reset_timeout(req); + if (req->type == none) + return; + if (req->transmission_mode == 1) return; uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); if (req->resent_finished == 3) { - reset_request(req); - ssp_printf("file sent, resetting request\n"); + req->type = none; + ssp_printf("file sent, closing request\n"); return; } diff --git a/Program/src/requests.c b/Program/src/requests.c index 3d0cf1d..33d4a50 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -34,7 +34,6 @@ void ssp_cleanup_req(void *request) { ssp_free(req->res.addr); if (req != NULL) ssp_free(req); - request = NULL; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index bb0a7a9..f26e6d2 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -42,7 +42,6 @@ static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { - Client *client = (Client *) other; Response res; @@ -79,7 +78,7 @@ static void remove_request_check(void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; - if (req->type == none) { + if (req->type == clean_up) { Request *remove_this = req_list->remove(req_list, 0, remove_request, req); ssp_cleanup_req(remove_this); } From d967f8709ed42cf7417bc2b2a536585b0c627934 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 16 Aug 2019 13:27:01 -0600 Subject: [PATCH 070/400] Decouple types --- Program/.gitignore | 3 +- Program/include/filesystem_funcs.h | 4 +- Program/include/mib.h | 24 ++++---- Program/include/packet.h | 4 +- Program/include/protocol_handler.h | 10 +-- Program/include/requests.h | 4 +- Program/include/types.h | 98 ++++++++++++++++-------------- Program/src/list.c | 7 ++- Program/src/main.c | 2 + Program/src/port.c | 3 +- Program/src/protocol_handler.c | 5 +- Program/src/requests.c | 3 + Program/src/tasks.c | 2 +- 13 files changed, 92 insertions(+), 77 deletions(-) diff --git a/Program/.gitignore b/Program/.gitignore index 151a620..6017289 100644 --- a/Program/.gitignore +++ b/Program/.gitignore @@ -1,2 +1,3 @@ *.o -*.a \ No newline at end of file +*.a +TODO diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index db5ebfa..d4ebb38 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -3,9 +3,11 @@ #define FILESYSTEM_FUNCS_H #include #include "list.h" +#include "types.h" #define TEMP_FILESIZE 1000 +/* typedef struct offset { uint32_t start; uint32_t end; @@ -22,7 +24,7 @@ typedef struct file { List *missing_offsets; } File; - +*/ uint32_t get_file_size(char *source_file_name); //allocates space for a file pointer diff --git a/Program/include/mib.h b/Program/include/mib.h index 12e40f5..ae618b9 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -1,15 +1,15 @@ //the management information base (MIB) //default faul handle -#include -#include -#include "packet.h" #ifndef MIB_H #define MIB_H - - +#include +#include +#include "packet.h" +#include "types.h" +/* typedef struct local_entity { unsigned int EOF_sent_indication : 1; @@ -70,12 +70,12 @@ typedef struct remote_entity { //time limit unsigned int transaction_inactivity_limit; - /* - Start of transmission opportunity A signal produced by the operating environment. - End of transmission opportunity A signal produced by the operating environment. - Start of reception opportunity A signal produced by the operating environment. - End of reception opportunity A signal produced by the operating environment. - */ + + //Start of transmission opportunity A signal produced by the operating environment. + //End of transmission opportunity A signal produced by the operating environment. + //Start of reception opportunity A signal produced by the operating environment. + //End of reception opportunity A signal produced by the operating environment. + } Remote_entity; @@ -85,7 +85,7 @@ typedef struct mib { List *remote_entities; } MIB; - +*/ MIB *init_mib(void); void free_mib(MIB *mib); diff --git a/Program/include/packet.h b/Program/include/packet.h index 12a2c51..c0ef7a9 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -3,9 +3,7 @@ #ifndef PACKET_H #define PACKET_H #include -#include "filesystem_funcs.h" #define PACKET_HEADER_LEN 224 - // PACKET_HEADER_LEN + data max size = (65536 * 8) #define PACKET_MAX_LEN 524512 #define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes @@ -301,7 +299,7 @@ typedef struct pdu_nak { //number of Nak_segments uint64_t segment_requests; - Offset *segments; + void *segments; } Pdu_nak; diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index cf8f546..5cb2efe 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -1,13 +1,9 @@ #ifndef PROTOCOL_H #define PROTOCOL_H +#include "types.h" -#include "list.h" -#include "packet.h" -#include "mib.h" -#include "filesystem_funcs.h" -#include "requests.h" - +/* typedef struct protocol_state { uint32_t packet_size; char *server_port; @@ -54,7 +50,7 @@ typedef struct client { } Client; - +*/ //for use void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); diff --git a/Program/include/requests.h b/Program/include/requests.h index 247ce80..e2465bc 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -4,7 +4,8 @@ #include "stdint.h" #include "protocol_handler.h" - +#include "types.h" +/* typedef struct response { int sfd; //this is a pointer to buff in a request @@ -77,6 +78,7 @@ typedef struct request { //handler for sending responses back Response res; } Request; +*/ void ssp_cleanup_req(void *request); Request *init_request(uint32_t buff_len); diff --git a/Program/include/types.h b/Program/include/types.h index e3cf81e..eefe7d9 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -102,52 +102,6 @@ typedef struct mib { } MIB; -typedef struct protocol_state { - uint32_t packet_size; - char *server_port; - void *server_handle; - MIB *mib; - uint32_t my_cfdp_id; - - List* request_list; - - Request *current_request; - - //lock this - uint32_t transaction_sequence_number; - - uint8_t verbose_level; - - //bool for exiting the server thread - uint8_t close; - -} Protocol_state; - - -//outgoing requests spin up client threads -typedef struct client { - - void *client_handle; - uint32_t packet_len; - - Request *current_request; - List *request_list; - - //can get rid of these, these are found in mib_info anyway - uint32_t cfdp_id; - uint32_t unitdata_id; - uint32_t unitdata_port; - - Remote_entity *mib_info; - Pdu_header *pdu_header; - - Protocol_state *p_state; - - //bool for exiting the client thread - uint8_t close; - - -} Client; typedef struct response { int sfd; @@ -162,6 +116,7 @@ typedef struct response { } Response; + typedef enum Indication { finished, none, @@ -222,5 +177,56 @@ typedef struct request { Response res; } Request; +typedef struct protocol_state { + uint32_t packet_size; + char *server_port; + void *server_handle; + MIB *mib; + uint32_t my_cfdp_id; + + List* request_list; + + Request *current_request; + + //lock this + uint32_t transaction_sequence_number; + + uint8_t verbose_level; + + //bool for exiting the server thread + uint8_t close; + +} Protocol_state; + + +//outgoing requests spin up client threads +typedef struct client { + + void *client_handle; + uint32_t packet_len; + + Request *current_request; + List *request_list; + + //can get rid of these, these are found in mib_info anyway + uint32_t cfdp_id; + uint32_t unitdata_id; + uint32_t unitdata_port; + + Remote_entity *mib_info; + Pdu_header *pdu_header; + + Protocol_state *p_state; + + //bool for exiting the client thread + uint8_t close; + + +} Client; + + + + + #endif diff --git a/Program/src/list.c b/Program/src/list.c index 40af636..b571282 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -1,6 +1,7 @@ #include "list.h" + #include #include #include @@ -13,9 +14,9 @@ NODE *createNode(void *element, uint32_t id) { NODE *newNode = calloc(sizeof(NODE), 1); - if(!checkAlloc(newNode, 0)) + if (newNode == NULL) { return NULL; - + } newNode->element = element; newNode->id = id; return newNode; @@ -262,7 +263,7 @@ static NODE *findNode(List *list, uint32_t id, int (*f)(void *element, void *arg List *linked_list() { List *newList = calloc(sizeof(List), 1); - if(!checkAlloc(newList, 0)) + if (newList == NULL) return NULL; newList->head = createNode(NULL, 0); diff --git a/Program/src/main.c b/Program/src/main.c index f883dab..dcf1c07 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -13,6 +13,8 @@ #include "utils.h" //for put request #include "requests.h" + +#include "types.h" //for main app #include "file_delivery_app.h" //for signal handler, because its nice diff --git a/Program/src/port.c b/Program/src/port.c index 3d74608..1e974b9 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -7,6 +7,7 @@ #include "utils.h" #include "mib.h" #include "filesystem_funcs.h" +#include #ifdef POSIX_PORT #include @@ -19,7 +20,7 @@ #include #endif -#include "protocol_handler.h" +#include "types.h" diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 7ebc7a2..8686914 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -6,7 +6,7 @@ #include "packet.h" #include "filesystem_funcs.h" #include "requests.h" - +#include "types.h" //snprintf #include @@ -704,11 +704,14 @@ static void reset_timeout(Request *req) { } } +/* static void print_offsets(void *element, void *args) { Offset *off = (Offset *) element; ssp_printf("missing offset start: %d end:%d\n", off->start, off->end); } +*/ + void on_server_time_out(Response res, Request *req) { if (req == NULL) diff --git a/Program/src/requests.c b/Program/src/requests.c index 33d4a50..51ead45 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -12,6 +12,9 @@ #include "utils.h" #include #include "tasks.h" +#include "types.h" +#include "filesystem_funcs.h" +#include "mib.h" void ssp_cleanup_req(void *request) { diff --git a/Program/src/tasks.c b/Program/src/tasks.c index f26e6d2..0ac7574 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -9,7 +9,7 @@ #include "mib.h" #include "filesystem_funcs.h" #include - +#include "types.h" /*------------------------------------------------------------------------------ Callbacks for the tasks bellow From c0f980572ea2d8c1665a0b0de64107eafd932852 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 17 Aug 2019 09:30:10 -0600 Subject: [PATCH 071/400] remote reset request function --- Program/include/requests.h | 1 - Program/src/requests.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index e2465bc..e009edf 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -82,5 +82,4 @@ typedef struct request { void ssp_cleanup_req(void *request); Request *init_request(uint32_t buff_len); -void reset_request(Request *req); #endif \ No newline at end of file diff --git a/Program/src/requests.c b/Program/src/requests.c index 51ead45..f877a51 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -41,11 +41,6 @@ void ssp_cleanup_req(void *request) { } -void reset_request(Request *req){ - req->type = none; -} - - Request *init_request(uint32_t buff_len) { Request *req = ssp_alloc(1, sizeof(Request)); From 672f5b24e4fce9285b779591429fbff53cec27cd Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 17 Aug 2019 11:48:16 -0600 Subject: [PATCH 072/400] removed redundant data from client struct --- Program/include/mib.h | 2 +- Program/include/types.h | 7 +------ Program/src/file_delivery_app.c | 9 +++------ Program/src/mib.c | 8 ++++++++ Program/src/requests.c | 2 +- Program/src/tasks.c | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index ae618b9..b16efb6 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -92,5 +92,5 @@ void free_mib(MIB *mib); int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port); Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); - +Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index eefe7d9..6c28782 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -208,12 +208,7 @@ typedef struct client { Request *current_request; List *request_list; - //can get rid of these, these are found in mib_info anyway - uint32_t cfdp_id; - uint32_t unitdata_id; - uint32_t unitdata_port; - - Remote_entity *mib_info; + Remote_entity *remote_entity; Pdu_header *pdu_header; Protocol_state *p_state; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 6dcdc30..52f8721 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -67,20 +67,17 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { client->current_request = NULL; client->request_list = linked_list(); client->packet_len = PACKET_LEN; - client->cfdp_id = cfdp_id; List *entity_list = p_state->mib->remote_entities; - Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); + //Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); + Remote_entity *remote = get_remote_entity(p_state->mib, cfdp_id); if (remote == NULL) ssp_printf("couldn't find entity in Remote_entity list\n"); //TODO clean this up, we don't need multiple instances of UT_ports etc - client->unitdata_port = remote->UT_port; - client->unitdata_id = remote->UT_address; - client->mib_info = remote; - + client->remote_entity = remote; client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); client->p_state = p_state; diff --git a/Program/src/mib.c b/Program/src/mib.c index ed20eac..95b19e0 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -75,6 +75,14 @@ Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ return pdu_header; } +Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id){ + + Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, dest_id, NULL, NULL); + return remote; + +}; + + void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header->destination_id); ssp_free(pdu_header->source_id); diff --git a/Program/src/requests.c b/Program/src/requests.c index f877a51..4000b24 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -87,7 +87,7 @@ Request *put_request(char *source_file_name, //enumeration req->type = put; - req->dest_cfdp_id = client->cfdp_id; + req->dest_cfdp_id = client->remote_entity->cfdp_id; req->file_size = file_size; memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 0ac7574..5a849da 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -237,10 +237,10 @@ void *ssp_connectionless_client_task(void* params){ char host_name[INET_ADDRSTRLEN]; char port[10]; //convert int to char * - snprintf(port, 10, "%d", client->unitdata_port); + snprintf(port, 10, "%d", client->remote_entity->UT_port); //convert uint id to char * - inet_ntop(AF_INET, &client->unitdata_id, host_name, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); #ifdef POSIX_PORT udpClient(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); From a073cedf5bf658d2bdee468aabe1194697b64494 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 17 Aug 2019 11:52:29 -0600 Subject: [PATCH 073/400] remove local_entity from MIB --- Program/include/types.h | 4 +++- Program/src/file_delivery_app.c | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index 6c28782..b540a58 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -97,7 +97,6 @@ typedef struct remote_entity { } Remote_entity; typedef struct mib { - Local_entity server; List *remote_entities; } MIB; @@ -161,6 +160,9 @@ typedef struct request { //bool for sending first blast of data packets uint8_t sent_first_data_round; + Remote_entity *remote_entity; + Local_entity *local_entity; + char* messages_to_user; char* filestore_requests; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 52f8721..9b613f0 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -68,9 +68,6 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { client->request_list = linked_list(); client->packet_len = PACKET_LEN; - - List *entity_list = p_state->mib->remote_entities; - //Remote_entity *remote = entity_list->find(entity_list, cfdp_id, NULL, NULL); Remote_entity *remote = get_remote_entity(p_state->mib, cfdp_id); if (remote == NULL) From 1cd0624cb17a88db8feecae0a05e1103f262d464 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 19 Aug 2019 14:31:37 -0600 Subject: [PATCH 074/400] moved some variables to local_entity --- Program/include/types.h | 11 +++++++---- Program/src/protocol_handler.c | 32 ++++++++++++++++---------------- Program/src/requests.c | 3 +++ 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index b540a58..c3f66df 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -43,6 +43,7 @@ typedef struct local_entity { //required when acting as receiving entity unsigned int resumed_indication : 1; + unsigned int Metadata_recv_indication: 1; //function pointer to default handler? void *default_fault_handler; @@ -65,6 +66,7 @@ typedef struct remote_entity { unsigned int async_report_interval; unsigned int immediate_nak_mode_enabled : 1; unsigned int prompt_transmission_interval; + //acknowledged or unacknowledged unsigned int default_transmission_mode: 1; @@ -86,6 +88,9 @@ typedef struct remote_entity { //time limit unsigned int transaction_inactivity_limit; + + + /* Start of transmission opportunity A signal produced by the operating environment. End of transmission opportunity A signal produced by the operating environment. @@ -150,15 +155,13 @@ typedef struct request { uint8_t flow_lable; uint8_t transmission_mode; - uint8_t received_metadata; - uint8_t received_eof; //counter for resending eof packets == 3 uint8_t resent_eof; - uint8_t received_finished; //counter for resending finished packets == 3 uint8_t resent_finished; + //bool for sending first blast of data packets - uint8_t sent_first_data_round; + // uint8_t sent_first_data_round; Remote_entity *remote_entity; Local_entity *local_entity; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 8686914..1fa7f90 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -342,7 +342,7 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { Pdu_eof *eof_packet = (Pdu_eof *) packet; - if (!req->received_metadata) { + if (!req->local_entity->Metadata_recv_indication) { request_metadata(req, res); } if (req->file == NULL) { @@ -351,7 +351,7 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { } - req->received_eof = 1; + req->local_entity->EOF_recv_indication = 1; req->file->eof_checksum = eof_packet->checksum; req->file->total_size = ntohl(eof_packet->file_size); @@ -361,7 +361,7 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { int process_file_request_metadata(Request *req) { char temp[75]; - req->received_metadata = 1; + req->local_entity->Metadata_recv_indication = 1; if (req->file == NULL) req->file = create_file(req->destination_file_name, 1); @@ -586,19 +586,19 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch(directive) { case FINISHED_PDU: - req->received_finished = 1; + req->local_entity->transaction_finished_indication = 1; req->type = finished; ssp_printf("received finished pdu\n"); break; case NAK_PDU: - req->received_metadata = 1; + req->local_entity->Metadata_recv_indication = 1; nak_response(packet, packet_index, req, res, client); ssp_printf("received Nak pdu\n"); break; case ACK_PDU: if (packet[packet_index] == EOF_PDU) { ssp_printf("received Eof ack\n"); - req->received_eof = 1; + req->local_entity->EOF_recv_indication = 1; } break; case NAK_DIRECTIVE: @@ -657,12 +657,12 @@ void user_request_handler(Response res, Request *req, Client* client) { break; case sending_data: - if (req->sent_first_data_round == 1) + if (req->local_entity->EOF_sent_indication == 1) return; if (build_data_packet(req->buff, start, req->file, client->packet_len)) { req->type = eof; - req->sent_first_data_round = 1; + req->local_entity->EOF_sent_indication = 1; ssp_printf("sending data blast\n"); } ssp_sendto(res); @@ -734,7 +734,7 @@ void on_server_time_out(Response res, Request *req) { } //send request for metadata - if (!req->received_metadata) { + if (!req->local_entity->Metadata_recv_indication) { ssp_printf("sending request for new metadata packet\n"); build_nak_directive(res.msg, start, META_DATA_PDU); ssp_sendto(res); @@ -742,7 +742,7 @@ void on_server_time_out(Response res, Request *req) { } //send missing eofs - if (!req->received_eof) { + if (!req->local_entity->EOF_recv_indication) { build_nak_directive(res.msg, start, EOF_PDU); ssp_sendto(res); } @@ -768,7 +768,7 @@ void on_server_time_out(Response res, Request *req) { } } //received EOF, send back 3 eof packets - if (req->received_eof && req->resent_eof < 3) { + if (req->local_entity->EOF_recv_indication && req->resent_eof < 3) { ssp_printf("sending eof ack\n"); build_ack(res.msg, start, EOF_PDU); ssp_sendto(res); @@ -788,7 +788,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ //process file data if (header->PDU_type == 1) { - if (!req->received_metadata) { + if (!req->local_entity->Metadata_recv_indication) { if (req->file == NULL) { snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); ssp_printf("haven't received metadata yet, building temperary file %s\n", req->source_file_name); @@ -806,7 +806,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ switch (directive->directive_code) { case META_DATA_PDU: - if (req->received_metadata) + if (req->local_entity->Metadata_recv_indication) break; req->type = put; @@ -816,10 +816,10 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ break; case EOF_PDU: - if (req->received_eof) + if (req->local_entity->EOF_recv_indication) break;; - if (!req->received_metadata) + if (!req->local_entity->Metadata_recv_indication) request_metadata(req, res); ssp_printf("received eof packet\n"); @@ -832,7 +832,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_ack* ack_packet = (Pdu_ack *) &packet[packet_index]; if (ack_packet->directive_code == FINISHED_PDU) { ssp_printf("received finished packet\n"); - req->received_finished = 1; + req->local_entity->transaction_finished_indication = 1; } break; default: diff --git a/Program/src/requests.c b/Program/src/requests.c index 4000b24..5923582 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -35,6 +35,8 @@ void ssp_cleanup_req(void *request) { ssp_free(req->buff); if (req->res.addr != NULL) ssp_free(req->res.addr); + if (req->local_entity != NULL) + ssp_free(req->local_entity); if (req != NULL) ssp_free(req); @@ -51,6 +53,7 @@ Request *init_request(uint32_t buff_len) { req->destination_file_name = ssp_alloc(MAX_PATH, sizeof(char)); checkAlloc(req->destination_file_name, 1); + req->local_entity = ssp_alloc(1, sizeof(Local_entity)); req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); From 7cb7350f45fd7dc70d15941856d50ec5cd532c0b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 19 Aug 2019 14:54:23 -0600 Subject: [PATCH 075/400] Moved packet building functions to its own file --- Program/include/packet.h | 360 ++------------------------------ Program/include/types.h | 363 ++++++++++++++++++++++++++++++++- Program/src/makefile | 1 + Program/src/packet.c | 310 ++++++++++++++++++++++++++++ Program/src/protocol_handler.c | 303 --------------------------- 5 files changed, 688 insertions(+), 649 deletions(-) create mode 100644 Program/src/packet.c diff --git a/Program/include/packet.h b/Program/include/packet.h index c0ef7a9..af7bf12 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -9,350 +9,20 @@ #define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes #define PACKET_STATIC_HEADER_LEN 4 //in bytes - -typedef struct pdu_header{ - unsigned int version: 3; - - //0 File directive, 1 File Data, - unsigned int PDU_type: 1; - - //0 toward file receiver, 1 toward file sender - unsigned int direction: 1; - - //0 acknowledged, 1 unacknowledged - unsigned int transmission_mode: 1; - - //0 crc not present, 1 crc present - unsigned int CRC_flag: 1; - - //set to 0 - unsigned int reserved_bit_0: 1; - - //data field length in octets - unsigned int PDU_data_field_len: 16; - - //set to 0 - unsigned int reserved_bit_1: 1; - - //length of entity ids in octets - unsigned int length_of_entity_IDs: 3; - - //set to 0 - unsigned int reserved_bit_2: 1; - - //number of octets in sequence number, 0 is one octet - unsigned int transaction_seq_num_len: 3; - - //variable in size, and will get memory allocated based on the length variables above - void *source_id; - - //variable in size, and will get memory allocated based on the length variables above - void *transaction_sequence_number; - - //variable in size, and will get memory allocated based on the length variables above - void *destination_id; -} Pdu_header; - -typedef struct originating_tranaction_id_message { - - unsigned int reserved_bit_0 : 1; - unsigned int length_of_entity_id : 3; - unsigned int reserved_bit_1 : 1; - unsigned int length_of_sequence_number: 3; - - //variable length of bits - void *source_id; - void *transaction_sequence_number; - -} Originating_tranaction_id_message; - - -/*------------------------------------------------------------------------------ - The following are the different TLV parameters and types associated - filestore_request: type 0x00 - value: struct filestore_request - filestore_response: type 0x01 - value: struct filestore_response - - //TODO - Messages to user. - Fault Handler overrides. - Flow Label. - -------------------------------------------------------------------------------*/ - - -typedef struct lv { - unsigned int length : 8; - // size is 8 * length - void *value; -} LV; - -typedef struct tlv { - unsigned int type : 8; - unsigned int length : 8; - // size is 8 * length - void *value; -} TLV; - - -//---------------------------filestore_request---------------------------------- -//action codes -#define CREATE_FILE 0x00 -#define DELETE_FILE 0x01 -#define RENAME_FILE 0x02 //second filename present -#define APPEND_FILE 0x03 //second filename present -#define REPLACE_FILE 0x04 //second filename present -#define CREATE_DIRECTORY 0x05 -#define REMOVE_DIRECTORY 0x06 -#define DENY_FILE 0x07 //delete if present -#define DENY_DIRECTORY 0x08 //delete if present - -// The type for this TLV is 0x00 -typedef struct filestore_request { - unsigned int action_code: 4; - unsigned int spare : 4; - LV first_file_name; - LV second_file_name; //only present in #RENAME_FILE, APPEND_FILE, REPLACE_FILE - - -} Filestore_request; - - -//---------------------------filestore_response--------------------------------- -#define SUCCESS 0x00 -#define CREATE_NOT_ALLOWED 0x01 -#define FILE_DOES_NOT_EXIST 0x01 -#define OLD_FILE_NAME_DOES_NOT_EXIST 0x01 -#define DELETE_NOT_ALLOWED 0x02 -#define NEW_FILE_NAME_ALREADY_EXISTS 0x02 -#define RENAME_NOT_ALLOWED 0x04 -#define FILE_NAME_1_DOES_NOT_EXIST 0x01 -#define FILE_NAME_2_DOES_NOT_EXIST 0x02 -#define APPEND_NOT_ALLOWED 0x04 -#define REPLACE_NOT_ALLOWED 0x04 -#define DIRECTORY_CANNOT_BE_CREATED 0x01 -#define DIRECTORY_DOES_NOT_EXIST 0x01 -#define NOT_PERFORMED 0x0F - - -// The type for this TLV is 0x01 -typedef struct filestore_response { - unsigned int action_code: 4; - unsigned int status_code : 4; - LV first_file_name; - LV second_file_name; //only present in #RENAME_FILE, APPEND_FILE, REPLACE_FILE - - LV filestore_message; - /*LV length field indicates zero length and LV value field is - omitted when there is no Filestore Message parameter present. */ - -} Filestore_response; - - - -/*------------------------------------------------------------------------------ - The following are the different PDUs, PDUs are what is included in the - data portion of the PDU_header these include: - - File directive PDUs: - File directive PDUs all start with a 1 byte directive code, - followed by one of the following various pdu types: - - //not implemented - -END-OF-FILE PDU - -FINISHED PDU - -ACK PDU - -NAK PDU - -PROMPT PDU - -KEEP ALIVE PDU - - //implemented - -METADATA PDU - - Non directive PDUs (when the PDU type in the header is set to 1): - -FILE DATA PDU - - - - - -------------------------------------------------------------------------------*/ - - -#define DIRECTIVE 0 -#define DATA 1 - -//directive_codes 00 - 03, and 0D-FF are reserved -#define EOF_PDU 0x04 -#define FINISHED_PDU 0x05 -#define ACK_PDU 0x06 -#define META_DATA_PDU 0x07 -#define NAK_PDU 0x08 -#define PROMPT_PDU 0x09 -#define KEEP_ALIVE_PDU 0x0C -#define SIZE_OF_DIRECTIVE_CODE 1 - -//custom, for missing metadata and eof -#define NAK_DIRECTIVE 0x0d - -//condition codes: - -#define COND_NO_ERROR 0x00 -/* -‘0000’ No error -‘0001’ Positive ACK limit reached -‘0010’ Keep alive limit reached -‘0011’ Invalid transmission mode -‘0100’ Filestore rejection -‘0101’ File checksum failure -‘0110’ File size error -‘0111’ NAK limit reached -‘1000’ Inactivity detected -‘1001’ Invalid file structure -‘1010’ Check limit reached -‘1011’ – ‘1101’ -CCSDS 727.0-B-4 -Condition -(reserved) -‘1110’ Suspend.request received -‘1111’ Cancel.request received -*/ - - -typedef struct pdu_directive { - uint8_t directive_code; -} Pdu_directive; - -/* -The segmentation control parameter - - shall indicate whether the file being delivered is to be segmented as an array of octets - or as an array of variable-length records; - - shall be omitted when local and remote file names are omitted. -*/ - -typedef struct pdu_meta_data { - //0 Record boundaries respeced (read as array of octets), 1 not respected (variable length) - unsigned int segmentation_control : 1; - - unsigned int reserved_bits: 7; - - //length of the file in octets, set all 0 for unbounded size - uint32_t file_size; - LV source_file_name; - LV destination_file_name; - - /* - Options include: - Filestore requests, - Messages to user. - Fault Handler overrides. - Flow Label. - */ - - TLV *options; - -} Pdu_meta_data; - - -typedef struct file_data_pdu_contents { - //in octets - uint32_t offset; - //variable sized - unsigned char *data; -} File_data_pdu_contents; - - -typedef struct pdu_eof { - unsigned int condition_code : 4; - unsigned int spare : 4; - uint32_t checksum; - /* In octets. This value shall be the total number of file data octets - transmitted by the sender, regardless of the condition code - (i.e., it shall be supplied even if the condition code is other than - ‘No error’). */ - uint32_t file_size; - - /* - Omitted if condition code is ‘No error’. Otherwise, entity ID in the - TLV is the ID of the entity at which transaction cancellation was - initiated.*/ - TLV fault_location; - -} Pdu_eof; - - -//custom, nak missing other directives, like metadata and eof -typedef struct pdu_nak_directive{ - uint8_t directive; - -} pdu_nak_directive; - - /* - start_scope is the begining of the nak requests - end_scope is the end - segments are - */ -typedef struct pdu_nak { - uint32_t start_scope; - uint32_t end_scope; - - //number of Nak_segments - uint64_t segment_requests; - void *segments; -} Pdu_nak; - - -#define ACK_FINISHED_WAYPOINT 0 -#define ACK_FINISHED_END 1 -#define ACK_OTHER 0 - -typedef struct pdu_ack { - //Directive code of the acknowledged PDU. - unsigned int directive_code : 4; - - /* - Values depend on directive code. For ACK of Finished PDU: binary ‘0000’ - if Finished PDU is generated by waypoint, binary ‘0001’ if Finished - PDU is generated by end system. (NOTE: this discrimination is - meaningful if the Extended Procedures are implemented.) - Binary ‘0000’ for ACKs of all other file directives. - */ - - unsigned int directive_subtype_code : 4; - - //Condition code of the acknowledged PDU. - unsigned int condition_code : 4; - unsigned int spare : 2; - - //Status of the transaction in the context of the entity that is issuing the acknowledgment. - unsigned int transaction_status : 2; - -} Pdu_ack; - - - -//file_status codes -#define FILE_DISCARDED_DELIBERATELY 1 -#define FILE_DISCARDED_DUE_TO_REJECTION 2 -#define FILE_RETAINED_SUCCESSFULLY 3 -#define FILE_STATUS_UNREPORTED 4 - - -typedef struct pdu_finished { - unsigned int condition_code : 4; - - // 0 generated by waypoint 1 generated by end system. - unsigned int end_system_status : 1; - - //0 data complete, 1 data incomplete - unsigned int delivery_code : 1; - - //see above - unsigned int file_status : 2; - TLV file_store_responses; - TLV fault_location; - -}Pdu_finished; +#include "types.h" + +uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); +uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req); +uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req); +uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); +uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); + +void build_eof_packet(char *packet, uint32_t start, Request *req); +void fill_nak_array(void *element, void *args); +uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); +uint8_t build_ack(char*packet, uint32_t start, uint8_t type); +uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) ; +void set_data_length(char*packet, uint16_t data_len); +uint16_t get_data_length(char*packet); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index c3f66df..6887d53 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -2,12 +2,373 @@ #define SSP_TYPES_H #include "stdint.h" -#include "packet.h" #include "list.h" #include +/*----------------------------------------------------------------------------- + + Packet structs for building packets + + +------------------------------------------------------------------------------*/ + +typedef struct pdu_header{ + unsigned int version: 3; + + //0 File directive, 1 File Data, + unsigned int PDU_type: 1; + + //0 toward file receiver, 1 toward file sender + unsigned int direction: 1; + + //0 acknowledged, 1 unacknowledged + unsigned int transmission_mode: 1; + + //0 crc not present, 1 crc present + unsigned int CRC_flag: 1; + + //set to 0 + unsigned int reserved_bit_0: 1; + + //data field length in octets + unsigned int PDU_data_field_len: 16; + + //set to 0 + unsigned int reserved_bit_1: 1; + + //length of entity ids in octets + unsigned int length_of_entity_IDs: 3; + + //set to 0 + unsigned int reserved_bit_2: 1; + + //number of octets in sequence number, 0 is one octet + unsigned int transaction_seq_num_len: 3; + + //variable in size, and will get memory allocated based on the length variables above + void *source_id; + + //variable in size, and will get memory allocated based on the length variables above + void *transaction_sequence_number; + + //variable in size, and will get memory allocated based on the length variables above + void *destination_id; +} Pdu_header; + +typedef struct originating_tranaction_id_message { + + unsigned int reserved_bit_0 : 1; + unsigned int length_of_entity_id : 3; + unsigned int reserved_bit_1 : 1; + unsigned int length_of_sequence_number: 3; + + //variable length of bits + void *source_id; + void *transaction_sequence_number; + +} Originating_tranaction_id_message; + + +/*------------------------------------------------------------------------------ + The following are the different TLV parameters and types associated + filestore_request: type 0x00 + value: struct filestore_request + filestore_response: type 0x01 + value: struct filestore_response + + //TODO + Messages to user. + Fault Handler overrides. + Flow Label. + +------------------------------------------------------------------------------*/ + + +typedef struct lv { + unsigned int length : 8; + // size is 8 * length + void *value; +} LV; + +typedef struct tlv { + unsigned int type : 8; + unsigned int length : 8; + // size is 8 * length + void *value; +} TLV; + + +//---------------------------filestore_request---------------------------------- +//action codes +#define CREATE_FILE 0x00 +#define DELETE_FILE 0x01 +#define RENAME_FILE 0x02 //second filename present +#define APPEND_FILE 0x03 //second filename present +#define REPLACE_FILE 0x04 //second filename present +#define CREATE_DIRECTORY 0x05 +#define REMOVE_DIRECTORY 0x06 +#define DENY_FILE 0x07 //delete if present +#define DENY_DIRECTORY 0x08 //delete if present + +// The type for this TLV is 0x00 +typedef struct filestore_request { + unsigned int action_code: 4; + unsigned int spare : 4; + LV first_file_name; + LV second_file_name; //only present in #RENAME_FILE, APPEND_FILE, REPLACE_FILE + + +} Filestore_request; + + +//---------------------------filestore_response--------------------------------- +#define SUCCESS 0x00 +#define CREATE_NOT_ALLOWED 0x01 +#define FILE_DOES_NOT_EXIST 0x01 +#define OLD_FILE_NAME_DOES_NOT_EXIST 0x01 +#define DELETE_NOT_ALLOWED 0x02 +#define NEW_FILE_NAME_ALREADY_EXISTS 0x02 +#define RENAME_NOT_ALLOWED 0x04 +#define FILE_NAME_1_DOES_NOT_EXIST 0x01 +#define FILE_NAME_2_DOES_NOT_EXIST 0x02 +#define APPEND_NOT_ALLOWED 0x04 +#define REPLACE_NOT_ALLOWED 0x04 +#define DIRECTORY_CANNOT_BE_CREATED 0x01 +#define DIRECTORY_DOES_NOT_EXIST 0x01 +#define NOT_PERFORMED 0x0F + + +// The type for this TLV is 0x01 +typedef struct filestore_response { + unsigned int action_code: 4; + unsigned int status_code : 4; + LV first_file_name; + LV second_file_name; //only present in #RENAME_FILE, APPEND_FILE, REPLACE_FILE + + LV filestore_message; + /*LV length field indicates zero length and LV value field is + omitted when there is no Filestore Message parameter present. */ + +} Filestore_response; + + + +/*------------------------------------------------------------------------------ + The following are the different PDUs, PDUs are what is included in the + data portion of the PDU_header these include: + + File directive PDUs: + File directive PDUs all start with a 1 byte directive code, + followed by one of the following various pdu types: + + //not implemented + -END-OF-FILE PDU + -FINISHED PDU + -ACK PDU + -NAK PDU + -PROMPT PDU + -KEEP ALIVE PDU + + //implemented + -METADATA PDU + + Non directive PDUs (when the PDU type in the header is set to 1): + -FILE DATA PDU + + + + + +------------------------------------------------------------------------------*/ + + +#define DIRECTIVE 0 +#define DATA 1 + +//directive_codes 00 - 03, and 0D-FF are reserved +#define EOF_PDU 0x04 +#define FINISHED_PDU 0x05 +#define ACK_PDU 0x06 +#define META_DATA_PDU 0x07 +#define NAK_PDU 0x08 +#define PROMPT_PDU 0x09 +#define KEEP_ALIVE_PDU 0x0C +#define SIZE_OF_DIRECTIVE_CODE 1 + +//custom, for missing metadata and eof +#define NAK_DIRECTIVE 0x0d + +//condition codes: + +#define COND_NO_ERROR 0x00 +/* +‘0000’ No error +‘0001’ Positive ACK limit reached +‘0010’ Keep alive limit reached +‘0011’ Invalid transmission mode +‘0100’ Filestore rejection +‘0101’ File checksum failure +‘0110’ File size error +‘0111’ NAK limit reached +‘1000’ Inactivity detected +‘1001’ Invalid file structure +‘1010’ Check limit reached +‘1011’ – ‘1101’ +CCSDS 727.0-B-4 +Condition +(reserved) +‘1110’ Suspend.request received +‘1111’ Cancel.request received +*/ + + +typedef struct pdu_directive { + uint8_t directive_code; +} Pdu_directive; + +/* +The segmentation control parameter + - shall indicate whether the file being delivered is to be segmented as an array of octets + or as an array of variable-length records; + - shall be omitted when local and remote file names are omitted. +*/ + +typedef struct pdu_meta_data { + //0 Record boundaries respeced (read as array of octets), 1 not respected (variable length) + unsigned int segmentation_control : 1; + + unsigned int reserved_bits: 7; + + //length of the file in octets, set all 0 for unbounded size + uint32_t file_size; + LV source_file_name; + LV destination_file_name; + + /* + Options include: + Filestore requests, + Messages to user. + Fault Handler overrides. + Flow Label. + */ + + TLV *options; + +} Pdu_meta_data; + + +typedef struct file_data_pdu_contents { + //in octets + uint32_t offset; + //variable sized + unsigned char *data; +} File_data_pdu_contents; + + +typedef struct pdu_eof { + unsigned int condition_code : 4; + unsigned int spare : 4; + uint32_t checksum; + /* In octets. This value shall be the total number of file data octets + transmitted by the sender, regardless of the condition code + (i.e., it shall be supplied even if the condition code is other than + ‘No error’). */ + uint32_t file_size; + + /* + Omitted if condition code is ‘No error’. Otherwise, entity ID in the + TLV is the ID of the entity at which transaction cancellation was + initiated.*/ + TLV fault_location; + +} Pdu_eof; + + +//custom, nak missing other directives, like metadata and eof +typedef struct pdu_nak_directive{ + uint8_t directive; + +} pdu_nak_directive; + + /* + start_scope is the begining of the nak requests + end_scope is the end + segments are + */ +typedef struct pdu_nak { + uint32_t start_scope; + uint32_t end_scope; + + //number of Nak_segments + uint64_t segment_requests; + void *segments; +} Pdu_nak; + + +#define ACK_FINISHED_WAYPOINT 0 +#define ACK_FINISHED_END 1 +#define ACK_OTHER 0 + +typedef struct pdu_ack { + //Directive code of the acknowledged PDU. + unsigned int directive_code : 4; + + /* + Values depend on directive code. For ACK of Finished PDU: binary ‘0000’ + if Finished PDU is generated by waypoint, binary ‘0001’ if Finished + PDU is generated by end system. (NOTE: this discrimination is + meaningful if the Extended Procedures are implemented.) + Binary ‘0000’ for ACKs of all other file directives. + */ + + unsigned int directive_subtype_code : 4; + + //Condition code of the acknowledged PDU. + unsigned int condition_code : 4; + unsigned int spare : 2; + + //Status of the transaction in the context of the entity that is issuing the acknowledgment. + unsigned int transaction_status : 2; + +} Pdu_ack; + + + +//file_status codes +#define FILE_DISCARDED_DELIBERATELY 1 +#define FILE_DISCARDED_DUE_TO_REJECTION 2 +#define FILE_RETAINED_SUCCESSFULLY 3 +#define FILE_STATUS_UNREPORTED 4 + + +typedef struct pdu_finished { + unsigned int condition_code : 4; + + // 0 generated by waypoint 1 generated by end system. + unsigned int end_system_status : 1; + + //0 data complete, 1 data incomplete + unsigned int delivery_code : 1; + + //see above + unsigned int file_status : 2; + TLV file_store_responses; + TLV fault_location; + +}Pdu_finished; + + + + +/*----------------------------------------------------------------------------- + + Functions and structs for the app + +------------------------------------------------------------------------------*/ + + typedef struct offset { uint32_t start; uint32_t end; diff --git a/Program/src/makefile b/Program/src/makefile index 67b0cd7..f1cbf01 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -14,6 +14,7 @@ CFILES += requests.c CFILES += tasks.c CFILES += file_delivery_app.c CFILES += list.c +CFILES += packet.c #----------------------------test files------------------------- #entrypoint diff --git a/Program/src/packet.c b/Program/src/packet.c new file mode 100644 index 0000000..c369112 --- /dev/null +++ b/Program/src/packet.c @@ -0,0 +1,310 @@ +#include "types.h" +#include "packet.h" +#include "stdint.h" +#include "string.h" +#include "utils.h" +#include "port.h" +#include "filesystem_funcs.h" + +/*------------------------------------------------------------------------------ + + creating packets + +------------------------------------------------------------------------------*/ +//returns the location in the packet where the next pointer for tthe packet will start after the header + +uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { + + memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); + uint32_t packet_index = PACKET_STATIC_HEADER_LEN; + + Pdu_header *header = (Pdu_header *)packet; + header->transmission_mode = transmission_mode; + + //copy variable length src id + memcpy(&packet[packet_index], + pdu_header->source_id, + pdu_header->length_of_entity_IDs); + packet_index += pdu_header->length_of_entity_IDs; + + //copy variable length transaction number id + memcpy(&packet[packet_index], + &transaction_sequence_number, + pdu_header->transaction_seq_num_len); + packet_index += pdu_header->transaction_seq_num_len; + + //copy variable length destination id + memcpy(&packet[packet_index], + pdu_header->destination_id, + pdu_header->length_of_entity_IDs); + + uint8_t total_bytes = PACKET_STATIC_HEADER_LEN + + pdu_header->length_of_entity_IDs + + pdu_header->transaction_seq_num_len + + pdu_header->length_of_entity_IDs; + + return total_bytes; +} + +uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { + + uint32_t packet_index = start; + uint32_t data_len = 0; + + packet[packet_index] = FINISHED_PDU; + packet_index++; + data_len++; + + //one byte + Pdu_finished *pdu_finished = (Pdu_finished *) &packet[packet_index]; + pdu_finished->condition_code = COND_NO_ERROR; + pdu_finished->delivery_code = 0; + pdu_finished->file_status = FILE_RETAINED_SUCCESSFULLY; + data_len += 1; + packet_index += 1; + + set_data_length(packet, data_len); + return data_len; +} + + +uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req) { + Pdu_header *header = (Pdu_header *) res.msg; + + header->PDU_type = DIRECTIVE; + uint8_t packet_index = start; + + //set directive 1 byte + Pdu_directive *directive = (Pdu_directive *) &res.msg[packet_index]; + directive->directive_code = META_DATA_PDU; + packet_index += SIZE_OF_DIRECTIVE_CODE; + Pdu_meta_data *meta_data_packet = (Pdu_meta_data *) &res.msg[packet_index]; + + //1 bytes + meta_data_packet->segmentation_control = req->segmentation_control; + meta_data_packet->reserved_bits = 0; + packet_index++; + + //4 bytes + uint32_t network_bytes = htonl(req->file_size); + network_bytes = network_bytes; + memcpy(&res.msg[packet_index], &network_bytes, sizeof(uint32_t)); + packet_index += 4; + + //variable length params + uint8_t src_file_name_length = strnlen(req->source_file_name, MAX_PATH); + uint8_t destination_file_length = strnlen(req->destination_file_name, MAX_PATH); + char *src_file_name = req->source_file_name; + char *destination_file_name = req->destination_file_name; + + //copy source length to packet (1 bytes) + memcpy(&res.msg[packet_index], &src_file_name_length, src_file_name_length); + packet_index++; + //copy source name to packet (length bytes) + memcpy(&res.msg[packet_index], src_file_name, src_file_name_length); + packet_index += src_file_name_length; + + //copy length to packet (1 byte) + memcpy(&res.msg[packet_index], &destination_file_length, 1); + packet_index++; + + //copy destination name to packet (length bytes) + memcpy(&res.msg[packet_index], destination_file_name, destination_file_length); + packet_index += destination_file_length; + + uint8_t data_len = packet_index - start; + set_data_length(res.msg, data_len); + + return packet_index; +} +uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { + + if (offset > req->file->total_size) { + return 1; + } + + Pdu_header *header = (Pdu_header *) packet; + header->PDU_type = DATA; + + uint16_t packet_index = start; + File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; + packet_offset->offset = offset; + + //4 bytes is the size of the offset paramater + packet_index += 4; + uint16_t data_size = client->packet_len - packet_index; + //fill the rest of the packet with data + int bytes = get_offset(req->file, &packet[packet_index], data_size, offset); + if (bytes <= 0){ + ssp_error("could not get offset, this could because the file is empty!\n"); + return 1; + } + + uint16_t data_len = bytes + 4; + set_data_length(packet, data_len); + + if (bytes < data_size) + return 1; + + return 0; +} + + +//requires a req->file to be created +//returns 1 on end of file +//length is the total size of the packet +uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { + + if (file->next_offset_to_send > file->total_size){ + ssp_error("cant send an offset past the file's length\n"); + return 1; + } + + Pdu_header *header = (Pdu_header *) packet; + //set header to file directive 0 is directive, 1 is data + header->PDU_type = 1; + + uint16_t packet_index = start; + File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; + + //4 bytes is the size of the offset paramater + packet_offset->offset = file->next_offset_to_send; + packet_index += 4; + + uint16_t data_size = length - packet_index; + + //fill the rest of the packet with data + int bytes = get_offset(file, &packet[packet_index], data_size, file->next_offset_to_send); + if (bytes <= 0){ + ssp_error("could not get offset, this could because the file is empty!\n"); + return 1; + } + + //calculate checksum for data packet, this is used to calculate in transit checksums + file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); + file->next_offset_to_send += bytes; + + + //add bytes read, and the packet offset to the data_field length + uint16_t data_len = bytes + 4; + set_data_length(packet, data_len); + + if (bytes < data_size) + return 1; + + return 0; +} + +void build_eof_packet(char *packet, uint32_t start, Request *req) { + + Pdu_header *header = (Pdu_header *) packet; + //set header to file directive 0 is directive, 1 is data + header->PDU_type = 0; + + uint8_t packet_index = (uint8_t) start; + Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; + directive->directive_code = EOF_PDU; + packet_index++; + + Pdu_eof *eof_packet = (Pdu_eof *) &packet[packet_index]; + + //this will be need to set from the req struct probably. + //4 bits, + eof_packet->condition_code = COND_NO_ERROR; + //4 bits reserved bits + eof_packet->spare = 0; + packet_index++; + + //4 bytes + eof_packet->file_size = ntohl(req->file->total_size); + packet_index += 4; + eof_packet->checksum = req->file->partial_checksum; + packet_index += 4; + + //TODO addTLV fault_location + uint16_t data_len = htons(packet_index - start); + set_data_length(packet, data_len); + +} + +//this is a callback for building nak_array server side +struct offset_holder { + Offset *offsets; + int i; +}; + +void fill_nak_array(void *element, void *args){ + struct offset_holder *holder = (struct offset_holder *)args; + + Offset *offset = (Offset *)element; + + holder->offsets[holder->i].start = htonl(offset->start); + holder->offsets[holder->i].end = htonl(offset->end); + holder->i++; +} + +uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { + + packet[start] = NAK_PDU; + uint32_t packet_index = start + 1; + Pdu_nak *pdu_nak = (Pdu_nak *) &packet[packet_index]; + uint64_t count = req->file->missing_offsets->count; + + //fill offset array with all missing offsets [holder.offsets] + struct offset_holder holder; + holder.offsets = ssp_alloc(count, sizeof(Offset)); + holder.i = 0; + + req->file->missing_offsets->iterate(req->file->missing_offsets, fill_nak_array, &holder); + + pdu_nak->start_scope = holder.offsets[0].start; + pdu_nak->end_scope = holder.offsets[holder.i-1].end; + + + pdu_nak->segment_requests = htonll(count); + packet_index+=16; + + memcpy(&packet[packet_index], holder.offsets, sizeof(Offset) * count); + ssp_free(holder.offsets); + + packet_index += sizeof(Offset) * count; + + uint16_t data_len = packet_index - start; + set_data_length(packet, data_len); + + return data_len; +} + +uint8_t build_ack(char*packet, uint32_t start, uint8_t type) { + packet[start] = ACK_PDU; + uint32_t packet_index = start + 1; + Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; + + pdu_ack->directive_code = type; + pdu_ack->directive_subtype_code = ACK_FINISHED_END; + pdu_ack->condition_code = COND_NO_ERROR; + packet_index += 2; + uint16_t data_len = packet_index - start; + set_data_length(packet, data_len); + + return data_len; +} + +uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { + uint8_t data_len = 2; + packet[start] = NAK_DIRECTIVE; + packet[start + 1] = directive; + + set_data_length(packet, data_len); + return data_len; +} + +void set_data_length(char*packet, uint16_t data_len){ + Pdu_header *header = (Pdu_header*) packet; + header->PDU_data_field_len = htons(data_len);; +} + +uint16_t get_data_length(char*packet) { + Pdu_header *header = (Pdu_header*) packet; + return ntohs(header->PDU_data_field_len); +} diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1fa7f90..762168e 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -11,309 +11,6 @@ //snprintf #include -/*------------------------------------------------------------------------------ - - creating packets - -------------------------------------------------------------------------------*/ -//returns the location in the packet where the next pointer for tthe packet will start after the header - -uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { - - memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); - uint32_t packet_index = PACKET_STATIC_HEADER_LEN; - - Pdu_header *header = (Pdu_header *)packet; - header->transmission_mode = transmission_mode; - - //copy variable length src id - memcpy(&packet[packet_index], - pdu_header->source_id, - pdu_header->length_of_entity_IDs); - packet_index += pdu_header->length_of_entity_IDs; - - //copy variable length transaction number id - memcpy(&packet[packet_index], - &transaction_sequence_number, - pdu_header->transaction_seq_num_len); - packet_index += pdu_header->transaction_seq_num_len; - - //copy variable length destination id - memcpy(&packet[packet_index], - pdu_header->destination_id, - pdu_header->length_of_entity_IDs); - - uint8_t total_bytes = PACKET_STATIC_HEADER_LEN - + pdu_header->length_of_entity_IDs - + pdu_header->transaction_seq_num_len - + pdu_header->length_of_entity_IDs; - - return total_bytes; -} - -static uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { - - uint32_t packet_index = start; - uint32_t data_len = 0; - - packet[packet_index] = FINISHED_PDU; - packet_index++; - data_len++; - - //one byte - Pdu_finished *pdu_finished = (Pdu_finished *) &packet[packet_index]; - pdu_finished->condition_code = COND_NO_ERROR; - pdu_finished->delivery_code = 0; - pdu_finished->file_status = FILE_RETAINED_SUCCESSFULLY; - data_len += 1; - packet_index += 1; - - set_data_length(packet, data_len); - return data_len; -} - - -static uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req) { - Pdu_header *header = (Pdu_header *) res.msg; - - header->PDU_type = DIRECTIVE; - uint8_t packet_index = start; - - //set directive 1 byte - Pdu_directive *directive = (Pdu_directive *) &res.msg[packet_index]; - directive->directive_code = META_DATA_PDU; - packet_index += SIZE_OF_DIRECTIVE_CODE; - Pdu_meta_data *meta_data_packet = (Pdu_meta_data *) &res.msg[packet_index]; - - //1 bytes - meta_data_packet->segmentation_control = req->segmentation_control; - meta_data_packet->reserved_bits = 0; - packet_index++; - - //4 bytes - uint32_t network_bytes = htonl(req->file_size); - network_bytes = network_bytes; - memcpy(&res.msg[packet_index], &network_bytes, sizeof(uint32_t)); - packet_index += 4; - - //variable length params - uint8_t src_file_name_length = strnlen(req->source_file_name, MAX_PATH); - uint8_t destination_file_length = strnlen(req->destination_file_name, MAX_PATH); - char *src_file_name = req->source_file_name; - char *destination_file_name = req->destination_file_name; - - //copy source length to packet (1 bytes) - memcpy(&res.msg[packet_index], &src_file_name_length, src_file_name_length); - packet_index++; - //copy source name to packet (length bytes) - memcpy(&res.msg[packet_index], src_file_name, src_file_name_length); - packet_index += src_file_name_length; - - //copy length to packet (1 byte) - memcpy(&res.msg[packet_index], &destination_file_length, 1); - packet_index++; - - //copy destination name to packet (length bytes) - memcpy(&res.msg[packet_index], destination_file_name, destination_file_length); - packet_index += destination_file_length; - - uint8_t data_len = packet_index - start; - set_data_length(res.msg, data_len); - - return packet_index; -} -static uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { - - if (offset > req->file->total_size) { - return 1; - } - - Pdu_header *header = (Pdu_header *) packet; - header->PDU_type = DATA; - - uint16_t packet_index = start; - File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; - packet_offset->offset = offset; - - //4 bytes is the size of the offset paramater - packet_index += 4; - uint16_t data_size = client->packet_len - packet_index; - //fill the rest of the packet with data - int bytes = get_offset(req->file, &packet[packet_index], data_size, offset); - if (bytes <= 0){ - ssp_error("could not get offset, this could because the file is empty!\n"); - return 1; - } - - uint16_t data_len = bytes + 4; - set_data_length(packet, data_len); - - if (bytes < data_size) - return 1; - - return 0; -} - - -//requires a req->file to be created -//returns 1 on end of file -//length is the total size of the packet -uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { - - if (file->next_offset_to_send > file->total_size){ - ssp_error("cant send an offset past the file's length\n"); - return 1; - } - - Pdu_header *header = (Pdu_header *) packet; - //set header to file directive 0 is directive, 1 is data - header->PDU_type = 1; - - uint16_t packet_index = start; - File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; - - //4 bytes is the size of the offset paramater - packet_offset->offset = file->next_offset_to_send; - packet_index += 4; - - uint16_t data_size = length - packet_index; - - //fill the rest of the packet with data - int bytes = get_offset(file, &packet[packet_index], data_size, file->next_offset_to_send); - if (bytes <= 0){ - ssp_error("could not get offset, this could because the file is empty!\n"); - return 1; - } - - //calculate checksum for data packet, this is used to calculate in transit checksums - file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); - file->next_offset_to_send += bytes; - - - //add bytes read, and the packet offset to the data_field length - uint16_t data_len = bytes + 4; - set_data_length(packet, data_len); - - if (bytes < data_size) - return 1; - - return 0; -} - -static void build_eof_packet(char *packet, uint32_t start, Request *req) { - - Pdu_header *header = (Pdu_header *) packet; - //set header to file directive 0 is directive, 1 is data - header->PDU_type = 0; - - uint8_t packet_index = (uint8_t) start; - Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; - directive->directive_code = EOF_PDU; - packet_index++; - - Pdu_eof *eof_packet = (Pdu_eof *) &packet[packet_index]; - - //this will be need to set from the req struct probably. - //4 bits, - eof_packet->condition_code = COND_NO_ERROR; - //4 bits reserved bits - eof_packet->spare = 0; - packet_index++; - - //4 bytes - eof_packet->file_size = ntohl(req->file->total_size); - packet_index += 4; - eof_packet->checksum = req->file->partial_checksum; - packet_index += 4; - - //TODO addTLV fault_location - uint16_t data_len = htons(packet_index - start); - set_data_length(packet, data_len); - -} - -//this is a callback for building nak_array server side -struct offset_holder { - Offset *offsets; - int i; -}; - -static void fill_nak_array(void *element, void *args){ - struct offset_holder *holder = (struct offset_holder *)args; - - Offset *offset = (Offset *)element; - - holder->offsets[holder->i].start = htonl(offset->start); - holder->offsets[holder->i].end = htonl(offset->end); - holder->i++; -} - -uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { - - packet[start] = NAK_PDU; - uint32_t packet_index = start + 1; - Pdu_nak *pdu_nak = (Pdu_nak *) &packet[packet_index]; - uint64_t count = req->file->missing_offsets->count; - - //fill offset array with all missing offsets [holder.offsets] - struct offset_holder holder; - holder.offsets = ssp_alloc(count, sizeof(Offset)); - holder.i = 0; - - req->file->missing_offsets->iterate(req->file->missing_offsets, fill_nak_array, &holder); - - pdu_nak->start_scope = holder.offsets[0].start; - pdu_nak->end_scope = holder.offsets[holder.i-1].end; - - - pdu_nak->segment_requests = htonll(count); - packet_index+=16; - - memcpy(&packet[packet_index], holder.offsets, sizeof(Offset) * count); - ssp_free(holder.offsets); - - packet_index += sizeof(Offset) * count; - - uint16_t data_len = packet_index - start; - set_data_length(packet, data_len); - - return data_len; -} - -uint8_t build_ack(char*packet, uint32_t start, uint8_t type) { - packet[start] = ACK_PDU; - uint32_t packet_index = start + 1; - Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; - - pdu_ack->directive_code = type; - pdu_ack->directive_subtype_code = ACK_FINISHED_END; - pdu_ack->condition_code = COND_NO_ERROR; - packet_index += 2; - uint16_t data_len = packet_index - start; - set_data_length(packet, data_len); - - return data_len; -} - -static uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { - uint8_t data_len = 2; - packet[start] = NAK_DIRECTIVE; - packet[start + 1] = directive; - - set_data_length(packet, data_len); - return data_len; -} - -void set_data_length(char*packet, uint16_t data_len){ - Pdu_header *header = (Pdu_header*) packet; - header->PDU_data_field_len = htons(data_len);; -} - -uint16_t get_data_length(char*packet) { - Pdu_header *header = (Pdu_header*) packet; - return ntohs(header->PDU_data_field_len); -} - /*------------------------------------------------------------------------------ bundled requests From c91ef368ec433d34599f2059f7de0d5955c522e3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 19 Aug 2019 15:07:47 -0600 Subject: [PATCH 076/400] Fixed dependencies --- Program/include/file_delivery_app.h | 2 +- Program/include/filesystem_funcs.h | 17 ------- Program/include/mib.h | 79 +---------------------------- Program/include/packet.h | 5 +- Program/include/port.h | 2 +- Program/include/protocol_handler.h | 49 ------------------ Program/include/tasks.h | 5 +- Program/src/file_delivery_app.c | 2 + Program/src/main.c | 1 + Program/src/packet.c | 2 +- Program/src/protocol_handler.c | 3 +- Program/src/tasks.c | 1 + Program/src/utils.c | 1 - 13 files changed, 14 insertions(+), 155 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 54f75e3..371ab1a 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -3,7 +3,7 @@ #ifndef FTP_APP_H #define FTP_APP_H -#include "protocol_handler.h" +#include "types.h" Protocol_state *init_ftp(uint32_t my_cfdp_address); diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index d4ebb38..0c64c77 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -7,24 +7,7 @@ #define TEMP_FILESIZE 1000 -/* -typedef struct offset { - uint32_t start; - uint32_t end; -} Offset; - -typedef struct file { - int fd; - uint8_t is_temp; - uint32_t next_offset_to_send; - uint32_t total_size; - uint32_t partial_checksum; - uint32_t eof_checksum; - List *missing_offsets; - -} File; -*/ uint32_t get_file_size(char *source_file_name); //allocates space for a file pointer diff --git a/Program/include/mib.h b/Program/include/mib.h index b16efb6..5e86e6a 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -5,87 +5,10 @@ #ifndef MIB_H #define MIB_H + #include -#include #include "packet.h" #include "types.h" -/* -typedef struct local_entity { - unsigned int EOF_sent_indication : 1; - - unsigned int EOF_recv_indication : 1; - - //required - unsigned int file_segment_recv_indication : 1; - - //required when acting as receiving entity - unsigned int transaction_finished_indication : 1; - - //required when acting as receiving entity - unsigned int suspended_indication : 1; - - //required when acting as receiving entity - unsigned int resumed_indication : 1; - - //function pointer to default handler? - void *default_fault_handler; - - //TODO routing information, extended procedures only, list maybe? - -} Local_entity; - - -typedef struct remote_entity { - - //TODO probably add new UT layer specific stuff - uint32_t UT_address; - uint16_t UT_port; - uint32_t cfdp_id; - - unsigned int one_way_light_time; - unsigned int total_round_trip_allowance; - unsigned int async_NAK_interval; - unsigned int async_keep_alive_interval; - unsigned int async_report_interval; - unsigned int immediate_nak_mode_enabled : 1; - unsigned int prompt_transmission_interval; - //acknowledged or unacknowledged - unsigned int default_transmission_mode: 1; - - //discard or retain (no idea what this is for yet) - unsigned int disposition_of_incomplete : 1; - - unsigned int CRC_required : 1; - //in octets - unsigned int max_file_segment_len; - //in octets - unsigned int keep_alive_discrepancy_limit; - - //Number of expirations - unsigned int positive_ack_timer_expiration_limit; - - //Number of expirations - unsigned int nak_timer_expiration_limit; - - //time limit - unsigned int transaction_inactivity_limit; - - - //Start of transmission opportunity A signal produced by the operating environment. - //End of transmission opportunity A signal produced by the operating environment. - //Start of reception opportunity A signal produced by the operating environment. - //End of reception opportunity A signal produced by the operating environment. - - - -} Remote_entity; - -typedef struct mib { - Local_entity server; - List *remote_entities; - -} MIB; -*/ MIB *init_mib(void); void free_mib(MIB *mib); diff --git a/Program/include/packet.h b/Program/include/packet.h index af7bf12..6298d6e 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -2,7 +2,6 @@ #ifndef PACKET_H #define PACKET_H -#include #define PACKET_HEADER_LEN 224 // PACKET_HEADER_LEN + data max size = (65536 * 8) #define PACKET_MAX_LEN 524512 @@ -10,9 +9,11 @@ #define PACKET_STATIC_HEADER_LEN 4 //in bytes #include "types.h" +#include + uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); -uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req); +uint8_t build_finished_pdu(char *packet, uint32_t start); uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); diff --git a/Program/include/port.h b/Program/include/port.h index 03fb2c8..6495c0d 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -8,7 +8,7 @@ #define MAX_PATH 255 -#include "protocol_handler.h" +#include "types.h" void ssp_error( char *msg); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 5cb2efe..56f0f35 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -3,55 +3,6 @@ #define PROTOCOL_H #include "types.h" -/* -typedef struct protocol_state { - uint32_t packet_size; - char *server_port; - void *server_handle; - MIB *mib; - uint32_t my_cfdp_id; - - List* request_list; - - Request *current_request; - - //lock this - uint32_t transaction_sequence_number; - - uint8_t verbose_level; - - //bool for exiting the server thread - uint8_t close; - -} Protocol_state; - - -//outgoing requests spin up client threads -typedef struct client { - - void *client_handle; - uint32_t packet_len; - - Request *current_request; - List *request_list; - - //can get rid of these, these are found in mib_info anyway - uint32_t cfdp_id; - uint32_t unitdata_id; - uint32_t unitdata_port; - - Remote_entity *mib_info; - Pdu_header *pdu_header; - - Protocol_state *p_state; - - //bool for exiting the client thread - uint8_t close; - - -} Client; -*/ - //for use void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client); diff --git a/Program/include/tasks.h b/Program/include/tasks.h index 2f8bf81..a2a0e1e 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -2,10 +2,7 @@ #ifndef SSP_TASKS_H #define SSP_TASKS_H - - -#include "protocol_handler.h" - +#include "types.h" void ssp_cleanup_client(Client *client); void ssp_cleanup_req(void *request); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 9b613f0..7c6f25b 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -8,6 +8,8 @@ #include "file_delivery_app.h" #include "tasks.h" #include +#include +#include "utils.h" Protocol_state *init_ftp(uint32_t my_cfdp_address) { diff --git a/Program/src/main.c b/Program/src/main.c index dcf1c07..983e086 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -4,6 +4,7 @@ #include #include #include +#include //Have to include these files diff --git a/Program/src/packet.c b/Program/src/packet.c index c369112..4ff33ff 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -46,7 +46,7 @@ uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uin return total_bytes; } -uint8_t build_finished_pdu(char *packet, uint32_t start, Request *req) { +uint8_t build_finished_pdu(char *packet, uint32_t start) { uint32_t packet_index = start; uint32_t data_len = 0; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 762168e..3f375ba 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -7,6 +7,7 @@ #include "filesystem_funcs.h" #include "requests.h" #include "types.h" +#include "utils.h" //snprintf #include @@ -455,7 +456,7 @@ void on_server_time_out(Response res, Request *req) { if (req->file->eof_checksum == req->file->partial_checksum){ ssp_printf("sending finsihed pdu\n"); - build_finished_pdu(res.msg, start, req); + build_finished_pdu(res.msg, start); ssp_sendto(res); req->resent_finished++; return; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 5a849da..e68c3ab 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -10,6 +10,7 @@ #include "filesystem_funcs.h" #include #include "types.h" +#include /*------------------------------------------------------------------------------ Callbacks for the tasks bellow diff --git a/Program/src/utils.c b/Program/src/utils.c index cc12629..408f922 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -10,7 +10,6 @@ to use for general functionality. #include #include "utils.h" #include -#include #include #include #include From ce7be37ec0b2ef58a6207af7db8342f798f99f00 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 19 Aug 2019 15:09:18 -0600 Subject: [PATCH 077/400] Move that there --- Program/include/protocol_handler.h | 13 +---- Program/include/requests.h | 89 +++++------------------------- 2 files changed, 16 insertions(+), 86 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 56f0f35..9700615 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -20,17 +20,6 @@ void set_data_length(char*packet, uint16_t data_len); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); uint16_t get_data_length(char*packet); -Request *put_request( - char *source_file_name, - char *destination_file_name, - uint8_t segmentation_control, - uint8_t fault_handler_overides, - uint8_t flow_lable, - uint8_t transmission_mode, - char* messages_to_user, - char* filestore_requests, - Client *client, - Protocol_state *p_state - ); + #endif \ No newline at end of file diff --git a/Program/include/requests.h b/Program/include/requests.h index e009edf..387e226 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -5,81 +5,22 @@ #include "stdint.h" #include "protocol_handler.h" #include "types.h" -/* -typedef struct response { - int sfd; - //this is a pointer to buff in a request - char *msg; - //this is type (struct sockaddr_in) in posix - void *addr; - //getting rid of this soon in favour of client based packet sizes - - size_t size_of_addr; - uint32_t packet_len; - -} Response; - -typedef enum Indication { - finished, - none, - transaction, - put, - eof, - //sending data - sending_data, - clean_up - -} Indication; - -//incoming requests spin up requests -typedef struct request { - Indication type; - uint64_t transaction_sequence_number; - uint32_t dest_cfdp_id; - - File *file; - uint32_t file_size; - - char *source_file_name; - char *destination_file_name; - - uint32_t packet_data_len; - - //timeout - uint8_t timeout; - - uint8_t segmentation_control; - uint8_t fault_handler_overides; - uint8_t flow_lable; - uint8_t transmission_mode; - - uint8_t received_metadata; - uint8_t received_eof; - //counter for resending eof packets == 3 - uint8_t resent_eof; - uint8_t received_finished; - //counter for resending finished packets == 3 - uint8_t resent_finished; - //bool for sending first blast of data packets - uint8_t sent_first_data_round; - - char* messages_to_user; - char* filestore_requests; - - //sets the buffer length, for making packets - uint32_t buff_len; - - //buffer for making packets - char* buff; - - //header for building response packets - Pdu_header *pdu_header; - - //handler for sending responses back - Response res; -} Request; -*/ void ssp_cleanup_req(void *request); Request *init_request(uint32_t buff_len); + +Request *put_request( + char *source_file_name, + char *destination_file_name, + uint8_t segmentation_control, + uint8_t fault_handler_overides, + uint8_t flow_lable, + uint8_t transmission_mode, + char* messages_to_user, + char* filestore_requests, + Client *client, + Protocol_state *p_state + ); + + #endif \ No newline at end of file From 7e8c9573a63c77ce8fc7515cc8b0e2b5ae3346f9 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 19 Aug 2019 15:34:21 -0600 Subject: [PATCH 078/400] Add macros for resend finished and eof packets --- Program/include/protocol_handler.h | 3 ++ Program/include/types.h | 16 +++++------ Program/src/protocol_handler.c | 46 +++++++++++++++--------------- Program/src/requests.c | 7 +++-- Program/src/tasks.c | 4 +-- 5 files changed, 40 insertions(+), 36 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 9700615..3d329fb 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -3,6 +3,9 @@ #define PROTOCOL_H #include "types.h" +#define RESEND_EOF_TIMES 3 +#define RESEND_FINISHED_TIMES 3 + //for use void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client); diff --git a/Program/include/types.h b/Program/include/types.h index 6887d53..6e726c4 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -475,28 +475,28 @@ typedef struct response { //this is type (struct sockaddr_in) in posix void *addr; //getting rid of this soon in favour of client based packet sizes - size_t size_of_addr; + uint32_t packet_len; } Response; -typedef enum Indication { - finished, +typedef enum procedure { + sending_finished, none, - transaction, - put, - eof, + sending_put_metadata, + sending_eof, //sending data sending_data, clean_up -} Indication; +} Request_procedure; //incoming requests spin up requests typedef struct request { - Indication type; + Request_procedure procedure; + uint64_t transaction_sequence_number; uint32_t dest_cfdp_id; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 3f375ba..40bf63d 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -153,7 +153,7 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l found_req->dest_cfdp_id = source_id; found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); - found_req->type = put; + found_req->procedure = sending_put_metadata; found_req->res.addr = ssp_alloc(res.size_of_addr, 1); memcpy(found_req->res.addr, res.addr, res.size_of_addr); found_req->res.packet_len = p_state->packet_size; @@ -285,7 +285,7 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch(directive) { case FINISHED_PDU: req->local_entity->transaction_finished_indication = 1; - req->type = finished; + req->procedure = sending_finished; ssp_printf("received finished pdu\n"); break; case NAK_PDU: @@ -304,12 +304,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ { case META_DATA_PDU: ssp_printf("resending metadata\n"); - req->type = put; + req->procedure = sending_put_metadata; break; case EOF_PDU: ssp_printf("resending eof\n"); - req->type = eof; + req->procedure = sending_eof; break; default: @@ -323,12 +323,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ } static void check_req_status(Request *req, Client *client) { - if (req->resent_finished >= 3){ - req->type = none; + if (req->resent_finished >= RESEND_FINISHED_TIMES){ + req->procedure = none; } - if (req->resent_finished == 3) { + if (req->resent_finished == RESEND_FINISHED_TIMES) { ssp_printf("file successfully sent\n"); - req->resent_finished = 4; + req->resent_finished = RESEND_FINISHED_TIMES + 1; } } @@ -345,12 +345,13 @@ void user_request_handler(Response res, Request *req, Client* client) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req, client); - switch (req->type) + switch (req->procedure) { - case eof: + case sending_eof: ssp_printf("sending eof\n"); - req->type = none; + req->procedure = none; build_eof_packet(req->buff, start, req); + req->local_entity->EOF_sent_indication = 1; ssp_sendto(res); break; @@ -359,21 +360,20 @@ void user_request_handler(Response res, Request *req, Client* client) { return; if (build_data_packet(req->buff, start, req->file, client->packet_len)) { - req->type = eof; - req->local_entity->EOF_sent_indication = 1; + req->procedure = sending_eof; ssp_printf("sending data blast\n"); } ssp_sendto(res); break; - case put: + case sending_put_metadata: ssp_printf("sending metadata\n"); start = build_put_packet_metadata(res, start, req); ssp_sendto(res); - req->type = sending_data; + req->procedure = sending_data; break; - case finished: + case sending_finished: ssp_printf("sending finished packet\n"); build_ack(req->buff, start, FINISHED_PDU); ssp_sendto(res); @@ -397,7 +397,7 @@ static void reset_timeout(Request *req) { //ssp_printf("timeout %u for id: %u sequence: %u\n", time, req->dest_cfdp_id, req->transaction_sequence_number); if (time == 20) { req->timeout = 0; - req->type = clean_up; + req->procedure = clean_up; ssp_printf("timeout, cleaning up request\n"); } } @@ -417,7 +417,7 @@ void on_server_time_out(Response res, Request *req) { reset_timeout(req); - if (req->type == none) + if (req->procedure == none) return; if (req->transmission_mode == 1) @@ -425,8 +425,8 @@ void on_server_time_out(Response res, Request *req) { uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); - if (req->resent_finished == 3) { - req->type = none; + if (req->resent_finished == RESEND_FINISHED_TIMES) { + req->procedure = none; ssp_printf("file sent, closing request\n"); return; } @@ -465,8 +465,8 @@ void on_server_time_out(Response res, Request *req) { ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); } } - //received EOF, send back 3 eof packets - if (req->local_entity->EOF_recv_indication && req->resent_eof < 3) { + //received EOF, send back 3 eof ack packets + if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { ssp_printf("sending eof ack\n"); build_ack(res.msg, start, EOF_PDU); ssp_sendto(res); @@ -507,7 +507,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ if (req->local_entity->Metadata_recv_indication) break; - req->type = put; + req->procedure = sending_put_metadata; ssp_printf("received metadata packet\n"); fill_request_pdu_metadata(&packet[packet_index], req); process_file_request_metadata(req); diff --git a/Program/src/requests.c b/Program/src/requests.c index 5923582..0412cbc 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -7,7 +7,7 @@ ------------------------------------------------------------------------------*/ #include "stdint.h" -#include "protocol_handler.h" +#include "requests.h" #include "port.h" #include "utils.h" #include @@ -57,7 +57,8 @@ Request *init_request(uint32_t buff_len) { req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); - req->type = none; + req->res.msg = req->buff; + req->procedure = none; checkAlloc(req->buff, 1); return req; } @@ -89,7 +90,7 @@ Request *put_request(char *source_file_name, req->transaction_sequence_number = p_state->transaction_sequence_number++; //enumeration - req->type = put; + req->procedure = sending_put_metadata; req->dest_cfdp_id = client->remote_entity->cfdp_id; req->file_size = file_size; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index e68c3ab..602e879 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -79,7 +79,7 @@ static void remove_request_check(void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; - if (req->type == clean_up) { + if (req->procedure == clean_up) { Request *remove_this = req_list->remove(req_list, 0, remove_request, req); ssp_cleanup_req(remove_this); } @@ -184,7 +184,7 @@ static int on_stdin(void *other) { fgets(input, MAX_PATH, stdin); input[strlen(input)-1]='\0'; - if (req->type == none){ + if (req->procedure == none){ if (strnlen(req->source_file_name, MAX_PATH) == 0){ if (get_file_size(input) == -1){ ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); From e9a53af2e3cd0aa08dcffd79a0dbdaacc4a0e7a3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 19 Aug 2019 16:19:54 -0600 Subject: [PATCH 079/400] add packet len to server callback functions --- Program/include/server.h | 4 ++-- Program/src/protocol_handler.c | 24 ++++++++++-------------- Program/src/server.c | 8 ++++---- Program/src/tasks.c | 8 ++++---- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/Program/include/server.h b/Program/include/server.h index bef6340..97db825 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -43,7 +43,7 @@ int prepareUdpHost(char *port); ------------------------------------------------------------------------------*/ void udpSelectServer(char* port, int packet_len, - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), int (*checkExit)(void *other), @@ -63,7 +63,7 @@ int *prepareSignalHandler(void); void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 40bf63d..ba18e92 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -20,10 +20,9 @@ static void request_metadata(Request *req, Response res) { - res.msg = req->buff; ssp_printf("sending request for new metadata packet\n"); - uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); - build_nak_directive(res.msg, start, META_DATA_PDU); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + build_nak_directive(req->buff, start, META_DATA_PDU); ssp_sendto(res); return; } @@ -158,7 +157,6 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l memcpy(found_req->res.addr, res.addr, res.size_of_addr); found_req->res.packet_len = p_state->packet_size; found_req->res.sfd = res.sfd; - found_req->res.msg = found_req->buff; request_list->push(request_list, found_req, transaction_sequence_number); } @@ -338,13 +336,11 @@ void user_request_handler(Response res, Request *req, Client* client) { if (req == NULL) return; - if (res.msg == NULL) { - ssp_printf("req->buff is null, couldn't process user request\n"); - return; - } uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req, client); + //Response res = req->res; + switch (req->procedure) { case sending_eof: @@ -423,7 +419,7 @@ void on_server_time_out(Response res, Request *req) { if (req->transmission_mode == 1) return; - uint8_t start = build_pdu_header(res.msg, req->transaction_sequence_number, 1, req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); if (req->resent_finished == RESEND_FINISHED_TIMES) { req->procedure = none; @@ -434,21 +430,21 @@ void on_server_time_out(Response res, Request *req) { //send request for metadata if (!req->local_entity->Metadata_recv_indication) { ssp_printf("sending request for new metadata packet\n"); - build_nak_directive(res.msg, start, META_DATA_PDU); + build_nak_directive(req->buff, start, META_DATA_PDU); ssp_sendto(res); return; } //send missing eofs if (!req->local_entity->EOF_recv_indication) { - build_nak_directive(res.msg, start, EOF_PDU); + build_nak_directive(req->buff, start, EOF_PDU); ssp_sendto(res); } //send missing NAKS if (req->file->missing_offsets->count > 0) { ssp_printf("sending Nak data\n"); - build_nak_packet(res.msg, start, req); + build_nak_packet(req->buff, start, req); ssp_sendto(res); return; @@ -456,7 +452,7 @@ void on_server_time_out(Response res, Request *req) { if (req->file->eof_checksum == req->file->partial_checksum){ ssp_printf("sending finsihed pdu\n"); - build_finished_pdu(res.msg, start); + build_finished_pdu(req->buff, start); ssp_sendto(res); req->resent_finished++; return; @@ -468,7 +464,7 @@ void on_server_time_out(Response res, Request *req) { //received EOF, send back 3 eof ack packets if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { ssp_printf("sending eof ack\n"); - build_ack(res.msg, start, EOF_PDU); + build_ack(req->buff, start, EOF_PDU); ssp_sendto(res); req->resent_eof++; } diff --git a/Program/src/server.c b/Program/src/server.c index f0ca9ab..084bd54 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -144,7 +144,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf //see header file void udpSelectServer(char* port, int packet_len, - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), int (*checkExit)(void *other), @@ -230,7 +230,7 @@ void udpSelectServer(char* port, int packet_len, } else { - if (onRecv(sfd, buff, buff_size, (void*) client, sizeof(struct sockaddr), other) == -1) + if (onRecv(sfd, buff, count, buff_size, (void*) client, sizeof(struct sockaddr), other) == -1) printf("recv failed\n"); } } @@ -248,7 +248,7 @@ void udpSelectServer(char* port, int packet_len, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) { @@ -315,7 +315,7 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo } else { - if (onRecv(sfd, buff, buff_size, (void *)&serveraddr, sizeof(struct sockaddr), onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, sizeof(struct sockaddr), onRecvParams) == -1) printf("recv failed\n"); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 602e879..0d818ab 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -17,7 +17,7 @@ ------------------------------------------------------------------------------*/ //this function is a callback when using my posix port -static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { +static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { Protocol_state *p_state = (Protocol_state *) other; Response res; @@ -41,7 +41,7 @@ static int on_recv_server(int sfd, char *packet, uint32_t *buff_size, void *addr } -static int on_recv_client(int sfd, char *packet, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { +static int on_recv_client(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { Client *client = (Client *) other; @@ -93,9 +93,9 @@ struct user_request_check_params { static void user_request_check(void *request, void *args) { Request * req = (Request *) request; struct user_request_check_params* params = (struct user_request_check_params *) args; - + params->res.msg = req->buff; - + memset(params->res.msg, 0, params->client->packet_len); user_request_handler(params->res, req, params->client); remove_request_check(request, params->client->request_list); From 62fcfbd591a4626c1d81fd1b6ea58321a02cef17 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 20 Aug 2019 15:54:42 -0600 Subject: [PATCH 080/400] working on fixing request cleanup after certain time --- Program/include/protocol_handler.h | 3 ++- Program/include/server.h | 2 +- Program/include/types.h | 2 -- Program/src/protocol_handler.c | 28 +++++++++++++++------------- Program/src/server.c | 23 ++++++++--------------- Program/src/tasks.c | 13 +++++++------ 6 files changed, 33 insertions(+), 38 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 3d329fb..c5502bd 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -5,13 +5,14 @@ #define RESEND_EOF_TIMES 3 #define RESEND_FINISHED_TIMES 3 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 100 //for use void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, uint32_t packet_index, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request); -int process_pdu_header(char*packet, Response res, Request **req, List *request_list, Protocol_state *p_state); +int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, Protocol_state *p_state); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); //for testing diff --git a/Program/include/server.h b/Program/include/server.h index 97db825..b36fa9f 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -42,7 +42,7 @@ int prepareUdpHost(char *port); Return: None ------------------------------------------------------------------------------*/ -void udpSelectServer(char* port, int packet_len, +void connectionless_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), diff --git a/Program/include/types.h b/Program/include/types.h index 6e726c4..8e368bd 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -450,8 +450,6 @@ typedef struct remote_entity { unsigned int transaction_inactivity_limit; - - /* Start of transmission opportunity A signal produced by the operating environment. End of transmission opportunity A signal produced by the operating environment. diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index ba18e92..e0af24e 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -96,10 +96,13 @@ static int find_request(void *element, void *args) { } + + + /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns 0 on fail*/ -int process_pdu_header(char*packet, Response res, Request **req, List *request_list, Protocol_state *p_state) { +int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; @@ -141,8 +144,8 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); - //server side, receiving requests - if (found_req == NULL) + //server side, receiving requests (this should be its own function) + if (found_req == NULL && is_server) { found_req = init_request(p_state->packet_size); ssp_printf("incoming new request\n"); @@ -158,7 +161,6 @@ int process_pdu_header(char*packet, Response res, Request **req, List *request_l found_req->res.packet_len = p_state->packet_size; found_req->res.sfd = res.sfd; request_list->push(request_list, found_req, transaction_sequence_number); - } found_req->packet_data_len = len; @@ -324,10 +326,6 @@ static void check_req_status(Request *req, Client *client) { if (req->resent_finished >= RESEND_FINISHED_TIMES){ req->procedure = none; } - if (req->resent_finished == RESEND_FINISHED_TIMES) { - ssp_printf("file successfully sent\n"); - req->resent_finished = RESEND_FINISHED_TIMES + 1; - } } //current user request, to send to remote @@ -339,7 +337,6 @@ void user_request_handler(Response res, Request *req, Client* client) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req, client); - //Response res = req->res; switch (req->procedure) { @@ -391,10 +388,15 @@ static void reset_timeout(Request *req) { uint8_t time = req->timeout++; //ssp_printf("timeout %u for id: %u sequence: %u\n", time, req->dest_cfdp_id, req->transaction_sequence_number); - if (time == 20) { - req->timeout = 0; - req->procedure = clean_up; - ssp_printf("timeout, cleaning up request\n"); + + ssp_printf("file sent, no other packets coming in, closing transaction %d\n", req->transaction_sequence_number); + + if (time >= TIMEOUT_BEFORE_CANCEL_REQUEST) { + if (req->procedure == none) { + req->procedure = clean_up; + return; + } + ssp_printf("timeout, closing up request, request stopped early\n"); } } diff --git a/Program/src/server.c b/Program/src/server.c index 084bd54..228b9d6 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -143,7 +143,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf } //see header file -void udpSelectServer(char* port, int packet_len, +void connectionless_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -161,8 +161,7 @@ void udpSelectServer(char* port, int packet_len, uint32_t *buff_size = calloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); - - *buff_size = packet_len + 10; + *buff_size = initial_buff_size + 10; uint32_t prev_buff_size = *buff_size; @@ -178,7 +177,7 @@ void udpSelectServer(char* port, int packet_len, { struct timeval timeout = { .tv_sec = 0, - .tv_usec = 1000e3, + .tv_usec = 100e3, }; fd_set readFds = masterReadFds; @@ -212,24 +211,18 @@ void udpSelectServer(char* port, int packet_len, //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html // good article! - if (FD_ISSET(sfd, &readFds)) - { + if (FD_ISSET(sfd, &readFds)) { socklen_t client_len = sizeof(*client); - int count = recvfrom(sfd, buff, packet_len, 0, (void *) client, &client_len); + int count = recvfrom(sfd, buff, *buff_size, 0, (void *) client, &client_len); - - if (count == -1) - { + if (count == -1) { perror("recv failed"); } - else if (count >= *buff_size) - { + else if (count >= *buff_size) { printf("packet too large\n"); - continue; } - else - { + else { if (onRecv(sfd, buff, count, buff_size, (void*) client, sizeof(struct sockaddr), other) == -1) printf("recv failed\n"); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 0d818ab..dc37709 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -28,12 +28,12 @@ static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t Request **request_container = &p_state->current_request; - uint32_t packet_index = process_pdu_header(packet, res, request_container, p_state->request_list, p_state); + uint32_t packet_index = process_pdu_header(packet, 1, res, request_container, p_state->request_list, p_state); p_state->current_request = (*request_container); if (packet_index == 0) return -1; - + parse_packet_server(packet, packet_index, res, (*request_container), p_state); memset(packet, 0, res.packet_len); @@ -53,7 +53,7 @@ static int on_recv_client(int sfd, char *packet, uint32_t packet_len, uint32_t * Request **request_container = &client->current_request; - uint32_t packet_index = process_pdu_header(packet, res, request_container, client->request_list, client->p_state); + uint32_t packet_index = process_pdu_header(packet, 0, res, request_container, client->request_list, client->p_state); if (packet_index == -1) { ssp_printf("error parsing header\n"); return -1; @@ -78,10 +78,11 @@ static int remove_request(void *request, void *args) { static void remove_request_check(void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; - - if (req->procedure == clean_up) { + if (req->procedure == clean_up) { + ssp_printf("CLEANINGUP request count: %d procedure:%d cleanup %d none: %d sending_put_metadata %d\n", req_list->count, req->procedure, clean_up, none, sending_put_metadata); Request *remove_this = req_list->remove(req_list, 0, remove_request, req); ssp_cleanup_req(remove_this); + //ssp_printf("CLEANINGUP request count: %d\n", req_list->count); } } @@ -224,7 +225,7 @@ void *ssp_connectionless_server_task(void *params) { p_state->transaction_sequence_number = 1; #ifdef POSIX_PORT - udpSelectServer(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + connectionless_server(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); #endif return NULL; From 1965d579227cba081d3377eb454f8f511669d8f5 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 20 Aug 2019 16:22:17 -0600 Subject: [PATCH 081/400] closeer to figuring out bug, not receiving finished --- Program/include/types.h | 2 +- Program/src/protocol_handler.c | 61 +++++++++++++++++----------------- Program/src/tasks.c | 6 ++-- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index 8e368bd..c4f8542 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -507,7 +507,7 @@ typedef struct request { uint32_t packet_data_len; //timeout - uint8_t timeout; + uint32_t timeout; uint8_t segmentation_control; uint8_t fault_handler_overides; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e0af24e..5d5c510 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -286,16 +286,16 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ case FINISHED_PDU: req->local_entity->transaction_finished_indication = 1; req->procedure = sending_finished; - ssp_printf("received finished pdu\n"); + ssp_printf("received finished pdu transaction: %d\n", req->transaction_sequence_number); break; case NAK_PDU: req->local_entity->Metadata_recv_indication = 1; nak_response(packet, packet_index, req, res, client); - ssp_printf("received Nak pdu\n"); + ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); break; case ACK_PDU: if (packet[packet_index] == EOF_PDU) { - ssp_printf("received Eof ack\n"); + ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); req->local_entity->EOF_recv_indication = 1; } break; @@ -303,12 +303,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch (packet[packet_index]) { case META_DATA_PDU: - ssp_printf("resending metadata\n"); + ssp_printf("resending metadata transaction: %d\n", req->transaction_sequence_number); req->procedure = sending_put_metadata; break; case EOF_PDU: - ssp_printf("resending eof\n"); + ssp_printf("resending eof transaction: %d\n", req->transaction_sequence_number); req->procedure = sending_eof; break; @@ -341,7 +341,7 @@ void user_request_handler(Response res, Request *req, Client* client) { switch (req->procedure) { case sending_eof: - ssp_printf("sending eof\n"); + ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); req->procedure = none; build_eof_packet(req->buff, start, req); req->local_entity->EOF_sent_indication = 1; @@ -354,20 +354,20 @@ void user_request_handler(Response res, Request *req, Client* client) { if (build_data_packet(req->buff, start, req->file, client->packet_len)) { req->procedure = sending_eof; - ssp_printf("sending data blast\n"); + ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); } ssp_sendto(res); break; case sending_put_metadata: - ssp_printf("sending metadata\n"); + ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(res, start, req); ssp_sendto(res); req->procedure = sending_data; break; case sending_finished: - ssp_printf("sending finished packet\n"); + ssp_printf("sending finished packet transaction: %d\n", req->transaction_sequence_number); build_ack(req->buff, start, FINISHED_PDU); ssp_sendto(res); req->resent_finished++; @@ -384,20 +384,19 @@ void user_request_handler(Response res, Request *req, Client* client) { ------------------------------------------------------------------------------*/ -static void reset_timeout(Request *req) { +static int reset_timeout(Request *req) { - uint8_t time = req->timeout++; - //ssp_printf("timeout %u for id: %u sequence: %u\n", time, req->dest_cfdp_id, req->transaction_sequence_number); - - ssp_printf("file sent, no other packets coming in, closing transaction %d\n", req->transaction_sequence_number); - - if (time >= TIMEOUT_BEFORE_CANCEL_REQUEST) { - if (req->procedure == none) { - req->procedure = clean_up; - return; + if (req->timeout++ >= TIMEOUT_BEFORE_CANCEL_REQUEST) { + ssp_printf("time to live ended, closing up request transaction: %d\n", req->transaction_sequence_number); + if (req->procedure != none) + ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); + else { + ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); } - ssp_printf("timeout, closing up request, request stopped early\n"); + req->procedure = clean_up; + return 1; } + return 0; } /* @@ -413,7 +412,8 @@ void on_server_time_out(Response res, Request *req) { if (req == NULL) return; - reset_timeout(req); + if (reset_timeout(req)) + return; if (req->procedure == none) return; @@ -425,13 +425,13 @@ void on_server_time_out(Response res, Request *req) { if (req->resent_finished == RESEND_FINISHED_TIMES) { req->procedure = none; - ssp_printf("file sent, closing request\n"); + ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); return; } //send request for metadata if (!req->local_entity->Metadata_recv_indication) { - ssp_printf("sending request for new metadata packet\n"); + ssp_printf("sending request for new metadata packet transaction: %d\n", req->transaction_sequence_number); build_nak_directive(req->buff, start, META_DATA_PDU); ssp_sendto(res); return; @@ -445,7 +445,7 @@ void on_server_time_out(Response res, Request *req) { //send missing NAKS if (req->file->missing_offsets->count > 0) { - ssp_printf("sending Nak data\n"); + ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); build_nak_packet(req->buff, start, req); ssp_sendto(res); return; @@ -453,7 +453,7 @@ void on_server_time_out(Response res, Request *req) { } else { if (req->file->eof_checksum == req->file->partial_checksum){ - ssp_printf("sending finsihed pdu\n"); + ssp_printf("sending finsihed pdu transaction: %d\n", req->transaction_sequence_number); build_finished_pdu(req->buff, start); ssp_sendto(res); req->resent_finished++; @@ -465,7 +465,7 @@ void on_server_time_out(Response res, Request *req) { } //received EOF, send back 3 eof ack packets if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { - ssp_printf("sending eof ack\n"); + ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); build_ack(req->buff, start, EOF_PDU); ssp_sendto(res); req->resent_eof++; @@ -493,6 +493,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ request_metadata(req, res); } write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); + ssp_printf("received data from transaction %d\n", req->transaction_sequence_number); return; } @@ -506,7 +507,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ break; req->procedure = sending_put_metadata; - ssp_printf("received metadata packet\n"); + ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); fill_request_pdu_metadata(&packet[packet_index], req); process_file_request_metadata(req); break; @@ -518,16 +519,16 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ if (!req->local_entity->Metadata_recv_indication) request_metadata(req, res); - ssp_printf("received eof packet\n"); + ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); process_pdu_eof(&packet[packet_index], req, res); break; case ACK_PDU: - ssp_printf("received Ack\n"); + ssp_printf("received Ack transaction: %d\n", req->transaction_sequence_number); Pdu_ack* ack_packet = (Pdu_ack *) &packet[packet_index]; if (ack_packet->directive_code == FINISHED_PDU) { - ssp_printf("received finished packet\n"); + ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); req->local_entity->transaction_finished_indication = 1; } break; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index dc37709..25c8175 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -78,11 +78,11 @@ static int remove_request(void *request, void *args) { static void remove_request_check(void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; - if (req->procedure == clean_up) { - ssp_printf("CLEANINGUP request count: %d procedure:%d cleanup %d none: %d sending_put_metadata %d\n", req_list->count, req->procedure, clean_up, none, sending_put_metadata); + //ssp_printf("CLEANINGUP request count: %d procedure:%d cleanup %d none: %d sending_put_metadata %d\n", req_list->count, req->procedure, clean_up, none, sending_put_metadata); + + if (req->procedure == clean_up) { Request *remove_this = req_list->remove(req_list, 0, remove_request, req); ssp_cleanup_req(remove_this); - //ssp_printf("CLEANINGUP request count: %d\n", req_list->count); } } From 8750b5a1bb7a8178055c3d51797440cc67eac4e2 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 20 Aug 2019 16:43:03 -0600 Subject: [PATCH 082/400] No issue, I was just sending it in fucking connectionless mode --- Program/src/main.c | 2 +- Program/src/protocol_handler.c | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index 983e086..c12971a 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -51,7 +51,7 @@ int main(int argc, char** argv) { //send via acknoleged mode //0 acknowledged, 1 unacknowledged if (conf->my_cfdp_id == 2) { - put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); } if (conf->my_cfdp_id == 3) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 5d5c510..a20fa67 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -408,10 +408,8 @@ static void print_offsets(void *element, void *args) { */ void on_server_time_out(Response res, Request *req) { - - if (req == NULL) - return; - + + if (reset_timeout(req)) return; @@ -442,6 +440,13 @@ void on_server_time_out(Response res, Request *req) { build_nak_directive(req->buff, start, EOF_PDU); ssp_sendto(res); } + //received EOF, send back 3 eof ack packets + if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { + ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); + build_ack(req->buff, start, EOF_PDU); + ssp_sendto(res); + req->resent_eof++; + } //send missing NAKS if (req->file->missing_offsets->count > 0) { @@ -463,13 +468,7 @@ void on_server_time_out(Response res, Request *req) { ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); } } - //received EOF, send back 3 eof ack packets - if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { - ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); - build_ack(req->buff, start, EOF_PDU); - ssp_sendto(res); - req->resent_eof++; - } + } //fills the current_request struct for the server, incomming requests @@ -514,7 +513,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ case EOF_PDU: if (req->local_entity->EOF_recv_indication) - break;; + break; if (!req->local_entity->Metadata_recv_indication) request_metadata(req, res); From 0ad85e03b651f1b92cd004e7342f590f14ff59c9 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 20 Aug 2019 16:48:45 -0600 Subject: [PATCH 083/400] up to date, push tis --- Program/src/protocol_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index a20fa67..2f9cb57 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -492,7 +492,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ request_metadata(req, res); } write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); - ssp_printf("received data from transaction %d\n", req->transaction_sequence_number); + //ssp_printf("received data from transaction %d\n", req->transaction_sequence_number); return; } From 25119404a7ff8d9e460d56d2c6498d0715c732a4 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 24 Aug 2019 11:42:34 -0600 Subject: [PATCH 084/400] moves some names around --- Program/include/server.h | 2 +- Program/src/server.c | 28 +++++++++++++++------------- Program/src/tasks.c | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Program/include/server.h b/Program/include/server.h index b36fa9f..308b98d 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -61,7 +61,7 @@ void connectionless_server(char* port, int initial_buff_size, int *prepareSignalHandler(void); -void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), diff --git a/Program/src/server.c b/Program/src/server.c index 228b9d6..e5547b7 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -172,6 +172,9 @@ void connectionless_server(char* port, int initial_buff_size, client = calloc(sizeof(struct sockaddr_storage), 1); checkAlloc(client, 1); + size_t size_of_addr = sizeof(struct sockaddr); + socklen_t client_len = sizeof(*client); + for (;;) { @@ -212,18 +215,17 @@ void connectionless_server(char* port, int initial_buff_size, //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html // good article! if (FD_ISSET(sfd, &readFds)) { - - socklen_t client_len = sizeof(*client); + int count = recvfrom(sfd, buff, *buff_size, 0, (void *) client, &client_len); if (count == -1) { - perror("recv failed"); + perror("recv failed server"); } else if (count >= *buff_size) { printf("packet too large\n"); } else { - if (onRecv(sfd, buff, count, buff_size, (void*) client, sizeof(struct sockaddr), other) == -1) + if (onRecv(sfd, buff, count, buff_size, (void*) client, size_of_addr, other) == -1) printf("recv failed\n"); } } @@ -239,7 +241,7 @@ void connectionless_server(char* port, int initial_buff_size, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), @@ -282,6 +284,9 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo serveraddr.sin_port = htons(port_val); serverlen = sizeof(serveraddr); + + size_t size_of_addr = sizeof(struct sockaddr); + for (;;) { if (exit_now || checkExit(checkExitParams)) @@ -297,18 +302,15 @@ void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, vo count = recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, (struct sockaddr*)&serveraddr, &serverlen); - if (count == -1) - { - //perror("recv failed"); + if (count == -1){ + //perror("recv failed client"); } - else if (count >= *buff_size) - { + else if (count >= *buff_size){ printf("packet too large\n"); continue; } - else - { - if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, sizeof(struct sockaddr), onRecvParams) == -1) + else{ + if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr, onRecvParams) == -1) printf("recv failed\n"); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 25c8175..7e1edfe 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -245,7 +245,7 @@ void *ssp_connectionless_client_task(void* params){ inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); #ifdef POSIX_PORT - udpClient(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + connectionless_client(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); #endif return NULL; } From d0444b5cfa5488cd1e9010cc783db31cdf797bdc Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 24 Aug 2019 12:48:53 -0600 Subject: [PATCH 085/400] recvfrom wrapper --- Program/include/port.h | 3 +++ Program/include/types.h | 1 + Program/src/port.c | 11 +++++++++++ Program/src/server.c | 15 ++++++++------- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 6495c0d..4ffc035 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -18,6 +18,9 @@ void ssp_printf(char *stuff, ...); Request *init_request(uint32_t buff_len); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); + +int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t server_addr_len); + void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); int ssp_open(char *pathname, int flags); diff --git a/Program/include/types.h b/Program/include/types.h index c4f8542..1ff5a9f 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -472,6 +472,7 @@ typedef struct response { char *msg; //this is type (struct sockaddr_in) in posix void *addr; + //getting rid of this soon in favour of client based packet sizes size_t size_of_addr; diff --git a/Program/src/port.c b/Program/src/port.c index 1e974b9..fb1d8d6 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -84,6 +84,17 @@ void ssp_sendto(Response res) { #endif } + +int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t server_addr_len) { + int count = 0; + #ifdef POSIX_PORT + count = recvfrom(sfd, buff, packet_len, flags, (struct sockaddr*)server_addr, (socklen_t*)&server_addr_len); + #endif + + return count; +} + + /*------------------------------------------------------------------------------ Std lib functions, for custom memory allocation, and stdio ------------------------------------------------------------------------------*/ diff --git a/Program/src/server.c b/Program/src/server.c index e5547b7..8bad939 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -32,6 +32,9 @@ This is my file for server.c. It develops a udp server for select. #include #include + +#include "port.h" + static int exit_now; @@ -173,8 +176,6 @@ void connectionless_server(char* port, int initial_buff_size, checkAlloc(client, 1); size_t size_of_addr = sizeof(struct sockaddr); - socklen_t client_len = sizeof(*client); - for (;;) { @@ -216,8 +217,9 @@ void connectionless_server(char* port, int initial_buff_size, // good article! if (FD_ISSET(sfd, &readFds)) { - int count = recvfrom(sfd, buff, *buff_size, 0, (void *) client, &client_len); - + //int count = recvfrom(sfd, buff, *buff_size, 0, (void *) client, &size_of_addr); + int count = ssp_recvfrom(sfd, buff, *buff_size, 0, (void *) client, size_of_addr); + if (count == -1) { perror("recv failed server"); } @@ -299,9 +301,8 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe if (onSend(sfd, serveraddr, onSendParams)) printf("send failed\n"); - - count = recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, (struct sockaddr*)&serveraddr, &serverlen); - + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, &serveraddr, serverlen); + if (count == -1){ //perror("recv failed client"); } From c4bfd67f9b6b3744623479e11783b15461ce07c5 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 24 Aug 2019 15:52:56 -0600 Subject: [PATCH 086/400] Moved FD stuff into port --- Program/include/port.h | 8 ++++++++ Program/src/port.c | 33 ++++++++++++++++++++++++++++++++- Program/src/server.c | 26 ++++++++++++++++++-------- 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 4ffc035..4399b16 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -32,6 +32,14 @@ int ssp_close(int fd); void ssp_free(void *pointer); void ssp_thread_join(void *thread_handle); + +//network stuff +void ssp_fd_zero(void *socket_set); +void ssp_fd_set(int sfd, void *socket_set); +int ssp_fd_is_set(int sfd, void *socket_set); +void *ssp_init_socket_set(); + + int ssp_rename(const char *old, const char *new); void reset_request(Request *req); diff --git a/Program/src/port.c b/Program/src/port.c index fb1d8d6..2f8be60 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -18,6 +18,7 @@ #include #include #include + #include #endif #include "types.h" @@ -84,7 +85,6 @@ void ssp_sendto(Response res) { #endif } - int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t server_addr_len) { int count = 0; #ifdef POSIX_PORT @@ -95,6 +95,37 @@ int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server } +void *ssp_init_socket_set() { + + #ifdef POSIX_PORT + fd_set *socket_set = ssp_alloc(1, sizeof(fd_set)); + #endif + return (void *)socket_set; +} + + + +void ssp_fd_zero(void *socket_set){ + #ifdef POSIX_PORT + FD_ZERO((fd_set*) socket_set); + #endif +} + +void ssp_fd_set(int sfd, void *socket_set) { + #ifdef POSIX_PORT + FD_SET(sfd, (fd_set*) socket_set); + #endif +} + +int ssp_fd_is_set(int sfd, void *socket_set){ + int is_set = 0; + #ifdef POSIX_PORT + is_set = FD_ISSET(sfd, (fd_set*) socket_set); + + #endif + return is_set; +} + /*------------------------------------------------------------------------------ Std lib functions, for custom memory allocation, and stdio ------------------------------------------------------------------------------*/ diff --git a/Program/src/server.c b/Program/src/server.c index 8bad939..dd352c3 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -156,10 +156,17 @@ void connectionless_server(char* port, int initial_buff_size, { int sfd = prepareUdpHost(port); - fd_set masterReadFds; - FD_ZERO(&masterReadFds); - FD_SET(STDIN_FILENO, &masterReadFds); - FD_SET(sfd, &masterReadFds); + //fd_set masterReadFds; + + void *socket_set = ssp_init_socket_set(); + + ssp_fd_zero(socket_set); + ssp_fd_set(sfd, socket_set); + ssp_fd_set(STDIN_FILENO, socket_set); + + //FD_ZERO(&masterReadFds); + //FD_SET(STDIN_FILENO, &masterReadFds); + //FD_SET(sfd, &masterReadFds); uint32_t *buff_size = calloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); @@ -184,8 +191,10 @@ void connectionless_server(char* port, int initial_buff_size, .tv_usec = 100e3, }; - fd_set readFds = masterReadFds; - int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); + fd_set readFds = *((fd_set*) socket_set); + + //int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); + int nrdy = select(sfd + 1, (fd_set*)socket_set, NULL, NULL, &timeout); if (exit_now || checkExit(other)){ @@ -208,14 +217,14 @@ void connectionless_server(char* port, int initial_buff_size, continue; } - if (FD_ISSET(STDIN_FILENO, &readFds)) { + if (ssp_fd_is_set(STDIN_FILENO, &readFds)) { onStdIn(other); continue; } //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html // good article! - if (FD_ISSET(sfd, &readFds)) { + if (ssp_fd_is_set(sfd, &readFds)) { //int count = recvfrom(sfd, buff, *buff_size, 0, (void *) client, &size_of_addr); int count = ssp_recvfrom(sfd, buff, *buff_size, 0, (void *) client, size_of_addr); @@ -232,6 +241,7 @@ void connectionless_server(char* port, int initial_buff_size, } } } + ssp_free(socket_set); free(buff_size); free(client); free(buff); From 2fd557ad6608011e48649fcf2cb41df5bf4ef14f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 25 Aug 2019 15:57:16 -0600 Subject: [PATCH 087/400] switching to ported verion of select call and associated utils --- Program/include/port.h | 4 ++-- Program/src/port.c | 21 +++++++++++++++++++-- Program/src/server.c | 17 +++++++++++++---- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 4399b16..2e6d665 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -37,8 +37,8 @@ void ssp_thread_join(void *thread_handle); void ssp_fd_zero(void *socket_set); void ssp_fd_set(int sfd, void *socket_set); int ssp_fd_is_set(int sfd, void *socket_set); -void *ssp_init_socket_set(); - +void *ssp_init_socket_set(size_t *size); +int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec); int ssp_rename(const char *old, const char *new); void reset_request(Request *req); diff --git a/Program/src/port.c b/Program/src/port.c index 2f8be60..e9bc98e 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -95,16 +95,16 @@ int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server } -void *ssp_init_socket_set() { +void *ssp_init_socket_set(size_t *size) { #ifdef POSIX_PORT fd_set *socket_set = ssp_alloc(1, sizeof(fd_set)); + *size = sizeof(fd_set); #endif return (void *)socket_set; } - void ssp_fd_zero(void *socket_set){ #ifdef POSIX_PORT FD_ZERO((fd_set*) socket_set); @@ -126,6 +126,23 @@ int ssp_fd_is_set(int sfd, void *socket_set){ return is_set; } +int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec) { + + #ifdef POSIX_PORT + + struct timeval timeout = { + .tv_sec = 0, + //.tv_usec = 100e3, + .tv_usec = timeout_in_usec + }; + + int nrdy = select(sfd + 1, read_socket_set, write_socket_set, restrict_socket_set, &timeout); + #endif + + return nrdy; +} + + /*------------------------------------------------------------------------------ Std lib functions, for custom memory allocation, and stdio ------------------------------------------------------------------------------*/ diff --git a/Program/src/server.c b/Program/src/server.c index dd352c3..e41c955 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -157,13 +157,18 @@ void connectionless_server(char* port, int initial_buff_size, int sfd = prepareUdpHost(port); //fd_set masterReadFds; + size_t size_of_socket_struct[1]; + *size_of_socket_struct = 0; - void *socket_set = ssp_init_socket_set(); + void *socket_set = ssp_init_socket_set(size_of_socket_struct); + void *read_socket_set = ssp_init_socket_set(size_of_socket_struct); ssp_fd_zero(socket_set); ssp_fd_set(sfd, socket_set); ssp_fd_set(STDIN_FILENO, socket_set); + + //FD_ZERO(&masterReadFds); //FD_SET(STDIN_FILENO, &masterReadFds); //FD_SET(sfd, &masterReadFds); @@ -172,7 +177,6 @@ void connectionless_server(char* port, int initial_buff_size, checkAlloc(buff_size, 1); *buff_size = initial_buff_size + 10; - uint32_t prev_buff_size = *buff_size; char *buff = calloc(sizeof(char), *buff_size); @@ -186,16 +190,20 @@ void connectionless_server(char* port, int initial_buff_size, for (;;) { + /* struct timeval timeout = { .tv_sec = 0, .tv_usec = 100e3, }; + */ fd_set readFds = *((fd_set*) socket_set); - //int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); - int nrdy = select(sfd + 1, (fd_set*)socket_set, NULL, NULL, &timeout); + //memset(read_socket_set, 0, *size_of_socket_struct); + memcpy(read_socket_set, socket_set, *size_of_socket_struct); + //int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); + int nrdy = ssp_select(sfd, &readFds, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ printf("exiting server thread\n"); @@ -241,6 +249,7 @@ void connectionless_server(char* port, int initial_buff_size, } } } + ssp_free(read_socket_set); ssp_free(socket_set); free(buff_size); free(client); From 791a8a4cc7020c83cd00af54e82463f3f0ad1079 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 25 Aug 2019 16:25:06 -0600 Subject: [PATCH 088/400] set up connectionless_server for RTOS port --- Program/include/port.h | 2 ++ Program/src/port.c | 11 ++++++++++- Program/src/server.c | 44 ++++++++++++------------------------------ 3 files changed, 24 insertions(+), 33 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 2e6d665..1ec4ebf 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -39,6 +39,8 @@ void ssp_fd_set(int sfd, void *socket_set); int ssp_fd_is_set(int sfd, void *socket_set); void *ssp_init_socket_set(size_t *size); int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec); +void *ssp_init_sockaddr_struct(size_t *size_of_addr); + int ssp_rename(const char *old, const char *new); void reset_request(Request *req); diff --git a/Program/src/port.c b/Program/src/port.c index e9bc98e..98c2f09 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -94,7 +94,6 @@ int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server return count; } - void *ssp_init_socket_set(size_t *size) { #ifdef POSIX_PORT @@ -142,6 +141,16 @@ int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *res return nrdy; } +void *ssp_init_sockaddr_struct(size_t *size_of_addr) { + + #ifdef POSIX_PORT + *size_of_addr = sizeof(struct sockaddr_storage); + void *addr = calloc(sizeof(struct sockaddr_storage), 1); + checkAlloc(addr, 1); + + #endif + return addr; +} /*------------------------------------------------------------------------------ Std lib functions, for custom memory allocation, and stdio diff --git a/Program/src/server.c b/Program/src/server.c index e41c955..7c99926 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -156,7 +156,6 @@ void connectionless_server(char* port, int initial_buff_size, { int sfd = prepareUdpHost(port); - //fd_set masterReadFds; size_t size_of_socket_struct[1]; *size_of_socket_struct = 0; @@ -167,12 +166,6 @@ void connectionless_server(char* port, int initial_buff_size, ssp_fd_set(sfd, socket_set); ssp_fd_set(STDIN_FILENO, socket_set); - - - //FD_ZERO(&masterReadFds); - //FD_SET(STDIN_FILENO, &masterReadFds); - //FD_SET(sfd, &masterReadFds); - uint32_t *buff_size = calloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); @@ -182,28 +175,16 @@ void connectionless_server(char* port, int initial_buff_size, char *buff = calloc(sizeof(char), *buff_size); checkAlloc(buff, 1); - struct sockaddr_storage *client; - client = calloc(sizeof(struct sockaddr_storage), 1); - checkAlloc(client, 1); + size_t size_of_addr[1]; + *size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct(size_of_addr); - size_t size_of_addr = sizeof(struct sockaddr); for (;;) { - /* - struct timeval timeout = { - .tv_sec = 0, - .tv_usec = 100e3, - }; - */ - fd_set readFds = *((fd_set*) socket_set); - - //memset(read_socket_set, 0, *size_of_socket_struct); - memcpy(read_socket_set, socket_set, *size_of_socket_struct); - - //int nrdy = select(sfd + 1, &readFds, NULL, NULL, &timeout); - int nrdy = ssp_select(sfd, &readFds, NULL, NULL, 100e3); + memcpy(read_socket_set, socket_set, size_of_socket_struct[0]); + int nrdy = ssp_select(sfd, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ printf("exiting server thread\n"); @@ -225,17 +206,16 @@ void connectionless_server(char* port, int initial_buff_size, continue; } - if (ssp_fd_is_set(STDIN_FILENO, &readFds)) { + if (ssp_fd_is_set(STDIN_FILENO, read_socket_set)) { onStdIn(other); continue; } //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html // good article! - if (ssp_fd_is_set(sfd, &readFds)) { + if (ssp_fd_is_set(sfd, read_socket_set)) { - //int count = recvfrom(sfd, buff, *buff_size, 0, (void *) client, &size_of_addr); - int count = ssp_recvfrom(sfd, buff, *buff_size, 0, (void *) client, size_of_addr); + int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr[0]); if (count == -1) { perror("recv failed server"); @@ -244,16 +224,16 @@ void connectionless_server(char* port, int initial_buff_size, printf("packet too large\n"); } else { - if (onRecv(sfd, buff, count, buff_size, (void*) client, size_of_addr, other) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], other) == -1) printf("recv failed\n"); } } } + ssp_free(addr); ssp_free(read_socket_set); ssp_free(socket_set); - free(buff_size); - free(client); - free(buff); + ssp_free(buff_size); + ssp_free(buff); close(sfd); onExit(other); } From 4ebc52305ed24e4b0b43a17672acf1e152516339 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 29 Aug 2019 14:16:01 -0600 Subject: [PATCH 089/400] making a connection server --- Program/include/file_delivery_app.h | 3 +- Program/include/server.h | 8 +- Program/include/tasks.h | 4 + Program/src/file_delivery_app.c | 7 ++ Program/src/server.c | 125 +++++++++++++++++++++----- Program/src/tasks.c | 25 +++--- Program/test/main.c | 22 +++-- Program/test/makefile | 14 +-- Program/test/protocol_handler_tests.c | 6 +- Program/test/server_tests.c | 21 +++++ Program/test/server_tests.h | 6 ++ 11 files changed, 190 insertions(+), 51 deletions(-) create mode 100644 Program/test/server_tests.c create mode 100644 Program/test/server_tests.h diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 371ab1a..33d2ac6 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -9,5 +9,6 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address); void ssp_connectionless_server(Protocol_state *p_state); Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); - +void ssp_connection_server(Protocol_state *p_state); +void ssp_connection_client(); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index 308b98d..9d1cb7f 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -14,10 +14,12 @@ This file is the header file for server.c /*------------------------------------------------------------------------------ Purpose: This function creates a host server on the specified port on localhost - Perameters: char *port is the port number you want to run the host on + Perameters: char *port is the port number you want to run the host on, conn_type + is either 0 for udp, or 1 for tcp Return: It returns a socket descriptor to a UDP ready port ------------------------------------------------------------------------------*/ -int prepareUdpHost(char *port); +int prepareHost(char *port, int conn_typ); + /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. @@ -50,6 +52,8 @@ void connectionless_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other); +void connection_server(char *port); +void connection_client(uint16_t port); /*-----------------------------CALLBACK onTimeOut------------------------------- Purpose: This is a simple udp client Perameters: hostname is the name of an address eg, 127.0.0.1, port is the por diff --git a/Program/include/tasks.h b/Program/include/tasks.h index a2a0e1e..62d1a76 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -9,4 +9,8 @@ void ssp_cleanup_req(void *request); void ssp_cleanup_p_state(Protocol_state *p_state); void *ssp_connectionless_server_task(void *params); void *ssp_connectionless_client_task(void* params); + +void *ssp_connection_client_task(void *params); +void *ssp_connection_server_task(void *params); + #endif \ No newline at end of file diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 7c6f25b..19478f8 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -58,7 +58,14 @@ void ssp_connectionless_server(Protocol_state *p_state) { p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); } +void ssp_connection_server(Protocol_state *p_state) { + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server, p_state); +} + +void ssp_connection_client() { + ssp_thread_create(STACK_ALLOCATION, ssp_connection_client, NULL); +} Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { diff --git a/Program/src/server.c b/Program/src/server.c index 7c99926..3c2c6ae 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -31,24 +31,24 @@ This is my file for server.c. It develops a udp server for select. #include #include #include - - +#include #include "port.h" static int exit_now; - - -//this code is reused from assignment 1, with small changes -//see header file -int prepareUdpHost(char *port) + +//if conn_typ == 1, tcp, if 0 udp +int prepareHost(char *port, int conn_typ) { struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_flags = AI_V4MAPPED; - hints.ai_socktype = SOCK_DGRAM; - + if (conn_typ == 0) + hints.ai_socktype = SOCK_DGRAM; + else + hints.ai_socktype = SOCK_STREAM; + int err = getaddrinfo(NULL, port, &hints, &res); if (err != 0) @@ -71,18 +71,18 @@ int prepareUdpHost(char *port) int val = 1; err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - err = bind(sfd, cur->ai_addr, cur->ai_addrlen); if (err == -1) { - perror("bind"); + perror("set sock opt"); close(sfd); continue; } + err = bind(sfd, cur->ai_addr, cur->ai_addrlen); if (err == -1) { - perror("listen"); + perror("bind"); close(sfd); continue; } @@ -145,6 +145,89 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf return 1; } +void connection_client(uint16_t port) { + + int sockfd, connfd; + struct sockaddr_in servaddr, cli; + + // socket create and varification + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + printf("socket creation failed...\n"); + exit(0); + } + else + printf("Socket successfully created..\n"); + bzero(&servaddr, sizeof(servaddr)); + + // assign IP, PORT + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + servaddr.sin_port = htons(port); + + // connect the client socket to server socket + if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { + printf("connection with the server failed...\n"); + exit(0); + } + else + printf("connected to the server..\n"); + + // function for chat + char buff[1000]; + int n; + + for (;;) { + bzero(buff, sizeof(buff)); + printf("Enter the string : "); + n = 0; + while ((buff[n++] = getchar()) != '\n'); + write(sockfd, buff, sizeof(buff)); + bzero(buff, sizeof(buff)); + + read(sockfd, buff, sizeof(buff)); + + + printf("From Server : %s", buff); + if ((strncmp(buff, "exit", 4)) == 0) { + printf("Client Exit...\n"); + break; + } + } + // close the socket + close(sockfd); + +} + +void connection_server(char *port) { + + int listenfd = 0, connfd = 0; + struct sockaddr_in serv_addr; + + + char sendBuff[1025]; + time_t ticks; + + listenfd = prepareHost("1111", 1); + + listen(listenfd, 10); + + while(1) + { + connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); + + ticks = time(NULL); + snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks)); + write(connfd, sendBuff, strlen(sendBuff)); + + close(connfd); + sleep(1); + } + +} + + + //see header file void connectionless_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), @@ -154,7 +237,7 @@ void connectionless_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other) { - int sfd = prepareUdpHost(port); + int sfd = prepareHost(port, 0); size_t size_of_socket_struct[1]; *size_of_socket_struct = 0; @@ -166,13 +249,13 @@ void connectionless_server(char* port, int initial_buff_size, ssp_fd_set(sfd, socket_set); ssp_fd_set(STDIN_FILENO, socket_set); - uint32_t *buff_size = calloc(1, sizeof(uint32_t)); + uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); *buff_size = initial_buff_size + 10; uint32_t prev_buff_size = *buff_size; - char *buff = calloc(sizeof(char), *buff_size); + char *buff = ssp_alloc(sizeof(char), *buff_size); checkAlloc(buff, 1); size_t size_of_addr[1]; @@ -254,18 +337,17 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe struct sockaddr_in serveraddr; struct hostent *server; - uint32_t *buff_size = malloc(sizeof(uint32_t)); + uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); *buff_size = packet_len + 10; uint32_t prev_buff_size = *buff_size; - char *buff = calloc(sizeof(char), prev_buff_size); + char *buff = ssp_alloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); - prepareSignalHandler(); - +//-------------------------------------------------------------- sfd = socket(AF_INET, SOCK_DGRAM, 0); if (sfd < 0) perror("ERROR opening socket"); @@ -284,10 +366,11 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); serveraddr.sin_port = htons(port_val); serverlen = sizeof(serveraddr); - - + size_t size_of_addr = sizeof(struct sockaddr); +//-------------------------------------------------------------- + for (;;) { if (exit_now || checkExit(checkExitParams)) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 7e1edfe..798120d 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -223,10 +223,7 @@ void *ssp_connectionless_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; - - #ifdef POSIX_PORT - connectionless_server(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); - #endif + connectionless_server(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); return NULL; } @@ -238,18 +235,28 @@ void *ssp_connectionless_client_task(void* params){ char host_name[INET_ADDRSTRLEN]; char port[10]; + //convert int to char * snprintf(port, 10, "%d", client->remote_entity->UT_port); //convert uint id to char * inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); - #ifdef POSIX_PORT - connectionless_client(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); - #endif + connectionless_client(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + return NULL; } +void *ssp_connection_server_task(void *params) { + Protocol_state* p_state = (Protocol_state*) params; + connection_server("1111"); +} + + +void *ssp_connection_client_task(void *params) { + Client *client = (Client *) params; + connection_client(1111); +} /*------------------------------------------------------------------------------ @@ -259,17 +266,13 @@ void *ssp_connectionless_client_task(void* params){ ------------------------------------------------------------------------------*/ - - void ssp_cleanup_p_state(Protocol_state *p_state) { p_state->request_list->free(p_state->request_list, ssp_cleanup_req); free_mib(p_state->mib); ssp_free(p_state->server_port); ssp_free(p_state); - } - void ssp_cleanup_client(Client *client) { client->request_list->free(client->request_list, ssp_cleanup_req); ssp_cleanup_pdu_header(client->pdu_header); diff --git a/Program/test/main.c b/Program/test/main.c index 6b49b44..cf16514 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -7,25 +7,26 @@ #include #include #include -#include "filesystem_funcs.h" -#include "port.h" -#include "test.h" -#include "mib.h" + +/* #include "packet_tests.h" #include "filesystem_tests.h" #include "file_delivery_app.h" #include "protocol_handler_tests.h" #include "list_tests.h" +*/ +#include "server_tests.h" +/* Protocol_state *init_test() { Protocol_state *p_state = init_ftp(1); ssp_connectionless_server(p_state); ssp_cleanup_p_state(p_state); - } +*/ -int main () { +int main (int argc, char **argv) { //init_test(); @@ -40,8 +41,13 @@ int main () { //error = request_tests(); //error = protocol_handler_test(); //error = packet_tests(); - error = list_tests(); + //error = list_tests(); //error = file_system_tests(); - return 0; + + if (strcmp(argv[1], "1") == 0) + error = server_tests(0); + else + error = server_tests(1); + return error; } \ No newline at end of file diff --git a/Program/test/makefile b/Program/test/makefile index 35b582f..97a9480 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -12,17 +12,21 @@ CFILES += $(PROJDIR)/src/port.c CFILES += $(PROJDIR)/src/server.c CFILES += $(PROJDIR)/src/protocol_handler.c CFILES += $(PROJDIR)/src/mib.c +CFILES += $(PROJDIR)/src/requests.c +CFILES += $(PROJDIR)/src/tasks.c +CFILES += $(PROJDIR)/src/file_delivery_app.c +CFILES += $(PROJDIR)/src/list.c +CFILES += $(PROJDIR)/src/packet.c + CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c CFILES += $(PROJDIR)/test/request_tests.c CFILES += $(PROJDIR)/test/filesystem_tests.c CFILES += $(PROJDIR)/test/protocol_handler_tests.c - CFILES += $(PROJDIR)/test/list_tests.c -CFILES += $(PROJDIR)/src/requests.c -CFILES += $(PROJDIR)/src/tasks.c -CFILES += $(PROJDIR)/src/file_delivery_app.c -CFILES += $(PROJDIR)/src/list.c +CFILES += $(PROJDIR)/test/server_tests.c + + #entrypoint MAIN = main diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 1bf7bb0..0c1c49c 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -4,7 +4,7 @@ #include "stdlib.h" #include "mib.h" #include "test.h" - +#include "file_delivery_app.h" static char *build_mock_packet(Protocol_state *p_state, uint32_t id) { char *packet = calloc(sizeof(char*), 2000); @@ -29,13 +29,13 @@ static int test_process_pdu_header() { //test 1 char *packet = build_mock_packet(p_state, 2); - process_pdu_header(packet, res, req_container, p_state->request_list, p_state); + process_pdu_header(packet, 1, res, req_container, p_state->request_list, p_state); ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 2); //test 2 char *packet2 = build_mock_packet(p_state, 3); - process_pdu_header(packet2, res, req_container, p_state->request_list, p_state); + process_pdu_header(packet2, 1, res, req_container, p_state->request_list, p_state); ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); ASSERT_NOT_EQUALS_INT("souce id should not equal", (*req_container)->dest_cfdp_id, 2); ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 3); diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c new file mode 100644 index 0000000..9ee5cb8 --- /dev/null +++ b/Program/test/server_tests.c @@ -0,0 +1,21 @@ + +#include "server_tests.h" +#include +#include "server.h" +#include "port.h" +#include "tasks.h" + +int server_tests(int client){ + + printf("Hello server!\n"); + + if (client) + connection_client(1111); + else + connection_server("1111"); + + + + return 0; +} + diff --git a/Program/test/server_tests.h b/Program/test/server_tests.h new file mode 100644 index 0000000..64818b8 --- /dev/null +++ b/Program/test/server_tests.h @@ -0,0 +1,6 @@ +#ifndef SERVER_TESTS_H +#define SERVER_TESTS_H + +int server_tests(int client); + +#endif \ No newline at end of file From 72ffa18aa40f3cb5e6e91ffeb9bc188fee8c8bec Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 29 Aug 2019 19:27:50 -0600 Subject: [PATCH 090/400] making a proper tcp server --- Program/include/server.h | 10 ++- Program/src/server.c | 127 ++++++++++++++++++++++++++++++++++-- Program/src/tasks.c | 6 +- Program/test/server_tests.c | 28 +++++++- 4 files changed, 158 insertions(+), 13 deletions(-) diff --git a/Program/include/server.h b/Program/include/server.h index 9d1cb7f..f794989 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -52,7 +52,15 @@ void connectionless_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other); -void connection_server(char *port); +void connection_server(char* port, int initial_buff_size, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other); + + void connection_client(uint16_t port); /*-----------------------------CALLBACK onTimeOut------------------------------- Purpose: This is a simple udp client diff --git a/Program/src/server.c b/Program/src/server.c index 3c2c6ae..18cebdb 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -37,17 +37,22 @@ This is my file for server.c. It develops a udp server for select. static int exit_now; //if conn_typ == 1, tcp, if 0 udp -int prepareHost(char *port, int conn_typ) +int prepareHost(char *port, int conn_type) { struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_flags = AI_V4MAPPED; - if (conn_typ == 0) - hints.ai_socktype = SOCK_DGRAM; - else - hints.ai_socktype = SOCK_STREAM; + + switch (conn_type) { + + case 0: + hints.ai_socktype = SOCK_DGRAM; + break; + case 1: + hints.ai_socktype = SOCK_STREAM; + } int err = getaddrinfo(NULL, port, &hints, &res); @@ -199,6 +204,7 @@ void connection_client(uint16_t port) { } +/* void connection_server(char *port) { int listenfd = 0, connfd = 0; @@ -211,10 +217,11 @@ void connection_server(char *port) { listenfd = prepareHost("1111", 1); listen(listenfd, 10); + char buff[10000]; while(1) { - connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); + sfd = accept(listenfd, (struct sockaddr*)NULL, NULL); ticks = time(NULL); snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks)); @@ -225,6 +232,112 @@ void connection_server(char *port) { } } +*/ + +//see header file +void connection_server(char* port, int initial_buff_size, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other) +{ + int sfd = prepareHost(port, 1); + //----------------------------------------------------------------------- + int err = listen(sfd, 10); + + if (err == -1) + ssp_error("listen failed\n"); + + + //----------------------------------------------------------------------- + + size_t size_of_socket_struct[1]; + *size_of_socket_struct = 0; + + void *socket_set = ssp_init_socket_set(size_of_socket_struct); + void *read_socket_set = ssp_init_socket_set(size_of_socket_struct); + + ssp_fd_zero(socket_set); + ssp_fd_set(sfd, socket_set); + ssp_fd_set(STDIN_FILENO, socket_set); + + uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); + checkAlloc(buff_size, 1); + + *buff_size = initial_buff_size + 10; + uint32_t prev_buff_size = *buff_size; + + char *buff = ssp_alloc(sizeof(char), *buff_size); + checkAlloc(buff, 1); + + size_t size_of_addr[1]; + *size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct(size_of_addr); + + + for (;;) + { + + memcpy(read_socket_set, socket_set, size_of_socket_struct[0]); + int nrdy = ssp_select(sfd, read_socket_set, NULL, NULL, 100e3); + + if (exit_now || checkExit(other)){ + printf("exiting server thread\n"); + break; + } + + if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ + printf("packet too large, cannot resize buffer\n"); + } + + if (nrdy == -1) { + perror("select"); + continue; + } + //timeout + if (nrdy == 0) { + if (onTimeOut(other) == -1) + printf("timeout failed\n"); + continue; + } + + if (ssp_fd_is_set(STDIN_FILENO, read_socket_set)) { + onStdIn(other); + continue; + } + + //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html + // good article! + if (ssp_fd_is_set(sfd, read_socket_set)) { + + int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr[0]); + + if (count == -1) { + perror("recv failed server"); + } + else if (count >= *buff_size) { + printf("packet too large\n"); + } + else { + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], other) == -1) + printf("recv failed\n"); + } + } + } + ssp_free(addr); + ssp_free(read_socket_set); + ssp_free(socket_set); + ssp_free(buff_size); + ssp_free(buff); + close(sfd); + onExit(other); +} + + + + @@ -298,7 +411,7 @@ void connectionless_server(char* port, int initial_buff_size, // good article! if (ssp_fd_is_set(sfd, read_socket_set)) { - int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr[0]); + int count = ssp_recvfrom(sfd, buff, *buff_size, MSG_TRUNC, addr, size_of_addr[0]); if (count == -1) { perror("recv failed server"); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 798120d..f24487c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -249,13 +249,15 @@ void *ssp_connectionless_client_task(void* params){ void *ssp_connection_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; - connection_server("1111"); + connection_server(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + return NULL; } void *ssp_connection_client_task(void *params) { - Client *client = (Client *) params; + //Client *client = (Client *) params; connection_client(1111); + return NULL; } diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 9ee5cb8..3cb4fda 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -5,16 +5,38 @@ #include "port.h" #include "tasks.h" + +int onRecv(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ + printf("hello!\n"); + ssp_write(sfd, "hello!\n", 8); + return 0; +} + +int onTimeOut(void *other) { + return 0; +} +int onStdIn(void *other){ + return 0; +} +int checkExit(void *other) { + return 0; +} +void onExit(void *other) { +} + + + int server_tests(int client){ + int buffsize = 10000; + char buff[buffsize]; + printf("Hello server!\n"); if (client) connection_client(1111); else - connection_server("1111"); - - + connection_server("1111", buffsize, onRecv, onTimeOut, onStdIn, checkExit, onExit, NULL); return 0; } From cb90fd710604d4d2750e08079cadc7b8327ca091 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 2 Sep 2019 13:17:03 -0600 Subject: [PATCH 091/400] tcp server works --- Program/src/server.c | 80 ++++++++++++++++++++----------------- Program/test/server_tests.c | 20 +++++++--- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/Program/src/server.c b/Program/src/server.c index 18cebdb..525987c 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -184,14 +184,14 @@ void connection_client(uint16_t port) { for (;;) { bzero(buff, sizeof(buff)); - printf("Enter the string : "); - n = 0; - while ((buff[n++] = getchar()) != '\n'); - write(sockfd, buff, sizeof(buff)); - bzero(buff, sizeof(buff)); + printf("sending Hello server? \n"); + strncpy(buff, "Hello server?", 15); + n = 0; - read(sockfd, buff, sizeof(buff)); + sendto(sockfd, buff, 600, 0, (struct sockaddr *)&servaddr, sizeof(servaddr) ); + bzero(buff, 1000); + read(sockfd, buff, sizeof(buff)); printf("From Server : %s", buff); if ((strncmp(buff, "exit", 4)) == 0) { @@ -244,14 +244,10 @@ void connection_server(char* port, int initial_buff_size, void *other) { int sfd = prepareHost(port, 1); - //----------------------------------------------------------------------- int err = listen(sfd, 10); if (err == -1) ssp_error("listen failed\n"); - - - //----------------------------------------------------------------------- size_t size_of_socket_struct[1]; *size_of_socket_struct = 0; @@ -276,10 +272,9 @@ void connection_server(char* port, int initial_buff_size, *size_of_addr = 0; void *addr = ssp_init_sockaddr_struct(size_of_addr); - for (;;) { - + memcpy(read_socket_set, socket_set, size_of_socket_struct[0]); int nrdy = ssp_select(sfd, read_socket_set, NULL, NULL, 100e3); @@ -302,27 +297,42 @@ void connection_server(char* port, int initial_buff_size, printf("timeout failed\n"); continue; } - - if (ssp_fd_is_set(STDIN_FILENO, read_socket_set)) { - onStdIn(other); - continue; - } - - //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html - // good article! - if (ssp_fd_is_set(sfd, read_socket_set)) { - int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr[0]); - - if (count == -1) { - perror("recv failed server"); - } - else if (count >= *buff_size) { - printf("packet too large\n"); - } - else { - if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], other) == -1) - printf("recv failed\n"); + for(int i = 0; i < FD_SETSIZE; i++) { + //printf("looping?\n"); + if (ssp_fd_is_set(i, read_socket_set)) { + printf("receiving from socket %d!\n", i); + + if (i == STDIN_FILENO) { + onStdIn(other); + break; + } + + if (i == sfd) { + int new_socket = accept(i, (struct sockaddr*) addr, size_of_addr); + if (new_socket < 0) + ssp_error ("accept failed"); + + ssp_fd_set(new_socket, socket_set); + ssp_fd_set(new_socket, read_socket_set); + continue; + } + + int count = ssp_recvfrom(i, buff, *buff_size, MSG_TRUNC, NULL, NULL); + + if (count < 0) { + perror("recv failed server"); + close(i); + FD_CLR(i, (fd_set*) socket_set); + } + else if (count >= *buff_size) { + printf("packet too large %d\n", count); + } + else { + printf("reading\n"); + if (onRecv(i, buff, count, buff_size, addr, size_of_addr[0], other) == -1) + printf("recv failed\n"); + } } } } @@ -380,7 +390,7 @@ void connectionless_server(char* port, int initial_buff_size, { memcpy(read_socket_set, socket_set, size_of_socket_struct[0]); - int nrdy = ssp_select(sfd, read_socket_set, NULL, NULL, 100e3); + int nrdy = ssp_select(FD_SETSIZE, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ printf("exiting server thread\n"); @@ -395,7 +405,7 @@ void connectionless_server(char* port, int initial_buff_size, perror("select"); continue; } - //timeout + if (nrdy == 0) { if (onTimeOut(other) == -1) printf("timeout failed\n"); @@ -407,8 +417,6 @@ void connectionless_server(char* port, int initial_buff_size, continue; } - //http://www.microhowto.info/howto/listen_for_and_receive_udp_datagrams_in_c.html - // good article! if (ssp_fd_is_set(sfd, read_socket_set)) { int count = ssp_recvfrom(sfd, buff, *buff_size, MSG_TRUNC, addr, size_of_addr[0]); diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 3cb4fda..33a87d2 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -8,7 +8,14 @@ int onRecv(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ printf("hello!\n"); - ssp_write(sfd, "hello!\n", 8); + Response res; + res.addr = addr; + res.msg = "hello back!!\n"; + res.packet_len = *buff_size; + res.size_of_addr = size_of_addr; + res.sfd = sfd; + + ssp_sendto(res); return 0; } @@ -31,13 +38,16 @@ int server_tests(int client){ int buffsize = 10000; char buff[buffsize]; - printf("Hello server!\n"); - if (client) + if (client) { + printf("I'm a client!\n"); connection_client(1111); - else + } + else { + printf("I'm a server!\n"); connection_server("1111", buffsize, onRecv, onTimeOut, onStdIn, checkExit, onExit, NULL); - + } + return 0; } From 681d711922b574e192f66f4d062c686861811d68 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 2 Sep 2019 13:24:26 -0600 Subject: [PATCH 092/400] add last select FD port func --- Program/include/port.h | 1 + Program/src/port.c | 8 ++++++++ Program/src/server.c | 37 ++----------------------------------- 3 files changed, 11 insertions(+), 35 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 1ec4ebf..16277c4 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -40,6 +40,7 @@ int ssp_fd_is_set(int sfd, void *socket_set); void *ssp_init_socket_set(size_t *size); int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec); void *ssp_init_sockaddr_struct(size_t *size_of_addr); +void ssp_fd_clr(int sfd, void *socket_set); int ssp_rename(const char *old, const char *new); diff --git a/Program/src/port.c b/Program/src/port.c index 98c2f09..ce5bee1 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -125,6 +125,14 @@ int ssp_fd_is_set(int sfd, void *socket_set){ return is_set; } +void ssp_fd_clr(int sfd, void *socket_set) { + + #ifdef POSIX_PORT + FD_CLR(sfd, (fd_et *) socket_set); + + #endif +} + int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec) { #ifdef POSIX_PORT diff --git a/Program/src/server.c b/Program/src/server.c index 525987c..8fe2f78 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -204,36 +204,6 @@ void connection_client(uint16_t port) { } -/* -void connection_server(char *port) { - - int listenfd = 0, connfd = 0; - struct sockaddr_in serv_addr; - - - char sendBuff[1025]; - time_t ticks; - - listenfd = prepareHost("1111", 1); - - listen(listenfd, 10); - char buff[10000]; - - while(1) - { - sfd = accept(listenfd, (struct sockaddr*)NULL, NULL); - - ticks = time(NULL); - snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks)); - write(connfd, sendBuff, strlen(sendBuff)); - - close(connfd); - sleep(1); - } - -} -*/ - //see header file void connection_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), @@ -299,7 +269,7 @@ void connection_server(char* port, int initial_buff_size, } for(int i = 0; i < FD_SETSIZE; i++) { - //printf("looping?\n"); + if (ssp_fd_is_set(i, read_socket_set)) { printf("receiving from socket %d!\n", i); @@ -323,7 +293,7 @@ void connection_server(char* port, int initial_buff_size, if (count < 0) { perror("recv failed server"); close(i); - FD_CLR(i, (fd_set*) socket_set); + ssp_fd_clr(i, socket_set); } else if (count >= *buff_size) { printf("packet too large %d\n", count); @@ -348,9 +318,6 @@ void connection_server(char* port, int initial_buff_size, - - - //see header file void connectionless_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), From 63ee8e7520e120285d7c593f1ca7faeb9c2b39d3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 2 Sep 2019 14:05:50 -0600 Subject: [PATCH 093/400] testing servers, cant read//send --- Program/include/server.h | 7 +- Program/src/port.c | 2 +- Program/src/server.c | 202 +++++++++++++++++++++++++----------- Program/test/server_tests.c | 41 ++++++-- 4 files changed, 184 insertions(+), 68 deletions(-) diff --git a/Program/include/server.h b/Program/include/server.h index f794989..dd19681 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -60,7 +60,12 @@ void connection_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other); - +void connectioned_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, + int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params)); + void connection_client(uint16_t port); /*-----------------------------CALLBACK onTimeOut------------------------------- Purpose: This is a simple udp client diff --git a/Program/src/port.c b/Program/src/port.c index ce5bee1..22187bb 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -128,7 +128,7 @@ int ssp_fd_is_set(int sfd, void *socket_set){ void ssp_fd_clr(int sfd, void *socket_set) { #ifdef POSIX_PORT - FD_CLR(sfd, (fd_et *) socket_set); + FD_CLR(sfd, (fd_set *) socket_set); #endif } diff --git a/Program/src/server.c b/Program/src/server.c index 8fe2f78..1386099 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -149,61 +149,6 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf } return 1; } - -void connection_client(uint16_t port) { - - int sockfd, connfd; - struct sockaddr_in servaddr, cli; - - // socket create and varification - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == -1) { - printf("socket creation failed...\n"); - exit(0); - } - else - printf("Socket successfully created..\n"); - bzero(&servaddr, sizeof(servaddr)); - - // assign IP, PORT - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - servaddr.sin_port = htons(port); - - // connect the client socket to server socket - if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { - printf("connection with the server failed...\n"); - exit(0); - } - else - printf("connected to the server..\n"); - - // function for chat - char buff[1000]; - int n; - - for (;;) { - bzero(buff, sizeof(buff)); - printf("sending Hello server? \n"); - strncpy(buff, "Hello server?", 15); - n = 0; - - sendto(sockfd, buff, 600, 0, (struct sockaddr *)&servaddr, sizeof(servaddr) ); - bzero(buff, 1000); - - read(sockfd, buff, sizeof(buff)); - - printf("From Server : %s", buff); - if ((strncmp(buff, "exit", 4)) == 0) { - printf("Client Exit...\n"); - break; - } - } - // close the socket - close(sockfd); - -} - //see header file void connection_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), @@ -465,11 +410,11 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe break; if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ - printf("packet too large, cannot resize buffer\n"); + ssp_error("packet too large, cannot resize buffer\n"); } if (onSend(sfd, serveraddr, onSendParams)) - printf("send failed\n"); + ssp_error("send failed\n"); count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, &serveraddr, serverlen); @@ -477,12 +422,12 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe //perror("recv failed client"); } else if (count >= *buff_size){ - printf("packet too large\n"); + ssp_error("packet too large\n"); continue; } else{ if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr, onRecvParams) == -1) - printf("recv failed\n"); + ssp_error("recv failed\n"); } } @@ -494,3 +439,142 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe } + +void connection_client(uint16_t port) { + + int sockfd, connfd; + struct sockaddr_in servaddr, cli; + + // socket create and varification + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + printf("socket creation failed...\n"); + exit(0); + } + else + printf("Socket successfully created..\n"); + bzero(&servaddr, sizeof(servaddr)); + + // assign IP, PORT + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); + servaddr.sin_port = htons(port); + + // connect the client socket to server socket + if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { + printf("connection with the server failed...\n"); + exit(0); + } + else + printf("connected to the server..\n"); + + // function for chat + char buff[1000]; + int n; + + for (;;) { + bzero(buff, sizeof(buff)); + printf("sending Hello server? \n"); + strncpy(buff, "Hello server?", 15); + n = 0; + + sendto(sockfd, buff, 600, 0, (struct sockaddr *)&servaddr, sizeof(servaddr) ); + bzero(buff, 1000); + + read(sockfd, buff, sizeof(buff)); + + printf("From Server : %s", buff); + if ((strncmp(buff, "exit", 4)) == 0) { + printf("Client Exit...\n"); + break; + } + } + // close the socket + close(sockfd); + +} + +//https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c +void connectioned_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, + int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params)) +{ + + int sfd, count, port_val; + socklen_t serverlen; + struct sockaddr_in serveraddr; + struct hostent *server; + + uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); + checkAlloc(buff_size, 1); + + *buff_size = packet_len + 10; + + uint32_t prev_buff_size = *buff_size; + + char *buff = ssp_alloc(sizeof(char), prev_buff_size); + checkAlloc(buff, 1); + + sfd = socket(AF_INET, SOCK_STREAM, 0); + if (sfd < 0) + perror("ERROR opening socket"); + + port_val = atoi(port); + + server = gethostbyname(hostname); + if (server == NULL) { + fprintf(stderr,"ERROR, no such host as %s\n", hostname); + exit(0); + } + + bzero((char *) &serveraddr, sizeof(serveraddr)); + serveraddr.sin_family = AF_INET; + + bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); + serveraddr.sin_port = htons(port_val); + serverlen = sizeof(serveraddr); + + size_t size_of_addr = sizeof(struct sockaddr); + + if (connect(sfd, (struct sockaddr *)&serveraddr, size_of_addr) != 0) { + ssp_error("connection with the server failed...\n"); + exit_now = 1; + } + + + for (;;) { + + if (exit_now || checkExit(checkExitParams)) + break; + + if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ + printf("packet too large, cannot resize buffer\n"); + } + + if (onSend(sfd, serveraddr, onSendParams)) + ssp_error("send failed here\n"); + + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, NULL); + + if (count == -1){ + //ssp_error("recv failed client"); + } + else if (count >= *buff_size){ + ssp_error("packet too large\n"); + continue; + } + else{ + if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr, onRecvParams) == -1) + ssp_error("recv failed\n"); + } + + } + + printf("exiting loop\n"); + free(buff_size); + free(buff); + close(sfd); + onExit(onExitParams); +} \ No newline at end of file diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 33a87d2..3c5c343 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -6,7 +6,7 @@ #include "tasks.h" -int onRecv(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ +static int onRecv(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ printf("hello!\n"); Response res; res.addr = addr; @@ -14,24 +14,48 @@ int onRecv(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, voi res.packet_len = *buff_size; res.size_of_addr = size_of_addr; res.sfd = sfd; - + ssp_sendto(res); return 0; } -int onTimeOut(void *other) { +static int onTimeOut(void *other) { return 0; } -int onStdIn(void *other){ +static int onStdIn(void *other){ return 0; } -int checkExit(void *other) { +static int checkExit(void *other) { return 0; } -void onExit(void *other) { +static void onExit(void *other) { } +//client stuff +static int onSend(int sfd, struct sockaddr_in addr, void *onSendParams) { + Response res; + res.addr = &addr; + res.msg = "hello serer!!\n"; + res.packet_len = 12; + res.size_of_addr = sizeof(struct sockaddr_in); + res.sfd = sfd; + printf("sending msg\n"); + ssp_sendto(res); + return 0; +} +static int onRecvClient(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) { + printf("recv %s\n", packet); + return 0; +} + +static int checkExitClient(void *params) { + return 0; +} + +static void onExitClient(void *params) { + +} int server_tests(int client){ @@ -41,7 +65,10 @@ int server_tests(int client){ if (client) { printf("I'm a client!\n"); - connection_client(1111); + //connection_client(1111); + connectioned_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + + } else { printf("I'm a server!\n"); From f810df43c8364519a6e77eb336afbc1df5cc4c03 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 10 Sep 2019 14:00:29 -0600 Subject: [PATCH 094/400] connection server/client working update --- Program/include/port.h | 2 +- Program/include/server.h | 3 +- Program/src/port.c | 12 ++- Program/src/server.c | 148 ++++++++++++------------------------ Program/test/server_tests.c | 20 +++-- 5 files changed, 70 insertions(+), 115 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 16277c4..f08d28b 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -39,7 +39,7 @@ void ssp_fd_set(int sfd, void *socket_set); int ssp_fd_is_set(int sfd, void *socket_set); void *ssp_init_socket_set(size_t *size); int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec); -void *ssp_init_sockaddr_struct(size_t *size_of_addr); +void *ssp_init_sockaddr_struct(char *host_name, char port, size_t *size_of_addr); void ssp_fd_clr(int sfd, void *socket_set); diff --git a/Program/include/server.h b/Program/include/server.h index dd19681..4ee1227 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -60,13 +60,12 @@ void connection_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other); -void connectioned_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); -void connection_client(uint16_t port); /*-----------------------------CALLBACK onTimeOut------------------------------- Purpose: This is a simple udp client Perameters: hostname is the name of an address eg, 127.0.0.1, port is the por diff --git a/Program/src/port.c b/Program/src/port.c index 22187bb..a950800 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -149,17 +149,23 @@ int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *res return nrdy; } -void *ssp_init_sockaddr_struct(size_t *size_of_addr) { +void *ssp_init_sockaddr_struct(char *host_name, char port, size_t *size_of_addr) { #ifdef POSIX_PORT - *size_of_addr = sizeof(struct sockaddr_storage); - void *addr = calloc(sizeof(struct sockaddr_storage), 1); + //if (strncmp(host_name, "", 1) == 0) + + + + *size_of_addr = sizeof(struct sockaddr); + void *addr = calloc(sizeof(struct sockaddr), 1); checkAlloc(addr, 1); #endif return addr; } + + /*------------------------------------------------------------------------------ Std lib functions, for custom memory allocation, and stdio ------------------------------------------------------------------------------*/ diff --git a/Program/src/server.c b/Program/src/server.c index 1386099..da306bc 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -36,6 +36,7 @@ This is my file for server.c. It develops a udp server for select. static int exit_now; + //if conn_typ == 1, tcp, if 0 udp int prepareHost(char *port, int conn_type) { @@ -80,7 +81,7 @@ int prepareHost(char *port, int conn_type) if (err == -1) { perror("set sock opt"); - close(sfd); + ssp_close(sfd); continue; } @@ -88,7 +89,7 @@ int prepareHost(char *port, int conn_type) if (err == -1) { perror("bind"); - close(sfd); + ssp_close(sfd); continue; } @@ -185,7 +186,7 @@ void connection_server(char* port, int initial_buff_size, size_t size_of_addr[1]; *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(size_of_addr); + void *addr = ssp_init_sockaddr_struct("", port, size_of_addr); for (;;) { @@ -194,29 +195,29 @@ void connection_server(char* port, int initial_buff_size, int nrdy = ssp_select(sfd, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ - printf("exiting server thread\n"); + ssp_printf("exiting server thread\n"); break; } if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ - printf("packet too large, cannot resize buffer\n"); + ssp_printf("packet too large, cannot resize buffer\n"); } if (nrdy == -1) { - perror("select"); + ssp_error("select"); continue; } //timeout if (nrdy == 0) { if (onTimeOut(other) == -1) - printf("timeout failed\n"); + ssp_printf("timeout failed\n"); continue; } for(int i = 0; i < FD_SETSIZE; i++) { if (ssp_fd_is_set(i, read_socket_set)) { - printf("receiving from socket %d!\n", i); + ssp_printf("receiving from socket %d!\n", i); if (i == STDIN_FILENO) { onStdIn(other); @@ -233,20 +234,20 @@ void connection_server(char* port, int initial_buff_size, continue; } - int count = ssp_recvfrom(i, buff, *buff_size, MSG_TRUNC, NULL, NULL); + int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, NULL); if (count < 0) { - perror("recv failed server"); - close(i); + ssp_error("recv failed server"); + ssp_close(i); ssp_fd_clr(i, socket_set); } else if (count >= *buff_size) { - printf("packet too large %d\n", count); + ssp_printf("packet too large %d\n", count); } else { - printf("reading\n"); + ssp_printf("reading\n"); if (onRecv(i, buff, count, buff_size, addr, size_of_addr[0], other) == -1) - printf("recv failed\n"); + ssp_printf("recv failed\n"); } } } @@ -256,7 +257,7 @@ void connection_server(char* port, int initial_buff_size, ssp_free(socket_set); ssp_free(buff_size); ssp_free(buff); - close(sfd); + ssp_close(sfd); onExit(other); } @@ -295,7 +296,7 @@ void connectionless_server(char* port, int initial_buff_size, size_t size_of_addr[1]; *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(size_of_addr); + void *addr = ssp_init_sockaddr_struct("", port, size_of_addr); for (;;) @@ -305,22 +306,22 @@ void connectionless_server(char* port, int initial_buff_size, int nrdy = ssp_select(FD_SETSIZE, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ - printf("exiting server thread\n"); + ssp_printf("exiting server thread\n"); break; } if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ - printf("packet too large, cannot resize buffer\n"); + ssp_printf("packet too large, cannot resize buffer\n"); } if (nrdy == -1) { - perror("select"); + ssp_error("select"); continue; } if (nrdy == 0) { if (onTimeOut(other) == -1) - printf("timeout failed\n"); + ssp_printf("timeout failed\n"); continue; } @@ -334,14 +335,14 @@ void connectionless_server(char* port, int initial_buff_size, int count = ssp_recvfrom(sfd, buff, *buff_size, MSG_TRUNC, addr, size_of_addr[0]); if (count == -1) { - perror("recv failed server"); + ssp_error("recv failed server"); } else if (count >= *buff_size) { - printf("packet too large\n"); + ssp_printf("packet too large\n"); } else { if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], other) == -1) - printf("recv failed\n"); + ssp_printf("recv failed\n"); } } } @@ -350,7 +351,7 @@ void connectionless_server(char* port, int initial_buff_size, ssp_free(socket_set); ssp_free(buff_size); ssp_free(buff); - close(sfd); + ssp_close(sfd); onExit(other); } @@ -388,6 +389,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe port_val = atoi(port); server = gethostbyname(hostname); + if (server == NULL) { fprintf(stderr,"ERROR, no such host as %s\n", hostname); exit(0); @@ -398,9 +400,10 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); serveraddr.sin_port = htons(port_val); - serverlen = sizeof(serveraddr); - - size_t size_of_addr = sizeof(struct sockaddr); + + size_t size_of_addr[1]; + *size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct(hostname, port, size_of_addr); //-------------------------------------------------------------- @@ -416,17 +419,17 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe if (onSend(sfd, serveraddr, onSendParams)) ssp_error("send failed\n"); - count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, &serveraddr, serverlen); + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, &serveraddr, size_of_addr[0]); - if (count == -1){ - //perror("recv failed client"); - } + if (count == -1) + continue; + else if (count >= *buff_size){ ssp_error("packet too large\n"); continue; } else{ - if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr, onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr[0], onRecvParams) == -1) ssp_error("recv failed\n"); } @@ -434,68 +437,13 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe free(buff_size); free(buff); - close(sfd); + ssp_close(sfd); onExit(onExitParams); } - -void connection_client(uint16_t port) { - - int sockfd, connfd; - struct sockaddr_in servaddr, cli; - - // socket create and varification - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd == -1) { - printf("socket creation failed...\n"); - exit(0); - } - else - printf("Socket successfully created..\n"); - bzero(&servaddr, sizeof(servaddr)); - - // assign IP, PORT - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - servaddr.sin_port = htons(port); - - // connect the client socket to server socket - if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { - printf("connection with the server failed...\n"); - exit(0); - } - else - printf("connected to the server..\n"); - - // function for chat - char buff[1000]; - int n; - - for (;;) { - bzero(buff, sizeof(buff)); - printf("sending Hello server? \n"); - strncpy(buff, "Hello server?", 15); - n = 0; - - sendto(sockfd, buff, 600, 0, (struct sockaddr *)&servaddr, sizeof(servaddr) ); - bzero(buff, 1000); - - read(sockfd, buff, sizeof(buff)); - - printf("From Server : %s", buff); - if ((strncmp(buff, "exit", 4)) == 0) { - printf("Client Exit...\n"); - break; - } - } - // close the socket - close(sockfd); - -} - //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void connectioned_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), @@ -536,21 +484,25 @@ void connectioned_client(char *hostname, char*port, int packet_len, void *onSend serveraddr.sin_port = htons(port_val); serverlen = sizeof(serveraddr); - size_t size_of_addr = sizeof(struct sockaddr); + //size_t size_of_addr = sizeof(struct sockaddr); + + size_t size_of_addr[1]; + *size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct(hostname, port, size_of_addr); + - if (connect(sfd, (struct sockaddr *)&serveraddr, size_of_addr) != 0) { + if (connect(sfd, (struct sockaddr *)&serveraddr, size_of_addr[0]) != 0) { ssp_error("connection with the server failed...\n"); exit_now = 1; } - for (;;) { if (exit_now || checkExit(checkExitParams)) break; if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ - printf("packet too large, cannot resize buffer\n"); + ssp_printf("packet too large, cannot resize buffer\n"); } if (onSend(sfd, serveraddr, onSendParams)) @@ -558,15 +510,15 @@ void connectioned_client(char *hostname, char*port, int packet_len, void *onSend count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, NULL); - if (count == -1){ - //ssp_error("recv failed client"); - } + if (count == -1) + continue; + else if (count >= *buff_size){ ssp_error("packet too large\n"); continue; } else{ - if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr, onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr[0], onRecvParams) == -1) ssp_error("recv failed\n"); } @@ -575,6 +527,6 @@ void connectioned_client(char *hostname, char*port, int packet_len, void *onSend printf("exiting loop\n"); free(buff_size); free(buff); - close(sfd); + ssp_close(sfd); onExit(onExitParams); } \ No newline at end of file diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 3c5c343..61bfff5 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -6,15 +6,14 @@ #include "tasks.h" -static int onRecv(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ - printf("hello!\n"); +static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ Response res; res.addr = addr; res.msg = "hello back!!\n"; res.packet_len = *buff_size; res.size_of_addr = size_of_addr; res.sfd = sfd; - + ssp_printf("packet data: %s\n", packet); ssp_sendto(res); return 0; } @@ -35,16 +34,15 @@ static void onExit(void *other) { static int onSend(int sfd, struct sockaddr_in addr, void *onSendParams) { Response res; res.addr = &addr; - res.msg = "hello serer!!\n"; + res.msg = "hello server!!\n"; res.packet_len = 12; res.size_of_addr = sizeof(struct sockaddr_in); res.sfd = sfd; - printf("sending msg\n"); ssp_sendto(res); return 0; } static int onRecvClient(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) { - printf("recv %s\n", packet); + printf("client received %s\n", packet); return 0; } @@ -60,19 +58,19 @@ static void onExitClient(void *params) { int server_tests(int client){ int buffsize = 10000; + char buff[buffsize]; - if (client) { printf("I'm a client!\n"); - //connection_client(1111); - connectioned_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); - + connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + //connectionless_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); } else { printf("I'm a server!\n"); - connection_server("1111", buffsize, onRecv, onTimeOut, onStdIn, checkExit, onExit, NULL); + //connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + connection_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); } return 0; From 2a2218f3fbb3cef749e2f87cafe59db8dbcf12fa Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 12 Sep 2019 14:31:11 -0600 Subject: [PATCH 095/400] Update connectionless and connection servers to use PrepareHost - connectionless has issues --- Program/include/file_delivery_app.h | 2 +- Program/include/port.h | 2 +- Program/include/server.h | 6 +- Program/src/file_delivery_app.c | 6 +- Program/src/port.c | 32 ++--- Program/src/server.c | 182 ++++++++++++---------------- Program/src/tasks.c | 10 +- Program/test/server_tests.c | 22 ++-- 8 files changed, 118 insertions(+), 144 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 33d2ac6..2bc5a7b 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -10,5 +10,5 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address); void ssp_connectionless_server(Protocol_state *p_state); Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); void ssp_connection_server(Protocol_state *p_state); -void ssp_connection_client(); +void ssp_connection_client(Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index f08d28b..16277c4 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -39,7 +39,7 @@ void ssp_fd_set(int sfd, void *socket_set); int ssp_fd_is_set(int sfd, void *socket_set); void *ssp_init_socket_set(size_t *size); int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec); -void *ssp_init_sockaddr_struct(char *host_name, char port, size_t *size_of_addr); +void *ssp_init_sockaddr_struct(size_t *size_of_addr); void ssp_fd_clr(int sfd, void *socket_set); diff --git a/Program/include/server.h b/Program/include/server.h index 4ee1227..dc6b43f 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -18,7 +18,7 @@ This file is the header file for server.c is either 0 for udp, or 1 for tcp Return: It returns a socket descriptor to a UDP ready port ------------------------------------------------------------------------------*/ -int prepareHost(char *port, int conn_typ); +int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host, void *addr); /*------------------------------------------------------------------------------ @@ -61,7 +61,7 @@ void connection_server(char* port, int initial_buff_size, void *other); void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); @@ -78,7 +78,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa int *prepareSignalHandler(void); void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 19478f8..48aedd5 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -59,12 +59,12 @@ void ssp_connectionless_server(Protocol_state *p_state) { } void ssp_connection_server(Protocol_state *p_state) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server, p_state); + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, p_state); } -void ssp_connection_client() { - ssp_thread_create(STACK_ALLOCATION, ssp_connection_client, NULL); +void ssp_connection_client(Protocol_state *p_state) { + ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, p_state); } Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { diff --git a/Program/src/port.c b/Program/src/port.c index a950800..29105c5 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -10,15 +10,21 @@ #include #ifdef POSIX_PORT - #include - #include - #include - #include - #include - #include - #include - #include - #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include #endif #include "types.h" @@ -143,23 +149,21 @@ int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *res .tv_usec = timeout_in_usec }; - int nrdy = select(sfd + 1, read_socket_set, write_socket_set, restrict_socket_set, &timeout); + int nrdy = select(sfd + 1, (fd_set *) read_socket_set, (fd_set *) write_socket_set, (fd_set *) restrict_socket_set, &timeout); #endif return nrdy; } -void *ssp_init_sockaddr_struct(char *host_name, char port, size_t *size_of_addr) { +void *ssp_init_sockaddr_struct(size_t *size_of_addr) { #ifdef POSIX_PORT - //if (strncmp(host_name, "", 1) == 0) - - *size_of_addr = sizeof(struct sockaddr); void *addr = calloc(sizeof(struct sockaddr), 1); checkAlloc(addr, 1); + #endif return addr; } diff --git a/Program/src/server.c b/Program/src/server.c index da306bc..32d6fe0 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -37,29 +37,22 @@ This is my file for server.c. It develops a udp server for select. static int exit_now; -//if conn_typ == 1, tcp, if 0 udp -int prepareHost(char *port, int conn_type) +//if conn_typ == 1, tcp/ bind_to_host == 1 for binding local, 2 for connect +int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host, void *addr) { struct addrinfo hints, *res; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_flags = AI_V4MAPPED; - - switch (conn_type) { - - case 0: - hints.ai_socktype = SOCK_DGRAM; - break; - case 1: - hints.ai_socktype = SOCK_STREAM; - } + hints.ai_socktype = conn_type; - int err = getaddrinfo(NULL, port, &hints, &res); + + int err = getaddrinfo(host_name, port, &hints, &res); if (err != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err)); + ssp_printf("get addr info"); exit(EXIT_FAILURE); } @@ -68,31 +61,46 @@ int prepareHost(char *port, int conn_type) for (cur = res; cur != NULL; cur = cur->ai_next) { + sfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); if (sfd < 0) { - perror("socket"); + ssp_error("socket"); } int val = 1; - err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - - if (err == -1) - { - perror("set sock opt"); - ssp_close(sfd); - continue; + if (bind_to_host != 0) { + err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (err == -1) { + ssp_error("set sock opt"); + ssp_close(sfd); + continue; + } } - err = bind(sfd, cur->ai_addr, cur->ai_addrlen); - if (err == -1) - { - perror("bind"); - ssp_close(sfd); - continue; + if (bind_to_host == 1) { + err = bind(sfd, cur->ai_addr, cur->ai_addrlen); + if (err == -1) { + ssp_error("bind"); + ssp_close(sfd); + continue; + } + } + else if (bind_to_host == 2) { + err = connect(sfd, cur->ai_addr, cur->ai_addrlen); + if (err == -1) { + ssp_error("connection with the server failed...\n"); + ssp_close(sfd); + continue; + } + } + struct sockaddr *a = (struct sockaddr* ) addr; + a->sa_family = cur->ai_family; + memcpy(a->sa_data, cur->ai_addr, sizeof(a->sa_data)); + freeaddrinfo(cur); break; } @@ -159,7 +167,14 @@ void connection_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other) { - int sfd = prepareHost(port, 1); + + + size_t size_of_addr[1]; + *size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct(size_of_addr); + + int sfd = prepareHost(NULL, port, SOCK_STREAM, 1, addr); + int err = listen(sfd, 10); if (err == -1) @@ -184,9 +199,6 @@ void connection_server(char* port, int initial_buff_size, char *buff = ssp_alloc(sizeof(char), *buff_size); checkAlloc(buff, 1); - size_t size_of_addr[1]; - *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct("", port, size_of_addr); for (;;) { @@ -225,7 +237,7 @@ void connection_server(char* port, int initial_buff_size, } if (i == sfd) { - int new_socket = accept(i, (struct sockaddr*) addr, size_of_addr); + int new_socket = accept(i, (struct sockaddr*) addr, (socklen_t *)size_of_addr); if (new_socket < 0) ssp_error ("accept failed"); @@ -234,7 +246,7 @@ void connection_server(char* port, int initial_buff_size, continue; } - int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, NULL); + int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, size_of_addr[0]); if (count < 0) { ssp_error("recv failed server"); @@ -273,7 +285,13 @@ void connectionless_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other) { - int sfd = prepareHost(port, 0); + + + size_t size_of_addr[1]; + *size_of_addr = 0; + + void *addr = ssp_init_sockaddr_struct(size_of_addr); + int sfd = prepareHost(NULL, port, SOCK_DGRAM, 1, addr); size_t size_of_socket_struct[1]; *size_of_socket_struct = 0; @@ -294,15 +312,14 @@ void connectionless_server(char* port, int initial_buff_size, char *buff = ssp_alloc(sizeof(char), *buff_size); checkAlloc(buff, 1); - size_t size_of_addr[1]; - *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct("", port, size_of_addr); + for (;;) { memcpy(read_socket_set, socket_set, size_of_socket_struct[0]); + int nrdy = ssp_select(FD_SETSIZE, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ @@ -331,12 +348,12 @@ void connectionless_server(char* port, int initial_buff_size, } if (ssp_fd_is_set(sfd, read_socket_set)) { + + int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr[0]); - int count = ssp_recvfrom(sfd, buff, *buff_size, MSG_TRUNC, addr, size_of_addr[0]); + if (count == -1) + continue; - if (count == -1) { - ssp_error("recv failed server"); - } else if (count >= *buff_size) { ssp_printf("packet too large\n"); } @@ -353,6 +370,7 @@ void connectionless_server(char* port, int initial_buff_size, ssp_free(buff); ssp_close(sfd); onExit(other); + } @@ -360,16 +378,13 @@ void connectionless_server(char* port, int initial_buff_size, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) { - int sfd, count, port_val; - socklen_t serverlen; - struct sockaddr_in serveraddr; - struct hostent *server; + int sfd, count; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); @@ -381,34 +396,14 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe char *buff = ssp_alloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); -//-------------------------------------------------------------- - sfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sfd < 0) - perror("ERROR opening socket"); - - port_val = atoi(port); - - server = gethostbyname(hostname); - - if (server == NULL) { - fprintf(stderr,"ERROR, no such host as %s\n", hostname); - exit(0); - } - - bzero((char *) &serveraddr, sizeof(serveraddr)); - serveraddr.sin_family = AF_INET; - - bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); - serveraddr.sin_port = htons(port_val); - size_t size_of_addr[1]; *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(hostname, port, size_of_addr); - -//-------------------------------------------------------------- + void *addr = ssp_init_sockaddr_struct(size_of_addr); + sfd = prepareHost(hostname, port, SOCK_DGRAM, 0, addr); for (;;) { + if (exit_now || checkExit(checkExitParams)) break; @@ -416,10 +411,10 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe ssp_error("packet too large, cannot resize buffer\n"); } - if (onSend(sfd, serveraddr, onSendParams)) + if (onSend(sfd, addr, onSendParams)) ssp_error("send failed\n"); - count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, &serveraddr, size_of_addr[0]); + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, addr, size_of_addr[0]); if (count == -1) continue; @@ -429,12 +424,13 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe continue; } else{ - if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr[0], onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], onRecvParams) == -1) ssp_error("recv failed\n"); } } + free(addr); free(buff_size); free(buff); ssp_close(sfd); @@ -444,16 +440,13 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), + int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) { - int sfd, count, port_val; - socklen_t serverlen; - struct sockaddr_in serveraddr; - struct hostent *server; + int sfd, count; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); @@ -465,36 +458,11 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa char *buff = ssp_alloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); - sfd = socket(AF_INET, SOCK_STREAM, 0); - if (sfd < 0) - perror("ERROR opening socket"); - - port_val = atoi(port); - - server = gethostbyname(hostname); - if (server == NULL) { - fprintf(stderr,"ERROR, no such host as %s\n", hostname); - exit(0); - } - - bzero((char *) &serveraddr, sizeof(serveraddr)); - serveraddr.sin_family = AF_INET; - - bcopy((char *)server->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, server->h_length); - serveraddr.sin_port = htons(port_val); - serverlen = sizeof(serveraddr); - - //size_t size_of_addr = sizeof(struct sockaddr); - size_t size_of_addr[1]; *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(hostname, port, size_of_addr); + void *addr = ssp_init_sockaddr_struct(size_of_addr); - - if (connect(sfd, (struct sockaddr *)&serveraddr, size_of_addr[0]) != 0) { - ssp_error("connection with the server failed...\n"); - exit_now = 1; - } + sfd = prepareHost(hostname, port, SOCK_STREAM, 2, addr); for (;;) { @@ -505,10 +473,10 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa ssp_printf("packet too large, cannot resize buffer\n"); } - if (onSend(sfd, serveraddr, onSendParams)) + if (onSend(sfd, addr, onSendParams)) ssp_error("send failed here\n"); - count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, NULL); + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, size_of_addr[0]); if (count == -1) continue; @@ -518,7 +486,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa continue; } else{ - if (onRecv(sfd, buff, count, buff_size, (void *)&serveraddr, size_of_addr[0], onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], onRecvParams) == -1) ssp_error("recv failed\n"); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index f24487c..e60900f 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -102,13 +102,9 @@ static void user_request_check(void *request, void *args) { remove_request_check(request, params->client->request_list); } -static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { +static int on_send_client(int sfd, void *addr, void *other) { - #ifdef POSIX_PORT - struct sockaddr_in* client_addr = (struct sockaddr_in*) &addr; - #endif - Response res; Client *client = (Client *) other; if (client->request_list->count == 0){ @@ -117,7 +113,7 @@ static int on_send_client(int sfd, struct sockaddr_in addr, void *other) { res.sfd = sfd; res.packet_len = client->packet_len; - res.addr = client_addr; + res.addr = addr; struct user_request_check_params params = { res, @@ -256,7 +252,7 @@ void *ssp_connection_server_task(void *params) { void *ssp_connection_client_task(void *params) { //Client *client = (Client *) params; - connection_client(1111); + //connection_client(1111); return NULL; } diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 61bfff5..89e4f9c 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -19,6 +19,7 @@ static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *b } static int onTimeOut(void *other) { + printf("timeout\n"); return 0; } static int onStdIn(void *other){ @@ -31,14 +32,19 @@ static void onExit(void *other) { } //client stuff -static int onSend(int sfd, struct sockaddr_in addr, void *onSendParams) { +static int onSend(int sfd, void *addr, void *onSendParams) { Response res; - res.addr = &addr; + res.addr = addr; res.msg = "hello server!!\n"; res.packet_len = 12; - res.size_of_addr = sizeof(struct sockaddr_in); + res.size_of_addr = sizeof(struct sockaddr); res.sfd = sfd; - ssp_sendto(res); + + sendto(sfd, res.msg, res.packet_len, 0, (struct sockaddr*)res.addr, res.size_of_addr); + + //ssp_sendto(res); + + return 0; } static int onRecvClient(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) { @@ -63,14 +69,14 @@ int server_tests(int client){ if (client) { printf("I'm a client!\n"); - connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); - //connectionless_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + //connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + connectionless_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); } else { printf("I'm a server!\n"); - //connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); - connection_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + //connection_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); } return 0; From 938bcc630fce81f8b253c21d853c63c25dc44e1c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 13 Sep 2019 16:46:21 -0600 Subject: [PATCH 096/400] replace sendto with connect/write? --- Program/include/port.h | 2 +- Program/include/server.h | 2 +- Program/src/port.c | 22 ++-- Program/src/protocol_handler.c | 2 +- Program/src/server.c | 60 +++++------ Program/test/server_tests.c | 179 +++++++++++++++++++++++++++++++-- 6 files changed, 215 insertions(+), 52 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 16277c4..702f60d 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -19,7 +19,7 @@ Request *init_request(uint32_t buff_len); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); -int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t server_addr_len); +int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len); void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); diff --git a/Program/include/server.h b/Program/include/server.h index dc6b43f..189e83a 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -18,7 +18,7 @@ This file is the header file for server.c is either 0 for udp, or 1 for tcp Return: It returns a socket descriptor to a UDP ready port ------------------------------------------------------------------------------*/ -int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host, void *addr); +int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host); /*------------------------------------------------------------------------------ diff --git a/Program/src/port.c b/Program/src/port.c index 29105c5..8903a51 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -84,17 +84,21 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { #ifdef POSIX_PORT - struct sockaddr* addr = (struct sockaddr*) res.addr; - int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); + //struct sockaddr* addr = (struct sockaddr*) res.addr; + //int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); + //if (n < 0) + // ssp_error("ERROR in ssp_sendto"); + + int n = write(res.sfd, res.msg, res.packet_len); if (n < 0) - ssp_error("ERROR in ssp_sendto"); + ssp_error("ERROR in write"); #endif } -int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t server_addr_len) { +int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { int count = 0; #ifdef POSIX_PORT - count = recvfrom(sfd, buff, packet_len, flags, (struct sockaddr*)server_addr, (socklen_t*)&server_addr_len); + count = recvfrom(sfd, buff, packet_len, flags, (struct sockaddr*)server_addr, (socklen_t*)server_addr_len); #endif return count; @@ -159,8 +163,8 @@ void *ssp_init_sockaddr_struct(size_t *size_of_addr) { #ifdef POSIX_PORT - *size_of_addr = sizeof(struct sockaddr); - void *addr = calloc(sizeof(struct sockaddr), 1); + *size_of_addr = sizeof(struct sockaddr_storage); + void *addr = ssp_alloc(1, sizeof(struct sockaddr_storage)); checkAlloc(addr, 1); @@ -207,10 +211,10 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void #ifdef POSIX_PORT - pthread_t *handler = ssp_alloc(sizeof(pthread_t), 1); + pthread_t *handler = ssp_alloc(1, sizeof(pthread_t)); checkAlloc(handler, 1); - pthread_attr_t *attr = ssp_alloc(sizeof(pthread_attr_t), 1); + pthread_attr_t *attr = ssp_alloc(1, sizeof(pthread_attr_t)); checkAlloc(attr, 1); int err = pthread_attr_init(attr); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2f9cb57..d1a564a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -156,7 +156,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); found_req->procedure = sending_put_metadata; - found_req->res.addr = ssp_alloc(res.size_of_addr, 1); + found_req->res.addr = ssp_alloc(1, res.size_of_addr); memcpy(found_req->res.addr, res.addr, res.size_of_addr); found_req->res.packet_len = p_state->packet_size; found_req->res.sfd = res.sfd; diff --git a/Program/src/server.c b/Program/src/server.c index 32d6fe0..5b56b54 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -38,7 +38,7 @@ static int exit_now; //if conn_typ == 1, tcp/ bind_to_host == 1 for binding local, 2 for connect -int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host, void *addr) +int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host) { struct addrinfo hints, *res; @@ -70,15 +70,13 @@ int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host, vo } int val = 1; - if (bind_to_host != 0) { - err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - if (err == -1) { - ssp_error("set sock opt"); - ssp_close(sfd); - continue; - } + err = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (err == -1) { + ssp_error("set sock opt"); + ssp_close(sfd); + continue; } - + if (bind_to_host == 1) { err = bind(sfd, cur->ai_addr, cur->ai_addrlen); if (err == -1) { @@ -86,21 +84,15 @@ int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host, vo ssp_close(sfd); continue; } - } - else if (bind_to_host == 2) { + } else { err = connect(sfd, cur->ai_addr, cur->ai_addrlen); if (err == -1) { ssp_error("connection with the server failed...\n"); ssp_close(sfd); continue; } - } - struct sockaddr *a = (struct sockaddr* ) addr; - a->sa_family = cur->ai_family; - memcpy(a->sa_data, cur->ai_addr, sizeof(a->sa_data)); - freeaddrinfo(cur); break; } @@ -173,7 +165,7 @@ void connection_server(char* port, int initial_buff_size, *size_of_addr = 0; void *addr = ssp_init_sockaddr_struct(size_of_addr); - int sfd = prepareHost(NULL, port, SOCK_STREAM, 1, addr); + int sfd = prepareHost(NULL, port, SOCK_STREAM, 1); int err = listen(sfd, 10); @@ -246,7 +238,7 @@ void connection_server(char* port, int initial_buff_size, continue; } - int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, size_of_addr[0]); + int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, size_of_addr); if (count < 0) { ssp_error("recv failed server"); @@ -258,7 +250,7 @@ void connection_server(char* port, int initial_buff_size, } else { ssp_printf("reading\n"); - if (onRecv(i, buff, count, buff_size, addr, size_of_addr[0], other) == -1) + if (onRecv(i, buff, count, buff_size, addr, *size_of_addr, other) == -1) ssp_printf("recv failed\n"); } } @@ -290,8 +282,7 @@ void connectionless_server(char* port, int initial_buff_size, size_t size_of_addr[1]; *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(size_of_addr); - int sfd = prepareHost(NULL, port, SOCK_DGRAM, 1, addr); + int sfd = prepareHost(NULL, port, SOCK_DGRAM, 1); size_t size_of_socket_struct[1]; *size_of_socket_struct = 0; @@ -314,7 +305,8 @@ void connectionless_server(char* port, int initial_buff_size, - + void *addr = ssp_init_sockaddr_struct(size_of_addr); + for (;;) { @@ -348,8 +340,8 @@ void connectionless_server(char* port, int initial_buff_size, } if (ssp_fd_is_set(sfd, read_socket_set)) { - - int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr[0]); + int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr); + if (count == -1) continue; @@ -358,7 +350,7 @@ void connectionless_server(char* port, int initial_buff_size, ssp_printf("packet too large\n"); } else { - if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], other) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, *size_of_addr, other) == -1) ssp_printf("recv failed\n"); } } @@ -396,10 +388,10 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe char *buff = ssp_alloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); - size_t size_of_addr[1]; - *size_of_addr = 0; + size_t size_of_addr[1] = {0}; void *addr = ssp_init_sockaddr_struct(size_of_addr); - sfd = prepareHost(hostname, port, SOCK_DGRAM, 0, addr); + + sfd = prepareHost(hostname, port, SOCK_DGRAM, 0); for (;;) { @@ -414,7 +406,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe if (onSend(sfd, addr, onSendParams)) ssp_error("send failed\n"); - count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, addr, size_of_addr[0]); + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, addr, size_of_addr); if (count == -1) continue; @@ -424,7 +416,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe continue; } else{ - if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, *size_of_addr, onRecvParams) == -1) ssp_error("recv failed\n"); } @@ -455,14 +447,14 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa uint32_t prev_buff_size = *buff_size; - char *buff = ssp_alloc(sizeof(char), prev_buff_size); + char *buff = ssp_alloc(prev_buff_size, sizeof(char)); checkAlloc(buff, 1); size_t size_of_addr[1]; *size_of_addr = 0; void *addr = ssp_init_sockaddr_struct(size_of_addr); - sfd = prepareHost(hostname, port, SOCK_STREAM, 2, addr); + sfd = prepareHost(hostname, port, SOCK_STREAM, 0); for (;;) { @@ -476,7 +468,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa if (onSend(sfd, addr, onSendParams)) ssp_error("send failed here\n"); - count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, size_of_addr[0]); + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, size_of_addr); if (count == -1) continue; @@ -486,7 +478,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa continue; } else{ - if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr[0], onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, *size_of_addr, onRecvParams) == -1) ssp_error("recv failed\n"); } diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 89e4f9c..4b1bbd2 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -6,6 +6,160 @@ #include "tasks.h" +//-------------------------------- +#include +#include +#include +#include +#include +#include +#include + +#define BUF_SIZE 500 +static int clin(char *host, char*port) +{ + struct addrinfo hints; + struct addrinfo *result, *rp; + int sfd, s, j; + size_t len; + ssize_t nread; + char buf[BUF_SIZE]; + + + /* Obtain address(es) matching host/port */ + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_flags = 0; + hints.ai_protocol = 0; /* Any protocol */ + + s = getaddrinfo(host, port, &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + exit(EXIT_FAILURE); + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully connect(2). + If socket(2) (or connect(2)) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) + break; /* Success */ + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + fprintf(stderr, "Could not connect\n"); + exit(EXIT_FAILURE); + } + + freeaddrinfo(result); /* No longer needed */ + + /* Send remaining command-line arguments as separate + datagrams, and read responses from server */ + + if (write(sfd, "stuff", 5) != 5) { + fprintf(stderr, "partial/failed write\n"); + exit(EXIT_FAILURE); + } + + nread = read(sfd, buf, BUF_SIZE); + if (nread == -1) { + perror("read"); + exit(EXIT_FAILURE); + } + + return 0; +} + +static int serv (char *port) +{ + struct addrinfo hints; + struct addrinfo *result, *rp; + int sfd, s; + struct sockaddr_storage peer_addr; + socklen_t peer_addr_len; + ssize_t nread; + char buf[BUF_SIZE]; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ + hints.ai_protocol = 0; /* Any protocol */ + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + s = getaddrinfo(NULL, port, &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + exit(EXIT_FAILURE); + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully bind(2). + If socket(2) (or bind(2)) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sfd == -1) + continue; + if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) + break; /* Success */ + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + fprintf(stderr, "Could not bind\n"); + exit(EXIT_FAILURE); + } + + freeaddrinfo(result); /* No longer needed */ + + /* Read datagrams and echo them back to sender */ + + for (;;) { + peer_addr_len = sizeof(struct sockaddr_storage); + nread = recvfrom(sfd, buf, BUF_SIZE, 0, + (struct sockaddr *) &peer_addr, &peer_addr_len); + if (nread == -1) + continue; /* Ignore failed request */ + + char host[NI_MAXHOST], service[NI_MAXSERV]; + + s = getnameinfo((struct sockaddr *) &peer_addr, + peer_addr_len, host, NI_MAXHOST, + service, NI_MAXSERV, NI_NUMERICSERV); + if (s == 0) + printf("Received %zd bytes from %s:%s\n", + nread, host, service); + else + fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s)); + + if (sendto(sfd, buf, nread, 0, + (struct sockaddr *) &peer_addr, + peer_addr_len) != nread) + fprintf(stderr, "Error sending response\n"); + } +} + + + +//-------------------------------------------------------------------- + static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ Response res; res.addr = addr; @@ -14,12 +168,17 @@ static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *b res.size_of_addr = size_of_addr; res.sfd = sfd; ssp_printf("packet data: %s\n", packet); - ssp_sendto(res); + + + int n = sendto(sfd, "Hello back", 12, 0, (struct sockaddr*)addr, res.size_of_addr); + if (n < 0) + ssp_error("ERROR in sendto"); + //ssp_sendto(res); return 0; } static int onTimeOut(void *other) { - printf("timeout\n"); + //printf("timeout\n"); return 0; } static int onStdIn(void *other){ @@ -39,11 +198,17 @@ static int onSend(int sfd, void *addr, void *onSendParams) { res.packet_len = 12; res.size_of_addr = sizeof(struct sockaddr); res.sfd = sfd; + printf("sending message:%s", res.msg); - sendto(sfd, res.msg, res.packet_len, 0, (struct sockaddr*)res.addr, res.size_of_addr); - + //sendto(sfd, "Hello", 5, 0, (struct sockaddr*)addr, res.size_of_addr); //ssp_sendto(res); + if (write(sfd, "HELLO", 5) != 5) { + fprintf(stderr, "partial/failed write\n"); + exit(EXIT_FAILURE); + } + + return 0; } @@ -70,12 +235,14 @@ int server_tests(int client){ if (client) { printf("I'm a client!\n"); //connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); - connectionless_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); - + connectionless_client("localhost", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + //clin("127.0.0.1", "1111"); } else { printf("I'm a server!\n"); connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + + //serv ("1111"); //connection_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); } From 1ec63db246abb7b1c017ffac19e274a8fb49c67d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 15 Sep 2019 11:53:45 -0600 Subject: [PATCH 097/400] Tcp works, but overloads the buffer it looks like, need to 'package' --- Program/include/file_delivery_app.h | 2 +- Program/include/server.h | 4 +- Program/src/file_delivery_app.c | 22 ++++- Program/src/main.c | 13 +-- Program/src/port.c | 11 +-- Program/src/protocol_handler.c | 15 ++-- Program/src/server.c | 85 +++++++++---------- Program/src/tasks.c | 19 ++++- Program/test/server_tests.c | 125 ++++++++++++++++++++++++---- 9 files changed, 211 insertions(+), 85 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 2bc5a7b..8147a15 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -10,5 +10,5 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address); void ssp_connectionless_server(Protocol_state *p_state); Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); void ssp_connection_server(Protocol_state *p_state); -void ssp_connection_client(Protocol_state *p_state); +Client *ssp_connection_client(uint32_t cfdp_id, Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index 189e83a..e0d455a 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -44,7 +44,7 @@ int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host); Return: None ------------------------------------------------------------------------------*/ -void connectionless_server(char* port, int initial_buff_size, +void connectionless_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -52,7 +52,7 @@ void connectionless_server(char* port, int initial_buff_size, void (*onExit)(void *other), void *other); -void connection_server(char* port, int initial_buff_size, +void connection_server(char* port, int initial_buff_size, int connection_limit, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 48aedd5..63b9646 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -63,8 +63,26 @@ void ssp_connection_server(Protocol_state *p_state) { } -void ssp_connection_client(Protocol_state *p_state) { - ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, p_state); +Client *ssp_connection_client(uint32_t cfdp_id, Protocol_state *p_state) { + Client *client = ssp_alloc(sizeof(Client), 1); + checkAlloc(client, 1); + + client->current_request = NULL; + client->request_list = linked_list(); + client->packet_len = PACKET_LEN; + + Remote_entity *remote = get_remote_entity(p_state->mib, cfdp_id); + + if (remote == NULL) + ssp_printf("couldn't find entity in Remote_entity list\n"); + + //TODO clean this up, we don't need multiple instances of UT_ports etc + client->remote_entity = remote; + client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); + client->p_state = p_state; + + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); + return client; } Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { diff --git a/Program/src/main.c b/Program/src/main.c index c12971a..acf46d8 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -41,18 +41,19 @@ int main(int argc, char** argv) { } Protocol_state *p_state = init_ftp(conf->my_cfdp_id); - ssp_connectionless_server(p_state); - + //ssp_connectionless_server(p_state); + ssp_connection_server(p_state); + //create a client if (conf->client_cfdp_id != 0){ //ssp_printf("input a src file:\n"); - Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - + //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + Client *new_client = ssp_connection_client(conf->client_cfdp_id, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged if (conf->my_cfdp_id == 2) { - put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); } if (conf->my_cfdp_id == 3) put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); diff --git a/Program/src/port.c b/Program/src/port.c index 8903a51..9efe2ed 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -84,14 +84,10 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { #ifdef POSIX_PORT - //struct sockaddr* addr = (struct sockaddr*) res.addr; - //int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); - //if (n < 0) - // ssp_error("ERROR in ssp_sendto"); - - int n = write(res.sfd, res.msg, res.packet_len); + struct sockaddr* addr = (struct sockaddr*) res.addr; + int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); if (n < 0) - ssp_error("ERROR in write"); + ssp_error("ERROR in ssp_sendto"); #endif } @@ -149,7 +145,6 @@ int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *res struct timeval timeout = { .tv_sec = 0, - //.tv_usec = 100e3, .tv_usec = timeout_in_usec }; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index d1a564a..caea10a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -265,7 +265,8 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien offset_end = ntohl(offset_end); packet_index += 4; build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); - ssp_sendto(res); + ssp_write(res.sfd, req->buff, res.packet_len); + //ssp_sendto(res); } return packet_index; @@ -345,7 +346,8 @@ void user_request_handler(Response res, Request *req, Client* client) { req->procedure = none; build_eof_packet(req->buff, start, req); req->local_entity->EOF_sent_indication = 1; - ssp_sendto(res); + ssp_write(res.sfd, req->buff, res.packet_len); + //ssp_sendto(res); break; case sending_data: @@ -356,20 +358,23 @@ void user_request_handler(Response res, Request *req, Client* client) { req->procedure = sending_eof; ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); } - ssp_sendto(res); + ssp_write(res.sfd, req->buff, res.packet_len); + //ssp_sendto(res); break; case sending_put_metadata: ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(res, start, req); - ssp_sendto(res); + ssp_write(res.sfd, req->buff, res.packet_len); + //ssp_sendto(res); req->procedure = sending_data; break; case sending_finished: ssp_printf("sending finished packet transaction: %d\n", req->transaction_sequence_number); build_ack(req->buff, start, FINISHED_PDU); - ssp_sendto(res); + ssp_write(res.sfd, req->buff, res.packet_len); + //ssp_sendto(res); req->resent_finished++; break; diff --git a/Program/src/server.c b/Program/src/server.c index 5b56b54..935bc67 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -50,10 +50,9 @@ int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host) int err = getaddrinfo(host_name, port, &hints, &res); - if (err != 0) - { - ssp_printf("get addr info"); - exit(EXIT_FAILURE); + if (err != 0) { + ssp_error("get addr info"); + return -1; } int sfd; @@ -64,8 +63,7 @@ int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host) sfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); - if (sfd < 0) - { + if (sfd < 0) { ssp_error("socket"); } @@ -99,8 +97,9 @@ int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host) if (cur == NULL) { - fprintf(stderr, "could not create server\n"); - exit(EXIT_FAILURE); + ssp_printf("error could not create server\n"); + freeaddrinfo(res); + return -1; } return sfd; @@ -151,7 +150,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf return 1; } //see header file -void connection_server(char* port, int initial_buff_size, +void connection_server(char* port, int initial_buff_size, int connection_limit, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -160,23 +159,24 @@ void connection_server(char* port, int initial_buff_size, void *other) { - - size_t size_of_addr[1]; - *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(size_of_addr); - int sfd = prepareHost(NULL, port, SOCK_STREAM, 1); + if (sfd < 0) + return; int err = listen(sfd, 10); if (err == -1) ssp_error("listen failed\n"); - size_t size_of_socket_struct[1]; - *size_of_socket_struct = 0; - void *socket_set = ssp_init_socket_set(size_of_socket_struct); - void *read_socket_set = ssp_init_socket_set(size_of_socket_struct); + size_t size_of_addr[1]; + *size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct(size_of_addr); + + size_t size_of_socket_struct = 0; + + void *socket_set = ssp_init_socket_set(&size_of_socket_struct); + void *read_socket_set = ssp_init_socket_set(&size_of_socket_struct); ssp_fd_zero(socket_set); ssp_fd_set(sfd, socket_set); @@ -191,13 +191,11 @@ void connection_server(char* port, int initial_buff_size, char *buff = ssp_alloc(sizeof(char), *buff_size); checkAlloc(buff, 1); - for (;;) { + memcpy(read_socket_set, socket_set, size_of_socket_struct); + int nrdy = ssp_select(FD_SETSIZE, read_socket_set, NULL, NULL, 100e3); - memcpy(read_socket_set, socket_set, size_of_socket_struct[0]); - int nrdy = ssp_select(sfd, read_socket_set, NULL, NULL, 100e3); - if (exit_now || checkExit(other)){ ssp_printf("exiting server thread\n"); break; @@ -215,6 +213,7 @@ void connection_server(char* port, int initial_buff_size, if (nrdy == 0) { if (onTimeOut(other) == -1) ssp_printf("timeout failed\n"); + continue; } @@ -234,11 +233,10 @@ void connection_server(char* port, int initial_buff_size, ssp_error ("accept failed"); ssp_fd_set(new_socket, socket_set); - ssp_fd_set(new_socket, read_socket_set); - continue; + break; } - int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, size_of_addr); + int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, NULL); if (count < 0) { ssp_error("recv failed server"); @@ -269,7 +267,7 @@ void connection_server(char* port, int initial_buff_size, //see header file -void connectionless_server(char* port, int initial_buff_size, +void connectionless_server(char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -278,17 +276,15 @@ void connectionless_server(char* port, int initial_buff_size, void *other) { - - size_t size_of_addr[1]; - *size_of_addr = 0; - int sfd = prepareHost(NULL, port, SOCK_DGRAM, 1); + if (sfd < 0) + return; - size_t size_of_socket_struct[1]; - *size_of_socket_struct = 0; + size_t size_of_socket_struct = 0; - void *socket_set = ssp_init_socket_set(size_of_socket_struct); - void *read_socket_set = ssp_init_socket_set(size_of_socket_struct); + + void *socket_set = ssp_init_socket_set(&size_of_socket_struct); + void *read_socket_set = ssp_init_socket_set(&size_of_socket_struct); ssp_fd_zero(socket_set); ssp_fd_set(sfd, socket_set); @@ -303,16 +299,16 @@ void connectionless_server(char* port, int initial_buff_size, char *buff = ssp_alloc(sizeof(char), *buff_size); checkAlloc(buff, 1); - - + size_t size_of_addr[1]; + *size_of_addr = 0; void *addr = ssp_init_sockaddr_struct(size_of_addr); for (;;) { - memcpy(read_socket_set, socket_set, size_of_socket_struct[0]); + memcpy(read_socket_set, socket_set, size_of_socket_struct); - int nrdy = ssp_select(FD_SETSIZE, read_socket_set, NULL, NULL, 100e3); + int nrdy = ssp_select(sfd + 1, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ ssp_printf("exiting server thread\n"); @@ -377,6 +373,9 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe { int sfd, count; + sfd = prepareHost(hostname, port, SOCK_DGRAM, 0); + if (sfd < 0) + return; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); @@ -391,7 +390,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe size_t size_of_addr[1] = {0}; void *addr = ssp_init_sockaddr_struct(size_of_addr); - sfd = prepareHost(hostname, port, SOCK_DGRAM, 0); + for (;;) { @@ -440,6 +439,10 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa int sfd, count; + sfd = prepareHost(hostname, port, SOCK_STREAM, 0); + if (sfd < 0) + exit_now = 1; + uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); @@ -454,7 +457,6 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa *size_of_addr = 0; void *addr = ssp_init_sockaddr_struct(size_of_addr); - sfd = prepareHost(hostname, port, SOCK_STREAM, 0); for (;;) { @@ -483,8 +485,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa } } - - printf("exiting loop\n"); + free(addr); free(buff_size); free(buff); ssp_close(sfd); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index e60900f..d1df9ea 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -245,14 +245,27 @@ void *ssp_connectionless_client_task(void* params){ void *ssp_connection_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; - connection_server(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + p_state->transaction_sequence_number = 1; + //1024 is the connection max limit + connection_server(p_state->server_port, PACKET_LEN, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); return NULL; } void *ssp_connection_client_task(void *params) { - //Client *client = (Client *) params; - //connection_client(1111); + Client *client = (Client *) params; + + char host_name[INET_ADDRSTRLEN]; + char port[10]; + + //convert int to char * + snprintf(port, 10, "%d", client->remote_entity->UT_port); + + //convert uint id to char * + inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); + + connection_client(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + return NULL; } diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 4b1bbd2..0af740b 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -30,7 +30,7 @@ static int clin(char *host, char*port) memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ + hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ hints.ai_flags = 0; hints.ai_protocol = 0; /* Any protocol */ @@ -158,6 +158,102 @@ static int serv (char *port) +static int servCon (char *port) +{ + struct addrinfo hints; + struct addrinfo *result, *rp; + int sfd, s; + struct sockaddr_storage peer_addr; + socklen_t peer_addr_len; + ssize_t nread; + char buf[BUF_SIZE]; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ + hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ + hints.ai_protocol = 0; /* Any protocol */ + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + s = getaddrinfo(NULL, port, &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + exit(EXIT_FAILURE); + } + + /* getaddrinfo() returns a list of address structures. + Try each address until we successfully bind(2). + If socket(2) (or bind(2)) fails, we (close the socket + and) try the next address. */ + + for (rp = result; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sfd == -1) + continue; + if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) + break; /* Success */ + + close(sfd); + } + + if (rp == NULL) { /* No address succeeded */ + fprintf(stderr, "Could not bind\n"); + exit(EXIT_FAILURE); + } + + freeaddrinfo(result); /* No longer needed */ + + int err = listen(sfd, 10); + if (err < 0) { + printf("error\n listen"); + return; + } + + /* Read datagrams and echo them back to sender */ + + for (;;) { + peer_addr_len = sizeof(struct sockaddr_storage); + + printf("accepting\n"); + int cfd = accept(sfd, &peer_addr, peer_addr_len); + + printf("accepted\n"); + + //nread = recvfrom(cfd, buf, BUF_SIZE, 0, + // (struct sockaddr *) &peer_addr, &peer_addr_len); + + nread = recv(cfd, buf, BUF_SIZE, 0); + if (nread == -1) { + printf("failed to read\n"); + continue; + } + + + + char host[NI_MAXHOST], service[NI_MAXSERV]; + + s = getnameinfo((struct sockaddr *) &peer_addr, + peer_addr_len, host, NI_MAXHOST, + service, NI_MAXSERV, NI_NUMERICSERV); + if (s == 0) + printf("Received %zd bytes from %s:%s\n", + nread, host, service); + else + fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s)); + + if (sendto(sfd, buf, nread, 0, + (struct sockaddr *) &peer_addr, + peer_addr_len) != nread) + fprintf(stderr, "Error sending response\n"); + } +} + + + + //-------------------------------------------------------------------- static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ @@ -169,8 +265,8 @@ static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *b res.sfd = sfd; ssp_printf("packet data: %s\n", packet); - - int n = sendto(sfd, "Hello back", 12, 0, (struct sockaddr*)addr, res.size_of_addr); + int n = send(sfd, "hello back!", 12, 0); + //int n = sendto(sfd, "Hello back", 12, 0, (struct sockaddr*)addr, res.size_of_addr); if (n < 0) ssp_error("ERROR in sendto"); //ssp_sendto(res); @@ -198,24 +294,21 @@ static int onSend(int sfd, void *addr, void *onSendParams) { res.packet_len = 12; res.size_of_addr = sizeof(struct sockaddr); res.sfd = sfd; - printf("sending message:%s", res.msg); + //printf("sending message:%s", res.msg); //sendto(sfd, "Hello", 5, 0, (struct sockaddr*)addr, res.size_of_addr); //ssp_sendto(res); - if (write(sfd, "HELLO", 5) != 5) { - fprintf(stderr, "partial/failed write\n"); - exit(EXIT_FAILURE); - } - - + int n = send(sfd, "HELLO", 5, 0); + if (n < 0) + fprintf(stderr, "partial/failed write\n"); + return 0; } static int onRecvClient(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) { printf("client received %s\n", packet); return 0; - } static int checkExitClient(void *params) { @@ -234,16 +327,16 @@ int server_tests(int client){ if (client) { printf("I'm a client!\n"); - //connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); - connectionless_client("localhost", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + //connectionless_client("localhost", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); //clin("127.0.0.1", "1111"); } else { printf("I'm a server!\n"); - connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + //connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); - //serv ("1111"); - //connection_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + //servCon ("1111"); + connection_server("1111", buffsize, 10, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); } return 0; From 8aae6ca4e0c44524eb5938a17994a383d7e041b5 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 16 Sep 2019 16:43:46 -0600 Subject: [PATCH 098/400] TCP (connection server/client works) --- Program/include/types.h | 8 +++++++- Program/src/server.c | 36 ++++++++++++------------------------ Program/src/tasks.c | 10 +++++----- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index 1ff5a9f..0d3fde1 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -542,11 +542,13 @@ typedef struct request { Response res; } Request; +//add "client" in here to represent local entity typedef struct protocol_state { - uint32_t packet_size; + uint32_t packet_len; char *server_port; void *server_handle; MIB *mib; + uint32_t my_cfdp_id; List* request_list; @@ -568,12 +570,16 @@ typedef struct protocol_state { typedef struct client { void *client_handle; + //the maximum size of the packet uint32_t packet_len; Request *current_request; List *request_list; + //information about the remote_entity Remote_entity *remote_entity; + + //packet header, useful for copying into outgoing packets Pdu_header *pdu_header; Protocol_state *p_state; diff --git a/Program/src/server.c b/Program/src/server.c index 935bc67..fdb6ad0 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -163,7 +163,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, if (sfd < 0) return; - int err = listen(sfd, 10); + int err = listen(sfd, connection_limit); if (err == -1) ssp_error("listen failed\n"); @@ -185,7 +185,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); - *buff_size = initial_buff_size + 10; + *buff_size = initial_buff_size; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), *buff_size); @@ -194,7 +194,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, for (;;) { memcpy(read_socket_set, socket_set, size_of_socket_struct); - int nrdy = ssp_select(FD_SETSIZE, read_socket_set, NULL, NULL, 100e3); + int nrdy = ssp_select(connection_limit + 1, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ ssp_printf("exiting server thread\n"); @@ -217,10 +217,9 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, continue; } - for(int i = 0; i < FD_SETSIZE; i++) { + for(int i = 0; i < connection_limit + 1; i++) { if (ssp_fd_is_set(i, read_socket_set)) { - ssp_printf("receiving from socket %d!\n", i); if (i == STDIN_FILENO) { onStdIn(other); @@ -237,17 +236,14 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, } int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, NULL); - + if (count < 0) { ssp_error("recv failed server"); ssp_close(i); ssp_fd_clr(i, socket_set); } - else if (count >= *buff_size) { - ssp_printf("packet too large %d\n", count); - } + else { - ssp_printf("reading\n"); if (onRecv(i, buff, count, buff_size, addr, *size_of_addr, other) == -1) ssp_printf("recv failed\n"); } @@ -337,7 +333,7 @@ void connectionless_server(char* port, int initial_buff_size, if (ssp_fd_is_set(sfd, read_socket_set)) { int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr); - + ssp_printf("read in this amount %d\n", count); if (count == -1) continue; @@ -387,14 +383,11 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe char *buff = ssp_alloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); - size_t size_of_addr[1] = {0}; - void *addr = ssp_init_sockaddr_struct(size_of_addr); - - + size_t size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct(&size_of_addr); for (;;) { - if (exit_now || checkExit(checkExitParams)) break; @@ -405,7 +398,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe if (onSend(sfd, addr, onSendParams)) ssp_error("send failed\n"); - count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, addr, size_of_addr); + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, addr, &size_of_addr); if (count == -1) continue; @@ -415,7 +408,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe continue; } else{ - if (onRecv(sfd, buff, count, buff_size, addr, *size_of_addr, onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, onRecvParams) == -1) ssp_error("recv failed\n"); } @@ -446,8 +439,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); - *buff_size = packet_len + 10; - + *buff_size = packet_len; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(prev_buff_size, sizeof(char)); @@ -475,10 +467,6 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa if (count == -1) continue; - else if (count >= *buff_size){ - ssp_error("packet too large\n"); - continue; - } else{ if (onRecv(sfd, buff, count, buff_size, addr, *size_of_addr, onRecvParams) == -1) ssp_error("recv failed\n"); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index d1df9ea..7ab6961 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -23,7 +23,7 @@ static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t Response res; res.addr = addr; res.sfd = sfd; - res.packet_len = p_state->packet_size; + res.packet_len = p_state->packet_len; res.size_of_addr = size_of_addr; Request **request_container = &p_state->current_request; @@ -219,7 +219,7 @@ void *ssp_connectionless_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; - connectionless_server(p_state->server_port, PACKET_LEN, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + connectionless_server(p_state->server_port, p_state->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); return NULL; } @@ -238,7 +238,7 @@ void *ssp_connectionless_client_task(void* params){ //convert uint id to char * inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); - connectionless_client(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + connectionless_client(host_name, port, client->packet_len, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); return NULL; } @@ -247,7 +247,7 @@ void *ssp_connection_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; //1024 is the connection max limit - connection_server(p_state->server_port, PACKET_LEN, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + connection_server(p_state->server_port, p_state->packet_len, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); return NULL; } @@ -264,7 +264,7 @@ void *ssp_connection_client_task(void *params) { //convert uint id to char * inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); - connection_client(host_name, port, PACKET_LEN, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + connection_client(host_name, port, client->packet_len, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); return NULL; } From e0de8fccf6fafe73c9e15c00e70b29156671777a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 16 Sep 2019 16:48:46 -0600 Subject: [PATCH 099/400] Not sure why these are here --- Program/src/file_delivery_app.a | Bin 159160 -> 0 bytes Program/src/remote_pic1.jpeg | Bin 150033 -> 0 bytes Program/src/remote_pic2.jpeg | Bin 150033 -> 0 bytes Program/test/testfile | 318 -------------------------------- 4 files changed, 318 deletions(-) delete mode 100644 Program/src/file_delivery_app.a delete mode 100644 Program/src/remote_pic1.jpeg delete mode 100644 Program/src/remote_pic2.jpeg delete mode 100644 Program/test/testfile diff --git a/Program/src/file_delivery_app.a b/Program/src/file_delivery_app.a deleted file mode 100644 index 7629c1ffe8f5b4cef3630127eb2245b7fb9ecadd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159160 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

lppL^W{;(2 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 PkZ(2W-D#PCmhb-nYj;U9 diff --git a/Program/src/remote_pic1.jpeg b/Program/src/remote_pic1.jpeg deleted file mode 100644 index 8c727e085507309e22d0059687c15e4d884930d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150033 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

u;b_%m1w>npTOZ22dacFAZgy8!w)SVc47OD( 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 z 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

u;b_%m1w>npTOZ22dacFAZgy8!w)SVc47OD( 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 z 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 Date: Sun, 22 Sep 2019 09:33:21 -0600 Subject: [PATCH 100/400] Include 'FreeRTOS porting in makefile' --- Program/include/port.h | 4 ++-- Program/src/file_delivery_app.c | 2 +- Program/src/main.c | 9 ++++----- Program/src/makefile | 15 +++++++++++++++ Program/src/port.c | 14 ++++++++++++++ Program/src/protocol_handler.c | 4 ++-- Program/src/server.c | 3 +-- 7 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 702f60d..7669d46 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -3,8 +3,8 @@ #define PORT_H #define STACK_ALLOCATION 16384 -#define POSIX_PORT 1 -#define FREE_RTOS_PORT 1 +#define POSIX_PORT +//#define FREE_RTOS_PORT #define MAX_PATH 255 diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 63b9646..7ca9688 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -37,7 +37,7 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { snprintf(port, 20, "%u", server_entity->UT_port); Protocol_state *p_state = ssp_alloc(sizeof(Protocol_state), 1); - p_state->packet_size = PACKET_LEN; + p_state->packet_len = PACKET_LEN; p_state->my_cfdp_id = my_cfdp_address; p_state->mib = mib; diff --git a/Program/src/main.c b/Program/src/main.c index acf46d8..c06d6fb 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -23,7 +23,6 @@ //for ssp_thread_join, can use p_thread join on linux #include "port.h" - //exit handler variable for the main thread static int *exit_now; @@ -41,15 +40,15 @@ int main(int argc, char** argv) { } Protocol_state *p_state = init_ftp(conf->my_cfdp_id); - //ssp_connectionless_server(p_state); - ssp_connection_server(p_state); + ssp_connectionless_server(p_state); + //ssp_connection_server(p_state); //create a client if (conf->client_cfdp_id != 0){ //ssp_printf("input a src file:\n"); - //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - Client *new_client = ssp_connection_client(conf->client_cfdp_id, p_state); + Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + //Client *new_client = ssp_connection_client(conf->client_cfdp_id, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged if (conf->my_cfdp_id == 2) { put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); diff --git a/Program/src/makefile b/Program/src/makefile index f1cbf01..cca85d1 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -1,6 +1,21 @@ PROJDIR = $(CURDIR)/.. INCLUDE += -I$(PROJDIR)/include + +#---------------------------FOR FREE RTOS INTEGRATION--------------------------- +#path to source includes +#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS-plus/Source/include +#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS/Source/include + +#path to compiler includes +#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008 + +#path to FreeRTOSconfig +#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS/Demo/ARM7_STR75x_GCC + +#------------------------------------------------------------------------------- + + CC = gcc #---------------------------File Names--------------------------- diff --git a/Program/src/port.c b/Program/src/port.c index 9efe2ed..1563b1a 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -29,6 +29,20 @@ #endif #include "types.h" +#ifdef FREE_RTOS_PORT + #include "FreeRTOS.h" + + + + + + #ifdef FREE_RTOS_PLUS + #include "" + #endif + +#endif + + /*------------------------------------------------------------------------------ diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index caea10a..8f3838d 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -147,7 +147,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r //server side, receiving requests (this should be its own function) if (found_req == NULL && is_server) { - found_req = init_request(p_state->packet_size); + found_req = init_request(p_state->packet_len); ssp_printf("incoming new request\n"); //Make new request and add it found_req->transmission_mode = header->transmission_mode; @@ -158,7 +158,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->procedure = sending_put_metadata; found_req->res.addr = ssp_alloc(1, res.size_of_addr); memcpy(found_req->res.addr, res.addr, res.size_of_addr); - found_req->res.packet_len = p_state->packet_size; + found_req->res.packet_len = p_state->packet_len; found_req->res.sfd = res.sfd; request_list->push(request_list, found_req, transaction_sequence_number); } diff --git a/Program/src/server.c b/Program/src/server.c index fdb6ad0..ff1d2a3 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -333,8 +333,7 @@ void connectionless_server(char* port, int initial_buff_size, if (ssp_fd_is_set(sfd, read_socket_set)) { int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr); - ssp_printf("read in this amount %d\n", count); - + if (count == -1) continue; From 6550306d3ebfbed0abae8c3fd7b4cd6d28eb706d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 23 Sep 2019 11:38:57 -0600 Subject: [PATCH 101/400] include FreeRTOS port --- Program/include/list.h | 5 +- Program/include/port.h | 18 +++++- Program/src/file_delivery_app.c | 6 +- Program/src/makefile | 20 ++++--- Program/src/port.c | 101 ++++++++++++++++++++++++-------- Program/src/server.c | 2 - README.md | 7 +++ 7 files changed, 117 insertions(+), 42 deletions(-) diff --git a/Program/include/list.h b/Program/include/list.h index f2b6bcc..baff40c 100644 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -1,7 +1,8 @@ + +#ifndef MY_LIST_H +#define MY_LIST_H #include -#ifndef LIST_H -#define LIST_H /*------------------------------------------------------------------------------ Purpose: This is a node for the link list bellow ------------------------------------------------------------------------------*/ diff --git a/Program/include/port.h b/Program/include/port.h index 7669d46..7848726 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -3,8 +3,22 @@ #define PORT_H #define STACK_ALLOCATION 16384 -#define POSIX_PORT -//#define FREE_RTOS_PORT + + + + +//#define POSIX_PORT +#define POSIX_FILESYSTEM +#define POSIX_NETWORK + +#define FREE_RTOS_PORT + + + + + + + #define MAX_PATH 255 diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 7ca9688..9ece961 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -40,7 +40,7 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { p_state->packet_len = PACKET_LEN; p_state->my_cfdp_id = my_cfdp_address; p_state->mib = mib; - + p_state->close = 0; p_state->server_port = ssp_alloc(sizeof(char), 10); checkAlloc(p_state->server_port, 1); @@ -55,11 +55,11 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { void ssp_connectionless_server(Protocol_state *p_state) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); + p_state->server_handle = ssp_thread_create(16384, ssp_connectionless_server_task, p_state); } void ssp_connection_server(Protocol_state *p_state) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, p_state); + p_state->server_handle = ssp_thread_create(16384, ssp_connection_server_task, p_state); } diff --git a/Program/src/makefile b/Program/src/makefile index cca85d1..a920fdc 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -2,20 +2,20 @@ PROJDIR = $(CURDIR)/.. INCLUDE += -I$(PROJDIR)/include + + #---------------------------FOR FREE RTOS INTEGRATION--------------------------- #path to source includes -#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS-plus/Source/include -#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS/Source/include +INCLUDE += -I$(PROJDIR)/../../../../Source/include -#path to compiler includes -#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008 +#path to compiler includes (portmacro.h) +INCLUDE += -I$(PROJDIR)/../../../../Source/portable/GCC/POSIX/ #path to FreeRTOSconfig -#INCLUDE += -I$(PROJDIR)/FreeRTOSv10.2.1/FreeRTOS/Demo/ARM7_STR75x_GCC +INCLUDE += -I$(PROJDIR)/../../../../Project/ #------------------------------------------------------------------------------- - CC = gcc #---------------------------File Names--------------------------- @@ -78,13 +78,17 @@ CFLAGS += $(INCLUDE) $(CWARNS) #---------------------------Build--------------------------- OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) + + all: $(MAIN) - ar -rsc file_delivery_app.a $(OBJS_FILES) -.PHONY: clean +.PHONY: clean lib $(MAIN): $(OBJS_FILES) +lib: $(OBJS_FILES) + ar -rsc file_delivery_app.a $(OBJS_FILES) + clean: rm -f *.o $(MAIN) diff --git a/Program/src/port.c b/Program/src/port.c index 1563b1a..2711b43 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -8,6 +8,8 @@ #include "mib.h" #include "filesystem_funcs.h" #include +#include "types.h" + #ifdef POSIX_PORT #include @@ -16,26 +18,36 @@ #include #include #include - #include #include - #include #include #include #include #include #include +#endif + + + + +#ifdef POSIX_FILESYSTEM + #include + #include + +#endif + + +#ifdef POSIX_NETWORK + #include + #include #endif -#include "types.h" #ifdef FREE_RTOS_PORT #include "FreeRTOS.h" + #include "task.h" + #include "portable.h" - - - - #ifdef FREE_RTOS_PLUS #include "" #endif @@ -50,20 +62,20 @@ File systems ------------------------------------------------------------------------------*/ int ssp_rename(const char *old, const char *new) { - #ifdef POSIX_PORT + #ifdef POSIX_FILESYSTEM return rename(old, new); #endif } int ssp_write(int fd, const void *buf, size_t count) { - #ifdef POSIX_PORT + #ifdef POSIX_FILESYSTEM return write(fd, buf, count); #endif } int ssp_read(int fd, char* buff, size_t size) { - #ifdef POSIX_PORT + #ifdef POSIX_FILESYSTEM return read(fd, buff, size); #endif @@ -71,20 +83,20 @@ int ssp_read(int fd, char* buff, size_t size) { //SEEK_END 2 SEEK_CUR 1 SEEK_SET 0 int ssp_lseek(int fd, int offset, int whence) { - #ifdef POSIX_PORT + #ifdef POSIX_FILESYSTEM return lseek(fd, offset, whence); #endif } int ssp_open(char *pathname, int flags) { - #ifdef POSIX_PORT + #ifdef POSIX_FILESYSTEM //open with read and write permissions return open(pathname, flags, 0666); #endif } int ssp_close(int fd) { - #ifdef POSIX_PORT + #ifdef POSIX_FILESYSTEM return close(fd); #endif } @@ -97,7 +109,7 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK struct sockaddr* addr = (struct sockaddr*) res.addr; int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); if (n < 0) @@ -107,7 +119,7 @@ void ssp_sendto(Response res) { int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { int count = 0; - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK count = recvfrom(sfd, buff, packet_len, flags, (struct sockaddr*)server_addr, (socklen_t*)server_addr_len); #endif @@ -116,7 +128,7 @@ int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server void *ssp_init_socket_set(size_t *size) { - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK fd_set *socket_set = ssp_alloc(1, sizeof(fd_set)); *size = sizeof(fd_set); #endif @@ -125,20 +137,21 @@ void *ssp_init_socket_set(size_t *size) { void ssp_fd_zero(void *socket_set){ - #ifdef POSIX_PORT + + #ifdef POSIX_NETWORK FD_ZERO((fd_set*) socket_set); #endif } void ssp_fd_set(int sfd, void *socket_set) { - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK FD_SET(sfd, (fd_set*) socket_set); #endif } int ssp_fd_is_set(int sfd, void *socket_set){ int is_set = 0; - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK is_set = FD_ISSET(sfd, (fd_set*) socket_set); #endif @@ -147,7 +160,7 @@ int ssp_fd_is_set(int sfd, void *socket_set){ void ssp_fd_clr(int sfd, void *socket_set) { - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK FD_CLR(sfd, (fd_set *) socket_set); #endif @@ -155,7 +168,7 @@ void ssp_fd_clr(int sfd, void *socket_set) { int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec) { - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK struct timeval timeout = { .tv_sec = 0, @@ -170,7 +183,7 @@ int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *res void *ssp_init_sockaddr_struct(size_t *size_of_addr) { - #ifdef POSIX_PORT + #ifdef POSIX_NETWORK *size_of_addr = sizeof(struct sockaddr_storage); void *addr = ssp_alloc(1, sizeof(struct sockaddr_storage)); @@ -188,16 +201,30 @@ void *ssp_init_sockaddr_struct(size_t *size_of_addr) { ------------------------------------------------------------------------------*/ void *ssp_alloc(uint32_t n_memb, size_t size) { + + //return calloc(n_memb, size); + #ifdef POSIX_PORT return calloc(n_memb, size); #endif + + #ifdef FREE_RTOS_PORT + return pvPortMalloc(n_memb * size); + #endif + } void ssp_free(void *pointer) { + //free(pointer); + #ifdef POSIX_PORT free(pointer); - pointer = NULL; #endif + + #ifdef FREE_RTOS_PORT + vPortFree(pointer); + #endif + } void ssp_error(char *error){ @@ -216,6 +243,11 @@ void ssp_printf( char *stuff, ...) { #endif } + + +/*------------------------------------------------------------------------------ + Threading and task functions +------------------------------------------------------------------------------*/ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params) { @@ -245,17 +277,36 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void perror("ERROR pthread_create"); ssp_free(attr); - #endif return handler; + #endif + + #ifdef FREE_RTOS_PORT + + TaskHandle_t *xHandle = ssp_alloc(1, sizeof(TaskHandle_t)); + BaseType_t xReturned; + + /* Create the task, storing the handle. */ + xReturned = xTaskCreate( + thread_func, /* Function that implements the task. */ + "FTP", /* Text name for the task. */ + stack_size, /* Stack size in words, not bytes. */ + params, /* Parameter passed into the task. */ + tskIDLE_PRIORITY,/* Priority at which the task is created. */ + xHandle ); /* Used to pass out the created task's handle. */ + + + return xHandle; + #endif } + +//not required for Free_rtos void ssp_thread_join(void *thread_handle) { #ifdef POSIX_PORT pthread_t * handle = (pthread_t*) thread_handle; pthread_join(*handle, NULL); ssp_free(thread_handle); #endif - } \ No newline at end of file diff --git a/Program/src/server.c b/Program/src/server.c index ff1d2a3..a71f3ed 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -301,7 +301,6 @@ void connectionless_server(char* port, int initial_buff_size, for (;;) { - memcpy(read_socket_set, socket_set, size_of_socket_struct); int nrdy = ssp_select(sfd + 1, read_socket_set, NULL, NULL, 100e3); @@ -386,7 +385,6 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe void *addr = ssp_init_sockaddr_struct(&size_of_addr); for (;;) { - if (exit_now || checkExit(checkExitParams)) break; diff --git a/README.md b/README.md index 1fc7ca2..5e3f86f 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,10 @@ I want to eventually make it opensource, but there is a lot of work to do before if you want to get in contact with me email me at evangiese77@gmail.com + + + + +Compilation Notes: + for compiling with free rtos, first we need to specifiy the locatifon of the free RTOS header files that we need within + our makefile. Then we can compile our .a file. To use this file, just staticly link to the file_delivery_app.a. From 25d9a574c5faf067b63e6a9e51c7aa58d0556dd4 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 23 Sep 2019 12:09:21 -0600 Subject: [PATCH 102/400] Fixed freeRtos thread warning, casting to thread type, fine as long as I dont return stuff --- Program/src/makefile | 1 - Program/src/port.c | 5 +++-- README.md | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Program/src/makefile b/Program/src/makefile index a920fdc..5943a19 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -93,4 +93,3 @@ clean: rm -f *.o $(MAIN) - diff --git a/Program/src/port.c b/Program/src/port.c index 2711b43..950a673 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -288,13 +288,14 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void /* Create the task, storing the handle. */ xReturned = xTaskCreate( - thread_func, /* Function that implements the task. */ + *((TaskFunction_t*) thread_func), /* Function that implements the task. */ "FTP", /* Text name for the task. */ stack_size, /* Stack size in words, not bytes. */ params, /* Parameter passed into the task. */ tskIDLE_PRIORITY,/* Priority at which the task is created. */ xHandle ); /* Used to pass out the created task's handle. */ - + if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) + ssp_error("Not enough memory to start task\n"); return xHandle; #endif diff --git a/README.md b/README.md index 5e3f86f..b756cd0 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,5 @@ email me at evangiese77@gmail.com Compilation Notes: for compiling with free rtos, first we need to specifiy the locatifon of the free RTOS header files that we need within our makefile. Then we can compile our .a file. To use this file, just staticly link to the file_delivery_app.a. + + From 3f713b0d3d41ebaae2985b522a7b62792d74b9ff Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 23 Sep 2019 16:52:57 -0600 Subject: [PATCH 103/400] remove casting --- Program/src/port.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 950a673..bdadb7e 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -202,8 +202,6 @@ void *ssp_init_sockaddr_struct(size_t *size_of_addr) { void *ssp_alloc(uint32_t n_memb, size_t size) { - //return calloc(n_memb, size); - #ifdef POSIX_PORT return calloc(n_memb, size); #endif @@ -215,8 +213,7 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { } void ssp_free(void *pointer) { - //free(pointer); - + #ifdef POSIX_PORT free(pointer); #endif @@ -288,7 +285,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void /* Create the task, storing the handle. */ xReturned = xTaskCreate( - *((TaskFunction_t*) thread_func), /* Function that implements the task. */ + thread_func, /* Function that implements the task. */ "FTP", /* Text name for the task. */ stack_size, /* Stack size in words, not bytes. */ params, /* Parameter passed into the task. */ From 233f56924d964bc289a92646f5bf1e31e98f6549 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 27 Sep 2019 14:29:34 -0600 Subject: [PATCH 104/400] add network type for mib --- Program/include/mib.h | 2 +- Program/include/port.h | 7 +- Program/include/server.h | 27 ++++--- Program/include/types.h | 15 +++- Program/src/file_delivery_app.c | 8 +- Program/src/mib.c | 8 +- Program/src/port.c | 16 +++- Program/src/protocol_handler.c | 26 +++---- Program/src/server.c | 128 ++++++++++++++++++++++++-------- Program/src/tasks.c | 12 ++- 10 files changed, 174 insertions(+), 75 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 5e86e6a..71ece45 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -12,7 +12,7 @@ MIB *init_mib(void); void free_mib(MIB *mib); -int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port); +int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, enum Network_type); Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); diff --git a/Program/include/port.h b/Program/include/port.h index 7848726..f988930 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -7,12 +7,11 @@ -//#define POSIX_PORT +#define POSIX_PORT #define POSIX_FILESYSTEM #define POSIX_NETWORK - -#define FREE_RTOS_PORT - +//#define CSP_NETWORK +//#define FREE_RTOS_PORT diff --git a/Program/include/server.h b/Program/include/server.h index e0d455a..d873e92 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -11,15 +11,6 @@ This file is the header file for server.c //figure out what to inlcude for types ask nick #include -/*------------------------------------------------------------------------------ - Purpose: This function creates a host server on the specified port - on localhost - Perameters: char *port is the port number you want to run the host on, conn_type - is either 0 for udp, or 1 for tcp - Return: It returns a socket descriptor to a UDP ready port -------------------------------------------------------------------------------*/ -int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host); - /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. @@ -61,7 +52,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, void *other); void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, void *onSendParams), + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); @@ -78,9 +69,25 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa int *prepareSignalHandler(void); void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params)); + +#ifdef CSP_NETWORK +void csp_connectionless_client(uint8_t my_id, uint8_t my_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); +void csp_connectionless_server(uint8_t MY_ID, uint8_t MY_PORT, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other); +#endif + #endif //SERVER_H diff --git a/Program/include/types.h b/Program/include/types.h index 0d3fde1..49d1c0a 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -413,11 +413,23 @@ typedef struct local_entity { } Local_entity; + +typedef enum Network_type { + csp, + free_rtos, + posix, + +} Network_type; + typedef struct remote_entity { //TODO probably add new UT layer specific stuff uint32_t UT_address; uint16_t UT_port; + + //csp, ip, rtos/ip + Network_type type_of_network; + uint32_t cfdp_id; unsigned int one_way_light_time; @@ -473,6 +485,8 @@ typedef struct response { //this is type (struct sockaddr_in) in posix void *addr; + enum Network_type type_of_network; + //getting rid of this soon in favour of client based packet sizes size_t size_of_addr; @@ -587,7 +601,6 @@ typedef struct client { //bool for exiting the client thread uint8_t close; - } Client; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 9ece961..130bcf7 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -22,10 +22,10 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { inet_pton(AF_INET, host_name, addr); //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111); - add_new_cfdp_entity(mib, 2, *addr, 1112); - add_new_cfdp_entity(mib, 3, *addr, 1113); - add_new_cfdp_entity(mib, 4, *addr, 1114); + add_new_cfdp_entity(mib, 1, *addr, 1111, posix); + add_new_cfdp_entity(mib, 2, *addr, 1112, posix); + add_new_cfdp_entity(mib, 3, *addr, 1113, posix); + add_new_cfdp_entity(mib, 4, *addr, 1114, posix); //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); diff --git a/Program/src/mib.c b/Program/src/mib.c index 95b19e0..7c05f67 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -5,6 +5,7 @@ #include #include "string.h" #include "list.h" +#include "types.h" MIB *init_mib() { MIB *mib = ssp_alloc(1, sizeof(MIB)); @@ -25,10 +26,11 @@ void free_mib(MIB *mib){ } //these configure peers for their specific transmission configuration, should be read in on a config file -int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port){ +int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, Network_type type){ Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); - + remote->type_of_network = type; + remote->CRC_required = 0; //these will be custom set by a config file @@ -41,6 +43,8 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ remote->cfdp_id = cfdp_id; remote->UT_port = port; + + return mib->remote_entities->insert(mib->remote_entities, remote, cfdp_id); } diff --git a/Program/src/port.c b/Program/src/port.c index bdadb7e..5b6e205 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -109,12 +109,22 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { - #ifdef POSIX_NETWORK + if (res.type_of_network == posix) { struct sockaddr* addr = (struct sockaddr*) res.addr; - int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); + int err = ssp_write(res.sfd, res.msg, res.packet_len); + if (err < 0) { + ssp_error("ERROR in ssp_sendto"); + } + + /* + int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, res.size_of_addr); if (n < 0) ssp_error("ERROR in ssp_sendto"); - #endif + */ + + + } + } int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 8f3838d..49d260d 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -54,7 +54,6 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { } -//TODO This needs more work, file handling when files already exist ect int process_file_request_metadata(Request *req) { char temp[75]; @@ -69,7 +68,6 @@ int process_file_request_metadata(Request *req) { return 1; } - ssp_printf("mode acknowledged, building offset map\n"); Offset *offset = ssp_alloc(1, sizeof(Offset)); offset->end = req->file_size; offset->start = 0; @@ -265,8 +263,8 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien offset_end = ntohl(offset_end); packet_index += 4; build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); - ssp_write(res.sfd, req->buff, res.packet_len); - //ssp_sendto(res); + //ssp_write(res.sfd, req->buff, res.packet_len); + ssp_sendto(res); } return packet_index; @@ -346,8 +344,8 @@ void user_request_handler(Response res, Request *req, Client* client) { req->procedure = none; build_eof_packet(req->buff, start, req); req->local_entity->EOF_sent_indication = 1; - ssp_write(res.sfd, req->buff, res.packet_len); - //ssp_sendto(res); + //ssp_write(res.sfd, req->buff, res.packet_len); + ssp_sendto(res); break; case sending_data: @@ -358,23 +356,23 @@ void user_request_handler(Response res, Request *req, Client* client) { req->procedure = sending_eof; ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); } - ssp_write(res.sfd, req->buff, res.packet_len); - //ssp_sendto(res); + //ssp_write(res.sfd, req->buff, res.packet_len); + ssp_sendto(res); break; case sending_put_metadata: ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(res, start, req); - ssp_write(res.sfd, req->buff, res.packet_len); - //ssp_sendto(res); + //ssp_write(res.sfd, req->buff, res.packet_len); + ssp_sendto(res); req->procedure = sending_data; break; case sending_finished: ssp_printf("sending finished packet transaction: %d\n", req->transaction_sequence_number); build_ack(req->buff, start, FINISHED_PDU); - ssp_write(res.sfd, req->buff, res.packet_len); - //ssp_sendto(res); + //ssp_write(res.sfd, req->buff, res.packet_len); + ssp_sendto(res); req->resent_finished++; break; @@ -393,7 +391,7 @@ static int reset_timeout(Request *req) { if (req->timeout++ >= TIMEOUT_BEFORE_CANCEL_REQUEST) { ssp_printf("time to live ended, closing up request transaction: %d\n", req->transaction_sequence_number); - if (req->procedure != none) + if (req->procedure != none) ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); else { ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); @@ -420,7 +418,7 @@ void on_server_time_out(Response res, Request *req) { if (req->procedure == none) return; - + if (req->transmission_mode == 1) return; diff --git a/Program/src/server.c b/Program/src/server.c index a71f3ed..463eb1f 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -34,11 +34,15 @@ This is my file for server.c. It develops a udp server for select. #include #include "port.h" +#ifdef CSP_NETWORK + #include "csp.h" +#endif + static int exit_now; //if conn_typ == 1, tcp/ bind_to_host == 1 for binding local, 2 for connect -int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host) +static int prepareHost(char *host_name, void *addr, size_t *size_of_addr, char *port, int conn_type, int bind_to_host) { struct addrinfo hints, *res; @@ -91,6 +95,9 @@ int prepareHost(char *host_name, char *port, int conn_type, int bind_to_host) } } + + + freeaddrinfo(cur); break; } @@ -158,21 +165,18 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, void (*onExit)(void *other), void *other) { + uint32_t size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct((size_t*)&size_of_addr); - int sfd = prepareHost(NULL, port, SOCK_STREAM, 1); + int sfd = prepareHost(NULL, addr, &size_of_addr, port, SOCK_STREAM, 1); if (sfd < 0) - return; + exit_now = 1; int err = listen(sfd, connection_limit); if (err == -1) ssp_error("listen failed\n"); - - size_t size_of_addr[1]; - *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(size_of_addr); - size_t size_of_socket_struct = 0; void *socket_set = ssp_init_socket_set(&size_of_socket_struct); @@ -244,7 +248,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, } else { - if (onRecv(i, buff, count, buff_size, addr, *size_of_addr, other) == -1) + if (onRecv(i, buff, count, buff_size, addr, size_of_addr, other) == -1) ssp_printf("recv failed\n"); } } @@ -272,9 +276,12 @@ void connectionless_server(char* port, int initial_buff_size, void *other) { - int sfd = prepareHost(NULL, port, SOCK_DGRAM, 1); + uint32_t size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct((size_t*)&size_of_addr); + + int sfd = prepareHost(NULL, addr, &size_of_addr, port, SOCK_DGRAM, 1); if (sfd < 0) - return; + exit_now = 1; size_t size_of_socket_struct = 0; @@ -295,9 +302,7 @@ void connectionless_server(char* port, int initial_buff_size, char *buff = ssp_alloc(sizeof(char), *buff_size); checkAlloc(buff, 1); - size_t size_of_addr[1]; - *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(size_of_addr); + for (;;) { @@ -331,7 +336,7 @@ void connectionless_server(char* port, int initial_buff_size, } if (ssp_fd_is_set(sfd, read_socket_set)) { - int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, size_of_addr); + int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, &size_of_addr); if (count == -1) continue; @@ -340,7 +345,7 @@ void connectionless_server(char* port, int initial_buff_size, ssp_printf("packet too large\n"); } else { - if (onRecv(sfd, buff, count, buff_size, addr, *size_of_addr, other) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, other) == -1) ssp_printf("recv failed\n"); } } @@ -360,16 +365,20 @@ void connectionless_server(char* port, int initial_buff_size, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, void *onSendParams), + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) { int sfd, count; - sfd = prepareHost(hostname, port, SOCK_DGRAM, 0); + + uint32_t size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct((size_t*)&size_of_addr); + + sfd = prepareHost(hostname, addr, &size_of_addr, port, SOCK_DGRAM, 0); if (sfd < 0) - return; + exit_now = 1; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); checkAlloc(buff_size, 1); @@ -381,8 +390,6 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe char *buff = ssp_alloc(sizeof(char), prev_buff_size); checkAlloc(buff, 1); - size_t size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(&size_of_addr); for (;;) { if (exit_now || checkExit(checkExitParams)) @@ -392,7 +399,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe ssp_error("packet too large, cannot resize buffer\n"); } - if (onSend(sfd, addr, onSendParams)) + if (onSend(sfd, addr, size_of_addr, onSendParams)) ssp_error("send failed\n"); count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, addr, &size_of_addr); @@ -421,7 +428,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, void *onSendParams), + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) @@ -429,7 +436,10 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa int sfd, count; - sfd = prepareHost(hostname, port, SOCK_STREAM, 0); + uint32_t size_of_addr = 0; + void *addr = ssp_init_sockaddr_struct((size_t*)&size_of_addr); + + sfd = prepareHost(hostname, addr, &size_of_addr, port, SOCK_STREAM, 0); if (sfd < 0) exit_now = 1; @@ -442,10 +452,6 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa char *buff = ssp_alloc(prev_buff_size, sizeof(char)); checkAlloc(buff, 1); - size_t size_of_addr[1]; - *size_of_addr = 0; - void *addr = ssp_init_sockaddr_struct(size_of_addr); - for (;;) { @@ -456,16 +462,16 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa ssp_printf("packet too large, cannot resize buffer\n"); } - if (onSend(sfd, addr, onSendParams)) + if (onSend(sfd, addr, size_of_addr, onSendParams)) ssp_error("send failed here\n"); - count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, size_of_addr); + count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, &size_of_addr); if (count == -1) continue; else{ - if (onRecv(sfd, buff, count, buff_size, addr, *size_of_addr, onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, onRecvParams) == -1) ssp_error("recv failed\n"); } @@ -475,4 +481,62 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa free(buff); ssp_close(sfd); onExit(onExitParams); -} \ No newline at end of file +} + +/*------------------------------------------------------------------------------ + + CSP STUFF! + +------------------------------------------------------------------------------*/ + +#ifdef CSP_NETWORK + +//https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c +void csp_connectionless_client(uint8_t my_id, uint8_t my_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, + int (*onSend)(int sfd, void *addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params)) +{ + +} + + +void csp_connectionless_server(uint8_t my_id, uint8_t my_port, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other) +{ + int err = csp_init(my_id); + if (err < 0) { + ssp_error("ERROR: couldn't init csp\n"); + return; + } + //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); + csp_socket_t *socket = csp_socket(0); + + err = csp_bind(socket, my_port); + if (err < 0) { + ssp_error("ERROR: couldn't bind csp\n"); + return; + } + + for (;;) { + csp_packet_t *packet = csp_recvfrom(socket, 10); + + //timout + if (packet == NULL) { + + } + else { + //do stuff + ssp_printf("%s\n", packet->data); + csp_buffer_free(packet); + } + + } +} +#endif \ No newline at end of file diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 7ab6961..d0d5abb 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -49,6 +49,7 @@ static int on_recv_client(int sfd, char *packet, uint32_t packet_len, uint32_t * res.addr = addr; res.sfd = sfd; res.packet_len = client->packet_len; + res.type_of_network = client->remote_entity->type_of_network; res.size_of_addr = size_of_addr; Request **request_container = &client->current_request; @@ -102,7 +103,7 @@ static void user_request_check(void *request, void *args) { remove_request_check(request, params->client->request_list); } -static int on_send_client(int sfd, void *addr, void *other) { +static int on_send_client(int sfd, void *addr, size_t size_of_addr, void *other) { Response res; @@ -114,7 +115,9 @@ static int on_send_client(int sfd, void *addr, void *other) { res.sfd = sfd; res.packet_len = client->packet_len; res.addr = addr; - + res.size_of_addr = size_of_addr; + res.type_of_network = client->remote_entity->type_of_network; + struct user_request_check_params params = { res, client @@ -122,7 +125,6 @@ static int on_send_client(int sfd, void *addr, void *other) { client->request_list->iterate(client->request_list, user_request_check, ¶ms); - return 0; } @@ -219,8 +221,10 @@ void *ssp_connectionless_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; + connectionless_server(p_state->server_port, p_state->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); - + //csp_connectionless_server(1, 1, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + return NULL; } From d64044a91e9545afb43ffc5205fbb468260fa36a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 27 Sep 2019 14:47:54 -0600 Subject: [PATCH 105/400] fixed accept bug --- Program/src/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/server.c b/Program/src/server.c index 463eb1f..46fa520 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -231,7 +231,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, } if (i == sfd) { - int new_socket = accept(i, (struct sockaddr*) addr, (socklen_t *)size_of_addr); + int new_socket = accept(i, (struct sockaddr*) addr, &size_of_addr); if (new_socket < 0) ssp_error ("accept failed"); From 12627b53902bd0e1240207bad5c2afcf01414590 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 27 Sep 2019 15:07:49 -0600 Subject: [PATCH 106/400] Close socket on client when server closes. --- Program/src/main.c | 11 ++++++----- Program/src/makefile | 19 ++++++++++++------- Program/src/protocol_handler.c | 4 ++-- Program/src/server.c | 16 ++++++++++------ Program/src/tasks.c | 8 ++++---- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index c06d6fb..f8f6cd7 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -40,18 +40,19 @@ int main(int argc, char** argv) { } Protocol_state *p_state = init_ftp(conf->my_cfdp_id); - ssp_connectionless_server(p_state); - //ssp_connection_server(p_state); + //ssp_connectionless_server(p_state); + ssp_connection_server(p_state); //create a client if (conf->client_cfdp_id != 0){ //ssp_printf("input a src file:\n"); - Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - //Client *new_client = ssp_connection_client(conf->client_cfdp_id, p_state); + //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); + Client *new_client = ssp_connection_client(conf->client_cfdp_id, p_state); + //send via acknoleged mode //0 acknowledged, 1 unacknowledged if (conf->my_cfdp_id == 2) { - put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); } if (conf->my_cfdp_id == 3) diff --git a/Program/src/makefile b/Program/src/makefile index 5943a19..8dc6628 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -6,16 +6,21 @@ INCLUDE += -I$(PROJDIR)/include #---------------------------FOR FREE RTOS INTEGRATION--------------------------- #path to source includes -INCLUDE += -I$(PROJDIR)/../../../../Source/include +#INCLUDE += -I$(PROJDIR)/../../../../Source/include #path to compiler includes (portmacro.h) -INCLUDE += -I$(PROJDIR)/../../../../Source/portable/GCC/POSIX/ +#INCLUDE += -I$(PROJDIR)/../../../../Source/portable/GCC/POSIX/ #path to FreeRTOSconfig -INCLUDE += -I$(PROJDIR)/../../../../Project/ +#INCLUDE += -I$(PROJDIR)/../../../../Project/ #------------------------------------------------------------------------------- - +#---------------------------FOR CSP INTEGRATION--------------------------------- +#path to source includes +INCLUDE += -I$(PROJDIR)/libcsp/include/csp +INCLUDE += -I$(PROJDIR)/libcsp/include +INCLUDE += -I$(PROJDIR)/libcsp/build/include +#------------------------------------------------------------------------------- CC = gcc #---------------------------File Names--------------------------- @@ -61,11 +66,13 @@ CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = LIBS = -pthread +STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a #---------------------------Compiler flags--------------------------- #32 bit machines, leave this out if your machine is 64 bit CFLAGS += -m32 +#CFLAGS += -m64 CFLAGS += -g -UUSE_STDIO -D__GCC_POSIX__=1 CFLAGS += -pthread CFLAGS += -DDEBUG=1 @@ -78,13 +85,11 @@ CFLAGS += $(INCLUDE) $(CWARNS) #---------------------------Build--------------------------- OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) - - all: $(MAIN) .PHONY: clean lib -$(MAIN): $(OBJS_FILES) +$(MAIN): $(OBJS_FILES) $(STATIC_FILES) lib: $(OBJS_FILES) ar -rsc file_delivery_app.a $(OBJS_FILES) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 49d260d..2df63bd 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -99,7 +99,7 @@ static int find_request(void *element, void *args) { /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet -where the data portion is, returns 0 on fail*/ +where the data portion is, returns -1 on fail*/ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, Protocol_state *p_state) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -120,7 +120,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r if (p_state->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", p_state->my_cfdp_id, dest_id); - return 0; + return -1; } uint16_t len = get_data_length(packet); diff --git a/Program/src/server.c b/Program/src/server.c index 46fa520..5f8262e 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -248,8 +248,11 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, } else { - if (onRecv(i, buff, count, buff_size, addr, size_of_addr, other) == -1) - ssp_printf("recv failed\n"); + if (onRecv(i, buff, count, buff_size, addr, size_of_addr, other) == -1) { + ssp_printf("recv failed, closing socket\n"); + ssp_fd_clr(i, socket_set); + ssp_close(i); + } } } } @@ -467,14 +470,15 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, &size_of_addr); - if (count == -1) + if (count < 0) continue; - else{ - if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, onRecvParams) == -1) - ssp_error("recv failed\n"); + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, onRecvParams) == -1) { + ssp_error("recv failed\n"); + exit_now = 1; } + } free(addr); free(buff_size); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index d0d5abb..6f12507 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -28,10 +28,10 @@ static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t Request **request_container = &p_state->current_request; - uint32_t packet_index = process_pdu_header(packet, 1, res, request_container, p_state->request_list, p_state); + int packet_index = process_pdu_header(packet, 1, res, request_container, p_state->request_list, p_state); p_state->current_request = (*request_container); - if (packet_index == 0) + if (packet_index < 0) return -1; parse_packet_server(packet, packet_index, res, (*request_container), p_state); @@ -54,8 +54,8 @@ static int on_recv_client(int sfd, char *packet, uint32_t packet_len, uint32_t * Request **request_container = &client->current_request; - uint32_t packet_index = process_pdu_header(packet, 0, res, request_container, client->request_list, client->p_state); - if (packet_index == -1) { + int packet_index = process_pdu_header(packet, 0, res, request_container, client->request_list, client->p_state); + if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; } From a3ec8bf0330304d1425a285a98b4fd8c879c1518 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 27 Sep 2019 15:29:38 -0600 Subject: [PATCH 107/400] move exit check before select to avoide bad file descriptors --- Program/src/server.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Program/src/server.c b/Program/src/server.c index 5f8262e..e6fe4a9 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -197,14 +197,15 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, for (;;) { - memcpy(read_socket_set, socket_set, size_of_socket_struct); - int nrdy = ssp_select(connection_limit + 1, read_socket_set, NULL, NULL, 100e3); if (exit_now || checkExit(other)){ ssp_printf("exiting server thread\n"); break; } + memcpy(read_socket_set, socket_set, size_of_socket_struct); + int nrdy = ssp_select(connection_limit + 1, read_socket_set, NULL, NULL, 100e3); + if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ ssp_printf("packet too large, cannot resize buffer\n"); } @@ -309,15 +310,14 @@ void connectionless_server(char* port, int initial_buff_size, for (;;) { - memcpy(read_socket_set, socket_set, size_of_socket_struct); - - int nrdy = ssp_select(sfd + 1, read_socket_set, NULL, NULL, 100e3); - if (exit_now || checkExit(other)){ ssp_printf("exiting server thread\n"); break; } + memcpy(read_socket_set, socket_set, size_of_socket_struct); + int nrdy = ssp_select(sfd + 1, read_socket_set, NULL, NULL, 100e3); + if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ ssp_printf("packet too large, cannot resize buffer\n"); } @@ -478,7 +478,6 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa exit_now = 1; } - } free(addr); free(buff_size); From 264f980eb8e33450b117dc11fb540467ef6f81c3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 27 Sep 2019 19:12:53 -0600 Subject: [PATCH 108/400] csp doesnt segfault, but doesnt send yet --- Program/include/port.h | 8 +-- Program/include/server.h | 10 ++-- Program/src/file_delivery_app.c | 4 +- Program/src/main.c | 1 - Program/src/port.c | 16 +++-- Program/src/server.c | 85 ++++++++++++++++++++++++--- Program/test/makefile | 11 +++- Program/test/packet_tests.c | 8 +-- Program/test/protocol_handler_tests.c | 2 +- Program/test/server_tests.c | 14 +++-- 10 files changed, 120 insertions(+), 39 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index f988930..2930af4 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -10,16 +10,10 @@ #define POSIX_PORT #define POSIX_FILESYSTEM #define POSIX_NETWORK -//#define CSP_NETWORK +#define CSP_NETWORK //#define FREE_RTOS_PORT - - - - - - #define MAX_PATH 255 #include "types.h" diff --git a/Program/include/server.h b/Program/include/server.h index d873e92..f540486 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -74,20 +74,22 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); -#ifdef CSP_NETWORK -void csp_connectionless_client(uint8_t my_id, uint8_t my_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +//#ifdef CSP_NETWORK +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)); -void csp_connectionless_server(uint8_t MY_ID, uint8_t MY_PORT, +void csp_connectionless_server(uint8_t my_id, uint8_t my_port, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other); -#endif +//#endif + + #endif //SERVER_H diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 130bcf7..1955746 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -24,8 +24,8 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { //adding new cfdp entities to management information base add_new_cfdp_entity(mib, 1, *addr, 1111, posix); add_new_cfdp_entity(mib, 2, *addr, 1112, posix); - add_new_cfdp_entity(mib, 3, *addr, 1113, posix); - add_new_cfdp_entity(mib, 4, *addr, 1114, posix); + add_new_cfdp_entity(mib, 3, 1, 1, csp); + add_new_cfdp_entity(mib, 4, 2, 2, csp); //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); diff --git a/Program/src/main.c b/Program/src/main.c index f8f6cd7..585f0b6 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -53,7 +53,6 @@ int main(int argc, char** argv) { //send via acknoleged mode //0 acknowledged, 1 unacknowledged if (conf->my_cfdp_id == 2) { put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); } if (conf->my_cfdp_id == 3) put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); diff --git a/Program/src/port.c b/Program/src/port.c index 5b6e205..dbec1f1 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -55,6 +55,12 @@ #endif +#ifdef CSP_NETWORK + #include "csp.h" + +#endif + + /*------------------------------------------------------------------------------ @@ -115,16 +121,14 @@ void ssp_sendto(Response res) { if (err < 0) { ssp_error("ERROR in ssp_sendto"); } + } + else if (res.type_of_network == csp) { - /* - int n = sendto(res.sfd, res.msg, res.packet_len, 0, addr, res.size_of_addr); - if (n < 0) - ssp_error("ERROR in ssp_sendto"); - */ - } + } + } int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { diff --git a/Program/src/server.c b/Program/src/server.c index e6fe4a9..8a810fe 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -41,6 +41,7 @@ This is my file for server.c. It develops a udp server for select. static int exit_now; + //if conn_typ == 1, tcp/ bind_to_host == 1 for binding local, 2 for connect static int prepareHost(char *host_name, void *addr, size_t *size_of_addr, char *port, int conn_type, int bind_to_host) { @@ -289,7 +290,6 @@ void connectionless_server(char* port, int initial_buff_size, size_t size_of_socket_struct = 0; - void *socket_set = ssp_init_socket_set(&size_of_socket_struct); void *read_socket_set = ssp_init_socket_set(&size_of_socket_struct); @@ -492,19 +492,74 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa ------------------------------------------------------------------------------*/ -#ifdef CSP_NETWORK +//#ifdef CSP_NETWORK //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void csp_connectionless_client(uint8_t my_id, uint8_t my_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) { + int err = csp_init(2); + + if (err < 0) { + ssp_error("ERROR: couldn't init csp\n"); + return; + } + //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); + csp_socket_t *soc = csp_socket(0); + csp_buffer_init(30, 300); + + csp_packet_t *packet; + csp_packet_t *packet_recieved; + + memcpy(packet->data, "Hello server!\n", 15); + + if (err < 0) { + ssp_error("ERROR: couldn't bind csp\n"); + return; + } + + for (;;) { + + if (exit_now || checkExit(checkExitParams)){ + ssp_printf("exiting server thread\n"); + break; + } + + packet = csp_buffer_get(1); + memcpy(packet->data, "Hello server!\n", 15); + + err = csp_sendto(dest_id, 1, 2, 2, 0, packet, 10); + if (err < 0) { + ssp_printf("error in csp_sento\n"); + } + + packet_recieved = csp_recvfrom(soc, 10); + + //timout + if (packet_recieved == NULL) + continue; + + else { + //do stuff + if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), onRecvParams) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet_recieved); + } + + } + + csp_buffer_free(packet); + + } + void csp_connectionless_server(uint8_t my_id, uint8_t my_port, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), @@ -513,33 +568,45 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, void (*onExit)(void *other), void *other) { + int err = csp_init(my_id); + if (err < 0) { ssp_error("ERROR: couldn't init csp\n"); return; } //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); - csp_socket_t *socket = csp_socket(0); + csp_socket_t *soc = csp_socket(0); - err = csp_bind(socket, my_port); + err = csp_bind(soc, my_port); + + if (err < 0) { ssp_error("ERROR: couldn't bind csp\n"); return; } for (;;) { - csp_packet_t *packet = csp_recvfrom(socket, 10); + + if (exit_now || checkExit(other)){ + ssp_printf("exiting server thread\n"); + break; + } + + csp_packet_t *packet = csp_recvfrom(soc, 10); //timout if (packet == NULL) { - + onTimeOut(other); } else { //do stuff - ssp_printf("%s\n", packet->data); + if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), other) == -1) + ssp_printf("recv failed\n"); + csp_buffer_free(packet); } } } -#endif \ No newline at end of file +//#endif \ No newline at end of file diff --git a/Program/test/makefile b/Program/test/makefile index 97a9480..41b7992 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -3,6 +3,14 @@ PROJDIR = $(CURDIR)/.. INCLUDE += -I$(PROJDIR)/include INCLUDE += -I$(PROJDIR)/test +#---------------------------FOR CSP INTEGRATION--------------------------------- +#path to source includes +INCLUDE += -I$(PROJDIR)/libcsp/include/csp +INCLUDE += -I$(PROJDIR)/libcsp/include +INCLUDE += -I$(PROJDIR)/libcsp/build/include +#------------------------------------------------------------------------------- + + CC = gcc #---------------------------File Names--------------------------- @@ -54,6 +62,7 @@ CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = LIBS = -pthread +STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a #---------------------------Compiler flags--------------------------- @@ -75,7 +84,7 @@ all: $(MAIN) .PHONY: clean -$(MAIN): $(OBJS_FILES) +$(MAIN): $(OBJS_FILES) $(STATIC_FILES) clean: rm -f *.o $(MAIN) diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index bf71129..0fb6ff1 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -240,10 +240,10 @@ int packet_tests() { inet_pton(AF_INET, host_name, addr); //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111); - add_new_cfdp_entity(mib, 2, *addr, 1112); - add_new_cfdp_entity(mib, 3, *addr, 1113); - add_new_cfdp_entity(mib, 4, *addr, 1114); + add_new_cfdp_entity(mib, 1, *addr, 1111, posix); + add_new_cfdp_entity(mib, 2, *addr, 1112, posix); + add_new_cfdp_entity(mib, 3, *addr, 1113, posix); + add_new_cfdp_entity(mib, 4, *addr, 1114, posix); Pdu_header *pdu_header = get_header_from_mib(mib, 1, 2); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 0c1c49c..d9bc9be 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -24,7 +24,7 @@ static int test_process_pdu_header() { int addr = 16; res.addr = &addr; res.sfd = 1; - res.packet_len = p_state->packet_size; + res.packet_len = p_state->packet_len; res.size_of_addr = 16; //test 1 diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 0af740b..081062f 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -257,6 +257,10 @@ static int servCon (char *port) //-------------------------------------------------------------------- static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other){ + + printf("received: %s\n", packet); + + /* Response res; res.addr = addr; res.msg = "hello back!!\n"; @@ -270,7 +274,9 @@ static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *b if (n < 0) ssp_error("ERROR in sendto"); //ssp_sendto(res); - return 0; + */ + + return 0; } static int onTimeOut(void *other) { @@ -327,8 +333,9 @@ int server_tests(int client){ if (client) { printf("I'm a client!\n"); - connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + //connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); //connectionless_client("localhost", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + csp_connectionless_client(1, 1, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); //clin("127.0.0.1", "1111"); } else { @@ -336,9 +343,8 @@ int server_tests(int client){ //connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); //servCon ("1111"); - connection_server("1111", buffsize, 10, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + csp_connectionless_server(1, 1, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); } return 0; } - From 1168455e3d0d2a3f83f38eb661b8436fd3865375 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 28 Sep 2019 14:00:23 -0600 Subject: [PATCH 109/400] add CSP tasks, move string conversion to tasks for port --- Program/.gitignore | 2 + Program/include/file_delivery_app.h | 8 +- Program/include/server.h | 7 +- Program/include/tasks.h | 5 + Program/include/types.h | 8 +- Program/src/file_delivery_app.c | 59 +++++------ Program/src/main.c | 12 +-- Program/src/server.c | 145 +++++++++++++++++++++++++--- Program/src/tasks.c | 48 ++++++++- Program/test/server_tests.c | 26 ++++- 10 files changed, 250 insertions(+), 70 deletions(-) diff --git a/Program/.gitignore b/Program/.gitignore index 6017289..8110d87 100644 --- a/Program/.gitignore +++ b/Program/.gitignore @@ -1,3 +1,5 @@ *.o *.a TODO +FreeRTOSv10.2.1 +libcsp \ No newline at end of file diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 8147a15..c5103a5 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -7,8 +7,8 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address); -void ssp_connectionless_server(Protocol_state *p_state); -Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); -void ssp_connection_server(Protocol_state *p_state); -Client *ssp_connection_client(uint32_t cfdp_id, Protocol_state *p_state); +Client *ssp_client(uint32_t cfdp_id, Protocol_state *p_state); +void ssp_server(Protocol_state *p_state); + + #endif \ No newline at end of file diff --git a/Program/include/server.h b/Program/include/server.h index f540486..65db4c3 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -75,7 +75,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe void (*onExit)(void *params)); //#ifdef CSP_NETWORK -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_id, uint8_t src_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), @@ -88,6 +88,11 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, int (*checkExit)(void *other), void (*onExit)(void *other), void *other); + +void csp_connection_server(void); +void csp_connection_client(void); + + //#endif diff --git a/Program/include/tasks.h b/Program/include/tasks.h index 62d1a76..4df44de 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -12,5 +12,10 @@ void *ssp_connectionless_client_task(void* params); void *ssp_connection_client_task(void *params); void *ssp_connection_server_task(void *params); +void *ssp_csp_connectionless_client_task(void *params); +void *ssp_csp_connectionless_server_task(void *params); +void *ssp_csp_connection_client_task(void *params); +void *ssp_csp_connection_server_task(void *params); + #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index 49d1c0a..aeb178e 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -440,7 +440,7 @@ typedef struct remote_entity { unsigned int immediate_nak_mode_enabled : 1; unsigned int prompt_transmission_interval; - //acknowledged or unacknowledged + //0 acknowledged or 1 unacknowledged unsigned int default_transmission_mode: 1; //discard or retain (no idea what this is for yet) @@ -559,7 +559,6 @@ typedef struct request { //add "client" in here to represent local entity typedef struct protocol_state { uint32_t packet_len; - char *server_port; void *server_handle; MIB *mib; @@ -568,7 +567,10 @@ typedef struct protocol_state { List* request_list; Request *current_request; - + + //underlying connection information + Remote_entity *remote_entity; + //lock this uint32_t transaction_sequence_number; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 1955746..4235172 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -11,6 +11,7 @@ #include #include "utils.h" + Protocol_state *init_ftp(uint32_t my_cfdp_address) { //Memory information base @@ -33,19 +34,12 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { ssp_printf("couldn't find your id in the information base\n"); } - char port[20]; - snprintf(port, 20, "%u", server_entity->UT_port); - Protocol_state *p_state = ssp_alloc(sizeof(Protocol_state), 1); p_state->packet_len = PACKET_LEN; p_state->my_cfdp_id = my_cfdp_address; p_state->mib = mib; p_state->close = 0; - - p_state->server_port = ssp_alloc(sizeof(char), 10); - checkAlloc(p_state->server_port, 1); - - strncpy ((char*)p_state->server_port, port, 10); + p_state->remote_entity = server_entity; p_state->request_list = linked_list(); p_state->current_request = NULL; @@ -54,16 +48,24 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { -void ssp_connectionless_server(Protocol_state *p_state) { - p_state->server_handle = ssp_thread_create(16384, ssp_connectionless_server_task, p_state); -} +void ssp_server(Protocol_state *p_state) { + + if (p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == 1) { + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); + + } else if(p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == 0) { + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, p_state); -void ssp_connection_server(Protocol_state *p_state) { - p_state->server_handle = ssp_thread_create(16384, ssp_connection_server_task, p_state); + } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == 1) { + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, p_state); + + } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == 0) { + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, p_state); + } } +Client *ssp_client(uint32_t cfdp_id, Protocol_state *p_state) { -Client *ssp_connection_client(uint32_t cfdp_id, Protocol_state *p_state) { Client *client = ssp_alloc(sizeof(Client), 1); checkAlloc(client, 1); @@ -81,30 +83,19 @@ Client *ssp_connection_client(uint32_t cfdp_id, Protocol_state *p_state) { client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); client->p_state = p_state; - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); - return client; -} + if (remote->type_of_network == posix && remote->default_transmission_mode == 1) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); -Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { + } else if(remote->type_of_network == posix && remote->default_transmission_mode == 0) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); + } else if (remote->type_of_network == csp && remote->default_transmission_mode == 1) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); - Client *client = ssp_alloc(sizeof(Client), 1); - checkAlloc(client, 1); - - client->current_request = NULL; - client->request_list = linked_list(); - client->packet_len = PACKET_LEN; - - Remote_entity *remote = get_remote_entity(p_state->mib, cfdp_id); - - if (remote == NULL) - ssp_printf("couldn't find entity in Remote_entity list\n"); + } else if (remote->type_of_network == csp && remote->default_transmission_mode == 0) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); + } - //TODO clean this up, we don't need multiple instances of UT_ports etc - client->remote_entity = remote; - client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); - client->p_state = p_state; - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); return client; } diff --git a/Program/src/main.c b/Program/src/main.c index 585f0b6..180d382 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -41,21 +41,17 @@ int main(int argc, char** argv) { Protocol_state *p_state = init_ftp(conf->my_cfdp_id); //ssp_connectionless_server(p_state); - ssp_connection_server(p_state); + ssp_server(p_state); //create a client if (conf->client_cfdp_id != 0){ //ssp_printf("input a src file:\n"); //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - Client *new_client = ssp_connection_client(conf->client_cfdp_id, p_state); - + Client *new_client = ssp_client(conf->client_cfdp_id, p_state); + put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); + //send via acknoleged mode //0 acknowledged, 1 unacknowledged - if (conf->my_cfdp_id == 2) { - put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - } - if (conf->my_cfdp_id == 3) - put_request("pic.jpeg", "remote_pic3.jpeg", 0, 0, 0, 1, NULL, NULL, new_client, p_state); ssp_thread_join(new_client->client_handle); printf("client disconnected\n"); diff --git a/Program/src/server.c b/Program/src/server.c index 8a810fe..ae32aae 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -495,14 +495,14 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa //#ifdef CSP_NETWORK //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_id, uint8_t src_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, void *addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params)) { - int err = csp_init(2); + int err = csp_init(src_id); if (err < 0) { ssp_error("ERROR: couldn't init csp\n"); @@ -510,18 +510,23 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendP } //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); csp_socket_t *soc = csp_socket(0); - csp_buffer_init(30, 300); + err = csp_buffer_init(30, 300); - csp_packet_t *packet; - csp_packet_t *packet_recieved; - - memcpy(packet->data, "Hello server!\n", 15); + if (err < 0) { + ssp_error("ERROR: couldn't init csp buffer\n"); + return; + } + err = csp_bind(soc, src_port); if (err < 0) { ssp_error("ERROR: couldn't bind csp\n"); return; } + csp_packet_t *packet_sending; + csp_packet_t *packet_recieved; + + for (;;) { if (exit_now || checkExit(checkExitParams)){ @@ -529,10 +534,10 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendP break; } - packet = csp_buffer_get(1); - memcpy(packet->data, "Hello server!\n", 15); + packet_sending = csp_buffer_get(1); + memcpy(packet_sending->data, "Hello server!\n", 15); - err = csp_sendto(dest_id, 1, 2, 2, 0, packet, 10); + err = csp_sendto(dest_id, dest_port, src_id, src_port, 0, packet_sending, 10); if (err < 0) { ssp_printf("error in csp_sento\n"); } @@ -545,7 +550,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendP else { //do stuff - if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), onRecvParams) == -1) + if (onRecv(-1, (char *)packet_recieved->data, packet_recieved->length, NULL, packet_recieved, sizeof(packet_recieved), onRecvParams) == -1) ssp_printf("recv failed\n"); csp_buffer_free(packet_recieved); @@ -553,7 +558,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, void *onSendP } - csp_buffer_free(packet); + csp_buffer_free(packet_sending); } @@ -609,4 +614,118 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, } } -//#endif \ No newline at end of file +//#endif + + + +//CODE FOR TESTING +/** Example defines */ +#define MY_ADDRESS 1 // Address of local CSP node +#define MY_PORT 10 // Port to send test traffic to + +void csp_connection_server() { + + /* Create socket without any socket options */ + csp_socket_t *sock = csp_socket(CSP_SO_NONE); + + /* Bind all ports to socket */ + csp_bind(sock, CSP_ANY); + + /* Create 10 connections backlog queue */ + csp_listen(sock, 10); + + /* Pointer to current connection and packet */ + csp_conn_t *conn; + csp_packet_t *packet; + + /* Process incoming connections */ + while (1) { + + /* Wait for connection, 10000 ms timeout */ + if ((conn = csp_accept(sock, 10000)) == NULL) + continue; + + /* Read packets. Timout is 100 ms */ + while ((packet = csp_read(conn, 100)) != NULL) { + switch (csp_conn_dport(conn)) { + case MY_PORT: + /* Process packet here */ + printf("Packet received on MY_PORT: %s\r\n", (char *) packet->data); + csp_buffer_free(packet); + break; + + default: + /* Let the service handler reply pings, buffer use, etc. */ + csp_service_handler(conn, packet); + break; + } + } + + /* Close current connection, and handle next */ + csp_close(conn); + + } + +} + +void csp_connection_client() { + + csp_packet_t * packet; + csp_conn_t * conn; + + while (1) { + + /** + * Try ping + */ + + sleep(1); + + int result = csp_ping(MY_ADDRESS, 100, 100, CSP_O_NONE); + printf("Ping result %d [ms]\r\n", result); + + sleep(1); + + /** + * Try data packet to server + */ + + /* Get packet buffer for data */ + packet = csp_buffer_get(100); + if (packet == NULL) { + /* Could not get buffer element */ + printf("Failed to get buffer element\n"); + return; + } + + /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ + conn = csp_connect(CSP_PRIO_NORM, MY_ADDRESS, MY_PORT, 1000, CSP_O_NONE); + if (conn == NULL) { + /* Connect failed */ + printf("Connection failed\n"); + /* Remember to free packet buffer */ + csp_buffer_free(packet); + return; + } + + /* Copy dummy data to packet */ + char *msg = "Hello World"; + strcpy((char *) packet->data, msg); + + /* Set packet length */ + packet->length = strlen(msg); + + /* Send packet */ + if (!csp_send(conn, packet, 1000)) { + /* Send failed */ + printf("Send failed\n"); + csp_buffer_free(packet); + } + + /* Close connection */ + csp_close(conn); + + } + +} + diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 6f12507..b5ea448 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -221,9 +221,13 @@ void *ssp_connectionless_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; + + char port[10]; + snprintf(port, 10, "%d",p_state->remote_entity->UT_port); + + ssp_printf("%s\n", port); - connectionless_server(p_state->server_port, p_state->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); - //csp_connectionless_server(1, 1, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + connectionless_server(port, p_state->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); return NULL; } @@ -250,8 +254,12 @@ void *ssp_connectionless_client_task(void* params){ void *ssp_connection_server_task(void *params) { Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; + + char port[20]; + snprintf(port, 20, "%u",p_state->remote_entity->UT_port); + //1024 is the connection max limit - connection_server(p_state->server_port, p_state->packet_len, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + connection_server(port, p_state->packet_len, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); return NULL; } @@ -273,7 +281,40 @@ void *ssp_connection_client_task(void *params) { return NULL; } +void *ssp_csp_connectionless_server_task(void *params) { + printf("starting csp connectionless server\n"); + Protocol_state *p_state = (Protocol_state *) params; + csp_connectionless_server(p_state->remote_entity->UT_address, + p_state->remote_entity->UT_port, + on_recv_server, + on_time_out_posix, + on_stdin, + check_exit_server, + on_exit_server, + p_state); + + return NULL; +} + +void *ssp_csp_connectionless_client_task(void *params) { + printf("starting csp connectionless client\n"); + Client *client = (Client *) params; + csp_connectionless_client(client->remote_entity->UT_address, + client->remote_entity->UT_port, + client->p_state->remote_entity->UT_address, + client->p_state->remote_entity->UT_port, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + return NULL; +} +void *ssp_csp_connection_client_task(void *params) { + + return NULL; +} + +void *ssp_csp_connection_server_task(void *params) { + + return NULL; +} /*------------------------------------------------------------------------------ free functions @@ -284,7 +325,6 @@ void *ssp_connection_client_task(void *params) { void ssp_cleanup_p_state(Protocol_state *p_state) { p_state->request_list->free(p_state->request_list, ssp_cleanup_req); free_mib(p_state->mib); - ssp_free(p_state->server_port); ssp_free(p_state); } diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 081062f..6dd3b2b 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -14,6 +14,7 @@ #include #include #include +#include "csp.h" #define BUF_SIZE 500 static int clin(char *host, char*port) @@ -328,14 +329,32 @@ static void onExitClient(void *params) { int server_tests(int client){ int buffsize = 10000; - char buff[buffsize]; + /* Init buffer system with 10 packets of maximum 300 bytes each */ + printf("Initialising CSP\r\n"); + csp_buffer_init(5, 300); + + /* Init CSP with address MY_ADDRESS */ + csp_init(1); + + /* Start router task with 500 word stack, OS task priority 1 */ + csp_route_start_task(500, 1); + + + + void *handle = ssp_thread_create(20000, csp_connectionless_client_task, NULL); + void *handle2 = ssp_thread_create(20000, csp_connectionless_server_task, NULL); + + ssp_thread_join(handle); + ssp_thread_join(handle2); + if (client) { printf("I'm a client!\n"); //connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); //connectionless_client("localhost", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); - csp_connectionless_client(1, 1, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + //csp_connectionless_client(1, 1, 2, 2, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); + //csp_connection_client(); //clin("127.0.0.1", "1111"); } else { @@ -343,7 +362,8 @@ int server_tests(int client){ //connectionless_server("1111", buffsize, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); //servCon ("1111"); - csp_connectionless_server(1, 1, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + //csp_connectionless_server(1, 1, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); + //csp_connection_server(); } return 0; From 514df3a707bbd07ed7c4248d758212d3b7b9ad11 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 5 Oct 2019 14:19:30 -0600 Subject: [PATCH 110/400] ftp + csp works for connectionless --- Program/include/port.h | 15 ++++++++ Program/include/server.h | 10 ++++-- Program/include/types.h | 1 + Program/src/file_delivery_app.c | 30 +++++++++++++--- Program/src/mib.c | 2 +- Program/src/port.c | 16 +++++++++ Program/src/server.c | 63 +++++++++++++++------------------ Program/src/tasks.c | 18 +++++----- Program/test/server_tests.c | 55 ++++++++++++++++++++++++---- 9 files changed, 151 insertions(+), 59 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 2930af4..198054b 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -10,6 +10,7 @@ #define POSIX_PORT #define POSIX_FILESYSTEM #define POSIX_NETWORK + #define CSP_NETWORK //#define FREE_RTOS_PORT @@ -18,6 +19,20 @@ #include "types.h" + +#ifdef CSP_NETWORK + #include "csp.h" + typedef struct csp_packet_wrapper { + uint8_t dest_id; + uint8_t dest_port; + uint8_t src_id; + uint8_t src_port; + csp_packet_t *packet; + + } csp_packet_wrapper; +#endif + + void ssp_error( char *msg); void ssp_printf(char *stuff, ...); diff --git a/Program/include/server.h b/Program/include/server.h index 65db4c3..03c7dc5 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -75,11 +75,12 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe void (*onExit)(void *params)); //#ifdef CSP_NETWORK -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_id, uint8_t src_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, void *onSendParams), +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), - void (*onExit)(void *params)); + void (*onExit)(void *params), + void *params); void csp_connectionless_server(uint8_t my_id, uint8_t my_port, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), @@ -93,6 +94,9 @@ void csp_connection_server(void); void csp_connection_client(void); +void test_csp_connectionless_client(void); +void test_csp_connectionless_server(void); + //#endif diff --git a/Program/include/types.h b/Program/include/types.h index aeb178e..5a14799 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -609,5 +609,6 @@ typedef struct client { + #endif diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 4235172..ba262dd 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -24,9 +24,31 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { //adding new cfdp entities to management information base add_new_cfdp_entity(mib, 1, *addr, 1111, posix); - add_new_cfdp_entity(mib, 2, *addr, 1112, posix); + add_new_cfdp_entity(mib, 2, *addr, 1112, posix); + + + +/*------------------------------------------------------------------------------ + you can init csp stuff here if need be +------------------------------------------------------------------------------*/ + + /* Init buffer system with 10 packets of maximum 300 bytes each */ + printf("Initialising CSP\r\n"); + csp_buffer_init(100, 2000); + + /* Init CSP with address MY_ADDRESS */ + csp_init(1); + + /* Start router task with 500 word stack, OS task priority 1 */ + csp_route_start_task(500, 1); + +/*------------------------------------------------------------------------------ + End +------------------------------------------------------------------------------*/ + + add_new_cfdp_entity(mib, 3, 1, 1, csp); - add_new_cfdp_entity(mib, 4, 2, 2, csp); + add_new_cfdp_entity(mib, 4, 1, 2, csp); //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); @@ -57,7 +79,7 @@ void ssp_server(Protocol_state *p_state) { p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, p_state); } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == 1) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, p_state); + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, p_state); } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == 0) { p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, p_state); @@ -74,7 +96,7 @@ Client *ssp_client(uint32_t cfdp_id, Protocol_state *p_state) { client->packet_len = PACKET_LEN; Remote_entity *remote = get_remote_entity(p_state->mib, cfdp_id); - + if (remote == NULL) ssp_printf("couldn't find entity in Remote_entity list\n"); diff --git a/Program/src/mib.c b/Program/src/mib.c index 7c05f67..0b6beab 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -34,7 +34,7 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ remote->CRC_required = 0; //these will be custom set by a config file - remote->default_transmission_mode = 1; + remote->default_transmission_mode = 0; remote ->max_file_segment_len = 1200; checkAlloc(remote, 1); diff --git a/Program/src/port.c b/Program/src/port.c index dbec1f1..303e4ae 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -124,8 +124,24 @@ void ssp_sendto(Response res) { } else if (res.type_of_network == csp) { + csp_packet_t *packet = (csp_packet_t *) res.addr; + csp_packet_t *packet_sending; + if (csp_buffer_remaining() != 0) { + packet_sending = csp_buffer_get(1); + memcpy(packet_sending->data, res.msg, res.packet_len); + int err = csp_sendto(0, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 100); + + if (err < 0) { + ssp_error("ERROR in ssp_sento"); + csp_buffer_free(packet); + } + + } + else + ssp_error("couldn't get new packet for sending!\n"); + } diff --git a/Program/src/server.c b/Program/src/server.c index ae32aae..fa36276 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -495,29 +495,22 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa //#ifdef CSP_NETWORK //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_id, uint8_t src_port, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, void *onSendParams), +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), - void (*onExit)(void *params)) + void (*onExit)(void *params), + void *params) { - int err = csp_init(src_id); + int err = 0; + uint8_t src_id = csp_get_address(); - if (err < 0) { - ssp_error("ERROR: couldn't init csp\n"); - return; - } //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); - csp_socket_t *soc = csp_socket(0); - err = csp_buffer_init(30, 300); + csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); - if (err < 0) { - ssp_error("ERROR: couldn't init csp buffer\n"); - return; - } - err = csp_bind(soc, src_port); + err = csp_bind(soc, CSP_ANY); if (err < 0) { ssp_error("ERROR: couldn't bind csp\n"); return; @@ -527,21 +520,28 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_i csp_packet_t *packet_recieved; + if (csp_buffer_remaining() != 0) { + + packet_sending = csp_buffer_get(1); + packet_sending->id.dst = dest_id; + packet_sending->id.dport = dest_port; + packet_sending->id.src = src_id; + packet_sending->id.sport = src_port; + } + else { + ssp_error("couldn't get new packet for sending!\n"); + exit_now = 1; + } + for (;;) { - if (exit_now || checkExit(checkExitParams)){ + if (exit_now || checkExit(params)){ ssp_printf("exiting server thread\n"); break; } - packet_sending = csp_buffer_get(1); - memcpy(packet_sending->data, "Hello server!\n", 15); - - err = csp_sendto(dest_id, dest_port, src_id, src_port, 0, packet_sending, 10); - if (err < 0) { - ssp_printf("error in csp_sento\n"); - } - + onSend(-1, packet_sending, sizeof(*packet_sending), params); + packet_recieved = csp_recvfrom(soc, 10); //timout @@ -549,18 +549,15 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_i continue; else { - //do stuff - if (onRecv(-1, (char *)packet_recieved->data, packet_recieved->length, NULL, packet_recieved, sizeof(packet_recieved), onRecvParams) == -1) + printf("CLIENT DATA Length: %d\n", packet_recieved->length); + if (onRecv(-1, (char *)packet_recieved->data, packet_recieved->length, NULL, packet_recieved, sizeof(packet_recieved), params) == -1) ssp_printf("recv failed\n"); csp_buffer_free(packet_recieved); } } - csp_buffer_free(packet_sending); - - } @@ -581,7 +578,7 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, return; } //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); - csp_socket_t *soc = csp_socket(0); + csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); err = csp_bind(soc, my_port); @@ -606,7 +603,8 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, } else { //do stuff - if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), other) == -1) + + if (onRecv(-1, (char *)packet->data, packet->length, NULL, &packet, sizeof(packet), other) == -1) ssp_printf("recv failed\n"); csp_buffer_free(packet); @@ -614,9 +612,6 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, } } -//#endif - - //CODE FOR TESTING /** Example defines */ diff --git a/Program/src/tasks.c b/Program/src/tasks.c index b5ea448..e1c7d3b 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -218,14 +218,12 @@ static int on_stdin(void *other) { ------------------------------------------------------------------------------*/ void *ssp_connectionless_server_task(void *params) { - + printf("starting posix connectionless server task\n"); Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; char port[10]; snprintf(port, 10, "%d",p_state->remote_entity->UT_port); - - ssp_printf("%s\n", port); connectionless_server(port, p_state->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); @@ -234,7 +232,7 @@ void *ssp_connectionless_server_task(void *params) { void *ssp_connectionless_client_task(void* params){ - + printf("starting posix connectionless client task \n"); Client *client = (Client *) params; char host_name[INET_ADDRSTRLEN]; @@ -252,19 +250,20 @@ void *ssp_connectionless_client_task(void* params){ } void *ssp_connection_server_task(void *params) { + printf("starting posix connection server\n"); Protocol_state* p_state = (Protocol_state*) params; p_state->transaction_sequence_number = 1; - char port[20]; - snprintf(port, 20, "%u",p_state->remote_entity->UT_port); + char port[10]; + snprintf(port, 10, "%u",p_state->remote_entity->UT_port); //1024 is the connection max limit connection_server(port, p_state->packet_len, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); return NULL; } - void *ssp_connection_client_task(void *params) { + printf("starting posix connection client\n"); Client *client = (Client *) params; char host_name[INET_ADDRSTRLEN]; @@ -300,9 +299,8 @@ void *ssp_csp_connectionless_client_task(void *params) { printf("starting csp connectionless client\n"); Client *client = (Client *) params; csp_connectionless_client(client->remote_entity->UT_address, - client->remote_entity->UT_port, - client->p_state->remote_entity->UT_address, - client->p_state->remote_entity->UT_port, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + client->remote_entity->UT_port, + client->p_state->remote_entity->UT_port, on_send_client, on_recv_client, check_exit_client, on_exit_client, client); return NULL; } diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 6dd3b2b..a063fd7 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -294,22 +294,27 @@ static void onExit(void *other) { } //client stuff -static int onSend(int sfd, void *addr, void *onSendParams) { +static int onSend(int sfd, void *addr, size_t size_of_addr, void *onSendParams) { Response res; res.addr = addr; res.msg = "hello server!!\n"; res.packet_len = 12; - res.size_of_addr = sizeof(struct sockaddr); res.sfd = sfd; + res.type_of_network = csp; + + + //packet_t *buff = csp_buffer_get(1); + //csp_sendto(0, 1, 1, 2, 0, ) //printf("sending message:%s", res.msg); //sendto(sfd, "Hello", 5, 0, (struct sockaddr*)addr, res.size_of_addr); - //ssp_sendto(res); - + ssp_sendto(res); + /* int n = send(sfd, "HELLO", 5, 0); if (n < 0) fprintf(stderr, "partial/failed write\n"); + */ return 0; } @@ -326,6 +331,34 @@ static void onExitClient(void *params) { } +void *ssp_csp_connectionless_server_task_test(void *params) { + printf("starting csp connectionless server\n"); + + csp_connectionless_server(1, + 1, + onRecvServer, + onTimeOut, + onStdIn, + checkExit, + onExit, + NULL); + + return NULL; +} + + + + +void *ssp_csp_connectionless_client_task_test(void *params) { + printf("starting csp connectionless client\n"); + csp_connectionless_client(1, + 1, + 2, + onSend, onRecvClient, checkExitClient, onExitClient, NULL); + return NULL; +} + + int server_tests(int client){ int buffsize = 10000; @@ -333,7 +366,7 @@ int server_tests(int client){ /* Init buffer system with 10 packets of maximum 300 bytes each */ printf("Initialising CSP\r\n"); - csp_buffer_init(5, 300); + csp_buffer_init(100, 300); /* Init CSP with address MY_ADDRESS */ csp_init(1); @@ -343,12 +376,20 @@ int server_tests(int client){ - void *handle = ssp_thread_create(20000, csp_connectionless_client_task, NULL); - void *handle2 = ssp_thread_create(20000, csp_connectionless_server_task, NULL); + //void *handle = ssp_thread_create(20000, csp_connectionless_client_task, NULL); + //void *handle2 = ssp_thread_create(20000, csp_connectionless_server_task, NULL); + + + + void *handle = ssp_thread_create(20000, ssp_csp_connectionless_server_task_test, NULL); + void *handle2 = ssp_thread_create(20000, ssp_csp_connectionless_client_task_test, NULL); + //test_csp_connectionless_server(); + ssp_thread_join(handle); ssp_thread_join(handle2); + if (client) { printf("I'm a client!\n"); //connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); From 37ab717665b85bdc3145086dbd2b00ad182e47e3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 10 Oct 2019 12:12:45 -0600 Subject: [PATCH 111/400] fixed connectionless posix bug --- Program/include/mib.h | 2 +- Program/include/packet.h | 5 +- Program/include/requests.h | 2 +- Program/include/server.h | 19 ++-- Program/include/types.h | 44 ++++++++- Program/src/file_delivery_app.c | 63 +++++++------ Program/src/main.c | 4 +- Program/src/mib.c | 4 +- Program/src/port.c | 43 +++++++-- Program/src/protocol_handler.c | 10 +-- Program/src/requests.c | 8 +- Program/src/server.c | 155 ++++++++++++++++---------------- Program/src/tasks.c | 34 +++++-- Program/test/packet_tests.c | 8 +- Program/test/server_tests.c | 85 ++++++++++-------- 15 files changed, 297 insertions(+), 189 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 71ece45..5baaaa5 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -12,7 +12,7 @@ MIB *init_mib(void); void free_mib(MIB *mib); -int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, enum Network_type); +int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, enum Network_type, int transmission_mode); Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); diff --git a/Program/include/packet.h b/Program/include/packet.h index 6298d6e..41ca11a 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -5,7 +5,10 @@ #define PACKET_HEADER_LEN 224 // PACKET_HEADER_LEN + data max size = (65536 * 8) #define PACKET_MAX_LEN 524512 -#define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes + +//#define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes +#define PACKET_LEN 256 +//dont change this #define PACKET_STATIC_HEADER_LEN 4 //in bytes #include "types.h" diff --git a/Program/include/requests.h b/Program/include/requests.h index 387e226..d921a74 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -16,7 +16,7 @@ Request *put_request( uint8_t fault_handler_overides, uint8_t flow_lable, uint8_t transmission_mode, - char* messages_to_user, + int messages_to_user, char* filestore_requests, Client *client, Protocol_state *p_state diff --git a/Program/include/server.h b/Program/include/server.h index 03c7dc5..0ea64e4 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -82,7 +82,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p void (*onExit)(void *params), void *params); -void csp_connectionless_server(uint8_t my_id, uint8_t my_port, +void csp_connectionless_server(uint8_t my_port, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -90,12 +90,21 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, void (*onExit)(void *other), void *other); -void csp_connection_server(void); -void csp_connection_client(void); +void csp_connection_server(uint8_t my_port, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other); +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params); -void test_csp_connectionless_client(void); -void test_csp_connectionless_server(void); //#endif diff --git a/Program/include/types.h b/Program/include/types.h index 5a14799..d672284 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -7,6 +7,9 @@ #include + +#define ACKNOWLEDGED_MODE 0 +#define UN_ACKNOWLEDGED_MODE 1 /*----------------------------------------------------------------------------- Packet structs for building packets @@ -99,6 +102,42 @@ typedef struct tlv { void *value; } TLV; +//TLV Types +#define MESSAGE_TO_USER 0x02 +#define FILESTORE_RESPONSE 0x01 +#define FILESTORE_REQUEST 0x00 + +//-------------------------------Messages--------------------------------------- +// The type for this TVL is 0x02 hex + +//message types +#define PROXY_PUT_REQUEST 00 +#define PROXY_MESSAGE_TO_USER 01 +#define PROXY_FILESTORE_REQUEST 02 +#define PROXY_FAULT_HANDLER_OVERRIDE 03 +#define PROXY_TRANSMISSION_MODE 04 +#define PROXY_FLOW_LABLE 05 +#define PROXY_SEGMENTATION_CONTROL 06 +#define PROXY_PUT_RESPONSE 07 +#define PROXY_FILESTORE_RESPONSE 08 +#define PROXY_PUT_CANCEL 09 + +typedef struct message_to_user { + + uint32_t message_id; + uint8_t message_type; + +} Message_to_user; + + +//type PROXY_PUT_REQUEST +struct message_proxy { + LV Destination_id; + LV source_file_name; + LV destination_file_name; +}; + +//------------------------------------------------------------------------------ //---------------------------filestore_request---------------------------------- //action codes @@ -486,7 +525,8 @@ typedef struct response { void *addr; enum Network_type type_of_network; - + int transmission_mode; + //getting rid of this soon in favour of client based packet sizes size_t size_of_addr; @@ -540,7 +580,7 @@ typedef struct request { Remote_entity *remote_entity; Local_entity *local_entity; - char* messages_to_user; + TLV message_to_user; char* filestore_requests; //sets the buffer length, for making packets diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index ba262dd..998451b 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -12,7 +12,7 @@ #include "utils.h" -Protocol_state *init_ftp(uint32_t my_cfdp_address) { +Protocol_state *init_ftp(uint32_t my_cfdp_address) { //Memory information base MIB *mib = init_mib(); @@ -23,38 +23,35 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { inet_pton(AF_INET, host_name, addr); //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111, posix); - add_new_cfdp_entity(mib, 2, *addr, 1112, posix); + add_new_cfdp_entity(mib, 1, *addr, 1111, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 5, 3, 3, csp, ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 6, 4, 4, csp, ACKNOWLEDGED_MODE); -/*------------------------------------------------------------------------------ - you can init csp stuff here if need be -------------------------------------------------------------------------------*/ - - /* Init buffer system with 10 packets of maximum 300 bytes each */ - printf("Initialising CSP\r\n"); - csp_buffer_init(100, 2000); - - /* Init CSP with address MY_ADDRESS */ - csp_init(1); - - /* Start router task with 500 word stack, OS task priority 1 */ - csp_route_start_task(500, 1); - -/*------------------------------------------------------------------------------ - End -------------------------------------------------------------------------------*/ - - - add_new_cfdp_entity(mib, 3, 1, 1, csp); - add_new_cfdp_entity(mib, 4, 1, 2, csp); //find server client in mib Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); if (server_entity == NULL) { ssp_printf("couldn't find your id in the information base\n"); } + + if (server_entity->type_of_network == csp) { + + printf("Initialising CSP\r\n"); + + /* Init CSP with address MY_ADDRESS */ + csp_init(server_entity->UT_address); + + /* Init buffer system with 10 packets of maximum PACKET_LEN bytes each */ + csp_buffer_init(10, PACKET_LEN); + + /* Start router task with 500 word stack, OS task priority 1 */ + csp_route_start_task(500, 1); + } Protocol_state *p_state = ssp_alloc(sizeof(Protocol_state), 1); p_state->packet_len = PACKET_LEN; @@ -72,17 +69,17 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { void ssp_server(Protocol_state *p_state) { - if (p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == 1) { + if (p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); - } else if(p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == 0) { + } else if(p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, p_state); - } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == 1) { + } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, p_state); - } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == 0) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, p_state); + } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, p_state); } } @@ -105,16 +102,16 @@ Client *ssp_client(uint32_t cfdp_id, Protocol_state *p_state) { client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); client->p_state = p_state; - if (remote->type_of_network == posix && remote->default_transmission_mode == 1) { + if (remote->type_of_network == posix && remote->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); - } else if(remote->type_of_network == posix && remote->default_transmission_mode == 0) { + } else if(remote->type_of_network == posix && remote->default_transmission_mode == ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); - } else if (remote->type_of_network == csp && remote->default_transmission_mode == 1) { + } else if (remote->type_of_network == csp && remote->default_transmission_mode == ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); - } else if (remote->type_of_network == csp && remote->default_transmission_mode == 0) { + } else if (remote->type_of_network == csp && remote->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); } diff --git a/Program/src/main.c b/Program/src/main.c index 180d382..0119852 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -49,8 +49,8 @@ int main(int argc, char** argv) { //ssp_printf("input a src file:\n"); //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); Client *new_client = ssp_client(conf->client_cfdp_id, p_state); - put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, 0, NULL, NULL, new_client, p_state); - + //put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, ACKNOWLEDGED_MODE, PROXY_PUT_REQUEST, NULL, new_client, p_state); + put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, ACKNOWLEDGED_MODE, 0, NULL, new_client, p_state); //send via acknoleged mode //0 acknowledged, 1 unacknowledged ssp_thread_join(new_client->client_handle); diff --git a/Program/src/mib.c b/Program/src/mib.c index 0b6beab..27db2a1 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -26,7 +26,7 @@ void free_mib(MIB *mib){ } //these configure peers for their specific transmission configuration, should be read in on a config file -int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, Network_type type){ +int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, Network_type type, int transmission_mode){ Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); remote->type_of_network = type; @@ -34,7 +34,7 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ remote->CRC_required = 0; //these will be custom set by a config file - remote->default_transmission_mode = 0; + remote->default_transmission_mode = transmission_mode; remote ->max_file_segment_len = 1200; checkAlloc(remote, 1); diff --git a/Program/src/port.c b/Program/src/port.c index 303e4ae..769ff59 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -114,37 +114,64 @@ int ssp_close(int fd) { ------------------------------------------------------------------------------*/ void ssp_sendto(Response res) { - - if (res.type_of_network == posix) { + + if (res.type_of_network == posix && res.transmission_mode == UN_ACKNOWLEDGED_MODE) { struct sockaddr* addr = (struct sockaddr*) res.addr; + + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); + if (err < 0) { + ssp_error("ERROR in sendto"); + } + } + else if (res.type_of_network == posix && res.transmission_mode == ACKNOWLEDGED_MODE) { + int err = ssp_write(res.sfd, res.msg, res.packet_len); if (err < 0) { - ssp_error("ERROR in ssp_sendto"); + ssp_error("ERROR in write"); } + } - else if (res.type_of_network == csp) { + else if (res.type_of_network == csp /*&& res.transmission_mode == UN_ACKNOWLEDGED_MODE*/) { csp_packet_t *packet = (csp_packet_t *) res.addr; csp_packet_t *packet_sending; if (csp_buffer_remaining() != 0) { packet_sending = csp_buffer_get(1); - + memcpy(packet_sending->data, res.msg, res.packet_len); - int err = csp_sendto(0, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 100); + int err = csp_sendto(0, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 10); if (err < 0) { ssp_error("ERROR in ssp_sento"); - csp_buffer_free(packet); + csp_buffer_free(packet_sending); } } else ssp_error("couldn't get new packet for sending!\n"); - + /* This is commented out because frankly, the connection mode of csp is kind of shit + } else if (res.type_of_network == csp && res.transmission_mode == ACKNOWLEDGED_MODE) { + csp_conn_t *conn = (csp_conn_t *) res.addr; + csp_packet_t *packet_sending; + + if (csp_buffer_remaining() != 0) { + packet_sending = csp_buffer_get(1); + + memcpy(packet_sending->data, res.msg, res.packet_len); + printf("calling csp_send\n"); + int err = csp_send(conn, packet_sending, 10); + + if (err < 0) { + ssp_error("ERROR in ssp_send"); + csp_buffer_free(packet_sending); + } + } + */ } + } int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2df63bd..ef8d816 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -153,11 +153,16 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->dest_cfdp_id = source_id; found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); + found_req->remote_entity = get_remote_entity(p_state->mib, source_id); + found_req->procedure = sending_put_metadata; found_req->res.addr = ssp_alloc(1, res.size_of_addr); memcpy(found_req->res.addr, res.addr, res.size_of_addr); found_req->res.packet_len = p_state->packet_len; found_req->res.sfd = res.sfd; + found_req->res.transmission_mode = p_state->remote_entity->default_transmission_mode; + found_req->res.type_of_network = p_state->remote_entity->type_of_network; + request_list->push(request_list, found_req, transaction_sequence_number); } @@ -263,7 +268,6 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien offset_end = ntohl(offset_end); packet_index += 4; build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); - //ssp_write(res.sfd, req->buff, res.packet_len); ssp_sendto(res); } @@ -344,7 +348,6 @@ void user_request_handler(Response res, Request *req, Client* client) { req->procedure = none; build_eof_packet(req->buff, start, req); req->local_entity->EOF_sent_indication = 1; - //ssp_write(res.sfd, req->buff, res.packet_len); ssp_sendto(res); break; @@ -356,14 +359,12 @@ void user_request_handler(Response res, Request *req, Client* client) { req->procedure = sending_eof; ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); } - //ssp_write(res.sfd, req->buff, res.packet_len); ssp_sendto(res); break; case sending_put_metadata: ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(res, start, req); - //ssp_write(res.sfd, req->buff, res.packet_len); ssp_sendto(res); req->procedure = sending_data; break; @@ -371,7 +372,6 @@ void user_request_handler(Response res, Request *req, Client* client) { case sending_finished: ssp_printf("sending finished packet transaction: %d\n", req->transaction_sequence_number); build_ack(req->buff, start, FINISHED_PDU); - //ssp_write(res.sfd, req->buff, res.packet_len); ssp_sendto(res); req->resent_finished++; break; diff --git a/Program/src/requests.c b/Program/src/requests.c index 0412cbc..c297943 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -71,7 +71,7 @@ Request *put_request(char *source_file_name, uint8_t fault_handler_overides, uint8_t flow_lable, uint8_t transmission_mode, - char* messages_to_user, + int messages_to_user, char* filestore_requests, Client *client, Protocol_state *p_state @@ -101,7 +101,11 @@ Request *put_request(char *source_file_name, req->fault_handler_overides = fault_handler_overides; req->flow_lable = flow_lable; req->transmission_mode = transmission_mode; - req->messages_to_user = messages_to_user; + + + if (messages_to_user & PROXY_MESSAGE_TO_USER) + ssp_printf("add message\n"); + //req->messages_to_user = messages_to_user; req->filestore_requests = filestore_requests; req->res.addr = ssp_alloc(sizeof(uint64_t), 1); diff --git a/Program/src/server.c b/Program/src/server.c index fa36276..eb4f14c 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -96,8 +96,8 @@ static int prepareHost(char *host_name, void *addr, size_t *size_of_addr, char * } } - - + memcpy(addr, cur->ai_addr, cur->ai_addrlen); + *size_of_addr = cur->ai_addrlen; freeaddrinfo(cur); break; @@ -527,6 +527,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p packet_sending->id.dport = dest_port; packet_sending->id.src = src_id; packet_sending->id.sport = src_port; + } else { ssp_error("couldn't get new packet for sending!\n"); @@ -562,7 +563,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p -void csp_connectionless_server(uint8_t my_id, uint8_t my_port, +void csp_connectionless_server(uint8_t my_port, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -571,17 +572,10 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, void *other) { - int err = csp_init(my_id); - - if (err < 0) { - ssp_error("ERROR: couldn't init csp\n"); - return; - } //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); - err = csp_bind(soc, my_port); - + int err = csp_bind(soc, my_port); if (err < 0) { ssp_error("ERROR: couldn't bind csp\n"); @@ -602,9 +596,8 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, onTimeOut(other); } else { - //do stuff - if (onRecv(-1, (char *)packet->data, packet->length, NULL, &packet, sizeof(packet), other) == -1) + if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), other) == -1) ssp_printf("recv failed\n"); csp_buffer_free(packet); @@ -613,18 +606,21 @@ void csp_connectionless_server(uint8_t my_id, uint8_t my_port, } } -//CODE FOR TESTING -/** Example defines */ -#define MY_ADDRESS 1 // Address of local CSP node -#define MY_PORT 10 // Port to send test traffic to - -void csp_connection_server() { +//This doesn't realy work +void csp_connection_server(uint8_t my_port, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other) +{ /* Create socket without any socket options */ csp_socket_t *sock = csp_socket(CSP_SO_NONE); /* Bind all ports to socket */ - csp_bind(sock, CSP_ANY); + csp_bind(sock, my_port); /* Create 10 connections backlog queue */ csp_listen(sock, 10); @@ -634,93 +630,92 @@ void csp_connection_server() { csp_packet_t *packet; /* Process incoming connections */ - while (1) { + for (;;) { - /* Wait for connection, 10000 ms timeout */ - if ((conn = csp_accept(sock, 10000)) == NULL) - continue; - - /* Read packets. Timout is 100 ms */ - while ((packet = csp_read(conn, 100)) != NULL) { - switch (csp_conn_dport(conn)) { - case MY_PORT: - /* Process packet here */ - printf("Packet received on MY_PORT: %s\r\n", (char *) packet->data); - csp_buffer_free(packet); - break; - - default: - /* Let the service handler reply pings, buffer use, etc. */ - csp_service_handler(conn, packet); - break; - } - } + if (exit_now || checkExit(other)){ + ssp_printf("exiting serv thread\n"); + break; + } + + /* Wait for connection, 1000 ms timeout */ + if ((conn = csp_accept(sock, 1000)) == NULL) { + onTimeOut(other); + continue; + } - /* Close current connection, and handle next */ - csp_close(conn); + for (;;) { + + if (exit_now || checkExit(other)) + break; - } + onTimeOut(other); -} + while ((packet = csp_read(conn, 100)) != NULL) { + if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), other) == -1) + ssp_printf("recv failed\n"); -void csp_connection_client() { + csp_buffer_free(packet); - csp_packet_t * packet; - csp_conn_t * conn; + } + } - while (1) { + csp_close(conn); - /** - * Try ping - */ + } - sleep(1); + /* Close current connection, and handle next */ + csp_close(conn); +} - int result = csp_ping(MY_ADDRESS, 100, 100, CSP_O_NONE); - printf("Ping result %d [ms]\r\n", result); +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params) +{ - sleep(1); + csp_packet_t * packet; + csp_conn_t * conn; - /** - * Try data packet to server - */ - /* Get packet buffer for data */ - packet = csp_buffer_get(100); - if (packet == NULL) { - /* Could not get buffer element */ - printf("Failed to get buffer element\n"); - return; - } + while (1) { + + if (exit_now || checkExit(params)){ + ssp_printf("exiting client thread\n"); + break; + } + /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ - conn = csp_connect(CSP_PRIO_NORM, MY_ADDRESS, MY_PORT, 1000, CSP_O_NONE); + conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_O_NONE); if (conn == NULL) { /* Connect failed */ printf("Connection failed\n"); - /* Remember to free packet buffer */ - csp_buffer_free(packet); return; } + + for (;;) { - /* Copy dummy data to packet */ - char *msg = "Hello World"; - strcpy((char *) packet->data, msg); + if (exit_now || checkExit(params)){ + ssp_printf("exiting client thread\n"); + break; + } - /* Set packet length */ - packet->length = strlen(msg); + onSend(-1, conn, sizeof(conn), params); - /* Send packet */ - if (!csp_send(conn, packet, 1000)) { - /* Send failed */ - printf("Send failed\n"); - csp_buffer_free(packet); - } + while ((packet = csp_read(conn, 100)) != NULL) { + if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), params) == -1) + ssp_printf("recv failed\n"); + csp_buffer_free(packet); + + } + } + /* Close connection */ csp_close(conn); } - } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index e1c7d3b..564775c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -16,7 +16,6 @@ Callbacks for the tasks bellow ------------------------------------------------------------------------------*/ -//this function is a callback when using my posix port static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { Protocol_state *p_state = (Protocol_state *) other; @@ -31,10 +30,11 @@ static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t int packet_index = process_pdu_header(packet, 1, res, request_container, p_state->request_list, p_state); p_state->current_request = (*request_container); + if (packet_index < 0) return -1; - parse_packet_server(packet, packet_index, res, (*request_container), p_state); + parse_packet_server(packet, packet_index, p_state->current_request->res, (*request_container), p_state); memset(packet, 0, res.packet_len); return 0; @@ -51,6 +51,7 @@ static int on_recv_client(int sfd, char *packet, uint32_t packet_len, uint32_t * res.packet_len = client->packet_len; res.type_of_network = client->remote_entity->type_of_network; res.size_of_addr = size_of_addr; + res.transmission_mode = client->remote_entity->default_transmission_mode; Request **request_container = &client->current_request; @@ -117,6 +118,9 @@ static int on_send_client(int sfd, void *addr, size_t size_of_addr, void *other) res.addr = addr; res.size_of_addr = size_of_addr; res.type_of_network = client->remote_entity->type_of_network; + res.transmission_mode = client->remote_entity->default_transmission_mode; + + struct user_request_check_params params = { res, @@ -283,8 +287,8 @@ void *ssp_connection_client_task(void *params) { void *ssp_csp_connectionless_server_task(void *params) { printf("starting csp connectionless server\n"); Protocol_state *p_state = (Protocol_state *) params; - csp_connectionless_server(p_state->remote_entity->UT_address, - p_state->remote_entity->UT_port, + csp_connectionless_server( + p_state->remote_entity->UT_port, on_recv_server, on_time_out_posix, on_stdin, @@ -304,13 +308,31 @@ void *ssp_csp_connectionless_client_task(void *params) { return NULL; } -void *ssp_csp_connection_client_task(void *params) { + +void *ssp_csp_connection_server_task(void *params) { + printf("starting csp connection server\n"); + Protocol_state *p_state = (Protocol_state *) params; + csp_connection_server(p_state->remote_entity->UT_port, + on_recv_server, + on_time_out_posix, + on_stdin, + check_exit_server, + on_exit_server, + params); return NULL; } -void *ssp_csp_connection_server_task(void *params) { +void *ssp_csp_connection_client_task(void *params) { + printf("starting csp connection client\n"); + Client *client = (Client *) params; + csp_connection_client(client->remote_entity->UT_address, client->remote_entity->UT_port, + on_send_client, + on_recv_client, + check_exit_client, + on_exit_client, + params); return NULL; } /*------------------------------------------------------------------------------ diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 0fb6ff1..4615ad7 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -240,10 +240,10 @@ int packet_tests() { inet_pton(AF_INET, host_name, addr); //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111, posix); - add_new_cfdp_entity(mib, 2, *addr, 1112, posix); - add_new_cfdp_entity(mib, 3, *addr, 1113, posix); - add_new_cfdp_entity(mib, 4, *addr, 1114, posix); + add_new_cfdp_entity(mib, 1, *addr, 1111, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 3, *addr, 1113, posix, ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 4, *addr, 1114, posix, ACKNOWLEDGED_MODE); Pdu_header *pdu_header = get_header_from_mib(mib, 1, 2); diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index a063fd7..c7d0470 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -261,21 +261,18 @@ static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *b printf("received: %s\n", packet); - /* + Response res; res.addr = addr; res.msg = "hello back!!\n"; - res.packet_len = *buff_size; + res.packet_len = 10; res.size_of_addr = size_of_addr; res.sfd = sfd; - ssp_printf("packet data: %s\n", packet); - - int n = send(sfd, "hello back!", 12, 0); - //int n = sendto(sfd, "Hello back", 12, 0, (struct sockaddr*)addr, res.size_of_addr); - if (n < 0) - ssp_error("ERROR in sendto"); - //ssp_sendto(res); - */ + res.type_of_network = csp; + res.transmission_mode = ACKNOWLEDGED_MODE; + + ssp_sendto(res); + return 0; } @@ -301,21 +298,11 @@ static int onSend(int sfd, void *addr, size_t size_of_addr, void *onSendParams) res.packet_len = 12; res.sfd = sfd; res.type_of_network = csp; - - - //packet_t *buff = csp_buffer_get(1); - //csp_sendto(0, 1, 1, 2, 0, ) - //printf("sending message:%s", res.msg); - - //sendto(sfd, "Hello", 5, 0, (struct sockaddr*)addr, res.size_of_addr); + res.transmission_mode = ACKNOWLEDGED_MODE; + printf("sending!!!\n"); + ssp_sendto(res); - /* - int n = send(sfd, "HELLO", 5, 0); - if (n < 0) - fprintf(stderr, "partial/failed write\n"); - */ - return 0; } static int onRecvClient(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) { @@ -334,31 +321,60 @@ static void onExitClient(void *params) { void *ssp_csp_connectionless_server_task_test(void *params) { printf("starting csp connectionless server\n"); - csp_connectionless_server(1, + csp_connectionless_server( 1, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, - NULL); + params); return NULL; } - - void *ssp_csp_connectionless_client_task_test(void *params) { printf("starting csp connectionless client\n"); csp_connectionless_client(1, 1, 2, - onSend, onRecvClient, checkExitClient, onExitClient, NULL); + onSend, onRecvClient, checkExitClient, onExitClient, params); return NULL; } +void *ssp_csp_connection_server_task_test(void *params) { + csp_connection_server(1, + onRecvServer, + onTimeOut, + onStdIn, + checkExit, + onExit, + params); +} + + +void *ssp_csp_connection_client_task_test(void *params) { + + csp_connection_client(1, 1, + onSend, + onRecvClient, + checkExitClient, + onExitClient, + params); +} +/* +void *ssp_csp_connectionless_client_task_test(void *params) { + csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params); +} +*/ + int server_tests(int client){ int buffsize = 10000; @@ -375,15 +391,10 @@ int server_tests(int client){ csp_route_start_task(500, 1); - - //void *handle = ssp_thread_create(20000, csp_connectionless_client_task, NULL); - //void *handle2 = ssp_thread_create(20000, csp_connectionless_server_task, NULL); - - - - - void *handle = ssp_thread_create(20000, ssp_csp_connectionless_server_task_test, NULL); - void *handle2 = ssp_thread_create(20000, ssp_csp_connectionless_client_task_test, NULL); +// void *handle = ssp_thread_create(20000, ssp_csp_connectionless_server_task_test, NULL); +// void *handle2 = ssp_thread_create(20000, ssp_csp_connectionless_client_task_test, NULL); + void *handle = ssp_thread_create(20000, ssp_csp_connection_server_task_test, NULL); + void *handle2 = ssp_thread_create(20000, ssp_csp_connection_client_task_test, NULL); //test_csp_connectionless_server(); ssp_thread_join(handle); From c7d3a45dc0acdcc7e484c0f60a35f4144ae8ab4e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 12 Oct 2019 12:00:39 -0600 Subject: [PATCH 112/400] Change all Protocol_state to Ftp app --- Program/include/file_delivery_app.h | 6 +-- Program/include/protocol_handler.h | 4 +- Program/include/requests.h | 11 ++-- Program/include/tasks.h | 2 +- Program/include/types.h | 10 ++-- Program/src/file_delivery_app.c | 51 ++++++++++--------- Program/src/main.c | 18 ++++--- Program/src/protocol_handler.c | 20 ++++---- Program/src/requests.c | 33 ++++++------ Program/src/tasks.c | 79 +++++++++++++++-------------- 10 files changed, 118 insertions(+), 116 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index c5103a5..e13c0f1 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -5,10 +5,10 @@ #define FTP_APP_H #include "types.h" -Protocol_state *init_ftp(uint32_t my_cfdp_address); +FTP *init_ftp(uint32_t my_cfdp_address); -Client *ssp_client(uint32_t cfdp_id, Protocol_state *p_state); -void ssp_server(Protocol_state *p_state); +Client *ssp_client(uint32_t cfdp_id, FTP *app); +void ssp_server(FTP *app); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index c5502bd..fcb58c0 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -8,11 +8,11 @@ #define TIMEOUT_BEFORE_CANCEL_REQUEST 100 //for use -void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state); +void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, uint32_t packet_index, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request); -int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, Protocol_state *p_state); +int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); //for testing diff --git a/Program/include/requests.h b/Program/include/requests.h index d921a74..513a5ee 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -9,18 +9,13 @@ void ssp_cleanup_req(void *request); Request *init_request(uint32_t buff_len); -Request *put_request( - char *source_file_name, +Request *put_request(char *source_file_name, char *destination_file_name, - uint8_t segmentation_control, - uint8_t fault_handler_overides, - uint8_t flow_lable, uint8_t transmission_mode, - int messages_to_user, - char* filestore_requests, Client *client, - Protocol_state *p_state + FTP *app ); +int send_request(Client *client, Request *req); #endif \ No newline at end of file diff --git a/Program/include/tasks.h b/Program/include/tasks.h index 4df44de..cd93175 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -6,7 +6,7 @@ void ssp_cleanup_client(Client *client); void ssp_cleanup_req(void *request); -void ssp_cleanup_p_state(Protocol_state *p_state); +void ssp_cleanup_ftp(FTP *app); void *ssp_connectionless_server_task(void *params); void *ssp_connectionless_client_task(void* params); diff --git a/Program/include/types.h b/Program/include/types.h index d672284..7801edf 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -124,7 +124,7 @@ typedef struct tlv { typedef struct message_to_user { - uint32_t message_id; + uint32_t message_id_cfdp; uint8_t message_type; } Message_to_user; @@ -597,7 +597,7 @@ typedef struct request { } Request; //add "client" in here to represent local entity -typedef struct protocol_state { +typedef struct ftp { uint32_t packet_len; void *server_handle; MIB *mib; @@ -611,6 +611,8 @@ typedef struct protocol_state { //underlying connection information Remote_entity *remote_entity; + List *active_clients; + //lock this uint32_t transaction_sequence_number; @@ -619,7 +621,7 @@ typedef struct protocol_state { //bool for exiting the server thread uint8_t close; -} Protocol_state; +} FTP; //outgoing requests spin up client threads @@ -638,7 +640,7 @@ typedef struct client { //packet header, useful for copying into outgoing packets Pdu_header *pdu_header; - Protocol_state *p_state; + FTP *app; //bool for exiting the client thread uint8_t close; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 998451b..50c92ae 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -12,7 +12,7 @@ #include "utils.h" -Protocol_state *init_ftp(uint32_t my_cfdp_address) { +FTP *init_ftp(uint32_t my_cfdp_address) { //Memory information base MIB *mib = init_mib(); @@ -53,37 +53,40 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address) { csp_route_start_task(500, 1); } - Protocol_state *p_state = ssp_alloc(sizeof(Protocol_state), 1); - p_state->packet_len = PACKET_LEN; - p_state->my_cfdp_id = my_cfdp_address; - p_state->mib = mib; - p_state->close = 0; - p_state->remote_entity = server_entity; - - p_state->request_list = linked_list(); - p_state->current_request = NULL; - return p_state; + FTP *app = ssp_alloc(sizeof(FTP), 1); + app->packet_len = PACKET_LEN; + app->my_cfdp_id = my_cfdp_address; + app->mib = mib; + app->close = 0; + app->remote_entity = server_entity; + app->active_clients = linked_list(); + app->request_list = linked_list(); + app->current_request = NULL; + + ssp_server(app); + + return app; } -void ssp_server(Protocol_state *p_state) { +void ssp_server(FTP *app) { - if (p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); + if (app->remote_entity->type_of_network == posix && app->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); - } else if(p_state->remote_entity->type_of_network == posix && p_state->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, p_state); + } else if(app->remote_entity->type_of_network == posix && app->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); - } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, p_state); + } else if (app->remote_entity->type_of_network == csp && app->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); - } else if (p_state->remote_entity->type_of_network == csp && p_state->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { - p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, p_state); + } else if (app->remote_entity->type_of_network == csp && app->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); } } -Client *ssp_client(uint32_t cfdp_id, Protocol_state *p_state) { +Client *ssp_client(uint32_t cfdp_id, FTP *app) { Client *client = ssp_alloc(sizeof(Client), 1); checkAlloc(client, 1); @@ -92,15 +95,15 @@ Client *ssp_client(uint32_t cfdp_id, Protocol_state *p_state) { client->request_list = linked_list(); client->packet_len = PACKET_LEN; - Remote_entity *remote = get_remote_entity(p_state->mib, cfdp_id); + Remote_entity *remote = get_remote_entity(app->mib, cfdp_id); if (remote == NULL) ssp_printf("couldn't find entity in Remote_entity list\n"); //TODO clean this up, we don't need multiple instances of UT_ports etc client->remote_entity = remote; - client->pdu_header = get_header_from_mib(p_state->mib, cfdp_id, p_state->my_cfdp_id); - client->p_state = p_state; + client->pdu_header = get_header_from_mib(app->mib, cfdp_id, app->my_cfdp_id); + client->app = app; if (remote->type_of_network == posix && remote->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); diff --git a/Program/src/main.c b/Program/src/main.c index 0119852..5634a65 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -38,26 +38,30 @@ int main(int argc, char** argv) { printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } - Protocol_state *p_state = init_ftp(conf->my_cfdp_id); + + FTP *app = init_ftp(conf->my_cfdp_id); - //ssp_connectionless_server(p_state); - ssp_server(p_state); + //ssp_connectionless_server(app); + //ssp_server(app); //create a client if (conf->client_cfdp_id != 0){ //ssp_printf("input a src file:\n"); //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - Client *new_client = ssp_client(conf->client_cfdp_id, p_state); - //put_request("pic.jpeg", "remote_pic1.jpeg", 0, 0, 0, ACKNOWLEDGED_MODE, PROXY_PUT_REQUEST, NULL, new_client, p_state); - put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, ACKNOWLEDGED_MODE, 0, NULL, new_client, p_state); + Client *new_client = ssp_client(conf->client_cfdp_id, app); + + Request *req = put_request("pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, new_client, app); + send_request(new_client, req); + + //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, ACKNOWLEDGED_MODE, 0, NULL, new_client, app); //send via acknoleged mode //0 acknowledged, 1 unacknowledged ssp_thread_join(new_client->client_handle); printf("client disconnected\n"); } - ssp_thread_join(p_state->server_handle); + ssp_thread_join(app->server_handle); free(conf); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index ef8d816..b4bf05e 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -100,7 +100,7 @@ static int find_request(void *element, void *args) { /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns -1 on fail*/ -int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, Protocol_state *p_state) { +int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header *header = (Pdu_header *) packet; @@ -118,8 +118,8 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; - if (p_state->my_cfdp_id != dest_id){ - ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", p_state->my_cfdp_id, dest_id); + if (app->my_cfdp_id != dest_id){ + ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); return -1; } @@ -145,23 +145,23 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r //server side, receiving requests (this should be its own function) if (found_req == NULL && is_server) { - found_req = init_request(p_state->packet_len); + found_req = init_request(app->packet_len); ssp_printf("incoming new request\n"); //Make new request and add it found_req->transmission_mode = header->transmission_mode; found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; found_req->transaction_sequence_number = transaction_sequence_number; - found_req->pdu_header = get_header_from_mib(p_state->mib, source_id, p_state->my_cfdp_id); - found_req->remote_entity = get_remote_entity(p_state->mib, source_id); + found_req->pdu_header = get_header_from_mib(app->mib, source_id, app->my_cfdp_id); + found_req->remote_entity = get_remote_entity(app->mib, source_id); found_req->procedure = sending_put_metadata; found_req->res.addr = ssp_alloc(1, res.size_of_addr); memcpy(found_req->res.addr, res.addr, res.size_of_addr); - found_req->res.packet_len = p_state->packet_len; + found_req->res.packet_len = app->packet_len; found_req->res.sfd = res.sfd; - found_req->res.transmission_mode = p_state->remote_entity->default_transmission_mode; - found_req->res.type_of_network = p_state->remote_entity->type_of_network; + found_req->res.transmission_mode = app->remote_entity->default_transmission_mode; + found_req->res.type_of_network = app->remote_entity->type_of_network; request_list->push(request_list, found_req, transaction_sequence_number); } @@ -475,7 +475,7 @@ void on_server_time_out(Response res, Request *req) { } //fills the current_request struct for the server, incomming requests -void parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Protocol_state *p_state) { +void parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, FTP *app) { if (packet_index == 0) return; diff --git a/Program/src/requests.c b/Program/src/requests.c index c297943..f8de0c9 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -67,14 +67,9 @@ Request *init_request(uint32_t buff_len) { //data will be delivered Request *put_request(char *source_file_name, char *destination_file_name, - uint8_t segmentation_control, - uint8_t fault_handler_overides, - uint8_t flow_lable, uint8_t transmission_mode, - int messages_to_user, - char* filestore_requests, Client *client, - Protocol_state *p_state + FTP *app ) { uint32_t file_size = get_file_size(source_file_name); @@ -87,7 +82,7 @@ Request *put_request(char *source_file_name, req->file = create_file(source_file_name, 0); //build a request - req->transaction_sequence_number = p_state->transaction_sequence_number++; + req->transaction_sequence_number = app->transaction_sequence_number++; //enumeration req->procedure = sending_put_metadata; @@ -97,20 +92,22 @@ Request *put_request(char *source_file_name, memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); - req->segmentation_control = segmentation_control; - req->fault_handler_overides = fault_handler_overides; - req->flow_lable = flow_lable; req->transmission_mode = transmission_mode; - - - if (messages_to_user & PROXY_MESSAGE_TO_USER) - ssp_printf("add message\n"); - //req->messages_to_user = messages_to_user; - req->filestore_requests = filestore_requests; - req->res.addr = ssp_alloc(sizeof(uint64_t), 1); + return req; +} + + +int send_request(Client *client, Request *req) { client->request_list->insert(client->request_list, req, 0); +} +/* +//Omission of source and destination filenames shall indicate that only Meta +//data will be delivered + + +int add_proxy_to_request(uint32_t beneficial_cfid, Request *req) { - return req; } +*/ \ No newline at end of file diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 564775c..8f6d61c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -18,23 +18,23 @@ ------------------------------------------------------------------------------*/ static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { - Protocol_state *p_state = (Protocol_state *) other; + FTP *app = (FTP *) other; Response res; res.addr = addr; res.sfd = sfd; - res.packet_len = p_state->packet_len; + res.packet_len = app->packet_len; res.size_of_addr = size_of_addr; - Request **request_container = &p_state->current_request; + Request **request_container = &app->current_request; - int packet_index = process_pdu_header(packet, 1, res, request_container, p_state->request_list, p_state); - p_state->current_request = (*request_container); + int packet_index = process_pdu_header(packet, 1, res, request_container, app->request_list, app); + app->current_request = (*request_container); if (packet_index < 0) return -1; - parse_packet_server(packet, packet_index, p_state->current_request->res, (*request_container), p_state); + parse_packet_server(packet, packet_index, app->current_request->res, (*request_container), app); memset(packet, 0, res.packet_len); return 0; @@ -55,7 +55,7 @@ static int on_recv_client(int sfd, char *packet, uint32_t packet_len, uint32_t * Request **request_container = &client->current_request; - int packet_index = process_pdu_header(packet, 0, res, request_container, client->request_list, client->p_state); + int packet_index = process_pdu_header(packet, 0, res, request_container, client->request_list, client->app); if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; @@ -140,18 +140,18 @@ static void timeout_check(void *request, void *args) { //this function is a callback when using my posix ports static int on_time_out_posix(void *other) { - Protocol_state *p_state = (Protocol_state*) other; - if(p_state->current_request == NULL) + FTP *app = (FTP*) other; + if(app->current_request == NULL) return 0; - p_state->request_list->iterate(p_state->request_list, timeout_check, p_state->request_list); + app->request_list->iterate(app->request_list, timeout_check, app->request_list); return 0; } static int check_exit_server(void *params) { - Protocol_state *p_state = (Protocol_state*) params; - if (p_state->close) + FTP *app = (FTP*) params; + if (app->close) return 1; return 0; } @@ -169,8 +169,8 @@ static void on_exit_client (void *params) { } static void on_exit_server (void *params) { - Protocol_state *p_state = (Protocol_state*) params; - ssp_cleanup_p_state(p_state); + FTP *app = (FTP*) params; + ssp_cleanup_ftp(app); } @@ -180,8 +180,8 @@ static void on_exit_server (void *params) { static int on_stdin(void *other) { /* - Protocol_state *p_state = (Protocol_state *) other; - Request *req = p_state->newClient->req; + FTP *app = (FTP *) other; + Request *req = app->newClient->req; char input[MAX_PATH]; fgets(input, MAX_PATH, stdin); @@ -193,21 +193,21 @@ static int on_stdin(void *other) { ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); return 0; } - memcpy(p_state->newClient->req->source_file_name, input, MAX_PATH); + memcpy(app->newClient->req->source_file_name, input, MAX_PATH); ssp_printf("Enter a destination file name:\n"); } else if (strnlen(req->destination_file_name, MAX_PATH) == 0){ - memcpy(p_state->newClient->req->destination_file_name, input, MAX_PATH); - ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, p_state->newClient->cfdp_id); + memcpy(app->newClient->req->destination_file_name, input, MAX_PATH); + ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", app->newClient->req->source_file_name, app->newClient->req->destination_file_name, app->newClient->cfdp_id); ssp_printf("cancel connection mode (yes):\n"); } else if (strncmp(input, "yes", 3) == 0){ ssp_printf("sending file connectionless\n"); - put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 1, NULL, NULL, p_state->newClient, p_state); + put_request(app->newClient->req->source_file_name, app->newClient->req->destination_file_name, 0, 0, 0, 1, NULL, NULL, app->newClient, app); } else { ssp_printf("sending file connected\n"); - put_request(p_state->newClient->req->source_file_name, p_state->newClient->req->destination_file_name, 0, 0, 0, 0, NULL, NULL, p_state->newClient, p_state); + put_request(app->newClient->req->source_file_name, app->newClient->req->destination_file_name, 0, 0, 0, 0, NULL, NULL, app->newClient, app); } } */ @@ -223,13 +223,13 @@ static int on_stdin(void *other) { ------------------------------------------------------------------------------*/ void *ssp_connectionless_server_task(void *params) { printf("starting posix connectionless server task\n"); - Protocol_state* p_state = (Protocol_state*) params; - p_state->transaction_sequence_number = 1; + FTP* app = (FTP*) params; + app->transaction_sequence_number = 1; char port[10]; - snprintf(port, 10, "%d",p_state->remote_entity->UT_port); + snprintf(port, 10, "%d",app->remote_entity->UT_port); - connectionless_server(port, p_state->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + connectionless_server(port, app->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, app); return NULL; } @@ -255,14 +255,14 @@ void *ssp_connectionless_client_task(void* params){ void *ssp_connection_server_task(void *params) { printf("starting posix connection server\n"); - Protocol_state* p_state = (Protocol_state*) params; - p_state->transaction_sequence_number = 1; + FTP* app = (FTP*) params; + app->transaction_sequence_number = 1; char port[10]; - snprintf(port, 10, "%u",p_state->remote_entity->UT_port); + snprintf(port, 10, "%u",app->remote_entity->UT_port); //1024 is the connection max limit - connection_server(port, p_state->packet_len, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, p_state); + connection_server(port, app->packet_len, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, app); return NULL; } @@ -286,15 +286,15 @@ void *ssp_connection_client_task(void *params) { void *ssp_csp_connectionless_server_task(void *params) { printf("starting csp connectionless server\n"); - Protocol_state *p_state = (Protocol_state *) params; + FTP *app = (FTP *) params; csp_connectionless_server( - p_state->remote_entity->UT_port, + app->remote_entity->UT_port, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, - p_state); + app); return NULL; } @@ -304,15 +304,15 @@ void *ssp_csp_connectionless_client_task(void *params) { Client *client = (Client *) params; csp_connectionless_client(client->remote_entity->UT_address, client->remote_entity->UT_port, - client->p_state->remote_entity->UT_port, on_send_client, on_recv_client, check_exit_client, on_exit_client, client); + client->app->remote_entity->UT_port, on_send_client, on_recv_client, check_exit_client, on_exit_client, client); return NULL; } void *ssp_csp_connection_server_task(void *params) { printf("starting csp connection server\n"); - Protocol_state *p_state = (Protocol_state *) params; - csp_connection_server(p_state->remote_entity->UT_port, + FTP *app = (FTP *) params; + csp_connection_server(app->remote_entity->UT_port, on_recv_server, on_time_out_posix, on_stdin, @@ -342,10 +342,11 @@ void *ssp_csp_connection_client_task(void *params) { ------------------------------------------------------------------------------*/ -void ssp_cleanup_p_state(Protocol_state *p_state) { - p_state->request_list->free(p_state->request_list, ssp_cleanup_req); - free_mib(p_state->mib); - ssp_free(p_state); +void ssp_cleanup_ftp(FTP *app) { + app->request_list->free(app->request_list, ssp_cleanup_req); + app->active_clients->free(app->active_clients, ssp_cleanup_client); + free_mib(app->mib); + ssp_free(app); } void ssp_cleanup_client(Client *client) { From e1cc7e01801ab7d0f161b36c4fdba4fb2bd5d437 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 12 Oct 2019 13:22:16 -0600 Subject: [PATCH 113/400] Add only remove nodes from list function --- Program/include/list.h | 1 + Program/src/list.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Program/include/list.h b/Program/include/list.h index baff40c..87a2c2a 100644 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -33,6 +33,7 @@ typedef struct List //returns a void pointer that should be cast to the type void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); struct NODE *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + void (*freeOnlyList)(struct List *list); void (*freeNode)(NODE *node); } List; diff --git a/Program/src/list.c b/Program/src/list.c index b571282..68ea522 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -182,6 +182,23 @@ static void freeList(List *list, void (*f)(void *element)) free(list); } + +static void freeNodes(List *list) { + + NODE *cur = list->head->next; + + while (cur->next != NULL) + { + NODE *n = cur; + cur = cur->next; + freeNode(n); + } + free(list->head); + free(list->tail); + free(list); + +} + /*------------------------------------------------------------------------------ This function finds an element, returns and element on success and NULL on failure. The return value should be cast to the element type. can search with @@ -292,6 +309,7 @@ List *linked_list() newList->insertAt = insertAt; newList->findNode = findNode; newList->freeNode = freeNode; + newList->freeOnlyList = freeNodes; return newList; } From f5c53880d189cce03f82c42edbab9999e09d0bba Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 12 Oct 2019 13:22:43 -0600 Subject: [PATCH 114/400] change put request to start up thread --- Program/include/requests.h | 6 +++--- Program/include/tasks.h | 3 ++- Program/include/types.h | 4 +++- Program/src/main.c | 15 +++++++++++---- Program/src/requests.c | 22 ++++++++++++++++------ Program/src/tasks.c | 21 ++++++++++++++++++--- 6 files changed, 53 insertions(+), 18 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 513a5ee..0047b0e 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -9,13 +9,13 @@ void ssp_cleanup_req(void *request); Request *init_request(uint32_t buff_len); -Request *put_request(char *source_file_name, +Request *put_request( + uint32_t dest_id, + char *source_file_name, char *destination_file_name, uint8_t transmission_mode, - Client *client, FTP *app ); -int send_request(Client *client, Request *req); #endif \ No newline at end of file diff --git a/Program/include/tasks.h b/Program/include/tasks.h index cd93175..5f8f0c0 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -3,6 +3,7 @@ #define SSP_TASKS_H #include "types.h" +#include "list.h" void ssp_cleanup_client(Client *client); void ssp_cleanup_req(void *request); @@ -16,6 +17,6 @@ void *ssp_csp_connectionless_client_task(void *params); void *ssp_csp_connectionless_server_task(void *params); void *ssp_csp_connection_client_task(void *params); void *ssp_csp_connection_server_task(void *params); - +void ssp_join_clients(List *clients); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index 7801edf..b166755 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -4,6 +4,7 @@ #include "stdint.h" #include "list.h" +#include #include @@ -568,6 +569,7 @@ typedef struct request { uint8_t fault_handler_overides; uint8_t flow_lable; uint8_t transmission_mode; + bool paused; //counter for resending eof packets == 3 uint8_t resent_eof; @@ -643,7 +645,7 @@ typedef struct client { FTP *app; //bool for exiting the client thread - uint8_t close; + bool close; } Client; diff --git a/Program/src/main.c b/Program/src/main.c index 5634a65..2546fd6 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -22,6 +22,7 @@ #include "server.h" //for ssp_thread_join, can use p_thread join on linux #include "port.h" +#include "tasks.h" //exit handler variable for the main thread static int *exit_now; @@ -49,19 +50,25 @@ int main(int argc, char** argv) { //ssp_printf("input a src file:\n"); //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - Client *new_client = ssp_client(conf->client_cfdp_id, app); + //Client *new_client = ssp_client(conf->client_cfdp_id, app); - Request *req = put_request("pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, new_client, app); - send_request(new_client, req); + Request *req = put_request(1, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); + + + //send_request(new_client, req); //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, ACKNOWLEDGED_MODE, 0, NULL, new_client, app); //send via acknoleged mode //0 acknowledged, 1 unacknowledged - ssp_thread_join(new_client->client_handle); + printf("client disconnected\n"); } + //ssp_thread_join(app->server_handle); + ssp_join_clients(app->active_clients); ssp_thread_join(app->server_handle); + + free(conf); diff --git a/Program/src/requests.c b/Program/src/requests.c index f8de0c9..fb7605b 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -15,6 +15,8 @@ #include "types.h" #include "filesystem_funcs.h" #include "mib.h" +#include +#include "file_delivery_app.h" void ssp_cleanup_req(void *request) { @@ -65,18 +67,26 @@ Request *init_request(uint32_t buff_len) { //Omission of source and destination filenames shall indicate that only Meta //data will be delivered -Request *put_request(char *source_file_name, +Request *put_request( + uint32_t dest_id, + char *source_file_name, char *destination_file_name, uint8_t transmission_mode, - Client *client, FTP *app ) { uint32_t file_size = get_file_size(source_file_name); - + Client *client; + if (file_size == -1) return NULL; + client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); + if (client == NULL) { + client = ssp_client(dest_id, app); + app->active_clients->insert(app->active_clients, client, dest_id); + } + //give the client a new request to perform Request *req = init_request(client->packet_len); req->file = create_file(source_file_name, 0); @@ -86,6 +96,7 @@ Request *put_request(char *source_file_name, //enumeration req->procedure = sending_put_metadata; + req->paused = true; req->dest_cfdp_id = client->remote_entity->cfdp_id; req->file_size = file_size; @@ -95,13 +106,12 @@ Request *put_request(char *source_file_name, req->transmission_mode = transmission_mode; req->res.addr = ssp_alloc(sizeof(uint64_t), 1); + client->request_list->insert(client->request_list, req, 0); + return req; } -int send_request(Client *client, Request *req) { - client->request_list->insert(client->request_list, req, 0); -} /* //Omission of source and destination filenames shall indicate that only Meta //data will be delivered diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 8f6d61c..55f7ddb 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -174,8 +174,6 @@ static void on_exit_server (void *params) { } - - //this function is just for posix fun static int on_stdin(void *other) { @@ -341,11 +339,28 @@ void *ssp_csp_connection_client_task(void *params) { ------------------------------------------------------------------------------*/ +static void ssp_client_join(void *element, void*args) { + Client *client = (Client *) element; + ssp_thread_join(client->client_handle); +} + +void ssp_join_clients(List *clients) { + clients->iterate(clients, ssp_client_join, NULL); +} + +static void exit_client(void *element, void *args) { + Client *client = (Client *) element; + client->close = true; +} void ssp_cleanup_ftp(FTP *app) { app->request_list->free(app->request_list, ssp_cleanup_req); - app->active_clients->free(app->active_clients, ssp_cleanup_client); + + if (app->close == true) + app->active_clients->iterate(app->active_clients, exit_client, NULL); + free_mib(app->mib); + app->active_clients->freeOnlyList(app->active_clients); ssp_free(app); } From 7fae8865281a3311622852393210a0181ebf316e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 12 Oct 2019 13:31:06 -0600 Subject: [PATCH 115/400] add onExit handler for csp servers --- Program/src/main.c | 3 +-- Program/src/server.c | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index 2546fd6..9ca0ec1 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -52,8 +52,7 @@ int main(int argc, char** argv) { //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); //Client *new_client = ssp_client(conf->client_cfdp_id, app); - Request *req = put_request(1, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); - + Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); //send_request(new_client, req); diff --git a/Program/src/server.c b/Program/src/server.c index eb4f14c..008f383 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -660,6 +660,7 @@ void csp_connection_server(uint8_t my_port, } csp_close(conn); + onExit(other); } @@ -715,7 +716,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, /* Close connection */ csp_close(conn); - + onExit(params); } } From 2bd6884929eef3f646265a4cf43c2713239fe622 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 12 Oct 2019 13:32:06 -0600 Subject: [PATCH 116/400] Delete dead code --- Program/src/port.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 769ff59..f39e1f3 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -150,28 +150,9 @@ void ssp_sendto(Response res) { } else ssp_error("couldn't get new packet for sending!\n"); - /* This is commented out because frankly, the connection mode of csp is kind of shit - } else if (res.type_of_network == csp && res.transmission_mode == ACKNOWLEDGED_MODE) { - - csp_conn_t *conn = (csp_conn_t *) res.addr; - csp_packet_t *packet_sending; - - if (csp_buffer_remaining() != 0) { - packet_sending = csp_buffer_get(1); - - memcpy(packet_sending->data, res.msg, res.packet_len); - printf("calling csp_send\n"); - int err = csp_send(conn, packet_sending, 10); - - if (err < 0) { - ssp_error("ERROR in ssp_send"); - csp_buffer_free(packet_sending); - } - } - */ + } - - + } int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { From a932f0315f4405c1e0ffce1d77dfbaf9e6e44f56 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 12 Oct 2019 13:40:09 -0600 Subject: [PATCH 117/400] fixed some things, should be working in a different branch --- Program/src/main.c | 13 ------------- Program/src/protocol_handler.c | 11 +++++++++-- Program/src/server.c | 3 ++- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index 9ca0ec1..30ac097 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -42,25 +42,12 @@ int main(int argc, char** argv) { FTP *app = init_ftp(conf->my_cfdp_id); - //ssp_connectionless_server(app); - //ssp_server(app); - //create a client if (conf->client_cfdp_id != 0){ - //ssp_printf("input a src file:\n"); - //Client *new_client = ssp_connectionless_client(conf->client_cfdp_id, p_state); - //Client *new_client = ssp_client(conf->client_cfdp_id, app); - Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); - //send_request(new_client, req); - //put_request("pic.jpeg", "remote_pic2.jpeg", 0, 0, 0, ACKNOWLEDGED_MODE, 0, NULL, new_client, app); - //send via acknoleged mode //0 acknowledged, 1 unacknowledged - - - printf("client disconnected\n"); } //ssp_thread_join(app->server_handle); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index b4bf05e..af3bafa 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -331,12 +331,15 @@ static void check_req_status(Request *req, Client *client) { } } -//current user request, to send to remote +//current user request, to send to server void user_request_handler(Response res, Request *req, Client* client) { if (req == NULL) return; + if (req->paused) + return; + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req, client); @@ -412,6 +415,9 @@ static void print_offsets(void *element, void *args) { void on_server_time_out(Response res, Request *req) { + + if (req->paused) + return; if (reset_timeout(req)) return; @@ -419,7 +425,7 @@ void on_server_time_out(Response res, Request *req) { if (req->procedure == none) return; - if (req->transmission_mode == 1) + if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); @@ -482,6 +488,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_header *header = (Pdu_header *) packet; + //set timeout to 0, because received data req->timeout = 0; //process file data diff --git a/Program/src/server.c b/Program/src/server.c index 008f383..c97633d 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -606,7 +606,7 @@ void csp_connectionless_server(uint8_t my_port, } } -//This doesn't realy work +//This doesn't work because it can't have multiple connections, maybe revisit? void csp_connection_server(uint8_t my_port, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), @@ -668,6 +668,7 @@ void csp_connection_server(uint8_t my_port, csp_close(conn); } + void csp_connection_client(uint8_t dest_id, uint8_t dest_port, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , From 901efd483e6b8c738176a98720453cee0b8ba6ca Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 14 Oct 2019 15:28:09 -0600 Subject: [PATCH 118/400] Add Proxy_put request data structure --- Program/include/requests.h | 5 +- Program/include/types.h | 44 +++++++++------- Program/src/list.c | 1 + Program/src/main.c | 2 + Program/src/requests.c | 73 +++++++++++++++++++++++++-- Program/test/main.c | 16 ++---- Program/test/protocol_handler_tests.c | 20 ++++---- Program/test/request_tests.c | 38 ++++++++++++-- 8 files changed, 152 insertions(+), 47 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 0047b0e..d7ac154 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -8,6 +8,7 @@ void ssp_cleanup_req(void *request); Request *init_request(uint32_t buff_len); +void start_request(Request *req); Request *put_request( uint32_t dest_id, @@ -17,5 +18,7 @@ Request *put_request( FTP *app ); - +int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); +//Frees a message struct +void free_message(void *params); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index b166755..d78f474 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -91,14 +91,14 @@ typedef struct originating_tranaction_id_message { typedef struct lv { - unsigned int length : 8; + uint8_t length; // size is 8 * length void *value; } LV; typedef struct tlv { - unsigned int type : 8; - unsigned int length : 8; + uint8_t type; + uint8_t length; // size is 8 * length void *value; } TLV; @@ -123,20 +123,34 @@ typedef struct tlv { #define PROXY_FILESTORE_RESPONSE 08 #define PROXY_PUT_CANCEL 09 -typedef struct message_to_user { - uint32_t message_id_cfdp; + +typedef struct message_header { + + char *message_id_cfdp; uint8_t message_type; -} Message_to_user; +} Message_header; //type PROXY_PUT_REQUEST -struct message_proxy { - LV Destination_id; - LV source_file_name; - LV destination_file_name; -}; +typedef struct message_put_proxy { + + LV *destination_id; + LV *source_file_name; + LV *destination_file_name; + +} Message_put_proxy; + +//can cast the message_value based on the message_type in the header; +typedef struct message { + + Message_header header; + void *value; + +} Message; + + //------------------------------------------------------------------------------ @@ -582,8 +596,7 @@ typedef struct request { Remote_entity *remote_entity; Local_entity *local_entity; - TLV message_to_user; - char* filestore_requests; + List *messages_to_user; //sets the buffer length, for making packets uint32_t buff_len; @@ -649,10 +662,5 @@ typedef struct client { } Client; - - - - - #endif diff --git a/Program/src/list.c b/Program/src/list.c index 68ea522..a6ae654 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -299,6 +299,7 @@ List *linked_list() head->next = tail; head->prev = NULL; + newList->count = 0; newList->push = push; newList->remove = removeElement; newList->iterate = iterate; diff --git a/Program/src/main.c b/Program/src/main.c index 30ac097..d706b2e 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -46,6 +46,8 @@ int main(int argc, char** argv) { if (conf->client_cfdp_id != 0){ Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); + start_request(req); + //send_request(new_client, req); } diff --git a/Program/src/requests.c b/Program/src/requests.c index fb7605b..3955bd4 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -18,6 +18,46 @@ #include #include "file_delivery_app.h" + +static void free_lv(LV *lv) { + ssp_free(lv->value); + ssp_free(lv); +} + +static LV *create_lv(int size, void *value) { + + LV *lv = ssp_alloc(1, sizeof(LV)); + lv->value = ssp_alloc(size, sizeof(char)); + memcpy(lv->value, value, size); + lv->length = size; + return lv; +} + + +void free_message(void *params) { + + Message *message = (Message*) params; + Message_put_proxy* proxy_request; + + switch (message->header.message_type) + { + case PROXY_PUT_REQUEST: + proxy_request = (Message_put_proxy *) message->value; + free_lv(proxy_request->destination_file_name); + free_lv(proxy_request->source_file_name); + free_lv(proxy_request->destination_id); + + break; + + default: + break; + } + + ssp_free(message->header.message_id_cfdp); + ssp_free(message->value); + ssp_free(message); +} + void ssp_cleanup_req(void *request) { if (request == NULL) @@ -39,6 +79,12 @@ void ssp_cleanup_req(void *request) { ssp_free(req->res.addr); if (req->local_entity != NULL) ssp_free(req->local_entity); + + if (req->messages_to_user->count > 0) + req->messages_to_user->free(req->messages_to_user, free_message); + else + req->messages_to_user->freeOnlyList(req->messages_to_user); + if (req != NULL) ssp_free(req); @@ -61,6 +107,8 @@ Request *init_request(uint32_t buff_len) { req->buff = ssp_alloc(buff_len, sizeof(char)); req->res.msg = req->buff; req->procedure = none; + + req->messages_to_user = linked_list(); checkAlloc(req->buff, 1); return req; } @@ -111,13 +159,32 @@ Request *put_request( return req; } +void start_request(Request *req){ + req->paused = false; +} -/* //Omission of source and destination filenames shall indicate that only Meta //data will be delivered -int add_proxy_to_request(uint32_t beneficial_cfid, Request *req) { +//beneficial_cfid is the destination id that the proxy will send to, length_of_id is in octets (or bytes) +int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { + + Message *message = ssp_alloc(1, sizeof(Message)); + + message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); + memcpy(message->header.message_id_cfdp, "cfdp", 5); + message->header.message_type = PROXY_PUT_REQUEST; + + Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); + + proxy->destination_file_name = create_lv(strnlen(dest_name, MAX_PATH), dest_name); + proxy->source_file_name = create_lv(strnlen(source_name, MAX_PATH), source_name); + proxy->destination_id = create_lv(length_of_id, &beneficial_cfid); + + message->value = proxy; + req->messages_to_user->push(req->messages_to_user, message, 0); + + return 1; } -*/ \ No newline at end of file diff --git a/Program/test/main.c b/Program/test/main.c index cf16514..5d89c43 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -7,6 +7,8 @@ #include #include #include +#include "types.h" +#include "request_tests.h" /* #include "packet_tests.h" @@ -17,19 +19,10 @@ */ #include "server_tests.h" -/* -Protocol_state *init_test() { - Protocol_state *p_state = init_ftp(1); - ssp_connectionless_server(p_state); - ssp_cleanup_p_state(p_state); -} -*/ int main (int argc, char **argv) { - //init_test(); - //Pdu_header *header = get_header_from_mib(mib, 2222, 1315); //packet_tests(header); //file_system_tests(); @@ -38,16 +31,17 @@ int main (int argc, char **argv) { //ssp_cleanup_pdu_header(header); int error = 0; - //error = request_tests(); + error = request_tests(); //error = protocol_handler_test(); //error = packet_tests(); //error = list_tests(); //error = file_system_tests(); - + /* if (strcmp(argv[1], "1") == 0) error = server_tests(0); else error = server_tests(1); + */ return error; } \ No newline at end of file diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index d9bc9be..c0f5337 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -5,10 +5,10 @@ #include "mib.h" #include "test.h" #include "file_delivery_app.h" -static char *build_mock_packet(Protocol_state *p_state, uint32_t id) { +static char *build_mock_packet(FTP *app, uint32_t id) { char *packet = calloc(sizeof(char*), 2000); - Pdu_header *pdu_header = get_header_from_mib(p_state->mib, 1, id); + Pdu_header *pdu_header = get_header_from_mib(app->mib, 1, id); build_pdu_header(packet, 1, 0, pdu_header); ssp_cleanup_pdu_header(pdu_header); return packet; @@ -17,32 +17,32 @@ static char *build_mock_packet(Protocol_state *p_state, uint32_t id) { static int test_process_pdu_header() { - Protocol_state *p_state = init_ftp(1); - Request **req_container = &p_state->current_request; + FTP *app = init_ftp(1); + Request **req_container = &app->current_request; Response res; int addr = 16; res.addr = &addr; res.sfd = 1; - res.packet_len = p_state->packet_len; + res.packet_len = app->packet_len; res.size_of_addr = 16; //test 1 - char *packet = build_mock_packet(p_state, 2); - process_pdu_header(packet, 1, res, req_container, p_state->request_list, p_state); + char *packet = build_mock_packet(app, 2); + process_pdu_header(packet, 1, res, req_container, app->request_list, app); ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 2); //test 2 - char *packet2 = build_mock_packet(p_state, 3); - process_pdu_header(packet2, 1, res, req_container, p_state->request_list, p_state); + char *packet2 = build_mock_packet(app, 3); + process_pdu_header(packet2, 1, res, req_container, app->request_list, app); ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); ASSERT_NOT_EQUALS_INT("souce id should not equal", (*req_container)->dest_cfdp_id, 2); ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 3); free(packet); free(packet2); - ssp_cleanup_p_state(p_state); + ssp_cleanup_app(app); } diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index bf3020b..7820b77 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -3,11 +3,12 @@ #include "requests.h" #include "string.h" #include "test.h" +#include "filesystem_funcs.h" static void list_print_id(void *element, void *args) { Request *req = (Request *) element; - printf("id: %d trans number: %d\n", req->dest_cfdp_id, req->transaction_sequence_number); + printf("id: %d trans number: %llu\n", req->dest_cfdp_id, req->transaction_sequence_number); } //for finding the struct in the list @@ -31,7 +32,7 @@ static void list_print(void *element, void *args) { ssp_printf("%s\n", req->source_file_name); } -int request_finding_test() { +static int request_finding_test() { List *list = linked_list(); @@ -79,7 +80,7 @@ int request_finding_test() { } -void request_test_list_storage() { +static void request_test_list_storage() { Request *req = init_request(5000); List *list = linked_list(); @@ -103,10 +104,39 @@ void request_test_list_storage() { } +static int add_proxy_message() { + + Request *req = init_request(5000); + + char *dest = "dest"; + char *src = "src"; + uint32_t id = 2; + uint8_t len = 1; + + + int error = add_proxy_message_to_request(id, len, src, dest, req); + + Message *message = req->messages_to_user->pop(req->messages_to_user); + ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); + + + Message_put_proxy *proxy = (Message_put_proxy *) message->value; + ASSERT_EQUALS_STR("proxy dest_id should equal 2", proxy->destination_id->value, &id, len); + ASSERT_EQUALS_STR("proxy src file", proxy->source_file_name->value, src, proxy->source_file_name->length); + ASSERT_EQUALS_STR("proxy dest file", proxy->destination_file_name->value, dest, proxy->destination_file_name->length); + + free_message(message); + + ssp_cleanup_req(req); + return 0; + +} int request_tests() { int error = 0; error = request_finding_test(); - return 0; + error = add_proxy_message(); + + return error; } \ No newline at end of file From 37215a8cb0fc4c73f4556fd628547cff6695eac7 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 14 Oct 2019 16:18:15 -0600 Subject: [PATCH 119/400] Add add_messages_to_packet function, untested --- Program/include/packet.h | 3 +++ Program/include/requests.h | 2 ++ Program/src/packet.c | 48 ++++++++++++++++++++++++++++++++++++ Program/src/requests.c | 7 ++++++ Program/test/makefile | 10 ++++---- Program/test/request_tests.c | 2 -- 6 files changed, 65 insertions(+), 7 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 41ca11a..4cfa52b 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -29,4 +29,7 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) ; void set_data_length(char*packet, uint16_t data_len); uint16_t get_data_length(char*packet); +uint32_t add_messages_to_packet(char *packet, uint32_t start, Request *req); + + #endif \ No newline at end of file diff --git a/Program/include/requests.h b/Program/include/requests.h index d7ac154..fdc27bc 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -21,4 +21,6 @@ Request *put_request( int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); //Frees a message struct void free_message(void *params); +void copy_lv_to_buffer(char *buffer, LV *lv); + #endif \ No newline at end of file diff --git a/Program/src/packet.c b/Program/src/packet.c index 4ff33ff..d764bd0 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -5,6 +5,7 @@ #include "utils.h" #include "port.h" #include "filesystem_funcs.h" +#include "requests.h" /*------------------------------------------------------------------------------ @@ -308,3 +309,50 @@ uint16_t get_data_length(char*packet) { Pdu_header *header = (Pdu_header*) packet; return ntohs(header->PDU_data_field_len); } + + +//returns length of added messages, copys messages into packet +uint32_t add_messages_to_packet(char *packet, uint32_t start, Request *req) { + + uint32_t packet_index = start; + + for (int i = 0; i < req->messages_to_user->count; i++) { + Message *message = (Message *) req->messages_to_user->pop(req->messages_to_user); + + memcpy(&packet[packet_index], message->header.message_id_cfdp, 5); + packet_index += 5; + + memcpy(&packet[packet_index], &message->header.message_type, 1); + packet_index += 1; + + + Message_put_proxy *proxy; + + switch (message->header.message_type) + { + case PROXY_PUT_REQUEST: + proxy = (Message_put_proxy *) message->value; + copy_lv_to_buffer(&packet[packet_index], proxy->destination_id); + packet_index += proxy->destination_id->length; + copy_lv_to_buffer(&packet[start], proxy->source_file_name); + packet_index += proxy->source_file_name->length; + copy_lv_to_buffer(&packet[start], proxy->destination_file_name); + packet_index += proxy->destination_file_name->length; + + break; + + default: + break; + } + } + return packet_index - start; +} + + +//adds messages from packet into request +uint32_t get_messages_from_packet(char *packet, uint32_t start, Request *req) { + + + +} + diff --git a/Program/src/requests.c b/Program/src/requests.c index 3955bd4..afb39d9 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -19,6 +19,11 @@ #include "file_delivery_app.h" + +void copy_lv_to_buffer(char *buffer, LV *lv){ + memcpy(buffer, lv->value, lv->length); +} + static void free_lv(LV *lv) { ssp_free(lv->value); ssp_free(lv); @@ -188,3 +193,5 @@ int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, return 1; } + + diff --git a/Program/test/makefile b/Program/test/makefile index 41b7992..f0cad73 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -26,13 +26,13 @@ CFILES += $(PROJDIR)/src/file_delivery_app.c CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -CFILES += $(PROJDIR)/test/packet_tests.c +#CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c CFILES += $(PROJDIR)/test/request_tests.c -CFILES += $(PROJDIR)/test/filesystem_tests.c -CFILES += $(PROJDIR)/test/protocol_handler_tests.c -CFILES += $(PROJDIR)/test/list_tests.c -CFILES += $(PROJDIR)/test/server_tests.c +#CFILES += $(PROJDIR)/test/filesystem_tests.c +#CFILES += $(PROJDIR)/test/protocol_handler_tests.c +#CFILES += $(PROJDIR)/test/list_tests.c +#CFILES += $(PROJDIR)/test/server_tests.c #entrypoint diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 7820b77..5480a38 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -113,13 +113,11 @@ static int add_proxy_message() { uint32_t id = 2; uint8_t len = 1; - int error = add_proxy_message_to_request(id, len, src, dest, req); Message *message = req->messages_to_user->pop(req->messages_to_user); ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); - Message_put_proxy *proxy = (Message_put_proxy *) message->value; ASSERT_EQUALS_STR("proxy dest_id should equal 2", proxy->destination_id->value, &id, len); ASSERT_EQUALS_STR("proxy src file", proxy->source_file_name->value, src, proxy->source_file_name->length); From d24465e4a9bdaa02689a84cc3d13ea25a8b52b87 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 17 Oct 2019 08:35:29 -0600 Subject: [PATCH 120/400] add 'add messages to packet' function, and building tests --- Program/include/packet.h | 3 +- Program/src/packet.c | 76 +++++++++++++++++++++--------------- Program/test/main.c | 12 ++---- Program/test/makefile | 3 +- Program/test/packet_tests.c | 7 +++- Program/test/packet_tests.h | 9 +---- Program/test/request_tests.c | 2 + Program/test/test.c | 1 - 8 files changed, 62 insertions(+), 51 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 4cfa52b..50a3fc3 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -29,7 +29,6 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) ; void set_data_length(char*packet, uint16_t data_len); uint16_t get_data_length(char*packet); -uint32_t add_messages_to_packet(char *packet, uint32_t start, Request *req); - +uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_user); #endif \ No newline at end of file diff --git a/Program/src/packet.c b/Program/src/packet.c index d764bd0..09e8de8 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -311,41 +311,55 @@ uint16_t get_data_length(char*packet) { } + +struct packet_callback_params { + char *packet; + uint32_t *packet_index; +}; + +static void add_messages_callback(void *element, void *args) { + struct packet_callback_params *params = (struct packet_callback_params *) args; + char *packet = params->packet; + uint32_t packet_index = *(params->packet_index); + + Message *message = (Message *) element; + + memcpy(&packet[packet_index], message->header.message_id_cfdp, 5); + packet_index += 5; + + memcpy(&packet[packet_index], &message->header.message_type, 1); + packet_index += 1; + + Message_put_proxy *proxy; + + switch (message->header.message_type) + { + case PROXY_PUT_REQUEST: + proxy = (Message_put_proxy *) message->value; + copy_lv_to_buffer(&packet[packet_index], proxy->destination_id); + packet_index += proxy->destination_id->length; + copy_lv_to_buffer(&packet[packet_index], proxy->source_file_name); + packet_index += proxy->source_file_name->length; + copy_lv_to_buffer(&packet[packet_index], proxy->destination_file_name); + packet_index += proxy->destination_file_name->length; + + break; + + default: + break; + } + + params->packet_index += packet_index; + +} + //returns length of added messages, copys messages into packet -uint32_t add_messages_to_packet(char *packet, uint32_t start, Request *req) { +uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_user) { uint32_t packet_index = start; + struct packet_callback_params params = {packet, &packet_index}; + messages_to_user->iterate(messages_to_user, add_messages_callback, ¶ms); - for (int i = 0; i < req->messages_to_user->count; i++) { - Message *message = (Message *) req->messages_to_user->pop(req->messages_to_user); - - memcpy(&packet[packet_index], message->header.message_id_cfdp, 5); - packet_index += 5; - - memcpy(&packet[packet_index], &message->header.message_type, 1); - packet_index += 1; - - - Message_put_proxy *proxy; - - switch (message->header.message_type) - { - case PROXY_PUT_REQUEST: - proxy = (Message_put_proxy *) message->value; - copy_lv_to_buffer(&packet[packet_index], proxy->destination_id); - packet_index += proxy->destination_id->length; - copy_lv_to_buffer(&packet[start], proxy->source_file_name); - packet_index += proxy->source_file_name->length; - copy_lv_to_buffer(&packet[start], proxy->destination_file_name); - packet_index += proxy->destination_file_name->length; - - break; - - default: - break; - } - } - return packet_index - start; } diff --git a/Program/test/main.c b/Program/test/main.c index 5d89c43..34af936 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -9,9 +9,10 @@ #include #include "types.h" #include "request_tests.h" +#include "packet_tests.h" + /* -#include "packet_tests.h" #include "filesystem_tests.h" #include "file_delivery_app.h" #include "protocol_handler_tests.h" @@ -23,17 +24,12 @@ int main (int argc, char **argv) { - //Pdu_header *header = get_header_from_mib(mib, 2222, 1315); - //packet_tests(header); - //file_system_tests(); - //request_test_list_storage(); - //free_mib(mib); - //ssp_cleanup_pdu_header(header); + int error = 0; error = request_tests(); //error = protocol_handler_test(); - //error = packet_tests(); + error = packet_tests(); //error = list_tests(); //error = file_system_tests(); diff --git a/Program/test/makefile b/Program/test/makefile index f0cad73..d46ec69 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -26,7 +26,8 @@ CFILES += $(PROJDIR)/src/file_delivery_app.c CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -#CFILES += $(PROJDIR)/test/packet_tests.c + +CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c CFILES += $(PROJDIR)/test/request_tests.c #CFILES += $(PROJDIR)/test/filesystem_tests.c diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 4615ad7..87e1b5f 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -9,6 +9,8 @@ #include "protocol_handler.h" #include "mib.h" #include "file_delivery_app.h" +#include "packet.h" +#include "packet_tests.h" #define PACKET_TEST_SIZE 2000 @@ -227,6 +229,7 @@ int test_build_pdu_header_header(char *packet, Pdu_header *header, uint64_t sequ return packet_index; } + int packet_tests() { printf("starting Packet Tests (creating and changing packet values)\n"); @@ -265,4 +268,6 @@ int packet_tests() { ssp_free(packet); return 0; -} \ No newline at end of file +} + + diff --git a/Program/test/packet_tests.h b/Program/test/packet_tests.h index 3e64ff2..f07e95b 100644 --- a/Program/test/packet_tests.h +++ b/Program/test/packet_tests.h @@ -3,15 +3,10 @@ #define PACKET_TEST_H -#include "protocol_handler.h" - - - - - +#include "types.h" int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); -int packet_tests(Pdu_header *header); +int packet_tests(); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 5480a38..642abbd 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -130,6 +130,8 @@ static int add_proxy_message() { } + + int request_tests() { int error = 0; diff --git a/Program/test/test.c b/Program/test/test.c index c5dd822..cea54ae 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -1,7 +1,6 @@ #include "test.h" #include - int test_num = 0; void ASSERT_EQUALS_INT(char* description, int val1, int val2) { From 252a7c979ee4d4854db97235a6f243493445d032 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 19 Oct 2019 15:18:38 -0600 Subject: [PATCH 121/400] Change res in build_put_packet_metadata to char* packet. --- Program/include/packet.h | 2 +- Program/src/packet.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 50a3fc3..476b438 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -17,7 +17,7 @@ uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_finished_pdu(char *packet, uint32_t start); -uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req); +uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); diff --git a/Program/src/packet.c b/Program/src/packet.c index 09e8de8..cbffb63 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -69,17 +69,17 @@ uint8_t build_finished_pdu(char *packet, uint32_t start) { } -uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req) { - Pdu_header *header = (Pdu_header *) res.msg; +uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { + Pdu_header *header = (Pdu_header *) packet; header->PDU_type = DIRECTIVE; uint8_t packet_index = start; //set directive 1 byte - Pdu_directive *directive = (Pdu_directive *) &res.msg[packet_index]; + Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; directive->directive_code = META_DATA_PDU; packet_index += SIZE_OF_DIRECTIVE_CODE; - Pdu_meta_data *meta_data_packet = (Pdu_meta_data *) &res.msg[packet_index]; + Pdu_meta_data *meta_data_packet = (Pdu_meta_data *) &packet[packet_index]; //1 bytes meta_data_packet->segmentation_control = req->segmentation_control; @@ -89,7 +89,7 @@ uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req) { //4 bytes uint32_t network_bytes = htonl(req->file_size); network_bytes = network_bytes; - memcpy(&res.msg[packet_index], &network_bytes, sizeof(uint32_t)); + memcpy(&packet[packet_index], &network_bytes, sizeof(uint32_t)); packet_index += 4; //variable length params @@ -99,22 +99,22 @@ uint8_t build_put_packet_metadata(Response res, uint32_t start, Request *req) { char *destination_file_name = req->destination_file_name; //copy source length to packet (1 bytes) - memcpy(&res.msg[packet_index], &src_file_name_length, src_file_name_length); + memcpy(&packet[packet_index], &src_file_name_length, src_file_name_length); packet_index++; //copy source name to packet (length bytes) - memcpy(&res.msg[packet_index], src_file_name, src_file_name_length); + memcpy(&packet[packet_index], src_file_name, src_file_name_length); packet_index += src_file_name_length; //copy length to packet (1 byte) - memcpy(&res.msg[packet_index], &destination_file_length, 1); + memcpy(&packet[packet_index], &destination_file_length, 1); packet_index++; //copy destination name to packet (length bytes) - memcpy(&res.msg[packet_index], destination_file_name, destination_file_length); + memcpy(&packet[packet_index], destination_file_name, destination_file_length); packet_index += destination_file_length; uint8_t data_len = packet_index - start; - set_data_length(res.msg, data_len); + set_data_length(packet, data_len); return packet_index; } From 8ab75457d740d756f9849972c643e5f2f410611d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 19 Oct 2019 15:19:25 -0600 Subject: [PATCH 122/400] change build_put_metadata in protocol handler to reflect change --- Program/src/protocol_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index af3bafa..65e8c47 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -367,7 +367,7 @@ void user_request_handler(Response res, Request *req, Client* client) { case sending_put_metadata: ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); - start = build_put_packet_metadata(res, start, req); + start = build_put_packet_metadata(req->buff, start, req); ssp_sendto(res); req->procedure = sending_data; break; From ee5ba61b292fa85d2d3ae6acc570597c46ce3aa0 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 19 Oct 2019 16:09:43 -0600 Subject: [PATCH 123/400] Add metadata file tests --- Program/test/packet_tests.c | 79 ++++++++++++++++++++++++++++++------- Program/test/testfile | 1 + 2 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 Program/test/testfile diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 87e1b5f..064baf6 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -17,11 +17,8 @@ static int test_respond_to_naks(char *packet, uint32_t packet_index) { Request *req = init_request(5000); - ssp_cleanup_req(req); - return 0; - } static int test_respond_metadata_request() { @@ -43,8 +40,7 @@ test_build_data_packet(char *packet, uint32_t packet_index){ uint32_t offset_in_packet = 0; memcpy(&offset_in_packet, &packet[packet_index], 4); - ssp_printf("offset size %u\n", offset_in_packet); - ASSERT_EQUALS_INT("test proper datapacket offset set", offset_in_packet, 987); + ASSERT_EQUALS_INT("test proper datapacket offset set", offset_in_packet, 10); free_file(file); } @@ -170,7 +166,6 @@ int test_build_ack_finished_pdu(char *packet, uint32_t start) { ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack->condition_code); ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack->directive_subtype_code, ACK_FINISHED_END); - return 0; } @@ -193,7 +188,7 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { return 0; } -int test_build_pdu_header_header(char *packet, Pdu_header *header, uint64_t sequence_number) { +int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_number) { printf("testing header creation\n"); @@ -230,6 +225,61 @@ int test_build_pdu_header_header(char *packet, Pdu_header *header, uint64_t sequ } +int test_build_metadata_packet(char *packet, uint32_t start) { + + memset(&packet[start], 0, 20); + + printf("testing metadata packets\n"); + Request *req = init_request(1000); + Request *recv_request = init_request(1000); + + uint8_t len = build_put_packet_metadata(packet, start, req); + fill_request_pdu_metadata(&packet[start + 1], recv_request); + + ASSERT_EQUALS_INT("test packet filesize", req->file_size, recv_request->file_size); + ASSERT_EQUALS_STR("test src_file_name", req->source_file_name, recv_request->source_file_name, strnlen(req->source_file_name, MAX_PATH)); + ASSERT_EQUALS_STR("test dest_file_name", req->destination_file_name, recv_request->destination_file_name, strnlen(req->source_file_name, MAX_PATH)); + + + + char *str = "HELLO WORLD"; + + memcpy(req->destination_file_name, str, strnlen(str, MAX_PATH) ); + memcpy(req->source_file_name, str, strnlen(str, MAX_PATH) ); + + len = build_put_packet_metadata(packet, start, req); + fill_request_pdu_metadata(&packet[start + 1], recv_request); + + ASSERT_EQUALS_INT("test packet filesize", req->file_size, recv_request->file_size); + ASSERT_EQUALS_STR("test src_file_name", req->source_file_name, recv_request->source_file_name, strnlen(req->source_file_name, MAX_PATH)); + ASSERT_EQUALS_STR("test dest_file_name", req->destination_file_name, recv_request->destination_file_name, strnlen(req->source_file_name, MAX_PATH)); + + + ssp_cleanup_req(req); + ssp_cleanup_req(recv_request); + + return 0; +} + + +int test_add_messages_to_packet() { + + /* + + char *dest = "dest"; + char *src = "src"; + uint32_t id = 2; + uint8_t len = 1; + + uint32_t packet_index = start; + + int error = add_proxy_message_to_request(id, len, src, dest, req); + packet_index += add_messages_to_packet(packet, packet_index, req->messages_to_user); + */ + + +} + int packet_tests() { printf("starting Packet Tests (creating and changing packet values)\n"); @@ -253,16 +303,17 @@ int packet_tests() { char *packet = calloc(PACKET_TEST_SIZE, sizeof(char)); uint64_t sequence_number = 12345663234; - int packet_index = test_build_pdu_header_header(packet, pdu_header, sequence_number); - test_build_ack_eof_pdu(packet, packet_index); - test_build_nak_packet(packet, packet_index); - test_respond_to_naks(packet, packet_index); - + int data_start_index = test_build_pdu_header(packet, pdu_header, sequence_number); + test_build_ack_eof_pdu(packet, data_start_index); + test_build_nak_packet(packet, data_start_index); + test_respond_to_naks(packet, data_start_index); memset(packet, 0, PACKET_TEST_SIZE); - packet_index = test_build_pdu_header_header(packet, pdu_header, sequence_number); - test_build_data_packet(packet, packet_index); + data_start_index = test_build_pdu_header(packet, pdu_header, sequence_number); + test_build_data_packet(packet, data_start_index); + test_build_metadata_packet(packet, data_start_index); + free_mib(mib); ssp_cleanup_pdu_header(pdu_header); ssp_free(packet); diff --git a/Program/test/testfile b/Program/test/testfile new file mode 100644 index 0000000..3a62505 --- /dev/null +++ b/Program/test/testfile @@ -0,0 +1 @@ +tempfileyo \ No newline at end of file From d83288f0e63b5cacfdf5e0f4f175b181f84b6962 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 19 Oct 2019 16:10:12 -0600 Subject: [PATCH 124/400] continue on from last request --- Program/include/protocol_handler.h | 6 ++++-- Program/src/packet.c | 11 +++++------ Program/src/protocol_handler.c | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index fcb58c0..e147ada 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -7,7 +7,6 @@ #define RESEND_FINISHED_TIMES 3 #define TIMEOUT_BEFORE_CANCEL_REQUEST 100 -//for use void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, uint32_t packet_index, Response res, Request *req, Client *client); @@ -15,7 +14,10 @@ void on_server_time_out(Response res, Request *current_request); int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); -//for testing + + +void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); + uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_ack (char *packet, uint32_t start, uint8_t type); int process_file_request_metadata(Request *req); diff --git a/Program/src/packet.c b/Program/src/packet.c index cbffb63..714232f 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -68,7 +68,7 @@ uint8_t build_finished_pdu(char *packet, uint32_t start) { return data_len; } - +//returns packet_index for data uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { Pdu_header *header = (Pdu_header *) packet; @@ -79,6 +79,7 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; directive->directive_code = META_DATA_PDU; packet_index += SIZE_OF_DIRECTIVE_CODE; + Pdu_meta_data *meta_data_packet = (Pdu_meta_data *) &packet[packet_index]; //1 bytes @@ -95,24 +96,22 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { //variable length params uint8_t src_file_name_length = strnlen(req->source_file_name, MAX_PATH); uint8_t destination_file_length = strnlen(req->destination_file_name, MAX_PATH); - char *src_file_name = req->source_file_name; - char *destination_file_name = req->destination_file_name; //copy source length to packet (1 bytes) memcpy(&packet[packet_index], &src_file_name_length, src_file_name_length); packet_index++; //copy source name to packet (length bytes) - memcpy(&packet[packet_index], src_file_name, src_file_name_length); + memcpy(&packet[packet_index], req->source_file_name, src_file_name_length); packet_index += src_file_name_length; - //copy length to packet (1 byte) memcpy(&packet[packet_index], &destination_file_length, 1); packet_index++; //copy destination name to packet (length bytes) - memcpy(&packet[packet_index], destination_file_name, destination_file_length); + memcpy(&packet[packet_index], req->destination_file_name, destination_file_length); packet_index += destination_file_length; + uint8_t data_len = packet_index - start; set_data_length(packet, data_len); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 65e8c47..58c73e0 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -203,7 +203,7 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File } -static void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) { +void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) { Pdu_meta_data *meta_data = (Pdu_meta_data *) meta_data_packet; req_to_fill->segmentation_control = meta_data->segmentation_control; From 0f04fe367682f85c353776764be700b20f4e0a5c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 26 Oct 2019 12:58:42 -0600 Subject: [PATCH 125/400] Add tests for lv functions --- Program/include/requests.h | 8 +++++- Program/include/types.h | 1 + Program/src/packet.c | 54 ++++++++++++++++++++++++++++++------ Program/src/requests.c | 54 ++++++++++++++++++++++++------------ Program/test/main.c | 1 + Program/test/packet_tests.c | 39 ++++++++++++++++++++++---- Program/test/request_tests.c | 28 ++++++++++++++++++- 7 files changed, 152 insertions(+), 33 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index fdc27bc..faa6bfd 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -19,8 +19,14 @@ Request *put_request( ); int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); + +Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); + //Frees a message struct void free_message(void *params); -void copy_lv_to_buffer(char *buffer, LV *lv); +LV *create_lv(int size, void *value); +uint16_t copy_lv_to_buffer(char *buffer, LV *lv); +LV *copy_lv_from_buffer(char *packet, uint32_t start); +void free_lv(LV *lv); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index d78f474..c2c3d0f 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -146,6 +146,7 @@ typedef struct message_put_proxy { typedef struct message { Message_header header; + //will take various kinds of Message_xx types void *value; } Message; diff --git a/Program/src/packet.c b/Program/src/packet.c index 714232f..08de506 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -311,6 +311,8 @@ uint16_t get_data_length(char*packet) { + + struct packet_callback_params { char *packet; uint32_t *packet_index; @@ -323,9 +325,11 @@ static void add_messages_callback(void *element, void *args) { Message *message = (Message *) element; + //5 bytes to copy cfdp\0 into the buffer memcpy(&packet[packet_index], message->header.message_id_cfdp, 5); packet_index += 5; + //one byte for message type memcpy(&packet[packet_index], &message->header.message_type, 1); packet_index += 1; @@ -335,12 +339,9 @@ static void add_messages_callback(void *element, void *args) { { case PROXY_PUT_REQUEST: proxy = (Message_put_proxy *) message->value; - copy_lv_to_buffer(&packet[packet_index], proxy->destination_id); - packet_index += proxy->destination_id->length; - copy_lv_to_buffer(&packet[packet_index], proxy->source_file_name); - packet_index += proxy->source_file_name->length; - copy_lv_to_buffer(&packet[packet_index], proxy->destination_file_name); - packet_index += proxy->destination_file_name->length; + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy->destination_id); + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy->source_file_name); + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy->destination_file_name); break; @@ -358,14 +359,51 @@ uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_ uint32_t packet_index = start; struct packet_callback_params params = {packet, &packet_index}; messages_to_user->iterate(messages_to_user, add_messages_callback, ¶ms); - + return packet_index; } //adds messages from packet into request -uint32_t get_messages_from_packet(char *packet, uint32_t start, Request *req) { +uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { + + if (strncmp(&packet[start], "cfdp", 5)) { + ssp_error("messages are poorly formatted\n"); + return 0; + } + + Message *m; + + switch (packet[start + 1]) + { + case PROXY_PUT_REQUEST: + m = create_message(PROXY_PUT_REQUEST); + //m->value = create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); + break; + + default: + break; + } + /* + packet_index = start + 6; + dest_id = copy_lv_from_buffer(packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", dest_id->length, len); + ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*) (dest_id->value), id); + packet_index += dest_id->length + 1; + free_lv(dest_id); + + + src_file = copy_lv_from_buffer(packet, packet_index); + ASSERT_EQUALS_INT("src_file.length", src_file->length, strnlen(src, 100)); + ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file->value, src_file->length); + packet_index += src_file->length + 1; + free_lv(src_file); + dest_file = copy_lv_from_buffer(packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", dest_file->length, strnlen(dest, 100)); + ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file->value, dest_file->length); + free_lv(dest_file); + */ } diff --git a/Program/src/requests.c b/Program/src/requests.c index afb39d9..c318cd1 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -19,25 +19,49 @@ #include "file_delivery_app.h" - -void copy_lv_to_buffer(char *buffer, LV *lv){ - memcpy(buffer, lv->value, lv->length); +//returns total space taken up in the packet from the added lv +uint16_t copy_lv_to_buffer(char *buffer, LV *lv){ + uint16_t packet_index = 0; + buffer[packet_index] = lv->length; + packet_index++; + memcpy(&buffer[packet_index], lv->value, lv->length); + packet_index += lv->length; + return packet_index; } -static void free_lv(LV *lv) { +void free_lv(LV *lv) { ssp_free(lv->value); ssp_free(lv); } -static LV *create_lv(int size, void *value) { +LV *create_lv(int size, void *value) { LV *lv = ssp_alloc(1, sizeof(LV)); lv->value = ssp_alloc(size, sizeof(char)); + + memcpy(lv->value, value, size); lv->length = size; + return lv; } +Message *create_message(uint8_t type) { + + Message *message = ssp_alloc(1, sizeof(Message)); + message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); + memcpy(message->header.message_id_cfdp, "cfdp", 5); + message->header.message_type = type; +} + + +//lv is what we copy into, packet is the buffer, and start is where in the buffer +//we start copying the lv to +LV *copy_lv_from_buffer(char *packet, uint32_t start) { + uint8_t len = packet[start]; + return create_lv(len, &packet[start + 1]); +} + void free_message(void *params) { @@ -172,23 +196,19 @@ void start_request(Request *req){ //data will be delivered - -//beneficial_cfid is the destination id that the proxy will send to, length_of_id is in octets (or bytes) -int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { - - Message *message = ssp_alloc(1, sizeof(Message)); - - message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); - memcpy(message->header.message_id_cfdp, "cfdp", 5); - message->header.message_type = PROXY_PUT_REQUEST; - +Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); - proxy->destination_file_name = create_lv(strnlen(dest_name, MAX_PATH), dest_name); proxy->source_file_name = create_lv(strnlen(source_name, MAX_PATH), source_name); proxy->destination_id = create_lv(length_of_id, &beneficial_cfid); + return proxy; +} + +//beneficial_cfid is the destination id that the proxy will send to, length_of_id is in octets (or bytes) +int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { - message->value = proxy; + Message *message = create_message(PROXY_PUT_REQUEST); + message->value = create_message_put_proxy(beneficial_cfid, length_of_id, source_name, dest_name, req); req->messages_to_user->push(req->messages_to_user, message, 0); return 1; diff --git a/Program/test/main.c b/Program/test/main.c index 34af936..e33543a 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -30,6 +30,7 @@ int main (int argc, char **argv) { error = request_tests(); //error = protocol_handler_test(); error = packet_tests(); + //error = list_tests(); //error = file_system_tests(); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 064baf6..17e80af 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -240,8 +240,6 @@ int test_build_metadata_packet(char *packet, uint32_t start) { ASSERT_EQUALS_STR("test src_file_name", req->source_file_name, recv_request->source_file_name, strnlen(req->source_file_name, MAX_PATH)); ASSERT_EQUALS_STR("test dest_file_name", req->destination_file_name, recv_request->destination_file_name, strnlen(req->source_file_name, MAX_PATH)); - - char *str = "HELLO WORLD"; memcpy(req->destination_file_name, str, strnlen(str, MAX_PATH) ); @@ -262,10 +260,8 @@ int test_build_metadata_packet(char *packet, uint32_t start) { } -int test_add_messages_to_packet() { +int test_add_messages_to_packet(char *packet, uint32_t start) { - /* - char *dest = "dest"; char *src = "src"; uint32_t id = 2; @@ -273,11 +269,41 @@ int test_add_messages_to_packet() { uint32_t packet_index = start; + Request *req = init_request(1000); + int error = add_proxy_message_to_request(id, len, src, dest, req); + packet_index += add_messages_to_packet(packet, packet_index, req->messages_to_user); - */ + ssp_print_hex(&packet[start], packet_index - start); + + ASSERT_EQUALS_STR("'cfdp' should be at the start of the message", &packet[start], "cfdp", 5); + ASSERT_EQUALS_INT("testing PROXY_PUT_REQUEST code", (uint8_t) packet[start + 5], PROXY_PUT_REQUEST); + + LV* dest_file, *src_file, *dest_id; + packet_index = start + 6; + dest_id = copy_lv_from_buffer(packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", dest_id->length, len); + ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*) (dest_id->value), id); + packet_index += dest_id->length + 1; + free_lv(dest_id); + + + src_file = copy_lv_from_buffer(packet, packet_index); + ASSERT_EQUALS_INT("src_file.length", src_file->length, strnlen(src, 100)); + ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file->value, src_file->length); + packet_index += src_file->length + 1; + free_lv(src_file); + + + dest_file = copy_lv_from_buffer(packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", dest_file->length, strnlen(dest, 100)); + ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file->value, dest_file->length); + free_lv(dest_file); + + + ssp_cleanup_req(req); } int packet_tests() { @@ -313,6 +339,7 @@ int packet_tests() { test_build_data_packet(packet, data_start_index); test_build_metadata_packet(packet, data_start_index); + test_add_messages_to_packet(packet, data_start_index); free_mib(mib); ssp_cleanup_pdu_header(pdu_header); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 642abbd..801f484 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -4,7 +4,7 @@ #include "string.h" #include "test.h" #include "filesystem_funcs.h" - +#include "string.h" static void list_print_id(void *element, void *args) { Request *req = (Request *) element; @@ -132,11 +132,37 @@ static int add_proxy_message() { +int test_lv_functions() { + + char packet[100]; + + char *str = "suphomie"; + LV *lv = create_lv(strnlen(str, 100), str); + + uint32_t len = strnlen(str, 100); + + ASSERT_EQUALS_INT("create_lv length works", lv->length, len); + ASSERT_EQUALS_STR("create_lv value works", str, lv->value, len); + + uint16_t packet_index = copy_lv_to_buffer(packet, lv); + ASSERT_EQUALS_INT("copy lv, length", packet[0], lv->length); + ASSERT_EQUALS_STR("copy lv, value", &packet[1], lv->value, lv->length); + + free_lv(lv); + + lv = copy_lv_from_buffer(packet, 0); + ASSERT_EQUALS_INT("copy lv length from packet", lv->length, len); + ASSERT_EQUALS_STR("copy lv value from packet", str, lv->value, len); + free_lv(lv); + +} + int request_tests() { int error = 0; error = request_finding_test(); error = add_proxy_message(); + error = test_lv_functions(); return error; } \ No newline at end of file From e30ac980c8bd2a32b7453689cf96b6a805f20e16 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 27 Oct 2019 11:47:35 -0600 Subject: [PATCH 126/400] Message transfering should work for proxy --- Program/include/packet.h | 2 + Program/include/protocol_handler.h | 2 +- Program/include/requests.h | 2 + Program/src/main.c | 3 +- Program/src/packet.c | 63 ++++++++++++-------- Program/src/protocol_handler.c | 15 ++--- Program/test/packet_tests.c | 96 +++++++++++++++++++++++++++--- 7 files changed, 140 insertions(+), 43 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 476b438..6862acc 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -29,6 +29,8 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) ; void set_data_length(char*packet, uint16_t data_len); uint16_t get_data_length(char*packet); +uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req); +uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req); uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_user); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index e147ada..f920a01 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -16,7 +16,7 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len -void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); +uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_ack (char *packet, uint32_t start, uint8_t type); diff --git a/Program/include/requests.h b/Program/include/requests.h index faa6bfd..bc06c85 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -22,11 +22,13 @@ int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); + //Frees a message struct void free_message(void *params); LV *create_lv(int size, void *value); uint16_t copy_lv_to_buffer(char *buffer, LV *lv); LV *copy_lv_from_buffer(char *packet, uint32_t start); +Message *create_message(uint8_t type); void free_lv(LV *lv); #endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index d706b2e..eba9950 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -46,8 +46,9 @@ int main(int argc, char** argv) { if (conf->client_cfdp_id != 0){ Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(1, 1, "pic.jpg", "dest.jpg", req); + start_request(req); - //send_request(new_client, req); } diff --git a/Program/src/packet.c b/Program/src/packet.c index 08de506..24b0d6c 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -68,7 +68,7 @@ uint8_t build_finished_pdu(char *packet, uint32_t start) { return data_len; } -//returns packet_index for data +//returns packet_index for data, to get length of meta data, subtract start from return value uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { Pdu_header *header = (Pdu_header *) packet; @@ -111,6 +111,8 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { memcpy(&packet[packet_index], req->destination_file_name, destination_file_length); packet_index += destination_file_length; + //add messages to metadata + packet_index = add_messages_to_packet(packet, packet_index, req->messages_to_user); uint8_t data_len = packet_index - start; set_data_length(packet, data_len); @@ -349,11 +351,11 @@ static void add_messages_callback(void *element, void *args) { break; } - params->packet_index += packet_index; + *(params->packet_index) = packet_index; } -//returns length of added messages, copys messages into packet +//returns length of added messages, including the start; copys messages into packet uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_user) { uint32_t packet_index = start; @@ -363,7 +365,7 @@ uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_ } -//adds messages from packet into request +//adds messages from packet into request, returns the location of the next message uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { if (strncmp(&packet[start], "cfdp", 5)) { @@ -372,38 +374,47 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { } Message *m; + Message_put_proxy *put_proxy; - switch (packet[start + 1]) + uint32_t message_start = start + 6; + + switch (packet[start + 5]) { case PROXY_PUT_REQUEST: m = create_message(PROXY_PUT_REQUEST); - //m->value = create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); + + m->value = ssp_alloc(1, sizeof(Message_put_proxy)); + put_proxy = (Message_put_proxy *) m->value; + + put_proxy->destination_id = copy_lv_from_buffer(packet, message_start); + message_start += put_proxy->destination_id->length + 1; + + put_proxy->source_file_name = copy_lv_from_buffer(packet, message_start); + message_start += put_proxy->source_file_name->length + 1; + + put_proxy->destination_file_name = copy_lv_from_buffer(packet, message_start); + message_start += put_proxy->destination_file_name->length + 1; break; default: break; } - /* - packet_index = start + 6; - dest_id = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("dest_file.length", dest_id->length, len); - ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*) (dest_id->value), id); - packet_index += dest_id->length + 1; - free_lv(dest_id); - - src_file = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("src_file.length", src_file->length, strnlen(src, 100)); - ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file->value, src_file->length); - packet_index += src_file->length + 1; - free_lv(src_file); - + req->messages_to_user->push(req->messages_to_user, m, 0); + return message_start; +} - dest_file = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("dest_file.length", dest_file->length, strnlen(dest, 100)); - ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file->value, dest_file->length); - free_lv(dest_file); - */ -} +uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req) { + + uint32_t packet_index = start; + + while (packet_index < data_length - 5) { + + if (strncmp(&packet[packet_index], "cfdp", 5)) + break; + packet_index = get_message_from_packet(packet, packet_index, req); + } + return packet_index; +} \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 58c73e0..873b926 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -94,9 +94,6 @@ static int find_request(void *element, void *args) { } - - - /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns -1 on fail*/ @@ -203,7 +200,7 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File } -void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) { +uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) { Pdu_meta_data *meta_data = (Pdu_meta_data *) meta_data_packet; req_to_fill->segmentation_control = meta_data->segmentation_control; @@ -227,7 +224,7 @@ void fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) { packet_index += file_name_len; - return; + return packet_index; } @@ -487,7 +484,8 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ return; Pdu_header *header = (Pdu_header *) packet; - + uint16_t data_len = get_data_length(packet); + //set timeout to 0, because received data req->timeout = 0; @@ -517,7 +515,10 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ req->procedure = sending_put_metadata; ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); - fill_request_pdu_metadata(&packet[packet_index], req); + packet_index += fill_request_pdu_metadata(&packet[packet_index], req); + get_messages_from_packet(packet, packet_index, data_len, req); + + //get messages from packet here process_file_request_metadata(req); break; diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 17e80af..cd32019 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -26,7 +26,7 @@ static int test_respond_metadata_request() { return 0; } -test_build_data_packet(char *packet, uint32_t packet_index){ +void test_build_data_packet(char *packet, uint32_t packet_index){ File *file = create_file("testfile", 0); @@ -190,7 +190,6 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_number) { - printf("testing header creation\n"); uint8_t length = build_pdu_header(packet, sequence_number, 0, header); uint32_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -252,7 +251,9 @@ int test_build_metadata_packet(char *packet, uint32_t start) { ASSERT_EQUALS_STR("test src_file_name", req->source_file_name, recv_request->source_file_name, strnlen(req->source_file_name, MAX_PATH)); ASSERT_EQUALS_STR("test dest_file_name", req->destination_file_name, recv_request->destination_file_name, strnlen(req->source_file_name, MAX_PATH)); - + uint16_t data_len = get_data_length(packet); + ASSERT_EQUALS_INT("test metadata set data length", data_len, len-start); + ssp_cleanup_req(req); ssp_cleanup_req(recv_request); @@ -269,19 +270,18 @@ int test_add_messages_to_packet(char *packet, uint32_t start) { uint32_t packet_index = start; + ssp_printf("testing add_messages_to_packet\n"); Request *req = init_request(1000); - int error = add_proxy_message_to_request(id, len, src, dest, req); - packet_index += add_messages_to_packet(packet, packet_index, req->messages_to_user); - ssp_print_hex(&packet[start], packet_index - start); + memset(&packet[start], 0, 100); + packet_index = add_messages_to_packet(packet, packet_index, req->messages_to_user); ASSERT_EQUALS_STR("'cfdp' should be at the start of the message", &packet[start], "cfdp", 5); ASSERT_EQUALS_INT("testing PROXY_PUT_REQUEST code", (uint8_t) packet[start + 5], PROXY_PUT_REQUEST); LV* dest_file, *src_file, *dest_id; - packet_index = start + 6; dest_id = copy_lv_from_buffer(packet, packet_index); ASSERT_EQUALS_INT("dest_file.length", dest_id->length, len); @@ -302,10 +302,89 @@ int test_add_messages_to_packet(char *packet, uint32_t start) { ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file->value, dest_file->length); free_lv(dest_file); + ssp_cleanup_req(req); + return 0; +} + +int test_get_message_from_packet(char *packet, uint32_t start) { + + char *dest = "dest"; + char *src = "src"; + uint32_t id = 2; + uint8_t len = 1; + + uint32_t packet_index = start; + + Request *req = init_request(1000); + int error = add_proxy_message_to_request(id, len, src, dest, req); + + uint32_t length_of_message = add_messages_to_packet(packet, start, req->messages_to_user); + + Request *req2 = init_request(1000); + uint32_t next_message = get_message_from_packet(packet, start, req2); + + Message *m = req2->messages_to_user->pop(req2->messages_to_user); + Message_put_proxy *p_message = m->value; + + ASSERT_EQUALS_INT("dest_file.length", p_message->destination_file_name->length, strnlen(dest, 100)); + ASSERT_EQUALS_STR("dest_file.value", p_message->destination_file_name->value, dest, strnlen(dest, 100)); + + ASSERT_EQUALS_INT("src_file.length", p_message->source_file_name->length, strnlen(src, 100)); + ASSERT_EQUALS_STR("src_file.value", src, p_message->source_file_name->value, strnlen(src, 100)); + + ASSERT_EQUALS_INT("dest_id.length", p_message->destination_id->length, len); + ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*)p_message->destination_id->value, id); + + ASSERT_EQUALS_INT("next message should be at index ", next_message, length_of_message); ssp_cleanup_req(req); + ssp_cleanup_req(req2); + return 0; + +} + + +//test multiple messages +int test_get_messages_from_packet(char *packet, uint32_t start) { + + char *dest = "dest"; + char *src = "src"; + uint32_t id = 2; + uint8_t len = 1; + + uint32_t packet_index = start; + + Request *req = init_request(1000); + int error = add_proxy_message_to_request(id, len, src, dest, req); + + uint32_t length_of_message = add_messages_to_packet(packet, start, req->messages_to_user); + length_of_message = add_messages_to_packet(packet, length_of_message, req->messages_to_user); + length_of_message = add_messages_to_packet(packet, length_of_message, req->messages_to_user); + + Request *req2 = init_request(1000); + get_messages_from_packet(packet, start, 1000 - start, req2); + int message_count = req2->messages_to_user->count; + + for (int i = 0; i < message_count; i++) { + + Message *message = req2->messages_to_user->pop(req2->messages_to_user); + + if (message->header.message_type == PROXY_PUT_REQUEST) { + + Message_put_proxy *p_message = (Message_put_proxy *) message->value; + ASSERT_EQUALS_INT("received proxy messages: dest.id", *(uint8_t*) p_message->destination_id->value, id); + ASSERT_EQUALS_STR("received proxy messages: src file", src, (char *) p_message->source_file_name->value, p_message->source_file_name->length); + ASSERT_EQUALS_STR("received proxy messages: dest file", dest, (char *) p_message->destination_file_name->value, p_message->destination_file_name->length); + } + } + + + + ssp_cleanup_req(req); + ssp_cleanup_req(req2); } + int packet_tests() { printf("starting Packet Tests (creating and changing packet values)\n"); @@ -326,7 +405,6 @@ int packet_tests() { Pdu_header *pdu_header = get_header_from_mib(mib, 1, 2); - char *packet = calloc(PACKET_TEST_SIZE, sizeof(char)); uint64_t sequence_number = 12345663234; int data_start_index = test_build_pdu_header(packet, pdu_header, sequence_number); @@ -340,6 +418,8 @@ int packet_tests() { test_build_data_packet(packet, data_start_index); test_build_metadata_packet(packet, data_start_index); test_add_messages_to_packet(packet, data_start_index); + test_get_message_from_packet(packet, data_start_index); + test_get_messages_from_packet(packet, data_start_index); free_mib(mib); ssp_cleanup_pdu_header(pdu_header); From 9bbd79331897b161b3269289205b4b486bd00e3a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 30 Oct 2019 19:06:23 -0600 Subject: [PATCH 127/400] Add proxy message integration --- Program/include/protocol_handler.h | 1 + Program/src/file_delivery_app.c | 1 + Program/src/filesystem_funcs.c | 6 +++--- Program/src/main.c | 9 ++++++-- Program/src/protocol_handler.c | 19 ++++++++++++++++- Program/src/requests.c | 33 ++++++++++++++++++++---------- Program/test/testestest | 0 7 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 Program/test/testestest diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index f920a01..7d8cbbd 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -17,6 +17,7 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); +void process_messages(Request *req, FTP *app); uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_ack (char *packet, uint32_t start, uint8_t type); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 50c92ae..bc30be4 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -25,6 +25,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { //adding new cfdp entities to management information base add_new_cfdp_entity(mib, 1, *addr, 1111, posix, UN_ACKNOWLEDGED_MODE); add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 7, *addr, 1113, posix, UN_ACKNOWLEDGED_MODE); add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 263ba3d..d985ed9 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -14,20 +14,20 @@ uint32_t get_file_size(char *source_file_name) { int fd = ssp_open(source_file_name, 0); if (fd == -1){ ssp_error("could not open file\n"); - return -1; + return 0; } int bytes = ssp_lseek(fd, 0, 2); if (bytes == -1){ ssp_error("could not seek file for file size\n"); - return -1; + return 0; } ssp_lseek(fd, 0, 0); if (ssp_close(fd) == -1){ ssp_error("could not close file\n"); - return -1; + return 0; } return bytes; diff --git a/Program/src/main.c b/Program/src/main.c index eba9950..ee70476 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -45,10 +45,15 @@ int main(int argc, char** argv) { //create a client if (conf->client_cfdp_id != 0){ - Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(1, 1, "pic.jpg", "dest.jpg", req); + //Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); + + Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + if (req == NULL) + return -1; + add_proxy_message_to_request(2, 1, "pic.jpeg", "dest.jpeg", req); start_request(req); + //send_request(new_client, req); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 873b926..9716267 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -228,6 +228,20 @@ uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) } +void process_messages(Request *req, FTP *app) { + + if (req->messages_to_user->count == 0) + return; + + Message *message = req->messages_to_user->pop(req->messages_to_user); + if (message->header.message_type == PROXY_PUT_REQUEST){ + + Message_put_proxy *p = (Message_put_proxy *) message->value; + start_request(put_request(*(uint8_t*)p->destination_id->value, (char *)p->source_file_name->value, (char *)p->destination_file_name->value, 0, app)); + } + +} + /*------------------------------------------------------------------------------ @@ -425,6 +439,7 @@ void on_server_time_out(Response res, Request *req) { if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); if (req->resent_finished == RESEND_FINISHED_TIMES) { @@ -485,7 +500,6 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_header *header = (Pdu_header *) packet; uint16_t data_len = get_data_length(packet); - //set timeout to 0, because received data req->timeout = 0; @@ -517,6 +531,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); packet_index += fill_request_pdu_metadata(&packet[packet_index], req); get_messages_from_packet(packet, packet_index, data_len, req); + process_messages(req, app); //get messages from packet here process_file_request_metadata(req); @@ -545,5 +560,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ default: break; } + + } diff --git a/Program/src/requests.c b/Program/src/requests.c index c318cd1..fb61e71 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -52,6 +52,7 @@ Message *create_message(uint8_t type) { message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); memcpy(message->header.message_id_cfdp, "cfdp", 5); message->header.message_type = type; + return message; } @@ -142,8 +143,9 @@ Request *init_request(uint32_t buff_len) { return req; } -//Omission of source and destination filenames shall indicate that only Meta -//data will be delivered +/*NULL for source and destination filenames shall indicate that only Meta +data will be delivered. Side effect: add request to client request list +returns the request*/ Request *put_request( uint32_t dest_id, char *source_file_name, @@ -152,13 +154,18 @@ Request *put_request( FTP *app ) { - uint32_t file_size = get_file_size(source_file_name); - Client *client; + File *file; + uint32_t file_size = 0; - if (file_size == -1) - return NULL; - - client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); + if (source_file_name != NULL && destination_file_name != NULL) { + file_size = get_file_size(source_file_name); + if (file_size == 0) + return NULL; + file = create_file(source_file_name, 0); + } + + //spin up a new client thread + Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); if (client == NULL) { client = ssp_client(dest_id, app); app->active_clients->insert(app->active_clients, client, dest_id); @@ -166,7 +173,6 @@ Request *put_request( //give the client a new request to perform Request *req = init_request(client->packet_len); - req->file = create_file(source_file_name, 0); //build a request req->transaction_sequence_number = app->transaction_sequence_number++; @@ -175,10 +181,15 @@ Request *put_request( req->procedure = sending_put_metadata; req->paused = true; req->dest_cfdp_id = client->remote_entity->cfdp_id; + + //do I need this/use this? req->file_size = file_size; - memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); - memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + if (source_file_name != NULL && destination_file_name != NULL) { + memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + + } req->transmission_mode = transmission_mode; req->res.addr = ssp_alloc(sizeof(uint64_t), 1); diff --git a/Program/test/testestest b/Program/test/testestest new file mode 100644 index 0000000..e69de29 From ed9dad04463ce2533673349a505d26d24dcd50bf Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 1 Nov 2019 10:31:30 -0600 Subject: [PATCH 128/400] fix mem leaks in tests --- Program/include/requests.h | 2 +- Program/src/requests.c | 57 ++++++++++++++++++++++++++++-------- Program/test/packet_tests.c | 9 ++++-- Program/test/request_tests.c | 21 +++++++++++-- 4 files changed, 71 insertions(+), 18 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index bc06c85..0202291 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -24,7 +24,7 @@ Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t le //Frees a message struct -void free_message(void *params); +void ssp_free_message(void *params); LV *create_lv(int size, void *value); uint16_t copy_lv_to_buffer(char *buffer, LV *lv); LV *copy_lv_from_buffer(char *packet, uint32_t start); diff --git a/Program/src/requests.c b/Program/src/requests.c index fb61e71..c6ab623 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -64,7 +64,7 @@ LV *copy_lv_from_buffer(char *packet, uint32_t start) { } -void free_message(void *params) { +void ssp_free_message(void *params) { Message *message = (Message*) params; Message_put_proxy* proxy_request; @@ -111,7 +111,7 @@ void ssp_cleanup_req(void *request) { ssp_free(req->local_entity); if (req->messages_to_user->count > 0) - req->messages_to_user->free(req->messages_to_user, free_message); + req->messages_to_user->free(req->messages_to_user, ssp_free_message); else req->messages_to_user->freeOnlyList(req->messages_to_user); @@ -137,6 +137,7 @@ Request *init_request(uint32_t buff_len) { req->buff = ssp_alloc(buff_len, sizeof(char)); req->res.msg = req->buff; req->procedure = none; + req->paused = true; req->messages_to_user = linked_list(); checkAlloc(req->buff, 1); @@ -157,15 +158,49 @@ Request *put_request( File *file; uint32_t file_size = 0; - if (source_file_name != NULL && destination_file_name != NULL) { - file_size = get_file_size(source_file_name); - if (file_size == 0) - return NULL; - file = create_file(source_file_name, 0); + if (source_file_name == NULL || destination_file_name == NULL) { + + //spin up a new client thread + Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); + + if (client == NULL) { + client = ssp_client(dest_id, app); + app->active_clients->insert(app->active_clients, client, dest_id); + } + + Request *req = init_request(client->packet_len); + + + //build a request + req->transaction_sequence_number = app->transaction_sequence_number++; + + //enumeration + req->procedure = sending_put_metadata; + req->dest_cfdp_id = client->remote_entity->cfdp_id; + + req->transmission_mode = transmission_mode; + req->res.addr = ssp_alloc(sizeof(uint64_t), 1); + + client->request_list->insert(client->request_list, req, 0); + + return req; + } + + if (strnlen(source_file_name, MAX_PATH) == 0 || strnlen(destination_file_name, MAX_PATH) == 0) { + ssp_printf("ERROR: no file names present in put request, if you want to just send messages, make both source and dest NULL\n"); + return; + } + + file_size = get_file_size(source_file_name); + if (file_size == 0) + return NULL; + file = create_file(source_file_name, 0); + //spin up a new client thread Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); + if (client == NULL) { client = ssp_client(dest_id, app); app->active_clients->insert(app->active_clients, client, dest_id); @@ -179,18 +214,14 @@ Request *put_request( //enumeration req->procedure = sending_put_metadata; - req->paused = true; req->dest_cfdp_id = client->remote_entity->cfdp_id; //do I need this/use this? req->file_size = file_size; - if (source_file_name != NULL && destination_file_name != NULL) { - memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); - memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); - } - req->transmission_mode = transmission_mode; req->res.addr = ssp_alloc(sizeof(uint64_t), 1); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index cd32019..e6c6edb 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -337,6 +337,7 @@ int test_get_message_from_packet(char *packet, uint32_t start) { ASSERT_EQUALS_INT("next message should be at index ", next_message, length_of_message); + ssp_free_message(m); ssp_cleanup_req(req); ssp_cleanup_req(req2); return 0; @@ -355,6 +356,8 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { uint32_t packet_index = start; Request *req = init_request(1000); + + int error = add_proxy_message_to_request(id, len, src, dest, req); uint32_t length_of_message = add_messages_to_packet(packet, start, req->messages_to_user); @@ -363,6 +366,7 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { Request *req2 = init_request(1000); get_messages_from_packet(packet, start, 1000 - start, req2); + int message_count = req2->messages_to_user->count; for (int i = 0; i < message_count; i++) { @@ -375,13 +379,14 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { ASSERT_EQUALS_INT("received proxy messages: dest.id", *(uint8_t*) p_message->destination_id->value, id); ASSERT_EQUALS_STR("received proxy messages: src file", src, (char *) p_message->source_file_name->value, p_message->source_file_name->length); ASSERT_EQUALS_STR("received proxy messages: dest file", dest, (char *) p_message->destination_file_name->value, p_message->destination_file_name->length); + } + ssp_free_message(message); } - - ssp_cleanup_req(req); ssp_cleanup_req(req2); + } diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 801f484..302f362 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -5,6 +5,7 @@ #include "test.h" #include "filesystem_funcs.h" #include "string.h" +#include "file_delivery_app.h" static void list_print_id(void *element, void *args) { Request *req = (Request *) element; @@ -123,8 +124,7 @@ static int add_proxy_message() { ASSERT_EQUALS_STR("proxy src file", proxy->source_file_name->value, src, proxy->source_file_name->length); ASSERT_EQUALS_STR("proxy dest file", proxy->destination_file_name->value, dest, proxy->destination_file_name->length); - free_message(message); - + ssp_free_message(message); ssp_cleanup_req(req); return 0; @@ -157,10 +157,27 @@ int test_lv_functions() { } + +int request_user_input_tests() { + + FTP *app = init_ftp(1); + put_request(2, "", "", 0, app); + + + + + + + + app->close = true; + ssp_thread_join(app->server_handle); +} + int request_tests() { int error = 0; error = request_finding_test(); + error = request_user_input_tests(); error = add_proxy_message(); error = test_lv_functions(); From a45eaeea052556fa2248bee37ce8d9ebd36bf25c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 2 Nov 2019 14:54:28 -0600 Subject: [PATCH 129/400] add user input cleaning for put_request --- Program/src/main.c | 4 -- Program/src/protocol_handler.c | 17 +++++-- Program/src/requests.c | 85 +++++++++++++++------------------- Program/test/packet_tests.c | 8 ++-- 4 files changed, 54 insertions(+), 60 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index ee70476..64de924 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -45,8 +45,6 @@ int main(int argc, char** argv) { //create a client if (conf->client_cfdp_id != 0){ - //Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "remote_pic1.jpeg", ACKNOWLEDGED_MODE, app); - Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); if (req == NULL) return -1; @@ -54,8 +52,6 @@ int main(int argc, char** argv) { add_proxy_message_to_request(2, 1, "pic.jpeg", "dest.jpeg", req); start_request(req); - //send_request(new_client, req); - } //ssp_thread_join(app->server_handle); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 9716267..1d350f9 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -235,8 +235,9 @@ void process_messages(Request *req, FTP *app) { Message *message = req->messages_to_user->pop(req->messages_to_user); if (message->header.message_type == PROXY_PUT_REQUEST){ - + Message_put_proxy *p = (Message_put_proxy *) message->value; + ssp_printf("source file name: %s\n", (char *)p->source_file_name->value); start_request(put_request(*(uint8_t*)p->destination_id->value, (char *)p->source_file_name->value, (char *)p->destination_file_name->value, 0, app)); } @@ -380,6 +381,12 @@ void user_request_handler(Response res, Request *req, Client* client) { ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(req->buff, start, req); ssp_sendto(res); + + if (req->file == NULL) { + req->procedure = sending_finished; + break; + } + req->procedure = sending_data; break; @@ -461,7 +468,7 @@ void on_server_time_out(Response res, Request *req) { build_nak_directive(req->buff, start, EOF_PDU); ssp_sendto(res); } - //received EOF, send back 3 eof ack packets + //received EOF, send back 3 eof ack packets if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); build_ack(req->buff, start, EOF_PDU); @@ -521,6 +528,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; packet_index++; + switch (directive->directive_code) { case META_DATA_PDU: @@ -533,8 +541,9 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ get_messages_from_packet(packet, packet_index, data_len, req); process_messages(req, app); - //get messages from packet here - process_file_request_metadata(req); + if (req->file_size != 0) + process_file_request_metadata(req); + break; case EOF_PDU: diff --git a/Program/src/requests.c b/Program/src/requests.c index c6ab623..ff8fe6e 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -144,6 +144,32 @@ Request *init_request(uint32_t buff_len) { return req; } + +//starts a new client, adding it to app->active_clients, as well as +//starting a new request and adding it to the client, returns a pointer +//to the request +static Request *start_new_client_request(FTP *app, uint8_t dest_id) { + + //spin up a new client thread + Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); + + if (client == NULL) { + client = ssp_client(dest_id, app); + app->active_clients->insert(app->active_clients, client, dest_id); + } + + Request *req = init_request(client->packet_len); + + //build a request + req->transaction_sequence_number = app->transaction_sequence_number++; + req->dest_cfdp_id = client->remote_entity->cfdp_id; + req->res.addr = ssp_alloc(sizeof(uint64_t), 1); + client->request_list->insert(client->request_list, req, 0); + + return req; +} + + /*NULL for source and destination filenames shall indicate that only Meta data will be delivered. Side effect: add request to client request list returns the request*/ @@ -155,67 +181,31 @@ Request *put_request( FTP *app ) { - File *file; + Request *req; uint32_t file_size = 0; if (source_file_name == NULL || destination_file_name == NULL) { - - //spin up a new client thread - Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); - - if (client == NULL) { - client = ssp_client(dest_id, app); - app->active_clients->insert(app->active_clients, client, dest_id); - } - - Request *req = init_request(client->packet_len); - - - //build a request - req->transaction_sequence_number = app->transaction_sequence_number++; - - //enumeration + req = start_new_client_request(app, dest_id); req->procedure = sending_put_metadata; - req->dest_cfdp_id = client->remote_entity->cfdp_id; - req->transmission_mode = transmission_mode; - req->res.addr = ssp_alloc(sizeof(uint64_t), 1); - - client->request_list->insert(client->request_list, req, 0); - return req; - } if (strnlen(source_file_name, MAX_PATH) == 0 || strnlen(destination_file_name, MAX_PATH) == 0) { ssp_printf("ERROR: no file names present in put request, if you want to just send messages, make both source and dest NULL\n"); - return; + return NULL; } + req = start_new_client_request(app, dest_id); + file_size = get_file_size(source_file_name); if (file_size == 0) return NULL; - file = create_file(source_file_name, 0); - - - //spin up a new client thread - Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); - - if (client == NULL) { - client = ssp_client(dest_id, app); - app->active_clients->insert(app->active_clients, client, dest_id); - } - - //give the client a new request to perform - Request *req = init_request(client->packet_len); - - //build a request - req->transaction_sequence_number = app->transaction_sequence_number++; - //enumeration + req->file = create_file(source_file_name, 0); req->procedure = sending_put_metadata; - req->dest_cfdp_id = client->remote_entity->cfdp_id; - + req->transmission_mode = transmission_mode; + //do I need this/use this? req->file_size = file_size; @@ -225,8 +215,6 @@ Request *put_request( req->transmission_mode = transmission_mode; req->res.addr = ssp_alloc(sizeof(uint64_t), 1); - client->request_list->insert(client->request_list, req, 0); - return req; } @@ -239,9 +227,10 @@ void start_request(Request *req){ Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { + Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); - proxy->destination_file_name = create_lv(strnlen(dest_name, MAX_PATH), dest_name); - proxy->source_file_name = create_lv(strnlen(source_name, MAX_PATH), source_name); + proxy->destination_file_name = create_lv(strnlen(dest_name, MAX_PATH) + 1, dest_name); + proxy->source_file_name = create_lv(strnlen(source_name, MAX_PATH) + 1, source_name); proxy->destination_id = create_lv(length_of_id, &beneficial_cfid); return proxy; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index e6c6edb..0edd2d9 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -291,14 +291,14 @@ int test_add_messages_to_packet(char *packet, uint32_t start) { src_file = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("src_file.length", src_file->length, strnlen(src, 100)); + ASSERT_EQUALS_INT("src_file.length", src_file->length, strnlen(src, 100) + 1); ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file->value, src_file->length); packet_index += src_file->length + 1; free_lv(src_file); dest_file = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("dest_file.length", dest_file->length, strnlen(dest, 100)); + ASSERT_EQUALS_INT("dest_file.length", dest_file->length, strnlen(dest, 100) + 1); ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file->value, dest_file->length); free_lv(dest_file); @@ -326,10 +326,10 @@ int test_get_message_from_packet(char *packet, uint32_t start) { Message *m = req2->messages_to_user->pop(req2->messages_to_user); Message_put_proxy *p_message = m->value; - ASSERT_EQUALS_INT("dest_file.length", p_message->destination_file_name->length, strnlen(dest, 100)); + ASSERT_EQUALS_INT("dest_file.length", p_message->destination_file_name->length, strnlen(dest, 100) + 1); ASSERT_EQUALS_STR("dest_file.value", p_message->destination_file_name->value, dest, strnlen(dest, 100)); - ASSERT_EQUALS_INT("src_file.length", p_message->source_file_name->length, strnlen(src, 100)); + ASSERT_EQUALS_INT("src_file.length", p_message->source_file_name->length, strnlen(src, 100) + 1); ASSERT_EQUALS_STR("src_file.value", src, p_message->source_file_name->value, strnlen(src, 100)); ASSERT_EQUALS_INT("dest_id.length", p_message->destination_id->length, len); From db6398b00a6f60bca2dd838a1d3182db141b6a65 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 2 Nov 2019 16:12:48 -0600 Subject: [PATCH 130/400] add removal of client threads from server, missing 8bytes on exit --- Program/include/list.h | 21 ++++---- Program/include/packet.h | 4 +- Program/src/filesystem_funcs.c | 6 +-- Program/src/list.c | 70 +++++++++++++++---------- Program/src/main.c | 2 +- Program/src/packet.c | 6 +-- Program/src/protocol_handler.c | 4 +- Program/src/server.c | 2 - Program/src/tasks.c | 96 +++++++++++++++++++--------------- 9 files changed, 120 insertions(+), 91 deletions(-) diff --git a/Program/include/list.h b/Program/include/list.h index 87a2c2a..8392d7f 100644 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -6,13 +6,13 @@ /*------------------------------------------------------------------------------ Purpose: This is a node for the link list bellow ------------------------------------------------------------------------------*/ -typedef struct NODE +typedef struct Node { uint32_t id; void *element; - struct NODE *next; - struct NODE *prev; -} NODE; + struct Node *next; + struct Node *prev; +} Node; /*------------------------------------------------------------------------------ Purpose: This is a LIST struct that contains functions useful for @@ -20,25 +20,26 @@ typedef struct NODE ------------------------------------------------------------------------------*/ typedef struct List { - struct NODE *head; - struct NODE *tail; + struct Node *head; + struct Node *tail; int count; int (*push)(struct List *list, void *element, uint32_t id); void *(*remove)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); - void (*iterate)(struct List *list, void (*f)(void *element, void *args), void *args); + void (*iterate)(struct List *list, void (*f)(Node *node, void *element, void *args), void *args); void (*free)(struct List *list, void (*f)(void *element)); void *(*pop) (struct List *list); int (*insert) (struct List *list, void *element, uint32_t id); int (*insertAt)(struct List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args); //returns a void pointer that should be cast to the type void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); - struct NODE *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + struct Node *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); void (*freeOnlyList)(struct List *list); - void (*freeNode)(NODE *node); + void (*freeNode)(Node *node); + void *(*removeNode)(struct List *list, Node *node); } List; -NODE *createNode(void *element, uint32_t id); +Node *createNode(void *element, uint32_t id); /*------------------------------------------------------------------------------ Purpose: This function initializes a linked list LIST *. Perameters: empty is just for the compiler errors, TODO use it for something diff --git a/Program/include/packet.h b/Program/include/packet.h index 6862acc..e0448ff 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -13,7 +13,7 @@ #include "types.h" #include - +#include "list.h" uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_finished_pdu(char *packet, uint32_t start); @@ -22,7 +22,7 @@ uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Reques uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); void build_eof_packet(char *packet, uint32_t start, Request *req); -void fill_nak_array(void *element, void *args); +void fill_nak_array_callback(Node *node, void *element, void *args); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); uint8_t build_ack(char*packet, uint32_t start, uint8_t type); uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) ; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index d985ed9..ca49394 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -196,7 +196,7 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs offset_to_insert.start = offset_start; offset_to_insert.end = offset_end; - NODE * node = nak_list->findNode(nak_list, -1, find_nak, &offset_to_insert); + Node *node = nak_list->findNode(nak_list, -1, find_nak, &offset_to_insert); if (node == NULL){ ssp_printf("trying to receive offset start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end); @@ -230,8 +230,8 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs offset_in_list->start = offset_end; new_offset->end = offset_start; - NODE *cur = node; - NODE *new = createNode(new_offset, new_offset->start); + Node *cur = node; + Node *new = createNode(new_offset, new_offset->start); new->next = cur; new->prev = cur->prev; diff --git a/Program/src/list.c b/Program/src/list.c index a6ae654..8d40992 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -11,9 +11,9 @@ new node, or NULL if failed ------------------------------------------------------------------------------*/ -NODE *createNode(void *element, uint32_t id) +Node *createNode(void *element, uint32_t id) { - NODE *newNode = calloc(sizeof(NODE), 1); + Node *newNode = calloc(sizeof(Node), 1); if (newNode == NULL) { return NULL; } @@ -31,7 +31,7 @@ NODE *createNode(void *element, uint32_t id) ------------------------------------------------------------------------------*/ -static void freeNode(NODE *node) { +static void freeNode(Node *node) { if (node != NULL) free(node); } @@ -41,9 +41,9 @@ static void *pop(List *list) { if (list->count == 0) return NULL; - NODE *last_data_node = list->tail->prev; + Node *last_data_node = list->tail->prev; - NODE *prev = last_data_node->prev; + Node *prev = last_data_node->prev; prev->next = list->tail; list->tail->prev = prev; @@ -61,8 +61,8 @@ static void *pop(List *list) { static int insert(List *list, void *element, uint32_t id) { - NODE *head = list->head; - NODE *node = createNode(element, id); + Node *head = list->head; + Node *node = createNode(element, id); if (node == NULL) { return 0; } @@ -84,11 +84,11 @@ static int insert(List *list, void *element, uint32_t id) { static int push(List *list, void *element, uint32_t id) { - NODE *newNode = createNode(element, id); + Node *newNode = createNode(element, id); if (newNode == NULL) { return 0; } - NODE *tail = list->tail; + Node *tail = list->tail; newNode->next = tail; newNode->prev = tail->prev; @@ -109,18 +109,33 @@ static int push(List *list, void *element, uint32_t id) to print out an element. ------------------------------------------------------------------------------*/ -static void iterate(List *list, void (*f)(void *element, void *args), void *args) +static void iterate(List *list, void (*f)(Node *node, void *element, void *args), void *args) { - NODE *cur = list->head->next; - NODE *next; + Node *cur = list->head->next; + Node *next; while (cur->next != NULL) { next = cur->next; - f(cur->element, args); + f(cur, cur->element, args); cur = next; } } +//deletes the node, and returns the object, (motifys the list) +static void *removeNode(List *list, Node *node) { + + Node *previous = node->prev; + Node *next = node->next; + + previous->next = next; + next->prev = previous; + + void *element = node->element; + list->freeNode(node); + list->count--; + return element; +} + /*------------------------------------------------------------------------------ This function removes an element from the linked list, returns the node stored if success @@ -130,7 +145,7 @@ static void iterate(List *list, void (*f)(void *element, void *args), void *args static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { - NODE *cur = list->head->next; + Node *cur = list->head->next; int found_with_func = 0; int found_with_id = 0; while (cur->next != NULL) @@ -143,8 +158,8 @@ static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void if (found_with_func || found_with_id) { - NODE *previous = cur->prev; - NODE *next = cur->next; + Node *previous = cur->prev; + Node *next = cur->next; previous->next = next; next->prev = previous; @@ -168,11 +183,11 @@ static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void static void freeList(List *list, void (*f)(void *element)) { - NODE *cur = list->head->next; + Node *cur = list->head->next; while (cur->next != NULL) { - NODE *n = cur; + Node *n = cur; cur = cur->next; f(n->element); freeNode(n); @@ -185,11 +200,11 @@ static void freeList(List *list, void (*f)(void *element)) static void freeNodes(List *list) { - NODE *cur = list->head->next; + Node *cur = list->head->next; while (cur->next != NULL) { - NODE *n = cur; + Node *n = cur; cur = cur->next; freeNode(n); } @@ -208,7 +223,7 @@ static void freeNodes(List *list) { static void *findElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { - NODE *cur = list->head->next; + Node *cur = list->head->next; int found_with_func = 0; int found_with_id = 0; while (cur->next != NULL) @@ -229,7 +244,7 @@ static void *findElement(List *list, uint32_t id, int (*f)(void *element, void * static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args) { - NODE *cur = list->head->next; + Node *cur = list->head->next; int found_with_func = 0; int found_with_id = 0; while (cur->next != NULL) @@ -241,7 +256,7 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme found_with_id = 1; if (found_with_func || found_with_id) { - NODE *new = createNode(element, id); + Node *new = createNode(element, id); new->next = cur; new->prev = cur->prev; new->prev->next = new; @@ -255,9 +270,9 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme } -static NODE *findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { +static Node *findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { - NODE *cur = list->head->next; + Node *cur = list->head->next; int found_with_func = 0; int found_with_id = 0; while (cur->next != NULL) @@ -291,8 +306,8 @@ List *linked_list() if (newList->tail == NULL) return NULL; - NODE *tail = newList->tail; - NODE *head = newList->head; + Node *tail = newList->tail; + Node *head = newList->head; tail->prev = head; tail->next = NULL; @@ -311,6 +326,7 @@ List *linked_list() newList->findNode = findNode; newList->freeNode = freeNode; newList->freeOnlyList = freeNodes; + newList->removeNode = removeNode; return newList; } diff --git a/Program/src/main.c b/Program/src/main.c index 64de924..08f87ab 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -55,7 +55,7 @@ int main(int argc, char** argv) { } //ssp_thread_join(app->server_handle); - ssp_join_clients(app->active_clients); + //ssp_join_clients(app->active_clients); ssp_thread_join(app->server_handle); diff --git a/Program/src/packet.c b/Program/src/packet.c index 24b0d6c..1a45737 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -235,7 +235,7 @@ struct offset_holder { int i; }; -void fill_nak_array(void *element, void *args){ +void fill_nak_array_callback(Node *node, void *element, void *args){ struct offset_holder *holder = (struct offset_holder *)args; Offset *offset = (Offset *)element; @@ -257,7 +257,7 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { holder.offsets = ssp_alloc(count, sizeof(Offset)); holder.i = 0; - req->file->missing_offsets->iterate(req->file->missing_offsets, fill_nak_array, &holder); + req->file->missing_offsets->iterate(req->file->missing_offsets, fill_nak_array_callback, &holder); pdu_nak->start_scope = holder.offsets[0].start; pdu_nak->end_scope = holder.offsets[holder.i-1].end; @@ -320,7 +320,7 @@ struct packet_callback_params { uint32_t *packet_index; }; -static void add_messages_callback(void *element, void *args) { +static void add_messages_callback(Node *node, void *element, void *args) { struct packet_callback_params *params = (struct packet_callback_params *) args; char *packet = params->packet; uint32_t packet_index = *(params->packet_index); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1d350f9..e5d352c 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -27,8 +27,6 @@ static void request_metadata(Request *req, Response res) { return; } - - /*------------------------------------------------------------------------------ Processing Packets @@ -239,6 +237,8 @@ void process_messages(Request *req, FTP *app) { Message_put_proxy *p = (Message_put_proxy *) message->value; ssp_printf("source file name: %s\n", (char *)p->source_file_name->value); start_request(put_request(*(uint8_t*)p->destination_id->value, (char *)p->source_file_name->value, (char *)p->destination_file_name->value, 0, app)); + ssp_free_message(message); + } } diff --git a/Program/src/server.c b/Program/src/server.c index c97633d..d85d78d 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -306,8 +306,6 @@ void connectionless_server(char* port, int initial_buff_size, char *buff = ssp_alloc(sizeof(char), *buff_size); checkAlloc(buff, 1); - - for (;;) { if (exit_now || checkExit(other)){ diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 55f7ddb..5ad646e 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -16,7 +16,7 @@ Callbacks for the tasks bellow ------------------------------------------------------------------------------*/ -static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { +static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { FTP *app = (FTP *) other; Response res; @@ -41,7 +41,7 @@ static int on_recv_server(int sfd, char *packet, uint32_t packet_len, uint32_t } -static int on_recv_client(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { +static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { Client *client = (Client *) other; @@ -93,7 +93,7 @@ struct user_request_check_params { Client *client; }; -static void user_request_check(void *request, void *args) { +static void user_request_check(Node *node, void *request, void *args) { Request * req = (Request *) request; struct user_request_check_params* params = (struct user_request_check_params *) args; @@ -104,8 +104,7 @@ static void user_request_check(void *request, void *args) { remove_request_check(request, params->client->request_list); } -static int on_send_client(int sfd, void *addr, size_t size_of_addr, void *other) { - +static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, void *other) { Response res; Client *client = (Client *) other; @@ -120,8 +119,6 @@ static int on_send_client(int sfd, void *addr, size_t size_of_addr, void *other) res.type_of_network = client->remote_entity->type_of_network; res.transmission_mode = client->remote_entity->default_transmission_mode; - - struct user_request_check_params params = { res, client @@ -132,50 +129,67 @@ static int on_send_client(int sfd, void *addr, size_t size_of_addr, void *other) return 0; } -static void timeout_check(void *request, void *args) { + + +static void timeout_check_callback(Node *node, void *request, void *args) { Request *req = (Request *) request; on_server_time_out(req->res, req); remove_request_check(request, args); } + + +static void client_check_callback(Node *node, void *client, void *args) { + Client *c = (Client *) client; + List *list = (List *) args; + + if (c->close) { + Client *remove_this = (Client *) list->removeNode(list, node); + + ssp_thread_join(c->client_handle); + ssp_free(remove_this); + } +} + //this function is a callback when using my posix ports -static int on_time_out_posix(void *other) { +static int on_time_out_callback(void *other) { FTP *app = (FTP*) other; if(app->current_request == NULL) return 0; - app->request_list->iterate(app->request_list, timeout_check, app->request_list); + app->request_list->iterate(app->request_list, timeout_check_callback, app->request_list); + app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); return 0; } -static int check_exit_server(void *params) { +static int check_exit_server_callback(void *params) { FTP *app = (FTP*) params; if (app->close) return 1; return 0; } -static int check_exit_client(void *params) { +static int check_exit_client_callback(void *params) { Client *client = (Client*) params; if (client->close) return 1; return 0; } -static void on_exit_client (void *params) { +static void on_exit_client_callback (void *params) { Client *client = (Client*) params; ssp_cleanup_client(client); } -static void on_exit_server (void *params) { +static void on_exit_server_callback (void *params) { FTP *app = (FTP*) params; ssp_cleanup_ftp(app); } //this function is just for posix fun -static int on_stdin(void *other) { +static int on_stdin_callback(void *other) { /* FTP *app = (FTP *) other; @@ -227,7 +241,7 @@ void *ssp_connectionless_server_task(void *params) { char port[10]; snprintf(port, 10, "%d",app->remote_entity->UT_port); - connectionless_server(port, app->packet_len, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, app); + connectionless_server(port, app->packet_len, on_recv_server_callback, on_time_out_callback, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, app); return NULL; } @@ -246,7 +260,7 @@ void *ssp_connectionless_client_task(void* params){ //convert uint id to char * inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); - connectionless_client(host_name, port, client->packet_len, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + connectionless_client(host_name, port, client->packet_len, client, client, client, client, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, on_exit_client_callback); return NULL; } @@ -260,7 +274,7 @@ void *ssp_connection_server_task(void *params) { snprintf(port, 10, "%u",app->remote_entity->UT_port); //1024 is the connection max limit - connection_server(port, app->packet_len, 10, on_recv_server, on_time_out_posix, on_stdin, check_exit_server, on_exit_server, app); + connection_server(port, app->packet_len, 10, on_recv_server_callback, on_time_out_callback, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, app); return NULL; } @@ -277,7 +291,7 @@ void *ssp_connection_client_task(void *params) { //convert uint id to char * inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); - connection_client(host_name, port, client->packet_len, client, client, client, client, on_send_client, on_recv_client, check_exit_client, on_exit_client); + connection_client(host_name, port, client->packet_len, client, client, client, client, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, on_exit_client_callback); return NULL; } @@ -286,13 +300,13 @@ void *ssp_csp_connectionless_server_task(void *params) { printf("starting csp connectionless server\n"); FTP *app = (FTP *) params; csp_connectionless_server( - app->remote_entity->UT_port, - on_recv_server, - on_time_out_posix, - on_stdin, - check_exit_server, - on_exit_server, - app); + app->remote_entity->UT_port, + on_recv_server_callback, + on_time_out_callback, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, + app); return NULL; } @@ -302,7 +316,7 @@ void *ssp_csp_connectionless_client_task(void *params) { Client *client = (Client *) params; csp_connectionless_client(client->remote_entity->UT_address, client->remote_entity->UT_port, - client->app->remote_entity->UT_port, on_send_client, on_recv_client, check_exit_client, on_exit_client, client); + client->app->remote_entity->UT_port, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, on_exit_client_callback, client); return NULL; } @@ -311,11 +325,11 @@ void *ssp_csp_connection_server_task(void *params) { printf("starting csp connection server\n"); FTP *app = (FTP *) params; csp_connection_server(app->remote_entity->UT_port, - on_recv_server, - on_time_out_posix, - on_stdin, - check_exit_server, - on_exit_server, + on_recv_server_callback, + on_time_out_callback, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, params); return NULL; @@ -326,10 +340,10 @@ void *ssp_csp_connection_client_task(void *params) { Client *client = (Client *) params; csp_connection_client(client->remote_entity->UT_address, client->remote_entity->UT_port, - on_send_client, - on_recv_client, - check_exit_client, - on_exit_client, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback, params); return NULL; } @@ -339,7 +353,7 @@ void *ssp_csp_connection_client_task(void *params) { ------------------------------------------------------------------------------*/ -static void ssp_client_join(void *element, void*args) { +static void ssp_client_join(Node *node, void *element, void*args) { Client *client = (Client *) element; ssp_thread_join(client->client_handle); } @@ -348,16 +362,16 @@ void ssp_join_clients(List *clients) { clients->iterate(clients, ssp_client_join, NULL); } -static void exit_client(void *element, void *args) { +static void exit_client(Node *node, void *element, void *args) { Client *client = (Client *) element; client->close = true; } void ssp_cleanup_ftp(FTP *app) { app->request_list->free(app->request_list, ssp_cleanup_req); + app->active_clients->iterate(app->active_clients, exit_client, NULL); - if (app->close == true) - app->active_clients->iterate(app->active_clients, exit_client, NULL); + app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); free_mib(app->mib); app->active_clients->freeOnlyList(app->active_clients); @@ -367,5 +381,5 @@ void ssp_cleanup_ftp(FTP *app) { void ssp_cleanup_client(Client *client) { client->request_list->free(client->request_list, ssp_cleanup_req); ssp_cleanup_pdu_header(client->pdu_header); - ssp_free(client); + } From 6f6adcbc0ec489595db14247267348490d5ee6ca Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 5 Nov 2019 09:04:07 -0700 Subject: [PATCH 131/400] fixed mem leak, don't need to allocate address, it does that in server --- Program/src/requests.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Program/src/requests.c b/Program/src/requests.c index ff8fe6e..1d9b2f8 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -135,10 +135,12 @@ Request *init_request(uint32_t buff_len) { req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); - req->res.msg = req->buff; + req->procedure = none; req->paused = true; + req->res.msg = req->buff; + req->messages_to_user = linked_list(); checkAlloc(req->buff, 1); return req; @@ -163,7 +165,6 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //build a request req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity->cfdp_id; - req->res.addr = ssp_alloc(sizeof(uint64_t), 1); client->request_list->insert(client->request_list, req, 0); return req; @@ -213,7 +214,6 @@ Request *put_request( memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); req->transmission_mode = transmission_mode; - req->res.addr = ssp_alloc(sizeof(uint64_t), 1); return req; } From 963ee5d866f2bd2ad97cb14b05bab31d44f9fbec Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 6 Nov 2019 10:24:51 -0700 Subject: [PATCH 132/400] fix pause bug --- Program/src/main.c | 10 ++++------ Program/src/protocol_handler.c | 14 ++++++++++---- Program/src/requests.c | 7 ++----- Program/src/tasks.c | 12 ++++++++---- Program/test/test.c | 2 +- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index 08f87ab..a2eecb7 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -45,20 +45,18 @@ int main(int argc, char** argv) { //create a client if (conf->client_cfdp_id != 0){ - Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "anotherpicyo.jpg", ACKNOWLEDGED_MODE, app); + if (req == NULL) return -1; - add_proxy_message_to_request(2, 1, "pic.jpeg", "dest.jpeg", req); + //add_proxy_message_to_request(2, 1, "pic.jpeg", "dest.jpg", req); start_request(req); } - //ssp_thread_join(app->server_handle); - //ssp_join_clients(app->active_clients); ssp_thread_join(app->server_handle); - - free(conf); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e5d352c..3a7f464 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -149,7 +149,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(app->mib, source_id, app->my_cfdp_id); found_req->remote_entity = get_remote_entity(app->mib, source_id); - found_req->procedure = sending_put_metadata; found_req->res.addr = ssp_alloc(1, res.size_of_addr); memcpy(found_req->res.addr, res.addr, res.size_of_addr); @@ -157,7 +156,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->res.sfd = res.sfd; found_req->res.transmission_mode = app->remote_entity->default_transmission_mode; found_req->res.type_of_network = app->remote_entity->type_of_network; - + found_req->paused = false; request_list->push(request_list, found_req, transaction_sequence_number); } @@ -235,8 +234,14 @@ void process_messages(Request *req, FTP *app) { if (message->header.message_type == PROXY_PUT_REQUEST){ Message_put_proxy *p = (Message_put_proxy *) message->value; - ssp_printf("source file name: %s\n", (char *)p->source_file_name->value); - start_request(put_request(*(uint8_t*)p->destination_id->value, (char *)p->source_file_name->value, (char *)p->destination_file_name->value, 0, app)); + ssp_printf("received proxy request for source file name: %s dest file name %s, to id %d\n", + (char *)p->source_file_name->value, + (char *)p->destination_file_name->value, + *(uint8_t*)p->destination_id->value); + + start_request(put_request(*(uint8_t*)p->destination_id->value, + (char *)p->source_file_name->value, + (char *)p->destination_file_name->value, ACKNOWLEDGED_MODE, app)); ssp_free_message(message); } @@ -410,6 +415,7 @@ void user_request_handler(Response res, Request *req, Client* client) { static int reset_timeout(Request *req) { + if (req->timeout++ >= TIMEOUT_BEFORE_CANCEL_REQUEST) { ssp_printf("time to live ended, closing up request transaction: %d\n", req->transaction_sequence_number); if (req->procedure != none) diff --git a/Program/src/requests.c b/Program/src/requests.c index 1d9b2f8..548de81 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -204,16 +204,13 @@ Request *put_request( return NULL; req->file = create_file(source_file_name, 0); + req->file_size = file_size; + req->procedure = sending_put_metadata; req->transmission_mode = transmission_mode; - //do I need this/use this? - req->file_size = file_size; - memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); - - req->transmission_mode = transmission_mode; return req; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 5ad646e..ea3575b 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -30,7 +30,6 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, int packet_index = process_pdu_header(packet, 1, res, request_container, app->request_list, app); app->current_request = (*request_container); - if (packet_index < 0) return -1; @@ -80,9 +79,9 @@ static int remove_request(void *request, void *args) { static void remove_request_check(void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; - //ssp_printf("CLEANINGUP request count: %d procedure:%d cleanup %d none: %d sending_put_metadata %d\n", req_list->count, req->procedure, clean_up, none, sending_put_metadata); if (req->procedure == clean_up) { + ssp_printf("removing request\n"); Request *remove_this = req_list->remove(req_list, 0, remove_request, req); ssp_cleanup_req(remove_this); } @@ -98,8 +97,8 @@ static void user_request_check(Node *node, void *request, void *args) { struct user_request_check_params* params = (struct user_request_check_params *) args; params->res.msg = req->buff; - memset(params->res.msg, 0, params->client->packet_len); + user_request_handler(params->res, req, params->client); remove_request_check(request, params->client->request_list); } @@ -135,6 +134,7 @@ static void timeout_check_callback(Node *node, void *request, void *args) { Request *req = (Request *) request; on_server_time_out(req->res, req); remove_request_check(request, args); + } @@ -144,12 +144,16 @@ static void client_check_callback(Node *node, void *client, void *args) { if (c->close) { Client *remove_this = (Client *) list->removeNode(list, node); - + ssp_printf("removing client, from server \n"); ssp_thread_join(c->client_handle); ssp_free(remove_this); } } +static void test_s () { + +} + //this function is a callback when using my posix ports static int on_time_out_callback(void *other) { diff --git a/Program/test/test.c b/Program/test/test.c index cea54ae..bb2845f 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -26,7 +26,7 @@ void ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { if (val1 == val2){ printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d\n", test_num); + printf(" fail # %d %s %s\n", test_num, __LINE__, __FILE__); } else { printf("\033[0;32m"); From cab9fca0c1c1e497d2e739db76a824df0ba4f4fb Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 8 Nov 2019 10:23:01 -0700 Subject: [PATCH 133/400] cleaning up tests --- Program/test/main.c | 6 +++--- Program/test/makefile | 1 + Program/test/tasks_tests.c | 25 +++++++++++++++++++++++++ Program/test/test.c | 8 ++++++++ Program/test/unit_tests.h | 7 +++++++ 5 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 Program/test/tasks_tests.c create mode 100644 Program/test/unit_tests.h diff --git a/Program/test/main.c b/Program/test/main.c index e33543a..6f2c558 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -27,12 +27,12 @@ int main (int argc, char **argv) { int error = 0; - error = request_tests(); + //error = request_tests(); //error = protocol_handler_test(); - error = packet_tests(); - + //error = packet_tests(); //error = list_tests(); //error = file_system_tests(); + error = tasks_tests(); /* if (strcmp(argv[1], "1") == 0) diff --git a/Program/test/makefile b/Program/test/makefile index d46ec69..70d6601 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -30,6 +30,7 @@ CFILES += $(PROJDIR)/src/packet.c CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c CFILES += $(PROJDIR)/test/request_tests.c +CFILES += $(PROJDIR)/test/tasks_tests.c #CFILES += $(PROJDIR)/test/filesystem_tests.c #CFILES += $(PROJDIR)/test/protocol_handler_tests.c #CFILES += $(PROJDIR)/test/list_tests.c diff --git a/Program/test/tasks_tests.c b/Program/test/tasks_tests.c new file mode 100644 index 0000000..2fbb04f --- /dev/null +++ b/Program/test/tasks_tests.c @@ -0,0 +1,25 @@ +#include "unit_tests.h" +#include "test.h" + + + +void test_remove_request() { + //remove_request_check(void *request, void *args); +} + + + +int tasks_tests() { + DECLARE_NEW_TEST("Tasks"); + + + test_remove_request(); + + + int error = 0; + + + + + return error; +} \ No newline at end of file diff --git a/Program/test/test.c b/Program/test/test.c index bb2845f..0f7652b 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -3,6 +3,14 @@ #include int test_num = 0; + + +void DECLARE_NEW_TEST(char *description) { + printf("\x1b[33m"); + printf("-----------------------------------%s-----------------------------------\n", description); +} + + void ASSERT_EQUALS_INT(char* description, int val1, int val2) { test_num++; diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h new file mode 100644 index 0000000..ddaf35a --- /dev/null +++ b/Program/test/unit_tests.h @@ -0,0 +1,7 @@ +#ifdef SSP_UNIT_TEST_H +#define SSP_UNIT_TEST_H + + int tasks_tests(); + + +#endif \ No newline at end of file From 4970c369fa87c12985b9a8d443998f1e44983ded Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 Nov 2019 12:03:17 -0700 Subject: [PATCH 134/400] test update --- Program/src/list.c | 12 +----- Program/test/filesystem_tests.c | 3 +- Program/test/filesystem_tests.h | 11 ----- Program/test/list_tests.c | 59 +++++++++++++++++++++++---- Program/test/list_tests.h | 10 ----- Program/test/main.c | 16 +------- Program/test/makefile | 2 + Program/test/packet_tests.c | 2 +- Program/test/packet_tests.h | 14 ------- Program/test/protocol_handler_tests.c | 3 ++ Program/test/protocol_handler_tests.h | 7 ---- Program/test/request_tests.c | 1 + Program/test/request_tests.h | 14 ------- Program/test/server_tests.c | 2 +- Program/test/server_tests.h | 6 --- Program/test/tasks_tests.c | 19 ++++++++- Program/test/unit_tests.h | 15 ++++++- 17 files changed, 95 insertions(+), 101 deletions(-) delete mode 100644 Program/test/filesystem_tests.h delete mode 100644 Program/test/list_tests.h delete mode 100644 Program/test/packet_tests.h delete mode 100644 Program/test/protocol_handler_tests.h delete mode 100644 Program/test/request_tests.h delete mode 100644 Program/test/server_tests.h diff --git a/Program/src/list.c b/Program/src/list.c index 8d40992..0084882 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -145,7 +145,7 @@ static void *removeNode(List *list, Node *node) { static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { - Node *cur = list->head->next; + Node *cur = list->head; int found_with_func = 0; int found_with_id = 0; while (cur->next != NULL) @@ -158,15 +158,7 @@ static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void if (found_with_func || found_with_id) { - Node *previous = cur->prev; - Node *next = cur->next; - - previous->next = next; - next->prev = previous; - - list->count--; - void *element = cur->element; - freeNode(cur); + void *element = removeNode(list, cur); return element; } cur = cur->next; diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index a12e4d0..0059e67 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -1,6 +1,5 @@ #include "filesystem_funcs.h" -#include "filesystem_tests.h" - +#include "unit_tests.h" static void nak_print(void *element, void *args){ diff --git a/Program/test/filesystem_tests.h b/Program/test/filesystem_tests.h deleted file mode 100644 index c9684f3..0000000 --- a/Program/test/filesystem_tests.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef FILESYSTEM_TESTS_H -#define FILESYSTEM_TESTS_H - - -#define TEMP_FILESIZE 1000 -int file_system_tests(); - - - - -#endif \ No newline at end of file diff --git a/Program/test/list_tests.c b/Program/test/list_tests.c index 36a6b14..8572d9d 100644 --- a/Program/test/list_tests.c +++ b/Program/test/list_tests.c @@ -2,7 +2,6 @@ #include "list.h" -#include "list_tests.h" #include "protocol_handler.h" #include "requests.h" @@ -12,16 +11,55 @@ #include "stdlib.h" #include "string.h" -void print_list(void *element, void *args) { +#include "unit_tests.h" + + +List *populate_request_list() { + List *list = linked_list(); + Request *r; + for (int i = 0; i < 5; i++) { + r = init_request(100); + r->dest_cfdp_id = i; + list->push(list, r, i); + } + return list; +} + + +void print_list(Node *node, void *element, void *args) { Request *r = (Request *) element; printf("source file name: %s\n", r->source_file_name); } -void free_all(void *element){ - ssp_cleanup_req((Request *)element); +void print_list_ids(Node *node, void *element, void *args) { + Request *r = (Request *) element; + ASSERT_EQUALS_INT("should equal ids", node->id, r->dest_cfdp_id); + } + +void remove_node_test(Node *node, void *element, void *args) { + Request *r = (Request *) element; + List *l = (List*) args; + + if (r->dest_cfdp_id == 2) { + void *element = l->removeNode(l, node); + ssp_cleanup_req(element); + } +} + +void test_remove_node() { + + List *l = populate_request_list(); + l->iterate(l, remove_node_test, l); + l->iterate(l, print_list_ids, l); + l->free(l, ssp_cleanup_req); +} + + + int list_tests() { + DECLARE_NEW_TEST("list.c"); List *list = linked_list(); Request *r = init_request(10000); @@ -34,7 +72,7 @@ int list_tests() { ASSERT_EQUALS_INT("should equal 1", 1, list->count); Request *r3 = (Request *) list->pop(list); - ASSERT_EQUALS_STR("should equal mybestfriend", "mybestfriend", r3->source_file_name, 12); + ASSERT_EQUALS_STR("list string should equal", "mybestfriend", r3->source_file_name, 12); ASSERT_EQUALS_INT("should equal 0", 0, list->count); list->push(list, r2, 1); @@ -42,13 +80,16 @@ int list_tests() { ASSERT_EQUALS_INT("should equal 2", 2, list->count); //test removals - Request *r4 = list->remove(list, 1, NULL, NULL); - ASSERT_EQUALS_INT("should equal 1", 1, list->count); - ASSERT_EQUALS_STR("should equal secondrequest", "secondrequest", r4->source_file_name, 12); + Request *r4 = list->remove(list, 1, NULL, NULL); + ASSERT_EQUALS_INT("request id should equal 1", 1, list->count); + ASSERT_EQUALS_STR("request source file_name should equal", "secondrequest", r4->source_file_name, 12); list->push(list, r4, 0); list->iterate(list, print_list, NULL); - list->free(list, free_all); + list->free(list, ssp_cleanup_req); + + test_remove_node(); + return 0; } \ No newline at end of file diff --git a/Program/test/list_tests.h b/Program/test/list_tests.h deleted file mode 100644 index 69fdaca..0000000 --- a/Program/test/list_tests.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef LIST_TESTS_H -#define LIST_TESTS_H - - -int list_tests(); - - - - -#endif \ No newline at end of file diff --git a/Program/test/main.c b/Program/test/main.c index 6f2c558..27d376f 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -8,19 +8,7 @@ #include #include #include "types.h" -#include "request_tests.h" -#include "packet_tests.h" - - -/* -#include "filesystem_tests.h" -#include "file_delivery_app.h" -#include "protocol_handler_tests.h" -#include "list_tests.h" -*/ -#include "server_tests.h" - - +#include "unit_tests.h" int main (int argc, char **argv) { @@ -30,7 +18,7 @@ int main (int argc, char **argv) { //error = request_tests(); //error = protocol_handler_test(); //error = packet_tests(); - //error = list_tests(); + error = list_tests(); //error = file_system_tests(); error = tasks_tests(); diff --git a/Program/test/makefile b/Program/test/makefile index 70d6601..d56c5ee 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -31,6 +31,8 @@ CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c CFILES += $(PROJDIR)/test/request_tests.c CFILES += $(PROJDIR)/test/tasks_tests.c +CFILES += $(PROJDIR)/test/list_tests.c + #CFILES += $(PROJDIR)/test/filesystem_tests.c #CFILES += $(PROJDIR)/test/protocol_handler_tests.c #CFILES += $(PROJDIR)/test/list_tests.c diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 0edd2d9..e929f70 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -10,7 +10,7 @@ #include "mib.h" #include "file_delivery_app.h" #include "packet.h" -#include "packet_tests.h" +#include "unit_tests.h" #define PACKET_TEST_SIZE 2000 diff --git a/Program/test/packet_tests.h b/Program/test/packet_tests.h deleted file mode 100644 index f07e95b..0000000 --- a/Program/test/packet_tests.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef PACKET_TEST_H -#define PACKET_TEST_H - - -#include "types.h" - -int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); -int packet_tests(); - - - - -#endif \ No newline at end of file diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index c0f5337..00ddbdc 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -5,6 +5,9 @@ #include "mib.h" #include "test.h" #include "file_delivery_app.h" +#include "unit_tests.h" + + static char *build_mock_packet(FTP *app, uint32_t id) { char *packet = calloc(sizeof(char*), 2000); diff --git a/Program/test/protocol_handler_tests.h b/Program/test/protocol_handler_tests.h deleted file mode 100644 index 8a3a9a5..0000000 --- a/Program/test/protocol_handler_tests.h +++ /dev/null @@ -1,7 +0,0 @@ - -#ifndef PROTOCL_HANDLER_TEST_H -#define PROTOCL_HANDLER_TEST_H - - - int protocol_handler_test(); -#endif diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 302f362..c6fd052 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -6,6 +6,7 @@ #include "filesystem_funcs.h" #include "string.h" #include "file_delivery_app.h" +#include "unit_tests.h" static void list_print_id(void *element, void *args) { Request *req = (Request *) element; diff --git a/Program/test/request_tests.h b/Program/test/request_tests.h deleted file mode 100644 index b3e05f5..0000000 --- a/Program/test/request_tests.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef PACKET_TEST_H -#define PACKET_TEST_H - - - - - -int request_tests(); - - - - -#endif \ No newline at end of file diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index c7d0470..6c1463c 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -1,5 +1,5 @@ -#include "server_tests.h" +#include "unit_tests.h" #include #include "server.h" #include "port.h" diff --git a/Program/test/server_tests.h b/Program/test/server_tests.h deleted file mode 100644 index 64818b8..0000000 --- a/Program/test/server_tests.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef SERVER_TESTS_H -#define SERVER_TESTS_H - -int server_tests(int client); - -#endif \ No newline at end of file diff --git a/Program/test/tasks_tests.c b/Program/test/tasks_tests.c index 2fbb04f..5546924 100644 --- a/Program/test/tasks_tests.c +++ b/Program/test/tasks_tests.c @@ -1,10 +1,27 @@ #include "unit_tests.h" #include "test.h" +#include "requests.h" +#include "list.h" +void check_request_callback(Node *node, void *request, void *args){ + Request *r = (Request *) request; + printf("id's remaining in list: %d\n", r->dest_cfdp_id); + +} void test_remove_request() { - //remove_request_check(void *request, void *args); + + + List *l = populate_request_list(); + Request *request = (Request *) l->find(l, 3, NULL, NULL); + request->procedure = clean_up; + + //remove_request_check(request, l); + + l->iterate(l, check_request_callback, NULL); + l->free(l, ssp_cleanup_req); + } diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index ddaf35a..9b5e52d 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -1,7 +1,20 @@ -#ifdef SSP_UNIT_TEST_H +#ifndef SSP_UNIT_TEST_H #define SSP_UNIT_TEST_H + #include "types.h" + #include "test.h" + + List *populate_request_list(); + int tasks_tests(); + int request_tests(); + int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); + int packet_tests(); + + + #define TEMP_FILESIZE 1000 + int file_system_tests(); + //int server_tests(int client ); #endif \ No newline at end of file From b507dca016541a23522b5d9eaeeadcef9e672ebf Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 Nov 2019 12:21:34 -0700 Subject: [PATCH 135/400] Fix segfault with list->remove, now works well --- Program/include/protocol_handler.h | 1 - Program/include/tasks.h | 3 ++ Program/src/main.c | 22 +++++++-- Program/src/protocol_handler.c | 8 +++- Program/src/tasks.c | 74 +++++++++++++++++++++++------- 5 files changed, 84 insertions(+), 24 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 7d8cbbd..c99aa64 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -15,7 +15,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); - uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); void process_messages(Request *req, FTP *app); diff --git a/Program/include/tasks.h b/Program/include/tasks.h index 5f8f0c0..e5e99d7 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -17,6 +17,9 @@ void *ssp_csp_connectionless_client_task(void *params); void *ssp_csp_connectionless_server_task(void *params); void *ssp_csp_connection_client_task(void *params); void *ssp_csp_connection_server_task(void *params); + void ssp_join_clients(List *clients); +void remove_request_check(Node *node, void *request, void *args); + #endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index a2eecb7..6cdd891 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -46,14 +46,26 @@ int main(int argc, char** argv) { if (conf->client_cfdp_id != 0){ //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - Request *req = put_request(conf->client_cfdp_id, "pic.jpeg", "anotherpicyo.jpg", ACKNOWLEDGED_MODE, app); - - if (req == NULL) - return -1; + start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy.jpg", ACKNOWLEDGED_MODE, app)); + start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy2.jpg", ACKNOWLEDGED_MODE, app)); + start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy3.jpg", ACKNOWLEDGED_MODE, app)); + start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); + + Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); + start_request(req); - //add_proxy_message_to_request(2, 1, "pic.jpeg", "dest.jpg", req); + req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); start_request(req); + + //if (req == NULL) + // return -1; + + //add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); + //start_request(req); + } ssp_thread_join(app->server_handle); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 3a7f464..35aa403 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -55,7 +55,6 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { int process_file_request_metadata(Request *req) { char temp[75]; - req->local_entity->Metadata_recv_indication = 1; if (req->file == NULL) req->file = create_file(req->destination_file_name, 1); @@ -474,6 +473,7 @@ void on_server_time_out(Response res, Request *req) { build_nak_directive(req->buff, start, EOF_PDU); ssp_sendto(res); } + //received EOF, send back 3 eof ack packets if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); @@ -482,6 +482,9 @@ void on_server_time_out(Response res, Request *req) { req->resent_eof++; } + if (req->file == NULL) + return; + //send missing NAKS if (req->file->missing_offsets->count > 0) { ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); @@ -546,6 +549,8 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ packet_index += fill_request_pdu_metadata(&packet[packet_index], req); get_messages_from_packet(packet, packet_index, data_len, req); process_messages(req, app); + + req->local_entity->Metadata_recv_indication = 1; if (req->file_size != 0) process_file_request_metadata(req); @@ -561,7 +566,6 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); process_pdu_eof(&packet[packet_index], req, res); - break; case ACK_PDU: diff --git a/Program/src/tasks.c b/Program/src/tasks.c index ea3575b..4c116a2 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -76,13 +76,13 @@ static int remove_request(void *request, void *args) { return 0; } -static void remove_request_check(void *request, void *args) { +void remove_request_check(Node *node, void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; if (req->procedure == clean_up) { ssp_printf("removing request\n"); - Request *remove_this = req_list->remove(req_list, 0, remove_request, req); + Request *remove_this = req_list->removeNode(req_list, node); ssp_cleanup_req(remove_this); } } @@ -100,7 +100,7 @@ static void user_request_check(Node *node, void *request, void *args) { memset(params->res.msg, 0, params->client->packet_len); user_request_handler(params->res, req, params->client); - remove_request_check(request, params->client->request_list); + remove_request_check(node, request, params->client->request_list); } static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, void *other) { @@ -133,8 +133,7 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi static void timeout_check_callback(Node *node, void *request, void *args) { Request *req = (Request *) request; on_server_time_out(req->res, req); - remove_request_check(request, args); - + remove_request_check(node, request, args); } @@ -150,10 +149,6 @@ static void client_check_callback(Node *node, void *client, void *args) { } } -static void test_s () { - -} - //this function is a callback when using my posix ports static int on_time_out_callback(void *other) { @@ -245,7 +240,14 @@ void *ssp_connectionless_server_task(void *params) { char port[10]; snprintf(port, 10, "%d",app->remote_entity->UT_port); - connectionless_server(port, app->packet_len, on_recv_server_callback, on_time_out_callback, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, app); + connectionless_server(port, + app->packet_len, + on_recv_server_callback, + on_time_out_callback, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, + app); return NULL; } @@ -264,7 +266,17 @@ void *ssp_connectionless_client_task(void* params){ //convert uint id to char * inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); - connectionless_client(host_name, port, client->packet_len, client, client, client, client, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, on_exit_client_callback); + connectionless_client(host_name, + port, + client->packet_len, + client, + client, + client, + client, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback); return NULL; } @@ -278,7 +290,16 @@ void *ssp_connection_server_task(void *params) { snprintf(port, 10, "%u",app->remote_entity->UT_port); //1024 is the connection max limit - connection_server(port, app->packet_len, 10, on_recv_server_callback, on_time_out_callback, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, app); + connection_server(port, + app->packet_len, + 10, + on_recv_server_callback, + on_time_out_callback, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, + app); + return NULL; } @@ -295,7 +316,17 @@ void *ssp_connection_client_task(void *params) { //convert uint id to char * inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); - connection_client(host_name, port, client->packet_len, client, client, client, client, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, on_exit_client_callback); + connection_client(host_name, + port, + client->packet_len, + client, + client, + client, + client, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback); return NULL; } @@ -303,6 +334,7 @@ void *ssp_connection_client_task(void *params) { void *ssp_csp_connectionless_server_task(void *params) { printf("starting csp connectionless server\n"); FTP *app = (FTP *) params; + csp_connectionless_server( app->remote_entity->UT_port, on_recv_server_callback, @@ -318,9 +350,16 @@ void *ssp_csp_connectionless_server_task(void *params) { void *ssp_csp_connectionless_client_task(void *params) { printf("starting csp connectionless client\n"); Client *client = (Client *) params; + csp_connectionless_client(client->remote_entity->UT_address, - client->remote_entity->UT_port, - client->app->remote_entity->UT_port, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, on_exit_client_callback, client); + client->remote_entity->UT_port, + client->app->remote_entity->UT_port, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback, + client); + return NULL; } @@ -328,6 +367,7 @@ void *ssp_csp_connectionless_client_task(void *params) { void *ssp_csp_connection_server_task(void *params) { printf("starting csp connection server\n"); FTP *app = (FTP *) params; + csp_connection_server(app->remote_entity->UT_port, on_recv_server_callback, on_time_out_callback, @@ -343,12 +383,14 @@ void *ssp_csp_connection_client_task(void *params) { printf("starting csp connection client\n"); Client *client = (Client *) params; - csp_connection_client(client->remote_entity->UT_address, client->remote_entity->UT_port, + csp_connection_client(client->remote_entity->UT_address, + client->remote_entity->UT_port, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, on_exit_client_callback, params); + return NULL; } /*------------------------------------------------------------------------------ From d9d507df7880683022e296fb0ff9bbeddf3d129a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 Nov 2019 14:27:29 -0700 Subject: [PATCH 136/400] proxy last commit, will move on to a different branch now --- Program/include/port.h | 2 ++ Program/src/main.c | 11 +++++++---- Program/src/port.c | 26 ++++++++++++++++++++++++++ Program/src/protocol_handler.c | 31 ++++++++++++++++--------------- Program/src/tasks.c | 14 +++++--------- 5 files changed, 56 insertions(+), 28 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 198054b..577f24b 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -67,5 +67,7 @@ void ssp_fd_clr(int sfd, void *socket_set); int ssp_rename(const char *old, const char *new); void reset_request(Request *req); +uint32_t ssp_time_count(); + #endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index 6cdd891..27dd121 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -46,18 +46,21 @@ int main(int argc, char** argv) { if (conf->client_cfdp_id != 0){ //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + + /* start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy2.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy3.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); + */ Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); start_request(req); - - req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); - start_request(req); + + //req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + //add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); + //start_request(req); //if (req == NULL) diff --git a/Program/src/port.c b/Program/src/port.c index f39e1f3..6df7ed0 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -25,6 +25,7 @@ #include #include #include + #include #endif @@ -63,6 +64,7 @@ + /*------------------------------------------------------------------------------ File system port functions, these are used to interchange different File systems @@ -279,6 +281,30 @@ void ssp_printf( char *stuff, ...) { } +uint32_t ssp_time_count() { + + #ifdef POSIX_PORT + clock_t c = clock(); + c = c / CLOCKS_PER_SEC; + return c; + #endif + + #ifdef FREE_RTOS_PORT + //some kind of ticks + #endif +} + +//returns a number to start counting from, modulo is the time in seconds that is the +/* +uint32_t start_timer(uint32_t modulo) { + return ssp_time_count() % modulo; +} + +//timeout_max is how long we want to check, time is our start, returned from start_timer +uint32_t check_timeout(uint32_t time, uint32_t timeout_max, uint32_t modulo) { + return +} +*/ /*------------------------------------------------------------------------------ Threading and task functions diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 35aa403..db13a6f 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -247,6 +247,21 @@ void process_messages(Request *req, FTP *app) { } +static int reset_timeout(Request *req) { + + + if (req->timeout++ >= TIMEOUT_BEFORE_CANCEL_REQUEST) { + ssp_printf("time to live ended, closing up request transaction: %d\n", req->transaction_sequence_number); + if (req->procedure != none) + ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); + else { + ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); + } + req->procedure = clean_up; + return 1; + } + return 0; +} /*------------------------------------------------------------------------------ @@ -357,7 +372,7 @@ void user_request_handler(Response res, Request *req, Client* client) { return; uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - + check_req_status(req, client); switch (req->procedure) @@ -412,21 +427,7 @@ void user_request_handler(Response res, Request *req, Client* client) { ------------------------------------------------------------------------------*/ -static int reset_timeout(Request *req) { - - if (req->timeout++ >= TIMEOUT_BEFORE_CANCEL_REQUEST) { - ssp_printf("time to live ended, closing up request transaction: %d\n", req->transaction_sequence_number); - if (req->procedure != none) - ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); - else { - ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); - } - req->procedure = clean_up; - return 1; - } - return 0; -} /* static void print_offsets(void *element, void *args) { diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 4c116a2..b021d91 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -68,14 +68,6 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u } -static int remove_request(void *request, void *args) { - Request *req = (Request *) request; - Request *req2 = (Request *) args; - if (req->dest_cfdp_id == req2->dest_cfdp_id && req->transaction_sequence_number == req2->transaction_sequence_number) - return 1; - return 0; -} - void remove_request_check(Node *node, void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; @@ -124,7 +116,10 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi }; client->request_list->iterate(client->request_list, user_request_check, ¶ms); - + if (client->request_list->count == 0) { + client->close = true; + } + return 0; } @@ -147,6 +142,7 @@ static void client_check_callback(Node *node, void *client, void *args) { ssp_thread_join(c->client_handle); ssp_free(remove_this); } + } //this function is a callback when using my posix ports From 306d40e8be626233549c70cfe00d9d54eff9ffb7 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 11 Nov 2019 15:33:36 -0700 Subject: [PATCH 137/400] timeout function works nice in linux --- Program/src/port.c | 17 ++++++----------- Program/src/utils.c | 7 +++++++ Program/test/main.c | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 6df7ed0..51a3176 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -65,6 +65,7 @@ + /*------------------------------------------------------------------------------ File system port functions, these are used to interchange different File systems @@ -281,12 +282,15 @@ void ssp_printf( char *stuff, ...) { } -uint32_t ssp_time_count() { + + +int ssp_time_count() { #ifdef POSIX_PORT clock_t c = clock(); c = c / CLOCKS_PER_SEC; return c; + #endif #ifdef FREE_RTOS_PORT @@ -294,17 +298,8 @@ uint32_t ssp_time_count() { #endif } -//returns a number to start counting from, modulo is the time in seconds that is the -/* -uint32_t start_timer(uint32_t modulo) { - return ssp_time_count() % modulo; -} -//timeout_max is how long we want to check, time is our start, returned from start_timer -uint32_t check_timeout(uint32_t time, uint32_t timeout_max, uint32_t modulo) { - return -} -*/ + /*------------------------------------------------------------------------------ Threading and task functions diff --git a/Program/src/utils.c b/Program/src/utils.c index 408f922..19a9e19 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -112,3 +112,10 @@ void ssp_print_hex(char *stuff, int size){ } ssp_printf("\n"); } + + +int is_negative(int number) { + int negative_mask = 0x80000000; + int is_negative = number & negative_mask; + return is_negative; +} \ No newline at end of file diff --git a/Program/test/main.c b/Program/test/main.c index 27d376f..a691ea9 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -10,6 +10,26 @@ #include "types.h" #include "unit_tests.h" + +//timeout_max is how long we want to check, time is our start, returned from start_timer +int check_timeout(int *prevtime, uint32_t timeout) { + + int prev = *prevtime; + int current_time = ssp_time_count(); + int time_out = prev + timeout; + + if (current_time >= time_out) { + *prevtime = current_time; + printf("current time %d timeout target %d\n", current_time, time_out); + return 1; + } + else if (current_time < prev) { + *prevtime = current_time; + printf("wrap arround\n"); + } + return 0; +} + int main (int argc, char **argv) { @@ -18,10 +38,21 @@ int main (int argc, char **argv) { //error = request_tests(); //error = protocol_handler_test(); //error = packet_tests(); - error = list_tests(); + //error = list_tests(); //error = file_system_tests(); - error = tasks_tests(); + //error = tasks_tests(); + uint32_t seconds = 0; + int prevtime = 0; + + bool is_timeout = false; + while (1) { + is_timeout = check_timeout(&prevtime, 100); + + if (is_timeout) + printf("timeout! %d\n", is_timeout); + + } /* if (strcmp(argv[1], "1") == 0) error = server_tests(0); From 9921ba4ab8fe270cc31bc5150539c09e1c555ad6 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 13 Nov 2019 10:17:07 -0700 Subject: [PATCH 138/400] Add better ttl --- Program/include/port.h | 2 +- Program/include/protocol_handler.h | 2 +- Program/include/types.h | 4 +-- Program/include/utils.h | 5 ++++ Program/src/protocol_handler.c | 28 +++----------------- Program/src/tasks.c | 42 ++++++++++++++++++++++++++---- Program/src/utils.c | 24 ++++++++++++++++- Program/test/main.c | 24 ++--------------- 8 files changed, 75 insertions(+), 56 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 577f24b..4d05e5a 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -67,7 +67,7 @@ void ssp_fd_clr(int sfd, void *socket_set); int ssp_rename(const char *old, const char *new); void reset_request(Request *req); -uint32_t ssp_time_count(); +int ssp_time_count(); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index c99aa64..329273a 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -5,7 +5,7 @@ #define RESEND_EOF_TIMES 3 #define RESEND_FINISHED_TIMES 3 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 100 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 10 void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); void user_request_handler(Response res, Request *req, Client *client); diff --git a/Program/include/types.h b/Program/include/types.h index c2c3d0f..97efbda 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -577,8 +577,8 @@ typedef struct request { uint32_t packet_data_len; - //timeout - uint32_t timeout; + //previous timeout time in seconds + int timeout; uint8_t segmentation_control; uint8_t fault_handler_overides; diff --git a/Program/include/utils.h b/Program/include/utils.h index 54a1db7..8e924dd 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -47,5 +47,10 @@ Config *configuration(int argc, char **argv); #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) void ssp_print_hex(char *stuff, int size); +int is_negative(int number); + +//check if timeout number of seconds has past since prevtime +int check_timeout(int *prevtime, uint32_t timeout); +void reset_timeout(int *prevtime); #endif //UTILS_H diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index db13a6f..968703a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -247,21 +247,6 @@ void process_messages(Request *req, FTP *app) { } -static int reset_timeout(Request *req) { - - - if (req->timeout++ >= TIMEOUT_BEFORE_CANCEL_REQUEST) { - ssp_printf("time to live ended, closing up request transaction: %d\n", req->transaction_sequence_number); - if (req->procedure != none) - ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); - else { - ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); - } - req->procedure = clean_up; - return 1; - } - return 0; -} /*------------------------------------------------------------------------------ @@ -355,7 +340,7 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ break; } } -static void check_req_status(Request *req, Client *client) { +static void check_req_status(Request *req) { if (req->resent_finished >= RESEND_FINISHED_TIMES){ req->procedure = none; @@ -373,7 +358,7 @@ void user_request_handler(Response res, Request *req, Client* client) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); - check_req_status(req, client); + check_req_status(req); switch (req->procedure) { @@ -416,6 +401,8 @@ void user_request_handler(Response res, Request *req, Client* client) { req->resent_finished++; break; + case clean_up: + case none: default: break; } @@ -443,9 +430,6 @@ void on_server_time_out(Response res, Request *req) { if (req->paused) return; - if (reset_timeout(req)) - return; - if (req->procedure == none) return; @@ -517,8 +501,6 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_header *header = (Pdu_header *) packet; uint16_t data_len = get_data_length(packet); - //set timeout to 0, because received data - req->timeout = 0; //process file data if (header->PDU_type == 1) { @@ -580,7 +562,5 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ default: break; } - - } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index b021d91..8af318b 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -10,12 +10,30 @@ #include "filesystem_funcs.h" #include #include "types.h" +#include "utils.h" #include /*------------------------------------------------------------------------------ Callbacks for the tasks bellow ------------------------------------------------------------------------------*/ + +//sets request procedure as clean_up if ttl passed +static void timeout(Request *req) { + + bool is_timeout = check_timeout(&req->timeout, TIMEOUT_BEFORE_CANCEL_REQUEST); + if (is_timeout) { + if (req->procedure != none) + ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); + else { + ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); + } + req->procedure = clean_up; + } +} + + + static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { FTP *app = (FTP *) other; @@ -28,12 +46,15 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, Request **request_container = &app->current_request; int packet_index = process_pdu_header(packet, 1, res, request_container, app->request_list, app); - app->current_request = (*request_container); + Request *current_request = (*request_container); + app->current_request = current_request; if (packet_index < 0) return -1; - parse_packet_server(packet, packet_index, app->current_request->res, (*request_container), app); + parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); + + reset_timeout(¤t_request->timeout); memset(packet, 0, res.packet_len); return 0; @@ -59,11 +80,15 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u ssp_printf("error parsing header\n"); return -1; } - - res.msg = (*request_container)->buff; - parse_packet_client(packet, packet_index, res, (*request_container), client); + Request *current_request = (*request_container); + res.msg = current_request->buff; + + parse_packet_client(packet, packet_index, res, current_request, client); + + reset_timeout(¤t_request->timeout); memset(packet, 0, res.packet_len); + return 0; } @@ -92,6 +117,9 @@ static void user_request_check(Node *node, void *request, void *args) { memset(params->res.msg, 0, params->client->packet_len); user_request_handler(params->res, req, params->client); + + timeout(req); + remove_request_check(node, request, params->client->request_list); } @@ -115,6 +143,7 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi client }; + client->request_list->iterate(client->request_list, user_request_check, ¶ms); if (client->request_list->count == 0) { client->close = true; @@ -128,6 +157,9 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi static void timeout_check_callback(Node *node, void *request, void *args) { Request *req = (Request *) request; on_server_time_out(req->res, req); + + timeout(req); + remove_request_check(node, request, args); } diff --git a/Program/src/utils.c b/Program/src/utils.c index 19a9e19..4145d29 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -118,4 +118,26 @@ int is_negative(int number) { int negative_mask = 0x80000000; int is_negative = number & negative_mask; return is_negative; -} \ No newline at end of file +} + + +void reset_timeout(int *prevtime) { + *prevtime = ssp_time_count(); +} + +int check_timeout(int *prevtime, uint32_t timeout) { + + int prev = *prevtime; + int current_time = ssp_time_count(); + int time_out = prev + timeout; + + if (current_time >= time_out) { + *prevtime = current_time; + return 1; + } + //wrap around the overflow condition + else if (current_time < prev) { + *prevtime = current_time; + } + return 0; +} diff --git a/Program/test/main.c b/Program/test/main.c index a691ea9..e0ad4eb 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -11,24 +11,6 @@ #include "unit_tests.h" -//timeout_max is how long we want to check, time is our start, returned from start_timer -int check_timeout(int *prevtime, uint32_t timeout) { - - int prev = *prevtime; - int current_time = ssp_time_count(); - int time_out = prev + timeout; - - if (current_time >= time_out) { - *prevtime = current_time; - printf("current time %d timeout target %d\n", current_time, time_out); - return 1; - } - else if (current_time < prev) { - *prevtime = current_time; - printf("wrap arround\n"); - } - return 0; -} int main (int argc, char **argv) { @@ -41,13 +23,11 @@ int main (int argc, char **argv) { //error = list_tests(); //error = file_system_tests(); //error = tasks_tests(); - uint32_t seconds = 0; + uint32_t seconds = 3; int prevtime = 0; - bool is_timeout = false; - while (1) { - is_timeout = check_timeout(&prevtime, 100); + is_timeout = check_timeout(&prevtime, seconds); if (is_timeout) printf("timeout! %d\n", is_timeout); From 2abc4943a60b18ac7712aa3651009728ca1a14e4 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 21 Nov 2019 10:09:59 -0700 Subject: [PATCH 139/400] change build_eof_packet to take in File instead of Request --- Program/src/packet.c | 6 +++--- Program/src/protocol_handler.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 1a45737..544e7a5 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -197,7 +197,7 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len return 0; } -void build_eof_packet(char *packet, uint32_t start, Request *req) { +void build_eof_packet(char *packet, uint32_t start, File *file) { Pdu_header *header = (Pdu_header *) packet; //set header to file directive 0 is directive, 1 is data @@ -218,9 +218,9 @@ void build_eof_packet(char *packet, uint32_t start, Request *req) { packet_index++; //4 bytes - eof_packet->file_size = ntohl(req->file->total_size); + eof_packet->file_size = ntohl(file->total_size); packet_index += 4; - eof_packet->checksum = req->file->partial_checksum; + eof_packet->checksum = file->partial_checksum; packet_index += 4; //TODO addTLV fault_location diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 968703a..7a64119 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -45,7 +45,7 @@ static void process_pdu_eof(char *packet, Request *req, Response res) { req->file = create_temp_file(req->source_file_name); } - + req->local_entity->EOF_recv_indication = 1; req->file->eof_checksum = eof_packet->checksum; req->file->total_size = ntohl(eof_packet->file_size); @@ -365,7 +365,7 @@ void user_request_handler(Response res, Request *req, Client* client) { case sending_eof: ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); req->procedure = none; - build_eof_packet(req->buff, start, req); + build_eof_packet(req->buff, start, req->file); req->local_entity->EOF_sent_indication = 1; ssp_sendto(res); break; @@ -455,6 +455,7 @@ void on_server_time_out(Response res, Request *req) { //send missing eofs if (!req->local_entity->EOF_recv_indication) { + ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); build_nak_directive(req->buff, start, EOF_PDU); ssp_sendto(res); } From cf1c9ceb58712bdaf111307d8c424435af6d625f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 25 Nov 2019 10:28:57 -0700 Subject: [PATCH 140/400] Add protocol tests --- Program/test/main.c | 14 ++--- Program/test/protocol_handler_tests.c | 74 ++++++++++++++++++++------- Program/test/unit_tests.h | 1 + 3 files changed, 59 insertions(+), 30 deletions(-) diff --git a/Program/test/main.c b/Program/test/main.c index e0ad4eb..93ace89 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -18,21 +18,13 @@ int main (int argc, char **argv) { int error = 0; //error = request_tests(); - //error = protocol_handler_test(); + error = protocol_handler_test(); + //error = packet_tests(); //error = list_tests(); //error = file_system_tests(); //error = tasks_tests(); - uint32_t seconds = 3; - int prevtime = 0; - bool is_timeout = false; - while (1) { - is_timeout = check_timeout(&prevtime, seconds); - - if (is_timeout) - printf("timeout! %d\n", is_timeout); - - } + /* if (strcmp(argv[1], "1") == 0) error = server_tests(0); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 00ddbdc..af48110 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -11,41 +11,77 @@ static char *build_mock_packet(FTP *app, uint32_t id) { char *packet = calloc(sizeof(char*), 2000); - Pdu_header *pdu_header = get_header_from_mib(app->mib, 1, id); + Pdu_header *pdu_header = get_header_from_mib(app->mib, id, app->my_cfdp_id); build_pdu_header(packet, 1, 0, pdu_header); ssp_cleanup_pdu_header(pdu_header); return packet; } +static Response mock_response() { + Response res; + int addr = 16; + res.addr = &addr; + res.sfd = 1; + res.packet_len = 2000; + res.size_of_addr = 16; + return res; + +} +static int test_wrong_id(FTP *app) { + + Response res = mock_response(); + char *packet = build_mock_packet(app, 2); + Request **req_container = &app->current_request; + process_pdu_header(packet, true, res, req_container, app->request_list, app); + ASSERT_EQUALS_INT("Test wrong id, Request should be NULL", (*req_container), NULL); + free(packet); +} + +static int test_correct_id(FTP *app) { + + Response res = mock_response(); + char *packet = build_mock_packet(app, 1); + Request **req_container = &app->current_request; + process_pdu_header(packet, true, res, req_container, app->request_list, app); + ASSERT_NOT_EQUALS_INT("Test wrong id, Request should not be NULL", (*req_container), NULL); + ASSERT_EQUALS_INT("Length of request should be 1", app->request_list->count, 1); + + free(packet); +} + static int test_process_pdu_header() { FTP *app = init_ftp(1); + + + test_wrong_id(app); + test_correct_id(app); + /* Request **req_container = &app->current_request; - Response res; - int addr = 16; - res.addr = &addr; - res.sfd = 1; - res.packet_len = app->packet_len; - res.size_of_addr = 16; + Response res = mock_response(); //test 1 - char *packet = build_mock_packet(app, 2); - process_pdu_header(packet, 1, res, req_container, app->request_list, app); - ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); - ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 2); + + process_pdu_header(packet, true, res, req_container, app->request_list, app); + if (*req_container != NULL) { + ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); + ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 2); + } //test 2 - char *packet2 = build_mock_packet(app, 3); - process_pdu_header(packet2, 1, res, req_container, app->request_list, app); - ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); - ASSERT_NOT_EQUALS_INT("souce id should not equal", (*req_container)->dest_cfdp_id, 2); - ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 3); + //char *packet2 = build_mock_packet(app, 3); + //process_pdu_header(packet2, 1, res, req_container, app->request_list, app); + //ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); + //ASSERT_NOT_EQUALS_INT("souce id should not equal", (*req_container)->dest_cfdp_id, 2); + //ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 3); - free(packet); - free(packet2); - ssp_cleanup_app(app); + */ + //free(packet2); + + app->close = true; + ssp_thread_join(app->server_handle); } diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index 9b5e52d..ef9d891 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -10,6 +10,7 @@ int request_tests(); int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); int packet_tests(); + int protocol_handler_test(); #define TEMP_FILESIZE 1000 From 5526bda437e3573d36867df6e7eb1bdfc2a022a6 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 27 Nov 2019 10:18:10 -0700 Subject: [PATCH 141/400] update protocl handler tests --- Program/include/packet.h | 2 +- Program/include/protocol_handler.h | 1 + Program/test/main.c | 4 +- Program/test/makefile | 10 ++-- Program/test/packet_tests.c | 6 +++ Program/test/protocol_handler_tests.c | 60 +++++++++++------------ Program/test/request_tests.c | 10 ++-- Program/test/tasks_tests.c | 3 +- Program/test/test.c | 68 +++++++++++++++++++++++---- Program/test/test.h | 12 +++-- Program/test/unit_tests.h | 10 ++-- 11 files changed, 122 insertions(+), 64 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index e0448ff..88196df 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -21,7 +21,7 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); -void build_eof_packet(char *packet, uint32_t start, Request *req); +void build_eof_packet(char *packet, uint32_t start, File *file); void fill_nak_array_callback(Node *node, void *element, void *args); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); uint8_t build_ack(char*packet, uint32_t start, uint8_t type); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 329273a..05316ff 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -13,6 +13,7 @@ void parse_packet_client(char* buff, uint32_t packet_index, Response res, Reques void on_server_time_out(Response res, Request *current_request); int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); +void process_pdu_eof(char *packet, Request *req, Response res); uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); diff --git a/Program/test/main.c b/Program/test/main.c index 93ace89..44353d1 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -12,15 +12,15 @@ -int main (int argc, char **argv) { +int main () { int error = 0; //error = request_tests(); + //error = packet_tests(); error = protocol_handler_test(); - //error = packet_tests(); //error = list_tests(); //error = file_system_tests(); //error = tasks_tests(); diff --git a/Program/test/makefile b/Program/test/makefile index d56c5ee..d703d84 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -27,14 +27,14 @@ CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -CFILES += $(PROJDIR)/test/packet_tests.c +#CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c -CFILES += $(PROJDIR)/test/request_tests.c -CFILES += $(PROJDIR)/test/tasks_tests.c -CFILES += $(PROJDIR)/test/list_tests.c +#CFILES += $(PROJDIR)/test/request_tests.c +#CFILES += $(PROJDIR)/test/tasks_tests.c +#CFILES += $(PROJDIR)/test/list_tests.c #CFILES += $(PROJDIR)/test/filesystem_tests.c -#CFILES += $(PROJDIR)/test/protocol_handler_tests.c +CFILES += $(PROJDIR)/test/protocol_handler_tests.c #CFILES += $(PROJDIR)/test/list_tests.c #CFILES += $(PROJDIR)/test/server_tests.c diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index e929f70..273c5bf 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -15,6 +15,12 @@ #define PACKET_TEST_SIZE 2000 +static int test_build_eof_packet() { + + + +} + static int test_respond_to_naks(char *packet, uint32_t packet_index) { Request *req = init_request(5000); ssp_cleanup_req(req); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index af48110..045e6d9 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -6,7 +6,7 @@ #include "test.h" #include "file_delivery_app.h" #include "unit_tests.h" - +#include "port.h" static char *build_mock_packet(FTP *app, uint32_t id) { @@ -25,68 +25,64 @@ static Response mock_response() { res.packet_len = 2000; res.size_of_addr = 16; return res; +} +static int test_process_pdu_eof() { +//char *packet, Request *req, Response res + + + //process_pdu_eof(packet, Request *req, Response res); + return 0; } -static int test_wrong_id(FTP *app) { + + +static int test_wrong_id(FTP *app) { + int error = 0; Response res = mock_response(); char *packet = build_mock_packet(app, 2); Request **req_container = &app->current_request; process_pdu_header(packet, true, res, req_container, app->request_list, app); - ASSERT_EQUALS_INT("Test wrong id, Request should be NULL", (*req_container), NULL); + Request *req = (*req_container); + error = ASSERT_NULL("Test wrong id, Request should be NULL", req); free(packet); + return error; } static int test_correct_id(FTP *app) { - + int error = 0; Response res = mock_response(); char *packet = build_mock_packet(app, 1); Request **req_container = &app->current_request; process_pdu_header(packet, true, res, req_container, app->request_list, app); - ASSERT_NOT_EQUALS_INT("Test wrong id, Request should not be NULL", (*req_container), NULL); - ASSERT_EQUALS_INT("Length of request should be 1", app->request_list->count, 1); + Request *req = (*req_container); + error = ASSERT_NOT_NULL("Test wrong id, Request should not be NULL", req); + error = ASSERT_EQUALS_INT("Length of request should be 1", app->request_list->count, 1); + error = ASSERT_EQUALS_INT("request transaction number should equal", req->transaction_sequence_number, 1); + error = ASSERT_NOT_EQUALS_INT("souce id should equal 2", req->dest_cfdp_id, 2); free(packet); + return error; + } static int test_process_pdu_header() { - + int error = 0; FTP *app = init_ftp(1); - - - test_wrong_id(app); - test_correct_id(app); - /* - Request **req_container = &app->current_request; - - Response res = mock_response(); - //test 1 - - process_pdu_header(packet, true, res, req_container, app->request_list, app); + error = test_wrong_id(app); + error = test_correct_id(app); - if (*req_container != NULL) { - ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); - ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 2); - } - //test 2 - //char *packet2 = build_mock_packet(app, 3); - //process_pdu_header(packet2, 1, res, req_container, app->request_list, app); - //ASSERT_EQUALS_INT("request transaction number should equal", (*req_container)->transaction_sequence_number, 1); - //ASSERT_NOT_EQUALS_INT("souce id should not equal", (*req_container)->dest_cfdp_id, 2); - //ASSERT_EQUALS_INT("souce id should equal", (*req_container)->dest_cfdp_id, 3); - - */ - //free(packet2); - app->close = true; ssp_thread_join(app->server_handle); + return error; } int protocol_handler_test() { int error = 0; error = test_process_pdu_header(); + error = test_process_pdu_eof(); return error; } \ No newline at end of file diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index c6fd052..bd40a76 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -163,13 +163,11 @@ int request_user_input_tests() { FTP *app = init_ftp(1); put_request(2, "", "", 0, app); - - - - - - + put_request(2, NULL, NULL, 0, app); + + + app->close = true; ssp_thread_join(app->server_handle); } diff --git a/Program/test/tasks_tests.c b/Program/test/tasks_tests.c index 5546924..edbd4c2 100644 --- a/Program/test/tasks_tests.c +++ b/Program/test/tasks_tests.c @@ -16,8 +16,9 @@ void test_remove_request() { List *l = populate_request_list(); Request *request = (Request *) l->find(l, 3, NULL, NULL); request->procedure = clean_up; + //run a task here, or a removal function + - //remove_request_check(request, l); l->iterate(l, check_request_callback, NULL); l->free(l, ssp_cleanup_req); diff --git a/Program/test/test.c b/Program/test/test.c index 0f7652b..3b3338b 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -1,6 +1,8 @@ #include "test.h" #include +#include + int test_num = 0; @@ -11,7 +13,7 @@ void DECLARE_NEW_TEST(char *description) { } -void ASSERT_EQUALS_INT(char* description, int val1, int val2) { +int ASSERT_EQUALS_INT(char* description, int val1, int val2) { test_num++; if (val1 == val2){ @@ -22,19 +24,24 @@ void ASSERT_EQUALS_INT(char* description, int val1, int val2) { else { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d\n", test_num); + printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf("\033[0m"); + return 1; } printf("\033[0m"); + return 0; } -void ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { +int ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { test_num++; if (val1 == val2){ printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %s %s\n", test_num, __LINE__, __FILE__); + printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf("\033[0m"); + return 1; } else { printf("\033[0;32m"); @@ -42,10 +49,11 @@ void ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { printf(" pass # %d\n", test_num); } printf("\033[0m"); + return 0; } -void ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { +int ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { test_num++; if (!memcmp(val1, val2, size)) { @@ -56,20 +64,25 @@ void ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) } else { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d\n", test_num); + printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf("\033[0m"); + return 1; } printf("\033[0m"); + return 0; } -void ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { +int ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { test_num++; if (!memcmp(val1, val2, size)) { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d\n", test_num); + printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf("\033[0m"); + return 1; } else { printf("\033[0;32m"); @@ -77,4 +90,43 @@ void ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t si printf(" pass # %d\n", test_num); } printf("\033[0m"); + return 0; +} + + +int ASSERT_NULL(char* description, void *val1) { + test_num++; + if (val1 != NULL) { + printf("\033[0;31m"); + printf("%s", description); + printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf("\033[0m"); + return 1; + } else { + printf("\033[0;32m"); + printf("%s", description); + printf(" pass # %d\n", test_num); + } + printf("\033[0m"); + return 0; + } + +int ASSERT_NOT_NULL(char* description, void *val1) { + + test_num++; + if (val1 == NULL) { + printf("\033[0;31m"); + printf("%s", description); + printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf("\033[0m"); + return 1; + + } else { + printf("\033[0;32m"); + printf("%s", description); + printf(" pass # %d\n", test_num); + } + printf("\033[0m"); + return 0; +} \ No newline at end of file diff --git a/Program/test/test.h b/Program/test/test.h index 80cc065..9f85c7f 100644 --- a/Program/test/test.h +++ b/Program/test/test.h @@ -3,9 +3,13 @@ #define PACKET_TEST_H #include -void ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size); -void ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2); -void ASSERT_EQUALS_INT(char* description, int val1, int val2); -void ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) ; +void DECLARE_NEW_TEST(char *description); +int ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size); +int ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2); +int ASSERT_EQUALS_INT(char* description, int val1, int val2); +int ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size); +int ASSERT_NULL(char* description, void *val1); +int ASSERT_NOT_NULL(char* description, void *val1); + #endif \ No newline at end of file diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index ef9d891..b3ce635 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -6,15 +6,15 @@ List *populate_request_list(); - int tasks_tests(); - int request_tests(); - int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); - int packet_tests(); + //int tasks_tests(); + //int request_tests(); + //int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); + //int packet_tests(); int protocol_handler_test(); #define TEMP_FILESIZE 1000 - int file_system_tests(); + //int file_system_tests(); //int server_tests(int client ); From 2e00842d82332bbbb3b1920a5b31e2cf410e31c1 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 30 Nov 2019 14:21:53 -0700 Subject: [PATCH 142/400] test build eof packet --- Program/src/mib.c | 2 +- Program/src/packet.c | 26 ++++++--- Program/src/protocol_handler.c | 3 +- Program/src/requests.c | 1 + Program/test/dest.jpg | Bin 0 -> 150033 bytes Program/test/main.c | 4 +- Program/test/makefile | 33 ++++++------ Program/test/mock.c | 73 ++++++++++++++++++++++++++ Program/test/packet_tests.c | 51 +++++++++++++++--- Program/test/protocol_handler_tests.c | 31 +++-------- Program/test/unit_tests.h | 6 ++- 11 files changed, 171 insertions(+), 59 deletions(-) create mode 100644 Program/test/dest.jpg create mode 100644 Program/test/mock.c diff --git a/Program/src/mib.c b/Program/src/mib.c index 27db2a1..60ddc46 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -68,8 +68,8 @@ Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ pdu_header->transaction_seq_num_len = 3; pdu_header->length_of_entity_IDs = 1; pdu_header->transmission_mode = remote->default_transmission_mode; - pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); + checkAlloc(pdu_header->destination_id, 1); memcpy(pdu_header->destination_id, &remote->cfdp_id, pdu_header->length_of_entity_IDs); diff --git a/Program/src/packet.c b/Program/src/packet.c index 544e7a5..8d530b4 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -12,8 +12,19 @@ creating packets ------------------------------------------------------------------------------*/ -//returns the location in the packet where the next pointer for tthe packet will start after the header + +// if is_data_packet is false, then is directive packet +static void set_packet_header(char *packet, uint16_t data_len, bool is_data_packet) { + + Pdu_header *header = (Pdu_header *) packet; + header->PDU_type = is_data_packet; + set_data_length(packet, data_len); + +} + + +//returns the location in the packet where the next pointer for tthe packet will start after the header uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); @@ -50,7 +61,7 @@ uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uin uint8_t build_finished_pdu(char *packet, uint32_t start) { uint32_t packet_index = start; - uint32_t data_len = 0; + uint16_t data_len = 0; packet[packet_index] = FINISHED_PDU; packet_index++; @@ -64,15 +75,13 @@ uint8_t build_finished_pdu(char *packet, uint32_t start) { data_len += 1; packet_index += 1; - set_data_length(packet, data_len); + set_packet_header(packet, data_len, DIRECTIVE); return data_len; } //returns packet_index for data, to get length of meta data, subtract start from return value uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { - Pdu_header *header = (Pdu_header *) packet; - - header->PDU_type = DIRECTIVE; + uint8_t packet_index = start; //set directive 1 byte @@ -115,8 +124,8 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { packet_index = add_messages_to_packet(packet, packet_index, req->messages_to_user); uint8_t data_len = packet_index - start; - set_data_length(packet, data_len); - + set_packet_header(packet, data_len, DIRECTIVE); + return packet_index; } uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { @@ -197,6 +206,7 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len return 0; } + void build_eof_packet(char *packet, uint32_t start, File *file) { Pdu_header *header = (Pdu_header *) packet; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 7a64119..23ac61b 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -33,7 +33,7 @@ static void request_metadata(Request *req, Response res) { ------------------------------------------------------------------------------*/ -static void process_pdu_eof(char *packet, Request *req, Response res) { +void process_pdu_eof(char *packet, Request *req, Response res) { Pdu_eof *eof_packet = (Pdu_eof *) packet; @@ -120,7 +120,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r uint16_t len = get_data_length(packet); Request *request = *req; - //if packet is from the same request, don't' change current request if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ diff --git a/Program/src/requests.c b/Program/src/requests.c index 548de81..be41dea 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -147,6 +147,7 @@ Request *init_request(uint32_t buff_len) { } + //starts a new client, adding it to app->active_clients, as well as //starting a new request and adding it to the client, returns a pointer //to the request diff --git a/Program/test/dest.jpg b/Program/test/dest.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b379f5cb9915b4b8e6ed4884534df91197fe50d5 GIT binary patch literal 150033 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%0Aud#$a{ zkRch~+8Cj=ikFE5nlK*>QBv$8%- z?PJ6U#$l9VjAms|Yh7|oVut%R)G!xJ#Y>x{sT~8pQD}yyiysuBIlrL!^N7k-<3AMJ zUKc(SG?MD@7z2c071oE}R`N!kMA_;BPynm-xZef+Jj8aEM4p^#L&83N8Gc-|m2;Y4 z2k{Db`E;O106Hz$0i|dj^ayWhZ>GDXj=UEiO){`|MGoJ;_GB=!oGI`tRTOT=EDIR* zd^#(~b!(A0;Cdzig$s8S`M%YEiq*2Mn&2-BGQ#m#~4nF_d8LQ%YLaJ*`qt zbY1qcgunyaecT;kDT6kPU)z@nXP@@}CE%qYMCx)#Vt!7J}h*t1fL8 z@#K|=nEPj;UDswe)g?zR!yE!b`+4`&;h1jbrPYl|s9(Zlub|iYXVT#>v0*XX67HsC zUB#++Uf=n$qhqRzixz7-6|i25q9tIq30$dSDi=e`PMjhKN@Z2;NNazId9{o|JR7bK zL>L=?rElX2Ha2{eSbW?l^ZyT}Bg^kZv$cNtoTTpO$)6Au8)0p-XJgo~IN=)XNqU^q zc`Jn>OXx2+oc*sSV-xLXlR5MYJ^ca$ocA z>PPB5j1%(=L3y{*2hWV-EN-rRJ5-hw2V4P4&V~KXWsmvSX5{NuTv=uR5+7kZ!EYId zy+6-be{LeXk#LXsbA?b(X1Aℑc2u$a@atbWiNxbvMP2=$?T5F5KLl$pGaqKH*a; zwgkM@>*Y}yMINU_&Sby8{d+&l#$KlN=dlMYf1bSSE7c7x^AL@IxN=)PP~jv#@QERSC%851eStg~x?3ga^=vUw~GjAspLo5>G_l$-Oz!igK?@c+i*irW` zJo;{RAg+nN^EqDWA3n1CX#eGW^oBGF&bK{MC%*hRjF&(0}t=2 zB_kpm4$!;6f`XPwks|DlE&H8jM{Nr8XP6(oqI|qCXC`N0A=2o?);saOr<8r3`6jUQG%r&YhD8)2 z*nHXHw>LlOCyALC%y*++2OyZEY5*9#<@#op%$z{6$O&lGS>U2z$ndg7B>>iV^w1@y zhZj*B{*@?~1mfg~SiUYVvGUDiW@IVc0L|SP=4iJMWmbKho}=lg+BV*N0`yiN*&L++ zdEpa2Rs+Hkt|Nk=ZS=?KadD}e`OAuJRuw+iBmtEX$(_F@g4y^(B2tR$$A$lcvHU-H zWWC^bkaOCJMl9tdK?)ymdMlk|L@CzU>~z!(U$=np5A(90W4XoC3P%RLLi;iaa>4QG zs#PTnR8SF9b#kwa0VZK(>cD#ro9QX=u zc6zcy-^CyHDZ$K+DB(@Kf^R7%*9vFZ*DX$i`aiEy{64bG2C(-&SC5p6A=ytaS7h?Y zqT=^G-iUmJE@LsQH`)VtE_-ipj|p?KW%OqzxgHr=Hb$YIcS_d$7I-}5#sILT2?$m@ zN(q9L#M150lznN^e~HCE^r*>i=tM`EIp;7uYj5(X`YCi5R{vXW=!kn}YTijy`46Qh z%0%Ic#23i5I?$#$U3TdB+hx(4;mpvr%Qo_(JNUwc&AJhM#G5l(5VLyHHTdaTpqUpF z=IPWNKce|lJ3%Ww@Yp|J;_qFGEQ800rIOE*m!(aS2!bBe#3(M7)0_2_`;H2uuMos~ zy6CN}{J?zHOy(JGiwW)c`s-&3x9!?s}Rbl?Dzc6}-O zlxbEaDkmYN<>phRyc(E`7kIEXz!cwi-}|_qo1(tlu+z?+jwD4mX{uf!-v;}m1`2IU z4o`{8S|-rxN2mszndq*o5*LjBJc9I2PNkm)SF29CmN-qMUvi7T59^xx0o5MqbL8jg zajmhNbj|;)sch(9?Pmr3F;% z@W%e-%xu~2*>R}syVq#1?)&jFcZ*-dA(ytkCS&~$aYVl4t4om0pnf|+3F>(C9F+;0 zr8)20)s)-aiR)U ztDCAUN4%lo_1zfzf8∓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

l*jbYJ-y8sPytNkQvyW#ZK6`YYz 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 W3X;8dcD~`lgbrK1JdJPvYvR8dkw82E literal 0 HcmV?d00001 diff --git a/Program/test/main.c b/Program/test/main.c index 44353d1..c68a499 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -18,8 +18,8 @@ int main () { int error = 0; //error = request_tests(); - //error = packet_tests(); - error = protocol_handler_test(); + error = packet_tests(); + //error = protocol_handler_test(); //error = list_tests(); //error = file_system_tests(); diff --git a/Program/test/makefile b/Program/test/makefile index d703d84..8ce54f6 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -27,8 +27,9 @@ CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -#CFILES += $(PROJDIR)/test/packet_tests.c +CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c +CFILES += $(PROJDIR)/test/mock.c #CFILES += $(PROJDIR)/test/request_tests.c #CFILES += $(PROJDIR)/test/tasks_tests.c #CFILES += $(PROJDIR)/test/list_tests.c @@ -43,25 +44,25 @@ CFILES += $(PROJDIR)/test/protocol_handler_tests.c MAIN = main #---------------------------Compiler Warnings--------------------------- -CWARNS += -W -CWARNS += -Wall +#CWARNS += -W +#CWARNS += -Wall #CWARNS += -Werror -CWARNS += -Wextra -CWARNS += -Wformat -CWARNS += -Wmissing-braces -CWARNS += -Wno-cast-align -CWARNS += -Wparentheses -CWARNS += -Wshadow -CWARNS += -Wno-sign-compare -CWARNS += -Wswitch +#CWARNS += -Wextra +#CWARNS += -Wformat +#CWARNS += -Wmissing-braces +#CWARNS += -Wno-cast-align +#CWARNS += -Wparentheses +#CWARNS += -Wshadow +#CWARNS += -Wno-sign-compare +#CWARNS += -Wswitch CWARNS += -Wuninitialized -CWARNS += -Wunknown-pragmas -CWARNS += -Wunused-function -CWARNS += -Wunused-label +#CWARNS += -Wunknown-pragmas +#CWARNS += -Wunused-function +#CWARNS += -Wunused-label #CWARNS += -Wunused-parameter #CWARNS += -Wunused-value -CWARNS += -Wunused-variable -CWARNS += -Wmissing-prototypes +#CWARNS += -Wunused-variable +#CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = diff --git a/Program/test/mock.c b/Program/test/mock.c new file mode 100644 index 0000000..34baffa --- /dev/null +++ b/Program/test/mock.c @@ -0,0 +1,73 @@ + +#include "types.h" +#include "filesystem_funcs.h" +#include "port.h" +#include "protocol_handler.h" +#include "mib.h" +#include "file_delivery_app.h" +#include "packet.h" +#include "unit_tests.h" +#include "requests.h" + +#include +#include +#include + + + +MIB *mock_mib() { + + //Memory information base + MIB *mib = init_mib(); + + //setting host name for testing + char *host_name = "127.0.0.1"; + uint32_t addr[sizeof(uint32_t)]; + inet_pton(AF_INET, host_name, addr); + + //adding new cfdp entities to management information base + add_new_cfdp_entity(mib, 1, *addr, 1111, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 7, *addr, 1113, posix, UN_ACKNOWLEDGED_MODE); + + add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); + + add_new_cfdp_entity(mib, 5, 3, 3, csp, ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 6, 4, 4, csp, ACKNOWLEDGED_MODE); + + return mib; +} + + +int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { + + MIB *mib = mock_mib(); + Pdu_header *pdu_header = get_header_from_mib(mib, dest_id, src_id); + int packet_index = build_pdu_header(packet, 1, 0, pdu_header); + + ssp_cleanup_pdu_header(pdu_header); + free_mib(mib); + + return packet_index; +} + +Response mock_response() { + Response res; + int addr = 16; + res.addr = &addr; + res.sfd = 1; + res.packet_len = 2000; + res.size_of_addr = 16; + return res; +} + +static int test_process_pdu_eof() { +//char *packet, Request *req, Response res + + + //process_pdu_eof(packet, Request *req, Response res); + return 0; +} + + diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 273c5bf..87df81e 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -11,18 +11,54 @@ #include "file_delivery_app.h" #include "packet.h" #include "unit_tests.h" +#include "requests.h" +#include "stdlib.h" #define PACKET_TEST_SIZE 2000 +/* +typedef struct pdu_eof { + unsigned int condition_code : 4; + unsigned int spare : 4; + uint32_t checksum; -static int test_build_eof_packet() { + uint32_t file_size; + //Omitted if condition code is ‘No error’. Otherwise, entity ID in the + //TLV is the ID of the entity at which transaction cancellation was + //initiated. + TLV fault_location; +} Pdu_eof; +*/ + +static int test_build_eof_packet(char *packet, int packet_start) { + + DECLARE_NEW_TEST("testing eof_packet"); + + File *file = create_file("dest.jpg", false); + + //need to set partialcheckus to checksum, because it gets set from reading in data + file->partial_checksum = check_sum_file(file, 1000); + build_eof_packet(packet, packet_start, file); + + int packet_index = packet_start; + Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; + directive->directive_code = EOF_PDU; + packet_index++; + + Pdu_eof *eof_pdu = (Pdu_eof*) &packet[packet_index]; + ASSERT_EQUALS_INT("condition_code should equal NO_ERROR", eof_pdu->condition_code, COND_NO_ERROR); + ASSERT_EQUALS_INT("filesize should equal", htonl(eof_pdu->file_size), file->total_size); + ASSERT_EQUALS_INT("checksum should equal", eof_pdu->checksum, file->partial_checksum); + //testing this + return 0; } static int test_respond_to_naks(char *packet, uint32_t packet_index) { Request *req = init_request(5000); + ssp_cleanup_req(req); return 0; } @@ -32,7 +68,7 @@ static int test_respond_metadata_request() { return 0; } -void test_build_data_packet(char *packet, uint32_t packet_index){ +static void test_build_data_packet(char *packet, uint32_t packet_index){ File *file = create_file("testfile", 0); @@ -164,7 +200,8 @@ int test_build_ack_finished_pdu(char *packet, uint32_t start) { printf("testing finished ack creation\n"); Request *req; - Pdu_directive *pdu_d = &packet[start]; + Pdu_directive *pdu_d = (Pdu_directive *)&packet[start]; + ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); Pdu_ack *ack = (Pdu_ack *)&packet[start + 1]; @@ -183,7 +220,7 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { Request *req; uint8_t len = build_ack (packet, start, EOF_PDU); - Pdu_directive *pdu_d = &packet[start]; + Pdu_directive *pdu_d = (Pdu_directive *) &packet[start]; ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); Pdu_ack *ack = (Pdu_ack *)&packet[start + 1]; @@ -204,14 +241,14 @@ int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_nu ASSERT_EQUALS_STR("packet source id ", &packet[packet_index], header->source_id, header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; - ASSERT_NOT_EQUALS_INT("transaction_sequence_number correctly placed ", &packet[packet_index], sequence_number); + ASSERT_NOT_EQUALS_INT("transaction_sequence_number correctly placed ", packet[packet_index], sequence_number); packet_index += header->transaction_seq_num_len; ASSERT_NOT_EQUALS_STR("packet destination not equal to source id ", &packet[packet_index], header->source_id, header->length_of_entity_IDs); ASSERT_EQUALS_STR("packet destination id ", &packet[packet_index], header->destination_id, header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; - Pdu_header *new_header = packet; + Pdu_header *new_header = (Pdu_header *)packet; ASSERT_EQUALS_INT("CRC = CRC", header->CRC_flag, new_header->CRC_flag); ASSERT_EQUALS_INT("direction = direction", header->direction, new_header->direction); @@ -428,6 +465,8 @@ int packet_tests() { test_build_data_packet(packet, data_start_index); test_build_metadata_packet(packet, data_start_index); + test_build_eof_packet(packet, data_start_index); + test_add_messages_to_packet(packet, data_start_index); test_get_message_from_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 045e6d9..83fc9e4 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -8,24 +8,6 @@ #include "unit_tests.h" #include "port.h" -static char *build_mock_packet(FTP *app, uint32_t id) { - - char *packet = calloc(sizeof(char*), 2000); - Pdu_header *pdu_header = get_header_from_mib(app->mib, id, app->my_cfdp_id); - build_pdu_header(packet, 1, 0, pdu_header); - ssp_cleanup_pdu_header(pdu_header); - return packet; -} - -static Response mock_response() { - Response res; - int addr = 16; - res.addr = &addr; - res.sfd = 1; - res.packet_len = 2000; - res.size_of_addr = 16; - return res; -} static int test_process_pdu_eof() { //char *packet, Request *req, Response res @@ -40,19 +22,24 @@ static int test_process_pdu_eof() { static int test_wrong_id(FTP *app) { int error = 0; Response res = mock_response(); - char *packet = build_mock_packet(app, 2); + char packet[2000]; + + int packet_index = mock_packet(packet, 2, 1); + Request **req_container = &app->current_request; process_pdu_header(packet, true, res, req_container, app->request_list, app); Request *req = (*req_container); error = ASSERT_NULL("Test wrong id, Request should be NULL", req); - free(packet); + return error; } static int test_correct_id(FTP *app) { int error = 0; Response res = mock_response(); - char *packet = build_mock_packet(app, 1); + char packet[2000]; + int packet_index = mock_packet(packet, 2, 1); + Request **req_container = &app->current_request; process_pdu_header(packet, true, res, req_container, app->request_list, app); Request *req = (*req_container); @@ -61,9 +48,7 @@ static int test_correct_id(FTP *app) { error = ASSERT_EQUALS_INT("request transaction number should equal", req->transaction_sequence_number, 1); error = ASSERT_NOT_EQUALS_INT("souce id should equal 2", req->dest_cfdp_id, 2); - free(packet); return error; - } static int test_process_pdu_header() { diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index b3ce635..28f2e10 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -9,10 +9,14 @@ //int tasks_tests(); //int request_tests(); //int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); - //int packet_tests(); + int packet_tests(); int protocol_handler_test(); + int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); + Response mock_response(); + + #define TEMP_FILESIZE 1000 //int file_system_tests(); From 96e253cb5efb5671c80ae3f0c05a252ab0709bf7 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 30 Nov 2019 17:22:36 -0700 Subject: [PATCH 143/400] Better testsing framework --- Program/test/test.c | 25 +++++++++++++------------ Program/test/test.h | 32 ++++++++++++++++++++++++++------ Program/test/unit_tests.h | 5 +++-- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/Program/test/test.c b/Program/test/test.c index 3b3338b..0eae64d 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -10,10 +10,11 @@ int test_num = 0; void DECLARE_NEW_TEST(char *description) { printf("\x1b[33m"); printf("-----------------------------------%s-----------------------------------\n", description); + printf("\033[0m"); } -int ASSERT_EQUALS_INT(char* description, int val1, int val2) { +int assert_equals_int(char *file_name, int line_num, char* description, int val1, int val2) { test_num++; if (val1 == val2){ @@ -24,7 +25,7 @@ int ASSERT_EQUALS_INT(char* description, int val1, int val2) { else { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf(" fail # %d %d %s\n", test_num, line_num, file_name); printf("\033[0m"); return 1; } @@ -33,13 +34,13 @@ int ASSERT_EQUALS_INT(char* description, int val1, int val2) { } -int ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { +int assert_not_equals_int(char *file_name, int line_num, char* description, int val1, int val2) { test_num++; if (val1 == val2){ printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf(" fail # %d %d %s\n", test_num, line_num, file_name); printf("\033[0m"); return 1; } @@ -53,7 +54,7 @@ int ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2) { } -int ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { +int assert_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size) { test_num++; if (!memcmp(val1, val2, size)) { @@ -64,7 +65,7 @@ int ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { } else { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf(" fail # %d %d %s\n", test_num, line_num, file_name); printf("\033[0m"); return 1; @@ -73,14 +74,14 @@ int ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { return 0; } -int ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size) { +int assert_not_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size) { test_num++; if (!memcmp(val1, val2, size)) { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf(" fail # %d %d %s\n", test_num, line_num, file_name); printf("\033[0m"); return 1; @@ -94,12 +95,12 @@ int ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t siz } -int ASSERT_NULL(char* description, void *val1) { +int assert_null(char *file_name, int line_num, char* description, void *val1) { test_num++; if (val1 != NULL) { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf(" fail # %d %d %s\n", test_num, line_num, file_name); printf("\033[0m"); return 1; } else { @@ -112,13 +113,13 @@ int ASSERT_NULL(char* description, void *val1) { } -int ASSERT_NOT_NULL(char* description, void *val1) { +int assert_not_null(char *file_name, int line_num, char* description, void *val1) { test_num++; if (val1 == NULL) { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, __LINE__, __FILE__); + printf(" fail # %d %d %s\n", test_num, line_num, file_name); printf("\033[0m"); return 1; diff --git a/Program/test/test.h b/Program/test/test.h index 9f85c7f..546effb 100644 --- a/Program/test/test.h +++ b/Program/test/test.h @@ -3,13 +3,33 @@ #define PACKET_TEST_H #include + +int assert_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size); +int assert_not_equals_int(char *file_name, int line_num, char* description, int val1, int val2); +int assert_equals_int(char *file_name, int line_num, char* description, int val1, int val2); +int assert_not_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size); +int assert_null(char *file_name, int line_num, char* description, void *val1); +int assert_not_null(char *file_name, int line_num, char* description, void *val1); + void DECLARE_NEW_TEST(char *description); -int ASSERT_EQUALS_STR(char* description, char *val1, char* val2, size_t size); -int ASSERT_NOT_EQUALS_INT(char* description, int val1, int val2); -int ASSERT_EQUALS_INT(char* description, int val1, int val2); -int ASSERT_NOT_EQUALS_STR(char* description, char *val1, char* val2, size_t size); -int ASSERT_NULL(char* description, void *val1); -int ASSERT_NOT_NULL(char* description, void *val1); +#define ASSERT_EQUALS_STR(description, val1, val2, size)\ + assert_equals_str(__FILE__, __LINE__, description, val1, val2, size); + +#define ASSERT_NOT_EQUALS_INT(description, val1, val2)\ + assert_not_equals_int(__FILE__, __LINE__, description, val1, val2); + +#define ASSERT_EQUALS_INT(description, val1, val2)\ + assert_equals_int(__FILE__, __LINE__, description, val1, val2); + +#define ASSERT_NOT_EQUALS_STR(description, val1, val2, size)\ + assert_not_equals_str(__FILE__, __LINE__, description, val1, val2, size); + +#define ASSERT_NULL(description, val1)\ + assert_null(__FILE__, __LINE__, description, val1); + +#define ASSERT_NOT_NULL(description, val1)\ + assert_not_null(__FILE__, __LINE__, description, val1); + #endif \ No newline at end of file diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index 28f2e10..19e1235 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -14,8 +14,9 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); - Response mock_response(); - + Response *mock_response(); + void mock_eof_packet(char *packet, int packet_index); + Request *mock_request(); #define TEMP_FILESIZE 1000 //int file_system_tests(); From d40418cf7c17926c1a6b6ed5753b54b31259dfeb Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 2 Dec 2019 10:29:15 -0700 Subject: [PATCH 144/400] mock request --- Program/src/port.c | 14 ++++-- Program/src/protocol_handler.c | 1 - Program/test/main.c | 4 +- Program/test/mock.c | 72 +++++++++++++++++++++++---- Program/test/packet_tests.c | 25 ++++++---- Program/test/protocol_handler_tests.c | 32 +++++++++--- Program/test/test.c | 12 ++--- Program/test/unit_tests.h | 2 +- 8 files changed, 121 insertions(+), 41 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 51a3176..ef3c4df 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -118,13 +118,19 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { + if (res.type_of_network == posix && res.transmission_mode == UN_ACKNOWLEDGED_MODE) { struct sockaddr* addr = (struct sockaddr*) res.addr; - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); - if (err < 0) { - ssp_error("ERROR in sendto"); - } + #ifdef TEST + printf(res.msg); + #endif + #ifndef TEST + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); + if (err < 0) { + ssp_error("ERROR in sendto"); + } + #endif } else if (res.type_of_network == posix && res.transmission_mode == ACKNOWLEDGED_MODE) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 23ac61b..09844c9 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -45,7 +45,6 @@ void process_pdu_eof(char *packet, Request *req, Response res) { req->file = create_temp_file(req->source_file_name); } - req->local_entity->EOF_recv_indication = 1; req->file->eof_checksum = eof_packet->checksum; req->file->total_size = ntohl(eof_packet->file_size); diff --git a/Program/test/main.c b/Program/test/main.c index c68a499..44353d1 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -18,8 +18,8 @@ int main () { int error = 0; //error = request_tests(); - error = packet_tests(); - //error = protocol_handler_test(); + //error = packet_tests(); + error = protocol_handler_test(); //error = list_tests(); //error = file_system_tests(); diff --git a/Program/test/mock.c b/Program/test/mock.c index 34baffa..10789d0 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -30,11 +30,11 @@ MIB *mock_mib() { add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); add_new_cfdp_entity(mib, 7, *addr, 1113, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); + //add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); + //add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 5, 3, 3, csp, ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 6, 4, 4, csp, ACKNOWLEDGED_MODE); + //add_new_cfdp_entity(mib, 5, 3, 3, csp, ACKNOWLEDGED_MODE); + //add_new_cfdp_entity(mib, 6, 4, 4, csp, ACKNOWLEDGED_MODE); return mib; } @@ -52,16 +52,66 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { return packet_index; } -Response mock_response() { - Response res; +void mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id) { + + int packet_index = mock_packet(packet, dest_id, src_id); + File *file = create_file("dest.jpg", false); + file->partial_checksum = check_sum_file(file, 1000); + build_eof_packet(packet, packet_index, file); + free_file(file); + +} + + + +Response *mock_response() { + Response *res = calloc(1, sizeof(Response)); int addr = 16; - res.addr = &addr; - res.sfd = 1; - res.packet_len = 2000; - res.size_of_addr = 16; + res->addr = &addr; + res->sfd = 1; + res->packet_len = 2000; + res->size_of_addr = 16; + res->type_of_network = posix; + res->transmission_mode = UN_ACKNOWLEDGED_MODE; return res; } + + + +Request *mock_request() { + Request *req = init_request(5000); + MIB *mib = mock_mib(); + + char *dest = "dest"; + char *src = "src"; + uint32_t id = 1; + + req->dest_cfdp_id = id; + req->file = create_file("dest_received.jpg", true); + memcpy (req->source_file_name, dest, strnlen(dest, 255)); + memcpy (req->destination_file_name, src, strnlen(src, 255)); + + req->pdu_header = get_header_from_mib(mib, id, 2); + req->remote_entity = get_remote_entity(mib, 1); + + int addr = 16; + req->res.addr = malloc(5); + memcpy(req->res.addr, &addr, 4); + req->res.sfd = 1; + req->res.packet_len = 2000; + req->res.size_of_addr = 16; + req->res.type_of_network = posix; + req->res.transmission_mode = UN_ACKNOWLEDGED_MODE; + req->res.msg = req->buff; + + free_mib(mib); + + return req; +} + + +/* static int test_process_pdu_eof() { //char *packet, Request *req, Response res @@ -71,3 +121,5 @@ static int test_process_pdu_eof() { } +*/ + diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 87df81e..6093568 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -51,7 +51,10 @@ static int test_build_eof_packet(char *packet, int packet_start) { Pdu_eof *eof_pdu = (Pdu_eof*) &packet[packet_index]; ASSERT_EQUALS_INT("condition_code should equal NO_ERROR", eof_pdu->condition_code, COND_NO_ERROR); ASSERT_EQUALS_INT("filesize should equal", htonl(eof_pdu->file_size), file->total_size); - ASSERT_EQUALS_INT("checksum should equal", eof_pdu->checksum, file->partial_checksum); + ASSERT_EQUALS_INT("checksum should equal", eof_pdu->checksum, file->partial_checksum); + + free_file(file); + //testing this return 0; } @@ -70,6 +73,8 @@ static int test_respond_metadata_request() { static void test_build_data_packet(char *packet, uint32_t packet_index){ + DECLARE_NEW_TEST("testing data packet"); + File *file = create_file("testfile", 0); build_data_packet(packet, packet_index, file, 1000); @@ -94,7 +99,8 @@ static void nak_print(void *element, void *args){ } static int test_build_nak_packet(char* packet, uint32_t start) { - printf("testing nak creation 1 \n"); + + DECLARE_NEW_TEST("testing build nak packet"); Request *req = init_request(5000); req->file_size = 100000; @@ -104,7 +110,6 @@ static int test_build_nak_packet(char* packet, uint32_t start) { process_file_request_metadata(req); uint64_t count = req->file->missing_offsets->count; - ssp_printf("missing offset number=%u\n", count); uint32_t data_len = build_nak_packet(packet, start, req); @@ -131,8 +136,6 @@ static int test_build_nak_packet(char* packet, uint32_t start) { ASSERT_EQUALS_INT("start offset == 0 ", start_scope, 0); ASSERT_EQUALS_INT("end scope == 100000 ", end_scope, 100000); - //add a bunch more - printf("testing nak creation 2 \n"); receive_offset(req->file, 0, 1250, 5000); receive_offset(req->file, 0, 6000, 9000); @@ -197,6 +200,8 @@ static int test_build_nak_packet(char* packet, uint32_t start) { } int test_build_ack_finished_pdu(char *packet, uint32_t start) { + + DECLARE_NEW_TEST("testing finish ack packet"); printf("testing finished ack creation\n"); Request *req; @@ -215,7 +220,8 @@ int test_build_ack_finished_pdu(char *packet, uint32_t start) { int test_build_ack_eof_pdu(char *packet, uint32_t start) { //empty request - printf("testing eof ack creation\n"); + + DECLARE_NEW_TEST("testing eof ack packet"); Request *req; uint8_t len = build_ack (packet, start, EOF_PDU); @@ -233,7 +239,8 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_number) { - printf("testing header creation\n"); + + DECLARE_NEW_TEST("testing header creation"); uint8_t length = build_pdu_header(packet, sequence_number, 0, header); uint32_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -270,8 +277,8 @@ int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_nu int test_build_metadata_packet(char *packet, uint32_t start) { memset(&packet[start], 0, 20); + DECLARE_NEW_TEST("testing metadata packets"); - printf("testing metadata packets\n"); Request *req = init_request(1000); Request *recv_request = init_request(1000); @@ -312,8 +319,8 @@ int test_add_messages_to_packet(char *packet, uint32_t start) { uint8_t len = 1; uint32_t packet_index = start; + DECLARE_NEW_TEST("testing add_messages_to_packet"); - ssp_printf("testing add_messages_to_packet\n"); Request *req = init_request(1000); int error = add_proxy_message_to_request(id, len, src, dest, req); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 83fc9e4..00a1573 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -7,13 +7,25 @@ #include "file_delivery_app.h" #include "unit_tests.h" #include "port.h" +#include "requests.h" + static int test_process_pdu_eof() { //char *packet, Request *req, Response res + + DECLARE_NEW_TEST("testing process eof pdu"); + + char *packet = malloc(2000); + mock_eof_packet(packet, 1, 2); + Request *req = mock_request(); + + process_pdu_eof(packet, req, req->res); + + free(packet); + ssp_cleanup_req(req); - //process_pdu_eof(packet, Request *req, Response res); return 0; } @@ -21,33 +33,37 @@ static int test_process_pdu_eof() { static int test_wrong_id(FTP *app) { int error = 0; - Response res = mock_response(); + Response *res = mock_response(); char packet[2000]; int packet_index = mock_packet(packet, 2, 1); Request **req_container = &app->current_request; - process_pdu_header(packet, true, res, req_container, app->request_list, app); + process_pdu_header(packet, true, *res, req_container, app->request_list, app); Request *req = (*req_container); error = ASSERT_NULL("Test wrong id, Request should be NULL", req); + error = ASSERT_EQUALS_INT("Length of request list should be 0", app->request_list->count, 0); + free(res); return error; } static int test_correct_id(FTP *app) { int error = 0; - Response res = mock_response(); + Response *res = mock_response(); char packet[2000]; - int packet_index = mock_packet(packet, 2, 1); + int packet_index = mock_packet(packet, 1, 2); Request **req_container = &app->current_request; - process_pdu_header(packet, true, res, req_container, app->request_list, app); + process_pdu_header(packet, true, *res, req_container, app->request_list, app); Request *req = (*req_container); + error = ASSERT_NOT_NULL("Test wrong id, Request should not be NULL", req); error = ASSERT_EQUALS_INT("Length of request should be 1", app->request_list->count, 1); error = ASSERT_EQUALS_INT("request transaction number should equal", req->transaction_sequence_number, 1); - error = ASSERT_NOT_EQUALS_INT("souce id should equal 2", req->dest_cfdp_id, 2); + error = ASSERT_EQUALS_INT("souce id should equal 2", req->dest_cfdp_id, 2); + free(res); return error; } @@ -67,7 +83,7 @@ static int test_process_pdu_header() { int protocol_handler_test() { int error = 0; - error = test_process_pdu_header(); + //error = test_process_pdu_header(); error = test_process_pdu_eof(); return error; } \ No newline at end of file diff --git a/Program/test/test.c b/Program/test/test.c index 0eae64d..0913701 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -25,7 +25,7 @@ int assert_equals_int(char *file_name, int line_num, char* description, int val else { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, line_num, file_name); + printf(" fail # %d %s:%d\n", test_num, file_name, line_num); printf("\033[0m"); return 1; } @@ -40,7 +40,7 @@ int assert_not_equals_int(char *file_name, int line_num, char* description, int if (val1 == val2){ printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, line_num, file_name); + printf(" fail # %d %s:%d\n", test_num, file_name, line_num); printf("\033[0m"); return 1; } @@ -65,7 +65,7 @@ int assert_equals_str(char *file_name, int line_num, char* description, char *va } else { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, line_num, file_name); + printf(" fail # %d %s:%d\n", test_num, file_name, line_num); printf("\033[0m"); return 1; @@ -81,7 +81,7 @@ int assert_not_equals_str(char *file_name, int line_num, char* description, char printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, line_num, file_name); + printf(" fail # %d %s:%d\n", test_num, file_name, line_num); printf("\033[0m"); return 1; @@ -100,7 +100,7 @@ int assert_null(char *file_name, int line_num, char* description, void *val1) { if (val1 != NULL) { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, line_num, file_name); + printf(" fail # %d %s:%d\n", test_num, file_name, line_num); printf("\033[0m"); return 1; } else { @@ -119,7 +119,7 @@ int assert_not_null(char *file_name, int line_num, char* description, void *val1 if (val1 == NULL) { printf("\033[0;31m"); printf("%s", description); - printf(" fail # %d %d %s\n", test_num, line_num, file_name); + printf(" fail # %d %s:%d\n", test_num, file_name, line_num); printf("\033[0m"); return 1; diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index 19e1235..a3aae61 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -15,7 +15,7 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); Response *mock_response(); - void mock_eof_packet(char *packet, int packet_index); + void mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id); Request *mock_request(); #define TEMP_FILESIZE 1000 From af2cc38f0865e4ebe4897324886e384be7642382 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 3 Dec 2019 09:35:41 -0700 Subject: [PATCH 145/400] test process eof --- Program/include/config.h | 1 + Program/include/types.h | 2 +- Program/src/port.c | 4 +-- Program/test/mock.c | 6 ++-- Program/test/protocol_handler_tests.c | 44 ++++++++++++++++++++++++--- Program/test/unit_tests.h | 2 +- 6 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 Program/include/config.h diff --git a/Program/include/config.h b/Program/include/config.h new file mode 100644 index 0000000..396b368 --- /dev/null +++ b/Program/include/config.h @@ -0,0 +1 @@ +#define TEST \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index 97efbda..a7462dd 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -471,7 +471,7 @@ typedef struct local_entity { typedef enum Network_type { csp, - free_rtos, + //free_rtos, posix, } Network_type; diff --git a/Program/src/port.c b/Program/src/port.c index ef3c4df..522be48 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -9,7 +9,7 @@ #include "filesystem_funcs.h" #include #include "types.h" - +#include "config.h" #ifdef POSIX_PORT #include @@ -123,7 +123,7 @@ void ssp_sendto(Response res) { struct sockaddr* addr = (struct sockaddr*) res.addr; #ifdef TEST - printf(res.msg); + printf("sending outgoing packet (testing)\n"); #endif #ifndef TEST int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); diff --git a/Program/test/mock.c b/Program/test/mock.c index 10789d0..0221c4e 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -52,14 +52,14 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { return packet_index; } -void mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id) { +File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *file_name) { int packet_index = mock_packet(packet, dest_id, src_id); - File *file = create_file("dest.jpg", false); + File *file = create_file(file_name, false); file->partial_checksum = check_sum_file(file, 1000); build_eof_packet(packet, packet_index, file); - free_file(file); + return file; } diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 00a1573..48fb31d 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -8,7 +8,7 @@ #include "unit_tests.h" #include "port.h" #include "requests.h" - +#include "filesystem_funcs.h" static int test_process_pdu_eof() { @@ -16,16 +16,52 @@ static int test_process_pdu_eof() { DECLARE_NEW_TEST("testing process eof pdu"); + char *packet = malloc(2000); - mock_eof_packet(packet, 1, 2); + + //test images + File *file = mock_eof_packet(packet, 1, 2, "test_files/dest.jpg"); Request *req = mock_request(); + process_pdu_eof(&packet[10], req, req->res); + + ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity->EOF_recv_indication, true); + ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); + ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); + + free_file(file); + ssp_cleanup_req(req); - process_pdu_eof(packet, req, req->res); + //test empty files + file = mock_eof_packet(packet, 1, 2, "test_files/empty.txt"); + req = mock_request(); + + process_pdu_eof(&packet[10], req, req->res); - free(packet); + ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity->EOF_recv_indication, true); + ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); + ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); + + + free_file(file); ssp_cleanup_req(req); + //test empty filestruct + file = mock_eof_packet(packet, 1, 2, "test_files/empty.txt"); + req = mock_request(); + free_file(req->file); + req->file = NULL; + + process_pdu_eof(&packet[10], req, req->res); + + ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity->EOF_recv_indication, true); + ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); + ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); + + free(packet); + free_file(file); + ssp_cleanup_req(req); + return 0; } diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index a3aae61..8823e28 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -15,7 +15,7 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); Response *mock_response(); - void mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id); +File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *file_name); Request *mock_request(); #define TEMP_FILESIZE 1000 From 989d5c8ca6e58d5f599a21f0fa1da69ccc36e270 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 10 Dec 2019 09:26:28 -0700 Subject: [PATCH 146/400] building better server state machine tests --- Program/src/protocol_handler.c | 23 ++++--- Program/src/requests.c | 2 +- Program/test/protocol_handler_tests.c | 98 ++++++++++++++++++++++++++- 3 files changed, 113 insertions(+), 10 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 09844c9..413f174 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -18,6 +18,14 @@ ------------------------------------------------------------------------------*/ + +static void build_temperary_file(Request *req) { + + snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); + ssp_printf("haven't received metadata yet, building temperary file %s\n", req->source_file_name); + req->file = create_temp_file(req->source_file_name); +} + static void request_metadata(Request *req, Response res) { ssp_printf("sending request for new metadata packet\n"); @@ -33,6 +41,7 @@ static void request_metadata(Request *req, Response res) { ------------------------------------------------------------------------------*/ +//processes the eof packet, sets checksum, indication, and filesize. void process_pdu_eof(char *packet, Request *req, Response res) { Pdu_eof *eof_packet = (Pdu_eof *) packet; @@ -41,8 +50,7 @@ void process_pdu_eof(char *packet, Request *req, Response res) { request_metadata(req, res); } if (req->file == NULL) { - snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); - req->file = create_temp_file(req->source_file_name); + build_temperary_file(req); } req->local_entity->EOF_recv_indication = 1; @@ -466,8 +474,10 @@ void on_server_time_out(Response res, Request *req) { req->resent_eof++; } - if (req->file == NULL) + if (req->file == NULL) { + ssp_printf("file is null, not sending data naks"); return; + } //send missing NAKS if (req->file->missing_offsets->count > 0) { @@ -478,7 +488,7 @@ void on_server_time_out(Response res, Request *req) { } else { - if (req->file->eof_checksum == req->file->partial_checksum){ + if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity->EOF_recv_indication){ ssp_printf("sending finsihed pdu transaction: %d\n", req->transaction_sequence_number); build_finished_pdu(req->buff, start); ssp_sendto(res); @@ -505,14 +515,11 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ if (header->PDU_type == 1) { if (!req->local_entity->Metadata_recv_indication) { if (req->file == NULL) { - snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); - ssp_printf("haven't received metadata yet, building temperary file %s\n", req->source_file_name); - req->file = create_temp_file(req->source_file_name); + build_temperary_file(req); } request_metadata(req, res); } write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); - //ssp_printf("received data from transaction %d\n", req->transaction_sequence_number); return; } diff --git a/Program/src/requests.c b/Program/src/requests.c index be41dea..564795f 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -204,7 +204,7 @@ Request *put_request( if (file_size == 0) return NULL; - req->file = create_file(source_file_name, 0); + req->file = create_file(source_file_name, false); req->file_size = file_size; req->procedure = sending_put_metadata; diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 48fb31d..9c9d7e8 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -65,6 +65,100 @@ static int test_process_pdu_eof() { return 0; } +/* + +void on_server_time_out(Response res, Request *req) { + + + if (req->paused) + return; + + if (req->procedure == none) + return; + + if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) + return; + + + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + + if (req->resent_finished == RESEND_FINISHED_TIMES) { + req->procedure = none; + ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); + return; + } + + //send request for metadata + if (!req->local_entity->Metadata_recv_indication) { + ssp_printf("sending request for new metadata packet transaction: %d\n", req->transaction_sequence_number); + build_nak_directive(req->buff, start, META_DATA_PDU); + ssp_sendto(res); + return; + } + + //send missing eofs + if (!req->local_entity->EOF_recv_indication) { + ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); + build_nak_directive(req->buff, start, EOF_PDU); + ssp_sendto(res); + } + + //received EOF, send back 3 eof ack packets + if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { + ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); + build_ack(req->buff, start, EOF_PDU); + ssp_sendto(res); + req->resent_eof++; + } + + if (req->file == NULL) + return; + + //send missing NAKS + if (req->file->missing_offsets->count > 0) { + ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); + build_nak_packet(req->buff, start, req); + ssp_sendto(res); + return; + + } else { + + if (req->file->eof_checksum == req->file->partial_checksum){ + ssp_printf("sending finsihed pdu transaction: %d\n", req->transaction_sequence_number); + build_finished_pdu(req->buff, start); + ssp_sendto(res); + req->resent_finished++; + return; + } + else { + ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); + } + } + +} +*/ +//main state machine +int test_on_server_time_out() { + + //Response res, Request *req + Request *req = mock_request(); + req->paused = false; + req->procedure = sending_data; + + //no meta data received, sending request for new one (can't send NAKs yet, because we don't know filesize) + on_server_time_out(req->res, req); + req->local_entity->Metadata_recv_indication = true; + + + on_server_time_out(req->res, req); + + + + //file equals null, should return. + on_server_time_out(req->res, req); + return 0; + +} static int test_wrong_id(FTP *app) { @@ -120,6 +214,8 @@ static int test_process_pdu_header() { int protocol_handler_test() { int error = 0; //error = test_process_pdu_header(); - error = test_process_pdu_eof(); + //error = test_process_pdu_eof(); + + error = test_on_server_time_out(); return error; } \ No newline at end of file From 7fe0ab666617f79ef1e301e0108a348b69e2e519 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 12 Dec 2019 19:58:54 -0700 Subject: [PATCH 147/400] made some resending functions --- Program/src/protocol_handler.c | 79 +++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 413f174..0188baa 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -26,15 +26,56 @@ static void build_temperary_file(Request *req) { req->file = create_temp_file(req->source_file_name); } + +static void send_ack(Request *req, Response res, unsigned int type){ + + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + build_ack(req->buff, start, type); + ssp_sendto(res); +} + +static void send_nak(Request *req, Response res, unsigned int type) { + + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + build_nak_directive(req->buff, start, type); + ssp_sendto(res); +} + +static void request_eof(Request *req, Response res) { + + ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); + send_nak(req, res, EOF_PDU); +} + static void request_metadata(Request *req, Response res) { - ssp_printf("sending request for new metadata packet\n"); + ssp_printf("sending request for new metadata packet %d\n", req->transaction_sequence_number); + send_nak(req, res, META_DATA_PDU); +} + +static void request_data(Request *req, Response res) { + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); - build_nak_directive(req->buff, start, META_DATA_PDU); + ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); + build_nak_packet(req->buff, start, req); ssp_sendto(res); - return; } +static void resend_eof_ack(Request *req, Response res) { + + ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); + send_ack(req,res, EOF_PDU); + req->resent_eof++; +} + +static void resend_finished_ack(Request *req, Response res) { + + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + ssp_printf("sending finished pdu transaction: %d\n", req->transaction_sequence_number); + build_finished_pdu(req->buff, start); + ssp_sendto(res); + req->resent_finished++; +} /*------------------------------------------------------------------------------ Processing Packets @@ -433,17 +474,9 @@ static void print_offsets(void *element, void *args) { void on_server_time_out(Response res, Request *req) { - if (req->paused) - return; - - if (req->procedure == none) + if (req->paused || req->procedure == none || req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; - if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) - return; - - - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); if (req->resent_finished == RESEND_FINISHED_TIMES) { req->procedure = none; @@ -453,25 +486,18 @@ void on_server_time_out(Response res, Request *req) { //send request for metadata if (!req->local_entity->Metadata_recv_indication) { - ssp_printf("sending request for new metadata packet transaction: %d\n", req->transaction_sequence_number); - build_nak_directive(req->buff, start, META_DATA_PDU); - ssp_sendto(res); + request_metadata(req, res); return; } //send missing eofs if (!req->local_entity->EOF_recv_indication) { - ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); - build_nak_directive(req->buff, start, EOF_PDU); - ssp_sendto(res); + request_eof(req, res); } //received EOF, send back 3 eof ack packets if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { - ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); - build_ack(req->buff, start, EOF_PDU); - ssp_sendto(res); - req->resent_eof++; + resend_eof_ack(req, res); } if (req->file == NULL) { @@ -481,18 +507,13 @@ void on_server_time_out(Response res, Request *req) { //send missing NAKS if (req->file->missing_offsets->count > 0) { - ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); - build_nak_packet(req->buff, start, req); - ssp_sendto(res); + request_data(req, res); return; } else { if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity->EOF_recv_indication){ - ssp_printf("sending finsihed pdu transaction: %d\n", req->transaction_sequence_number); - build_finished_pdu(req->buff, start); - ssp_sendto(res); - req->resent_finished++; + resend_finished_ack(req, res); return; } else { From f5a32096a2fb14c500b2f794df727586d4579949 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 15 Dec 2019 14:43:00 -0700 Subject: [PATCH 148/400] fixed eof bug --- Program/src/protocol_handler.c | 24 +++++--- Program/test/mock.c | 3 + Program/test/protocol_handler_tests.c | 82 +++------------------------ 3 files changed, 26 insertions(+), 83 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 0188baa..25ce53c 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -74,6 +74,7 @@ static void resend_finished_ack(Request *req, Response res) { ssp_printf("sending finished pdu transaction: %d\n", req->transaction_sequence_number); build_finished_pdu(req->buff, start); ssp_sendto(res); + req->local_entity->transaction_finished_indication = true; req->resent_finished++; } /*------------------------------------------------------------------------------ @@ -484,6 +485,7 @@ void on_server_time_out(Response res, Request *req) { return; } + //send request for metadata if (!req->local_entity->Metadata_recv_indication) { request_metadata(req, res); @@ -494,12 +496,18 @@ void on_server_time_out(Response res, Request *req) { if (!req->local_entity->EOF_recv_indication) { request_eof(req, res); } - //received EOF, send back 3 eof ack packets - if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { + else if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { resend_eof_ack(req, res); } + //receiving just messages, send back finished + if (req->file_size == 0) { + resend_finished_ack(req, res); + return; + } + + //if have not received metadata for a file tranaction, this should not ever trigger //TODO add asert if (req->file == NULL) { ssp_printf("file is null, not sending data naks"); return; @@ -511,14 +519,14 @@ void on_server_time_out(Response res, Request *req) { return; } else { - + //finished transaction, if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity->EOF_recv_indication){ resend_finished_ack(req, res); return; } - else { - ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); - } + + ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); + } } @@ -560,7 +568,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ get_messages_from_packet(packet, packet_index, data_len, req); process_messages(req, app); - req->local_entity->Metadata_recv_indication = 1; + req->local_entity->Metadata_recv_indication = true; if (req->file_size != 0) process_file_request_metadata(req); @@ -583,7 +591,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ Pdu_ack* ack_packet = (Pdu_ack *) &packet[packet_index]; if (ack_packet->directive_code == FINISHED_PDU) { ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); - req->local_entity->transaction_finished_indication = 1; + req->local_entity->transaction_finished_indication = true; } break; default: diff --git a/Program/test/mock.c b/Program/test/mock.c index 0221c4e..53505a7 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -62,8 +62,11 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *fil return file; } +void mock_metadata_packet() { +} + Response *mock_response() { Response *res = calloc(1, sizeof(Response)); int addr = 16; diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 9c9d7e8..c7c037a 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -65,78 +65,6 @@ static int test_process_pdu_eof() { return 0; } -/* - -void on_server_time_out(Response res, Request *req) { - - - if (req->paused) - return; - - if (req->procedure == none) - return; - - if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) - return; - - - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); - - if (req->resent_finished == RESEND_FINISHED_TIMES) { - req->procedure = none; - ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); - return; - } - - //send request for metadata - if (!req->local_entity->Metadata_recv_indication) { - ssp_printf("sending request for new metadata packet transaction: %d\n", req->transaction_sequence_number); - build_nak_directive(req->buff, start, META_DATA_PDU); - ssp_sendto(res); - return; - } - - //send missing eofs - if (!req->local_entity->EOF_recv_indication) { - ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); - build_nak_directive(req->buff, start, EOF_PDU); - ssp_sendto(res); - } - - //received EOF, send back 3 eof ack packets - if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { - ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); - build_ack(req->buff, start, EOF_PDU); - ssp_sendto(res); - req->resent_eof++; - } - - if (req->file == NULL) - return; - - //send missing NAKS - if (req->file->missing_offsets->count > 0) { - ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); - build_nak_packet(req->buff, start, req); - ssp_sendto(res); - return; - - } else { - - if (req->file->eof_checksum == req->file->partial_checksum){ - ssp_printf("sending finsihed pdu transaction: %d\n", req->transaction_sequence_number); - build_finished_pdu(req->buff, start); - ssp_sendto(res); - req->resent_finished++; - return; - } - else { - ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); - } - } - -} -*/ //main state machine int test_on_server_time_out() { @@ -148,14 +76,18 @@ int test_on_server_time_out() { //no meta data received, sending request for new one (can't send NAKs yet, because we don't know filesize) on_server_time_out(req->res, req); req->local_entity->Metadata_recv_indication = true; + on_server_time_out(req->res, req); - + req->local_entity->EOF_recv_indication = true; on_server_time_out(req->res, req); - + req->local_entity->transaction_finished_indication = true; + on_server_time_out(req->res, req); + + on_server_time_out_different(req->res, req); //file equals null, should return. - on_server_time_out(req->res, req); + //on_server_time_out(req->res, req); return 0; } From 09d0788238b77327982501aaf61f14e05839b7fc Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 15 Dec 2019 16:11:34 -0700 Subject: [PATCH 149/400] change build eof function, limit its scope, --- Program/include/packet.h | 2 +- Program/include/types.h | 7 +- Program/src/packet.c | 6 +- Program/src/protocol_handler.c | 187 ++++++++++++++++++--------------- Program/src/requests.c | 2 + 5 files changed, 110 insertions(+), 94 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 88196df..f5c06e1 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -21,7 +21,7 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); -void build_eof_packet(char *packet, uint32_t start, File *file); +void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t checksum); void fill_nak_array_callback(Node *node, void *element, void *args); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); uint8_t build_ack(char*packet, uint32_t start, uint8_t type); diff --git a/Program/include/types.h b/Program/include/types.h index a7462dd..f5f596c 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -460,6 +460,7 @@ typedef struct local_entity { unsigned int resumed_indication : 1; unsigned int Metadata_recv_indication: 1; + //function pointer to default handler? void *default_fault_handler; @@ -552,13 +553,13 @@ typedef struct response { typedef enum procedure { - sending_finished, none, + sending_finished, sending_put_metadata, sending_eof, - //sending data sending_data, - clean_up + clean_up, + sending_start, } Request_procedure; diff --git a/Program/src/packet.c b/Program/src/packet.c index 8d530b4..232e584 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -207,7 +207,7 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len } -void build_eof_packet(char *packet, uint32_t start, File *file) { +void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t checksum) { Pdu_header *header = (Pdu_header *) packet; //set header to file directive 0 is directive, 1 is data @@ -228,9 +228,9 @@ void build_eof_packet(char *packet, uint32_t start, File *file) { packet_index++; //4 bytes - eof_packet->file_size = ntohl(file->total_size); + eof_packet->file_size = ntohl(file_size); packet_index += 4; - eof_packet->checksum = file->partial_checksum; + eof_packet->checksum = checksum; packet_index += 4; //TODO addTLV fault_location diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 25ce53c..6b92983 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -41,26 +41,6 @@ static void send_nak(Request *req, Response res, unsigned int type) { ssp_sendto(res); } -static void request_eof(Request *req, Response res) { - - ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); - send_nak(req, res, EOF_PDU); -} - -static void request_metadata(Request *req, Response res) { - - ssp_printf("sending request for new metadata packet %d\n", req->transaction_sequence_number); - send_nak(req, res, META_DATA_PDU); -} - -static void request_data(Request *req, Response res) { - - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); - ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); - build_nak_packet(req->buff, start, req); - ssp_sendto(res); -} - static void resend_eof_ack(Request *req, Response res) { ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); @@ -68,59 +48,12 @@ static void resend_eof_ack(Request *req, Response res) { req->resent_eof++; } -static void resend_finished_ack(Request *req, Response res) { - - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); - ssp_printf("sending finished pdu transaction: %d\n", req->transaction_sequence_number); - build_finished_pdu(req->buff, start); - ssp_sendto(res); - req->local_entity->transaction_finished_indication = true; - req->resent_finished++; -} /*------------------------------------------------------------------------------ Processing Packets ------------------------------------------------------------------------------*/ -//processes the eof packet, sets checksum, indication, and filesize. -void process_pdu_eof(char *packet, Request *req, Response res) { - - Pdu_eof *eof_packet = (Pdu_eof *) packet; - - if (!req->local_entity->Metadata_recv_indication) { - request_metadata(req, res); - } - if (req->file == NULL) { - build_temperary_file(req); - } - - req->local_entity->EOF_recv_indication = 1; - req->file->eof_checksum = eof_packet->checksum; - req->file->total_size = ntohl(eof_packet->file_size); - -} - -int process_file_request_metadata(Request *req) { - - char temp[75]; - - if (req->file == NULL) - req->file = create_file(req->destination_file_name, 1); - - else if (req->file->is_temp) { - snprintf(temp, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); - change_tempfile_to_actual(temp, req->destination_file_name, req->file_size, req->file); - return 1; - } - - Offset *offset = ssp_alloc(1, sizeof(Offset)); - offset->end = req->file_size; - offset->start = 0; - req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); - - return 1; -} //for finding the struct in the list @@ -303,6 +236,13 @@ void process_messages(Request *req, FTP *app) { ------------------------------------------------------------------------------*/ +static void resend_finished_ack(Request *req, Response res) { + + ssp_printf("sending finished packet transaction ack: %d\n", req->transaction_sequence_number); + send_ack(req, res, FINISHED_PDU); + req->resent_finished++; +} + int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; @@ -351,19 +291,19 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch(directive) { case FINISHED_PDU: - req->local_entity->transaction_finished_indication = 1; + req->local_entity->transaction_finished_indication = true; req->procedure = sending_finished; ssp_printf("received finished pdu transaction: %d\n", req->transaction_sequence_number); break; case NAK_PDU: - req->local_entity->Metadata_recv_indication = 1; + req->local_entity->Metadata_recv_indication = true; nak_response(packet, packet_index, req, res, client); ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); break; case ACK_PDU: if (packet[packet_index] == EOF_PDU) { ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); - req->local_entity->EOF_recv_indication = 1; + req->local_entity->EOF_recv_indication = true; } break; case NAK_DIRECTIVE: @@ -398,10 +338,7 @@ static void check_req_status(Request *req) { //current user request, to send to server void user_request_handler(Response res, Request *req, Client* client) { - if (req == NULL) - return; - - if (req->paused) + if (req == NULL || req->paused) return; uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); @@ -413,13 +350,17 @@ void user_request_handler(Response res, Request *req, Client* client) { case sending_eof: ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); req->procedure = none; - build_eof_packet(req->buff, start, req->file); - req->local_entity->EOF_sent_indication = 1; + if (req->file_size == 0) + build_eof_packet(req->buff, start, 0, 0); + else + build_eof_packet(req->buff, start, req->file->total_size, req->file->partial_checksum); + + req->local_entity->EOF_sent_indication = true; ssp_sendto(res); break; case sending_data: - if (req->local_entity->EOF_sent_indication == 1) + if (req->local_entity->EOF_sent_indication == true) return; if (build_data_packet(req->buff, start, req->file, client->packet_len)) { @@ -434,8 +375,8 @@ void user_request_handler(Response res, Request *req, Client* client) { start = build_put_packet_metadata(req->buff, start, req); ssp_sendto(res); - if (req->file == NULL) { - req->procedure = sending_finished; + if (req->file_size == 0 ){ + req->procedure = sending_eof; break; } @@ -443,14 +384,13 @@ void user_request_handler(Response res, Request *req, Client* client) { break; case sending_finished: - ssp_printf("sending finished packet transaction: %d\n", req->transaction_sequence_number); - build_ack(req->buff, start, FINISHED_PDU); - ssp_sendto(res); - req->resent_finished++; + resend_finished_ack(req, res); break; + case sending_start: case clean_up: case none: + break; default: break; } @@ -472,6 +412,76 @@ static void print_offsets(void *element, void *args) { } */ +static void request_eof(Request *req, Response res) { + + ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); + send_nak(req, res, EOF_PDU); +} + +static void request_metadata(Request *req, Response res) { + + ssp_printf("sending request for new metadata packet %d\n", req->transaction_sequence_number); + send_nak(req, res, META_DATA_PDU); +} + +static void request_data(Request *req, Response res) { + + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); + build_nak_packet(req->buff, start, req); + ssp_sendto(res); +} + + +static void resend_finished_pdu(Request *req, Response res) { + + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + ssp_printf("sending finished pdu transaction: %d\n", req->transaction_sequence_number); + build_finished_pdu(req->buff, start); + ssp_sendto(res); + req->resent_finished++; +} + + +//processes the eof packet, sets checksum, indication, and filesize. +void process_pdu_eof(char *packet, Request *req, Response res) { + + Pdu_eof *eof_packet = (Pdu_eof *) packet; + + if (!req->local_entity->Metadata_recv_indication) { + request_metadata(req, res); + } + if (req->file == NULL) { + build_temperary_file(req); + } + + req->local_entity->EOF_recv_indication = 1; + req->file->eof_checksum = eof_packet->checksum; + req->file->total_size = ntohl(eof_packet->file_size); + +} + +int process_file_request_metadata(Request *req) { + + char temp[75]; + + if (req->file == NULL) + req->file = create_file(req->destination_file_name, 1); + + else if (req->file->is_temp) { + snprintf(temp, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); + change_tempfile_to_actual(temp, req->destination_file_name, req->file_size, req->file); + return 1; + } + + Offset *offset = ssp_alloc(1, sizeof(Offset)); + offset->end = req->file_size; + offset->start = 0; + req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); + + return 1; +} + void on_server_time_out(Response res, Request *req) { @@ -502,8 +512,10 @@ void on_server_time_out(Response res, Request *req) { } //receiving just messages, send back finished - if (req->file_size == 0) { - resend_finished_ack(req, res); + if (req->file_size == 0) + { + req->local_entity->transaction_finished_indication = true; + resend_finished_pdu(req, res); return; } @@ -519,9 +531,10 @@ void on_server_time_out(Response res, Request *req) { return; } else { - //finished transaction, + //finished transaction, should have checksum complete, and received eof notification if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity->EOF_recv_indication){ - resend_finished_ack(req, res); + req->local_entity->transaction_finished_indication = true; + resend_finished_pdu(req, res); return; } diff --git a/Program/src/requests.c b/Program/src/requests.c index 564795f..07ae7b1 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -166,6 +166,8 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //build a request req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity->cfdp_id; + req->pdu_header = get_header_from_mib(app->mib, client->remote_entity->cfdp_id, app->my_cfdp_id); + client->request_list->insert(client->request_list, req, 0); return req; From 672fedd125a58ad70c9ab7ceee22944957125800 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 15 Dec 2019 17:00:04 -0700 Subject: [PATCH 150/400] clean up protocl handler --- Program/src/protocol_handler.c | 79 ++++++++++++++++++++++------------ Program/src/requests.c | 5 ++- 2 files changed, 55 insertions(+), 29 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 6b92983..2a05a08 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -243,6 +243,49 @@ static void resend_finished_ack(Request *req, Response res) { req->resent_finished++; } +static void send_put_metadata(Request *req, Response res) { + + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); + ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); + start = build_put_packet_metadata(req->buff, start, req); + ssp_sendto(res); +} + +static void send_eof_pdu(Request *req, Response res) { + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); + ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); + if (req->file_size == 0) + build_eof_packet(req->buff, start, 0, 0); + else + build_eof_packet(req->buff, start, req->file->total_size, req->file->partial_checksum); + + req->local_entity->EOF_sent_indication = true; + ssp_sendto(res); + return; +} + +static void start_sequence(Request *req, Response res) { + send_put_metadata(req, res); + if (req->file_size == 0 ){ + req->procedure = sending_eof; + return; + } + req->procedure = sending_data; +} + +static void send_data(Request *req, Response res) { + if (req->local_entity->EOF_sent_indication == true) + return; + + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); + if (build_data_packet(req->buff, start, req->file, req->packet_data_len)) { + req->procedure = sending_eof; + ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); + } + ssp_sendto(res); +} + + int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; @@ -341,53 +384,35 @@ void user_request_handler(Response res, Request *req, Client* client) { if (req == NULL || req->paused) return; - uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); + //uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req); switch (req->procedure) { case sending_eof: - ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); + send_eof_pdu(req, res); req->procedure = none; - if (req->file_size == 0) - build_eof_packet(req->buff, start, 0, 0); - else - build_eof_packet(req->buff, start, req->file->total_size, req->file->partial_checksum); - - req->local_entity->EOF_sent_indication = true; - ssp_sendto(res); break; case sending_data: - if (req->local_entity->EOF_sent_indication == true) - return; - - if (build_data_packet(req->buff, start, req->file, client->packet_len)) { - req->procedure = sending_eof; - ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); - } - ssp_sendto(res); + send_data(req, res); break; case sending_put_metadata: - ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); - start = build_put_packet_metadata(req->buff, start, req); - ssp_sendto(res); - - if (req->file_size == 0 ){ - req->procedure = sending_eof; - break; - } - - req->procedure = sending_data; + send_put_metadata(req, res); + req->procedure = none; break; case sending_finished: resend_finished_ack(req, res); + req->procedure = none; break; case sending_start: + start_sequence(req, res); + break; + case clean_up: case none: break; diff --git a/Program/src/requests.c b/Program/src/requests.c index 07ae7b1..13a314b 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -167,6 +167,7 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity->cfdp_id; req->pdu_header = get_header_from_mib(app->mib, client->remote_entity->cfdp_id, app->my_cfdp_id); + req->packet_data_len = client->packet_len; client->request_list->insert(client->request_list, req, 0); @@ -190,7 +191,7 @@ Request *put_request( if (source_file_name == NULL || destination_file_name == NULL) { req = start_new_client_request(app, dest_id); - req->procedure = sending_put_metadata; + req->procedure = sending_start; req->transmission_mode = transmission_mode; return req; } @@ -209,7 +210,7 @@ Request *put_request( req->file = create_file(source_file_name, false); req->file_size = file_size; - req->procedure = sending_put_metadata; + req->procedure = sending_start; req->transmission_mode = transmission_mode; memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); From 62b438cdd6745315d42b3052697f5fbf944b3532 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 22 Dec 2019 16:05:20 -0700 Subject: [PATCH 151/400] move process_metadata to own function --- Program/src/filesystem_funcs.c | 2 +- Program/src/protocol_handler.c | 115 ++++++++++++++++++++------------- Program/src/requests.c | 7 +- 3 files changed, 75 insertions(+), 49 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index ca49394..ffe6096 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -271,7 +271,7 @@ static int print_nak(void *element, void* args) { int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file) { - //ssp_printf("renaming %s to: %s", temp, destination_file_name); + ssp_printf("renaming %s to: %s", temp, destination_file_name); ssp_rename(temp, destination_file_name); //file->missing_offsets->print(file->missing_offsets, print_nak, NULL); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2a05a08..234d19a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -131,6 +131,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->remote_entity = get_remote_entity(app->mib, source_id); found_req->procedure = sending_put_metadata; found_req->res.addr = ssp_alloc(1, res.size_of_addr); + memcpy(found_req->res.addr, res.addr, res.size_of_addr); found_req->res.packet_len = app->packet_len; found_req->res.sfd = res.sfd; @@ -265,9 +266,10 @@ static void send_eof_pdu(Request *req, Response res) { } static void start_sequence(Request *req, Response res) { + send_put_metadata(req, res); if (req->file_size == 0 ){ - req->procedure = sending_eof; + req->procedure = none; return; } req->procedure = sending_data; @@ -278,7 +280,8 @@ static void send_data(Request *req, Response res) { return; uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); - if (build_data_packet(req->buff, start, req->file, req->packet_data_len)) { + + if (build_data_packet(req->buff, start, req->file, res.packet_len)) { req->procedure = sending_eof; ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); } @@ -344,10 +347,22 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); break; case ACK_PDU: - if (packet[packet_index] == EOF_PDU) { - ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); - req->local_entity->EOF_recv_indication = true; + + switch (packet[packet_index]) + { + case EOF_PDU: + ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); + req->local_entity->EOF_recv_indication = true; + break; + + case META_DATA_PDU: + ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); + req->local_entity->Metadata_recv_indication = true; + + default: + break; } + break; case NAK_DIRECTIVE: switch (packet[packet_index]) @@ -375,7 +390,7 @@ static void check_req_status(Request *req) { if (req->resent_finished >= RESEND_FINISHED_TIMES){ req->procedure = none; - } + } } //current user request, to send to server @@ -383,8 +398,6 @@ void user_request_handler(Response res, Request *req, Client* client) { if (req == NULL || req->paused) return; - - //uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, client->pdu_header); check_req_status(req); @@ -395,7 +408,7 @@ void user_request_handler(Response res, Request *req, Client* client) { req->procedure = none; break; - case sending_data: + case sending_data: send_data(req, res); break; @@ -413,7 +426,7 @@ void user_request_handler(Response res, Request *req, Client* client) { start_sequence(req, res); break; - case clean_up: + case clean_up: // will close the request happens in the previous functions case none: break; default: @@ -473,10 +486,7 @@ void process_pdu_eof(char *packet, Request *req, Response res) { Pdu_eof *eof_packet = (Pdu_eof *) packet; - if (!req->local_entity->Metadata_recv_indication) { - request_metadata(req, res); - } - if (req->file == NULL) { + if (req->file == NULL && req->local_entity->Metadata_recv_indication) { build_temperary_file(req); } @@ -489,7 +499,6 @@ void process_pdu_eof(char *packet, Request *req, Response res) { int process_file_request_metadata(Request *req) { char temp[75]; - if (req->file == NULL) req->file = create_file(req->destination_file_name, 1); @@ -507,42 +516,71 @@ int process_file_request_metadata(Request *req) { return 1; } +static void process_metadata(char *packet, uint32_t packet_index, Response res, Request *req, FTP *app) { + + req->procedure = sending_put_metadata; + req->local_entity->Metadata_recv_indication = true; + + ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); + packet_index += fill_request_pdu_metadata(&packet[packet_index], req); + + uint16_t data_len = get_data_length(packet); + + get_messages_from_packet(packet, packet_index, data_len, req); + process_messages(req, app); + + send_ack(req, res, META_DATA_PDU); + + if (req->file_size != 0) + process_file_request_metadata(req); + else { + printf("just receiving messages, closing request\n"); + req->local_entity->transaction_finished_indication = true; + req->local_entity->EOF_recv_indication = true; + req->procedure = none; + } +} + + void on_server_time_out(Response res, Request *req) { - if (req->paused || req->procedure == none || req->transmission_mode == UN_ACKNOWLEDGED_MODE) + if (req->paused) return; + if (req->procedure == none || + req->transmission_mode == UN_ACKNOWLEDGED_MODE || + req->local_entity->transaction_finished_indication) + return; - if (req->resent_finished == RESEND_FINISHED_TIMES) { - req->procedure = none; + if (req->resent_finished == RESEND_FINISHED_TIMES && req->local_entity->transaction_finished_indication) { + req->procedure = clean_up; ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); return; } - //send request for metadata if (!req->local_entity->Metadata_recv_indication) { request_metadata(req, res); return; } + //receiving just messages, send back finished + if (req->file_size == 0) { + resend_finished_pdu(req, res); + return; + } + //send missing eofs if (!req->local_entity->EOF_recv_indication) { request_eof(req, res); } + //received EOF, send back 3 eof ack packets else if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { resend_eof_ack(req, res); } - //receiving just messages, send back finished - if (req->file_size == 0) - { - req->local_entity->transaction_finished_indication = true; - resend_finished_pdu(req, res); - return; - } //if have not received metadata for a file tranaction, this should not ever trigger //TODO add asert if (req->file == NULL) { @@ -557,7 +595,7 @@ void on_server_time_out(Response res, Request *req) { } else { //finished transaction, should have checksum complete, and received eof notification - if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity->EOF_recv_indication){ + if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity->EOF_recv_indication) { req->local_entity->transaction_finished_indication = true; resend_finished_pdu(req, res); return; @@ -576,17 +614,18 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ return; Pdu_header *header = (Pdu_header *) packet; - uint16_t data_len = get_data_length(packet); //process file data if (header->PDU_type == 1) { if (!req->local_entity->Metadata_recv_indication) { if (req->file == NULL) { + printf("file is null\n"); build_temperary_file(req); } - request_metadata(req, res); + //request_metadata(req, res); } - write_packet_data_to_file(&packet[packet_index], req->packet_data_len, req->file); + uint16_t data_len = get_data_length(packet); + write_packet_data_to_file(&packet[packet_index], data_len, req->file); return; } @@ -599,26 +638,12 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ case META_DATA_PDU: if (req->local_entity->Metadata_recv_indication) break; - - req->procedure = sending_put_metadata; - ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); - packet_index += fill_request_pdu_metadata(&packet[packet_index], req); - get_messages_from_packet(packet, packet_index, data_len, req); - process_messages(req, app); - - req->local_entity->Metadata_recv_indication = true; - - if (req->file_size != 0) - process_file_request_metadata(req); - + process_metadata(packet, packet_index, res, req, app); break; case EOF_PDU: if (req->local_entity->EOF_recv_indication) break; - - if (!req->local_entity->Metadata_recv_indication) - request_metadata(req, res); ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); process_pdu_eof(&packet[packet_index], req, res); diff --git a/Program/src/requests.c b/Program/src/requests.c index 13a314b..a711807 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -167,7 +167,8 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity->cfdp_id; req->pdu_header = get_header_from_mib(app->mib, client->remote_entity->cfdp_id, app->my_cfdp_id); - req->packet_data_len = client->packet_len; + req->res.packet_len = client->packet_len; + req->packet_data_len = app->packet_len; client->request_list->insert(client->request_list, req, 0); @@ -191,8 +192,8 @@ Request *put_request( if (source_file_name == NULL || destination_file_name == NULL) { req = start_new_client_request(app, dest_id); - req->procedure = sending_start; req->transmission_mode = transmission_mode; + req->procedure = sending_start; return req; } @@ -210,8 +211,8 @@ Request *put_request( req->file = create_file(source_file_name, false); req->file_size = file_size; - req->procedure = sending_start; req->transmission_mode = transmission_mode; + req->procedure = sending_start; memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); From 629e74d6276480d865147bf9bdd6f5b53a764c8a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 22 Dec 2019 16:09:56 -0700 Subject: [PATCH 152/400] change temperary file to include and update size. --- Program/include/filesystem_funcs.h | 2 +- Program/src/filesystem_funcs.c | 8 +++++--- Program/src/protocol_handler.c | 12 ++++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 0c64c77..2473cb2 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -19,6 +19,6 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); uint32_t calc_check_sum(char *data, uint32_t length); uint32_t check_sum_file(File *file, uint16_t stack_buffer); int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end); -File *create_temp_file(char *file_name); +File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); #endif diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index ffe6096..50ca683 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -248,15 +248,16 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs } -File *create_temp_file(char *file_name) { +File *create_temp_file(char *file_name, uint32_t size) { File *file = create_file(file_name, 1); file->is_temp = 1; + file->total_size = size; ssp_printf("mode acknowledged, building offset map\n"); Offset *offset = ssp_alloc(1, sizeof(Offset)); - offset->end = TEMP_FILESIZE; + offset->end = size; offset->start = 0; - file->missing_offsets->insert(file->missing_offsets, offset, TEMP_FILESIZE); + file->missing_offsets->insert(file->missing_offsets, offset, size); return file; } @@ -285,5 +286,6 @@ int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t offset->end = file_size; file->missing_offsets->push(file->missing_offsets, offset, file_size); file->is_temp = 0; + file->total_size = file_size; return 0; } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 234d19a..536ecf5 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -19,11 +19,11 @@ ------------------------------------------------------------------------------*/ -static void build_temperary_file(Request *req) { +static void build_temperary_file(Request *req, uint32_t size) { snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); ssp_printf("haven't received metadata yet, building temperary file %s\n", req->source_file_name); - req->file = create_temp_file(req->source_file_name); + req->file = create_temp_file(req->source_file_name, size); } @@ -485,14 +485,15 @@ static void resend_finished_pdu(Request *req, Response res) { void process_pdu_eof(char *packet, Request *req, Response res) { Pdu_eof *eof_packet = (Pdu_eof *) packet; + uint32_t file_size = ntohl(eof_packet->file_size); if (req->file == NULL && req->local_entity->Metadata_recv_indication) { - build_temperary_file(req); + build_temperary_file(req, file_size); } req->local_entity->EOF_recv_indication = 1; req->file->eof_checksum = eof_packet->checksum; - req->file->total_size = ntohl(eof_packet->file_size); + req->file->total_size = file_size; } @@ -620,9 +621,8 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ if (!req->local_entity->Metadata_recv_indication) { if (req->file == NULL) { printf("file is null\n"); - build_temperary_file(req); + build_temperary_file(req, TEMP_FILESIZE); } - //request_metadata(req, res); } uint16_t data_len = get_data_length(packet); write_packet_data_to_file(&packet[packet_index], data_len, req->file); From 01936bf0eaec87c54f81f6c02732764f00f38a08 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 22 Dec 2019 16:13:24 -0700 Subject: [PATCH 153/400] udpate before merging --- Program/include/config.h | 2 +- Program/include/port.h | 1 - Program/src/main.c | 11 ++++++----- Program/src/protocol_handler.c | 20 ++++++++++++++------ Program/src/tasks.c | 3 +-- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Program/include/config.h b/Program/include/config.h index 396b368..d433022 100644 --- a/Program/include/config.h +++ b/Program/include/config.h @@ -1 +1 @@ -#define TEST \ No newline at end of file +//#define TEST \ No newline at end of file diff --git a/Program/include/port.h b/Program/include/port.h index 4d05e5a..56f121c 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -54,7 +54,6 @@ int ssp_close(int fd); void ssp_free(void *pointer); void ssp_thread_join(void *thread_handle); - //network stuff void ssp_fd_zero(void *socket_set); void ssp_fd_set(int sfd, void *socket_set); diff --git a/Program/src/main.c b/Program/src/main.c index 27dd121..382b193 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -51,16 +51,17 @@ int main(int argc, char** argv) { start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy2.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy3.jpg", ACKNOWLEDGED_MODE, app)); - start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); - */ + //start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); + + Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); start_request(req); - //req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - //add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); - //start_request(req); + req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); + start_request(req); //if (req == NULL) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 536ecf5..83695ac 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -484,6 +484,8 @@ static void resend_finished_pdu(Request *req, Response res) { //processes the eof packet, sets checksum, indication, and filesize. void process_pdu_eof(char *packet, Request *req, Response res) { + + ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); Pdu_eof *eof_packet = (Pdu_eof *) packet; uint32_t file_size = ntohl(eof_packet->file_size); @@ -644,17 +646,23 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ case EOF_PDU: if (req->local_entity->EOF_recv_indication) break; - - ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); process_pdu_eof(&packet[packet_index], req, res); break; case ACK_PDU: ssp_printf("received Ack transaction: %d\n", req->transaction_sequence_number); - Pdu_ack* ack_packet = (Pdu_ack *) &packet[packet_index]; - if (ack_packet->directive_code == FINISHED_PDU) { - ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); - req->local_entity->transaction_finished_indication = true; + Pdu_ack* ack_packet = (Pdu_ack *) &packet[packet_index]; + switch (ack_packet->directive_code) + { + case FINISHED_PDU: + + ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); + req->local_entity->transaction_finished_indication = true; + /* code */ + break; + + default: + break; } break; default: diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 8af318b..ae9c57c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -110,7 +110,7 @@ struct user_request_check_params { }; static void user_request_check(Node *node, void *request, void *args) { - Request * req = (Request *) request; + Request *req = (Request *) request; struct user_request_check_params* params = (struct user_request_check_params *) args; params->res.msg = req->buff; @@ -143,7 +143,6 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi client }; - client->request_list->iterate(client->request_list, user_request_check, ¶ms); if (client->request_list->count == 0) { client->close = true; From 6cf7817d2173fc8c5f91fcb6d9dbbdd320b2fb59 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 1 Jan 2020 14:32:40 -0700 Subject: [PATCH 154/400] fix list iteration, timer only worked on one thread --- Program/include/packet.h | 2 +- Program/include/port.h | 2 +- Program/include/requests.h | 3 +- Program/include/types.h | 2 ++ Program/src/list.c | 5 ++- Program/src/main.c | 36 +++++++++++++++----- Program/src/packet.c | 6 ++-- Program/src/port.c | 19 ++++++++--- Program/src/protocol_handler.c | 13 ++++--- Program/src/requests.c | 62 +++++++++++++++++++++++++++++++++- Program/src/tasks.c | 34 ++++++++++--------- Program/src/utils.c | 1 - 12 files changed, 142 insertions(+), 43 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index f5c06e1..7c9f71f 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -7,7 +7,7 @@ #define PACKET_MAX_LEN 524512 //#define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes -#define PACKET_LEN 256 +#define PACKET_LEN 252 //dont change this #define PACKET_STATIC_HEADER_LEN 4 //in bytes diff --git a/Program/include/port.h b/Program/include/port.h index 56f121c..4ef7501 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -44,6 +44,7 @@ void ssp_sendto(Response res); int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len); void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); +int ssp_time_count(void); int ssp_open(char *pathname, int flags); int ssp_read(int fd, char* buff, size_t size); @@ -66,7 +67,6 @@ void ssp_fd_clr(int sfd, void *socket_set); int ssp_rename(const char *old, const char *new); void reset_request(Request *req); -int ssp_time_count(); #endif \ No newline at end of file diff --git a/Program/include/requests.h b/Program/include/requests.h index 0202291..7970b13 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -22,7 +22,7 @@ int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); - +void print_request_state(Request *req); //Frees a message struct void ssp_free_message(void *params); LV *create_lv(int size, void *value); @@ -30,5 +30,6 @@ uint16_t copy_lv_to_buffer(char *buffer, LV *lv); LV *copy_lv_from_buffer(char *packet, uint32_t start); Message *create_message(uint8_t type); void free_lv(LV *lv); +void print_request_procedure(Request *req); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index f5f596c..77b982a 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -461,6 +461,8 @@ typedef struct local_entity { unsigned int Metadata_recv_indication: 1; + unsigned int Metadata_sent_indication: 1; + //function pointer to default handler? void *default_fault_handler; diff --git a/Program/src/list.c b/Program/src/list.c index 0084882..1dd91a5 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -111,9 +111,11 @@ static int push(List *list, void *element, uint32_t id) static void iterate(List *list, void (*f)(Node *node, void *element, void *args), void *args) { + + Node *cur = list->head->next; Node *next; - while (cur->next != NULL) + while (cur->next != NULL && cur != list->tail) { next = cur->next; f(cur, cur->element, args); @@ -124,6 +126,7 @@ static void iterate(List *list, void (*f)(Node *node, void *element, void *args) //deletes the node, and returns the object, (motifys the list) static void *removeNode(List *list, Node *node) { + Node *previous = node->prev; Node *next = node->next; diff --git a/Program/src/main.c b/Program/src/main.c index 382b193..010c282 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -47,14 +47,14 @@ int main(int argc, char** argv) { //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - /* + start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy2.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy3.jpg", ACKNOWLEDGED_MODE, app)); - */ + //start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); - + /* Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); start_request(req); @@ -63,12 +63,32 @@ int main(int argc, char** argv) { add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); start_request(req); - - //if (req == NULL) - // return -1; - //add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); - //start_request(req); + req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy3.jpg", req); + start_request(req); +/* + req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy4.jpg", req); + start_request(req); + + req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy5.jpg", req); + start_request(req); +/* + + Request *req; + for (int i=0; i < 10; i++) { + sleep(10); + req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + char filename[11] = {'p','r','o','x','y', (char) (48+i), '.', 'j', 'p', 'g', '\0'}; + + + add_proxy_message_to_request(2, 1, "pic.jpeg", filename, req); + start_request(req); + + } +*/ } diff --git a/Program/src/packet.c b/Program/src/packet.c index 232e584..5deca46 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -166,11 +166,11 @@ uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Reques //length is the total size of the packet uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { - if (file->next_offset_to_send > file->total_size){ - ssp_error("cant send an offset past the file's length\n"); - return 1; + if (file->next_offset_to_send >= file->total_size){ + return 0; } + Pdu_header *header = (Pdu_header *) packet; //set header to file directive 0 is directive, 1 is data header->PDU_type = 1; diff --git a/Program/src/port.c b/Program/src/port.c index 522be48..135dbae 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -250,7 +250,10 @@ void *ssp_init_sockaddr_struct(size_t *size_of_addr) { void *ssp_alloc(uint32_t n_memb, size_t size) { #ifdef POSIX_PORT - return calloc(n_memb, size); + void *mem = calloc(n_memb, size); + if (mem == NULL) + ssp_printf("Memory failed to alloc!\n"); + return mem; #endif #ifdef FREE_RTOS_PORT @@ -289,16 +292,22 @@ void ssp_printf( char *stuff, ...) { - +//returns seconds elapsed int ssp_time_count() { #ifdef POSIX_PORT - clock_t c = clock(); - c = c / CLOCKS_PER_SEC; - return c; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + //clock_t c = clock(); + //c = c / CLOCKS_PER_SEC; + return ts.tv_sec; #endif + + + + #ifdef FREE_RTOS_PORT //some kind of ticks #endif diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 83695ac..a87e04a 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -141,9 +141,15 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r request_list->push(request_list, found_req, transaction_sequence_number); } + else if (found_req == NULL) { + ssp_printf("could not find request \n"); + return -1; + } + found_req->packet_data_len = len; *req = found_req; + return packet_index; } @@ -249,6 +255,7 @@ static void send_put_metadata(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(req->buff, start, req); + req->local_entity->Metadata_sent_indication = true; ssp_sendto(res); } @@ -275,10 +282,7 @@ static void start_sequence(Request *req, Response res) { req->procedure = sending_data; } -static void send_data(Request *req, Response res) { - if (req->local_entity->EOF_sent_indication == true) - return; - +static void send_data(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); if (build_data_packet(req->buff, start, req->file, res.packet_len)) { @@ -342,7 +346,6 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ ssp_printf("received finished pdu transaction: %d\n", req->transaction_sequence_number); break; case NAK_PDU: - req->local_entity->Metadata_recv_indication = true; nak_response(packet, packet_index, req, res, client); ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); break; diff --git a/Program/src/requests.c b/Program/src/requests.c index a711807..2d58603 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -138,7 +138,8 @@ Request *init_request(uint32_t buff_len) { req->procedure = none; req->paused = true; - + reset_timeout(&req->timeout); + req->res.msg = req->buff; req->messages_to_user = linked_list(); @@ -156,9 +157,13 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //spin up a new client thread Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); + if (client == NULL) { + ssp_printf("Spinning up a new client thread\n"); client = ssp_client(dest_id, app); app->active_clients->insert(app->active_clients, client, dest_id); + } else { + ssp_printf("adding request to existing client thread\n"); } Request *req = init_request(client->packet_len); @@ -190,6 +195,7 @@ Request *put_request( Request *req; uint32_t file_size = 0; + ssp_printf("trying to start new request\n"); if (source_file_name == NULL || destination_file_name == NULL) { req = start_new_client_request(app, dest_id); req->transmission_mode = transmission_mode; @@ -248,3 +254,57 @@ int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, } +void print_request_state(Request *req) { + + ssp_printf("----------------Transaction %d---------------\n", req->transaction_sequence_number); + ssp_printf("local_entity stats: \n"); + ssp_printf("EOF_recv indication %d\n", req->local_entity->EOF_recv_indication); + ssp_printf("EOF_sent indication %d\n", req->local_entity->EOF_sent_indication); + ssp_printf("Metadata_recv indication %d\n", req->local_entity->Metadata_recv_indication); + ssp_printf("Metadata_sent indication %d\n", req->local_entity->Metadata_sent_indication); + + ssp_printf("Resume indication %d\n", req->local_entity->resumed_indication); + ssp_printf("Suspended indication %d\n", req->local_entity->suspended_indication); + ssp_printf("Transaction finished indication %d\n", req->local_entity->transaction_finished_indication); + print_request_procedure(req); + ssp_printf("---------------------------------------------\n"); +} + + +void print_request_procedure(Request *req){ + + ssp_printf("current procedure: "); + switch (req->procedure) + { + case sending_eof: + ssp_printf("sending_eof\n"); + break; + + case sending_data: + ssp_printf("sending_data\n"); + break; + + case sending_put_metadata: + ssp_printf("sending_put_metadata\n"); + break; + + case sending_finished: + ssp_printf("sending_finished\n"); + break; + + case sending_start: + ssp_printf("sending_start\n"); + break; + + case clean_up: // will close the request happens in the previous functions + ssp_printf("clean_up\n"); + break; + + case none: + ssp_printf("none\n"); + break; + + default: + break; + } +} \ No newline at end of file diff --git a/Program/src/tasks.c b/Program/src/tasks.c index ae9c57c..2c039e0 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -12,6 +12,9 @@ #include "types.h" #include "utils.h" #include + +//for print_request_state +#include "requests.h" /*------------------------------------------------------------------------------ Callbacks for the tasks bellow @@ -23,10 +26,11 @@ static void timeout(Request *req) { bool is_timeout = check_timeout(&req->timeout, TIMEOUT_BEFORE_CANCEL_REQUEST); if (is_timeout) { - if (req->procedure != none) - ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); - else { + if (req->local_entity->transaction_finished_indication){ ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); + } else { + ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); + print_request_state(req); } req->procedure = clean_up; } @@ -96,7 +100,8 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u void remove_request_check(Node *node, void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; - + //print_request_procedure(req); + if (req->procedure == clean_up) { ssp_printf("removing request\n"); Request *remove_this = req_list->removeNode(req_list, node); @@ -117,7 +122,6 @@ static void user_request_check(Node *node, void *request, void *args) { memset(params->res.msg, 0, params->client->packet_len); user_request_handler(params->res, req, params->client); - timeout(req); remove_request_check(node, request, params->client->request_list); @@ -153,12 +157,10 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi -static void timeout_check_callback(Node *node, void *request, void *args) { +static void timeout_check_callback_server(Node *node, void *request, void *args) { Request *req = (Request *) request; on_server_time_out(req->res, req); - timeout(req); - remove_request_check(node, request, args); } @@ -166,7 +168,7 @@ static void timeout_check_callback(Node *node, void *request, void *args) { static void client_check_callback(Node *node, void *client, void *args) { Client *c = (Client *) client; List *list = (List *) args; - + //printf("checking client\n"); if (c->close) { Client *remove_this = (Client *) list->removeNode(list, node); ssp_printf("removing client, from server \n"); @@ -176,14 +178,14 @@ static void client_check_callback(Node *node, void *client, void *args) { } -//this function is a callback when using my posix ports -static int on_time_out_callback(void *other) { +//this function is a callback for servers +static int on_time_out_callback_server(void *other) { FTP *app = (FTP*) other; if(app->current_request == NULL) return 0; - app->request_list->iterate(app->request_list, timeout_check_callback, app->request_list); + app->request_list->iterate(app->request_list, timeout_check_callback_server, app->request_list); app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); return 0; @@ -270,7 +272,7 @@ void *ssp_connectionless_server_task(void *params) { connectionless_server(port, app->packet_len, on_recv_server_callback, - on_time_out_callback, + on_time_out_callback_server, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, @@ -321,7 +323,7 @@ void *ssp_connection_server_task(void *params) { app->packet_len, 10, on_recv_server_callback, - on_time_out_callback, + on_time_out_callback_server, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, @@ -365,7 +367,7 @@ void *ssp_csp_connectionless_server_task(void *params) { csp_connectionless_server( app->remote_entity->UT_port, on_recv_server_callback, - on_time_out_callback, + on_time_out_callback_server, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, @@ -397,7 +399,7 @@ void *ssp_csp_connection_server_task(void *params) { csp_connection_server(app->remote_entity->UT_port, on_recv_server_callback, - on_time_out_callback, + on_time_out_callback_server, on_stdin_callback, check_exit_server_callback, on_exit_server_callback, diff --git a/Program/src/utils.c b/Program/src/utils.c index 4145d29..5ec417f 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -18,7 +18,6 @@ to use for general functionality. #include "port.h" - #define MAX_LEN 255 #define ID_LEN 10 From c2eb68dad8225a333438c8840bf93ff1a39527be Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 2 Jan 2020 19:50:10 -0700 Subject: [PATCH 155/400] omg, it actually works --- Program/src/list.c | 2 -- Program/src/main.c | 13 ++++++------- Program/src/tasks.c | 21 ++++++++++----------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Program/src/list.c b/Program/src/list.c index 1dd91a5..25cf83c 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -111,8 +111,6 @@ static int push(List *list, void *element, uint32_t id) static void iterate(List *list, void (*f)(Node *node, void *element, void *args), void *args) { - - Node *cur = list->head->next; Node *next; while (cur->next != NULL && cur != list->tail) diff --git a/Program/src/main.c b/Program/src/main.c index 010c282..8c6427a 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -45,16 +45,15 @@ int main(int argc, char** argv) { //create a client if (conf->client_cfdp_id != 0){ - //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - + /* start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy2.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy3.jpg", ACKNOWLEDGED_MODE, app)); - + */ //start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); - /* + Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); start_request(req); @@ -75,9 +74,9 @@ int main(int argc, char** argv) { req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy5.jpg", req); start_request(req); -/* +*/ - Request *req; + //Request *req; for (int i=0; i < 10; i++) { sleep(10); req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); @@ -88,7 +87,7 @@ int main(int argc, char** argv) { start_request(req); } -*/ + } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 2c039e0..55af903 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -131,7 +131,9 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi Response res; Client *client = (Client *) other; + if (client->request_list->count == 0){ + client->close = true; return 0; } @@ -147,11 +149,7 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi client }; - client->request_list->iterate(client->request_list, user_request_check, ¶ms); - if (client->request_list->count == 0) { - client->close = true; - } - + client->request_list->iterate(client->request_list, user_request_check, ¶ms); return 0; } @@ -168,7 +166,6 @@ static void timeout_check_callback_server(Node *node, void *request, void *args) static void client_check_callback(Node *node, void *client, void *args) { Client *c = (Client *) client; List *list = (List *) args; - //printf("checking client\n"); if (c->close) { Client *remove_this = (Client *) list->removeNode(list, node); ssp_printf("removing client, from server \n"); @@ -182,12 +179,14 @@ static void client_check_callback(Node *node, void *client, void *args) { static int on_time_out_callback_server(void *other) { FTP *app = (FTP*) other; - if(app->current_request == NULL) - return 0; - app->request_list->iterate(app->request_list, timeout_check_callback_server, app->request_list); - app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); - + if (app->active_clients->count) { + app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); + } + if (app->request_list->count) { + app->request_list->iterate(app->request_list, timeout_check_callback_server, app->request_list); + } + return 0; } From 200c9b7ffb2c352a0579a3c4fcb6d403700d603f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 2 Jan 2020 20:32:44 -0700 Subject: [PATCH 156/400] Fix invalid read, (realy need to clean up parse_pdu_header) --- Program/src/protocol_handler.c | 6 +++--- Program/src/tasks.c | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index a87e04a..84d847e 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -103,11 +103,14 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r Request *request = *req; + //if packet is from the same request, don't' change current request + /* if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ (*req)->packet_data_len = len; return packet_index; } + */ //look for active request in list struct request_search_params params = { @@ -126,7 +129,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->transmission_mode = header->transmission_mode; found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; - found_req->transaction_sequence_number = transaction_sequence_number; found_req->pdu_header = get_header_from_mib(app->mib, source_id, app->my_cfdp_id); found_req->remote_entity = get_remote_entity(app->mib, source_id); found_req->procedure = sending_put_metadata; @@ -148,8 +150,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->packet_data_len = len; *req = found_req; - - return packet_index; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 55af903..62ec6ae 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -53,8 +53,10 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, Request *current_request = (*request_container); app->current_request = current_request; - if (packet_index < 0) + if (packet_index < 0) { + ssp_printf("error parsing header\n"); return -1; + } parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); From 3d3683be75a5df002fcc26d696578ee5d66cad5e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 5 Jan 2020 13:16:27 -0700 Subject: [PATCH 157/400] Change local entity, not mallocing for it --- Program/include/port.h | 3 -- Program/include/types.h | 9 ++-- Program/src/protocol_handler.c | 83 +++++++++++++++++++++++++--------- Program/src/requests.c | 83 ++++++++++++++++++++++++++-------- Program/src/tasks.c | 2 +- 5 files changed, 131 insertions(+), 49 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 4ef7501..8481fda 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -14,8 +14,6 @@ #define CSP_NETWORK //#define FREE_RTOS_PORT - -#define MAX_PATH 255 #include "types.h" @@ -37,7 +35,6 @@ void ssp_error( char *msg); void ssp_printf(char *stuff, ...); -Request *init_request(uint32_t buff_len); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); diff --git a/Program/include/types.h b/Program/include/types.h index 77b982a..60f79b3 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -8,7 +8,7 @@ #include - +#define MAX_PATH 255 #define ACKNOWLEDGED_MODE 0 #define UN_ACKNOWLEDGED_MODE 1 /*----------------------------------------------------------------------------- @@ -575,8 +575,8 @@ typedef struct request { File *file; uint32_t file_size; - char *source_file_name; - char *destination_file_name; + char source_file_name[MAX_PATH]; + char destination_file_name[MAX_PATH]; uint32_t packet_data_len; @@ -598,7 +598,7 @@ typedef struct request { // uint8_t sent_first_data_round; Remote_entity *remote_entity; - Local_entity *local_entity; + Local_entity local_entity; List *messages_to_user; @@ -649,6 +649,7 @@ typedef struct client { void *client_handle; //the maximum size of the packet uint32_t packet_len; + uint32_t cfdp_id; Request *current_request; List *request_list; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 84d847e..e7b04bd 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -73,6 +73,46 @@ static int find_request(void *element, void *args) { } +//------------------------------------TODO------------------------------------------ +Request *parse_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app) { + + uint8_t packet_index = PACKET_STATIC_HEADER_LEN; + Pdu_header *header = (Pdu_header *) packet; + + uint32_t source_id = 0; + memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); + packet_index += header->length_of_entity_IDs; + + uint32_t transaction_sequence_number = 0; + memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); + packet_index += header->transaction_seq_num_len; + + uint32_t dest_id = 0; + memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); + packet_index += header->length_of_entity_IDs; + + if (app->my_cfdp_id != dest_id){ + ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); + return -1; + } + + struct request_search_params params = { + source_id, + transaction_sequence_number, + }; + + Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); + return found_req; +} + + + + + + +//------------------------------------------------------------------------------ + + /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns -1 on fail*/ @@ -124,6 +164,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r if (found_req == NULL && is_server) { found_req = init_request(app->packet_len); + ssp_printf("incoming new request\n"); //Make new request and add it found_req->transmission_mode = header->transmission_mode; @@ -255,7 +296,7 @@ static void send_put_metadata(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(req->buff, start, req); - req->local_entity->Metadata_sent_indication = true; + req->local_entity.Metadata_sent_indication = true; ssp_sendto(res); } @@ -267,7 +308,7 @@ static void send_eof_pdu(Request *req, Response res) { else build_eof_packet(req->buff, start, req->file->total_size, req->file->partial_checksum); - req->local_entity->EOF_sent_indication = true; + req->local_entity.EOF_sent_indication = true; ssp_sendto(res); return; } @@ -341,7 +382,7 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch(directive) { case FINISHED_PDU: - req->local_entity->transaction_finished_indication = true; + req->local_entity.transaction_finished_indication = true; req->procedure = sending_finished; ssp_printf("received finished pdu transaction: %d\n", req->transaction_sequence_number); break; @@ -355,12 +396,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ { case EOF_PDU: ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); - req->local_entity->EOF_recv_indication = true; + req->local_entity.EOF_recv_indication = true; break; case META_DATA_PDU: ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); - req->local_entity->Metadata_recv_indication = true; + req->local_entity.Metadata_recv_indication = true; default: break; @@ -492,11 +533,11 @@ void process_pdu_eof(char *packet, Request *req, Response res) { Pdu_eof *eof_packet = (Pdu_eof *) packet; uint32_t file_size = ntohl(eof_packet->file_size); - if (req->file == NULL && req->local_entity->Metadata_recv_indication) { + if (req->file == NULL && req->local_entity.Metadata_recv_indication) { build_temperary_file(req, file_size); } - req->local_entity->EOF_recv_indication = 1; + req->local_entity.EOF_recv_indication = 1; req->file->eof_checksum = eof_packet->checksum; req->file->total_size = file_size; @@ -525,7 +566,7 @@ int process_file_request_metadata(Request *req) { static void process_metadata(char *packet, uint32_t packet_index, Response res, Request *req, FTP *app) { req->procedure = sending_put_metadata; - req->local_entity->Metadata_recv_indication = true; + req->local_entity.Metadata_recv_indication = true; ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); packet_index += fill_request_pdu_metadata(&packet[packet_index], req); @@ -541,8 +582,8 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, process_file_request_metadata(req); else { printf("just receiving messages, closing request\n"); - req->local_entity->transaction_finished_indication = true; - req->local_entity->EOF_recv_indication = true; + req->local_entity.transaction_finished_indication = true; + req->local_entity.EOF_recv_indication = true; req->procedure = none; } } @@ -556,17 +597,17 @@ void on_server_time_out(Response res, Request *req) { if (req->procedure == none || req->transmission_mode == UN_ACKNOWLEDGED_MODE || - req->local_entity->transaction_finished_indication) + req->local_entity.transaction_finished_indication) return; - if (req->resent_finished == RESEND_FINISHED_TIMES && req->local_entity->transaction_finished_indication) { + if (req->resent_finished == RESEND_FINISHED_TIMES && req->local_entity.transaction_finished_indication) { req->procedure = clean_up; ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); return; } //send request for metadata - if (!req->local_entity->Metadata_recv_indication) { + if (!req->local_entity.Metadata_recv_indication) { request_metadata(req, res); return; } @@ -578,12 +619,12 @@ void on_server_time_out(Response res, Request *req) { } //send missing eofs - if (!req->local_entity->EOF_recv_indication) { + if (!req->local_entity.EOF_recv_indication) { request_eof(req, res); } //received EOF, send back 3 eof ack packets - else if (req->local_entity->EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { + else if (req->local_entity.EOF_recv_indication && req->resent_eof < RESEND_EOF_TIMES) { resend_eof_ack(req, res); } @@ -601,8 +642,8 @@ void on_server_time_out(Response res, Request *req) { } else { //finished transaction, should have checksum complete, and received eof notification - if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity->EOF_recv_indication) { - req->local_entity->transaction_finished_indication = true; + if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity.EOF_recv_indication) { + req->local_entity.transaction_finished_indication = true; resend_finished_pdu(req, res); return; } @@ -623,7 +664,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ //process file data if (header->PDU_type == 1) { - if (!req->local_entity->Metadata_recv_indication) { + if (!req->local_entity.Metadata_recv_indication) { if (req->file == NULL) { printf("file is null\n"); build_temperary_file(req, TEMP_FILESIZE); @@ -641,13 +682,13 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ switch (directive->directive_code) { case META_DATA_PDU: - if (req->local_entity->Metadata_recv_indication) + if (req->local_entity.Metadata_recv_indication) break; process_metadata(packet, packet_index, res, req, app); break; case EOF_PDU: - if (req->local_entity->EOF_recv_indication) + if (req->local_entity.EOF_recv_indication) break; process_pdu_eof(&packet[packet_index], req, res); break; @@ -660,7 +701,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ case FINISHED_PDU: ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); - req->local_entity->transaction_finished_indication = true; + req->local_entity.transaction_finished_indication = true; /* code */ break; diff --git a/Program/src/requests.c b/Program/src/requests.c index 2d58603..9185438 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -99,16 +99,10 @@ void ssp_cleanup_req(void *request) { free_file(req->file); if (req->pdu_header != NULL) ssp_cleanup_pdu_header(req->pdu_header); - if (req->source_file_name != NULL) - ssp_free(req->source_file_name); - if (req->destination_file_name != NULL) - ssp_free(req->destination_file_name); if (req->buff != NULL) ssp_free(req->buff); if (req->res.addr != NULL) ssp_free(req->res.addr); - if (req->local_entity != NULL) - ssp_free(req->local_entity); if (req->messages_to_user->count > 0) req->messages_to_user->free(req->messages_to_user, ssp_free_message); @@ -121,17 +115,14 @@ void ssp_cleanup_req(void *request) { } -Request *init_request(uint32_t buff_len) { - Request *req = ssp_alloc(1, sizeof(Request)); - req->source_file_name = ssp_alloc(MAX_PATH, sizeof(char)); - checkAlloc(req->source_file_name, 1); - req->destination_file_name = ssp_alloc(MAX_PATH, sizeof(char)); - checkAlloc(req->destination_file_name, 1); - req->local_entity = ssp_alloc(1, sizeof(Local_entity)); +Request *init_request(uint32_t buff_len) { + + Request *req = ssp_alloc(1, sizeof(Request)); + req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); @@ -143,7 +134,59 @@ Request *init_request(uint32_t buff_len) { req->res.msg = req->buff; req->messages_to_user = linked_list(); + + checkAlloc(req->buff, 1); + return req; +} + + +Request *init_request_2(uint32_t buff_len, uint32_t transaction_id, Client *client) { + + + Request *req = ssp_alloc(1, sizeof(Request)); + checkAlloc(req, 1); + + + req->pdu_header = client->pdu_header; + req->remote_entity = client->remote_entity; + + req->file = NULL; + req->buff_len = buff_len; + + req->buff = ssp_alloc(buff_len, sizeof(char)); checkAlloc(req->buff, 1); + + req->dest_cfdp_id = client->remote_entity->cfdp_id; + req->transaction_sequence_number = transaction_id; + + req->procedure = none; + req->paused = true; + reset_timeout(&req->timeout); + + req->res.msg = req->buff; + + req->messages_to_user = linked_list(); + checkAlloc(req->messages_to_user, 1); + + + //using the hosts network transfer, should switch to client configuration + /* + req->transmission_mode = header->transmission_mode; + req->transaction_sequence_number = transaction_sequence_number; + req->dest_cfdp_id = source_id; + + req->res.transmission_mode = app->remote_entity->default_transmission_mode; + req->res.type_of_network = app->remote_entity->type_of_network; + req->res.packet_len = app->packet_len; + req->res.sfd = res.sfd; + req->res.addr = ssp_alloc(1, res.size_of_addr); + + memcpy(found_req->res.addr, res.addr, res.size_of_addr); + */ + + //req->paused = false; + //req->procedure = sending_put_metadata; + return req; } @@ -258,14 +301,14 @@ void print_request_state(Request *req) { ssp_printf("----------------Transaction %d---------------\n", req->transaction_sequence_number); ssp_printf("local_entity stats: \n"); - ssp_printf("EOF_recv indication %d\n", req->local_entity->EOF_recv_indication); - ssp_printf("EOF_sent indication %d\n", req->local_entity->EOF_sent_indication); - ssp_printf("Metadata_recv indication %d\n", req->local_entity->Metadata_recv_indication); - ssp_printf("Metadata_sent indication %d\n", req->local_entity->Metadata_sent_indication); + ssp_printf("EOF_recv indication %d\n", req->local_entity.EOF_recv_indication); + ssp_printf("EOF_sent indication %d\n", req->local_entity.EOF_sent_indication); + ssp_printf("Metadata_recv indication %d\n", req->local_entity.Metadata_recv_indication); + ssp_printf("Metadata_sent indication %d\n", req->local_entity.Metadata_sent_indication); - ssp_printf("Resume indication %d\n", req->local_entity->resumed_indication); - ssp_printf("Suspended indication %d\n", req->local_entity->suspended_indication); - ssp_printf("Transaction finished indication %d\n", req->local_entity->transaction_finished_indication); + ssp_printf("Resume indication %d\n", req->local_entity.resumed_indication); + ssp_printf("Suspended indication %d\n", req->local_entity.suspended_indication); + ssp_printf("Transaction finished indication %d\n", req->local_entity.transaction_finished_indication); print_request_procedure(req); ssp_printf("---------------------------------------------\n"); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 62ec6ae..ebd3a7d 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -26,7 +26,7 @@ static void timeout(Request *req) { bool is_timeout = check_timeout(&req->timeout, TIMEOUT_BEFORE_CANCEL_REQUEST); if (is_timeout) { - if (req->local_entity->transaction_finished_indication){ + if (req->local_entity.transaction_finished_indication){ ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); } else { ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); From 6d93d0244e8a9663ec0fc21fddf2239ef063cf54 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 11 Jan 2020 14:26:32 -0700 Subject: [PATCH 158/400] add json parser --- Program/include/filesystem_funcs.h | 2 + Program/include/jsmn.h | 471 +++++++++++++++++++++++++++++ Program/src/file_delivery_app.c | 2 +- Program/src/filesystem_funcs.c | 53 +++- Program/src/requests.c | 31 +- Program/test/dest.jpg | Bin 150033 -> 0 bytes Program/test/filesystem_tests.c | 32 +- Program/test/main.c | 6 +- Program/test/makefile | 10 +- Program/test/mib.json | 3 + Program/test/unit_tests.h | 2 +- 11 files changed, 575 insertions(+), 37 deletions(-) create mode 100644 Program/include/jsmn.h delete mode 100644 Program/test/dest.jpg create mode 100644 Program/test/mib.json diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 2473cb2..9ef8529 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -21,4 +21,6 @@ uint32_t check_sum_file(File *file, uint16_t stack_buffer); int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end); File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); +int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); + #endif diff --git a/Program/include/jsmn.h b/Program/include/jsmn.h new file mode 100644 index 0000000..cb27ca1 --- /dev/null +++ b/Program/include/jsmn.h @@ -0,0 +1,471 @@ +/* + * MIT License + * + * Copyright (c) 2010 Serge Zaitsev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef JSMN_H +#define JSMN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef JSMN_STATIC +#define JSMN_API static +#else +#define JSMN_API extern +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +/** + * JSON token description. + * type type (object, array, string etc.) + * start start position in JSON data string + * end end position in JSON data string + */ +typedef struct { + jsmntype_t type; + int start; + int end; + int size; +#ifdef JSMN_PARENT_LINKS + int parent; +#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string. + */ +typedef struct { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g. parent object or array */ +} jsmn_parser; + +/** + * Create JSON parser over an array of tokens + */ +JSMN_API void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each + * describing + * a single JSON object. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens); + +#ifndef JSMN_HEADER +/** + * Allocates a fresh unused token from the token pool. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type, + const int start, const int end) { + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t': + case '\r': + case '\n': + case ' ': + case ',': + case ']': + case '}': + goto found; + default: + /* to quiet a warning from gcc*/ + break; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + parser->pos++; + + /* Skip starting quote */ + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + + /* Quote: end of string */ + if (c == '\"') { + if (tokens == NULL) { + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': + case '/': + case '\\': + case 'b': + case 'f': + case 'r': + case 'n': + case 't': + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; + i++) { + /* If it isn't a hex character we have an error */ + if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; + switch (c) { + case '{': + case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + return JSMN_ERROR_NOMEM; + } + if (parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; +#ifdef JSMN_STRICT + /* In strict mode an object or array can't become a key */ + if (t->type == JSMN_OBJECT) { + return JSMN_ERROR_INVAL; + } +#endif + t->size++; +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': + case ']': + if (tokens == NULL) { + break; + } + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + if (token->type != type || parser->toksuper == -1) { + return JSMN_ERROR_INVAL; + } + break; + } + token = &tokens[token->parent]; + } +#else + for (i = parser->toknext - 1; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + parser->toksuper = -1; + token->end = parser->pos + 1; + break; + } + } + /* Error if unmatched closing bracket */ + if (i == -1) { + return JSMN_ERROR_INVAL; + } + for (; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + parser->toksuper = i; + break; + } + } +#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + case '\t': + case '\r': + case '\n': + case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +#else + for (i = parser->toknext - 1; i >= 0; i--) { + if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { + if (tokens[i].start != -1 && tokens[i].end == -1) { + parser->toksuper = i; + break; + } + } + } +#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 't': + case 'f': + case 'n': + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + const jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +JSMN_API void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +#endif /* JSMN_HEADER */ + +#ifdef __cplusplus +} +#endif + +#endif /* JSMN_H */ diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index bc30be4..b78b036 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -97,7 +97,7 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { client->packet_len = PACKET_LEN; Remote_entity *remote = get_remote_entity(app->mib, cfdp_id); - + if (remote == NULL) ssp_printf("couldn't find entity in Remote_entity list\n"); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 50ca683..cb0ddd5 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -7,7 +7,7 @@ #include "utils.h" #include "string.h" #include "list.h" - +#include "jsmn.h" uint32_t get_file_size(char *source_file_name) { @@ -289,3 +289,54 @@ int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file->total_size = file_size; return 0; } + +int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params) { + + jsmn_parser p; + int number_of_tokens = 255; + jsmntok_t tok[number_of_tokens]; + + jsmn_init(&p); + + uint32_t total_size = get_file_size(file_name); + if (total_size == 0){ + ssp_error("couldn't get file size\n"); + return 1; + } + + char buff[total_size]; + + int fd = ssp_open(file_name, O_RDWR); + + int r = read(fd, buff, sizeof(buff)); + if (r < 0) { + ssp_error("read failed\n"); + return 1; + } + + r = jsmn_parse(&p, buff, total_size, tok, number_of_tokens); + if (r < 0) { + ssp_error("Failed to parse JSON\n"); + return 1; + } + + for (int i = 1; i < r; i++) { + + + int key_size = tok[i].end - tok[i].start; + int value_size = tok[i+1].end - tok[i+1].start; + + char key[key_size + 1]; + key[key_size] = '\0'; + strncpy(key, &buff[tok[i].start], key_size); + + char value[value_size + 1]; + value[value_size] = '\0'; + strncpy(value, &buff[tok[i+1].start], value_size); + + callback(key, value, params); + i++; + + } + return 0; +} \ No newline at end of file diff --git a/Program/src/requests.c b/Program/src/requests.c index 9185438..c92eb10 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -140,48 +140,39 @@ Request *init_request(uint32_t buff_len) { } -Request *init_request_2(uint32_t buff_len, uint32_t transaction_id, Client *client) { - +Request *init_request_2(uint32_t buff_len, uint32_t transaction_id, Pdu_header *pdu_header, Remote_entity *remote_entity) { Request *req = ssp_alloc(1, sizeof(Request)); checkAlloc(req, 1); - req->pdu_header = client->pdu_header; - req->remote_entity = client->remote_entity; - + req->pdu_header = pdu_header; + req->remote_entity = remote_entity; req->file = NULL; req->buff_len = buff_len; + req->dest_cfdp_id = remote_entity->cfdp_id; + req->transaction_sequence_number = transaction_id; + req->procedure = none; + req->paused = true; req->buff = ssp_alloc(buff_len, sizeof(char)); checkAlloc(req->buff, 1); - req->dest_cfdp_id = client->remote_entity->cfdp_id; - req->transaction_sequence_number = transaction_id; - - req->procedure = none; - req->paused = true; reset_timeout(&req->timeout); req->res.msg = req->buff; req->messages_to_user = linked_list(); checkAlloc(req->messages_to_user, 1); + req->res.transmission_mode = remote_entity->default_transmission_mode; + req->res.type_of_network = remote_entity->type_of_network; + req->res.packet_len = buff_len; + //req->res.addr = remote_entity->UT_address; //using the hosts network transfer, should switch to client configuration /* - req->transmission_mode = header->transmission_mode; - req->transaction_sequence_number = transaction_sequence_number; - req->dest_cfdp_id = source_id; - - req->res.transmission_mode = app->remote_entity->default_transmission_mode; - req->res.type_of_network = app->remote_entity->type_of_network; - req->res.packet_len = app->packet_len; req->res.sfd = res.sfd; - req->res.addr = ssp_alloc(1, res.size_of_addr); - - memcpy(found_req->res.addr, res.addr, res.size_of_addr); */ //req->paused = false; diff --git a/Program/test/dest.jpg b/Program/test/dest.jpg deleted file mode 100644 index b379f5cb9915b4b8e6ed4884534df91197fe50d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150033 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%0Aud#$a{ zkRch~+8Cj=ikFE5nlK*>QBv$8%- z?PJ6U#$l9VjAms|Yh7|oVut%R)G!xJ#Y>x{sT~8pQD}yyiysuBIlrL!^N7k-<3AMJ zUKc(SG?MD@7z2c071oE}R`N!kMA_;BPynm-xZef+Jj8aEM4p^#L&83N8Gc-|m2;Y4 z2k{Db`E;O106Hz$0i|dj^ayWhZ>GDXj=UEiO){`|MGoJ;_GB=!oGI`tRTOT=EDIR* zd^#(~b!(A0;Cdzig$s8S`M%YEiq*2Mn&2-BGQ#m#~4nF_d8LQ%YLaJ*`qt zbY1qcgunyaecT;kDT6kPU)z@nXP@@}CE%qYMCx)#Vt!7J}h*t1fL8 z@#K|=nEPj;UDswe)g?zR!yE!b`+4`&;h1jbrPYl|s9(Zlub|iYXVT#>v0*XX67HsC zUB#++Uf=n$qhqRzixz7-6|i25q9tIq30$dSDi=e`PMjhKN@Z2;NNazId9{o|JR7bK zL>L=?rElX2Ha2{eSbW?l^ZyT}Bg^kZv$cNtoTTpO$)6Au8)0p-XJgo~IN=)XNqU^q zc`Jn>OXx2+oc*sSV-xLXlR5MYJ^ca$ocA z>PPB5j1%(=L3y{*2hWV-EN-rRJ5-hw2V4P4&V~KXWsmvSX5{NuTv=uR5+7kZ!EYId zy+6-be{LeXk#LXsbA?b(X1Aℑc2u$a@atbWiNxbvMP2=$?T5F5KLl$pGaqKH*a; zwgkM@>*Y}yMINU_&Sby8{d+&l#$KlN=dlMYf1bSSE7c7x^AL@IxN=)PP~jv#@QERSC%851eStg~x?3ga^=vUw~GjAspLo5>G_l$-Oz!igK?@c+i*irW` zJo;{RAg+nN^EqDWA3n1CX#eGW^oBGF&bK{MC%*hRjF&(0}t=2 zB_kpm4$!;6f`XPwks|DlE&H8jM{Nr8XP6(oqI|qCXC`N0A=2o?);saOr<8r3`6jUQG%r&YhD8)2 z*nHXHw>LlOCyALC%y*++2OyZEY5*9#<@#op%$z{6$O&lGS>U2z$ndg7B>>iV^w1@y zhZj*B{*@?~1mfg~SiUYVvGUDiW@IVc0L|SP=4iJMWmbKho}=lg+BV*N0`yiN*&L++ zdEpa2Rs+Hkt|Nk=ZS=?KadD}e`OAuJRuw+iBmtEX$(_F@g4y^(B2tR$$A$lcvHU-H zWWC^bkaOCJMl9tdK?)ymdMlk|L@CzU>~z!(U$=np5A(90W4XoC3P%RLLi;iaa>4QG zs#PTnR8SF9b#kwa0VZK(>cD#ro9QX=u zc6zcy-^CyHDZ$K+DB(@Kf^R7%*9vFZ*DX$i`aiEy{64bG2C(-&SC5p6A=ytaS7h?Y zqT=^G-iUmJE@LsQH`)VtE_-ipj|p?KW%OqzxgHr=Hb$YIcS_d$7I-}5#sILT2?$m@ zN(q9L#M150lznN^e~HCE^r*>i=tM`EIp;7uYj5(X`YCi5R{vXW=!kn}YTijy`46Qh z%0%Ic#23i5I?$#$U3TdB+hx(4;mpvr%Qo_(JNUwc&AJhM#G5l(5VLyHHTdaTpqUpF z=IPWNKce|lJ3%Ww@Yp|J;_qFGEQ800rIOE*m!(aS2!bBe#3(M7)0_2_`;H2uuMos~ zy6CN}{J?zHOy(JGiwW)c`s-&3x9!?s}Rbl?Dzc6}-O zlxbEaDkmYN<>phRyc(E`7kIEXz!cwi-}|_qo1(tlu+z?+jwD4mX{uf!-v;}m1`2IU z4o`{8S|-rxN2mszndq*o5*LjBJc9I2PNkm)SF29CmN-qMUvi7T59^xx0o5MqbL8jg zajmhNbj|;)sch(9?Pmr3F;% z@W%e-%xu~2*>R}syVq#1?)&jFcZ*-dA(ytkCS&~$aYVl4t4om0pnf|+3F>(C9F+;0 zr8)20)s)-aiR)U ztDCAUN4%lo_1zfzf8∓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

l*jbYJ-y8sPytNkQvyW#ZK6`YYz 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 W3X;8dcD~`lgbrK1JdJPvYvR8dkw82E diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 0059e67..0edc5a8 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -1,18 +1,18 @@ #include "filesystem_funcs.h" #include "unit_tests.h" +#include "port.h" -static void nak_print(void *element, void *args){ +static void nak_print(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; ssp_printf("start: %u end: %u\n", offset->start, offset->end); } -static receive_offset_tests(){ - - File *file = create_temp_file("temp_test"); +static int receive_offset_tests(){ + File *file = create_temp_file("temp_test", 2000); receive_offset(file, 0, 5, 50); file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); @@ -20,12 +20,32 @@ static receive_offset_tests(){ file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); receive_offset(file, 0, 50, 100); + file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); + return 0; + +} + +void print_json(char *key, char *value, void *params) { + + ssp_printf("%s:%s\n", key, value); } + +int read_json_file_test() { + + int error = read_json("mib.json", print_json, NULL); + + return 1; +} + + + int file_system_tests() { int error = 0; - error = receive_offset_tests(); + //error = receive_offset_tests(); + error = read_json_file_test(); return error; -} \ No newline at end of file +} + diff --git a/Program/test/main.c b/Program/test/main.c index 44353d1..105abd1 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -16,13 +16,13 @@ int main () { int error = 0; - + //error = request_tests(); //error = packet_tests(); - error = protocol_handler_test(); + //error = protocol_handler_test(); //error = list_tests(); - //error = file_system_tests(); + error = file_system_tests(); //error = tasks_tests(); /* diff --git a/Program/test/makefile b/Program/test/makefile index 8ce54f6..5f1a45a 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -27,15 +27,15 @@ CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -CFILES += $(PROJDIR)/test/packet_tests.c -CFILES += $(PROJDIR)/test/test.c -CFILES += $(PROJDIR)/test/mock.c +#CFILES += $(PROJDIR)/test/packet_tests.c +#CFILES += $(PROJDIR)/test/test.c +#CFILES += $(PROJDIR)/test/mock.c #CFILES += $(PROJDIR)/test/request_tests.c #CFILES += $(PROJDIR)/test/tasks_tests.c #CFILES += $(PROJDIR)/test/list_tests.c -#CFILES += $(PROJDIR)/test/filesystem_tests.c -CFILES += $(PROJDIR)/test/protocol_handler_tests.c +CFILES += $(PROJDIR)/test/filesystem_tests.c +#CFILES += $(PROJDIR)/test/protocol_handler_tests.c #CFILES += $(PROJDIR)/test/list_tests.c #CFILES += $(PROJDIR)/test/server_tests.c diff --git a/Program/test/mib.json b/Program/test/mib.json new file mode 100644 index 0000000..8f651f9 --- /dev/null +++ b/Program/test/mib.json @@ -0,0 +1,3 @@ +{ + "cfdp_id": "1" +} \ No newline at end of file diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index 8823e28..ab0e197 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -17,9 +17,9 @@ Response *mock_response(); File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *file_name); Request *mock_request(); + int file_system_tests(); #define TEMP_FILESIZE 1000 - //int file_system_tests(); //int server_tests(int client ); From c751bfeb7ae54120f865bbe1a8a1df61717aa1df Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 16 Jan 2020 20:11:59 -0700 Subject: [PATCH 159/400] Add parsing function to MIB --- Program/include/mib.h | 2 + Program/src/main.c | 18 ++-- Program/src/mib.c | 177 +++++++++++++++++++++++++++++++- Program/src/mib/peer_1.json | 23 +++++ Program/src/protocol_handler.c | 9 +- Program/src/tasks.c | 23 +++-- Program/src/utils.c | 3 +- Program/test/filesystem_tests.c | 9 +- Program/test/mib.json | 3 - Program/test/mib/peer_1.json | 23 +++++ 10 files changed, 252 insertions(+), 38 deletions(-) create mode 100644 Program/src/mib/peer_1.json delete mode 100644 Program/test/mib.json create mode 100644 Program/test/mib/peer_1.json diff --git a/Program/include/mib.h b/Program/include/mib.h index 5baaaa5..9e48a3a 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -16,4 +16,6 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); +Remote_entity *get_remote_entity2(uint32_t dest_id); + #endif \ No newline at end of file diff --git a/Program/src/main.c b/Program/src/main.c index 8c6427a..470f49d 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -29,6 +29,7 @@ static int *exit_now; int main(int argc, char** argv) { + //exit handler for the main thread; exit_now = prepareSignalHandler(); @@ -53,7 +54,7 @@ int main(int argc, char** argv) { */ //start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); - + Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); start_request(req); @@ -66,18 +67,11 @@ int main(int argc, char** argv) { req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy3.jpg", req); start_request(req); -/* - req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy4.jpg", req); - start_request(req); - req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy5.jpg", req); - start_request(req); -*/ - //Request *req; - for (int i=0; i < 10; i++) { +/* + Request *req; + for (int i=0; i < 4; i++) { sleep(10); req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); char filename[11] = {'p','r','o','x','y', (char) (48+i), '.', 'j', 'p', 'g', '\0'}; @@ -87,7 +81,7 @@ int main(int argc, char** argv) { start_request(req); } - +*/ } diff --git a/Program/src/mib.c b/Program/src/mib.c index 60ddc46..3a781f0 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -6,6 +6,11 @@ #include "string.h" #include "list.h" #include "types.h" +#include "filesystem_funcs.h" +#include "stdlib.h" + +//snprintf +#include "stdio.h" MIB *init_mib() { MIB *mib = ssp_alloc(1, sizeof(MIB)); @@ -14,7 +19,6 @@ MIB *init_mib() { return mib; } - static void free_mib_callback(void *element) { ssp_free(element); } @@ -43,8 +47,6 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ remote->cfdp_id = cfdp_id; remote->UT_port = port; - - return mib->remote_entities->insert(mib->remote_entities, remote, cfdp_id); } @@ -87,9 +89,178 @@ Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id){ }; + + + +enum { + PARSE_cfdp_id, + PARSE_UT_address, + PARSE_UT_port, + PARSE_type_of_network, + PARSE_default_transmission_mode, + PARSE_one_way_light_time, + PARSE_total_round_trip_allowance, + PARSE_async_NAK_interval, + PARSE_async_keep_alive_interval, + PARSE_async_report_interval, + PARSE_immediate_nak_mode_enabled, + PARSE_prompt_transmission_interval, + PARSE_disposition_of_incomplete, + PARSE_CRC_required, + PARSE_max_file_segment_len, + PARSE_keep_alive_discrepancy_limit, + PARSE_positive_ack_timer_expiration_limit, + PARSE_nak_timer_expiration_limit, + PARSE_transaction_inactivity_limit, + PARSE_TOTAL, +}; + +static char *parse_list[PARSE_TOTAL] = { + "cfdp_id" , + "UT_address", + "UT_port" , + "type_of_network", + "default_transmission_mode" , + + "one_way_light_time" , + "total_round_trip_allowance" , + "async_NAK_interval", + "async_keep_alive_interval", + "async_report_interval" , + "immediate_nak_mode_enabled" , + "prompt_transmission_interval" , + "disposition_of_incomplete" , + + "CRC_required" , + "max_file_segment_len" , + "keep_alive_discrepancy_limit" , + "positive_ack_timer_expiration_limit" , + "nak_timer_expiration_limit" , + "transaction_inactivity_limit" +}; + + +static void parse_mib(char *key, char *value, void *params) { + + int len = 0; + for (int i = 0; i < PARSE_TOTAL; i++) { + len = strnlen(parse_list[i], 50); + + if (strncmp(key, parse_list[i], len) != 0) + continue; + + Remote_entity *remote = (Remote_entity *) params; + + switch (i) + { + case PARSE_cfdp_id: + remote->cfdp_id = atol(value); + break; + case PARSE_UT_address: + remote->UT_address = atol(value); + break; + case PARSE_UT_port: + remote->UT_port = atol(value); + break; + case PARSE_type_of_network: + remote->type_of_network = atol(value); + break; + case PARSE_default_transmission_mode: + remote->default_transmission_mode = atol(value); + break; + case PARSE_one_way_light_time: + remote->one_way_light_time = atol(value); + break; + case PARSE_total_round_trip_allowance: + remote->total_round_trip_allowance = atol(value); + break; + case PARSE_async_NAK_interval: + remote->async_NAK_interval = atol(value); + break; + case PARSE_async_keep_alive_interval: + remote->async_keep_alive_interval = atol(value); + break; + case PARSE_async_report_interval: + remote->async_report_interval = atol(value); + break; + case PARSE_immediate_nak_mode_enabled: + remote->immediate_nak_mode_enabled = atol(value); + break; + case PARSE_prompt_transmission_interval: + remote->prompt_transmission_interval = atol(value); + break; + case PARSE_disposition_of_incomplete: + remote->disposition_of_incomplete = atol(value); + break; + case PARSE_CRC_required: + remote->CRC_required = atol(value); + break; + case PARSE_max_file_segment_len: + remote->max_file_segment_len = atol(value); + break; + case PARSE_keep_alive_discrepancy_limit: + remote->keep_alive_discrepancy_limit = atol(value); + break; + case PARSE_positive_ack_timer_expiration_limit: + remote->positive_ack_timer_expiration_limit = atol(value); + break; + case PARSE_nak_timer_expiration_limit: + remote->nak_timer_expiration_limit = atol(value); + break; + case PARSE_transaction_inactivity_limit: + remote->transaction_inactivity_limit = atol(value); + break; + default: + break; + } + + + } + +} + +static Remote_entity * get_remote_entity_from_json (uint32_t cfdp_id) { + + char file_name[50]; + snprintf(file_name, 50, "%s%d%s", "mib/peer_", cfdp_id, ".json"); + + Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); + + if (remote == NULL) { + ssp_error("ssp_alloc"); + return NULL; + } + + int error = read_json(file_name, parse_mib, remote); + + if (error < 0) { + ssp_error("could not get remote, json parsing failed\n"); + ssp_free(remote); + return NULL; + } + + return remote; + +} + + +Remote_entity *get_remote_entity2(uint32_t dest_id){ + + Remote_entity *remote = get_remote_entity_from_json(dest_id); + return remote; + +}; + + + void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header->destination_id); ssp_free(pdu_header->source_id); ssp_free(pdu_header); } + + + + + diff --git a/Program/src/mib/peer_1.json b/Program/src/mib/peer_1.json new file mode 100644 index 0000000..de16707 --- /dev/null +++ b/Program/src/mib/peer_1.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 1, + "UT_address" : 2130706433, + "UT_port" : 1234, + "type_of_network" : 1, + "default_transmission_mode" : 1, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 1, + "max_file_segment_len" : 255, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e7b04bd..2d1378b 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -74,6 +74,7 @@ static int find_request(void *element, void *args) { //------------------------------------TODO------------------------------------------ +/* Request *parse_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; @@ -104,10 +105,7 @@ Request *parse_pdu_header(char*packet, uint8_t is_server, Response res, Request Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); return found_req; } - - - - +*/ //------------------------------------------------------------------------------ @@ -141,9 +139,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r uint16_t len = get_data_length(packet); - Request *request = *req; - - //if packet is from the same request, don't' change current request /* if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ diff --git a/Program/src/tasks.c b/Program/src/tasks.c index ebd3a7d..ea3c6b8 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -8,11 +8,16 @@ #include #include "mib.h" #include "filesystem_funcs.h" -#include + #include "types.h" #include "utils.h" #include + +//snprintf +#include + + //for print_request_state #include "requests.h" /*------------------------------------------------------------------------------ @@ -263,7 +268,7 @@ static int on_stdin_callback(void *other) { ------------------------------------------------------------------------------*/ void *ssp_connectionless_server_task(void *params) { - printf("starting posix connectionless server task\n"); + ssp_printf("starting posix connectionless server task\n"); FTP* app = (FTP*) params; app->transaction_sequence_number = 1; @@ -284,7 +289,7 @@ void *ssp_connectionless_server_task(void *params) { void *ssp_connectionless_client_task(void* params){ - printf("starting posix connectionless client task \n"); + ssp_printf("starting posix connectionless client task \n"); Client *client = (Client *) params; char host_name[INET_ADDRSTRLEN]; @@ -312,7 +317,7 @@ void *ssp_connectionless_client_task(void* params){ } void *ssp_connection_server_task(void *params) { - printf("starting posix connection server\n"); + ssp_printf("starting posix connection server\n"); FTP* app = (FTP*) params; app->transaction_sequence_number = 1; @@ -334,7 +339,7 @@ void *ssp_connection_server_task(void *params) { } void *ssp_connection_client_task(void *params) { - printf("starting posix connection client\n"); + ssp_printf("starting posix connection client\n"); Client *client = (Client *) params; char host_name[INET_ADDRSTRLEN]; @@ -362,7 +367,7 @@ void *ssp_connection_client_task(void *params) { } void *ssp_csp_connectionless_server_task(void *params) { - printf("starting csp connectionless server\n"); + ssp_printf("starting csp connectionless server\n"); FTP *app = (FTP *) params; csp_connectionless_server( @@ -378,7 +383,7 @@ void *ssp_csp_connectionless_server_task(void *params) { } void *ssp_csp_connectionless_client_task(void *params) { - printf("starting csp connectionless client\n"); + ssp_printf("starting csp connectionless client\n"); Client *client = (Client *) params; csp_connectionless_client(client->remote_entity->UT_address, @@ -395,7 +400,7 @@ void *ssp_csp_connectionless_client_task(void *params) { void *ssp_csp_connection_server_task(void *params) { - printf("starting csp connection server\n"); + ssp_printf("starting csp connection server\n"); FTP *app = (FTP *) params; csp_connection_server(app->remote_entity->UT_port, @@ -410,7 +415,7 @@ void *ssp_csp_connection_server_task(void *params) { } void *ssp_csp_connection_client_task(void *params) { - printf("starting csp connection client\n"); + ssp_printf("starting csp connection client\n"); Client *client = (Client *) params; csp_connection_client(client->remote_entity->UT_address, diff --git a/Program/src/utils.c b/Program/src/utils.c index 5ec417f..60d77ee 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -27,8 +27,7 @@ int checkAlloc(void *mem, int notOkToFail) if (mem == NULL && notOkToFail) { - perror("malloc"); - exit(EXIT_FAILURE); + ssp_error("malloc"); } else if(mem == NULL && !notOkToFail) { return 0; diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 0edc5a8..1160029 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -1,7 +1,7 @@ #include "filesystem_funcs.h" #include "unit_tests.h" #include "port.h" - +#include "mib.h" static void nak_print(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; @@ -35,17 +35,22 @@ void print_json(char *key, char *value, void *params) { int read_json_file_test() { - int error = read_json("mib.json", print_json, NULL); + int error = read_json("mib/peer_1.json", print_json, NULL); return 1; } +int read_mib() { + Remote_entity *entity = get_remote_entity2(1); + +} int file_system_tests() { int error = 0; //error = receive_offset_tests(); error = read_json_file_test(); + error = read_mib(); return error; } diff --git a/Program/test/mib.json b/Program/test/mib.json deleted file mode 100644 index 8f651f9..0000000 --- a/Program/test/mib.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "cfdp_id": "1" -} \ No newline at end of file diff --git a/Program/test/mib/peer_1.json b/Program/test/mib/peer_1.json new file mode 100644 index 0000000..de16707 --- /dev/null +++ b/Program/test/mib/peer_1.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 1, + "UT_address" : 2130706433, + "UT_port" : 1234, + "type_of_network" : 1, + "default_transmission_mode" : 1, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 1, + "max_file_segment_len" : 255, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file From 6ce9f9355efd05c8e63dee6629147ca563dbbe00 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 18 Jan 2020 10:54:10 -0700 Subject: [PATCH 160/400] get remote entity now doesn't allocate --- Program/src/mib.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Program/src/mib.c b/Program/src/mib.c index 3a781f0..fb69cb2 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -219,34 +219,37 @@ static void parse_mib(char *key, char *value, void *params) { } -static Remote_entity * get_remote_entity_from_json (uint32_t cfdp_id) { +static int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { char file_name[50]; snprintf(file_name, 50, "%s%d%s", "mib/peer_", cfdp_id, ".json"); - - Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); - - if (remote == NULL) { - ssp_error("ssp_alloc"); - return NULL; - } int error = read_json(file_name, parse_mib, remote); if (error < 0) { ssp_error("could not get remote, json parsing failed\n"); - ssp_free(remote); - return NULL; + return -1; } - return remote; + return 0; } Remote_entity *get_remote_entity2(uint32_t dest_id){ - Remote_entity *remote = get_remote_entity_from_json(dest_id); + Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); + + if (remote == NULL) { + ssp_error("ssp_alloc\n"); + return NULL; + } + + int error = get_remote_entity_from_json(remote, dest_id); + if (error == -1) { + ssp_error("couldn't get remote from json\n"); + } + return remote; }; From b7c724279ef8266f3986154727ebf572799321c5 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 18 Jan 2020 11:14:49 -0700 Subject: [PATCH 161/400] change FTP type to not need Remote_entity pointer --- Program/include/mib.h | 1 + Program/include/types.h | 2 +- Program/src/file_delivery_app.c | 30 +++++++++++++++++++----------- Program/src/main.c | 3 +++ Program/src/mib.c | 4 ++-- Program/src/port.c | 1 + Program/src/protocol_handler.c | 4 ++-- Program/src/requests.c | 5 ----- Program/src/tasks.c | 10 +++++----- 9 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 9e48a3a..4cb48ba 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -17,5 +17,6 @@ Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); Remote_entity *get_remote_entity2(uint32_t dest_id); +int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index 60f79b3..a5b6389 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -628,7 +628,7 @@ typedef struct ftp { Request *current_request; //underlying connection information - Remote_entity *remote_entity; + Remote_entity remote_entity; List *active_clients; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index b78b036..33f10cc 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -33,19 +33,27 @@ FTP *init_ftp(uint32_t my_cfdp_address) { add_new_cfdp_entity(mib, 5, 3, 3, csp, ACKNOWLEDGED_MODE); add_new_cfdp_entity(mib, 6, 4, 4, csp, ACKNOWLEDGED_MODE); + + Remote_entity remote_entity; + int error = get_remote_entity_from_json(&remote_entity, my_cfdp_address); + if (error == -1) { + ssp_error("couldn't start server\n"); + return NULL; + } + //find server client in mib - Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); - if (server_entity == NULL) { - ssp_printf("couldn't find your id in the information base\n"); - } + //Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); + //if (server_entity == NULL) { + // ssp_printf("couldn't find your id in the information base\n"); + //} - if (server_entity->type_of_network == csp) { + if (remote_entity.type_of_network == csp) { printf("Initialising CSP\r\n"); /* Init CSP with address MY_ADDRESS */ - csp_init(server_entity->UT_address); + csp_init(remote_entity.UT_address); /* Init buffer system with 10 packets of maximum PACKET_LEN bytes each */ csp_buffer_init(10, PACKET_LEN); @@ -59,7 +67,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { app->my_cfdp_id = my_cfdp_address; app->mib = mib; app->close = 0; - app->remote_entity = server_entity; + app->remote_entity = remote_entity; app->active_clients = linked_list(); app->request_list = linked_list(); app->current_request = NULL; @@ -73,16 +81,16 @@ FTP *init_ftp(uint32_t my_cfdp_address) { void ssp_server(FTP *app) { - if (app->remote_entity->type_of_network == posix && app->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + if (app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); - } else if(app->remote_entity->type_of_network == posix && app->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { + } else if(app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); - } else if (app->remote_entity->type_of_network == csp && app->remote_entity->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); - } else if (app->remote_entity->type_of_network == csp && app->remote_entity->default_transmission_mode == ACKNOWLEDGED_MODE) { + } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); } } diff --git a/Program/src/main.c b/Program/src/main.c index 470f49d..b84f80c 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -42,6 +42,9 @@ int main(int argc, char** argv) { } FTP *app = init_ftp(conf->my_cfdp_id); + if (app == NULL) { + return 1; + } //create a client if (conf->client_cfdp_id != 0){ diff --git a/Program/src/mib.c b/Program/src/mib.c index fb69cb2..9e78314 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -219,7 +219,7 @@ static void parse_mib(char *key, char *value, void *params) { } -static int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { +int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { char file_name[50]; snprintf(file_name, 50, "%s%d%s", "mib/peer_", cfdp_id, ".json"); @@ -249,7 +249,7 @@ Remote_entity *get_remote_entity2(uint32_t dest_id){ if (error == -1) { ssp_error("couldn't get remote from json\n"); } - + return remote; }; diff --git a/Program/src/port.c b/Program/src/port.c index 135dbae..d9c11ac 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -128,6 +128,7 @@ void ssp_sendto(Response res) { #ifndef TEST int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); if (err < 0) { + ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(*addr)); ssp_error("ERROR in sendto"); } #endif diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2d1378b..a2fce57 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -173,8 +173,8 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r memcpy(found_req->res.addr, res.addr, res.size_of_addr); found_req->res.packet_len = app->packet_len; found_req->res.sfd = res.sfd; - found_req->res.transmission_mode = app->remote_entity->default_transmission_mode; - found_req->res.type_of_network = app->remote_entity->type_of_network; + found_req->res.transmission_mode = app->remote_entity.default_transmission_mode; + found_req->res.type_of_network = app->remote_entity.type_of_network; found_req->paused = false; request_list->push(request_list, found_req, transaction_sequence_number); } diff --git a/Program/src/requests.c b/Program/src/requests.c index c92eb10..8f96d6c 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -39,7 +39,6 @@ LV *create_lv(int size, void *value) { LV *lv = ssp_alloc(1, sizeof(LV)); lv->value = ssp_alloc(size, sizeof(char)); - memcpy(lv->value, value, size); lv->length = size; @@ -116,9 +115,6 @@ void ssp_cleanup_req(void *request) { - - - Request *init_request(uint32_t buff_len) { Request *req = ssp_alloc(1, sizeof(Request)); @@ -191,7 +187,6 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //spin up a new client thread Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); - if (client == NULL) { ssp_printf("Spinning up a new client thread\n"); client = ssp_client(dest_id, app); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index ea3c6b8..bb9c9ba 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -273,7 +273,7 @@ void *ssp_connectionless_server_task(void *params) { app->transaction_sequence_number = 1; char port[10]; - snprintf(port, 10, "%d",app->remote_entity->UT_port); + snprintf(port, 10, "%d",app->remote_entity.UT_port); connectionless_server(port, app->packet_len, @@ -322,7 +322,7 @@ void *ssp_connection_server_task(void *params) { app->transaction_sequence_number = 1; char port[10]; - snprintf(port, 10, "%u",app->remote_entity->UT_port); + snprintf(port, 10, "%u",app->remote_entity.UT_port); //1024 is the connection max limit connection_server(port, @@ -371,7 +371,7 @@ void *ssp_csp_connectionless_server_task(void *params) { FTP *app = (FTP *) params; csp_connectionless_server( - app->remote_entity->UT_port, + app->remote_entity.UT_port, on_recv_server_callback, on_time_out_callback_server, on_stdin_callback, @@ -388,7 +388,7 @@ void *ssp_csp_connectionless_client_task(void *params) { csp_connectionless_client(client->remote_entity->UT_address, client->remote_entity->UT_port, - client->app->remote_entity->UT_port, + client->app->remote_entity.UT_port, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, @@ -403,7 +403,7 @@ void *ssp_csp_connection_server_task(void *params) { ssp_printf("starting csp connection server\n"); FTP *app = (FTP *) params; - csp_connection_server(app->remote_entity->UT_port, + csp_connection_server(app->remote_entity.UT_port, on_recv_server_callback, on_time_out_callback_server, on_stdin_callback, From 77fd06efe9ac4eff949e148df4a6660c2090c841 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 18 Jan 2020 12:01:32 -0700 Subject: [PATCH 162/400] Add better errors for json read --- Program/src/filesystem_funcs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index cb0ddd5..6fb50db 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -301,7 +301,7 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa uint32_t total_size = get_file_size(file_name); if (total_size == 0){ ssp_error("couldn't get file size\n"); - return 1; + return -1; } char buff[total_size]; @@ -311,13 +311,13 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa int r = read(fd, buff, sizeof(buff)); if (r < 0) { ssp_error("read failed\n"); - return 1; + return -1; } r = jsmn_parse(&p, buff, total_size, tok, number_of_tokens); if (r < 0) { ssp_error("Failed to parse JSON\n"); - return 1; + return -1; } for (int i = 1; i < r; i++) { From d08af12965fb9c15a572ab637fd264cac68ac413 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 18 Jan 2020 14:45:33 -0700 Subject: [PATCH 163/400] reduce pointer dependecy from MIB structure --- Program/include/types.h | 2 +- Program/src/file_delivery_app.c | 38 ++++++++++++++++++--------------- Program/src/port.c | 1 + Program/src/requests.c | 6 +++--- Program/src/tasks.c | 25 +++++++++++----------- 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index a5b6389..8871a0c 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -655,7 +655,7 @@ typedef struct client { List *request_list; //information about the remote_entity - Remote_entity *remote_entity; + Remote_entity remote_entity; //packet header, useful for copying into outgoing packets Pdu_header *pdu_header; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 33f10cc..f1a63cb 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -19,13 +19,15 @@ FTP *init_ftp(uint32_t my_cfdp_address) { //setting host name for testing char *host_name = "127.0.0.1"; - uint32_t addr[sizeof(uint32_t)]; - inet_pton(AF_INET, host_name, addr); + uint32_t addr = 0; + + inet_pton(AF_INET, host_name, &addr); //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 7, *addr, 1113, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 1, addr, 1111, posix, UN_ACKNOWLEDGED_MODE); + + add_new_cfdp_entity(mib, 2, addr, 1112, posix, UN_ACKNOWLEDGED_MODE); + add_new_cfdp_entity(mib, 7, addr, 1113, posix, UN_ACKNOWLEDGED_MODE); add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); @@ -41,7 +43,6 @@ FTP *init_ftp(uint32_t my_cfdp_address) { return NULL; } - //find server client in mib //Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); //if (server_entity == NULL) { @@ -104,26 +105,29 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { client->request_list = linked_list(); client->packet_len = PACKET_LEN; - Remote_entity *remote = get_remote_entity(app->mib, cfdp_id); - - if (remote == NULL) - ssp_printf("couldn't find entity in Remote_entity list\n"); - - //TODO clean this up, we don't need multiple instances of UT_ports etc - client->remote_entity = remote; + + //Remote_entity *remote_entity = ssp_alloc(1, sizeof(Remote_entity)); + Remote_entity remote_entity; + int error = get_remote_entity_from_json(&remote_entity, cfdp_id); + if (error < 0) { + ssp_error("couldn't get client remote_entity from mib\n"); + return NULL; + } + + client->remote_entity = remote_entity; client->pdu_header = get_header_from_mib(app->mib, cfdp_id, app->my_cfdp_id); client->app = app; - if (remote->type_of_network == posix && remote->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + if (remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); - } else if(remote->type_of_network == posix && remote->default_transmission_mode == ACKNOWLEDGED_MODE) { + } else if(remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); - } else if (remote->type_of_network == csp && remote->default_transmission_mode == ACKNOWLEDGED_MODE) { + } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); - } else if (remote->type_of_network == csp && remote->default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); } diff --git a/Program/src/port.c b/Program/src/port.c index d9c11ac..b28abbe 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -126,6 +126,7 @@ void ssp_sendto(Response res) { printf("sending outgoing packet (testing)\n"); #endif #ifndef TEST + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); if (err < 0) { ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(*addr)); diff --git a/Program/src/requests.c b/Program/src/requests.c index 8f96d6c..5ad6f82 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -164,7 +164,7 @@ Request *init_request_2(uint32_t buff_len, uint32_t transaction_id, Pdu_header * req->res.type_of_network = remote_entity->type_of_network; req->res.packet_len = buff_len; - //req->res.addr = remote_entity->UT_address; + //req->res.addr = remote_entity.UT_address; //using the hosts network transfer, should switch to client configuration /* @@ -199,8 +199,8 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //build a request req->transaction_sequence_number = app->transaction_sequence_number++; - req->dest_cfdp_id = client->remote_entity->cfdp_id; - req->pdu_header = get_header_from_mib(app->mib, client->remote_entity->cfdp_id, app->my_cfdp_id); + req->dest_cfdp_id = client->remote_entity.cfdp_id; + req->pdu_header = get_header_from_mib(app->mib, client->remote_entity.cfdp_id, app->my_cfdp_id); req->res.packet_len = client->packet_len; req->packet_data_len = app->packet_len; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index bb9c9ba..99ee37c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -80,9 +80,9 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u res.addr = addr; res.sfd = sfd; res.packet_len = client->packet_len; - res.type_of_network = client->remote_entity->type_of_network; + res.type_of_network = client->remote_entity.type_of_network; res.size_of_addr = size_of_addr; - res.transmission_mode = client->remote_entity->default_transmission_mode; + res.transmission_mode = client->remote_entity.default_transmission_mode; Request **request_container = &client->current_request; @@ -148,8 +148,8 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi res.packet_len = client->packet_len; res.addr = addr; res.size_of_addr = size_of_addr; - res.type_of_network = client->remote_entity->type_of_network; - res.transmission_mode = client->remote_entity->default_transmission_mode; + res.type_of_network = client->remote_entity.type_of_network; + res.transmission_mode = client->remote_entity.default_transmission_mode; struct user_request_check_params params = { res, @@ -296,11 +296,12 @@ void *ssp_connectionless_client_task(void* params){ char port[10]; //convert int to char * - snprintf(port, 10, "%d", client->remote_entity->UT_port); + snprintf(port, 10, "%d", client->remote_entity.UT_port); //convert uint id to char * - inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &client->remote_entity.UT_address, host_name, INET_ADDRSTRLEN); + connectionless_client(host_name, port, client->packet_len, @@ -346,10 +347,10 @@ void *ssp_connection_client_task(void *params) { char port[10]; //convert int to char * - snprintf(port, 10, "%d", client->remote_entity->UT_port); + snprintf(port, 10, "%d", client->remote_entity.UT_port); //convert uint id to char * - inet_ntop(AF_INET, &client->remote_entity->UT_address, host_name, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &client->remote_entity.UT_address, host_name, INET_ADDRSTRLEN); connection_client(host_name, port, @@ -386,8 +387,8 @@ void *ssp_csp_connectionless_client_task(void *params) { ssp_printf("starting csp connectionless client\n"); Client *client = (Client *) params; - csp_connectionless_client(client->remote_entity->UT_address, - client->remote_entity->UT_port, + csp_connectionless_client(client->remote_entity.UT_address, + client->remote_entity.UT_port, client->app->remote_entity.UT_port, on_send_client_callback, on_recv_client_callback, @@ -418,8 +419,8 @@ void *ssp_csp_connection_client_task(void *params) { ssp_printf("starting csp connection client\n"); Client *client = (Client *) params; - csp_connection_client(client->remote_entity->UT_address, - client->remote_entity->UT_port, + csp_connection_client(client->remote_entity.UT_address, + client->remote_entity.UT_port, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, From 422aa49bba8a7cf01d7c77a95b6da0a55311329a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 18 Jan 2020 15:49:23 -0700 Subject: [PATCH 164/400] break memory dependency from remote_etity in request --- Program/include/mib.h | 4 ++- Program/include/types.h | 2 +- Program/include/utils.h | 8 ++---- Program/src/file_delivery_app.c | 7 +++-- Program/src/mib.c | 49 ++++++++++++++++++++++++++++----- Program/src/port.c | 13 ++++++--- Program/src/protocol_handler.c | 19 +++++++++++-- Program/src/requests.c | 17 +++++++----- Program/src/server.c | 19 ++++++------- Program/src/utils.c | 13 ++++----- 10 files changed, 104 insertions(+), 47 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 4cb48ba..36edac1 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -13,7 +13,9 @@ MIB *init_mib(void); void free_mib(MIB *mib); int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, enum Network_type, int transmission_mode); -Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); +//Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); +Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id); + void ssp_cleanup_pdu_header(Pdu_header *pdu_header); Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); Remote_entity *get_remote_entity2(uint32_t dest_id); diff --git a/Program/include/types.h b/Program/include/types.h index 8871a0c..fe1fdcb 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -597,7 +597,7 @@ typedef struct request { //bool for sending first blast of data packets // uint8_t sent_first_data_round; - Remote_entity *remote_entity; + Remote_entity remote_entity; Local_entity local_entity; List *messages_to_user; diff --git a/Program/include/utils.h b/Program/include/utils.h index 8e924dd..1b94270 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -25,13 +25,11 @@ typedef struct config /*------------------------------------------------------------------------------ - Purpose: This function checks to see if the memory is allocated, - it exits if ok = 1 and keeps running in ok == 0 + Purpose: This function checks to see if the memory is allocated Perameters: void *mem: - int notOkToFail: - Return: returns nothing + Return: returns -1 on bad mem, and 1 on ok ------------------------------------------------------------------------------*/ -int checkAlloc(void *mem, int notOkToFail); +int checkAlloc(void *mem); /*------------------------------------------------------------------------------ Purpose: This function is used to make a configuration struct from the diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index f1a63cb..a53f0a4 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -99,8 +99,9 @@ void ssp_server(FTP *app) { Client *ssp_client(uint32_t cfdp_id, FTP *app) { Client *client = ssp_alloc(sizeof(Client), 1); - checkAlloc(client, 1); - + if (checkAlloc(client) < 0) + return NULL; + client->current_request = NULL; client->request_list = linked_list(); client->packet_len = PACKET_LEN; @@ -115,7 +116,7 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { } client->remote_entity = remote_entity; - client->pdu_header = get_header_from_mib(app->mib, cfdp_id, app->my_cfdp_id); + client->pdu_header = get_header_from_mib(remote_entity, app->my_cfdp_id); client->app = app; if (remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { diff --git a/Program/src/mib.c b/Program/src/mib.c index 9e78314..79db2c5 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -14,7 +14,7 @@ MIB *init_mib() { MIB *mib = ssp_alloc(1, sizeof(MIB)); - checkAlloc(mib, 1); + checkAlloc(mib); mib->remote_entities = linked_list(); return mib; } @@ -41,7 +41,7 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ remote->default_transmission_mode = transmission_mode; remote ->max_file_segment_len = 1200; - checkAlloc(remote, 1); + checkAlloc(remote); remote->UT_address = UT_address; remote->cfdp_id = cfdp_id; @@ -50,7 +50,7 @@ int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_ return mib->remote_entities->insert(mib->remote_entities, remote, cfdp_id); } - +/* Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, dest_id, NULL, NULL); @@ -59,7 +59,7 @@ Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ } Pdu_header *pdu_header = ssp_alloc(1, sizeof(Pdu_header)); - checkAlloc(pdu_header, 1); + checkAlloc(pdu_header); pdu_header->reserved_bit_0 = 0; pdu_header->reserved_bit_1 = 0; @@ -72,11 +72,11 @@ Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ pdu_header->transmission_mode = remote->default_transmission_mode; pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - checkAlloc(pdu_header->destination_id, 1); + checkAlloc(pdu_header->destination_id); memcpy(pdu_header->destination_id, &remote->cfdp_id, pdu_header->length_of_entity_IDs); pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - checkAlloc(pdu_header->source_id, 1); + checkAlloc(pdu_header->source_id); memcpy(pdu_header->source_id, &source_id, pdu_header->length_of_entity_IDs); return pdu_header; } @@ -87,10 +87,46 @@ Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id){ return remote; }; +*/ + + +Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id) { + + Pdu_header *pdu_header = ssp_alloc(1, sizeof(Pdu_header)); + if (pdu_header == NULL) + return NULL; + if (checkAlloc(pdu_header) < 0) + return NULL; + pdu_header->reserved_bit_0 = 0; + pdu_header->reserved_bit_1 = 0; + pdu_header->reserved_bit_2 = 0; + pdu_header->CRC_flag = remote.CRC_required; + pdu_header->direction = 1; + pdu_header->PDU_type = 0; + pdu_header->transaction_seq_num_len = 3; + pdu_header->length_of_entity_IDs = 1; + pdu_header->transmission_mode = remote.default_transmission_mode; + pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); + + if (checkAlloc(pdu_header->destination_id) < 0) + return NULL; + + memcpy(pdu_header->destination_id, &remote.cfdp_id, pdu_header->length_of_entity_IDs); + + pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); + if (checkAlloc(pdu_header->source_id) < 0) + return NULL; + + + memcpy(pdu_header->source_id, &source_id, pdu_header->length_of_entity_IDs); + return pdu_header; + +} + enum { PARSE_cfdp_id, @@ -255,7 +291,6 @@ Remote_entity *get_remote_entity2(uint32_t dest_id){ }; - void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header->destination_id); ssp_free(pdu_header->source_id); diff --git a/Program/src/port.c b/Program/src/port.c index b28abbe..6b82bda 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -236,7 +236,8 @@ void *ssp_init_sockaddr_struct(size_t *size_of_addr) { *size_of_addr = sizeof(struct sockaddr_storage); void *addr = ssp_alloc(1, sizeof(struct sockaddr_storage)); - checkAlloc(addr, 1); + if (checkAlloc(addr) < 0) + return NULL; #endif @@ -326,10 +327,14 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void #ifdef POSIX_PORT pthread_t *handler = ssp_alloc(1, sizeof(pthread_t)); - checkAlloc(handler, 1); + if (checkAlloc(handler) < 0) + return NULL; + pthread_attr_t *attr = ssp_alloc(1, sizeof(pthread_attr_t)); - checkAlloc(attr, 1); + + if (checkAlloc(attr) < 0) + return NULL; int err = pthread_attr_init(attr); if (0 != err) @@ -339,7 +344,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void err = pthread_attr_setstacksize(attr, stack_size); if (0 != err) - perror("ERROR pthread_attr_setstacksize %d"); + ssp_error("ERROR pthread_attr_setstacksize %d"); if (EINVAL == err) { printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index a2fce57..4085dee 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -138,6 +138,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r } uint16_t len = get_data_length(packet); + int error = 0; //if packet is from the same request, don't' change current request /* @@ -154,10 +155,18 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r }; Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); + Remote_entity remote_entity; //server side, receiving requests (this should be its own function) if (found_req == NULL && is_server) { + + error = get_remote_entity_from_json(&remote_entity, source_id); + if (error < 0) { + ssp_error("could not get remote entity for incoming packet \n"); + return -1; + } + found_req = init_request(app->packet_len); ssp_printf("incoming new request\n"); @@ -165,8 +174,14 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->transmission_mode = header->transmission_mode; found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; - found_req->pdu_header = get_header_from_mib(app->mib, source_id, app->my_cfdp_id); - found_req->remote_entity = get_remote_entity(app->mib, source_id); + + found_req->pdu_header = get_header_from_mib(remote_entity, app->my_cfdp_id); + if (found_req->pdu_header == NULL) + ssp_printf("PDU HEADER IS NULL\n"); + + + found_req->remote_entity = remote_entity; + found_req->procedure = sending_put_metadata; found_req->res.addr = ssp_alloc(1, res.size_of_addr); diff --git a/Program/src/requests.c b/Program/src/requests.c index 5ad6f82..ec59f3d 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -131,11 +131,12 @@ Request *init_request(uint32_t buff_len) { req->messages_to_user = linked_list(); - checkAlloc(req->buff, 1); + checkAlloc(req->buff); return req; } +/* Request *init_request_2(uint32_t buff_len, uint32_t transaction_id, Pdu_header *pdu_header, Remote_entity *remote_entity) { Request *req = ssp_alloc(1, sizeof(Request)); @@ -167,17 +168,16 @@ Request *init_request_2(uint32_t buff_len, uint32_t transaction_id, Pdu_header * //req->res.addr = remote_entity.UT_address; //using the hosts network transfer, should switch to client configuration - /* - req->res.sfd = res.sfd; - */ + + //req->res.sfd = res.sfd; + //req->paused = false; //req->procedure = sending_put_metadata; return req; } - - +*/ //starts a new client, adding it to app->active_clients, as well as //starting a new request and adding it to the client, returns a pointer @@ -200,7 +200,10 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //build a request req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity.cfdp_id; - req->pdu_header = get_header_from_mib(app->mib, client->remote_entity.cfdp_id, app->my_cfdp_id); + req->pdu_header = get_header_from_mib(client->remote_entity, app->my_cfdp_id); + if (req->pdu_header ==NULL) + ssp_printf("PDU HEADER IS NULL\n"); + req->res.packet_len = client->packet_len; req->packet_data_len = app->packet_len; diff --git a/Program/src/server.c b/Program/src/server.c index d85d78d..f5adf97 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -149,8 +149,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf if (*newBufferSize != *prev_buff_size) { *buffer = realloc(*buffer, *newBufferSize); - if(checkAlloc(*buffer, 0)){ - *prev_buff_size = *newBufferSize; + if(checkAlloc(*buffer) < 0){ return 1; } return 0; @@ -188,13 +187,13 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, ssp_fd_set(STDIN_FILENO, socket_set); uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size, 1); + checkAlloc(buff_size); *buff_size = initial_buff_size; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), *buff_size); - checkAlloc(buff, 1); + checkAlloc(buff); for (;;) { @@ -298,13 +297,13 @@ void connectionless_server(char* port, int initial_buff_size, ssp_fd_set(STDIN_FILENO, socket_set); uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size, 1); + checkAlloc(buff_size); *buff_size = initial_buff_size + 10; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), *buff_size); - checkAlloc(buff, 1); + checkAlloc(buff); for (;;) { @@ -382,14 +381,14 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe exit_now = 1; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size, 1); + checkAlloc(buff_size); *buff_size = packet_len + 10; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), prev_buff_size); - checkAlloc(buff, 1); + checkAlloc(buff); for (;;) { @@ -445,13 +444,13 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa exit_now = 1; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size, 1); + checkAlloc(buff_size); *buff_size = packet_len; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(prev_buff_size, sizeof(char)); - checkAlloc(buff, 1); + checkAlloc(buff); for (;;) { diff --git a/Program/src/utils.c b/Program/src/utils.c index 60d77ee..e1565e6 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -22,15 +22,12 @@ to use for general functionality. #define ID_LEN 10 //see header file -int checkAlloc(void *mem, int notOkToFail) +int checkAlloc(void *mem) { - - if (mem == NULL && notOkToFail) + if (mem == NULL) { ssp_error("malloc"); - } - else if(mem == NULL && !notOkToFail) { - return 0; + return -1; } return 1; } @@ -41,7 +38,9 @@ Config *configuration(int argc, char **argv) { int ch; Config *conf = calloc(sizeof(Config), 1); - checkAlloc(conf, 1); + if (checkAlloc(conf) < 0) + return NULL; + conf->timer = 15; conf->verbose_level = 0; From ca33a069b8e039a4bcf12e4d99b5663af6a874e1 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 25 Jan 2020 13:01:54 -0700 Subject: [PATCH 165/400] Remove MIB struct --- Program/include/types.h | 2 -- Program/src/file_delivery_app.c | 30 +----------------------------- Program/src/tasks.c | 8 ++++---- 3 files changed, 5 insertions(+), 35 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index fe1fdcb..7728c67 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -619,8 +619,6 @@ typedef struct request { typedef struct ftp { uint32_t packet_len; void *server_handle; - MIB *mib; - uint32_t my_cfdp_id; List* request_list; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index a53f0a4..e827524 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -14,27 +14,6 @@ FTP *init_ftp(uint32_t my_cfdp_address) { - //Memory information base - MIB *mib = init_mib(); - - //setting host name for testing - char *host_name = "127.0.0.1"; - uint32_t addr = 0; - - inet_pton(AF_INET, host_name, &addr); - - //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, addr, 1111, posix, UN_ACKNOWLEDGED_MODE); - - add_new_cfdp_entity(mib, 2, addr, 1112, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 7, addr, 1113, posix, UN_ACKNOWLEDGED_MODE); - - add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); - - add_new_cfdp_entity(mib, 5, 3, 3, csp, ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 6, 4, 4, csp, ACKNOWLEDGED_MODE); - Remote_entity remote_entity; int error = get_remote_entity_from_json(&remote_entity, my_cfdp_address); @@ -43,12 +22,6 @@ FTP *init_ftp(uint32_t my_cfdp_address) { return NULL; } - //find server client in mib - //Remote_entity* server_entity = mib->remote_entities->find(mib->remote_entities, my_cfdp_address, NULL, NULL); - //if (server_entity == NULL) { - // ssp_printf("couldn't find your id in the information base\n"); - //} - if (remote_entity.type_of_network == csp) { printf("Initialising CSP\r\n"); @@ -66,8 +39,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { FTP *app = ssp_alloc(sizeof(FTP), 1); app->packet_len = PACKET_LEN; app->my_cfdp_id = my_cfdp_address; - app->mib = mib; - app->close = 0; + app->close = false; app->remote_entity = remote_entity; app->active_clients = linked_list(); app->request_list = linked_list(); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 99ee37c..6adc07c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -297,9 +297,10 @@ void *ssp_connectionless_client_task(void* params){ //convert int to char * snprintf(port, 10, "%d", client->remote_entity.UT_port); + uint32_t ut_addr = htonl(client->remote_entity.UT_address); //convert uint id to char * - inet_ntop(AF_INET, &client->remote_entity.UT_address, host_name, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); connectionless_client(host_name, @@ -349,8 +350,9 @@ void *ssp_connection_client_task(void *params) { //convert int to char * snprintf(port, 10, "%d", client->remote_entity.UT_port); + uint32_t ut_addr = htonl(client->remote_entity.UT_address); //convert uint id to char * - inet_ntop(AF_INET, &client->remote_entity.UT_address, host_name, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); connection_client(host_name, port, @@ -454,8 +456,6 @@ void ssp_cleanup_ftp(FTP *app) { app->active_clients->iterate(app->active_clients, exit_client, NULL); app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); - - free_mib(app->mib); app->active_clients->freeOnlyList(app->active_clients); ssp_free(app); } From 6459dd715a67d4590b3ff5bf84770c92798258ec Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 25 Jan 2020 13:03:20 -0700 Subject: [PATCH 166/400] Delete placeholder MIB functions --- Program/src/mib.c | 78 ----------------------------------------------- 1 file changed, 78 deletions(-) diff --git a/Program/src/mib.c b/Program/src/mib.c index 79db2c5..c21ce55 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -12,84 +12,6 @@ //snprintf #include "stdio.h" -MIB *init_mib() { - MIB *mib = ssp_alloc(1, sizeof(MIB)); - checkAlloc(mib); - mib->remote_entities = linked_list(); - return mib; -} - -static void free_mib_callback(void *element) { - ssp_free(element); -} - -void free_mib(MIB *mib){ - - mib->remote_entities->free(mib->remote_entities, free_mib_callback); - ssp_free(mib); -} - -//these configure peers for their specific transmission configuration, should be read in on a config file -int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, Network_type type, int transmission_mode){ - - Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); - remote->type_of_network = type; - - remote->CRC_required = 0; - //these will be custom set by a config file - - remote->default_transmission_mode = transmission_mode; - - remote ->max_file_segment_len = 1200; - checkAlloc(remote); - - remote->UT_address = UT_address; - remote->cfdp_id = cfdp_id; - remote->UT_port = port; - - return mib->remote_entities->insert(mib->remote_entities, remote, cfdp_id); -} - -/* -Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id){ - - Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, dest_id, NULL, NULL); - if (remote == NULL) { - return NULL; - } - - Pdu_header *pdu_header = ssp_alloc(1, sizeof(Pdu_header)); - checkAlloc(pdu_header); - - pdu_header->reserved_bit_0 = 0; - pdu_header->reserved_bit_1 = 0; - pdu_header->reserved_bit_2 = 0; - pdu_header->CRC_flag = remote->CRC_required; - pdu_header->direction = 1; - pdu_header->PDU_type = 0; - pdu_header->transaction_seq_num_len = 3; - pdu_header->length_of_entity_IDs = 1; - pdu_header->transmission_mode = remote->default_transmission_mode; - pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - - checkAlloc(pdu_header->destination_id); - memcpy(pdu_header->destination_id, &remote->cfdp_id, pdu_header->length_of_entity_IDs); - - pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - checkAlloc(pdu_header->source_id); - memcpy(pdu_header->source_id, &source_id, pdu_header->length_of_entity_IDs); - return pdu_header; -} - -Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id){ - - Remote_entity *remote = mib->remote_entities->find(mib->remote_entities, dest_id, NULL, NULL); - return remote; - -}; -*/ - - Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id) { From 1e1bbdcb03c59d26907820caaca88c4113872740 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 25 Jan 2020 13:26:23 -0700 Subject: [PATCH 167/400] remove pdu_header pointer from Request --- Program/include/mib.h | 1 + Program/include/protocol_handler.h | 1 - Program/include/types.h | 2 +- Program/src/mib.c | 47 ++++++++++++++++++------------ Program/src/protocol_handler.c | 29 +++++++++++------- Program/src/requests.c | 7 +---- Program/test/mock.c | 4 +-- 7 files changed, 51 insertions(+), 40 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 36edac1..d543918 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -15,6 +15,7 @@ void free_mib(MIB *mib); int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, enum Network_type, int transmission_mode); //Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id); +int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 05316ff..7ef5b0a 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -19,7 +19,6 @@ void process_pdu_eof(char *packet, Request *req, Response res); uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); void process_messages(Request *req, FTP *app); -uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_ack (char *packet, uint32_t start, uint8_t type); int process_file_request_metadata(Request *req); int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client); diff --git a/Program/include/types.h b/Program/include/types.h index 7728c67..689dc22 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -609,7 +609,7 @@ typedef struct request { char* buff; //header for building response packets - Pdu_header *pdu_header; + Pdu_header pdu_header; //handler for sending responses back Response res; diff --git a/Program/src/mib.c b/Program/src/mib.c index c21ce55..8c95a0c 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -49,6 +49,34 @@ Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id) { } +int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { + + + pdu_header->reserved_bit_0 = 0; + pdu_header->reserved_bit_1 = 0; + pdu_header->reserved_bit_2 = 0; + pdu_header->CRC_flag = remote.CRC_required; + pdu_header->direction = 1; + pdu_header->PDU_type = 0; + pdu_header->transaction_seq_num_len = 3; + pdu_header->length_of_entity_IDs = 1; + pdu_header->transmission_mode = remote.default_transmission_mode; + pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); + + if (checkAlloc(pdu_header->destination_id) < 0) + return -1; + + memcpy(pdu_header->destination_id, &remote.cfdp_id, pdu_header->length_of_entity_IDs); + + pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); + if (checkAlloc(pdu_header->source_id) < 0) + return -1; + + + memcpy(pdu_header->source_id, &my_cfdp_id, pdu_header->length_of_entity_IDs); + return 0; +} + enum { PARSE_cfdp_id, @@ -194,25 +222,6 @@ int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { } -Remote_entity *get_remote_entity2(uint32_t dest_id){ - - Remote_entity *remote = ssp_alloc(1, sizeof(Remote_entity)); - - if (remote == NULL) { - ssp_error("ssp_alloc\n"); - return NULL; - } - - int error = get_remote_entity_from_json(remote, dest_id); - if (error == -1) { - ssp_error("couldn't get remote from json\n"); - } - - return remote; - -}; - - void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header->destination_id); ssp_free(pdu_header->source_id); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 4085dee..0af1919 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -29,14 +29,14 @@ static void build_temperary_file(Request *req, uint32_t size) { static void send_ack(Request *req, Response res, unsigned int type){ - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); build_ack(req->buff, start, type); ssp_sendto(res); } static void send_nak(Request *req, Response res, unsigned int type) { - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); build_nak_directive(req->buff, start, type); ssp_sendto(res); } @@ -168,17 +168,24 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r } found_req = init_request(app->packet_len); + if (found_req == NULL) { + ssp_error("could not get allocate for new request \n"); + return -1; + } ssp_printf("incoming new request\n"); + //Make new request and add it found_req->transmission_mode = header->transmission_mode; found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; - found_req->pdu_header = get_header_from_mib(remote_entity, app->my_cfdp_id); - if (found_req->pdu_header == NULL) - ssp_printf("PDU HEADER IS NULL\n"); - + error = get_header_from_mib2(&found_req->pdu_header, remote_entity, app->my_cfdp_id); + if (error < 0) { + ssp_printf("Couldn't make PDU HEADER IS NULL\n"); + return -1; + } + found_req->remote_entity = remote_entity; @@ -303,7 +310,7 @@ static void resend_finished_ack(Request *req, Response res) { static void send_put_metadata(Request *req, Response res) { - uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, &req->pdu_header); ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(req->buff, start, req); req->local_entity.Metadata_sent_indication = true; @@ -311,7 +318,7 @@ static void send_put_metadata(Request *req, Response res) { } static void send_eof_pdu(Request *req, Response res) { - uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, &req->pdu_header); ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); if (req->file_size == 0) build_eof_packet(req->buff, start, 0, 0); @@ -334,7 +341,7 @@ static void start_sequence(Request *req, Response res) { } static void send_data(Request *req, Response res) { - uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, req->pdu_header); + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, &req->pdu_header); if (build_data_packet(req->buff, start, req->file, res.packet_len)) { req->procedure = sending_eof; @@ -518,7 +525,7 @@ static void request_metadata(Request *req, Response res) { static void request_data(Request *req, Response res) { - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); build_nak_packet(req->buff, start, req); ssp_sendto(res); @@ -527,7 +534,7 @@ static void request_data(Request *req, Response res) { static void resend_finished_pdu(Request *req, Response res) { - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); ssp_printf("sending finished pdu transaction: %d\n", req->transaction_sequence_number); build_finished_pdu(req->buff, start); ssp_sendto(res); diff --git a/Program/src/requests.c b/Program/src/requests.c index ec59f3d..88d1341 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -96,8 +96,6 @@ void ssp_cleanup_req(void *request) { if (req->file != NULL) free_file(req->file); - if (req->pdu_header != NULL) - ssp_cleanup_pdu_header(req->pdu_header); if (req->buff != NULL) ssp_free(req->buff); if (req->res.addr != NULL) @@ -200,10 +198,7 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //build a request req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity.cfdp_id; - req->pdu_header = get_header_from_mib(client->remote_entity, app->my_cfdp_id); - if (req->pdu_header ==NULL) - ssp_printf("PDU HEADER IS NULL\n"); - + req->pdu_header = *client->pdu_header; req->res.packet_len = client->packet_len; req->packet_data_len = app->packet_len; diff --git a/Program/test/mock.c b/Program/test/mock.c index 53505a7..e17b15a 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -42,8 +42,8 @@ MIB *mock_mib() { int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { - MIB *mib = mock_mib(); - Pdu_header *pdu_header = get_header_from_mib(mib, dest_id, src_id); + Pdu_header pdu_header; + int error = get_header_from_mib2(pdu_header, remote_entity, src_id); int packet_index = build_pdu_header(packet, 1, 0, pdu_header); ssp_cleanup_pdu_header(pdu_header); From 44bc07b229206d5b846ed2b5171eaac97277656a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 25 Jan 2020 14:57:24 -0700 Subject: [PATCH 168/400] change void pointer to uint32_t in Pdu_header --- Program/include/mib.h | 1 - Program/include/types.h | 2 +- Program/src/mib.c | 18 +++++------------- Program/src/packet.c | 2 +- Program/src/requests.c | 3 +++ Program/test/main.c | 4 ++-- Program/test/makefile | 6 +++--- Program/test/mib/peer_1.json | 6 +++--- Program/test/mib/peer_2.json | 23 +++++++++++++++++++++++ Program/test/packet_tests.c | 34 +++++++++++++++++----------------- Program/test/test.c | 4 ++-- Program/test/test.h | 4 ++-- 12 files changed, 62 insertions(+), 45 deletions(-) create mode 100644 Program/test/mib/peer_2.json diff --git a/Program/include/mib.h b/Program/include/mib.h index d543918..82460de 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -13,7 +13,6 @@ MIB *init_mib(void); void free_mib(MIB *mib); int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, enum Network_type, int transmission_mode); -//Pdu_header *get_header_from_mib(MIB *mib, uint32_t dest_id, uint32_t source_id); Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id); int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); diff --git a/Program/include/types.h b/Program/include/types.h index 689dc22..0ef46eb 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -52,7 +52,7 @@ typedef struct pdu_header{ unsigned int transaction_seq_num_len: 3; //variable in size, and will get memory allocated based on the length variables above - void *source_id; + uint32_t source_id; //variable in size, and will get memory allocated based on the length variables above void *transaction_sequence_number; diff --git a/Program/src/mib.c b/Program/src/mib.c index 8c95a0c..6b39419 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -38,17 +38,14 @@ Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id) { return NULL; memcpy(pdu_header->destination_id, &remote.cfdp_id, pdu_header->length_of_entity_IDs); - - pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - if (checkAlloc(pdu_header->source_id) < 0) - return NULL; - - - memcpy(pdu_header->source_id, &source_id, pdu_header->length_of_entity_IDs); + pdu_header->source_id = source_id; + return pdu_header; } + + int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { @@ -68,12 +65,8 @@ int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t memcpy(pdu_header->destination_id, &remote.cfdp_id, pdu_header->length_of_entity_IDs); - pdu_header->source_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - if (checkAlloc(pdu_header->source_id) < 0) - return -1; - + pdu_header->source_id = my_cfdp_id; - memcpy(pdu_header->source_id, &my_cfdp_id, pdu_header->length_of_entity_IDs); return 0; } @@ -224,7 +217,6 @@ int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header->destination_id); - ssp_free(pdu_header->source_id); ssp_free(pdu_header); } diff --git a/Program/src/packet.c b/Program/src/packet.c index 5deca46..d9f0738 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -35,7 +35,7 @@ uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uin //copy variable length src id memcpy(&packet[packet_index], - pdu_header->source_id, + &pdu_header->source_id, pdu_header->length_of_entity_IDs); packet_index += pdu_header->length_of_entity_IDs; diff --git a/Program/src/requests.c b/Program/src/requests.c index 88d1341..ae478d3 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -101,6 +101,9 @@ void ssp_cleanup_req(void *request) { if (req->res.addr != NULL) ssp_free(req->res.addr); + if (req->pdu_header.destination_id != NULL) + ssp_free(req->pdu_header.destination_id); + if (req->messages_to_user->count > 0) req->messages_to_user->free(req->messages_to_user, ssp_free_message); else diff --git a/Program/test/main.c b/Program/test/main.c index 105abd1..3211386 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -18,11 +18,11 @@ int main () { int error = 0; //error = request_tests(); - //error = packet_tests(); + error = packet_tests(); //error = protocol_handler_test(); //error = list_tests(); - error = file_system_tests(); + //error = file_system_tests(); //error = tasks_tests(); /* diff --git a/Program/test/makefile b/Program/test/makefile index 5f1a45a..b872bdc 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -27,14 +27,14 @@ CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -#CFILES += $(PROJDIR)/test/packet_tests.c -#CFILES += $(PROJDIR)/test/test.c +CFILES += $(PROJDIR)/test/packet_tests.c +CFILES += $(PROJDIR)/test/test.c #CFILES += $(PROJDIR)/test/mock.c #CFILES += $(PROJDIR)/test/request_tests.c #CFILES += $(PROJDIR)/test/tasks_tests.c #CFILES += $(PROJDIR)/test/list_tests.c -CFILES += $(PROJDIR)/test/filesystem_tests.c +#CFILES += $(PROJDIR)/test/filesystem_tests.c #CFILES += $(PROJDIR)/test/protocol_handler_tests.c #CFILES += $(PROJDIR)/test/list_tests.c #CFILES += $(PROJDIR)/test/server_tests.c diff --git a/Program/test/mib/peer_1.json b/Program/test/mib/peer_1.json index de16707..467b35e 100644 --- a/Program/test/mib/peer_1.json +++ b/Program/test/mib/peer_1.json @@ -1,7 +1,7 @@ { "cfdp_id": 1, "UT_address" : 2130706433, - "UT_port" : 1234, + "UT_port" : 1111, "type_of_network" : 1, "default_transmission_mode" : 1, @@ -14,8 +14,8 @@ "prompt_transmission_interval" : 123, "disposition_of_incomplete" : 123, - "CRC_required" : 1, - "max_file_segment_len" : 255, + "CRC_required" : 0, + "max_file_segment_len" : 1200, "keep_alive_discrepancy_limit" : 8, "positive_ack_timer_expiration_limit" : 123, "nak_timer_expiration_limit" : 123, diff --git a/Program/test/mib/peer_2.json b/Program/test/mib/peer_2.json new file mode 100644 index 0000000..dbf2600 --- /dev/null +++ b/Program/test/mib/peer_2.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 2, + "UT_address" : 2130706433, + "UT_port" : 1112, + "type_of_network" : 1, + "default_transmission_mode" : 1, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "max_file_segment_len" : 1200, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 6093568..5a6d6cd 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -41,7 +41,7 @@ static int test_build_eof_packet(char *packet, int packet_start) { //need to set partialcheckus to checksum, because it gets set from reading in data file->partial_checksum = check_sum_file(file, 1000); - build_eof_packet(packet, packet_start, file); + build_eof_packet(packet, packet_start, file->total_size, file->partial_checksum); int packet_index = packet_start; Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; @@ -245,13 +245,15 @@ int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_nu uint32_t packet_index = PACKET_STATIC_HEADER_LEN; ASSERT_EQUALS_INT("packet length: ", length, 9); - ASSERT_EQUALS_STR("packet source id ", &packet[packet_index], header->source_id, header->length_of_entity_IDs); + ASSERT_EQUALS_STR("packet source id ", &packet[packet_index], &header->source_id, header->length_of_entity_IDs); + + packet_index += header->length_of_entity_IDs; ASSERT_NOT_EQUALS_INT("transaction_sequence_number correctly placed ", packet[packet_index], sequence_number); packet_index += header->transaction_seq_num_len; - ASSERT_NOT_EQUALS_STR("packet destination not equal to source id ", &packet[packet_index], header->source_id, header->length_of_entity_IDs); + ASSERT_NOT_EQUALS_STR("packet destination not equal to source id ", &packet[packet_index], &header->source_id, header->length_of_entity_IDs); ASSERT_EQUALS_STR("packet destination id ", &packet[packet_index], header->destination_id, header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; @@ -444,31 +446,29 @@ int packet_tests() { printf("starting Packet Tests (creating and changing packet values)\n"); - //Memory information base - MIB *mib = init_mib(); //setting host name for testing char *host_name = "127.0.0.1"; uint32_t addr[sizeof(uint32_t)]; inet_pton(AF_INET, host_name, addr); - //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 3, *addr, 1113, posix, ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 4, *addr, 1114, posix, ACKNOWLEDGED_MODE); - - Pdu_header *pdu_header = get_header_from_mib(mib, 1, 2); - char *packet = calloc(PACKET_TEST_SIZE, sizeof(char)); uint64_t sequence_number = 12345663234; - int data_start_index = test_build_pdu_header(packet, pdu_header, sequence_number); + + Pdu_header pdu_header; + Remote_entity remote_entity; + + int error = get_remote_entity_from_json (&remote_entity, 1); + get_header_from_mib2(&pdu_header, remote_entity, 2); + + int data_start_index = test_build_pdu_header(packet, &pdu_header, sequence_number); + /* test_build_ack_eof_pdu(packet, data_start_index); test_build_nak_packet(packet, data_start_index); test_respond_to_naks(packet, data_start_index); memset(packet, 0, PACKET_TEST_SIZE); - data_start_index = test_build_pdu_header(packet, pdu_header, sequence_number); + data_start_index = test_build_pdu_header(packet, &pdu_header, sequence_number); test_build_data_packet(packet, data_start_index); test_build_metadata_packet(packet, data_start_index); @@ -478,8 +478,8 @@ int packet_tests() { test_get_message_from_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); - free_mib(mib); - ssp_cleanup_pdu_header(pdu_header); + */ + ssp_cleanup_pdu_header(&pdu_header); ssp_free(packet); return 0; diff --git a/Program/test/test.c b/Program/test/test.c index 0913701..3c1539c 100644 --- a/Program/test/test.c +++ b/Program/test/test.c @@ -54,7 +54,7 @@ int assert_not_equals_int(char *file_name, int line_num, char* description, int } -int assert_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size) { +int assert_equals_str(char *file_name, int line_num, char* description, void *val1, void* val2, size_t size) { test_num++; if (!memcmp(val1, val2, size)) { @@ -74,7 +74,7 @@ int assert_equals_str(char *file_name, int line_num, char* description, char *va return 0; } -int assert_not_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size) { +int assert_not_equals_str(char *file_name, int line_num, char* description, void *val1, void* val2, size_t size) { test_num++; if (!memcmp(val1, val2, size)) { diff --git a/Program/test/test.h b/Program/test/test.h index 546effb..5e1dc33 100644 --- a/Program/test/test.h +++ b/Program/test/test.h @@ -4,10 +4,10 @@ #include -int assert_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size); +int assert_equals_str(char *file_name, int line_num, char* description, void *val1, void* val2, size_t size); int assert_not_equals_int(char *file_name, int line_num, char* description, int val1, int val2); int assert_equals_int(char *file_name, int line_num, char* description, int val1, int val2); -int assert_not_equals_str(char *file_name, int line_num, char* description, char *val1, char* val2, size_t size); +int assert_not_equals_str(char *file_name, int line_num, char* description, void *val1, void* val2, size_t size); int assert_null(char *file_name, int line_num, char* description, void *val1); int assert_not_null(char *file_name, int line_num, char* description, void *val1); From b3e2976dec752ac03bb562d7f51583320e0cff14 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 25 Jan 2020 15:31:34 -0700 Subject: [PATCH 169/400] remove destination ID pointer --- Program/include/types.h | 9 +++++---- Program/src/mib.c | 17 ++--------------- Program/src/mib/peer_1.json | 6 +++--- Program/src/mib/peer_2.json | 23 +++++++++++++++++++++++ Program/src/packet.c | 2 +- Program/src/requests.c | 3 --- Program/test/packet_tests.c | 2 +- 7 files changed, 35 insertions(+), 27 deletions(-) create mode 100644 Program/src/mib/peer_2.json diff --git a/Program/include/types.h b/Program/include/types.h index 0ef46eb..6f22d1b 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -51,14 +51,15 @@ typedef struct pdu_header{ //number of octets in sequence number, 0 is one octet unsigned int transaction_seq_num_len: 3; - //variable in size, and will get memory allocated based on the length variables above + //variable in size (for actual packet), and will get memory allocated based on the length variables above uint32_t source_id; - //variable in size, and will get memory allocated based on the length variables above + //variable in size (for actual packet), and will get memory allocated based on the length variables above void *transaction_sequence_number; - //variable in size, and will get memory allocated based on the length variables above - void *destination_id; + //variable in size (for actual packet), and will get memory allocated based on the length variables above + uint32_t destination_id; + } Pdu_header; typedef struct originating_tranaction_id_message { diff --git a/Program/src/mib.c b/Program/src/mib.c index 6b39419..0341a51 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -32,12 +32,7 @@ Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id) { pdu_header->transaction_seq_num_len = 3; pdu_header->length_of_entity_IDs = 1; pdu_header->transmission_mode = remote.default_transmission_mode; - pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - - if (checkAlloc(pdu_header->destination_id) < 0) - return NULL; - - memcpy(pdu_header->destination_id, &remote.cfdp_id, pdu_header->length_of_entity_IDs); + pdu_header->destination_id = remote.cfdp_id; pdu_header->source_id = source_id; return pdu_header; @@ -48,7 +43,6 @@ Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id) { int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { - pdu_header->reserved_bit_0 = 0; pdu_header->reserved_bit_1 = 0; pdu_header->reserved_bit_2 = 0; @@ -58,13 +52,7 @@ int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t pdu_header->transaction_seq_num_len = 3; pdu_header->length_of_entity_IDs = 1; pdu_header->transmission_mode = remote.default_transmission_mode; - pdu_header->destination_id = ssp_alloc(pdu_header->length_of_entity_IDs, sizeof(u_int8_t)); - - if (checkAlloc(pdu_header->destination_id) < 0) - return -1; - - memcpy(pdu_header->destination_id, &remote.cfdp_id, pdu_header->length_of_entity_IDs); - + pdu_header->destination_id = remote.cfdp_id; pdu_header->source_id = my_cfdp_id; return 0; @@ -216,7 +204,6 @@ int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { - ssp_free(pdu_header->destination_id); ssp_free(pdu_header); } diff --git a/Program/src/mib/peer_1.json b/Program/src/mib/peer_1.json index de16707..467b35e 100644 --- a/Program/src/mib/peer_1.json +++ b/Program/src/mib/peer_1.json @@ -1,7 +1,7 @@ { "cfdp_id": 1, "UT_address" : 2130706433, - "UT_port" : 1234, + "UT_port" : 1111, "type_of_network" : 1, "default_transmission_mode" : 1, @@ -14,8 +14,8 @@ "prompt_transmission_interval" : 123, "disposition_of_incomplete" : 123, - "CRC_required" : 1, - "max_file_segment_len" : 255, + "CRC_required" : 0, + "max_file_segment_len" : 1200, "keep_alive_discrepancy_limit" : 8, "positive_ack_timer_expiration_limit" : 123, "nak_timer_expiration_limit" : 123, diff --git a/Program/src/mib/peer_2.json b/Program/src/mib/peer_2.json new file mode 100644 index 0000000..dbf2600 --- /dev/null +++ b/Program/src/mib/peer_2.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 2, + "UT_address" : 2130706433, + "UT_port" : 1112, + "type_of_network" : 1, + "default_transmission_mode" : 1, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "max_file_segment_len" : 1200, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/src/packet.c b/Program/src/packet.c index d9f0738..36952cd 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -47,7 +47,7 @@ uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uin //copy variable length destination id memcpy(&packet[packet_index], - pdu_header->destination_id, + &pdu_header->destination_id, pdu_header->length_of_entity_IDs); uint8_t total_bytes = PACKET_STATIC_HEADER_LEN diff --git a/Program/src/requests.c b/Program/src/requests.c index ae478d3..73ab9e1 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -100,9 +100,6 @@ void ssp_cleanup_req(void *request) { ssp_free(req->buff); if (req->res.addr != NULL) ssp_free(req->res.addr); - - if (req->pdu_header.destination_id != NULL) - ssp_free(req->pdu_header.destination_id); if (req->messages_to_user->count > 0) req->messages_to_user->free(req->messages_to_user, ssp_free_message); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 5a6d6cd..4ff06fb 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -254,7 +254,7 @@ int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_nu packet_index += header->transaction_seq_num_len; ASSERT_NOT_EQUALS_STR("packet destination not equal to source id ", &packet[packet_index], &header->source_id, header->length_of_entity_IDs); - ASSERT_EQUALS_STR("packet destination id ", &packet[packet_index], header->destination_id, header->length_of_entity_IDs); + ASSERT_EQUALS_STR("packet destination id ", &packet[packet_index], &header->destination_id, header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; Pdu_header *new_header = (Pdu_header *)packet; From 01df2cfbc3e2a999058c3ee1c6b29d833adf533e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 25 Jan 2020 15:44:21 -0700 Subject: [PATCH 170/400] remove pdu memory allocations --- Program/include/mib.h | 4 ---- Program/include/types.h | 2 +- Program/src/file_delivery_app.c | 3 ++- Program/src/mib.c | 28 ---------------------------- Program/src/protocol_handler.c | 5 +---- Program/src/requests.c | 2 +- Program/src/tasks.c | 1 - 7 files changed, 5 insertions(+), 40 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 82460de..6da922e 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -10,10 +10,6 @@ #include "packet.h" #include "types.h" -MIB *init_mib(void); -void free_mib(MIB *mib); -int add_new_cfdp_entity(MIB *mib, uint32_t cfdp_id, uint32_t UT_address, uint16_t port, enum Network_type, int transmission_mode); -Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id); int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); diff --git a/Program/include/types.h b/Program/include/types.h index 6f22d1b..971010f 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -657,7 +657,7 @@ typedef struct client { Remote_entity remote_entity; //packet header, useful for copying into outgoing packets - Pdu_header *pdu_header; + Pdu_header pdu_header; FTP *app; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index e827524..9bb9878 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -88,7 +88,8 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { } client->remote_entity = remote_entity; - client->pdu_header = get_header_from_mib(remote_entity, app->my_cfdp_id); + get_header_from_mib2(&client->pdu_header, remote_entity, app->my_cfdp_id); + client->app = app; if (remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { diff --git a/Program/src/mib.c b/Program/src/mib.c index 0341a51..ac7adb8 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -12,34 +12,6 @@ //snprintf #include "stdio.h" -Pdu_header *get_header_from_mib (Remote_entity remote, uint32_t source_id) { - - - Pdu_header *pdu_header = ssp_alloc(1, sizeof(Pdu_header)); - if (pdu_header == NULL) - return NULL; - - if (checkAlloc(pdu_header) < 0) - return NULL; - - - pdu_header->reserved_bit_0 = 0; - pdu_header->reserved_bit_1 = 0; - pdu_header->reserved_bit_2 = 0; - pdu_header->CRC_flag = remote.CRC_required; - pdu_header->direction = 1; - pdu_header->PDU_type = 0; - pdu_header->transaction_seq_num_len = 3; - pdu_header->length_of_entity_IDs = 1; - pdu_header->transmission_mode = remote.default_transmission_mode; - pdu_header->destination_id = remote.cfdp_id; - pdu_header->source_id = source_id; - - return pdu_header; - -} - - int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 0af1919..e293830 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -363,11 +363,8 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien if (req->buff == NULL){ ssp_printf("req->buff is null\n"); } - if (client->pdu_header == NULL){ - ssp_printf("pdu_header is null\n"); - } - uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, client->pdu_header); + uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, &client->pdu_header); uint32_t offset_start = 0; uint32_t offset_end = 0; diff --git a/Program/src/requests.c b/Program/src/requests.c index 73ab9e1..1189a39 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -198,7 +198,7 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //build a request req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity.cfdp_id; - req->pdu_header = *client->pdu_header; + req->pdu_header = client->pdu_header; req->res.packet_len = client->packet_len; req->packet_data_len = app->packet_len; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 6adc07c..cdc1e60 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -462,6 +462,5 @@ void ssp_cleanup_ftp(FTP *app) { void ssp_cleanup_client(Client *client) { client->request_list->free(client->request_list, ssp_cleanup_req); - ssp_cleanup_pdu_header(client->pdu_header); } From f1d0a76cc5a5c49fd9d90d0828319eedba866b38 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 28 Jan 2020 20:42:25 -0700 Subject: [PATCH 171/400] Add frees in case of inpropper allocations --- Program/src/list.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Program/src/list.c b/Program/src/list.c index 25cf83c..64b671d 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -287,17 +287,22 @@ static Node *findNode(List *list, uint32_t id, int (*f)(void *element, void *arg List *linked_list() { - List *newList = calloc(sizeof(List), 1); + List *newList = ssp_alloc(sizeof(List), 1); if (newList == NULL) return NULL; newList->head = createNode(NULL, 0); - if (newList->head == NULL) + if (newList->head == NULL) { + ssp_free(newList); return NULL; + } newList->tail = createNode(NULL, 0); - if (newList->tail == NULL) + if (newList->tail == NULL) { + ssp_free(newList->head); + ssp_free(newList); return NULL; + } Node *tail = newList->tail; Node *head = newList->head; From 12c545209c32f433724bd1ade014060077e657a4 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 28 Jan 2020 20:45:08 -0700 Subject: [PATCH 172/400] add allocation port functions --- Program/src/list.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Program/src/list.c b/Program/src/list.c index 64b671d..94b830e 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -5,6 +5,7 @@ #include #include #include +#include "port.h" /*------------------------------------------------------------------------------ This function creates a new node to add into the linked list, returns the @@ -13,7 +14,7 @@ Node *createNode(void *element, uint32_t id) { - Node *newNode = calloc(sizeof(Node), 1); + Node *newNode = ssp_alloc(sizeof(Node), 1); if (newNode == NULL) { return NULL; } @@ -33,7 +34,7 @@ Node *createNode(void *element, uint32_t id) static void freeNode(Node *node) { if (node != NULL) - free(node); + ssp_free(node); } static void *pop(List *list) { @@ -185,9 +186,9 @@ static void freeList(List *list, void (*f)(void *element)) f(n->element); freeNode(n); } - free(list->head); - free(list->tail); - free(list); + ssp_free(list->head); + ssp_free(list->tail); + ssp_free(list); } @@ -201,9 +202,9 @@ static void freeNodes(List *list) { cur = cur->next; freeNode(n); } - free(list->head); - free(list->tail); - free(list); + ssp_free(list->head); + ssp_free(list->tail); + ssp_free(list); } From 37e5f892d1ea976d1588cd8c1f79e82edfec2c06 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 11:35:27 -0700 Subject: [PATCH 173/400] Change name to get_header_from_mib --- Program/include/mib.h | 2 +- Program/src/mib.c | 2 +- Program/src/port.c | 2 +- Program/src/protocol_handler.c | 2 +- Program/test/packet_tests.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 6da922e..af1ddc2 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -10,7 +10,7 @@ #include "packet.h" #include "types.h" -int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); +int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); diff --git a/Program/src/mib.c b/Program/src/mib.c index ac7adb8..0803276 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -13,7 +13,7 @@ #include "stdio.h" -int get_header_from_mib2 (Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { +int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { pdu_header->reserved_bit_0 = 0; pdu_header->reserved_bit_1 = 0; diff --git a/Program/src/port.c b/Program/src/port.c index 6b82bda..a5cb8f5 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -255,7 +255,7 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { #ifdef POSIX_PORT void *mem = calloc(n_memb, size); if (mem == NULL) - ssp_printf("Memory failed to alloc!\n"); + ssp_error("Memory failed to alloc!\n"); return mem; #endif diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e293830..2863fb8 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -180,7 +180,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; - error = get_header_from_mib2(&found_req->pdu_header, remote_entity, app->my_cfdp_id); + error = get_header_from_mib(&found_req->pdu_header, remote_entity, app->my_cfdp_id); if (error < 0) { ssp_printf("Couldn't make PDU HEADER IS NULL\n"); return -1; diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 4ff06fb..d740693 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -459,7 +459,7 @@ int packet_tests() { Remote_entity remote_entity; int error = get_remote_entity_from_json (&remote_entity, 1); - get_header_from_mib2(&pdu_header, remote_entity, 2); + get_header_from_mib(&pdu_header, remote_entity, 2); int data_start_index = test_build_pdu_header(packet, &pdu_header, sequence_number); /* From 127c954eb4f3462479e7627d04bb2698ffd6377b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 11:35:35 -0700 Subject: [PATCH 174/400] Add memory failurehandling --- Program/src/file_delivery_app.c | 36 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 9bb9878..f079d86 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -37,16 +37,24 @@ FTP *init_ftp(uint32_t my_cfdp_address) { } FTP *app = ssp_alloc(sizeof(FTP), 1); + if (app == NULL) + return NULL; + app->packet_len = PACKET_LEN; app->my_cfdp_id = my_cfdp_address; app->close = false; app->remote_entity = remote_entity; + app->active_clients = linked_list(); + if (app->active_clients == NULL) + return NULL; + app->request_list = linked_list(); - app->current_request = NULL; + if (app->request_list == NULL) + return NULL; + app->current_request = NULL; ssp_server(app); - return app; } @@ -70,25 +78,29 @@ void ssp_server(FTP *app) { Client *ssp_client(uint32_t cfdp_id, FTP *app) { + Remote_entity remote_entity; + int error = get_remote_entity_from_json(&remote_entity, cfdp_id); + if (error < 0) { + ssp_error("couldn't get client remote_entity from mib\n"); + return NULL; + } + Client *client = ssp_alloc(sizeof(Client), 1); - if (checkAlloc(client) < 0) + if (client == NULL) return NULL; client->current_request = NULL; client->request_list = linked_list(); - client->packet_len = PACKET_LEN; - - //Remote_entity *remote_entity = ssp_alloc(1, sizeof(Remote_entity)); - Remote_entity remote_entity; - int error = get_remote_entity_from_json(&remote_entity, cfdp_id); - if (error < 0) { - ssp_error("couldn't get client remote_entity from mib\n"); + if (client->request_list == NULL) { + ssp_free(client); return NULL; } - + + client->packet_len = PACKET_LEN; client->remote_entity = remote_entity; - get_header_from_mib2(&client->pdu_header, remote_entity, app->my_cfdp_id); + + get_header_from_mib(&client->pdu_header, remote_entity, app->my_cfdp_id); client->app = app; From 9dfacd69f544ba465fc1b39ec62b0be4ec8ddf2b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 11:54:29 -0700 Subject: [PATCH 175/400] change/limit client parameteres --- Program/include/server.h | 16 ++++++++-------- Program/src/server.c | 38 +++++++++++++++++++------------------- Program/src/tasks.c | 11 ++--------- 3 files changed, 29 insertions(+), 36 deletions(-) diff --git a/Program/include/server.h b/Program/include/server.h index 0ea64e4..f4da79b 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -51,10 +51,10 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, void (*onExit)(void *other), void *other); -void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), +void connection_client(char *hostname, char*port, int packet_len, void *params, + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *params), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , + int (*checkExit)(void *params), void (*onExit)(void *params)); /*-----------------------------CALLBACK onTimeOut------------------------------- @@ -68,10 +68,10 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa int *prepareSignalHandler(void); -void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), +void connectionless_client(char *hostname, char*port, int packet_len, void *params, + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *params), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , + int (*checkExit)(void *params), void (*onExit)(void *params)); //#ifdef CSP_NETWORK diff --git a/Program/src/server.c b/Program/src/server.c index f5adf97..19282df 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -364,10 +364,10 @@ void connectionless_server(char* port, int initial_buff_size, //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void connectionless_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), +void connectionless_client(char *hostname, char*port, int packet_len, void *params, + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *params), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , + int (*checkExit)(void *params), void (*onExit)(void *params)) { @@ -392,14 +392,14 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe for (;;) { - if (exit_now || checkExit(checkExitParams)) + if (exit_now || checkExit(params)) break; if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ ssp_error("packet too large, cannot resize buffer\n"); } - if (onSend(sfd, addr, size_of_addr, onSendParams)) + if (onSend(sfd, addr, size_of_addr, params)) ssp_error("send failed\n"); count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, addr, &size_of_addr); @@ -412,7 +412,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe continue; } else{ - if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, onRecvParams) == -1) + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, params) == -1) ssp_error("recv failed\n"); } @@ -422,15 +422,15 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *onSe free(buff_size); free(buff); ssp_close(sfd); - onExit(onExitParams); + onExit(params); } //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void connection_client(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, - int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), +void connection_client(char *hostname, char*port, int packet_len, void *params, + int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *params), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , + int (*checkExit)(void *params), void (*onExit)(void *params)) { @@ -455,14 +455,14 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa for (;;) { - if (exit_now || checkExit(checkExitParams)) + if (exit_now || checkExit(params)) break; if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ ssp_printf("packet too large, cannot resize buffer\n"); } - if (onSend(sfd, addr, size_of_addr, onSendParams)) + if (onSend(sfd, addr, size_of_addr, params)) ssp_error("send failed here\n"); count = ssp_recvfrom(sfd, buff, packet_len, MSG_DONTWAIT, NULL, &size_of_addr); @@ -470,7 +470,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa if (count < 0) continue; - if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, onRecvParams) == -1) { + if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, params) == -1) { ssp_error("recv failed\n"); exit_now = 1; } @@ -480,7 +480,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa free(buff_size); free(buff); ssp_close(sfd); - onExit(onExitParams); + onExit(params); } /*------------------------------------------------------------------------------ @@ -493,9 +493,9 @@ void connection_client(char *hostname, char*port, int packet_len, void *onSendPa //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, - int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *params), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , + int (*checkExit)(void *params), void (*onExit)(void *params), void *params) { diff --git a/Program/src/tasks.c b/Program/src/tasks.c index cdc1e60..9921d5c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -296,20 +296,16 @@ void *ssp_connectionless_client_task(void* params){ char port[10]; //convert int to char * - snprintf(port, 10, "%d", client->remote_entity.UT_port); + int error = snprintf(port, 10, "%d", client->remote_entity.UT_port); uint32_t ut_addr = htonl(client->remote_entity.UT_address); //convert uint id to char * inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); - connectionless_client(host_name, port, client->packet_len, client, - client, - client, - client, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, @@ -357,10 +353,7 @@ void *ssp_connection_client_task(void *params) { connection_client(host_name, port, client->packet_len, - client, - client, - client, - client, + client, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, From 04f1a04ef4588ae2a12f70de5cf9c7d331d34946 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 14:09:14 -0700 Subject: [PATCH 176/400] moved all client cleanup to single function --- Program/include/tasks.h | 3 +-- Program/src/tasks.c | 37 ++++++++++++++++++++----------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Program/include/tasks.h b/Program/include/tasks.h index e5e99d7..d5d449e 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -17,8 +17,7 @@ void *ssp_csp_connectionless_client_task(void *params); void *ssp_csp_connectionless_server_task(void *params); void *ssp_csp_connection_client_task(void *params); void *ssp_csp_connection_server_task(void *params); - -void ssp_join_clients(List *clients); +void ssp_client_join(Client *client); void remove_request_check(Node *node, void *request, void *args); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 9921d5c..ebeb67f 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -107,7 +107,6 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u void remove_request_check(Node *node, void *request, void *args) { Request *req = (Request *) request; List *req_list = (List *) args; - //print_request_procedure(req); if (req->procedure == clean_up) { ssp_printf("removing request\n"); @@ -176,8 +175,7 @@ static void client_check_callback(Node *node, void *client, void *args) { if (c->close) { Client *remove_this = (Client *) list->removeNode(list, node); ssp_printf("removing client, from server \n"); - ssp_thread_join(c->client_handle); - ssp_free(remove_this); + ssp_client_join(remove_this); } } @@ -212,8 +210,7 @@ static int check_exit_client_callback(void *params) { } static void on_exit_client_callback (void *params) { - Client *client = (Client*) params; - ssp_cleanup_client(client); + } static void on_exit_server_callback (void *params) { @@ -273,8 +270,13 @@ void *ssp_connectionless_server_task(void *params) { app->transaction_sequence_number = 1; char port[10]; - snprintf(port, 10, "%d",app->remote_entity.UT_port); - + //convert to a string for the connectionless_server function + int error = snprintf(port, 10, "%d",app->remote_entity.UT_port); + if (error < 0) { + ssp_cleanup_ftp(app); + return NULL; + } + connectionless_server(port, app->packet_len, on_recv_server_callback, @@ -297,6 +299,11 @@ void *ssp_connectionless_client_task(void* params){ //convert int to char * int error = snprintf(port, 10, "%d", client->remote_entity.UT_port); + if (error < 0) { + ssp_cleanup_client(client); + return NULL; + } + uint32_t ut_addr = htonl(client->remote_entity.UT_address); //convert uint id to char * @@ -430,13 +437,14 @@ void *ssp_csp_connection_client_task(void *params) { ------------------------------------------------------------------------------*/ -static void ssp_client_join(Node *node, void *element, void*args) { - Client *client = (Client *) element; - ssp_thread_join(client->client_handle); +void ssp_cleanup_client(Client *client) { + client->request_list->free(client->request_list, ssp_cleanup_req); + ssp_free(client); } +void ssp_client_join(Client *client) { -void ssp_join_clients(List *clients) { - clients->iterate(clients, ssp_client_join, NULL); + ssp_thread_join(client->client_handle); + ssp_cleanup_client(client); } static void exit_client(Node *node, void *element, void *args) { @@ -452,8 +460,3 @@ void ssp_cleanup_ftp(FTP *app) { app->active_clients->freeOnlyList(app->active_clients); ssp_free(app); } - -void ssp_cleanup_client(Client *client) { - client->request_list->free(client->request_list, ssp_cleanup_req); - -} From 306d563eb2cbbb2987087fdaa5c9facc110715df Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 14:24:33 -0700 Subject: [PATCH 177/400] add some error prevention --- Program/src/tasks.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index ebeb67f..55f8d45 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -307,7 +307,11 @@ void *ssp_connectionless_client_task(void* params){ uint32_t ut_addr = htonl(client->remote_entity.UT_address); //convert uint id to char * - inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); + void *ret = inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); + if (ret == NULL) { + ssp_error("inet_ntop"); + return NULL; + } connectionless_client(host_name, port, @@ -351,11 +355,19 @@ void *ssp_connection_client_task(void *params) { char port[10]; //convert int to char * - snprintf(port, 10, "%d", client->remote_entity.UT_port); + int error = snprintf(port, 10, "%d", client->remote_entity.UT_port); + if (error < 0) { + ssp_cleanup_client(client); + return NULL; + } uint32_t ut_addr = htonl(client->remote_entity.UT_address); //convert uint id to char * - inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); + void *ret = inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); + if (ret == NULL) { + ssp_error("inet_ntop"); + return NULL; + } connection_client(host_name, port, From 4f2a86629672babd92a8a9169b2e1ba2abaf3368 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 14:48:28 -0700 Subject: [PATCH 178/400] add ip converting function --- Program/include/server.h | 2 +- Program/src/server.c | 4 +-- Program/src/tasks.c | 68 ++++++++++++++++++++++------------------ 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/Program/include/server.h b/Program/include/server.h index f4da79b..8b09522 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -35,7 +35,7 @@ This file is the header file for server.c Return: None ------------------------------------------------------------------------------*/ -void connectionless_server(char* port, int initial_buff_size, +void connectionless_server(char *host_name, char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), diff --git a/Program/src/server.c b/Program/src/server.c index 19282df..3a5ebe5 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -271,7 +271,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, //see header file -void connectionless_server(char* port, int initial_buff_size, +void connectionless_server(char *host_name, char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -283,7 +283,7 @@ void connectionless_server(char* port, int initial_buff_size, uint32_t size_of_addr = 0; void *addr = ssp_init_sockaddr_struct((size_t*)&size_of_addr); - int sfd = prepareHost(NULL, addr, &size_of_addr, port, SOCK_DGRAM, 1); + int sfd = prepareHost(host_name, addr, &size_of_addr, port, SOCK_DGRAM, 1); if (sfd < 0) exit_now = 1; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 55f8d45..2eb7eb3 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -264,20 +264,44 @@ static int on_stdin_callback(void *other) { Tasks ------------------------------------------------------------------------------*/ + + + +static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port){ + //convert int to char * + int error = snprintf(port, 10, "%d", remote_entity.UT_port); + if (error < 0) { + ssp_error("snprintf"); + return -1; + } + + uint32_t ut_addr = htonl(remote_entity.UT_address); + + //convert uint id to char * + const char *ret = inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); + if (ret == NULL) { + ssp_error("inet_ntop"); + return -1; + } + return 0; +} +//------------------------------------------------------------------------------ + + void *ssp_connectionless_server_task(void *params) { ssp_printf("starting posix connectionless server task\n"); FTP* app = (FTP*) params; app->transaction_sequence_number = 1; char port[10]; - //convert to a string for the connectionless_server function - int error = snprintf(port, 10, "%d",app->remote_entity.UT_port); + char host_name[INET_ADDRSTRLEN]; + + int error = get_ip_port(app->remote_entity, host_name, port); if (error < 0) { - ssp_cleanup_ftp(app); return NULL; } - connectionless_server(port, + connectionless_server(host_name, port, app->packet_len, on_recv_server_callback, on_time_out_callback_server, @@ -294,25 +318,14 @@ void *ssp_connectionless_client_task(void* params){ ssp_printf("starting posix connectionless client task \n"); Client *client = (Client *) params; - char host_name[INET_ADDRSTRLEN]; char port[10]; + char host_name[INET_ADDRSTRLEN]; - //convert int to char * - int error = snprintf(port, 10, "%d", client->remote_entity.UT_port); + int error = get_ip_port(client->remote_entity, host_name, port); if (error < 0) { - ssp_cleanup_client(client); return NULL; } - uint32_t ut_addr = htonl(client->remote_entity.UT_address); - - //convert uint id to char * - void *ret = inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); - if (ret == NULL) { - ssp_error("inet_ntop"); - return NULL; - } - connectionless_client(host_name, port, client->packet_len, @@ -331,7 +344,12 @@ void *ssp_connection_server_task(void *params) { app->transaction_sequence_number = 1; char port[10]; - snprintf(port, 10, "%u",app->remote_entity.UT_port); + char host_name[INET_ADDRSTRLEN]; + + int error = get_ip_port(app->remote_entity, host_name, port); + if (error < 0) { + return NULL; + } //1024 is the connection max limit connection_server(port, @@ -351,21 +369,11 @@ void *ssp_connection_client_task(void *params) { ssp_printf("starting posix connection client\n"); Client *client = (Client *) params; - char host_name[INET_ADDRSTRLEN]; char port[10]; + char host_name[INET_ADDRSTRLEN]; - //convert int to char * - int error = snprintf(port, 10, "%d", client->remote_entity.UT_port); + int error = get_ip_port(client->remote_entity, host_name, port); if (error < 0) { - ssp_cleanup_client(client); - return NULL; - } - - uint32_t ut_addr = htonl(client->remote_entity.UT_address); - //convert uint id to char * - void *ret = inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); - if (ret == NULL) { - ssp_error("inet_ntop"); return NULL; } From 16f7f7f90eb19b2f947621cf81728e4d13ce10e5 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 14:57:34 -0700 Subject: [PATCH 179/400] add propper server ip binding, and harden tasks --- Program/include/server.h | 23 +++++++++++------------ Program/src/server.c | 4 ++-- Program/src/tasks.c | 4 ++++ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Program/include/server.h b/Program/include/server.h index 8b09522..4d50d84 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -12,6 +12,7 @@ This file is the header file for server.c #include +int *prepareSignalHandler(void); /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. Perameters: int sfd: The socket descriptor created by prepareUdpHost @@ -35,6 +36,15 @@ This file is the header file for server.c Return: None ------------------------------------------------------------------------------*/ +/*-----------------------------CALLBACK onTimeOut------------------------------- + Purpose: This is a simple udp client + Perameters: hostname is the name of an address eg, 127.0.0.1, port is the por + channel_size is the size of the channel in bytes + eg, 1111 + Return: None +------------------------------------------------------------------------------*/ + + void connectionless_server(char *host_name, char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), @@ -43,7 +53,7 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, void (*onExit)(void *other), void *other); -void connection_server(char* port, int initial_buff_size, int connection_limit, +void connection_server(char *host_name, char* port, int initial_buff_size, int connection_limit, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -57,17 +67,6 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, int (*checkExit)(void *params), void (*onExit)(void *params)); -/*-----------------------------CALLBACK onTimeOut------------------------------- - Purpose: This is a simple udp client - Perameters: hostname is the name of an address eg, 127.0.0.1, port is the por - channel_size is the size of the channel in bytes - eg, 1111 - Return: None -------------------------------------------------------------------------------*/ - - -int *prepareSignalHandler(void); - void connectionless_client(char *hostname, char*port, int packet_len, void *params, int (*onSend)(int sfd, void *addr, size_t size_of_addr, void *params), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , diff --git a/Program/src/server.c b/Program/src/server.c index 3a5ebe5..6544f2a 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -157,7 +157,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf return 1; } //see header file -void connection_server(char* port, int initial_buff_size, int connection_limit, +void connection_server(char *host_name, char* port, int initial_buff_size, int connection_limit, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -168,7 +168,7 @@ void connection_server(char* port, int initial_buff_size, int connection_limit, uint32_t size_of_addr = 0; void *addr = ssp_init_sockaddr_struct((size_t*)&size_of_addr); - int sfd = prepareHost(NULL, addr, &size_of_addr, port, SOCK_STREAM, 1); + int sfd = prepareHost(host_name, addr, &size_of_addr, port, SOCK_STREAM, 1); if (sfd < 0) exit_now = 1; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 2eb7eb3..e0cba08 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -298,6 +298,7 @@ void *ssp_connectionless_server_task(void *params) { int error = get_ip_port(app->remote_entity, host_name, port); if (error < 0) { + ssp_cleanup_ftp(app); return NULL; } @@ -323,6 +324,7 @@ void *ssp_connectionless_client_task(void* params){ int error = get_ip_port(client->remote_entity, host_name, port); if (error < 0) { + ssp_cleanup_client(client); return NULL; } @@ -348,6 +350,7 @@ void *ssp_connection_server_task(void *params) { int error = get_ip_port(app->remote_entity, host_name, port); if (error < 0) { + ssp_cleanup_ftp(app); return NULL; } @@ -374,6 +377,7 @@ void *ssp_connection_client_task(void *params) { int error = get_ip_port(client->remote_entity, host_name, port); if (error < 0) { + ssp_cleanup_client(client); return NULL; } From 9210397e7f7ebcf7cdb3f8a433fbb0e4d5193b5f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 1 Feb 2020 15:06:09 -0700 Subject: [PATCH 180/400] Missed this --- Program/src/tasks.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index e0cba08..004e68c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -41,8 +41,6 @@ static void timeout(Request *req) { } } - - static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { FTP *app = (FTP *) other; From cdaf2ddb3f993fdc51f616137e75878ed9c8c7ad Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 9 Feb 2020 12:30:41 -0700 Subject: [PATCH 181/400] split process header function --- Program/include/protocol_handler.h | 5 ++ Program/src/port.c | 4 ++ Program/src/protocol_handler.c | 104 ++++++++++++++++++----------- Program/src/requests.c | 19 +++--- Program/src/server.c | 58 ++++++++-------- Program/src/tasks.c | 15 +++-- 6 files changed, 119 insertions(+), 86 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 7ef5b0a..c1b8f1a 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -15,6 +15,11 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); void process_pdu_eof(char *packet, Request *req, Response res); + Request *add_new_incomming_request(uint32_t source_id, + uint32_t transmission_mode, + uint32_t transaction_sequence_number, + Response res, + FTP *app); uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); void process_messages(Request *req, FTP *app); diff --git a/Program/src/port.c b/Program/src/port.c index a5cb8f5..92e27bf 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -267,6 +267,9 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { void ssp_free(void *pointer) { + if (pointer == NULL) + return; + #ifdef POSIX_PORT free(pointer); #endif @@ -381,6 +384,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void } + //not required for Free_rtos void ssp_thread_join(void *thread_handle) { #ifdef POSIX_PORT diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2863fb8..db9938f 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -110,6 +110,59 @@ Request *parse_pdu_header(char*packet, uint8_t is_server, Response res, Request //------------------------------------------------------------------------------ + Request *add_new_incomming_request(uint32_t source_id, + uint32_t transmission_mode, + uint32_t transaction_sequence_number, + Response res, + FTP *app) { + + Remote_entity remote_entity; + int error = get_remote_entity_from_json(&remote_entity, source_id); + if (error < 0) { + ssp_error("could not get remote entity for incoming packet \n"); + return NULL; + } + Pdu_header pdu_header; + error = get_header_from_mib(&pdu_header, remote_entity, app->my_cfdp_id); + if (error < 0) { + ssp_printf("Couldn't make PDU HEADER IS NULL\n"); + return NULL; + } + + Request *found_req = init_request(app->packet_len); + if (found_req == NULL) { + ssp_error("could not get allocate for new request \n"); + return NULL; + } + + ssp_printf("incoming new request\n"); + + //Make new request and add it + found_req->transmission_mode = transmission_mode; + found_req->transaction_sequence_number = transaction_sequence_number; + found_req->dest_cfdp_id = source_id; + found_req->pdu_header = pdu_header; + + found_req->remote_entity = remote_entity; + found_req->procedure = sending_put_metadata; + + found_req->res.addr = ssp_alloc(1, res.size_of_addr); + + if (found_req == NULL) { + ssp_cleanup_req(found_req); + NULL; + } + + memcpy(found_req->res.addr, res.addr, res.size_of_addr); + + found_req->res.packet_len = app->packet_len; + found_req->res.sfd = res.sfd; + found_req->res.transmission_mode = app->remote_entity.default_transmission_mode; + found_req->res.type_of_network = app->remote_entity.type_of_network; + found_req->paused = false; + return found_req; +} + /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet @@ -138,15 +191,13 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r } uint16_t len = get_data_length(packet); - int error = 0; //if packet is from the same request, don't' change current request - /* - if (request != NULL && request->transaction_sequence_number == transaction_sequence_number && request->dest_cfdp_id == source_id){ + Request *current_req = (*req); + if (current_req != NULL && current_req->transaction_sequence_number == transaction_sequence_number && current_req->dest_cfdp_id == source_id){ (*req)->packet_data_len = len; return packet_index; } - */ //look for active request in list struct request_search_params params = { @@ -155,54 +206,27 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r }; Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); - Remote_entity remote_entity; //server side, receiving requests (this should be its own function) if (found_req == NULL && is_server) { - - error = get_remote_entity_from_json(&remote_entity, source_id); - if (error < 0) { - ssp_error("could not get remote entity for incoming packet \n"); - return -1; - } + + found_req = add_new_incomming_request(source_id, + header->transmission_mode, + transaction_sequence_number, + res, + app); - found_req = init_request(app->packet_len); if (found_req == NULL) { - ssp_error("could not get allocate for new request \n"); + ssp_error("could not create request for incomming transmission"); return -1; } - - ssp_printf("incoming new request\n"); - - //Make new request and add it - found_req->transmission_mode = header->transmission_mode; - found_req->transaction_sequence_number = transaction_sequence_number; - found_req->dest_cfdp_id = source_id; - error = get_header_from_mib(&found_req->pdu_header, remote_entity, app->my_cfdp_id); - if (error < 0) { - ssp_printf("Couldn't make PDU HEADER IS NULL\n"); - return -1; - } - - - found_req->remote_entity = remote_entity; - - found_req->procedure = sending_put_metadata; - found_req->res.addr = ssp_alloc(1, res.size_of_addr); - - memcpy(found_req->res.addr, res.addr, res.size_of_addr); - found_req->res.packet_len = app->packet_len; - found_req->res.sfd = res.sfd; - found_req->res.transmission_mode = app->remote_entity.default_transmission_mode; - found_req->res.type_of_network = app->remote_entity.type_of_network; - found_req->paused = false; - request_list->push(request_list, found_req, transaction_sequence_number); + app->request_list->push(app->request_list, found_req, transaction_sequence_number); } else if (found_req == NULL) { - ssp_printf("could not find request \n"); + ssp_error("could not find request \n"); return -1; } diff --git a/Program/src/requests.c b/Program/src/requests.c index 1189a39..b2f39d1 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -96,18 +96,15 @@ void ssp_cleanup_req(void *request) { if (req->file != NULL) free_file(req->file); - if (req->buff != NULL) - ssp_free(req->buff); - if (req->res.addr != NULL) - ssp_free(req->res.addr); if (req->messages_to_user->count > 0) req->messages_to_user->free(req->messages_to_user, ssp_free_message); else req->messages_to_user->freeOnlyList(req->messages_to_user); - if (req != NULL) - ssp_free(req); + ssp_free(req->buff); + ssp_free(req->res.addr); + ssp_free(req); } @@ -120,7 +117,9 @@ Request *init_request(uint32_t buff_len) { req->file = NULL; req->buff_len = buff_len; req->buff = ssp_alloc(buff_len, sizeof(char)); - + if (req->buff == NULL) + return NULL; + req->procedure = none; req->paused = true; reset_timeout(&req->timeout); @@ -128,8 +127,10 @@ Request *init_request(uint32_t buff_len) { req->res.msg = req->buff; req->messages_to_user = linked_list(); - - checkAlloc(req->buff); + if (req->messages_to_user == NULL) { + ssp_free(req->buff); + return NULL; + } return req; } diff --git a/Program/src/server.c b/Program/src/server.c index 6544f2a..f9c3d3b 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -6,7 +6,6 @@ Evan Giese 1689223 This is my file for server.c. It develops a udp server for select. ------------------------------------------------------------------------------*/ -#include #include #include #include @@ -19,19 +18,8 @@ This is my file for server.c. It develops a udp server for select. #include #include #include -#include -#include #include "utils.h" #include "server.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "port.h" #ifdef CSP_NETWORK @@ -138,7 +126,7 @@ int *prepareSignalHandler() if (sigaction(SIGINT, &actionData, NULL) == -1) { - perror("sigaction sigint failed\n"); + ssp_error("sigaction sigint failed\n"); exit(EXIT_FAILURE); } return &exit_now; @@ -187,13 +175,15 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c ssp_fd_set(STDIN_FILENO, socket_set); uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size); + if (buff_size == NULL) + exit_now = true; *buff_size = initial_buff_size; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), *buff_size); - checkAlloc(buff); + if (buff_size == NULL) + exit_now = true; for (;;) { @@ -297,16 +287,18 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, ssp_fd_set(STDIN_FILENO, socket_set); uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size); + if (buff_size == NULL) + exit_now = true; *buff_size = initial_buff_size + 10; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), *buff_size); - checkAlloc(buff); + if (buff == NULL) + exit_now = true; + + for (;;) { - for (;;) - { if (exit_now || checkExit(other)){ ssp_printf("exiting server thread\n"); break; @@ -381,14 +373,16 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *para exit_now = 1; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size); + if (buff_size == NULL) + exit_now = true; *buff_size = packet_len + 10; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), prev_buff_size); - checkAlloc(buff); + if (buff == NULL) + exit_now = true; for (;;) { @@ -418,9 +412,9 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *para } - free(addr); - free(buff_size); - free(buff); + ssp_free(addr); + ssp_free(buff_size); + ssp_free(buff); ssp_close(sfd); onExit(params); } @@ -444,13 +438,15 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, exit_now = 1; uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); - checkAlloc(buff_size); + if (buff_size == NULL) + exit_now = true; *buff_size = packet_len; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(prev_buff_size, sizeof(char)); - checkAlloc(buff); + if (buff == NULL) + exit_now = true; for (;;) { @@ -476,9 +472,9 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, } } - free(addr); - free(buff_size); - free(buff); + ssp_free(addr); + ssp_free(buff_size); + ssp_free(buff); ssp_close(sfd); onExit(params); } @@ -547,7 +543,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p continue; else { - printf("CLIENT DATA Length: %d\n", packet_recieved->length); + ssp_printf("CLIENT DATA Length: %d\n", packet_recieved->length); if (onRecv(-1, (char *)packet_recieved->data, packet_recieved->length, NULL, packet_recieved, sizeof(packet_recieved), params) == -1) ssp_printf("recv failed\n"); @@ -690,7 +686,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_O_NONE); if (conn == NULL) { /* Connect failed */ - printf("Connection failed\n"); + ssp_printf("Connection failed\n"); return; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 004e68c..a31eb8b 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -52,14 +52,15 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, Request **request_container = &app->current_request; - int packet_index = process_pdu_header(packet, 1, res, request_container, app->request_list, app); - Request *current_request = (*request_container); - app->current_request = current_request; - + int packet_index = process_pdu_header(packet,true, res, request_container, app->request_list, app); if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; } + + Request *current_request = (*request_container); + app->current_request = current_request; + parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); @@ -84,11 +85,12 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u Request **request_container = &client->current_request; - int packet_index = process_pdu_header(packet, 0, res, request_container, client->request_list, client->app); + int packet_index = process_pdu_header(packet, false, res, request_container, client->request_list, client->app); if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; } + Request *current_request = (*request_container); res.msg = current_request->buff; @@ -353,7 +355,8 @@ void *ssp_connection_server_task(void *params) { } //1024 is the connection max limit - connection_server(port, + connection_server(host_name, + port, app->packet_len, 10, on_recv_server_callback, From 7f623e41706455e34bfffc3b8675e046cec67862 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 20 Feb 2020 21:30:47 -0700 Subject: [PATCH 182/400] change LV memory allocations --- Program/src/packet.c | 12 ++++---- Program/src/protocol_handler.c | 55 ++++++---------------------------- Program/src/requests.c | 36 ++++++++++------------ 3 files changed, 31 insertions(+), 72 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 36952cd..44cee1d 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -396,14 +396,14 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { m->value = ssp_alloc(1, sizeof(Message_put_proxy)); put_proxy = (Message_put_proxy *) m->value; - put_proxy->destination_id = copy_lv_from_buffer(packet, message_start); - message_start += put_proxy->destination_id->length + 1; + copy_lv_from_buffer(&put_proxy->destination_id, packet, message_start); + message_start += put_proxy->destination_id.length + 1; - put_proxy->source_file_name = copy_lv_from_buffer(packet, message_start); - message_start += put_proxy->source_file_name->length + 1; + copy_lv_from_buffer(&put_proxy->source_file_name, packet, message_start); + message_start += put_proxy->source_file_name.length + 1; - put_proxy->destination_file_name = copy_lv_from_buffer(packet, message_start); - message_start += put_proxy->destination_file_name->length + 1; + copy_lv_from_buffer(&put_proxy->destination_file_name, packet, message_start); + message_start += put_proxy->destination_file_name.length + 1; break; default: diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index db9938f..52b39b7 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -73,44 +73,7 @@ static int find_request(void *element, void *args) { } -//------------------------------------TODO------------------------------------------ -/* -Request *parse_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app) { - - uint8_t packet_index = PACKET_STATIC_HEADER_LEN; - Pdu_header *header = (Pdu_header *) packet; - - uint32_t source_id = 0; - memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); - packet_index += header->length_of_entity_IDs; - - uint32_t transaction_sequence_number = 0; - memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); - packet_index += header->transaction_seq_num_len; - - uint32_t dest_id = 0; - memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); - packet_index += header->length_of_entity_IDs; - - if (app->my_cfdp_id != dest_id){ - ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); - return -1; - } - - struct request_search_params params = { - source_id, - transaction_sequence_number, - }; - - Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); - return found_req; -} -*/ - - -//------------------------------------------------------------------------------ - - Request *add_new_incomming_request(uint32_t source_id, + Request *new_incomming_request(uint32_t source_id, uint32_t transmission_mode, uint32_t transaction_sequence_number, Response res, @@ -195,7 +158,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r //if packet is from the same request, don't' change current request Request *current_req = (*req); if (current_req != NULL && current_req->transaction_sequence_number == transaction_sequence_number && current_req->dest_cfdp_id == source_id){ - (*req)->packet_data_len = len; + current_req->packet_data_len = len; return packet_index; } @@ -211,7 +174,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r if (found_req == NULL && is_server) { - found_req = add_new_incomming_request(source_id, + found_req = new_incomming_request(source_id, header->transmission_mode, transaction_sequence_number, res, @@ -304,13 +267,13 @@ void process_messages(Request *req, FTP *app) { Message_put_proxy *p = (Message_put_proxy *) message->value; ssp_printf("received proxy request for source file name: %s dest file name %s, to id %d\n", - (char *)p->source_file_name->value, - (char *)p->destination_file_name->value, - *(uint8_t*)p->destination_id->value); + (char *)p->source_file_name.value, + (char *)p->destination_file_name.value, + *(uint8_t*)p->destination_id.value); - start_request(put_request(*(uint8_t*)p->destination_id->value, - (char *)p->source_file_name->value, - (char *)p->destination_file_name->value, ACKNOWLEDGED_MODE, app)); + start_request(put_request(*(uint8_t*)p->destination_id.value, + (char *)p->source_file_name.value, + (char *)p->destination_file_name.value, ACKNOWLEDGED_MODE, app)); ssp_free_message(message); } diff --git a/Program/src/requests.c b/Program/src/requests.c index b2f39d1..e013e36 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -20,29 +20,24 @@ //returns total space taken up in the packet from the added lv -uint16_t copy_lv_to_buffer(char *buffer, LV *lv){ +uint16_t copy_lv_to_buffer(char *buffer, LV lv){ uint16_t packet_index = 0; - buffer[packet_index] = lv->length; + buffer[packet_index] = lv.length; packet_index++; - memcpy(&buffer[packet_index], lv->value, lv->length); - packet_index += lv->length; + memcpy(&buffer[packet_index], lv.value, lv.length); + packet_index += lv.length; return packet_index; } -void free_lv(LV *lv) { - ssp_free(lv->value); - ssp_free(lv); +void free_lv(LV lv) { + ssp_free(lv.value); } -LV *create_lv(int size, void *value) { +void create_lv(LV *lv, int len, void *value) { - LV *lv = ssp_alloc(1, sizeof(LV)); - lv->value = ssp_alloc(size, sizeof(char)); - - memcpy(lv->value, value, size); - lv->length = size; - - return lv; + lv->value = ssp_alloc(len, sizeof(char)); + memcpy(lv->value, value, len); + lv->length = len; } Message *create_message(uint8_t type) { @@ -57,9 +52,10 @@ Message *create_message(uint8_t type) { //lv is what we copy into, packet is the buffer, and start is where in the buffer //we start copying the lv to -LV *copy_lv_from_buffer(char *packet, uint32_t start) { +void copy_lv_from_buffer(LV *lv, char *packet, uint32_t start) { uint8_t len = packet[start]; - return create_lv(len, &packet[start + 1]); + create_lv(lv, len, &packet[start + 1]); + return; } @@ -265,9 +261,9 @@ void start_request(Request *req){ Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); - proxy->destination_file_name = create_lv(strnlen(dest_name, MAX_PATH) + 1, dest_name); - proxy->source_file_name = create_lv(strnlen(source_name, MAX_PATH) + 1, source_name); - proxy->destination_id = create_lv(length_of_id, &beneficial_cfid); + create_lv(&proxy->destination_file_name, strnlen(dest_name, MAX_PATH) + 1, dest_name); + create_lv(&proxy->source_file_name, strnlen(source_name, MAX_PATH) + 1, source_name); + create_lv(&proxy->destination_id, length_of_id, &beneficial_cfid); return proxy; } From f04b9115e576436bd2058c3e9d72ebd71926e707 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 20 Feb 2020 21:57:47 -0700 Subject: [PATCH 183/400] WIP writing Messages to files --- Program/src/filesystem_funcs.c | 113 ++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 2 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 6fb50db..683f52f 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -5,7 +5,7 @@ #include #include #include "utils.h" -#include "string.h" +#include #include "list.h" #include "jsmn.h" @@ -307,8 +307,12 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa char buff[total_size]; int fd = ssp_open(file_name, O_RDWR); + if (fd < 0) { + ssp_error("couldn't open file\n"); + return -1; + } - int r = read(fd, buff, sizeof(buff)); + int r = ssp_read(fd, buff, sizeof(buff)); if (r < 0) { ssp_error("read failed\n"); return -1; @@ -339,4 +343,109 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa } return 0; +} + + + + +int write_lv(LV lv) { + + +} + +void write_message_length(Node *node, void *element, void *fd) { + int fd = *(int*)fd; + Message *message = (Message *)element; + + //SEEK_END 2 SEEK_CUR 1 SEEK_SET 0 + int error = ssp_lseek(fd, 0, SEEK_END); + if (error < 0) + ssp_error("failed to locate end\n"); + + error = ssp_write(fd, message->header.message_type, sizeof(uint32_t)); + if (error < 0) + ssp_error("failed to append to end of file\n"); + + int error = ssp_lseek(fd, 0, SEEK_END); + if (error < 0) + ssp_error("failed to locate end\n"); + + + switch (message->header.message_type) + { + case PROXY_PUT_REQUEST: + break; + + default: + break; + } + + //ssp_write(fd, ) +} + + + +#include +//work in progress +int save_req_json(Request *req) { + + char file_name[255]; + snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".json"); + + int fd = ssp_open(file_name, O_RDWR | O_CREAT); + if (fd < 0) { + ssp_error("couldn't open file\n"); + return -1; + } + + + int req_len = sizeof(Request); + int message_len = 0; + + int message_count = req->messages_to_user->count; + req->messages_to_user->iterate(req->messages_to_user, ,&message_len) + + + + char buff[req_len]; + memcpy(buff, req, req_len); + + + + int error = ssp_write(fd, buff, len); + if (error == -1) + return -1; + + //char listbuff[req->messages_to_user->count]; + print_request_state(req); + + return 0; +} + + + +int get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { + + char file_name[255]; + snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".json"); + + int fd = ssp_open(file_name, O_RDWR | O_CREAT); + if (fd < 0) { + ssp_error("couldn't open file\n"); + return -1; + } + + int len = sizeof(Request); + char buff[len]; + int error = ssp_read(fd, buff, len); + if (error == -1) + return -1; + + + Request *req = (Request *) buff; + print_request_state(req); + + + return 0; + } \ No newline at end of file From 6dbb10db16f36b1d927029a82758d3934c29997f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 27 Feb 2020 20:44:24 -0700 Subject: [PATCH 184/400] working on writing state --- Program/include/filesystem_funcs.h | 2 + Program/include/requests.h | 8 ++-- Program/include/types.h | 6 +-- Program/src/filesystem_funcs.c | 66 +++++++++++++++++------------- Program/test/filesystem_tests.c | 29 +++++++++---- Program/test/makefile | 2 +- Program/test/request_tests.c | 17 ++++---- 7 files changed, 77 insertions(+), 53 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 9ef8529..40bbf35 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -22,5 +22,7 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); +int save_req_json(Request *req); +int get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); #endif diff --git a/Program/include/requests.h b/Program/include/requests.h index 7970b13..006ec15 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -25,11 +25,11 @@ Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t le void print_request_state(Request *req); //Frees a message struct void ssp_free_message(void *params); -LV *create_lv(int size, void *value); -uint16_t copy_lv_to_buffer(char *buffer, LV *lv); -LV *copy_lv_from_buffer(char *packet, uint32_t start); +uint16_t copy_lv_to_buffer(char *buffer, LV lv); +void copy_lv_from_buffer(LV *lv, char *packet, uint32_t start); Message *create_message(uint8_t type); -void free_lv(LV *lv); +void create_lv(LV *lv, int len, void *value); +void free_lv(LV lv); void print_request_procedure(Request *req); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index 971010f..97e8b50 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -137,9 +137,9 @@ typedef struct message_header { //type PROXY_PUT_REQUEST typedef struct message_put_proxy { - LV *destination_id; - LV *source_file_name; - LV *destination_file_name; + LV destination_id; + LV source_file_name; + LV destination_file_name; } Message_put_proxy; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 683f52f..dbf36db 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -348,43 +348,51 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa -int write_lv(LV lv) { +static struct params { + int error; + int fd; +}; -} +static void write_message_callback(Node *node, void *element, void *param) { + + struct params *p = (struct params *) param; + int fd = p->fd; -void write_message_length(Node *node, void *element, void *fd) { - int fd = *(int*)fd; Message *message = (Message *)element; //SEEK_END 2 SEEK_CUR 1 SEEK_SET 0 int error = ssp_lseek(fd, 0, SEEK_END); - if (error < 0) + if (error < 0) { + p->error = error; ssp_error("failed to locate end\n"); - - error = ssp_write(fd, message->header.message_type, sizeof(uint32_t)); - if (error < 0) + return; + } + error = ssp_write(fd, &message->header.message_type, sizeof(uint32_t)); + if (error < 0) { + p->error = error; ssp_error("failed to append to end of file\n"); - - int error = ssp_lseek(fd, 0, SEEK_END); - if (error < 0) + return; + } + error = ssp_lseek(fd, 0, SEEK_END); + if (error < 0) { + p->error = error; ssp_error("failed to locate end\n"); - - + return; + } + switch (message->header.message_type) { case PROXY_PUT_REQUEST: + ssp_printf("writing put proxy message\n"); break; default: break; } - - //ssp_write(fd, ) } - #include //work in progress int save_req_json(Request *req) { @@ -397,28 +405,28 @@ int save_req_json(Request *req) { ssp_error("couldn't open file\n"); return -1; } - int req_len = sizeof(Request); - int message_len = 0; - - int message_count = req->messages_to_user->count; - req->messages_to_user->iterate(req->messages_to_user, ,&message_len) - - - char buff[req_len]; + memcpy(buff, req, req_len); + int error = ssp_write(fd, buff, req_len); + if (error == -1) + return -1; + struct params param = { + 0, + fd + }; - int error = ssp_write(fd, buff, len); - if (error == -1) + if (!req->messages_to_user->count) + return 0; + + req->messages_to_user->iterate(req->messages_to_user, write_message_callback, ¶m); + if (param.fd < 0) return -1; - //char listbuff[req->messages_to_user->count]; - print_request_state(req); - return 0; } diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 1160029..389de61 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -2,6 +2,7 @@ #include "unit_tests.h" #include "port.h" #include "mib.h" +#include "requests.h" static void nak_print(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; @@ -41,16 +42,28 @@ int read_json_file_test() { } -int read_mib() { - Remote_entity *entity = get_remote_entity2(1); - -} - int file_system_tests() { int error = 0; - //error = receive_offset_tests(); - error = read_json_file_test(); - error = read_mib(); + + Request *req = init_request(1000); + req->dest_cfdp_id = 1; + req->transaction_sequence_number = 1; + req->local_entity.EOF_recv_indication = 1; + req->local_entity.EOF_sent_indication = 1; + req->local_entity.suspended_indication = 1; + + req->messages_to_user->push(req->messages_to_user, create_message(PROXY_PUT_REQUEST), 0); + + printf("write test\n"); + error = save_req_json(req); + if (error == -1) + printf("failed to write\n"); + + error = get_req_json(1, 1); + if (error == -1) + return -1; + + //ssp_cleanup_req(req); return error; } diff --git a/Program/test/makefile b/Program/test/makefile index b872bdc..aa3174f 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -34,7 +34,7 @@ CFILES += $(PROJDIR)/test/test.c #CFILES += $(PROJDIR)/test/tasks_tests.c #CFILES += $(PROJDIR)/test/list_tests.c -#CFILES += $(PROJDIR)/test/filesystem_tests.c +CFILES += $(PROJDIR)/test/filesystem_tests.c #CFILES += $(PROJDIR)/test/protocol_handler_tests.c #CFILES += $(PROJDIR)/test/list_tests.c #CFILES += $(PROJDIR)/test/server_tests.c diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index bd40a76..2090861 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -138,22 +138,23 @@ int test_lv_functions() { char packet[100]; char *str = "suphomie"; - LV *lv = create_lv(strnlen(str, 100), str); + LV lv; + create_lv(lv, strnlen(str, 100), str); uint32_t len = strnlen(str, 100); - ASSERT_EQUALS_INT("create_lv length works", lv->length, len); - ASSERT_EQUALS_STR("create_lv value works", str, lv->value, len); + ASSERT_EQUALS_INT("create_lv length works", lv.length, len); + ASSERT_EQUALS_STR("create_lv value works", str, lv.value, len); uint16_t packet_index = copy_lv_to_buffer(packet, lv); - ASSERT_EQUALS_INT("copy lv, length", packet[0], lv->length); - ASSERT_EQUALS_STR("copy lv, value", &packet[1], lv->value, lv->length); + ASSERT_EQUALS_INT("copy lv, length", packet[0], lv.length); + ASSERT_EQUALS_STR("copy lv, value", &packet[1], lv.value, lv.length); free_lv(lv); - lv = copy_lv_from_buffer(packet, 0); - ASSERT_EQUALS_INT("copy lv length from packet", lv->length, len); - ASSERT_EQUALS_STR("copy lv value from packet", str, lv->value, len); + copy_lv_from_buffer(lv, packet, 0); + ASSERT_EQUALS_INT("copy lv length from packet", lv.length, len); + ASSERT_EQUALS_STR("copy lv value from packet", str, lv.value, len); free_lv(lv); } From ac050d46e880ce3a479eec2cbfbb1554763aa1b8 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 23 Mar 2020 20:11:44 -0600 Subject: [PATCH 185/400] add save proxy message --- Program/include/filesystem_funcs.h | 2 +- Program/src/filesystem_funcs.c | 80 +++++++++++++++++++++++++----- Program/src/requests.c | 22 ++++++++ Program/test/filesystem_tests.c | 15 ++++-- 4 files changed, 100 insertions(+), 19 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 40bbf35..6efe874 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -23,6 +23,6 @@ File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); int save_req_json(Request *req); -int get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); +Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); #endif diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index dbf36db..c4d60a0 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -354,10 +354,59 @@ static struct params { }; +static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy_message) { + + char *error_message = "failed to write put proxy message\n"; + int err = ssp_write(fd, &proxy_message->destination_file_name.length, sizeof(uint8_t)); + if (err < 0) { + *error = err; + ssp_printf("1 "); + ssp_error(error_message); + return; + } + err = ssp_write(fd, &proxy_message->destination_file_name.value, proxy_message->destination_file_name.length); + if (err < 0) { + *error = err; + ssp_printf("2"); + ssp_error(error_message); + return; + } + err = ssp_write(fd, &proxy_message->source_file_name.length, sizeof(uint8_t)); + if (err < 0) { + *error = err; + ssp_printf("3"); + ssp_error(error_message); + return; + } + err = ssp_write(fd, &proxy_message->source_file_name.value, proxy_message->source_file_name.length); + if (err < 0) { + *error = err; + ssp_printf("4"); + ssp_error(error_message); + return; + } + err = ssp_write(fd, &proxy_message->destination_id.length, sizeof(uint8_t)); + if (err < 0) { + *error = err; + ssp_error(error_message); + return; + } + err = ssp_write(fd, &proxy_message->destination_id.value, proxy_message->destination_id.length); + if (error < 0) { + *error = err; + ssp_error(error_message); + return; + } + +} + static void write_message_callback(Node *node, void *element, void *param) { struct params *p = (struct params *) param; int fd = p->fd; + if (p->error < 0){ + return; + } Message *message = (Message *)element; @@ -368,23 +417,28 @@ static void write_message_callback(Node *node, void *element, void *param) { ssp_error("failed to locate end\n"); return; } + //write type error = ssp_write(fd, &message->header.message_type, sizeof(uint32_t)); if (error < 0) { p->error = error; ssp_error("failed to append to end of file\n"); return; } + //move file end error = ssp_lseek(fd, 0, SEEK_END); if (error < 0) { p->error = error; ssp_error("failed to locate end\n"); return; } - + Message_put_proxy *proxy_message; + switch (message->header.message_type) { case PROXY_PUT_REQUEST: + proxy_message = (Message_put_proxy *)message->value; ssp_printf("writing put proxy message\n"); + write_put_proxy_message(fd, &p->error, proxy_message); break; default: @@ -424,7 +478,7 @@ int save_req_json(Request *req) { return 0; req->messages_to_user->iterate(req->messages_to_user, write_message_callback, ¶m); - if (param.fd < 0) + if (param.error < 0) return -1; return 0; @@ -432,7 +486,7 @@ int save_req_json(Request *req) { -int get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { +Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { char file_name[255]; snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".json"); @@ -440,20 +494,20 @@ int get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { ssp_error("couldn't open file\n"); - return -1; + return NULL; } int len = sizeof(Request); - char buff[len]; - int error = ssp_read(fd, buff, len); - if (error == -1) - return -1; - - - Request *req = (Request *) buff; - print_request_state(req); + Request *req = ssp_alloc(1, sizeof(Request)); + if (req == NULL) + return req; + int error = ssp_read(fd, (char *)req, len); + if (error == -1){ + ssp_free(req); + req = NULL; + } - return 0; + return req; } \ No newline at end of file diff --git a/Program/src/requests.c b/Program/src/requests.c index e013e36..b904535 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -277,6 +277,24 @@ int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, return 1; } +static void print_messages_callback(Node *node, void *element, void *args) { + + Message *m = (Message*) element; + + ssp_printf("Message type: %s\n", m->header.message_type); + ssp_printf("id: %d\n", m->header.message_id_cfdp); + Message_put_proxy *proxy; + + if (m->header.message_type == PROXY_PUT_REQUEST) { + proxy = (Message_put_proxy *)m->value; + + ssp_printf("dest filename: %s\n", proxy->destination_file_name); + ssp_printf("source filename: %s\n", proxy->source_file_name); + ssp_printf("id: %s\n", proxy->destination_id); + + } + +} void print_request_state(Request *req) { @@ -291,6 +309,10 @@ void print_request_state(Request *req) { ssp_printf("Suspended indication %d\n", req->local_entity.suspended_indication); ssp_printf("Transaction finished indication %d\n", req->local_entity.transaction_finished_indication); print_request_procedure(req); + + ssp_printf("current messages: "); + req->messages_to_user->iterate(req->messages_to_user, print_messages_callback, NULL); + ssp_printf("---------------------------------------------\n"); } diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 389de61..421deab 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -51,17 +51,22 @@ int file_system_tests() { req->local_entity.EOF_recv_indication = 1; req->local_entity.EOF_sent_indication = 1; req->local_entity.suspended_indication = 1; - - req->messages_to_user->push(req->messages_to_user, create_message(PROXY_PUT_REQUEST), 0); + char *dest_file = "stuff"; + char *src_file = "morestuff"; + + Message *m = create_message(PROXY_PUT_REQUEST); + m->value = create_message_put_proxy(1, 1, dest_file, src_file, req); + + req->messages_to_user->push(req->messages_to_user, m, 0); printf("write test\n"); error = save_req_json(req); if (error == -1) printf("failed to write\n"); - error = get_req_json(1, 1); - if (error == -1) - return -1; + Request *got_req = get_req_json(1, 1); + + print_request_state(got_req); //ssp_cleanup_req(req); return error; From ebf788ab161030fd987754068b72436aa5d5019f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 24 Mar 2020 21:34:53 -0600 Subject: [PATCH 186/400] raed and write messages, still not working --- Program/include/list.h | 2 +- Program/include/requests.h | 4 +- Program/include/types.h | 2 +- Program/src/filesystem_funcs.c | 124 +++++++++++++++++++++++++++++---- Program/src/requests.c | 20 +++--- 5 files changed, 125 insertions(+), 27 deletions(-) diff --git a/Program/include/list.h b/Program/include/list.h index 8392d7f..7eba12f 100644 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -22,7 +22,7 @@ typedef struct List { struct Node *head; struct Node *tail; - int count; + uint32_t count; int (*push)(struct List *list, void *element, uint32_t id); void *(*remove)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); void (*iterate)(struct List *list, void (*f)(Node *node, void *element, void *args), void *args); diff --git a/Program/include/requests.h b/Program/include/requests.h index 006ec15..6b5cb89 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -20,7 +20,7 @@ Request *put_request( int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); -Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); +Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name); void print_request_state(Request *req); //Frees a message struct @@ -31,5 +31,7 @@ Message *create_message(uint8_t type); void create_lv(LV *lv, int len, void *value); void free_lv(LV lv); void print_request_procedure(Request *req); +void ssp_free_put_proxy_message(Message_put_proxy* proxy_request); + #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index 97e8b50..5cb880b 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -128,7 +128,7 @@ typedef struct tlv { typedef struct message_header { - char *message_id_cfdp; + char message_id_cfdp[5]; uint8_t message_type; } Message_header; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index c4d60a0..e2a5e7a 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -8,6 +8,7 @@ #include #include "list.h" #include "jsmn.h" +#include "requests.h" uint32_t get_file_size(char *source_file_name) { @@ -360,28 +361,24 @@ static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy int err = ssp_write(fd, &proxy_message->destination_file_name.length, sizeof(uint8_t)); if (err < 0) { *error = err; - ssp_printf("1 "); ssp_error(error_message); return; } - err = ssp_write(fd, &proxy_message->destination_file_name.value, proxy_message->destination_file_name.length); + err = ssp_write(fd, proxy_message->destination_file_name.value, proxy_message->destination_file_name.length); if (err < 0) { *error = err; - ssp_printf("2"); ssp_error(error_message); return; } err = ssp_write(fd, &proxy_message->source_file_name.length, sizeof(uint8_t)); if (err < 0) { *error = err; - ssp_printf("3"); ssp_error(error_message); return; } - err = ssp_write(fd, &proxy_message->source_file_name.value, proxy_message->source_file_name.length); + err = ssp_write(fd, proxy_message->source_file_name.value, proxy_message->source_file_name.length); if (err < 0) { *error = err; - ssp_printf("4"); ssp_error(error_message); return; } @@ -391,7 +388,7 @@ static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy ssp_error(error_message); return; } - err = ssp_write(fd, &proxy_message->destination_id.value, proxy_message->destination_id.length); + err = ssp_write(fd, proxy_message->destination_id.value, proxy_message->destination_id.length); if (error < 0) { *error = err; ssp_error(error_message); @@ -418,7 +415,7 @@ static void write_message_callback(Node *node, void *element, void *param) { return; } //write type - error = ssp_write(fd, &message->header.message_type, sizeof(uint32_t)); + error = ssp_write(fd, &message->header.message_type, sizeof(uint8_t)); if (error < 0) { p->error = error; ssp_error("failed to append to end of file\n"); @@ -477,6 +474,10 @@ int save_req_json(Request *req) { if (!req->messages_to_user->count) return 0; + error = ssp_write(fd, &req->messages_to_user->count, sizeof(uint8_t)); + if (error == -1) + return -1; + req->messages_to_user->iterate(req->messages_to_user, write_message_callback, ¶m); if (param.error < 0) return -1; @@ -484,11 +485,70 @@ int save_req_json(Request *req) { return 0; } +Message *read_in_proxy_message(int fd) { + + uint8_t destination_file_name_len = 0; + char destination_file_name[255]; + uint8_t src_file_name_len = 0; + char src_file_name[255]; + uint8_t dest_id_len = 0; + uint32_t dest_id = 0; + + char *error_message = "failed to read put proxy message\n"; + int err = ssp_read(fd, &destination_file_name_len, sizeof(uint8_t)); + if (err < 0) { + ssp_error(error_message); + return NULL; + } + printf("destination_file_name_len %d\n", destination_file_name_len); + + err = ssp_read(fd, destination_file_name, destination_file_name_len); + if (err < 0) { + ssp_error(error_message); + return NULL; + } + err = ssp_read(fd, &src_file_name_len, sizeof(uint8_t)); + if (err < 0) { + ssp_error(error_message); + return NULL; + } + err = ssp_read(fd, src_file_name, src_file_name_len); + if (err < 0) { + ssp_error(error_message); + return NULL; + } + err = ssp_read(fd, &dest_id_len, sizeof(uint8_t)); + if (err < 0) { + ssp_error(error_message); + return NULL; + } + err = ssp_read(fd, (char *)&dest_id, dest_id_len); + if (err < 0) { + ssp_error(error_message); + return NULL; + } + + Message *message = create_message(PROXY_PUT_REQUEST); + if (message == NULL) + return NULL; + ssp_printf("src file name: %s dest file name %s\n", src_file_name, destination_file_name); + + Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, src_file_name, destination_file_name); + if (proxy_message == NULL) { + ssp_free(message); + return NULL; + } + + message->value = proxy_message; + return message; +} Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { char file_name[255]; + uint8_t number_of_messages; + snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".json"); int fd = ssp_open(file_name, O_RDWR | O_CREAT); @@ -498,16 +558,50 @@ Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { } int len = sizeof(Request); - Request *req = ssp_alloc(1, sizeof(Request)); - if (req == NULL) - return req; + Request req; + //read in request static data + int error = ssp_read(fd, (char *)&req, len); + if (error == -1){ + return NULL; + } - int error = ssp_read(fd, (char *)req, len); + //read in count of messages + error = ssp_read(fd, &number_of_messages, sizeof(uint8_t)); if (error == -1){ - ssp_free(req); - req = NULL; + return NULL; + } + + if (number_of_messages > 0) { + + List *messages = linked_list(); + if (messages == NULL) + return NULL; + + for (int i = 0; i < number_of_messages; i++) { + + uint8_t message_type = 0; + error = ssp_read(fd, &message_type, sizeof(uint8_t)); + if (error == -1) + return NULL; + + Message *message; + switch (message_type) + { + case PROXY_PUT_REQUEST: + ssp_printf("reading put proxy message\n"); + message = read_in_proxy_message(fd); + break; + + default: + break; + } + messages->push(messages, message, -1); + } } - return req; + Request *r = ssp_alloc(1, sizeof(Request)); + memcpy(r, &req, sizeof(Request)); + + return r; } \ No newline at end of file diff --git a/Program/src/requests.c b/Program/src/requests.c index b904535..5930c77 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -43,7 +43,7 @@ void create_lv(LV *lv, int len, void *value) { Message *create_message(uint8_t type) { Message *message = ssp_alloc(1, sizeof(Message)); - message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); + //message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); memcpy(message->header.message_id_cfdp, "cfdp", 5); message->header.message_type = type; return message; @@ -58,6 +58,13 @@ void copy_lv_from_buffer(LV *lv, char *packet, uint32_t start) { return; } +void ssp_free_put_proxy_message(Message_put_proxy* proxy_request) { + + free_lv(proxy_request->destination_file_name); + free_lv(proxy_request->source_file_name); + free_lv(proxy_request->destination_id); + +} void ssp_free_message(void *params) { @@ -68,17 +75,12 @@ void ssp_free_message(void *params) { { case PROXY_PUT_REQUEST: proxy_request = (Message_put_proxy *) message->value; - free_lv(proxy_request->destination_file_name); - free_lv(proxy_request->source_file_name); - free_lv(proxy_request->destination_id); - + ssp_free_put_proxy_message(proxy_request); break; default: break; } - - ssp_free(message->header.message_id_cfdp); ssp_free(message->value); ssp_free(message); } @@ -258,7 +260,7 @@ void start_request(Request *req){ //data will be delivered -Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { +Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name) { Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); create_lv(&proxy->destination_file_name, strnlen(dest_name, MAX_PATH) + 1, dest_name); @@ -271,7 +273,7 @@ Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t le int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { Message *message = create_message(PROXY_PUT_REQUEST); - message->value = create_message_put_proxy(beneficial_cfid, length_of_id, source_name, dest_name, req); + message->value = create_message_put_proxy(beneficial_cfid, length_of_id, source_name, dest_name); req->messages_to_user->push(req->messages_to_user, message, 0); return 1; From 2ee2eb3e28d958fecb2a470847650f0386f11fb7 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 25 Mar 2020 20:55:12 -0600 Subject: [PATCH 187/400] Save and get requests work --- Program/include/filesystem_funcs.h | 4 ++-- Program/src/filesystem_funcs.c | 35 ++++++++++++++++-------------- Program/src/requests.c | 13 +++++------ 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 6efe874..02df8f2 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -22,7 +22,7 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); -int save_req_json(Request *req); -Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); +int save_req(Request *req); +Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); #endif diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index e2a5e7a..595b26e 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -327,7 +327,6 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa for (int i = 1; i < r; i++) { - int key_size = tok[i].end - tok[i].start; int value_size = tok[i+1].end - tok[i+1].start; @@ -346,15 +345,11 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa return 0; } - - - static struct params { int error; int fd; }; - static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy_message) { char *error_message = "failed to write put proxy message\n"; @@ -446,10 +441,10 @@ static void write_message_callback(Node *node, void *element, void *param) { #include //work in progress -int save_req_json(Request *req) { +int save_req(Request *req) { char file_name[255]; - snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".json"); + snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { @@ -482,6 +477,10 @@ int save_req_json(Request *req) { if (param.error < 0) return -1; + error = ssp_close(fd); + if (error < 0) { + ssp_error("couldn't close file descriptor\n"); + } return 0; } @@ -532,24 +531,22 @@ Message *read_in_proxy_message(int fd) { if (message == NULL) return NULL; - ssp_printf("src file name: %s dest file name %s\n", src_file_name, destination_file_name); - Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, src_file_name, destination_file_name); if (proxy_message == NULL) { ssp_free(message); return NULL; } - + message->value = proxy_message; return message; } -Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { +Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { char file_name[255]; uint8_t number_of_messages; - snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".json"); + snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { @@ -569,11 +566,12 @@ Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { error = ssp_read(fd, &number_of_messages, sizeof(uint8_t)); if (error == -1){ return NULL; - } - + } + + List *messages = NULL; if (number_of_messages > 0) { - List *messages = linked_list(); + messages = linked_list(); if (messages == NULL) return NULL; @@ -591,7 +589,7 @@ Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { ssp_printf("reading put proxy message\n"); message = read_in_proxy_message(fd); break; - + default: break; } @@ -601,6 +599,11 @@ Request *get_req_json(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { Request *r = ssp_alloc(1, sizeof(Request)); memcpy(r, &req, sizeof(Request)); + r->messages_to_user = messages; + error = close(fd); + if (error < 0) { + ssp_error("couldn't close file descriptor \n"); + } return r; diff --git a/Program/src/requests.c b/Program/src/requests.c index 5930c77..00dcb8e 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -258,8 +258,6 @@ void start_request(Request *req){ //Omission of source and destination filenames shall indicate that only Meta //data will be delivered - - Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name) { Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); @@ -284,15 +282,16 @@ static void print_messages_callback(Node *node, void *element, void *args) { Message *m = (Message*) element; ssp_printf("Message type: %s\n", m->header.message_type); - ssp_printf("id: %d\n", m->header.message_id_cfdp); + ssp_printf("id: %s\n", m->header.message_id_cfdp); Message_put_proxy *proxy; if (m->header.message_type == PROXY_PUT_REQUEST) { proxy = (Message_put_proxy *)m->value; - ssp_printf("dest filename: %s\n", proxy->destination_file_name); - ssp_printf("source filename: %s\n", proxy->source_file_name); - ssp_printf("id: %s\n", proxy->destination_id); + ssp_printf("dest filename: %s\n", proxy->destination_file_name.value); + ssp_printf("source filename: %s\n", proxy->source_file_name.value); + ssp_printf("id lendth: %d\n", proxy->destination_id.length); + ssp_printf("id: %d\n", *(uint8_t*) proxy->destination_id.value); } @@ -312,7 +311,7 @@ void print_request_state(Request *req) { ssp_printf("Transaction finished indication %d\n", req->local_entity.transaction_finished_indication); print_request_procedure(req); - ssp_printf("current messages: "); + ssp_printf("current messages: \n"); req->messages_to_user->iterate(req->messages_to_user, print_messages_callback, NULL); ssp_printf("---------------------------------------------\n"); From 4d0c2ac4afc74d0d05ffaa61886d81f2d522add4 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 31 Mar 2020 22:08:15 -0600 Subject: [PATCH 188/400] Add save_file function --- Program/include/filesystem_funcs.h | 2 + Program/src/filesystem_funcs.c | 56 +++++++++++++++++++++++++- Program/src/requests.c | 4 +- Program/test/filesystem_tests.c | 63 ++++++++++++++++++++++++++---- Program/test/packet_tests.c | 42 ++++++++++---------- 5 files changed, 135 insertions(+), 32 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 02df8f2..f94a638 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -23,6 +23,8 @@ File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); int save_req(Request *req); +void save_file_meta_data(int fd, int *error, File *file); + Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); #endif diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 595b26e..13bd457 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -350,6 +350,57 @@ static struct params { int fd; }; +static void save_file_callback(Node *node, void *element, void *param) { + + char *error_message = "failed to write offset\n"; + + struct params *p = (struct params *) param; + int fd = p->fd; + if (p->error < 0){ + return; + } + + Offset *offset = (Offset *)element; + + int err = ssp_write(p->fd, offset, sizeof(Offset)); + if (err < 0) { + ssp_error(error_message); + p->error = err; + return; + } +} + +/* + first write file, + then length of offsets, + then offsets +*/ +void save_file_meta_data(int fd, int *error, File *file) { + + char *error_message = "failed to write file\n"; + int err = ssp_write(fd, file, sizeof(File)); + if (err < 0) { + ssp_error(error_message); + *error = err; + return; + } + + err = ssp_write(fd, &file->missing_offsets->count, sizeof(uint32_t)); + if (err < 0) { + ssp_error(error_message); + *error = err; + return; + } + + struct params param = { + 0, + fd + }; + + file->missing_offsets->iterate(file->missing_offsets, save_file_callback, ¶m); + +} + static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy_message) { char *error_message = "failed to write put proxy message\n"; @@ -391,7 +442,6 @@ static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy } } - static void write_message_callback(Node *node, void *element, void *param) { struct params *p = (struct params *) param; @@ -541,6 +591,7 @@ Message *read_in_proxy_message(int fd) { return message; } + Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { char file_name[255]; @@ -593,6 +644,7 @@ Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { default: break; } + message->header.message_type = message_type; messages->push(messages, message, -1); } } @@ -600,6 +652,8 @@ Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { Request *r = ssp_alloc(1, sizeof(Request)); memcpy(r, &req, sizeof(Request)); r->messages_to_user = messages; + + r->file = NULL; error = close(fd); if (error < 0) { ssp_error("couldn't close file descriptor \n"); diff --git a/Program/src/requests.c b/Program/src/requests.c index 00dcb8e..99b36ea 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -281,13 +281,13 @@ static void print_messages_callback(Node *node, void *element, void *args) { Message *m = (Message*) element; - ssp_printf("Message type: %s\n", m->header.message_type); + ssp_printf("Message type: %d\n", m->header.message_type); ssp_printf("id: %s\n", m->header.message_id_cfdp); Message_put_proxy *proxy; if (m->header.message_type == PROXY_PUT_REQUEST) { proxy = (Message_put_proxy *)m->value; - + ssp_printf("Message type: PROXY_PUT_REQUST\n"); ssp_printf("dest filename: %s\n", proxy->destination_file_name.value); ssp_printf("source filename: %s\n", proxy->source_file_name.value); ssp_printf("id lendth: %d\n", proxy->destination_id.length); diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 421deab..b298532 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -3,14 +3,14 @@ #include "port.h" #include "mib.h" #include "requests.h" +#include + static void nak_print(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; ssp_printf("start: %u end: %u\n", offset->start, offset->end); } - - static int receive_offset_tests(){ File *file = create_temp_file("temp_test", 2000); @@ -41,8 +41,38 @@ int read_json_file_test() { return 1; } +int test_save_file() { + + char *file_name = "temp/test_file_save"; + int fd = ssp_open(file_name, O_RDWR | O_CREAT); + if (fd < 0) { + ssp_error("couldn't open file\n"); + return -1; + } + int *error = 0; + File file; + file.missing_offsets = linked_list(); + + Offset one = { + 0, 250 + }; + Offset two = { + 0, 250 + }; + Offset three = { + 0, 250 + }; + + file.missing_offsets->push(file.missing_offsets, &one, -1); + file.missing_offsets->push(file.missing_offsets, &two, -1); + file.missing_offsets->push(file.missing_offsets, &three, -1); + + save_file_meta_data(fd, error, &file); + +} + +static int test_saving_request(){ -int file_system_tests() { int error = 0; Request *req = init_request(1000); @@ -55,20 +85,37 @@ int file_system_tests() { char *src_file = "morestuff"; Message *m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, dest_file, src_file, req); + m->value = create_message_put_proxy(1, 1, dest_file, src_file); + req->messages_to_user->push(req->messages_to_user, m, 0); + m = create_message(PROXY_PUT_REQUEST); + m->value = create_message_put_proxy(1, 1, dest_file, src_file); + req->messages_to_user->push(req->messages_to_user, m, 0); + + m = create_message(PROXY_PUT_REQUEST); + m->value = create_message_put_proxy(1, 1, dest_file, src_file); req->messages_to_user->push(req->messages_to_user, m, 0); printf("write test\n"); - error = save_req_json(req); + error = save_req(req); if (error == -1) printf("failed to write\n"); - - Request *got_req = get_req_json(1, 1); + + printf("read test\n"); + Request *got_req = get_req(1, 1); print_request_state(got_req); - //ssp_cleanup_req(req); + ssp_cleanup_req(req); + ssp_cleanup_req(got_req); + return error; +} + + +int file_system_tests() { + int error = 0; + //int error = test_saving_request(); + error = test_save_file(); return error; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index d740693..4289405 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -332,26 +332,26 @@ int test_add_messages_to_packet(char *packet, uint32_t start) { ASSERT_EQUALS_STR("'cfdp' should be at the start of the message", &packet[start], "cfdp", 5); ASSERT_EQUALS_INT("testing PROXY_PUT_REQUEST code", (uint8_t) packet[start + 5], PROXY_PUT_REQUEST); - LV* dest_file, *src_file, *dest_id; + LV dest_file, src_file, dest_id; packet_index = start + 6; - dest_id = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("dest_file.length", dest_id->length, len); - ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*) (dest_id->value), id); - packet_index += dest_id->length + 1; + copy_lv_from_buffer(&dest_id, packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", dest_id.length, len); + ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*) (dest_id.value), id); + packet_index += dest_id.length + 1; free_lv(dest_id); - src_file = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("src_file.length", src_file->length, strnlen(src, 100) + 1); - ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file->value, src_file->length); - packet_index += src_file->length + 1; + copy_lv_from_buffer(&src_file, packet, packet_index); + ASSERT_EQUALS_INT("src_file.length", src_file.length, strnlen(src, 100) + 1); + ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file.value, src_file.length); + packet_index += src_file.length + 1; free_lv(src_file); - dest_file = copy_lv_from_buffer(packet, packet_index); - ASSERT_EQUALS_INT("dest_file.length", dest_file->length, strnlen(dest, 100) + 1); - ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file->value, dest_file->length); + copy_lv_from_buffer(&dest_file, packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", dest_file.length, strnlen(dest, 100) + 1); + ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file.value, dest_file.length); free_lv(dest_file); ssp_cleanup_req(req); @@ -378,14 +378,14 @@ int test_get_message_from_packet(char *packet, uint32_t start) { Message *m = req2->messages_to_user->pop(req2->messages_to_user); Message_put_proxy *p_message = m->value; - ASSERT_EQUALS_INT("dest_file.length", p_message->destination_file_name->length, strnlen(dest, 100) + 1); - ASSERT_EQUALS_STR("dest_file.value", p_message->destination_file_name->value, dest, strnlen(dest, 100)); + ASSERT_EQUALS_INT("dest_file.length", p_message->destination_file_name.length, strnlen(dest, 100) + 1); + ASSERT_EQUALS_STR("dest_file.value", p_message->destination_file_name.value, dest, strnlen(dest, 100)); - ASSERT_EQUALS_INT("src_file.length", p_message->source_file_name->length, strnlen(src, 100) + 1); - ASSERT_EQUALS_STR("src_file.value", src, p_message->source_file_name->value, strnlen(src, 100)); + ASSERT_EQUALS_INT("src_file.length", p_message->source_file_name.length, strnlen(src, 100) + 1); + ASSERT_EQUALS_STR("src_file.value", src, p_message->source_file_name.value, strnlen(src, 100)); - ASSERT_EQUALS_INT("dest_id.length", p_message->destination_id->length, len); - ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*)p_message->destination_id->value, id); + ASSERT_EQUALS_INT("dest_id.length", p_message->destination_id.length, len); + ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*)p_message->destination_id.value, id); ASSERT_EQUALS_INT("next message should be at index ", next_message, length_of_message); @@ -428,9 +428,9 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { if (message->header.message_type == PROXY_PUT_REQUEST) { Message_put_proxy *p_message = (Message_put_proxy *) message->value; - ASSERT_EQUALS_INT("received proxy messages: dest.id", *(uint8_t*) p_message->destination_id->value, id); - ASSERT_EQUALS_STR("received proxy messages: src file", src, (char *) p_message->source_file_name->value, p_message->source_file_name->length); - ASSERT_EQUALS_STR("received proxy messages: dest file", dest, (char *) p_message->destination_file_name->value, p_message->destination_file_name->length); + ASSERT_EQUALS_INT("received proxy messages: dest.id", *(uint8_t*) p_message->destination_id.value, id); + ASSERT_EQUALS_STR("received proxy messages: src file", src, (char *) p_message->source_file_name.value, p_message->source_file_name.length); + ASSERT_EQUALS_STR("received proxy messages: dest file", dest, (char *) p_message->destination_file_name.value, p_message->destination_file_name.length); } ssp_free_message(message); From bc0e650cbe00851fac4993ccef043917fdb02273 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 1 Apr 2020 21:08:12 -0600 Subject: [PATCH 189/400] add save_file --- Program/include/filesystem_funcs.h | 4 +++- Program/test/filesystem_tests.c | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index f94a638..e7e142c 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -23,7 +23,9 @@ File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); int save_req(Request *req); -void save_file_meta_data(int fd, int *error, File *file); + +int save_file_meta_data(int fd, File *file); +int read_file_meta_data(int fd, File *file); Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index b298532..0da66d2 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -51,24 +51,37 @@ int test_save_file() { } int *error = 0; File file; + memset(&file, 0, sizeof(File)); + file.missing_offsets = linked_list(); Offset one = { 0, 250 }; Offset two = { - 0, 250 + 100, 250 }; Offset three = { - 0, 250 + 250, 250 }; file.missing_offsets->push(file.missing_offsets, &one, -1); file.missing_offsets->push(file.missing_offsets, &two, -1); file.missing_offsets->push(file.missing_offsets, &three, -1); - save_file_meta_data(fd, error, &file); + save_file_meta_data(fd, &file); + + File read; + memset(&read, 0, sizeof(File)); + + file.missing_offsets->freeOnlyList(file.missing_offsets); + + ssp_lseek(fd, 0, 0); + + read_file_meta_data(fd, &read); + + read.missing_offsets->free(read.missing_offsets, ssp_free); } static int test_saving_request(){ From 7eae1afdd33c15c7f33fcadebb92b37ca710adef Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 2 Apr 2020 21:09:38 -0600 Subject: [PATCH 190/400] add tests --- Program/include/filesystem_funcs.h | 3 +- Program/src/filesystem_funcs.c | 108 ++++++++++++++++++++--------- Program/test/filesystem_tests.c | 74 +++++++++++++++++--- 3 files changed, 139 insertions(+), 46 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index e7e142c..fde301a 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -26,7 +26,6 @@ int save_req(Request *req); int save_file_meta_data(int fd, File *file); int read_file_meta_data(int fd, File *file); - -Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num); +int get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req); #endif diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 13bd457..b0c79ca 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -375,21 +375,20 @@ static void save_file_callback(Node *node, void *element, void *param) { then length of offsets, then offsets */ -void save_file_meta_data(int fd, int *error, File *file) { +int save_file_meta_data(int fd, File *file) { char *error_message = "failed to write file\n"; + int err = ssp_write(fd, file, sizeof(File)); if (err < 0) { ssp_error(error_message); - *error = err; - return; + return -1; } err = ssp_write(fd, &file->missing_offsets->count, sizeof(uint32_t)); if (err < 0) { ssp_error(error_message); - *error = err; - return; + return -1; } struct params param = { @@ -397,10 +396,61 @@ void save_file_meta_data(int fd, int *error, File *file) { fd }; - file->missing_offsets->iterate(file->missing_offsets, save_file_callback, ¶m); + file->missing_offsets->iterate(file->missing_offsets, save_file_callback, ¶m); + return param.error; +} + +int read_file_meta_data(int fd, File *file) { + + uint32_t length = 0; + char *error_msg = "read failed meta data\n"; + int r = ssp_read(fd, (char *)file, sizeof(File)); + if (r < 0) { + ssp_error(error_msg); + return -1; + } + + r = ssp_read(fd, (char *)&length, sizeof(uint32_t)); + if (r < 0) { + ssp_error(error_msg); + return -1; + } + + Offset offset; + memset(&offset, 0, sizeof(Offset)); + + List *missing_offsets = linked_list(); + if (missing_offsets == NULL) { + return -1; + } + + for (int i = 0; i < length; i++) { + r = ssp_read(fd, (char*)&offset, sizeof(Offset)); + + if (r < 0) { + ssp_error(error_msg); + return -1; + } + + Offset *new_offset = ssp_alloc(1, sizeof(Offset)); + if (new_offset == NULL) { + missing_offsets->free(missing_offsets, ssp_free); + return -1; + } + + memcpy(new_offset, &offset, sizeof(Offset)); + missing_offsets->push(missing_offsets, new_offset, -1); + } + + file->missing_offsets = missing_offsets; + return 0; } +//length +//dest_file +//length +//src_file static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy_message) { char *error_message = "failed to write put proxy message\n"; @@ -479,7 +529,7 @@ static void write_message_callback(Node *node, void *element, void *param) { { case PROXY_PUT_REQUEST: proxy_message = (Message_put_proxy *)message->value; - ssp_printf("writing put proxy message\n"); + //ssp_printf("writing put proxy message\n"); write_put_proxy_message(fd, &p->error, proxy_message); break; @@ -502,12 +552,8 @@ int save_req(Request *req) { return -1; } - int req_len = sizeof(Request); - char buff[req_len]; - - memcpy(buff, req, req_len); - - int error = ssp_write(fd, buff, req_len); + //writing request struct + int error = ssp_write(fd, req, sizeof(Request)); if (error == -1) return -1; @@ -519,6 +565,7 @@ int save_req(Request *req) { if (!req->messages_to_user->count) return 0; + //writing message count error = ssp_write(fd, &req->messages_to_user->count, sizeof(uint8_t)); if (error == -1) return -1; @@ -549,8 +596,6 @@ Message *read_in_proxy_message(int fd) { ssp_error(error_message); return NULL; } - printf("destination_file_name_len %d\n", destination_file_name_len); - err = ssp_read(fd, destination_file_name, destination_file_name_len); if (err < 0) { ssp_error(error_message); @@ -581,7 +626,9 @@ Message *read_in_proxy_message(int fd) { if (message == NULL) return NULL; - Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, src_file_name, destination_file_name); + //why does this not work? + + Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, destination_file_name, src_file_name); if (proxy_message == NULL) { ssp_free(message); return NULL; @@ -592,7 +639,7 @@ Message *read_in_proxy_message(int fd) { } -Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { +int get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req) { char file_name[255]; uint8_t number_of_messages; @@ -602,42 +649,40 @@ Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { ssp_error("couldn't open file\n"); - return NULL; + return -1; } - int len = sizeof(Request); - Request req; - //read in request static data - int error = ssp_read(fd, (char *)&req, len); + //read in request struct + int error = ssp_read(fd, (char *)req, sizeof(Request)); if (error == -1){ - return NULL; + return -1; } //read in count of messages error = ssp_read(fd, &number_of_messages, sizeof(uint8_t)); if (error == -1){ - return NULL; + return -1; } List *messages = NULL; + if (number_of_messages > 0) { messages = linked_list(); if (messages == NULL) - return NULL; + return -1; for (int i = 0; i < number_of_messages; i++) { uint8_t message_type = 0; error = ssp_read(fd, &message_type, sizeof(uint8_t)); if (error == -1) - return NULL; + return -1; Message *message; switch (message_type) { case PROXY_PUT_REQUEST: - ssp_printf("reading put proxy message\n"); message = read_in_proxy_message(fd); break; @@ -649,16 +694,13 @@ Request *get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num) { } } - Request *r = ssp_alloc(1, sizeof(Request)); - memcpy(r, &req, sizeof(Request)); - r->messages_to_user = messages; + req->messages_to_user = messages; + req->file = NULL; - r->file = NULL; error = close(fd); if (error < 0) { ssp_error("couldn't close file descriptor \n"); } - return r; - + return error; } \ No newline at end of file diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 0da66d2..71315ed 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -4,7 +4,7 @@ #include "mib.h" #include "requests.h" #include - +#include "test.h" static void nak_print(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; @@ -43,6 +43,9 @@ int read_json_file_test() { int test_save_file() { + + DECLARE_NEW_TEST("test saving file"); + char *file_name = "temp/test_file_save"; int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { @@ -81,6 +84,30 @@ int test_save_file() { read_file_meta_data(fd, &read); + Offset *offset = read.missing_offsets->pop(read.missing_offsets); + ASSERT_EQUALS_INT("offset start should equal", three.start, offset->start); + ASSERT_EQUALS_INT("offset end should equal", three.end, offset->end); + ssp_free(offset); + + offset = read.missing_offsets->pop(read.missing_offsets); + ASSERT_EQUALS_INT("offset start should equal", two.start, offset->start); + ASSERT_EQUALS_INT("offset end should equal", two.end, offset->end); + ssp_free(offset); + + offset = read.missing_offsets->pop(read.missing_offsets); + ASSERT_EQUALS_INT("offset start should equal", one.start, offset->start); + ASSERT_EQUALS_INT("offset end should equal", one.end, offset->end); + ssp_free(offset); + + ASSERT_EQUALS_INT("File eof_checksum", file.eof_checksum, read.eof_checksum); + ASSERT_EQUALS_INT("File fd --should be ignored", file.fd, read.fd); + + ASSERT_EQUALS_INT("File is_temp", file.is_temp, read.is_temp); + ASSERT_EQUALS_INT("File next_offset_to_send", file.next_offset_to_send, read.next_offset_to_send); + + ASSERT_EQUALS_INT("File partial_checksum", file.partial_checksum, read.partial_checksum); + ASSERT_EQUALS_INT("File total_size", file.total_size, read.total_size); + read.missing_offsets->free(read.missing_offsets, ssp_free); } @@ -88,6 +115,8 @@ static int test_saving_request(){ int error = 0; + DECLARE_NEW_TEST("test saving requests"); + Request *req = init_request(1000); req->dest_cfdp_id = 1; req->transaction_sequence_number = 1; @@ -98,37 +127,60 @@ static int test_saving_request(){ char *src_file = "morestuff"; Message *m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, dest_file, src_file); + m->value = create_message_put_proxy(1, 1, src_file, dest_file); req->messages_to_user->push(req->messages_to_user, m, 0); m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, dest_file, src_file); + m->value = create_message_put_proxy(1, 1, src_file, dest_file); req->messages_to_user->push(req->messages_to_user, m, 0); m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, dest_file, src_file); + m->value = create_message_put_proxy(1, 1, src_file, dest_file); req->messages_to_user->push(req->messages_to_user, m, 0); - printf("write test\n"); error = save_req(req); if (error == -1) printf("failed to write\n"); - printf("read test\n"); - Request *got_req = get_req(1, 1); + Request got_req; + error = get_req(1, 1, &got_req); - print_request_state(got_req); + //print_request_state(&got_req); + Message *message = got_req.messages_to_user->pop(got_req.messages_to_user); + Message_put_proxy *proxy_message = (Message_put_proxy *) message->value; + + ssp_printf("recv dest file name %s : suppose to be %s\n", proxy_message->destination_file_name.value, dest_file); + ssp_printf("%d : %d\n", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + + ASSERT_EQUALS_STR("third message src file name", proxy_message->destination_file_name.value, dest_file, proxy_message->destination_file_name.length); + ASSERT_EQUALS_STR("third message src file name", proxy_message->source_file_name.value, src_file, proxy_message->source_file_name.length); + ASSERT_EQUALS_INT("third message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + + message = got_req.messages_to_user->pop(got_req.messages_to_user); + proxy_message = (Message_put_proxy *) message->value; + ASSERT_EQUALS_STR("second message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); + ASSERT_EQUALS_STR("second message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); + ASSERT_EQUALS_INT("second message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + + message = got_req.messages_to_user->pop(got_req.messages_to_user); + proxy_message = (Message_put_proxy *) message->value; + ASSERT_EQUALS_STR("first message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); + ASSERT_EQUALS_STR("first message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); + ASSERT_EQUALS_INT("first message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + ssp_cleanup_req(req); - ssp_cleanup_req(got_req); + got_req.messages_to_user->free(got_req.messages_to_user, ssp_free_message); + + //need to free list return error; } int file_system_tests() { int error = 0; - //int error = test_saving_request(); - error = test_save_file(); + error = test_saving_request(); + //error = test_save_file(); return error; } From 0b11a37245877a65b8c37d6f9aeb99286f9b37e0 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 11 Apr 2020 14:17:08 -0600 Subject: [PATCH 191/400] finish file journaling tests --- Program/include/filesystem_funcs.h | 8 +- Program/include/port.h | 2 - Program/include/protocol_handler.h | 2 +- Program/src/filesystem_funcs.c | 139 ++++++++++++++++++----------- Program/test/filesystem_tests.c | 23 +++-- Program/test/main.c | 7 +- 6 files changed, 106 insertions(+), 75 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index fde301a..87d93da 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -22,10 +22,10 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); -int save_req(Request *req); -int save_file_meta_data(int fd, File *file); -int read_file_meta_data(int fd, File *file); -int get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req); +int save_req_to_file(Request *req); +int save_file_to_file(int fd, File *file); +int get_file_from_file(int fd, File *file); +int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req); #endif diff --git a/Program/include/port.h b/Program/include/port.h index 8481fda..c8b298b 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -32,9 +32,7 @@ void ssp_error( char *msg); - void ssp_printf(char *stuff, ...); - void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index c1b8f1a..ca48394 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -15,7 +15,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); void process_pdu_eof(char *packet, Request *req, Response res); - Request *add_new_incomming_request(uint32_t source_id, + Request *new_incomming_request(uint32_t source_id, uint32_t transmission_mode, uint32_t transaction_sequence_number, Response res, diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index b0c79ca..58dd4e3 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -9,6 +9,7 @@ #include "list.h" #include "jsmn.h" #include "requests.h" +#include uint32_t get_file_size(char *source_file_name) { @@ -355,7 +356,6 @@ static void save_file_callback(Node *node, void *element, void *param) { char *error_message = "failed to write offset\n"; struct params *p = (struct params *) param; - int fd = p->fd; if (p->error < 0){ return; } @@ -375,7 +375,7 @@ static void save_file_callback(Node *node, void *element, void *param) { then length of offsets, then offsets */ -int save_file_meta_data(int fd, File *file) { +int save_file_to_file(int fd, File *file) { char *error_message = "failed to write file\n"; @@ -400,7 +400,7 @@ int save_file_meta_data(int fd, File *file) { return param.error; } -int read_file_meta_data(int fd, File *file) { +int get_file_from_file(int fd, File *file) { uint32_t length = 0; char *error_msg = "read failed meta data\n"; @@ -485,7 +485,7 @@ static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy return; } err = ssp_write(fd, proxy_message->destination_id.value, proxy_message->destination_id.length); - if (error < 0) { + if (err < 0) { *error = err; ssp_error(error_message); return; @@ -502,27 +502,13 @@ static void write_message_callback(Node *node, void *element, void *param) { Message *message = (Message *)element; - //SEEK_END 2 SEEK_CUR 1 SEEK_SET 0 - int error = ssp_lseek(fd, 0, SEEK_END); - if (error < 0) { - p->error = error; - ssp_error("failed to locate end\n"); - return; - } //write type - error = ssp_write(fd, &message->header.message_type, sizeof(uint8_t)); + int error = ssp_write(fd, &message->header.message_type, sizeof(uint8_t)); if (error < 0) { p->error = error; ssp_error("failed to append to end of file\n"); return; } - //move file end - error = ssp_lseek(fd, 0, SEEK_END); - if (error < 0) { - p->error = error; - ssp_error("failed to locate end\n"); - return; - } Message_put_proxy *proxy_message; switch (message->header.message_type) @@ -539,13 +525,30 @@ static void write_message_callback(Node *node, void *element, void *param) { } -#include +static int write_file_present_bool(int fd, File *file) { + int error = 0; + bool file_is_present = true; + bool file_is_not_present = false; + + if (file != NULL) { + error = ssp_write(fd, &file_is_present, sizeof(bool)); + if (error == -1) + return -1; + } else { + error = ssp_write(fd, &file_is_not_present, sizeof(bool)); + if (error == -1) + return -1; + } + return error; +} + //work in progress -int save_req(Request *req) { +//[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] +int save_req_to_file(Request *req) { char file_name[255]; snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); - + int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { ssp_error("couldn't open file\n"); @@ -562,14 +565,27 @@ int save_req(Request *req) { fd }; - if (!req->messages_to_user->count) - return 0; + //writing is file present + error = write_file_present_bool(fd, req->file); + if (error < 0) + return -1; + + //writing file + if (req->file != NULL) { + error = save_file_to_file(fd, req->file); + if (error < 0) + return -1; + } //writing message count error = ssp_write(fd, &req->messages_to_user->count, sizeof(uint8_t)); if (error == -1) return -1; + if (!req->messages_to_user->count) + return 0; + + //writing messages req->messages_to_user->iterate(req->messages_to_user, write_message_callback, ¶m); if (param.error < 0) return -1; @@ -628,7 +644,7 @@ Message *read_in_proxy_message(int fd) { //why does this not work? - Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, destination_file_name, src_file_name); + Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, src_file_name, destination_file_name); if (proxy_message == NULL) { ssp_free(message); return NULL; @@ -638,40 +654,15 @@ Message *read_in_proxy_message(int fd) { return message; } +static int get_messages_from_file(int fd, List *messages){ -int get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req) { - - char file_name[255]; uint8_t number_of_messages; - - snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); - - int fd = ssp_open(file_name, O_RDWR | O_CREAT); - if (fd < 0) { - ssp_error("couldn't open file\n"); - return -1; - } - - //read in request struct - int error = ssp_read(fd, (char *)req, sizeof(Request)); - if (error == -1){ - return -1; - } - - //read in count of messages - error = ssp_read(fd, &number_of_messages, sizeof(uint8_t)); + int error = ssp_read(fd, &number_of_messages, sizeof(uint8_t)); if (error == -1){ return -1; } - List *messages = NULL; - if (number_of_messages > 0) { - - messages = linked_list(); - if (messages == NULL) - return -1; - for (int i = 0; i < number_of_messages; i++) { uint8_t message_type = 0; @@ -684,6 +675,7 @@ int get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req) { { case PROXY_PUT_REQUEST: message = read_in_proxy_message(fd); + break; default: @@ -693,9 +685,50 @@ int get_req(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req) { messages->push(messages, message, -1); } } +} + +//[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] +int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req) { + + char file_name[255]; + + snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); + + int fd = ssp_open(file_name, O_RDWR | O_CREAT); + if (fd < 0) { + ssp_error("couldn't open file\n"); + return -1; + } + + //read in request struct + int error = ssp_read(fd, (char *)req, sizeof(Request)); + if (error == -1) + return -1; + + //check to see if file is present + bool is_file_present = false; + error = ssp_read(fd, (char *)&is_file_present, sizeof(bool)); + if (error == -1) + return -1; + + File *file; + if (is_file_present) { + file = ssp_alloc(1, sizeof(File)); + if (file == NULL) { + return -1; + } + error = get_file_from_file(fd, file); + } + + List *messages = linked_list(); + if (messages == NULL) + return -1; + + error = get_messages_from_file(fd, messages); + if (error == -1) + return -1; req->messages_to_user = messages; - req->file = NULL; error = close(fd); if (error < 0) { diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 71315ed..3fd4c3b 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -73,7 +73,7 @@ int test_save_file() { file.missing_offsets->push(file.missing_offsets, &three, -1); - save_file_meta_data(fd, &file); + save_file_to_file(fd, &file); File read; memset(&read, 0, sizeof(File)); @@ -82,7 +82,7 @@ int test_save_file() { ssp_lseek(fd, 0, 0); - read_file_meta_data(fd, &read); + get_file_from_file(fd, &read); Offset *offset = read.missing_offsets->pop(read.missing_offsets); ASSERT_EQUALS_INT("offset start should equal", three.start, offset->start); @@ -118,6 +118,7 @@ static int test_saving_request(){ DECLARE_NEW_TEST("test saving requests"); Request *req = init_request(1000); + req->dest_cfdp_id = 1; req->transaction_sequence_number = 1; req->local_entity.EOF_recv_indication = 1; @@ -138,21 +139,19 @@ static int test_saving_request(){ m->value = create_message_put_proxy(1, 1, src_file, dest_file); req->messages_to_user->push(req->messages_to_user, m, 0); - error = save_req(req); + error = save_req_to_file(req); if (error == -1) printf("failed to write\n"); - + + //---------------------------GETTING REQUEST-------------------------------- Request got_req; - error = get_req(1, 1, &got_req); - - //print_request_state(&got_req); + error = get_req_from_file(1, 1, &got_req); + if (error < 0) + printf("failed to write\n"); Message *message = got_req.messages_to_user->pop(got_req.messages_to_user); Message_put_proxy *proxy_message = (Message_put_proxy *) message->value; - ssp_printf("recv dest file name %s : suppose to be %s\n", proxy_message->destination_file_name.value, dest_file); - ssp_printf("%d : %d\n", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); - ASSERT_EQUALS_STR("third message src file name", proxy_message->destination_file_name.value, dest_file, proxy_message->destination_file_name.length); ASSERT_EQUALS_STR("third message src file name", proxy_message->source_file_name.value, src_file, proxy_message->source_file_name.length); ASSERT_EQUALS_INT("third message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); @@ -171,7 +170,7 @@ static int test_saving_request(){ ssp_cleanup_req(req); got_req.messages_to_user->free(got_req.messages_to_user, ssp_free_message); - + //need to free list return error; } @@ -180,7 +179,7 @@ static int test_saving_request(){ int file_system_tests() { int error = 0; error = test_saving_request(); - //error = test_save_file(); + error = test_save_file(); return error; } diff --git a/Program/test/main.c b/Program/test/main.c index 3211386..fef368c 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -18,11 +18,12 @@ int main () { int error = 0; //error = request_tests(); - error = packet_tests(); + //error = packet_tests(); //error = protocol_handler_test(); - + + //error = list_tests(); - //error = file_system_tests(); + error = file_system_tests(); //error = tasks_tests(); /* From c8a1625d0704d2b5623d1ee07d77d1820de0283e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 11 Apr 2020 14:21:48 -0600 Subject: [PATCH 192/400] fix compiler warnings --- Program/src/filesystem_funcs.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 58dd4e3..527d5df 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -597,7 +597,7 @@ int save_req_to_file(Request *req) { return 0; } -Message *read_in_proxy_message(int fd) { +static Message *read_in_proxy_message(int fd) { uint8_t destination_file_name_len = 0; char destination_file_name[255]; @@ -607,7 +607,7 @@ Message *read_in_proxy_message(int fd) { uint32_t dest_id = 0; char *error_message = "failed to read put proxy message\n"; - int err = ssp_read(fd, &destination_file_name_len, sizeof(uint8_t)); + int err = ssp_read(fd, (char*) &destination_file_name_len, sizeof(uint8_t)); if (err < 0) { ssp_error(error_message); return NULL; @@ -617,7 +617,7 @@ Message *read_in_proxy_message(int fd) { ssp_error(error_message); return NULL; } - err = ssp_read(fd, &src_file_name_len, sizeof(uint8_t)); + err = ssp_read(fd, (char*) &src_file_name_len, sizeof(uint8_t)); if (err < 0) { ssp_error(error_message); return NULL; @@ -627,7 +627,7 @@ Message *read_in_proxy_message(int fd) { ssp_error(error_message); return NULL; } - err = ssp_read(fd, &dest_id_len, sizeof(uint8_t)); + err = ssp_read(fd, (char*) &dest_id_len, sizeof(uint8_t)); if (err < 0) { ssp_error(error_message); return NULL; @@ -657,7 +657,7 @@ Message *read_in_proxy_message(int fd) { static int get_messages_from_file(int fd, List *messages){ uint8_t number_of_messages; - int error = ssp_read(fd, &number_of_messages, sizeof(uint8_t)); + int error = ssp_read(fd, (char *) &number_of_messages, sizeof(uint8_t)); if (error == -1){ return -1; } @@ -666,7 +666,7 @@ static int get_messages_from_file(int fd, List *messages){ for (int i = 0; i < number_of_messages; i++) { uint8_t message_type = 0; - error = ssp_read(fd, &message_type, sizeof(uint8_t)); + error = ssp_read(fd, (char *) &message_type, sizeof(uint8_t)); if (error == -1) return -1; @@ -685,6 +685,7 @@ static int get_messages_from_file(int fd, List *messages){ messages->push(messages, message, -1); } } + return 0; } //[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] From 57843a31326a76b50d343c10d3b8526264ed8abe Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 12 Apr 2020 13:22:12 -0600 Subject: [PATCH 193/400] Add config --- Program/include/config.h | 16 +++++++++++++++- Program/include/port.h | 15 +++++---------- Program/src/file_delivery_app.c | 10 +++++++++- Program/src/port.c | 30 +++++++++++++++--------------- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/Program/include/config.h b/Program/include/config.h index d433022..886cf4d 100644 --- a/Program/include/config.h +++ b/Program/include/config.h @@ -1 +1,15 @@ -//#define TEST \ No newline at end of file + +#define STACK_ALLOCATION 16384 + +//----------------Choose One Operating system function calls-------------------- +//#define POSIX_PORT +#define FREE_RTOS_PORT +//------------------------------------------------------------------------------ +//----------------Choose One File system function calls------------------------- +#define POSIX_FILESYSTEM +//------------------------------------------------------------------------------ +//----------------Choose as many networks as you need--------------------------- +#define POSIX_NETWORK +#define CSP_NETWORK +//------------------------------------------------------------------------------ + diff --git a/Program/include/port.h b/Program/include/port.h index c8b298b..d3ce726 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -2,22 +2,18 @@ #ifndef PORT_H #define PORT_H -#define STACK_ALLOCATION 16384 - - +/* +#define STACK_ALLOCATION 16384 -#define POSIX_PORT +//#define POSIX_PORT +#define FREE_RTOS_PORT #define POSIX_FILESYSTEM #define POSIX_NETWORK - #define CSP_NETWORK -//#define FREE_RTOS_PORT - +*/ #include "types.h" - - #ifdef CSP_NETWORK #include "csp.h" typedef struct csp_packet_wrapper { @@ -30,7 +26,6 @@ } csp_packet_wrapper; #endif - void ssp_error( char *msg); void ssp_printf(char *stuff, ...); void *ssp_alloc(uint32_t u_memb, size_t size); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index f079d86..7ddf52c 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -10,6 +10,14 @@ #include #include #include "utils.h" +#include "config.h" + + +#ifdef CSP_NETWORK + #include "csp.h" + +#endif + FTP *init_ftp(uint32_t my_cfdp_address) { @@ -30,7 +38,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { csp_init(remote_entity.UT_address); /* Init buffer system with 10 packets of maximum PACKET_LEN bytes each */ - csp_buffer_init(10, PACKET_LEN); + csp_buffer_init(1000, PACKET_LEN); /* Start router task with 500 word stack, OS task priority 1 */ csp_route_start_task(500, 1); diff --git a/Program/src/port.c b/Program/src/port.c index 92e27bf..400b0f7 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -11,6 +11,7 @@ #include "types.h" #include "config.h" + #ifdef POSIX_PORT #include #include @@ -28,9 +29,6 @@ #include #endif - - - #ifdef POSIX_FILESYSTEM #include #include @@ -121,18 +119,6 @@ void ssp_sendto(Response res) { if (res.type_of_network == posix && res.transmission_mode == UN_ACKNOWLEDGED_MODE) { struct sockaddr* addr = (struct sockaddr*) res.addr; - - #ifdef TEST - printf("sending outgoing packet (testing)\n"); - #endif - #ifndef TEST - - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); - if (err < 0) { - ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(*addr)); - ssp_error("ERROR in sendto"); - } - #endif } else if (res.type_of_network == posix && res.transmission_mode == ACKNOWLEDGED_MODE) { @@ -284,6 +270,10 @@ void ssp_error(char *error){ #ifdef POSIX_PORT perror(error); #endif + #ifdef FREE_RTOS_PORT + perror(error); + #endif + } void ssp_printf( char *stuff, ...) { @@ -294,6 +284,15 @@ void ssp_printf( char *stuff, ...) { va_end (args); fflush(stdout); #endif + + #ifdef FREE_RTOS_PORT + va_list args; + va_start(args, stuff); + vfprintf(stdout, stuff, args); + va_end (args); + fflush(stdout); + #endif + } @@ -317,6 +316,7 @@ int ssp_time_count() { #ifdef FREE_RTOS_PORT //some kind of ticks #endif + return -1; } From 19d94786f9d0ea5369efd9483e3011335805fc44 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 21 Apr 2020 21:29:12 -0600 Subject: [PATCH 194/400] add save to timeout --- Program/src/tasks.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index a31eb8b..830b4b4 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -34,8 +34,9 @@ static void timeout(Request *req) { if (req->local_entity.transaction_finished_indication){ ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); } else { - ssp_printf("stopped early, an issue occured transaction: %d\n", req->transaction_sequence_number); + ssp_printf("stopped early, timed out without finishing transaction, saving req to be reopened later: %d\n", req->transaction_sequence_number); print_request_state(req); + save_req_to_file(req); } req->procedure = clean_up; } @@ -52,7 +53,7 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, Request **request_container = &app->current_request; - int packet_index = process_pdu_header(packet,true, res, request_container, app->request_list, app); + int packet_index = process_pdu_header(packet, true, res, request_container, app->request_list, app); if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; From 1489d9248336a23a57d6dab658b4d90944767313 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 21 Apr 2020 22:19:50 -0600 Subject: [PATCH 195/400] remove req->procedure == none from on-server_time_out --- Program/src/protocol_handler.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 52b39b7..d2bfea9 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -583,7 +583,7 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, process_file_request_metadata(req); else { printf("just receiving messages, closing request\n"); - req->local_entity.transaction_finished_indication = true; + //req->local_entity.transaction_finished_indication = true; req->local_entity.EOF_recv_indication = true; req->procedure = none; } @@ -596,17 +596,16 @@ void on_server_time_out(Response res, Request *req) { if (req->paused) return; - if (req->procedure == none || - req->transmission_mode == UN_ACKNOWLEDGED_MODE || + if (req->transmission_mode == UN_ACKNOWLEDGED_MODE || req->local_entity.transaction_finished_indication) return; + if (req->resent_finished == RESEND_FINISHED_TIMES && req->local_entity.transaction_finished_indication) { req->procedure = clean_up; ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); return; } - //send request for metadata if (!req->local_entity.Metadata_recv_indication) { request_metadata(req, res); @@ -614,7 +613,7 @@ void on_server_time_out(Response res, Request *req) { } //receiving just messages, send back finished - if (req->file_size == 0) { + if (req->file_size == 0 && RESEND_FINISHED_TIMES != req->resent_finished) { resend_finished_pdu(req, res); return; } From 72d00b20be065b8def116231b52ce54999d9060f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 3 May 2020 11:51:22 -0600 Subject: [PATCH 196/400] add message cont part request --- Program/include/requests.h | 2 + Program/include/types.h | 8 ++++ Program/src/requests.c | 86 +++++++++++++++++++++++++------------- 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 6b5cb89..9f2d206 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -21,6 +21,8 @@ Request *put_request( int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name); +Message_cont_part_request *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, uint32_t originator_id, uint32_t transaction_id); + void print_request_state(Request *req); //Frees a message struct diff --git a/Program/include/types.h b/Program/include/types.h index 5cb880b..2460fdb 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -143,6 +143,14 @@ typedef struct message_put_proxy { } Message_put_proxy; +typedef struct message_cont_part_request { + + LV destination_id; + LV originator_id; + LV transaction_id; + +} Message_cont_part_request; + //can cast the message_value based on the message_type in the header; typedef struct message { diff --git a/Program/src/requests.c b/Program/src/requests.c index 99b36ea..5ebabbe 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -40,6 +40,15 @@ void create_lv(LV *lv, int len, void *value) { lv->length = len; } +//lv is what we copy into, packet is the buffer, and start is where in the buffer +//we start copying the lv to +void copy_lv_from_buffer(LV *lv, char *packet, uint32_t start) { + uint8_t len = packet[start]; + create_lv(lv, len, &packet[start + 1]); + return; +} + + Message *create_message(uint8_t type) { Message *message = ssp_alloc(1, sizeof(Message)); @@ -50,14 +59,6 @@ Message *create_message(uint8_t type) { } -//lv is what we copy into, packet is the buffer, and start is where in the buffer -//we start copying the lv to -void copy_lv_from_buffer(LV *lv, char *packet, uint32_t start) { - uint8_t len = packet[start]; - create_lv(lv, len, &packet[start + 1]); - return; -} - void ssp_free_put_proxy_message(Message_put_proxy* proxy_request) { free_lv(proxy_request->destination_file_name); @@ -85,6 +86,54 @@ void ssp_free_message(void *params) { ssp_free(message); } + + +/*------------------------------------------------------------------------------ + Messages (additional minor requests, things like mv files) +------------------------------------------------------------------------------*/ + +//Omission of source and destination filenames shall indicate that only Meta +//data will be delivered +Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name) { + + Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); + create_lv(&proxy->destination_file_name, strnlen(dest_name, MAX_PATH) + 1, dest_name); + create_lv(&proxy->source_file_name, strnlen(source_name, MAX_PATH) + 1, source_name); + create_lv(&proxy->destination_id, length_of_id, &beneficial_cfid); + return proxy; +} + +//beneficial_cfid is the destination id that the proxy will send to, length_of_id is in octets (or bytes) +int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { + + Message *message = create_message(PROXY_PUT_REQUEST); + message->value = create_message_put_proxy(beneficial_cfid, length_of_id, source_name, dest_name); + req->messages_to_user->push(req->messages_to_user, message, 0); + + return 1; +} + +Message_cont_part_request *create_message_put_proxy(uint32_t beneficial_cfid, + uint8_t length_of_id, + uint32_t originator_id, + uint8_t originator_id_length, + uint32_t transaction_id, + uint8_t transaction_id_length) { + + + Message_cont_part_request *message = ssp_alloc(1, sizeof(Message_put_proxy)); + create_lv(&message->destination_id, length_of_id, beneficial_cfid); + create_lv(&message->originator_id, originator_id_length, originator_id); + create_lv(&message->transaction_id, transaction_id_length, transaction_id); + return message; +} + + + +/*------------------------------------------------------------------------------ + Requests (major functions to initialize requests +------------------------------------------------------------------------------*/ + void ssp_cleanup_req(void *request) { if (request == NULL) @@ -256,27 +305,6 @@ void start_request(Request *req){ req->paused = false; } -//Omission of source and destination filenames shall indicate that only Meta -//data will be delivered -Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name) { - - Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); - create_lv(&proxy->destination_file_name, strnlen(dest_name, MAX_PATH) + 1, dest_name); - create_lv(&proxy->source_file_name, strnlen(source_name, MAX_PATH) + 1, source_name); - create_lv(&proxy->destination_id, length_of_id, &beneficial_cfid); - return proxy; -} - -//beneficial_cfid is the destination id that the proxy will send to, length_of_id is in octets (or bytes) -int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { - - Message *message = create_message(PROXY_PUT_REQUEST); - message->value = create_message_put_proxy(beneficial_cfid, length_of_id, source_name, dest_name); - req->messages_to_user->push(req->messages_to_user, message, 0); - - return 1; -} - static void print_messages_callback(Node *node, void *element, void *args) { Message *m = (Message*) element; From 168abdfb53323efd3799e8673000bcd78f48934e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 4 May 2020 20:53:42 -0600 Subject: [PATCH 197/400] add create message functions and testing --- Program/include/requests.h | 16 +++- Program/include/types.h | 3 +- Program/src/requests.c | 156 +++++++++++++++++++++++++---------- Program/test/makefile | 4 +- Program/test/request_tests.c | 53 +++++++++--- Program/test/unit_tests.h | 3 +- 6 files changed, 171 insertions(+), 64 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 9f2d206..2e3e99c 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -19,10 +19,21 @@ Request *put_request( ); int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); +int add_cont_partial_message_to_request(uint32_t beneficial_cfid, + uint8_t beneficial_id_length, + uint32_t originator_id, + uint8_t originator_id_length, + uint32_t transaction_id, + uint8_t transaction_id_length, + Request *req); Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name); -Message_cont_part_request *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, uint32_t originator_id, uint32_t transaction_id); - +Message_cont_part_request *create_message_cont_partial_request(uint32_t beneficial_cfid, + uint8_t beneficial_id_length, + uint32_t originator_id, + uint8_t originator_id_length, + uint32_t transaction_id, + uint8_t transaction_id_length); void print_request_state(Request *req); //Frees a message struct @@ -33,7 +44,6 @@ Message *create_message(uint8_t type); void create_lv(LV *lv, int len, void *value); void free_lv(LV lv); void print_request_procedure(Request *req); -void ssp_free_put_proxy_message(Message_put_proxy* proxy_request); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index 2460fdb..b5cbcf2 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -124,7 +124,8 @@ typedef struct tlv { #define PROXY_FILESTORE_RESPONSE 08 #define PROXY_PUT_CANCEL 09 - +//custom +#define PROXY_CONTINUE_PARTIAL 10 typedef struct message_header { diff --git a/Program/src/requests.c b/Program/src/requests.c index 5ebabbe..0981288 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -52,6 +52,9 @@ void copy_lv_from_buffer(LV *lv, char *packet, uint32_t start) { Message *create_message(uint8_t type) { Message *message = ssp_alloc(1, sizeof(Message)); + if (message == NULL) + return NULL; + //message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); memcpy(message->header.message_id_cfdp, "cfdp", 5); message->header.message_type = type; @@ -59,76 +62,139 @@ Message *create_message(uint8_t type) { } -void ssp_free_put_proxy_message(Message_put_proxy* proxy_request) { - - free_lv(proxy_request->destination_file_name); - free_lv(proxy_request->source_file_name); - free_lv(proxy_request->destination_id); - -} - -void ssp_free_message(void *params) { - - Message *message = (Message*) params; - Message_put_proxy* proxy_request; - - switch (message->header.message_type) - { - case PROXY_PUT_REQUEST: - proxy_request = (Message_put_proxy *) message->value; - ssp_free_put_proxy_message(proxy_request); - break; - - default: - break; - } - ssp_free(message->value); - ssp_free(message); -} - /*------------------------------------------------------------------------------ Messages (additional minor requests, things like mv files) ------------------------------------------------------------------------------*/ + + //Omission of source and destination filenames shall indicate that only Meta //data will be delivered -Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name) { +Message_put_proxy * +create_message_put_proxy(uint32_t beneficial_cfid, + uint8_t length_of_id, + char *source_name, + char *dest_name) { + + Message_put_proxy *message = ssp_alloc(1, sizeof(Message_put_proxy)); + if (message == NULL) + return NULL; - Message_put_proxy *proxy = ssp_alloc(1, sizeof(Message_put_proxy)); - create_lv(&proxy->destination_file_name, strnlen(dest_name, MAX_PATH) + 1, dest_name); - create_lv(&proxy->source_file_name, strnlen(source_name, MAX_PATH) + 1, source_name); - create_lv(&proxy->destination_id, length_of_id, &beneficial_cfid); - return proxy; + create_lv(&message->destination_file_name, strnlen(dest_name, MAX_PATH) + 1, dest_name); + create_lv(&message->source_file_name, strnlen(source_name, MAX_PATH) + 1, source_name); + create_lv(&message->destination_id, length_of_id, &beneficial_cfid); + return message; } //beneficial_cfid is the destination id that the proxy will send to, length_of_id is in octets (or bytes) -int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req) { +int add_proxy_message_to_request(uint32_t beneficial_cfid, + uint8_t length_of_id, + char *source_name, + char *dest_name, + Request *req) { Message *message = create_message(PROXY_PUT_REQUEST); + if (message == NULL) + return -1; + message->value = create_message_put_proxy(beneficial_cfid, length_of_id, source_name, dest_name); - req->messages_to_user->push(req->messages_to_user, message, 0); + if (message->value == NULL) { + ssp_free(message); + return -1; + } + req->messages_to_user->push(req->messages_to_user, message, 0); return 1; } -Message_cont_part_request *create_message_put_proxy(uint32_t beneficial_cfid, - uint8_t length_of_id, - uint32_t originator_id, - uint8_t originator_id_length, - uint32_t transaction_id, - uint8_t transaction_id_length) { +Message_cont_part_request * +create_message_cont_partial_request(uint32_t beneficial_cfid, + uint8_t beneficial_id_length, + uint32_t originator_id, + uint8_t originator_id_length, + uint32_t transaction_id, + uint8_t transaction_id_length) { + Message_cont_part_request *message = ssp_alloc(1, sizeof(Message_cont_part_request)); + if (message == NULL) + return NULL; - Message_cont_part_request *message = ssp_alloc(1, sizeof(Message_put_proxy)); - create_lv(&message->destination_id, length_of_id, beneficial_cfid); - create_lv(&message->originator_id, originator_id_length, originator_id); - create_lv(&message->transaction_id, transaction_id_length, transaction_id); + create_lv(&message->destination_id, beneficial_id_length, &beneficial_cfid); + create_lv(&message->originator_id, originator_id_length, &originator_id); + create_lv(&message->transaction_id, transaction_id_length, &transaction_id); return message; } +//beneficial_cfid is the destination id that the proxy will send to, originator +//is the sender's id +int add_cont_partial_message_to_request(uint32_t beneficial_cfid, + uint8_t beneficial_id_length, + uint32_t originator_id, + uint8_t originator_id_length, + uint32_t transaction_id, + uint8_t transaction_id_length, + Request *req){ + + Message *message = create_message(PROXY_CONTINUE_PARTIAL); + if (message == NULL) + return -1; + + message->value = create_message_cont_partial_request(beneficial_cfid, + beneficial_id_length, + originator_id, + originator_id_length, + transaction_id, + transaction_id_length + ); + if (message->value == NULL) { + ssp_free(message); + return -1; + } + + req->messages_to_user->push(req->messages_to_user, message, 0); + return 1; +} + + +static void ssp_free_put_proxy_message(Message_put_proxy* message) { + + free_lv(message->destination_file_name); + free_lv(message->source_file_name); + free_lv(message->destination_id); + +} +static void ssp_free_proxy_cont_partial_request(Message_cont_part_request *message) { + + free_lv(message->destination_id); + free_lv(message->originator_id); + free_lv(message->transaction_id); +} + +void ssp_free_message(void *params) { + + Message *message = (Message*) params; + Message_put_proxy* proxy_request; + Message_cont_part_request* proxy_cont_partial_request; + + switch (message->header.message_type) + { + case PROXY_PUT_REQUEST: + proxy_request = (Message_put_proxy *) message->value; + ssp_free_put_proxy_message(proxy_request); + break; + case PROXY_CONTINUE_PARTIAL: + proxy_cont_partial_request = (Message_cont_part_request *) message->value; + ssp_free_proxy_cont_partial_request(proxy_cont_partial_request); + break; + default: + break; + } + ssp_free(message->value); + ssp_free(message); +} /*------------------------------------------------------------------------------ Requests (major functions to initialize requests diff --git a/Program/test/makefile b/Program/test/makefile index aa3174f..25281d0 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -27,10 +27,10 @@ CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -CFILES += $(PROJDIR)/test/packet_tests.c +#CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c #CFILES += $(PROJDIR)/test/mock.c -#CFILES += $(PROJDIR)/test/request_tests.c +CFILES += $(PROJDIR)/test/request_tests.c #CFILES += $(PROJDIR)/test/tasks_tests.c #CFILES += $(PROJDIR)/test/list_tests.c diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 2090861..21f1819 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -8,7 +8,7 @@ #include "file_delivery_app.h" #include "unit_tests.h" -static void list_print_id(void *element, void *args) { +static void list_print_id(Node *node, void *element, void *args) { Request *req = (Request *) element; printf("id: %d trans number: %llu\n", req->dest_cfdp_id, req->transaction_sequence_number); } @@ -28,7 +28,7 @@ static int find_request(void *element, void *args) { return 0; } -static void list_print(void *element, void *args) { +static void list_print(Node *node, void *element, void *args) { Request *req = (Request *) element; ssp_printf("%s\n", req->source_file_name); @@ -121,9 +121,9 @@ static int add_proxy_message() { ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); Message_put_proxy *proxy = (Message_put_proxy *) message->value; - ASSERT_EQUALS_STR("proxy dest_id should equal 2", proxy->destination_id->value, &id, len); - ASSERT_EQUALS_STR("proxy src file", proxy->source_file_name->value, src, proxy->source_file_name->length); - ASSERT_EQUALS_STR("proxy dest file", proxy->destination_file_name->value, dest, proxy->destination_file_name->length); + ASSERT_EQUALS_STR("proxy dest_id should equal 2", proxy->destination_id.value, &id, len); + ASSERT_EQUALS_STR("proxy src file", proxy->source_file_name.value, src, proxy->source_file_name.length); + ASSERT_EQUALS_STR("proxy dest file", proxy->destination_file_name.value, dest, proxy->destination_file_name.length); ssp_free_message(message); ssp_cleanup_req(req); @@ -131,6 +131,38 @@ static int add_proxy_message() { } +static int add_continue_partial_message() { + int error = 0; + Request *req = init_request(5000); + + uint32_t src_id = 1; + uint32_t dest_id = 1; + uint32_t transaction_id = 4444; + + uint8_t len = 1; + + error = add_cont_partial_message_to_request( + dest_id, + len, + src_id, + len, + transaction_id, + 4, + req); + + Message *message = req->messages_to_user->pop(req->messages_to_user); + ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); + + Message_cont_part_request *proxy = (Message_cont_part_request *) message->value; + ASSERT_EQUALS_STR("proxy dest_id should equal 1", proxy->destination_id.value, &dest_id, proxy->destination_id.length); + ASSERT_EQUALS_STR("proxy originator id should equal 1", proxy->originator_id.value, &src_id, proxy->originator_id.length); + ASSERT_EQUALS_STR("proxy transaction id should equal 4444", proxy->transaction_id.value, &transaction_id, proxy->transaction_id.length); + + ssp_free_message(message); + ssp_cleanup_req(req); + + return error; +} int test_lv_functions() { @@ -139,7 +171,7 @@ int test_lv_functions() { char *str = "suphomie"; LV lv; - create_lv(lv, strnlen(str, 100), str); + create_lv(&lv, strnlen(str, 100), str); uint32_t len = strnlen(str, 100); @@ -152,7 +184,7 @@ int test_lv_functions() { free_lv(lv); - copy_lv_from_buffer(lv, packet, 0); + copy_lv_from_buffer(&lv, packet, 0); ASSERT_EQUALS_INT("copy lv length from packet", lv.length, len); ASSERT_EQUALS_STR("copy lv value from packet", str, lv.value, len); free_lv(lv); @@ -164,11 +196,7 @@ int request_user_input_tests() { FTP *app = init_ftp(1); put_request(2, "", "", 0, app); - put_request(2, NULL, NULL, 0, app); - - - app->close = true; ssp_thread_join(app->server_handle); } @@ -180,6 +208,7 @@ int request_tests() { error = request_user_input_tests(); error = add_proxy_message(); error = test_lv_functions(); - + error = add_continue_partial_message(); + return error; } \ No newline at end of file diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index ab0e197..9e227f0 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -18,7 +18,8 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *file_name); Request *mock_request(); int file_system_tests(); - + int request_tests(); + #define TEMP_FILESIZE 1000 //int server_tests(int client ); From 6195973f5c4bb4f4527adbe996535ed56f71269a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 8 May 2020 20:11:24 -0600 Subject: [PATCH 198/400] fix up before re-branching --- Program/src/main.c | 17 +++++++---- Program/src/packet.c | 58 +++++++++++++++++++++++------------ Program/src/requests.c | 11 +++++++ Program/src/start.sh | 1 - Program/test/main.c | 4 +-- Program/test/makefile | 2 +- Program/test/packet_tests.c | 60 ++++++++++++++++++++++++++++++++----- 7 files changed, 116 insertions(+), 37 deletions(-) delete mode 100644 Program/src/start.sh diff --git a/Program/src/main.c b/Program/src/main.c index b84f80c..d721440 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -55,18 +55,23 @@ int main(int argc, char** argv) { start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy2.jpg", ACKNOWLEDGED_MODE, app)); start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy3.jpg", ACKNOWLEDGED_MODE, app)); */ - //start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy4.jpg", ACKNOWLEDGED_MODE, app)); + Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy4.jpg", ACKNOWLEDGED_MODE, app); + start_request(req); + + /* + req = put_request(conf->client_cfdp_id, NULL, NULL, UN_ACKNOWLEDGED_MODE, app); + if (req != NULL) + add_proxy_message_to_request(2, 1, "pictures/pic.jpeg", "pictures/Proxy.jpg", req); - - Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy.jpg", req); start_request(req); - + */ + + /* req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); start_request(req); - + req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy3.jpg", req); start_request(req); diff --git a/Program/src/packet.c b/Program/src/packet.c index 44cee1d..04e8adc 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -321,10 +321,6 @@ uint16_t get_data_length(char*packet) { return ntohs(header->PDU_data_field_len); } - - - - struct packet_callback_params { char *packet; uint32_t *packet_index; @@ -345,18 +341,25 @@ static void add_messages_callback(Node *node, void *element, void *args) { memcpy(&packet[packet_index], &message->header.message_type, 1); packet_index += 1; - Message_put_proxy *proxy; + Message_put_proxy *proxy_put; + Message_cont_part_request *proxy_cont_part; switch (message->header.message_type) { case PROXY_PUT_REQUEST: - proxy = (Message_put_proxy *) message->value; - packet_index += copy_lv_to_buffer(&packet[packet_index], proxy->destination_id); - packet_index += copy_lv_to_buffer(&packet[packet_index], proxy->source_file_name); - packet_index += copy_lv_to_buffer(&packet[packet_index], proxy->destination_file_name); + proxy_put = (Message_put_proxy *) message->value; + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_put->destination_id); + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_put->source_file_name); + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_put->destination_file_name); + break; + case PROXY_CONTINUE_PARTIAL: + proxy_cont_part = (Message_cont_part_request *) message->value; + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->destination_id); + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->originator_id); + packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->transaction_id); break; - + default: break; } @@ -384,7 +387,8 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { } Message *m; - Message_put_proxy *put_proxy; + Message_put_proxy *proxy_put; + Message_cont_part_request *proxy_cont_part; uint32_t message_start = start + 6; @@ -394,18 +398,34 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { m = create_message(PROXY_PUT_REQUEST); m->value = ssp_alloc(1, sizeof(Message_put_proxy)); - put_proxy = (Message_put_proxy *) m->value; + proxy_put = (Message_put_proxy *) m->value; - copy_lv_from_buffer(&put_proxy->destination_id, packet, message_start); - message_start += put_proxy->destination_id.length + 1; + copy_lv_from_buffer(&proxy_put->destination_id, packet, message_start); + message_start += proxy_put->destination_id.length + 1; - copy_lv_from_buffer(&put_proxy->source_file_name, packet, message_start); - message_start += put_proxy->source_file_name.length + 1; + copy_lv_from_buffer(&proxy_put->source_file_name, packet, message_start); + message_start += proxy_put->source_file_name.length + 1; - copy_lv_from_buffer(&put_proxy->destination_file_name, packet, message_start); - message_start += put_proxy->destination_file_name.length + 1; + copy_lv_from_buffer(&proxy_put->destination_file_name, packet, message_start); + message_start += proxy_put->destination_file_name.length + 1; break; - + + case PROXY_CONTINUE_PARTIAL: + m = create_message(PROXY_CONTINUE_PARTIAL); + + m->value = ssp_alloc(1, sizeof(Message_cont_part_request)); + proxy_cont_part = (Message_cont_part_request *) m->value; + + copy_lv_from_buffer(&proxy_cont_part->destination_id, packet, message_start); + message_start += proxy_cont_part->destination_id.length + 1; + + copy_lv_from_buffer(&proxy_cont_part->originator_id, packet, message_start); + message_start += proxy_cont_part->originator_id.length + 1; + + copy_lv_from_buffer(&proxy_cont_part->transaction_id, packet, message_start); + message_start += proxy_cont_part->transaction_id.length + 1; + + default: break; } diff --git a/Program/src/requests.c b/Program/src/requests.c index 0981288..3ee9969 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -336,6 +336,12 @@ Request *put_request( Request *req; uint32_t file_size = 0; + bool exists = does_file_exist(source_file_name); + if (exists == false) { + ssp_printf("ERROR: File does not exist\n"); + return NULL; + } + ssp_printf("trying to start new request\n"); if (source_file_name == NULL || destination_file_name == NULL) { req = start_new_client_request(app, dest_id); @@ -368,6 +374,11 @@ Request *put_request( } void start_request(Request *req){ + if (req == NULL) { + ssp_printf("ERROR: couldn't start request\n"); + return; + } + ssp_printf("started request\n"); req->paused = false; } diff --git a/Program/src/start.sh b/Program/src/start.sh deleted file mode 100644 index d5cac58..0000000 --- a/Program/src/start.sh +++ /dev/null @@ -1 +0,0 @@ -sudo tc qdisc add dev lo root netem loss 10% diff --git a/Program/test/main.c b/Program/test/main.c index fef368c..7935b23 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -18,12 +18,12 @@ int main () { int error = 0; //error = request_tests(); - //error = packet_tests(); + error = packet_tests(); //error = protocol_handler_test(); //error = list_tests(); - error = file_system_tests(); + //error = file_system_tests(); //error = tasks_tests(); /* diff --git a/Program/test/makefile b/Program/test/makefile index 25281d0..ff00eba 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -27,7 +27,7 @@ CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c -#CFILES += $(PROJDIR)/test/packet_tests.c +CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c #CFILES += $(PROJDIR)/test/mock.c CFILES += $(PROJDIR)/test/request_tests.c diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 4289405..2d32fc4 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -83,10 +83,14 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ ASSERT_EQUALS_STR("test proper datapacket creation", &packet[packet_index + 4], "tempfileyo", 10); ASSERT_EQUALS_INT("should equal 100", packet_index + 87 + 4, 100); + build_data_packet(packet, packet_index, file, 1000); uint32_t offset_in_packet = 0; memcpy(&offset_in_packet, &packet[packet_index], 4); + + printf("%d\n", offset_in_packet); + ASSERT_EQUALS_INT("test proper datapacket offset set", offset_in_packet, 10); free_file(file); @@ -262,12 +266,12 @@ int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_nu ASSERT_EQUALS_INT("CRC = CRC", header->CRC_flag, new_header->CRC_flag); ASSERT_EQUALS_INT("direction = direction", header->direction, new_header->direction); ASSERT_EQUALS_INT("length_of_entity_IDs = length_of_entity_IDs ", header->length_of_entity_IDs, new_header->length_of_entity_IDs); - ASSERT_EQUALS_INT("PDU data_field_len = PDU_data_field_len ", header->PDU_data_field_len, new_header->PDU_data_field_len); + //ASSERT_EQUALS_INT("PDU data_field_len = PDU_data_field_len ", header->PDU_data_field_len, new_header->PDU_data_field_len); ASSERT_EQUALS_INT("PDU_type = PDU_type", header->PDU_type, new_header->PDU_type); ASSERT_EQUALS_INT("reserved_bit_0 = reserved_bit_0 ", header->reserved_bit_0, new_header->reserved_bit_0); ASSERT_EQUALS_INT("reserved_bit_1 = reserved_bit_1 ", header->reserved_bit_1, new_header->reserved_bit_1); ASSERT_EQUALS_INT("reserved_bit_2 = reserved_bit_2 ", header->reserved_bit_2, new_header->reserved_bit_2); - ASSERT_EQUALS_INT("version = version", header->version, new_header->version); + //ASSERT_EQUALS_INT("version = version", header->version, new_header->version); ASSERT_EQUALS_INT("transaction_seq_num_len = transaction_seq_num_len ", header->transaction_seq_num_len, new_header->transaction_seq_num_len); ASSERT_EQUALS_INT("transmission_mode = transmission_mode ", 0, new_header->transmission_mode); ASSERT_EQUALS_INT("total header length equal ", packet_index, length); @@ -313,6 +317,48 @@ int test_build_metadata_packet(char *packet, uint32_t start) { } +int test_add_cont_part_to_packet(char *packet, uint32_t start){ + + DECLARE_NEW_TEST("testing add_message_cont_part_to_packet"); + + uint32_t packet_index = start; + + Request *req = init_request(1000); + int error = add_cont_partial_message_to_request(1,1,1,1,1,1,req); + + memset(&packet[start], 0, 100); + packet_index = add_messages_to_packet(packet, packet_index, req->messages_to_user); + + ASSERT_EQUALS_STR("'cfdp' should be at the start of the message", &packet[start], "cfdp", 5); + ASSERT_EQUALS_INT("testing PROXY_PUT_REQUEST code", (uint8_t) packet[start + 5], PROXY_CONTINUE_PARTIAL); + + + LV dest_id, original_id, transaction_id; + + packet_index = start + 6; + copy_lv_from_buffer(&dest_id, packet, packet_index); + ASSERT_EQUALS_INT("dest_id.length", dest_id.length, 1); + ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*) (dest_id.value), id); + packet_index += dest_id.length + 1; + free_lv(dest_id); + + + copy_lv_from_buffer(&src_file, packet, packet_index); + ASSERT_EQUALS_INT("src_file.length", src_file.length, strnlen(src, 100) + 1); + ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file.value, src_file.length); + packet_index += src_file.length + 1; + free_lv(src_file); + + + copy_lv_from_buffer(&dest_file, packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", dest_file.length, strnlen(dest, 100) + 1); + ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file.value, dest_file.length); + free_lv(dest_file); + + ssp_cleanup_req(req); +} + + int test_add_messages_to_packet(char *packet, uint32_t start) { char *dest = "dest"; @@ -446,13 +492,14 @@ int packet_tests() { printf("starting Packet Tests (creating and changing packet values)\n"); - + //setting host name for testing char *host_name = "127.0.0.1"; uint32_t addr[sizeof(uint32_t)]; inet_pton(AF_INET, host_name, addr); - char *packet = calloc(PACKET_TEST_SIZE, sizeof(char)); + char packet[PACKET_TEST_SIZE]; + uint64_t sequence_number = 12345663234; Pdu_header pdu_header; @@ -462,7 +509,7 @@ int packet_tests() { get_header_from_mib(&pdu_header, remote_entity, 2); int data_start_index = test_build_pdu_header(packet, &pdu_header, sequence_number); - /* + test_build_ack_eof_pdu(packet, data_start_index); test_build_nak_packet(packet, data_start_index); test_respond_to_naks(packet, data_start_index); @@ -478,9 +525,6 @@ int packet_tests() { test_get_message_from_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); - */ - ssp_cleanup_pdu_header(&pdu_header); - ssp_free(packet); return 0; } From b26b8c8386ac8099cd87345df6afb9d8ab59194d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 May 2020 16:05:28 -0600 Subject: [PATCH 199/400] change headers --- Program/include/filesystem_funcs.h | 4 ++++ Program/include/packet.h | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 87d93da..c569d98 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -7,6 +7,10 @@ #define TEMP_FILESIZE 1000 +struct params { + int error; + int fd; +}; uint32_t get_file_size(char *source_file_name); diff --git a/Program/include/packet.h b/Program/include/packet.h index 7c9f71f..964f2a5 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -2,12 +2,7 @@ #ifndef PACKET_H #define PACKET_H -#define PACKET_HEADER_LEN 224 -// PACKET_HEADER_LEN + data max size = (65536 * 8) -#define PACKET_MAX_LEN 524512 -//#define PACKET_LEN 1024 + 224 // 1248 limiting the data portion to 56 bytes -#define PACKET_LEN 252 //dont change this #define PACKET_STATIC_HEADER_LEN 4 //in bytes From b485d3cd4719156921fa9a6e3da58550ac1ccc58 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 May 2020 16:06:40 -0600 Subject: [PATCH 200/400] remove packet data len --- Program/include/types.h | 4 +--- Program/src/file_delivery_app.c | 7 +++---- Program/src/filesystem_funcs.c | 5 +---- Program/src/protocol_handler.c | 21 +++++++++++++-------- Program/src/requests.c | 1 - 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index b5cbcf2..6810c72 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -516,7 +516,7 @@ typedef struct remote_entity { unsigned int CRC_required : 1; //in octets - unsigned int max_file_segment_len; + unsigned int mtu; //in octets unsigned int keep_alive_discrepancy_limit; @@ -588,8 +588,6 @@ typedef struct request { char source_file_name[MAX_PATH]; char destination_file_name[MAX_PATH]; - uint32_t packet_data_len; - //previous timeout time in seconds int timeout; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index f079d86..5f778da 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -11,7 +11,6 @@ #include #include "utils.h" - FTP *init_ftp(uint32_t my_cfdp_address) { @@ -30,7 +29,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { csp_init(remote_entity.UT_address); /* Init buffer system with 10 packets of maximum PACKET_LEN bytes each */ - csp_buffer_init(10, PACKET_LEN); + csp_buffer_init(10, remote_entity.mtu); /* Start router task with 500 word stack, OS task priority 1 */ csp_route_start_task(500, 1); @@ -40,7 +39,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { if (app == NULL) return NULL; - app->packet_len = PACKET_LEN; + app->packet_len = remote_entity.mtu; app->my_cfdp_id = my_cfdp_address; app->close = false; app->remote_entity = remote_entity; @@ -97,7 +96,7 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { return NULL; } - client->packet_len = PACKET_LEN; + client->packet_len = remote_entity.mtu; client->remote_entity = remote_entity; get_header_from_mib(&client->pdu_header, remote_entity, app->my_cfdp_id); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 527d5df..170adfb 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -346,10 +346,7 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa return 0; } -static struct params { - int error; - int fd; -}; + static void save_file_callback(Node *node, void *element, void *param) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index d2bfea9..1ed75e2 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -118,7 +118,7 @@ static int find_request(void *element, void *args) { memcpy(found_req->res.addr, res.addr, res.size_of_addr); - found_req->res.packet_len = app->packet_len; + found_req->res.packet_len = remote_entity.mtu; found_req->res.sfd = res.sfd; found_req->res.transmission_mode = app->remote_entity.default_transmission_mode; found_req->res.type_of_network = app->remote_entity.type_of_network; @@ -148,17 +148,24 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; + /* if (app->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); return -1; } - - uint16_t len = get_data_length(packet); + */ //if packet is from the same request, don't' change current request Request *current_req = (*req); - if (current_req != NULL && current_req->transaction_sequence_number == transaction_sequence_number && current_req->dest_cfdp_id == source_id){ - current_req->packet_data_len = len; + + uint16_t len = get_data_length(packet); + + if (len > app->packet_len){ + ssp_printf("packet received %d that was too big for our buffer %d\n", len, app->packet_len); + return -1; + } + + if (current_req != NULL && current_req->transaction_sequence_number == transaction_sequence_number && current_req->dest_cfdp_id == source_id){ return packet_index; } @@ -193,7 +200,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r return -1; } - found_req->packet_data_len = len; *req = found_req; return packet_index; @@ -628,13 +634,12 @@ void on_server_time_out(Response res, Request *req) { resend_eof_ack(req, res); } - + //if have not received metadata for a file tranaction, this should not ever trigger //TODO add asert if (req->file == NULL) { ssp_printf("file is null, not sending data naks"); return; } - //send missing NAKS if (req->file->missing_offsets->count > 0) { request_data(req, res); diff --git a/Program/src/requests.c b/Program/src/requests.c index 3ee9969..777db13 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -314,7 +314,6 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { req->dest_cfdp_id = client->remote_entity.cfdp_id; req->pdu_header = client->pdu_header; req->res.packet_len = client->packet_len; - req->packet_data_len = app->packet_len; client->request_list->insert(client->request_list, req, 0); From ef1ebb4a978859c49ff6232a8d83e5d4ecb813c2 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 May 2020 16:08:28 -0600 Subject: [PATCH 201/400] add mtu field --- Program/src/mib.c | 13 +++++-------- Program/src/mib/peer_1.json | 2 +- Program/src/mib/peer_2.json | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Program/src/mib.c b/Program/src/mib.c index 0803276..0ce8fef 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -46,7 +46,7 @@ enum { PARSE_prompt_transmission_interval, PARSE_disposition_of_incomplete, PARSE_CRC_required, - PARSE_max_file_segment_len, + PARSE_mtu, PARSE_keep_alive_discrepancy_limit, PARSE_positive_ack_timer_expiration_limit, PARSE_nak_timer_expiration_limit, @@ -69,9 +69,9 @@ static char *parse_list[PARSE_TOTAL] = { "immediate_nak_mode_enabled" , "prompt_transmission_interval" , "disposition_of_incomplete" , - + "CRC_required" , - "max_file_segment_len" , + "MTU" , "keep_alive_discrepancy_limit" , "positive_ack_timer_expiration_limit" , "nak_timer_expiration_limit" , @@ -134,8 +134,8 @@ static void parse_mib(char *key, char *value, void *params) { case PARSE_CRC_required: remote->CRC_required = atol(value); break; - case PARSE_max_file_segment_len: - remote->max_file_segment_len = atol(value); + case PARSE_mtu: + remote->mtu = atol(value); break; case PARSE_keep_alive_discrepancy_limit: remote->keep_alive_discrepancy_limit = atol(value); @@ -152,10 +152,7 @@ static void parse_mib(char *key, char *value, void *params) { default: break; } - - } - } int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { diff --git a/Program/src/mib/peer_1.json b/Program/src/mib/peer_1.json index 467b35e..9ae6348 100644 --- a/Program/src/mib/peer_1.json +++ b/Program/src/mib/peer_1.json @@ -4,6 +4,7 @@ "UT_port" : 1111, "type_of_network" : 1, "default_transmission_mode" : 1, + "MTU" : 1500, "one_way_light_time" : 123, "total_round_trip_allowance" : 123, @@ -15,7 +16,6 @@ "disposition_of_incomplete" : 123, "CRC_required" : 0, - "max_file_segment_len" : 1200, "keep_alive_discrepancy_limit" : 8, "positive_ack_timer_expiration_limit" : 123, "nak_timer_expiration_limit" : 123, diff --git a/Program/src/mib/peer_2.json b/Program/src/mib/peer_2.json index dbf2600..7ef92a4 100644 --- a/Program/src/mib/peer_2.json +++ b/Program/src/mib/peer_2.json @@ -4,6 +4,7 @@ "UT_port" : 1112, "type_of_network" : 1, "default_transmission_mode" : 1, + "MTU" : 1500, "one_way_light_time" : 123, "total_round_trip_allowance" : 123, @@ -15,7 +16,6 @@ "disposition_of_incomplete" : 123, "CRC_required" : 0, - "max_file_segment_len" : 1200, "keep_alive_discrepancy_limit" : 8, "positive_ack_timer_expiration_limit" : 123, "nak_timer_expiration_limit" : 123, From 98a54fc626f8f68ee1ec60164b9333652e5598f9 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 May 2020 16:08:42 -0600 Subject: [PATCH 202/400] clean up packets --- Program/src/packet.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 04e8adc..3c8dc91 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -134,9 +134,6 @@ uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Reques return 1; } - Pdu_header *header = (Pdu_header *) packet; - header->PDU_type = DATA; - uint16_t packet_index = start; File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; packet_offset->offset = offset; @@ -152,7 +149,7 @@ uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Reques } uint16_t data_len = bytes + 4; - set_data_length(packet, data_len); + set_packet_header(packet, data_len, DATA); if (bytes < data_size) return 1; @@ -170,11 +167,6 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len return 0; } - - Pdu_header *header = (Pdu_header *) packet; - //set header to file directive 0 is directive, 1 is data - header->PDU_type = 1; - uint16_t packet_index = start; File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; @@ -198,8 +190,7 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len //add bytes read, and the packet offset to the data_field length uint16_t data_len = bytes + 4; - set_data_length(packet, data_len); - + set_packet_header(packet, data_len, DATA); if (bytes < data_size) return 1; @@ -234,9 +225,8 @@ void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t packet_index += 4; //TODO addTLV fault_location - uint16_t data_len = htons(packet_index - start); - set_data_length(packet, data_len); - + uint16_t data_len = packet_index - start; + set_packet_header(packet, data_len, DIRECTIVE); } //this is a callback for building nak_array server side @@ -282,7 +272,7 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet_index += sizeof(Offset) * count; uint16_t data_len = packet_index - start; - set_data_length(packet, data_len); + set_packet_header(packet, data_len, DIRECTIVE); return data_len; } @@ -297,8 +287,7 @@ uint8_t build_ack(char*packet, uint32_t start, uint8_t type) { pdu_ack->condition_code = COND_NO_ERROR; packet_index += 2; uint16_t data_len = packet_index - start; - set_data_length(packet, data_len); - + set_packet_header(packet, data_len, DIRECTIVE); return data_len; } @@ -307,7 +296,7 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { packet[start] = NAK_DIRECTIVE; packet[start + 1] = directive; - set_data_length(packet, data_len); + set_packet_header(packet, data_len, DIRECTIVE); return data_len; } From e1fe62f5d3f092551272328a37b056c082879444 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 9 May 2020 16:09:30 -0600 Subject: [PATCH 203/400] clean up tests --- Program/test/mock.c | 73 ++++++++++++++++--------------------- Program/test/packet_tests.c | 32 +++++----------- 2 files changed, 42 insertions(+), 63 deletions(-) diff --git a/Program/test/mock.c b/Program/test/mock.c index e17b15a..a8fd483 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -14,41 +14,40 @@ #include +void mock_mock_remote_entity(Remote_entity *remote_entity, uint32_t cfdp_id) { + + remote_entity->UT_address = 1; + remote_entity->UT_port = 1; + remote_entity->type_of_network = 1; + remote_entity->one_way_light_time = 1; + remote_entity->total_round_trip_allowance = 1; + remote_entity->async_NAK_interval = 1; + remote_entity->async_keep_alive_interval = 1; + remote_entity->async_report_interval= 1; + remote_entity->immediate_nak_mode_enabled= 1; + remote_entity->prompt_transmission_interval= 1; + remote_entity->default_transmission_mode= 1; + remote_entity->disposition_of_incomplete= 1; + remote_entity->CRC_required= 1; + remote_entity->mtu= 1500; + remote_entity->keep_alive_discrepancy_limit= 1; + remote_entity->positive_ack_timer_expiration_limit= 1; + remote_entity->nak_timer_expiration_limit= 1; + remote_entity->transaction_inactivity_limit= 1; + remote_entity->cfdp_id = cfdp_id; -MIB *mock_mib() { - - //Memory information base - MIB *mib = init_mib(); - - //setting host name for testing - char *host_name = "127.0.0.1"; - uint32_t addr[sizeof(uint32_t)]; - inet_pton(AF_INET, host_name, addr); - - //adding new cfdp entities to management information base - add_new_cfdp_entity(mib, 1, *addr, 1111, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 2, *addr, 1112, posix, UN_ACKNOWLEDGED_MODE); - add_new_cfdp_entity(mib, 7, *addr, 1113, posix, UN_ACKNOWLEDGED_MODE); - - //add_new_cfdp_entity(mib, 3, 1, 1, csp, UN_ACKNOWLEDGED_MODE); - //add_new_cfdp_entity(mib, 4, 2, 2, csp, UN_ACKNOWLEDGED_MODE); - - //add_new_cfdp_entity(mib, 5, 3, 3, csp, ACKNOWLEDGED_MODE); - //add_new_cfdp_entity(mib, 6, 4, 4, csp, ACKNOWLEDGED_MODE); - - return mib; } - int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { Pdu_header pdu_header; - int error = get_header_from_mib2(pdu_header, remote_entity, src_id); - int packet_index = build_pdu_header(packet, 1, 0, pdu_header); + Remote_entity remote_entity; + + mock_mock_remote_entity(&remote_entity, src_id); + + int error = get_header_from_mib(&pdu_header, remote_entity, dest_id); + int packet_index = build_pdu_header(packet, 1, 0, &pdu_header); - ssp_cleanup_pdu_header(pdu_header); - free_mib(mib); - return packet_index; } @@ -56,23 +55,18 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *fil int packet_index = mock_packet(packet, dest_id, src_id); File *file = create_file(file_name, false); - file->partial_checksum = check_sum_file(file, 1000); - build_eof_packet(packet, packet_index, file); + build_eof_packet(packet, packet_index, file->total_size, check_sum_file(file, 1000)); return file; } -void mock_metadata_packet() { - - -} Response *mock_response() { Response *res = calloc(1, sizeof(Response)); int addr = 16; res->addr = &addr; res->sfd = 1; - res->packet_len = 2000; + res->packet_len = 1500; res->size_of_addr = 16; res->type_of_network = posix; res->transmission_mode = UN_ACKNOWLEDGED_MODE; @@ -80,11 +74,8 @@ Response *mock_response() { } - - Request *mock_request() { Request *req = init_request(5000); - MIB *mib = mock_mib(); char *dest = "dest"; char *src = "src"; @@ -95,8 +86,9 @@ Request *mock_request() { memcpy (req->source_file_name, dest, strnlen(dest, 255)); memcpy (req->destination_file_name, src, strnlen(src, 255)); - req->pdu_header = get_header_from_mib(mib, id, 2); - req->remote_entity = get_remote_entity(mib, 1); + + mock_mock_remote_entity(&req->remote_entity, id); + get_header_from_mib(&req->pdu_header, req->remote_entity, 1); int addr = 16; req->res.addr = malloc(5); @@ -108,7 +100,6 @@ Request *mock_request() { req->res.transmission_mode = UN_ACKNOWLEDGED_MODE; req->res.msg = req->buff; - free_mib(mib); return req; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 2d32fc4..a81ee4d 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -82,17 +82,6 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ ASSERT_EQUALS_INT("test proper datapacket offset set", (uint64_t)packet[packet_index], 0); ASSERT_EQUALS_STR("test proper datapacket creation", &packet[packet_index + 4], "tempfileyo", 10); - ASSERT_EQUALS_INT("should equal 100", packet_index + 87 + 4, 100); - - build_data_packet(packet, packet_index, file, 1000); - - uint32_t offset_in_packet = 0; - memcpy(&offset_in_packet, &packet[packet_index], 4); - - printf("%d\n", offset_in_packet); - - ASSERT_EQUALS_INT("test proper datapacket offset set", offset_in_packet, 10); - free_file(file); } @@ -338,22 +327,22 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ packet_index = start + 6; copy_lv_from_buffer(&dest_id, packet, packet_index); ASSERT_EQUALS_INT("dest_id.length", dest_id.length, 1); - ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*) (dest_id.value), id); + ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*) (dest_id.value), 1); packet_index += dest_id.length + 1; free_lv(dest_id); - copy_lv_from_buffer(&src_file, packet, packet_index); - ASSERT_EQUALS_INT("src_file.length", src_file.length, strnlen(src, 100) + 1); - ASSERT_EQUALS_STR("src_file.value", src, (char *) src_file.value, src_file.length); - packet_index += src_file.length + 1; - free_lv(src_file); + copy_lv_from_buffer(&original_id, packet, packet_index); + ASSERT_EQUALS_INT("original_id.length", original_id.length, 1); + ASSERT_EQUALS_INT("original_id.value", *(uint8_t*)original_id.value, 1); + packet_index += original_id.length + 1; + free_lv(original_id); - copy_lv_from_buffer(&dest_file, packet, packet_index); - ASSERT_EQUALS_INT("dest_file.length", dest_file.length, strnlen(dest, 100) + 1); - ASSERT_EQUALS_STR("dest_file.value", dest, (char *)dest_file.value, dest_file.length); - free_lv(dest_file); + copy_lv_from_buffer(&transaction_id, packet, packet_index); + ASSERT_EQUALS_INT("dest_file.length", transaction_id.length, 1); + ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*)transaction_id.value, transaction_id.length); + free_lv(transaction_id); ssp_cleanup_req(req); } @@ -515,7 +504,6 @@ int packet_tests() { test_respond_to_naks(packet, data_start_index); memset(packet, 0, PACKET_TEST_SIZE); - data_start_index = test_build_pdu_header(packet, &pdu_header, sequence_number); test_build_data_packet(packet, data_start_index); test_build_metadata_packet(packet, data_start_index); From 0e25b7a6019cfe3b49552efd862a64a130b5ab3d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 12 May 2020 19:10:16 -0600 Subject: [PATCH 204/400] moved functions --- Program/src/file_delivery_app.c | 103 ++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 39 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 5f778da..7900e53 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -11,6 +11,42 @@ #include #include "utils.h" + + +static void create_ssp_server_drivers(FTP *app) { + + if (app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); + + } else if(app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); + + } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); + + } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); + } +} + +static void create_ssp_client_drivers(Client *client) { + Remote_entity remote_entity = client->remote_entity; + + if (remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); + + } else if(remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); + + } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); + + } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); + } + +} + FTP *init_ftp(uint32_t my_cfdp_address) { @@ -38,43 +74,40 @@ FTP *init_ftp(uint32_t my_cfdp_address) { FTP *app = ssp_alloc(sizeof(FTP), 1); if (app == NULL) return NULL; - + app->packet_len = remote_entity.mtu; + app->buff = ssp_alloc(1, app->packet_len); + if (app->buff == NULL) { + ssp_free(app); + return NULL; + } + app->my_cfdp_id = my_cfdp_address; app->close = false; app->remote_entity = remote_entity; app->active_clients = linked_list(); - if (app->active_clients == NULL) + if (app->active_clients == NULL) { + ssp_free(app->buff); + ssp_free(app); return NULL; + } app->request_list = linked_list(); - if (app->request_list == NULL) + if (app->request_list == NULL){ + ssp_free(app->buff); + ssp_free(app); + app->active_clients->freeOnlyList(app->active_clients); return NULL; + } app->current_request = NULL; - ssp_server(app); + create_ssp_server_drivers(app); return app; } -void ssp_server(FTP *app) { - - if (app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); - - } else if(app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); - - } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); - - } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); - } -} - Client *ssp_client(uint32_t cfdp_id, FTP *app) { Remote_entity remote_entity; @@ -87,35 +120,27 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { Client *client = ssp_alloc(sizeof(Client), 1); if (client == NULL) return NULL; - - client->current_request = NULL; + client->request_list = linked_list(); - if (client->request_list == NULL) { ssp_free(client); return NULL; } client->packet_len = remote_entity.mtu; - client->remote_entity = remote_entity; + client->buff = ssp_alloc(1, remote_entity.mtu); + if (client->buff == NULL){ + ssp_free(client); + client->request_list->freeOnlyList(client->request_list); + return NULL; + } + client->remote_entity = remote_entity; get_header_from_mib(&client->pdu_header, remote_entity, app->my_cfdp_id); - + + client->current_request = NULL; client->app = app; - - if (remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); - - } else if(remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); - - } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); - - } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); - } - + create_ssp_client_drivers(client); return client; } From 927af38e9601ea5a17eae843630b9ce1f9ccbdee Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 May 2020 19:47:18 -0600 Subject: [PATCH 205/400] change function to drivers --- Program/include/file_delivery_app.h | 2 +- Program/src/file_delivery_app.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index e13c0f1..edc160a 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -8,7 +8,7 @@ FTP *init_ftp(uint32_t my_cfdp_address); Client *ssp_client(uint32_t cfdp_id, FTP *app); -void ssp_server(FTP *app); +void create_ssp_server(FTP *app); #endif \ No newline at end of file diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 7900e53..808dbe6 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -15,10 +15,10 @@ static void create_ssp_server_drivers(FTP *app) { - if (app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + if (app->remote_entity.type_of_network == posix_connection_less) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); - } else if(app->remote_entity.type_of_network == posix && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { + } else if(app->remote_entity.type_of_network == posix_connection) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { @@ -32,10 +32,10 @@ static void create_ssp_server_drivers(FTP *app) { static void create_ssp_client_drivers(Client *client) { Remote_entity remote_entity = client->remote_entity; - if (remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + if (remote_entity.type_of_network == posix_connection_less) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); - } else if(remote_entity.type_of_network == posix && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { + } else if(remote_entity.type_of_network == posix_connection) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { From 2e5ce7110848ad72b9cc07b5130ff28da7741895 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 May 2020 19:48:09 -0600 Subject: [PATCH 206/400] Change init request to re-use buffer --- Program/include/requests.h | 2 +- Program/src/protocol_handler.c | 15 ++++----- Program/src/requests.c | 58 ++++------------------------------ 3 files changed, 14 insertions(+), 61 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 2e3e99c..67fc7b2 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -7,7 +7,7 @@ #include "types.h" void ssp_cleanup_req(void *request); -Request *init_request(uint32_t buff_len); +Request *init_request(char *buff, uint32_t buff_len); void start_request(Request *req); Request *put_request( diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1ed75e2..01875fb 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -92,12 +92,12 @@ static int find_request(void *element, void *args) { return NULL; } - Request *found_req = init_request(app->packet_len); + Request *found_req = init_request(app->buff, app->packet_len); if (found_req == NULL) { ssp_error("could not get allocate for new request \n"); return NULL; } - + ssp_printf("incoming new request\n"); //Make new request and add it @@ -111,9 +111,9 @@ static int find_request(void *element, void *args) { found_req->res.addr = ssp_alloc(1, res.size_of_addr); - if (found_req == NULL) { + if (found_req->res.addr == NULL) { ssp_cleanup_req(found_req); - NULL; + return NULL; } memcpy(found_req->res.addr, res.addr, res.size_of_addr); @@ -122,6 +122,8 @@ static int find_request(void *element, void *args) { found_req->res.sfd = res.sfd; found_req->res.transmission_mode = app->remote_entity.default_transmission_mode; found_req->res.type_of_network = app->remote_entity.type_of_network; + found_req->res.msg = found_req->buff; + found_req->paused = false; return found_req; } @@ -148,18 +150,15 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; - /* if (app->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); return -1; } - */ //if packet is from the same request, don't' change current request Request *current_req = (*req); uint16_t len = get_data_length(packet); - if (len > app->packet_len){ ssp_printf("packet received %d that was too big for our buffer %d\n", len, app->packet_len); return -1; @@ -177,7 +176,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); - //server side, receiving requests (this should be its own function) + //if server, create new request if (found_req == NULL && is_server) { diff --git a/Program/src/requests.c b/Program/src/requests.c index 777db13..8ab57a1 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -215,7 +215,6 @@ void ssp_cleanup_req(void *request) { else req->messages_to_user->freeOnlyList(req->messages_to_user); - ssp_free(req->buff); ssp_free(req->res.addr); ssp_free(req); @@ -223,16 +222,15 @@ void ssp_cleanup_req(void *request) { -Request *init_request(uint32_t buff_len) { +Request *init_request(char *buff, uint32_t buff_len) { Request *req = ssp_alloc(1, sizeof(Request)); + if (req == NULL) + return NULL; req->file = NULL; req->buff_len = buff_len; - req->buff = ssp_alloc(buff_len, sizeof(char)); - if (req->buff == NULL) - return NULL; - + req->buff = buff; req->procedure = none; req->paused = true; reset_timeout(&req->timeout); @@ -247,50 +245,6 @@ Request *init_request(uint32_t buff_len) { return req; } - -/* -Request *init_request_2(uint32_t buff_len, uint32_t transaction_id, Pdu_header *pdu_header, Remote_entity *remote_entity) { - - Request *req = ssp_alloc(1, sizeof(Request)); - checkAlloc(req, 1); - - - req->pdu_header = pdu_header; - req->remote_entity = remote_entity; - req->file = NULL; - req->buff_len = buff_len; - req->dest_cfdp_id = remote_entity->cfdp_id; - req->transaction_sequence_number = transaction_id; - req->procedure = none; - req->paused = true; - - req->buff = ssp_alloc(buff_len, sizeof(char)); - checkAlloc(req->buff, 1); - - reset_timeout(&req->timeout); - - req->res.msg = req->buff; - - req->messages_to_user = linked_list(); - checkAlloc(req->messages_to_user, 1); - req->res.transmission_mode = remote_entity->default_transmission_mode; - req->res.type_of_network = remote_entity->type_of_network; - req->res.packet_len = buff_len; - - //req->res.addr = remote_entity.UT_address; - - //using the hosts network transfer, should switch to client configuration - - //req->res.sfd = res.sfd; - - - //req->paused = false; - //req->procedure = sending_put_metadata; - - return req; -} -*/ - //starts a new client, adding it to app->active_clients, as well as //starting a new request and adding it to the client, returns a pointer //to the request @@ -307,8 +261,8 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { ssp_printf("adding request to existing client thread\n"); } - Request *req = init_request(client->packet_len); - + Request *req = init_request(client->buff, client->packet_len); + //build a request req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity.cfdp_id; From db0c15ca19578384bcb6ff516536fb7742551f81 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 May 2020 19:48:43 -0600 Subject: [PATCH 207/400] better error handling in task --- Program/src/tasks.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 830b4b4..0c66d4b 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -42,17 +42,22 @@ static void timeout(Request *req) { } } -static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { + +static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { + FTP *app = (FTP *) other; + if (packet_len > app->packet_len) { + ssp_printf("packet received is too big for app\n"); + return -1; + } + Response res; res.addr = addr; res.sfd = sfd; - res.packet_len = app->packet_len; res.size_of_addr = size_of_addr; Request **request_container = &app->current_request; - int packet_index = process_pdu_header(packet, true, res, request_container, app->request_list, app); if (packet_index < 0) { ssp_printf("error parsing header\n"); @@ -61,29 +66,32 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, Request *current_request = (*request_container); app->current_request = current_request; - parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); reset_timeout(¤t_request->timeout); - memset(packet, 0, res.packet_len); + memset(packet, 0, packet_len); return 0; } + static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { Client *client = (Client *) other; + if (packet_len > client->app->packet_len) { + ssp_printf("packet received is too big for app\n"); + return -1; + } Response res; res.addr = addr; res.sfd = sfd; - res.packet_len = client->packet_len; res.type_of_network = client->remote_entity.type_of_network; res.size_of_addr = size_of_addr; res.transmission_mode = client->remote_entity.default_transmission_mode; - + Request **request_container = &client->current_request; int packet_index = process_pdu_header(packet, false, res, request_container, client->request_list, client->app); @@ -99,7 +107,7 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u reset_timeout(¤t_request->timeout); - memset(packet, 0, res.packet_len); + memset(packet, 0, packet_len); return 0; @@ -133,7 +141,7 @@ static void user_request_check(Node *node, void *request, void *args) { remove_request_check(node, request, params->client->request_list); } - +//TODO can getrid of res here I think, well at least the addr static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, void *other) { Response res; @@ -143,7 +151,7 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi client->close = true; return 0; } - + res.sfd = sfd; res.packet_len = client->packet_len; res.addr = addr; @@ -465,6 +473,7 @@ void *ssp_csp_connection_client_task(void *params) { void ssp_cleanup_client(Client *client) { client->request_list->free(client->request_list, ssp_cleanup_req); + ssp_free(client->buff); ssp_free(client); } void ssp_client_join(Client *client) { @@ -481,8 +490,8 @@ static void exit_client(Node *node, void *element, void *args) { void ssp_cleanup_ftp(FTP *app) { app->request_list->free(app->request_list, ssp_cleanup_req); app->active_clients->iterate(app->active_clients, exit_client, NULL); - app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); app->active_clients->freeOnlyList(app->active_clients); + ssp_free(app->buff); ssp_free(app); } From 48453a0127ad6b17ea9d98cb2debdc733793f4d2 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 May 2020 19:49:15 -0600 Subject: [PATCH 208/400] change file saving/getting location --- Program/src/filesystem_funcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 170adfb..6297fb5 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -544,7 +544,7 @@ static int write_file_present_bool(int fd, File *file) { int save_req_to_file(Request *req) { char file_name[255]; - snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); + snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { @@ -690,7 +690,7 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Reque char file_name[255]; - snprintf(file_name, 255, "%s%u%s%llu%s", "pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); + snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { From 63f7ce63ef8434f7a898283fb0436ef25093dadb Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 15 May 2020 19:49:48 -0600 Subject: [PATCH 209/400] change network types --- Program/include/types.h | 18 ++++++++++++++---- Program/src/port.c | 10 +++++----- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index 6810c72..3145bcb 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -483,9 +483,9 @@ typedef struct local_entity { typedef enum Network_type { - csp, - //free_rtos, - posix, + posix_connection_less, + posix_connection, + csp } Network_type; @@ -625,7 +625,13 @@ typedef struct request { //add "client" in here to represent local entity typedef struct ftp { + + //the maximum size of the packet uint32_t packet_len; + + //buffer for making packets, is length of packet_len + char* buff; + void *server_handle; uint32_t my_cfdp_id; @@ -655,6 +661,10 @@ typedef struct client { void *client_handle; //the maximum size of the packet uint32_t packet_len; + + //buffer for making packets, is length of packet_len + char* buff; + uint32_t cfdp_id; Request *current_request; @@ -665,7 +675,7 @@ typedef struct client { //packet header, useful for copying into outgoing packets Pdu_header pdu_header; - + FTP *app; //bool for exiting the client thread diff --git a/Program/src/port.c b/Program/src/port.c index 92e27bf..84a7ed9 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -119,22 +119,22 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { - if (res.type_of_network == posix && res.transmission_mode == UN_ACKNOWLEDGED_MODE) { + if (res.type_of_network == posix_connection_less) { struct sockaddr* addr = (struct sockaddr*) res.addr; #ifdef TEST printf("sending outgoing packet (testing)\n"); #endif #ifndef TEST - - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(*addr)); + + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); if (err < 0) { - ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(*addr)); + ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); ssp_error("ERROR in sendto"); } #endif } - else if (res.type_of_network == posix && res.transmission_mode == ACKNOWLEDGED_MODE) { + else if (res.type_of_network == posix_connection) { int err = ssp_write(res.sfd, res.msg, res.packet_len); if (err < 0) { From 1811de437e83bf833151e41feb89ba7e98d40fd0 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 16 May 2020 14:41:19 -0600 Subject: [PATCH 210/400] fix tcp server --- Program/src/port.c | 22 ++++----------------- Program/src/protocol_handler.c | 18 ++++++++++++----- Program/src/server.c | 35 +++++++++++++++++++++------------- 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 84a7ed9..5d86645 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -119,28 +119,14 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { - if (res.type_of_network == posix_connection_less) { + if (res.type_of_network == posix_connection_less || res.type_of_network == posix_connection) { struct sockaddr* addr = (struct sockaddr*) res.addr; - - #ifdef TEST - printf("sending outgoing packet (testing)\n"); - #endif - #ifndef TEST - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); - if (err < 0) { - ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); - ssp_error("ERROR in sendto"); - } - #endif - } - else if (res.type_of_network == posix_connection) { - - int err = ssp_write(res.sfd, res.msg, res.packet_len); + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); if (err < 0) { - ssp_error("ERROR in write"); + ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); + ssp_error("ERROR in sendto"); } - } else if (res.type_of_network == csp /*&& res.transmission_mode == UN_ACKNOWLEDGED_MODE*/) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 01875fb..e882bab 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -28,6 +28,8 @@ static void build_temperary_file(Request *req, uint32_t size) { static void send_ack(Request *req, Response res, unsigned int type){ + if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) + return; uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); build_ack(req->buff, start, type); @@ -35,7 +37,9 @@ static void send_ack(Request *req, Response res, unsigned int type){ } static void send_nak(Request *req, Response res, unsigned int type) { - + if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) + return; + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); build_nak_directive(req->buff, start, type); ssp_sendto(res); @@ -659,12 +663,14 @@ void on_server_time_out(Response res, Request *req) { } //fills the current_request struct for the server, incomming requests -void parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, FTP *app) { +int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, FTP *app) { if (packet_index == 0) - return; + return -1; Pdu_header *header = (Pdu_header *) packet; + uint16_t data_len = get_data_length(packet); + uint32_t packet_len = packet_index + data_len; //process file data if (header->PDU_type == 1) { @@ -674,9 +680,9 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ build_temperary_file(req, TEMP_FILESIZE); } } - uint16_t data_len = get_data_length(packet); write_packet_data_to_file(&packet[packet_index], data_len, req->file); - return; + ssp_printf("received data packet transaction: %d\n", req->transaction_sequence_number); + return packet_len; } @@ -716,5 +722,7 @@ void parse_packet_server(char *packet, uint32_t packet_index, Response res, Requ default: break; } + + return packet_len; } diff --git a/Program/src/server.c b/Program/src/server.c index f9c3d3b..5acbe62 100755 --- a/Program/src/server.c +++ b/Program/src/server.c @@ -184,7 +184,7 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c char *buff = ssp_alloc(sizeof(char), *buff_size); if (buff_size == NULL) exit_now = true; - + for (;;) { @@ -230,21 +230,30 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c break; } - int count = ssp_recvfrom(i, buff, *buff_size, 0, NULL, NULL); - - if (count < 0) { - ssp_error("recv failed server"); - ssp_close(i); - ssp_fd_clr(i, socket_set); - } - - else { - if (onRecv(i, buff, count, buff_size, addr, size_of_addr, other) == -1) { - ssp_printf("recv failed, closing socket\n"); + int count = 0; + while (count < *buff_size) { + count += ssp_recvfrom(i, &buff[count], *buff_size - count, 0, NULL, NULL); + if (count < 0) { + ssp_error("recv failed server"); + break; + } + else if (count == 0) { + ssp_error("connection finished"); ssp_fd_clr(i, socket_set); ssp_close(i); - } + break; + } + } + + if (count <= 0) + continue; + + int bytes_parsed = onRecv(i, buff, count, buff_size, addr, size_of_addr, other); + if (bytes_parsed == -1) { + ssp_printf("recv failed somewhere in parsing\n"); } + + } } } From 719bd09b937b8f84ea78d08cf28b38599b84a4ba Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 16 May 2020 14:42:38 -0600 Subject: [PATCH 211/400] add count(parse size) to on_recv_server_callback --- Program/src/tasks.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 0c66d4b..95e4dd7 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -67,12 +67,13 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, u Request *current_request = (*request_container); app->current_request = current_request; - parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); + int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); reset_timeout(¤t_request->timeout); - memset(packet, 0, packet_len); - return 0; + memset(packet, 0, count); + + return count; } @@ -91,7 +92,8 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u res.type_of_network = client->remote_entity.type_of_network; res.size_of_addr = size_of_addr; res.transmission_mode = client->remote_entity.default_transmission_mode; - + res.msg = client->buff; + Request **request_container = &client->current_request; int packet_index = process_pdu_header(packet, false, res, request_container, client->request_list, client->app); @@ -101,7 +103,6 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u } Request *current_request = (*request_container); - res.msg = current_request->buff; parse_packet_client(packet, packet_index, res, current_request, client); @@ -133,7 +134,6 @@ static void user_request_check(Node *node, void *request, void *args) { Request *req = (Request *) request; struct user_request_check_params* params = (struct user_request_check_params *) args; - params->res.msg = req->buff; memset(params->res.msg, 0, params->client->packet_len); user_request_handler(params->res, req, params->client); @@ -158,6 +158,7 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi res.size_of_addr = size_of_addr; res.type_of_network = client->remote_entity.type_of_network; res.transmission_mode = client->remote_entity.default_transmission_mode; + res.msg = client->buff; struct user_request_check_params params = { res, From c574ce882380cee2dd3a600a1413ef912c52a7c0 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 20 May 2020 17:41:00 -0600 Subject: [PATCH 212/400] seperate csp and posix servers --- Program/include/csp_server_provider.h | 43 +++ Program/include/port.h | 10 - .../{server.h => posix_server_provider.h} | 51 +-- Program/include/protocol_handler.h | 2 +- Program/src/csp_server_provider.c | 248 ++++++++++++++ Program/src/main.c | 15 +- Program/src/makefile | 8 +- Program/src/port.c | 109 +------ .../src/{server.c => posix_server_provider.c} | 305 ++++-------------- Program/src/protocol_handler.c | 4 +- Program/src/tasks.c | 3 +- 11 files changed, 384 insertions(+), 414 deletions(-) create mode 100755 Program/include/csp_server_provider.h rename Program/include/{server.h => posix_server_provider.h} (63%) mode change 100755 => 100644 create mode 100755 Program/src/csp_server_provider.c rename Program/src/{server.c => posix_server_provider.c} (67%) diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h new file mode 100755 index 0000000..e91238e --- /dev/null +++ b/Program/include/csp_server_provider.h @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------------ +CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks +Assignment #1 +Evan Giese 1689223 + +This file is the header file for server.c +------------------------------------------------------------------------------*/ +#ifndef CSP_SERVER_H +#define CSP_SERVER_H + +#include + +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params); + +void csp_connectionless_server(uint8_t my_port, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other); + +void csp_connection_server(uint8_t my_port, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other); + +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params); + +#endif diff --git a/Program/include/port.h b/Program/include/port.h index c8b298b..fee1ce7 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -36,8 +36,6 @@ void ssp_printf(char *stuff, ...); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); -int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len); - void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); int ssp_time_count(void); @@ -51,14 +49,6 @@ void ssp_free(void *pointer); void ssp_thread_join(void *thread_handle); //network stuff -void ssp_fd_zero(void *socket_set); -void ssp_fd_set(int sfd, void *socket_set); -int ssp_fd_is_set(int sfd, void *socket_set); -void *ssp_init_socket_set(size_t *size); -int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec); -void *ssp_init_sockaddr_struct(size_t *size_of_addr); -void ssp_fd_clr(int sfd, void *socket_set); - int ssp_rename(const char *old, const char *new); void reset_request(Request *req); diff --git a/Program/include/server.h b/Program/include/posix_server_provider.h old mode 100755 new mode 100644 similarity index 63% rename from Program/include/server.h rename to Program/include/posix_server_provider.h index 4d50d84..c1c8c44 --- a/Program/include/server.h +++ b/Program/include/posix_server_provider.h @@ -1,17 +1,8 @@ -/*------------------------------------------------------------------------------ -CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks -Assignment #1 -Evan Giese 1689223 +#ifndef POSIX_SERVER_H +#define POSIX_SERVER_H -This file is the header file for server.c -------------------------------------------------------------------------------*/ -#ifndef SERVER_H -#define SERVER_H -//figure out what to inlcude for types ask nick #include - - int *prepareSignalHandler(void); /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. @@ -73,40 +64,4 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *para int (*checkExit)(void *params), void (*onExit)(void *params)); -//#ifdef CSP_NETWORK -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, - int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), - void (*onExit)(void *params), - void *params); - -void csp_connectionless_server(uint8_t my_port, - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), - int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), - int (*checkExit)(void *other), - void (*onExit)(void *other), - void *other); - -void csp_connection_server(uint8_t my_port, - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), - int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), - int (*checkExit)(void *other), - void (*onExit)(void *other), - void *other); - -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, - int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), - void (*onExit)(void *params), - void *params); - - -//#endif - - - -#endif //SERVER_H +#endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index ca48394..e993faf 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -7,7 +7,7 @@ #define RESEND_FINISHED_TIMES 3 #define TIMEOUT_BEFORE_CANCEL_REQUEST 10 -void parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); +int parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, uint32_t packet_index, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c new file mode 100755 index 0000000..3a03811 --- /dev/null +++ b/Program/src/csp_server_provider.c @@ -0,0 +1,248 @@ +/*------------------------------------------------------------------------------ +CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks +Assignment #2 +Evan Giese 1689223 + +This is my file for server.c. It develops a udp server for select. +------------------------------------------------------------------------------*/ + +#include "csp.h" +#include "csp_server_provider.h" +#include "port.h" +static int exit_now; + +/*------------------------------------------------------------------------------ + + CSP STUFF! + +------------------------------------------------------------------------------*/ + +//#ifdef CSP_NETWORK + +//https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *params), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , + int (*checkExit)(void *params), + void (*onExit)(void *params), + void *params) +{ + + int err = 0; + uint8_t src_id = csp_get_address(); + + //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); + csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); + + + err = csp_bind(soc, CSP_ANY); + if (err < 0) { + ssp_error("ERROR: couldn't bind csp\n"); + return; + } + + csp_packet_t *packet_sending; + csp_packet_t *packet_recieved; + + + if (csp_buffer_remaining() != 0) { + + packet_sending = csp_buffer_get(1); + packet_sending->id.dst = dest_id; + packet_sending->id.dport = dest_port; + packet_sending->id.src = src_id; + packet_sending->id.sport = src_port; + + } + else { + ssp_error("couldn't get new packet for sending!\n"); + exit_now = 1; + } + + for (;;) { + + if (exit_now || checkExit(params)){ + ssp_printf("exiting server thread\n"); + break; + } + + onSend(-1, packet_sending, sizeof(*packet_sending), params); + + packet_recieved = csp_recvfrom(soc, 10); + + //timout + if (packet_recieved == NULL) + continue; + + else { + ssp_printf("CLIENT DATA Length: %d\n", packet_recieved->length); + if (onRecv(-1, (char *)packet_recieved->data, packet_recieved->length, NULL, packet_recieved, sizeof(packet_recieved), params) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet_recieved); + } + + } + csp_buffer_free(packet_sending); +} + + + +void csp_connectionless_server(uint8_t my_port, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other) +{ + + //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); + csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); + + int err = csp_bind(soc, my_port); + + if (err < 0) { + ssp_error("ERROR: couldn't bind csp\n"); + return; + } + + for (;;) { + + if (exit_now || checkExit(other)){ + ssp_printf("exiting server thread\n"); + break; + } + + csp_packet_t *packet = csp_recvfrom(soc, 10); + + //timout + if (packet == NULL) { + onTimeOut(other); + } + else { + + if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), other) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet); + } + + } +} + +//This doesn't work because it can't have multiple connections, maybe revisit? +void csp_connection_server(uint8_t my_port, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other) +{ + + /* Create socket without any socket options */ + csp_socket_t *sock = csp_socket(CSP_SO_NONE); + + /* Bind all ports to socket */ + csp_bind(sock, my_port); + + /* Create 10 connections backlog queue */ + csp_listen(sock, 10); + + /* Pointer to current connection and packet */ + csp_conn_t *conn; + csp_packet_t *packet; + + /* Process incoming connections */ + for (;;) { + + if (exit_now || checkExit(other)){ + ssp_printf("exiting serv thread\n"); + break; + } + + /* Wait for connection, 1000 ms timeout */ + if ((conn = csp_accept(sock, 1000)) == NULL) { + onTimeOut(other); + continue; + } + + for (;;) { + + if (exit_now || checkExit(other)) + break; + + onTimeOut(other); + + while ((packet = csp_read(conn, 100)) != NULL) { + if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), other) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet); + + } + } + + csp_close(conn); + onExit(other); + + } + + /* Close current connection, and handle next */ + csp_close(conn); +} + + +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params) +{ + + csp_packet_t * packet; + csp_conn_t * conn; + + + while (1) { + + + if (exit_now || checkExit(params)){ + ssp_printf("exiting client thread\n"); + break; + } + + /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ + conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_O_NONE); + if (conn == NULL) { + /* Connect failed */ + ssp_printf("Connection failed\n"); + return; + } + + for (;;) { + + if (exit_now || checkExit(params)){ + ssp_printf("exiting client thread\n"); + break; + } + + onSend(-1, conn, sizeof(conn), params); + + while ((packet = csp_read(conn, 100)) != NULL) { + if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), params) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet); + + } + } + + /* Close connection */ + csp_close(conn); + onExit(params); + } +} + diff --git a/Program/src/main.c b/Program/src/main.c index d721440..f345b0e 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -19,7 +19,7 @@ //for main app #include "file_delivery_app.h" //for signal handler, because its nice -#include "server.h" +#include "posix_server_provider.h" //for ssp_thread_join, can use p_thread join on linux #include "port.h" #include "tasks.h" @@ -50,12 +50,11 @@ int main(int argc, char** argv) { if (conf->client_cfdp_id != 0){ - /* - start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy.jpg", ACKNOWLEDGED_MODE, app)); - start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy2.jpg", ACKNOWLEDGED_MODE, app)); - start_request(put_request(conf->client_cfdp_id, "pic.jpeg", "noProxy3.jpg", ACKNOWLEDGED_MODE, app)); - */ - Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy4.jpg", ACKNOWLEDGED_MODE, app); + + start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); + //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", UN_ACKNOWLEDGED_MODE, app)); + //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy3.jpg", UN_ACKNOWLEDGED_MODE, app)); + Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/tcp.jpg", ACKNOWLEDGED_MODE, app); start_request(req); /* @@ -76,8 +75,6 @@ int main(int argc, char** argv) { add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy3.jpg", req); start_request(req); - -/* Request *req; for (int i=0; i < 4; i++) { sleep(10); diff --git a/Program/src/makefile b/Program/src/makefile index 8dc6628..d0be716 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -26,12 +26,13 @@ CC = gcc #---------------------------File Names--------------------------- CFILES += port.c CFILES += utils.c -CFILES += server.c #used for poxix port +CFILES += tasks.c +CFILES += posix_server_provider.c #used for poxix port +CFILES += csp_server_provider.c CFILES += protocol_handler.c CFILES += mib.c CFILES += filesystem_funcs.c CFILES += requests.c -CFILES += tasks.c CFILES += file_delivery_app.c CFILES += list.c CFILES += packet.c @@ -85,11 +86,12 @@ CFLAGS += $(INCLUDE) $(CWARNS) #---------------------------Build--------------------------- OBJS_FILES = $(patsubst %.c, %.o, $(CFILES)) -all: $(MAIN) +all: $(MAIN) .PHONY: clean lib $(MAIN): $(OBJS_FILES) $(STATIC_FILES) +# mv *.o obj lib: $(OBJS_FILES) ar -rsc file_delivery_app.a $(OBJS_FILES) diff --git a/Program/src/port.c b/Program/src/port.c index 5d86645..2619e04 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -1,6 +1,5 @@ #include "packet.h" -#include "server.h" #include "port.h" #include #include @@ -28,22 +27,12 @@ #include #endif - - - #ifdef POSIX_FILESYSTEM #include #include - #endif -#ifdef POSIX_NETWORK - #include - #include - -#endif - #ifdef FREE_RTOS_PORT #include "FreeRTOS.h" #include "task.h" @@ -58,7 +47,6 @@ #ifdef CSP_NETWORK #include "csp.h" - #endif @@ -119,16 +107,8 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { - if (res.type_of_network == posix_connection_less || res.type_of_network == posix_connection) { - struct sockaddr* addr = (struct sockaddr*) res.addr; - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); - if (err < 0) { - ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); - ssp_error("ERROR in sendto"); - } - } - else if (res.type_of_network == csp /*&& res.transmission_mode == UN_ACKNOWLEDGED_MODE*/) { + if (res.type_of_network == csp /*&& res.transmission_mode == UN_ACKNOWLEDGED_MODE*/) { csp_packet_t *packet = (csp_packet_t *) res.addr; csp_packet_t *packet_sending; @@ -148,86 +128,17 @@ void ssp_sendto(Response res) { else ssp_error("couldn't get new packet for sending!\n"); - } - -} - -int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { - int count = 0; - #ifdef POSIX_NETWORK - count = recvfrom(sfd, buff, packet_len, flags, (struct sockaddr*)server_addr, (socklen_t*)server_addr_len); - #endif - - return count; -} - -void *ssp_init_socket_set(size_t *size) { - - #ifdef POSIX_NETWORK - fd_set *socket_set = ssp_alloc(1, sizeof(fd_set)); - *size = sizeof(fd_set); - #endif - return (void *)socket_set; -} - - -void ssp_fd_zero(void *socket_set){ - - #ifdef POSIX_NETWORK - FD_ZERO((fd_set*) socket_set); - #endif -} - -void ssp_fd_set(int sfd, void *socket_set) { - #ifdef POSIX_NETWORK - FD_SET(sfd, (fd_set*) socket_set); - #endif -} - -int ssp_fd_is_set(int sfd, void *socket_set){ - int is_set = 0; - #ifdef POSIX_NETWORK - is_set = FD_ISSET(sfd, (fd_set*) socket_set); - - #endif - return is_set; -} - -void ssp_fd_clr(int sfd, void *socket_set) { - - #ifdef POSIX_NETWORK - FD_CLR(sfd, (fd_set *) socket_set); - - #endif -} - -int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec) { - - #ifdef POSIX_NETWORK - - struct timeval timeout = { - .tv_sec = 0, - .tv_usec = timeout_in_usec - }; - - int nrdy = select(sfd + 1, (fd_set *) read_socket_set, (fd_set *) write_socket_set, (fd_set *) restrict_socket_set, &timeout); - #endif - - return nrdy; -} - -void *ssp_init_sockaddr_struct(size_t *size_of_addr) { - - #ifdef POSIX_NETWORK - - *size_of_addr = sizeof(struct sockaddr_storage); - void *addr = ssp_alloc(1, sizeof(struct sockaddr_storage)); - if (checkAlloc(addr) < 0) - return NULL; + } else { + struct sockaddr* addr = (struct sockaddr*) res.addr; - #endif - return addr; + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); + if (err < 0) { + ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); + ssp_error("ERROR in sendto"); + } + } + } diff --git a/Program/src/server.c b/Program/src/posix_server_provider.c similarity index 67% rename from Program/src/server.c rename to Program/src/posix_server_provider.c index 5acbe62..e267aaf 100755 --- a/Program/src/server.c +++ b/Program/src/posix_server_provider.c @@ -19,17 +19,76 @@ This is my file for server.c. It develops a udp server for select. #include #include #include "utils.h" -#include "server.h" +#include "posix_server_provider.h" #include "port.h" +#include + -#ifdef CSP_NETWORK - #include "csp.h" -#endif static int exit_now; + +static int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { + int count = 0; + count = recvfrom(sfd, buff, packet_len, flags, (struct sockaddr*)server_addr, (socklen_t*)server_addr_len); + return count; +} + +static void *ssp_init_socket_set(size_t *size) { + fd_set *socket_set = ssp_alloc(1, sizeof(fd_set)); + *size = sizeof(fd_set); + return (void *)socket_set; +} + + +static void ssp_fd_zero(void *socket_set){ + + FD_ZERO((fd_set*) socket_set); +} + +static void ssp_fd_set(int sfd, void *socket_set) { + + FD_SET(sfd, (fd_set*) socket_set); + +} + +static int ssp_fd_is_set(int sfd, void *socket_set){ + int is_set = 0; + is_set = FD_ISSET(sfd, (fd_set*) socket_set); + return is_set; +} + +static void ssp_fd_clr(int sfd, void *socket_set) { + + FD_CLR(sfd, (fd_set *) socket_set); + +} + +static int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec) { + + struct timeval timeout = { + .tv_sec = 0, + .tv_usec = timeout_in_usec + }; + + int nrdy = select(sfd + 1, (fd_set *) read_socket_set, (fd_set *) write_socket_set, (fd_set *) restrict_socket_set, &timeout); + + return nrdy; +} + +static void *ssp_init_sockaddr_struct(size_t *size_of_addr) { + + *size_of_addr = sizeof(struct sockaddr_storage); + void *addr = ssp_alloc(1, sizeof(struct sockaddr_storage)); + if (checkAlloc(addr) < 0) + return NULL; + + return addr; +} + + //if conn_typ == 1, tcp/ bind_to_host == 1 for binding local, 2 for connect static int prepareHost(char *host_name, void *addr, size_t *size_of_addr, char *port, int conn_type, int bind_to_host) { @@ -486,240 +545,4 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, ssp_free(buff); ssp_close(sfd); onExit(params); -} - -/*------------------------------------------------------------------------------ - - CSP STUFF! - -------------------------------------------------------------------------------*/ - -//#ifdef CSP_NETWORK - -//https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, - int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *params), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , - int (*checkExit)(void *params), - void (*onExit)(void *params), - void *params) -{ - - int err = 0; - uint8_t src_id = csp_get_address(); - - //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); - csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); - - - err = csp_bind(soc, CSP_ANY); - if (err < 0) { - ssp_error("ERROR: couldn't bind csp\n"); - return; - } - - csp_packet_t *packet_sending; - csp_packet_t *packet_recieved; - - - if (csp_buffer_remaining() != 0) { - - packet_sending = csp_buffer_get(1); - packet_sending->id.dst = dest_id; - packet_sending->id.dport = dest_port; - packet_sending->id.src = src_id; - packet_sending->id.sport = src_port; - - } - else { - ssp_error("couldn't get new packet for sending!\n"); - exit_now = 1; - } - - for (;;) { - - if (exit_now || checkExit(params)){ - ssp_printf("exiting server thread\n"); - break; - } - - onSend(-1, packet_sending, sizeof(*packet_sending), params); - - packet_recieved = csp_recvfrom(soc, 10); - - //timout - if (packet_recieved == NULL) - continue; - - else { - ssp_printf("CLIENT DATA Length: %d\n", packet_recieved->length); - if (onRecv(-1, (char *)packet_recieved->data, packet_recieved->length, NULL, packet_recieved, sizeof(packet_recieved), params) == -1) - ssp_printf("recv failed\n"); - - csp_buffer_free(packet_recieved); - } - - } - csp_buffer_free(packet_sending); -} - - - -void csp_connectionless_server(uint8_t my_port, - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), - int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), - int (*checkExit)(void *other), - void (*onExit)(void *other), - void *other) -{ - - //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); - csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); - - int err = csp_bind(soc, my_port); - - if (err < 0) { - ssp_error("ERROR: couldn't bind csp\n"); - return; - } - - for (;;) { - - if (exit_now || checkExit(other)){ - ssp_printf("exiting server thread\n"); - break; - } - - csp_packet_t *packet = csp_recvfrom(soc, 10); - - //timout - if (packet == NULL) { - onTimeOut(other); - } - else { - - if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), other) == -1) - ssp_printf("recv failed\n"); - - csp_buffer_free(packet); - } - - } -} - -//This doesn't work because it can't have multiple connections, maybe revisit? -void csp_connection_server(uint8_t my_port, - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), - int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), - int (*checkExit)(void *other), - void (*onExit)(void *other), - void *other) -{ - - /* Create socket without any socket options */ - csp_socket_t *sock = csp_socket(CSP_SO_NONE); - - /* Bind all ports to socket */ - csp_bind(sock, my_port); - - /* Create 10 connections backlog queue */ - csp_listen(sock, 10); - - /* Pointer to current connection and packet */ - csp_conn_t *conn; - csp_packet_t *packet; - - /* Process incoming connections */ - for (;;) { - - if (exit_now || checkExit(other)){ - ssp_printf("exiting serv thread\n"); - break; - } - - /* Wait for connection, 1000 ms timeout */ - if ((conn = csp_accept(sock, 1000)) == NULL) { - onTimeOut(other); - continue; - } - - for (;;) { - - if (exit_now || checkExit(other)) - break; - - onTimeOut(other); - - while ((packet = csp_read(conn, 100)) != NULL) { - if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), other) == -1) - ssp_printf("recv failed\n"); - - csp_buffer_free(packet); - - } - } - - csp_close(conn); - onExit(other); - - } - - /* Close current connection, and handle next */ - csp_close(conn); -} - - -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, - int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , - int (*checkExit)(void *checkExitParams), - void (*onExit)(void *params), - void *params) -{ - - csp_packet_t * packet; - csp_conn_t * conn; - - - while (1) { - - - if (exit_now || checkExit(params)){ - ssp_printf("exiting client thread\n"); - break; - } - - /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ - conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_O_NONE); - if (conn == NULL) { - /* Connect failed */ - ssp_printf("Connection failed\n"); - return; - } - - for (;;) { - - if (exit_now || checkExit(params)){ - ssp_printf("exiting client thread\n"); - break; - } - - onSend(-1, conn, sizeof(conn), params); - - while ((packet = csp_read(conn, 100)) != NULL) { - if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), params) == -1) - ssp_printf("recv failed\n"); - - csp_buffer_free(packet); - - } - } - - /* Close connection */ - csp_close(conn); - onExit(params); - } -} - +} \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e882bab..c41eab8 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -21,7 +21,7 @@ static void build_temperary_file(Request *req, uint32_t size) { - snprintf(req->source_file_name, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); + snprintf(req->source_file_name, 75, "%s%llu%s", "incomplete_requests/.temp_", req->transaction_sequence_number, ".jpeg"); ssp_printf("haven't received metadata yet, building temperary file %s\n", req->source_file_name); req->file = create_temp_file(req->source_file_name, size); } @@ -560,7 +560,7 @@ int process_file_request_metadata(Request *req) { req->file = create_file(req->destination_file_name, 1); else if (req->file->is_temp) { - snprintf(temp, 75, "%s%llu%s", ".temp_", req->transaction_sequence_number, ".jpeg"); + snprintf(temp, 75, "%s%llu%s", "incomplete_requests/.temp_", req->transaction_sequence_number, ".jpeg"); change_tempfile_to_actual(temp, req->destination_file_name, req->file_size, req->file); return 1; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 95e4dd7..f258d7c 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -3,7 +3,6 @@ #include "protocol_handler.h" #include "tasks.h" -#include "server.h" #include "port.h" #include #include "mib.h" @@ -13,6 +12,8 @@ #include "utils.h" #include +#include "posix_server_provider.h" +#include "csp_server_provider.h" //snprintf #include From 22f78c40d48e85f01edc346873b1a285c2b04d5d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 20 May 2020 18:22:53 -0600 Subject: [PATCH 213/400] removing unused headers --- Program/include/csp_server_provider.h | 3 +-- Program/include/file_delivery_app.h | 2 -- Program/include/filesystem_funcs.h | 2 -- Program/include/mib.h | 2 -- Program/include/packet.h | 1 - Program/include/port.h | 4 ---- Program/include/posix_server_provider.h | 3 +-- Program/include/requests.h | 2 -- Program/include/tasks.h | 1 - Program/include/types.h | 3 +-- Program/include/utils.h | 1 - Program/src/file_delivery_app.c | 11 +-------- Program/src/list.c | 7 ------ Program/src/makefile | 4 ++-- Program/src/mib.c | 6 ----- Program/src/packet.c | 3 ++- Program/src/pic.jpeg | Bin 150033 -> 0 bytes Program/src/port.c | 29 ++++++------------------ Program/src/posix_server_provider.c | 15 ++---------- Program/src/protocol_handler.c | 2 +- Program/src/utils.c | 1 + 21 files changed, 19 insertions(+), 83 deletions(-) delete mode 100644 Program/src/pic.jpeg diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index e91238e..0336284 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -7,8 +7,7 @@ This file is the header file for server.c ------------------------------------------------------------------------------*/ #ifndef CSP_SERVER_H #define CSP_SERVER_H - -#include +#include void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index edc160a..f5eb6e6 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -6,9 +6,7 @@ #include "types.h" FTP *init_ftp(uint32_t my_cfdp_address); - Client *ssp_client(uint32_t cfdp_id, FTP *app); void create_ssp_server(FTP *app); - #endif \ No newline at end of file diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index c569d98..a5a94df 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -1,8 +1,6 @@ #ifndef FILESYSTEM_FUNCS_H #define FILESYSTEM_FUNCS_H -#include -#include "list.h" #include "types.h" #define TEMP_FILESIZE 1000 diff --git a/Program/include/mib.h b/Program/include/mib.h index af1ddc2..69d58c2 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -6,8 +6,6 @@ #ifndef MIB_H #define MIB_H -#include -#include "packet.h" #include "types.h" int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); diff --git a/Program/include/packet.h b/Program/include/packet.h index 964f2a5..3a95d21 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -7,7 +7,6 @@ #define PACKET_STATIC_HEADER_LEN 4 //in bytes #include "types.h" -#include #include "list.h" uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); diff --git a/Program/include/port.h b/Program/include/port.h index fee1ce7..859efc7 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -16,8 +16,6 @@ #include "types.h" - - #ifdef CSP_NETWORK #include "csp.h" typedef struct csp_packet_wrapper { @@ -48,8 +46,6 @@ int ssp_close(int fd); void ssp_free(void *pointer); void ssp_thread_join(void *thread_handle); -//network stuff - int ssp_rename(const char *old, const char *new); void reset_request(Request *req); diff --git a/Program/include/posix_server_provider.h b/Program/include/posix_server_provider.h index c1c8c44..b4d20f2 100644 --- a/Program/include/posix_server_provider.h +++ b/Program/include/posix_server_provider.h @@ -1,8 +1,7 @@ #ifndef POSIX_SERVER_H #define POSIX_SERVER_H - -#include +#include int *prepareSignalHandler(void); /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. diff --git a/Program/include/requests.h b/Program/include/requests.h index 67fc7b2..6f6e7c7 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -2,8 +2,6 @@ #ifndef REQUESTS_H #define REQUESTS_H -#include "stdint.h" -#include "protocol_handler.h" #include "types.h" void ssp_cleanup_req(void *request); diff --git a/Program/include/tasks.h b/Program/include/tasks.h index d5d449e..19aee65 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -3,7 +3,6 @@ #define SSP_TASKS_H #include "types.h" -#include "list.h" void ssp_cleanup_client(Client *client); void ssp_cleanup_req(void *request); diff --git a/Program/include/types.h b/Program/include/types.h index 3145bcb..54c67b9 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -1,9 +1,8 @@ #ifndef SSP_TYPES_H #define SSP_TYPES_H -#include "stdint.h" +#include #include "list.h" - #include #include diff --git a/Program/include/utils.h b/Program/include/utils.h index 1b94270..77ebde9 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -9,7 +9,6 @@ This file is the header file for utils.c #define UTILS_H #include -#include /*------------------------------------------------------------------------------ Purpose: This struct if our configuration for this program, these elements diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 808dbe6..6da0a93 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -1,17 +1,8 @@ #include "mib.h" -#include "protocol_handler.h" #include "port.h" -#include -#include -#include #include "file_delivery_app.h" #include "tasks.h" -#include -#include -#include "utils.h" - - static void create_ssp_server_drivers(FTP *app) { @@ -59,7 +50,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { if (remote_entity.type_of_network == csp) { - printf("Initialising CSP\r\n"); + ssp_printf("Initialising CSP\r\n"); /* Init CSP with address MY_ADDRESS */ csp_init(remote_entity.UT_address); diff --git a/Program/src/list.c b/Program/src/list.c index 94b830e..2e37af4 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -1,10 +1,6 @@ #include "list.h" - -#include -#include -#include #include "port.h" /*------------------------------------------------------------------------------ @@ -23,9 +19,6 @@ Node *createNode(void *element, uint32_t id) return newNode; } - - - /*------------------------------------------------------------------------------ This function creates a new node to add into the linked list, returns the new node. diff --git a/Program/src/makefile b/Program/src/makefile index d0be716..db4d40a 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -25,6 +25,7 @@ CC = gcc #---------------------------File Names--------------------------- CFILES += port.c +CFILES += file_delivery_app.c CFILES += utils.c CFILES += tasks.c CFILES += posix_server_provider.c #used for poxix port @@ -33,7 +34,6 @@ CFILES += protocol_handler.c CFILES += mib.c CFILES += filesystem_funcs.c CFILES += requests.c -CFILES += file_delivery_app.c CFILES += list.c CFILES += packet.c #----------------------------test files------------------------- @@ -91,7 +91,7 @@ all: $(MAIN) .PHONY: clean lib $(MAIN): $(OBJS_FILES) $(STATIC_FILES) -# mv *.o obj + mv *.o obj lib: $(OBJS_FILES) ar -rsc file_delivery_app.a $(OBJS_FILES) diff --git a/Program/src/mib.c b/Program/src/mib.c index 0ce8fef..1f94ef6 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -1,15 +1,9 @@ #include "mib.h" -#include "utils.h" #include "port.h" -#include -#include "string.h" -#include "list.h" #include "types.h" #include "filesystem_funcs.h" #include "stdlib.h" - -//snprintf #include "stdio.h" diff --git a/Program/src/packet.c b/Program/src/packet.c index 3c8dc91..831016c 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -6,7 +6,8 @@ #include "port.h" #include "filesystem_funcs.h" #include "requests.h" - + #include + /*------------------------------------------------------------------------------ creating packets diff --git a/Program/src/pic.jpeg b/Program/src/pic.jpeg deleted file mode 100644 index 8c727e085507309e22d0059687c15e4d884930d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 150033 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

u;b_%m1w>npTOZ22dacFAZgy8!w)SVc47OD( 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 z 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 -#include #include "utils.h" #include "mib.h" #include "filesystem_funcs.h" -#include #include "types.h" #include "config.h" #ifdef POSIX_PORT - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include + #include + #include + #include + #include + #include + #include #endif #ifdef POSIX_FILESYSTEM - #include #include + #include #endif @@ -50,10 +39,6 @@ #endif - - - - /*------------------------------------------------------------------------------ File system port functions, these are used to interchange different File systems diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index e267aaf..bf6edbb 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -6,25 +6,15 @@ Evan Giese 1689223 This is my file for server.c. It develops a udp server for select. ------------------------------------------------------------------------------*/ -#include -#include -#include #include -#include #include #include #include #include -#include -#include -#include -#include "utils.h" #include "posix_server_provider.h" #include "port.h" #include - - static int exit_now; @@ -82,7 +72,7 @@ static void *ssp_init_sockaddr_struct(size_t *size_of_addr) { *size_of_addr = sizeof(struct sockaddr_storage); void *addr = ssp_alloc(1, sizeof(struct sockaddr_storage)); - if (checkAlloc(addr) < 0) + if (addr == NULL) return NULL; return addr; @@ -195,8 +185,7 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf if (*newBufferSize != *prev_buff_size) { *buffer = realloc(*buffer, *newBufferSize); - - if(checkAlloc(*buffer) < 0){ + if (buffer == NULL) { return 1; } return 0; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index c41eab8..e7f6c47 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -8,10 +8,10 @@ #include "requests.h" #include "types.h" #include "utils.h" +#include //snprintf #include - /*------------------------------------------------------------------------------ bundled requests diff --git a/Program/src/utils.c b/Program/src/utils.c index e1565e6..6193183 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -17,6 +17,7 @@ to use for general functionality. #include #include "port.h" +#include #define MAX_LEN 255 #define ID_LEN 10 From 2c000703ae9326b46de6c7716a3b176bdd8ba4c7 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 21 May 2020 19:41:35 -0600 Subject: [PATCH 214/400] remove more unessary includes --- Program/include/port.h | 14 +++- Program/include/utils.h | 33 -------- Program/src/filesystem_funcs.c | 21 ++--- Program/src/main.c | 72 +++++++++++++++++ Program/src/mib.c | 4 + Program/src/packet.c | 6 +- Program/src/port.c | 16 +--- Program/src/posix_server_provider.c | 7 -- Program/src/protocol_handler.c | 3 +- Program/src/requests.c | 9 +-- Program/src/tasks.c | 33 +++++++- Program/src/utils.c | 120 +--------------------------- 12 files changed, 140 insertions(+), 198 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 859efc7..a3c4ecd 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,8 +9,6 @@ #define POSIX_PORT #define POSIX_FILESYSTEM -#define POSIX_NETWORK - #define CSP_NETWORK //#define FREE_RTOS_PORT @@ -29,6 +27,7 @@ #endif + void ssp_error( char *msg); void ssp_printf(char *stuff, ...); void *ssp_alloc(uint32_t u_memb, size_t size); @@ -37,6 +36,17 @@ void ssp_sendto(Response res); void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); int ssp_time_count(void); + +#ifdef POSIX_FILESYSTEM + #include + + #define SSP_O_RDWR O_RDWR + #define SSP_O_CREAT O_CREAT + #define SSP_O_TRUNC O_TRUNC + #define SSP_SEEK_SET SEEK_SET + +#endif + int ssp_open(char *pathname, int flags); int ssp_read(int fd, char* buff, size_t size); int ssp_lseek(int fd, int offset, int whence); diff --git a/Program/include/utils.h b/Program/include/utils.h index 77ebde9..0bd4d07 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -10,44 +10,11 @@ This file is the header file for utils.c #include -/*------------------------------------------------------------------------------ - Purpose: This struct if our configuration for this program, these elements - are set with getopt -------------------------------------------------------------------------------*/ -typedef struct config -{ - unsigned int timer; - uint32_t client_cfdp_id; - uint32_t my_cfdp_id; - uint8_t verbose_level; -} Config; - - -/*------------------------------------------------------------------------------ - Purpose: This function checks to see if the memory is allocated - Perameters: void *mem: - Return: returns -1 on bad mem, and 1 on ok -------------------------------------------------------------------------------*/ -int checkAlloc(void *mem); - -/*------------------------------------------------------------------------------ - Purpose: This function is used to make a configuration struct from the - arguments - Perameters: int agrc: the number of arguments - char **argv: the arguments - Return: CONFIG * -------------------------------------------------------------------------------*/ -Config *configuration(int argc, char **argv); - //https://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c #define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) void ssp_print_hex(char *stuff, int size); -int is_negative(int number); -//check if timeout number of seconds has past since prevtime -int check_timeout(int *prevtime, uint32_t timeout); -void reset_timeout(int *prevtime); #endif //UTILS_H diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 6297fb5..532538e 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -1,14 +1,9 @@ #include #include "port.h" #include "filesystem_funcs.h" -#include -#include -#include -#include "utils.h" -#include -#include "list.h" #include "jsmn.h" #include "requests.h" +//snprintf #include uint32_t get_file_size(char *source_file_name) { @@ -39,13 +34,13 @@ File *create_file(char *source_file_name, int clear_file_contents) { int fd = 0; if (clear_file_contents){ - fd = ssp_open(source_file_name, O_RDWR | O_CREAT | O_TRUNC); + fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC); }else { - fd = ssp_open(source_file_name, O_RDWR | O_CREAT); + fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT); } if (fd == -1){ ssp_error("couldn't create file\n"); - fd = ssp_open(source_file_name, O_RDWR); + fd = ssp_open(source_file_name, SSP_O_RDWR); if (fd == -1) { ssp_error("count not open file\n"); return NULL; @@ -75,7 +70,7 @@ File *create_file(char *source_file_name, int clear_file_contents) { int does_file_exist(char *source_file_name) { - int fd = ssp_open(source_file_name, O_RDWR); + int fd = ssp_open(source_file_name, SSP_O_RDWR); if (fd == -1){ return 0; } @@ -94,7 +89,7 @@ int get_offset(File *file, void *buff, uint32_t buf_size, int offset) { return -1; } - if (ssp_lseek(file->fd, offset, SEEK_SET) == -1){ + if (ssp_lseek(file->fd, offset, SSP_SEEK_SET) == -1){ ssp_error("could'nt set offset\n"); } @@ -114,7 +109,7 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset) { return -1; } - ssp_lseek(file->fd, (int) offset, SEEK_SET); + ssp_lseek(file->fd, (int) offset, SSP_SEEK_SET); int bytes = ssp_write(file->fd, buff, (size_t) size); if (bytes == -1){ @@ -728,7 +723,7 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Reque req->messages_to_user = messages; - error = close(fd); + error = ssp_close(fd); if (error < 0) { ssp_error("couldn't close file descriptor \n"); } diff --git a/Program/src/main.c b/Program/src/main.c index f345b0e..7a6f674 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -27,6 +27,78 @@ //exit handler variable for the main thread static int *exit_now; +/*------------------------------------------------------------------------------ + Purpose: This struct if our configuration for this program, these elements + are set with getopt +------------------------------------------------------------------------------*/ +typedef struct config +{ + unsigned int timer; + uint32_t client_cfdp_id; + uint32_t my_cfdp_id; + uint8_t verbose_level; +} Config; + + +static Config *configuration(int argc, char **argv) +{ + int ch; + Config *conf = calloc(sizeof(Config), 1); + if (conf == NULL) + return NULL; + + + conf->timer = 15; + conf->verbose_level = 0; + conf->client_cfdp_id = 0; + conf->my_cfdp_id = 0; + + uint32_t tmp; + while ((ch = getopt(argc, argv, "t: i: c: v: h")) != -1) + { + switch (ch) + { + case 't': + tmp = strtol(optarg, NULL, 10); + conf->timer = tmp; + break; + + case 'i': + tmp = strtol(optarg, NULL, 10); + conf->my_cfdp_id = tmp; + break; + + case 'v': + tmp = strtol(optarg, NULL, 10); + conf->verbose_level = (uint8_t) tmp; + break; + + case 'c': + tmp = strtol(optarg, NULL, 10); + conf->client_cfdp_id = tmp; + break; + + case 'h': + ssp_printf("\n-----------HELP MESSAGE------------\n"); + ssp_printf("\nusage: %s [options] \n\n", basename(argv[0])); + ssp_printf("Options: %s%s%s%s\n", + "-t timeout\n", + "-i my cfdp id for server\n", + "-c client id\n", + "-v verbose level (1-3)" + "-h HelpMessage"); + + ssp_printf("Default port number mis 1111\n"); + ssp_printf("\n---------------END----------------\n"); + break; + default: + ssp_printf("\ngot something not found using default\n"); + break; + } + } + return conf; +} + int main(int argc, char** argv) { diff --git a/Program/src/mib.c b/Program/src/mib.c index 1f94ef6..5b6ab8f 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -3,7 +3,11 @@ #include "port.h" #include "types.h" #include "filesystem_funcs.h" + +//atoi #include "stdlib.h" + +//snprintf #include "stdio.h" diff --git a/Program/src/packet.c b/Program/src/packet.c index 831016c..b6b4180 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -1,12 +1,12 @@ #include "types.h" #include "packet.h" -#include "stdint.h" -#include "string.h" #include "utils.h" #include "port.h" #include "filesystem_funcs.h" #include "requests.h" - #include + +//hton +#include /*------------------------------------------------------------------------------ diff --git a/Program/src/port.c b/Program/src/port.c index 549d767..4cf50bb 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -1,11 +1,4 @@ - -#include "packet.h" #include "port.h" -#include "utils.h" -#include "mib.h" -#include "filesystem_funcs.h" -#include "types.h" -#include "config.h" #ifdef POSIX_PORT #include @@ -21,7 +14,6 @@ #include #endif - #ifdef FREE_RTOS_PORT #include "FreeRTOS.h" #include "task.h" @@ -30,10 +22,8 @@ #ifdef FREE_RTOS_PLUS #include "" #endif - #endif - #ifdef CSP_NETWORK #include "csp.h" #endif @@ -212,14 +202,16 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void #ifdef POSIX_PORT pthread_t *handler = ssp_alloc(1, sizeof(pthread_t)); - if (checkAlloc(handler) < 0) + if (handler == NULL) return NULL; pthread_attr_t *attr = ssp_alloc(1, sizeof(pthread_attr_t)); - if (checkAlloc(attr) < 0) + if (attr == NULL) { + ssp_free(handler); return NULL; + } int err = pthread_attr_init(attr); if (0 != err) diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index bf6edbb..a5ee6d1 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -25,7 +25,6 @@ static int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void } static void *ssp_init_socket_set(size_t *size) { - fd_set *socket_set = ssp_alloc(1, sizeof(fd_set)); *size = sizeof(fd_set); return (void *)socket_set; @@ -33,15 +32,11 @@ static void *ssp_init_socket_set(size_t *size) { static void ssp_fd_zero(void *socket_set){ - FD_ZERO((fd_set*) socket_set); - } static void ssp_fd_set(int sfd, void *socket_set) { - FD_SET(sfd, (fd_set*) socket_set); - } static int ssp_fd_is_set(int sfd, void *socket_set){ @@ -51,9 +46,7 @@ static int ssp_fd_is_set(int sfd, void *socket_set){ } static void ssp_fd_clr(int sfd, void *socket_set) { - FD_CLR(sfd, (fd_set *) socket_set); - } static int ssp_select(int sfd, void *read_socket_set, void *write_socket_set, void *restrict_socket_set, uint32_t timeout_in_usec) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e7f6c47..7f088a1 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -2,12 +2,13 @@ #include "mib.h" #include "port.h" #include "protocol_handler.h" -#include "string.h" #include "packet.h" #include "filesystem_funcs.h" #include "requests.h" #include "types.h" #include "utils.h" + +//htons #include //snprintf diff --git a/Program/src/requests.c b/Program/src/requests.c index 8ab57a1..c9d272b 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -6,16 +6,11 @@ aka: request from person ------------------------------------------------------------------------------*/ -#include "stdint.h" #include "requests.h" #include "port.h" #include "utils.h" -#include -#include "tasks.h" #include "types.h" #include "filesystem_funcs.h" -#include "mib.h" -#include #include "file_delivery_app.h" @@ -233,8 +228,7 @@ Request *init_request(char *buff, uint32_t buff_len) { req->buff = buff; req->procedure = none; req->paused = true; - reset_timeout(&req->timeout); - + req->timeout = ssp_time_count(); req->res.msg = req->buff; req->messages_to_user = linked_list(); @@ -363,7 +357,6 @@ void print_request_state(Request *req) { ssp_printf("EOF_sent indication %d\n", req->local_entity.EOF_sent_indication); ssp_printf("Metadata_recv indication %d\n", req->local_entity.Metadata_recv_indication); ssp_printf("Metadata_sent indication %d\n", req->local_entity.Metadata_sent_indication); - ssp_printf("Resume indication %d\n", req->local_entity.resumed_indication); ssp_printf("Suspended indication %d\n", req->local_entity.suspended_indication); ssp_printf("Transaction finished indication %d\n", req->local_entity.transaction_finished_indication); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index f258d7c..440a8cb 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -21,12 +21,44 @@ //for print_request_state #include "requests.h" + +/* +//usefull for cpu clocks +static int is_negative(int number) { + int negative_mask = 0x80000000; + int is_negative = number & negative_mask; + return is_negative; +} +*/ + +static void reset_timeout(int *prevtime) { + *prevtime = ssp_time_count(); +} + +static int check_timeout(int *prevtime, uint32_t timeout) { + + int prev = *prevtime; + int current_time = ssp_time_count(); + int time_out = prev + timeout; + + if (current_time >= time_out) { + *prevtime = current_time; + return 1; + } + //wrap around the overflow condition + else if (current_time < prev) { + *prevtime = current_time; + } + return 0; +} + /*------------------------------------------------------------------------------ Callbacks for the tasks bellow ------------------------------------------------------------------------------*/ + //sets request procedure as clean_up if ttl passed static void timeout(Request *req) { @@ -266,7 +298,6 @@ static int on_stdin_callback(void *other) { } */ return 0; - } diff --git a/Program/src/utils.c b/Program/src/utils.c index 6193183..128b794 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -7,96 +7,9 @@ Evan Giese 1689223 This is my utils.c file, it contains useful function and abstract data types to use for general functionality. ------------------------------------------------------------------------------*/ -#include -#include "utils.h" -#include -#include -#include -#include -#include -#include -#include "port.h" - -#include - -#define MAX_LEN 255 -#define ID_LEN 10 - -//see header file -int checkAlloc(void *mem) -{ - if (mem == NULL) - { - ssp_error("malloc"); - return -1; - } - return 1; -} - - -//see header file -Config *configuration(int argc, char **argv) -{ - int ch; - Config *conf = calloc(sizeof(Config), 1); - if (checkAlloc(conf) < 0) - return NULL; - - - conf->timer = 15; - conf->verbose_level = 0; - conf->client_cfdp_id = 0; - conf->my_cfdp_id = 0; - - uint32_t tmp; - while ((ch = getopt(argc, argv, "t: i: c: v: h")) != -1) - { - switch (ch) - { - case 't': - tmp = strtol(optarg, NULL, 10); - conf->timer = tmp; - break; - - case 'i': - tmp = strtol(optarg, NULL, 10); - conf->my_cfdp_id = tmp; - break; - - case 'v': - tmp = strtol(optarg, NULL, 10); - conf->verbose_level = (uint8_t) tmp; - break; - - case 'c': - tmp = strtol(optarg, NULL, 10); - conf->client_cfdp_id = tmp; - break; - - case 'h': - printf("\n-----------HELP MESSAGE------------\n"); - printf("\nusage: %s [options] \n\n", basename(argv[0])); - printf("Options: %s%s%s%s\n", - "-t timeout\n", - "-i my cfdp id for server\n", - "-c client id\n", - "-v verbose level (1-3)" - "-h HelpMessage"); - - printf("Default port number mis 1111\n"); - printf("\n---------------END----------------\n"); - break; - default: - printf("\ngot something not found using default\n"); - break; - } - } - return conf; -} - - - +#include "port.h" +#include "utils.h" //size is the number of bytes we want to print void ssp_print_hex(char *stuff, int size){ @@ -110,32 +23,3 @@ void ssp_print_hex(char *stuff, int size){ } ssp_printf("\n"); } - - -int is_negative(int number) { - int negative_mask = 0x80000000; - int is_negative = number & negative_mask; - return is_negative; -} - - -void reset_timeout(int *prevtime) { - *prevtime = ssp_time_count(); -} - -int check_timeout(int *prevtime, uint32_t timeout) { - - int prev = *prevtime; - int current_time = ssp_time_count(); - int time_out = prev + timeout; - - if (current_time >= time_out) { - *prevtime = current_time; - return 1; - } - //wrap around the overflow condition - else if (current_time < prev) { - *prevtime = current_time; - } - return 0; -} From aaa29ea294d1bec84a0dc8fa4c83c7227524852b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 21 May 2020 20:04:18 -0600 Subject: [PATCH 215/400] more moving stuff --- Program/include/port.h | 27 +++++++++++++-------------- Program/src/csp_server_provider.c | 10 ---------- Program/src/list.c | 2 -- Program/src/port.c | 6 ------ Program/src/posix_server_provider.c | 9 --------- Program/src/protocol_handler.c | 6 ------ Program/src/tasks.c | 17 +++++------------ Program/src/utils.c | 10 ---------- 8 files changed, 18 insertions(+), 69 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index a3c4ecd..21e97ea 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -4,9 +4,6 @@ #define STACK_ALLOCATION 16384 - - - #define POSIX_PORT #define POSIX_FILESYSTEM #define CSP_NETWORK @@ -26,17 +23,6 @@ } csp_packet_wrapper; #endif - - -void ssp_error( char *msg); -void ssp_printf(char *stuff, ...); -void *ssp_alloc(uint32_t u_memb, size_t size); -void ssp_sendto(Response res); - -void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); -int ssp_time_count(void); - - #ifdef POSIX_FILESYSTEM #include @@ -44,9 +30,22 @@ int ssp_time_count(void); #define SSP_O_CREAT O_CREAT #define SSP_O_TRUNC O_TRUNC #define SSP_SEEK_SET SEEK_SET +#endif +#ifdef POSIX_PORT + #include + #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN #endif + +void ssp_error( char *msg); +void ssp_printf(char *stuff, ...); +void *ssp_alloc(uint32_t u_memb, size_t size); +void ssp_sendto(Response res); + +void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); +int ssp_time_count(void); + int ssp_open(char *pathname, int flags); int ssp_read(int fd, char* buff, size_t size); int ssp_lseek(int fd, int offset, int whence); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 3a03811..513f4ca 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -1,11 +1,3 @@ -/*------------------------------------------------------------------------------ -CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks -Assignment #2 -Evan Giese 1689223 - -This is my file for server.c. It develops a udp server for select. -------------------------------------------------------------------------------*/ - #include "csp.h" #include "csp_server_provider.h" #include "port.h" @@ -17,8 +9,6 @@ static int exit_now; ------------------------------------------------------------------------------*/ -//#ifdef CSP_NETWORK - //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *params), diff --git a/Program/src/list.c b/Program/src/list.c index 2e37af4..aec2209 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -1,5 +1,3 @@ - - #include "list.h" #include "port.h" diff --git a/Program/src/port.c b/Program/src/port.c index 4cf50bb..ebd9a0f 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -18,10 +18,6 @@ #include "FreeRTOS.h" #include "task.h" #include "portable.h" - - #ifdef FREE_RTOS_PLUS - #include "" - #endif #endif #ifdef CSP_NETWORK @@ -168,8 +164,6 @@ void ssp_printf( char *stuff, ...) { #endif } - - //returns seconds elapsed int ssp_time_count() { diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index a5ee6d1..e447c33 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -1,11 +1,3 @@ -/*------------------------------------------------------------------------------ -CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks -Assignment #2 -Evan Giese 1689223 - -This is my file for server.c. It develops a udp server for select. -------------------------------------------------------------------------------*/ - #include #include #include @@ -17,7 +9,6 @@ This is my file for server.c. It develops a udp server for select. static int exit_now; - static int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { int count = 0; count = recvfrom(sfd, buff, packet_len, flags, (struct sockaddr*)server_addr, (socklen_t*)server_addr_len); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 7f088a1..e039df5 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -13,11 +13,7 @@ //snprintf #include -/*------------------------------------------------------------------------------ - - bundled requests -------------------------------------------------------------------------------*/ static void build_temperary_file(Request *req, uint32_t size) { @@ -59,8 +55,6 @@ static void resend_eof_ack(Request *req, Response res) { ------------------------------------------------------------------------------*/ - - //for finding the struct in the list struct request_search_params { uint32_t source_id; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 440a8cb..78561f0 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -1,16 +1,10 @@ - - - #include "protocol_handler.h" #include "tasks.h" #include "port.h" -#include #include "mib.h" #include "filesystem_funcs.h" #include "types.h" -#include "utils.h" -#include #include "posix_server_provider.h" #include "csp_server_provider.h" @@ -18,7 +12,6 @@ //snprintf #include - //for print_request_state #include "requests.h" @@ -320,7 +313,7 @@ static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port) uint32_t ut_addr = htonl(remote_entity.UT_address); //convert uint id to char * - const char *ret = inet_ntop(AF_INET, &ut_addr, host_name, INET_ADDRSTRLEN); + const char *ret = inet_ntop(AF_INET, &ut_addr, host_name, SSP_INET_ADDRSTRLEN); if (ret == NULL) { ssp_error("inet_ntop"); return -1; @@ -336,7 +329,7 @@ void *ssp_connectionless_server_task(void *params) { app->transaction_sequence_number = 1; char port[10]; - char host_name[INET_ADDRSTRLEN]; + char host_name[SSP_INET_ADDRSTRLEN]; int error = get_ip_port(app->remote_entity, host_name, port); if (error < 0) { @@ -362,7 +355,7 @@ void *ssp_connectionless_client_task(void* params){ Client *client = (Client *) params; char port[10]; - char host_name[INET_ADDRSTRLEN]; + char host_name[SSP_INET_ADDRSTRLEN]; int error = get_ip_port(client->remote_entity, host_name, port); if (error < 0) { @@ -388,7 +381,7 @@ void *ssp_connection_server_task(void *params) { app->transaction_sequence_number = 1; char port[10]; - char host_name[INET_ADDRSTRLEN]; + char host_name[SSP_INET_ADDRSTRLEN]; int error = get_ip_port(app->remote_entity, host_name, port); if (error < 0) { @@ -416,7 +409,7 @@ void *ssp_connection_client_task(void *params) { Client *client = (Client *) params; char port[10]; - char host_name[INET_ADDRSTRLEN]; + char host_name[SSP_INET_ADDRSTRLEN]; int error = get_ip_port(client->remote_entity, host_name, port); if (error < 0) { diff --git a/Program/src/utils.c b/Program/src/utils.c index 128b794..17e92c2 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -1,13 +1,3 @@ - -/*------------------------------------------------------------------------------ -CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks -Assignment #2 -Evan Giese 1689223 - -This is my utils.c file, it contains useful function and abstract data types -to use for general functionality. -------------------------------------------------------------------------------*/ - #include "port.h" #include "utils.h" //size is the number of bytes we want to print From 9ef118e4570d4a8a94ad2848339f259c78b3dd5e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 22 May 2020 22:16:56 -0600 Subject: [PATCH 216/400] moving more header files around, and include guards --- Program/include/config.h | 1 - Program/include/csp_server_provider.h | 7 +- Program/include/file_delivery_app.h | 7 +- Program/include/filesystem_funcs.h | 5 + Program/include/list.h | 5 + Program/include/mib.h | 9 +- Program/include/packet.h | 5 + Program/include/port.h | 25 +- Program/include/posix_server_provider.h | 6 + Program/include/protocol_handler.h | 5 + Program/include/requests.h | 6 +- Program/include/tasks.h | 5 + Program/include/types.h | 7 +- Program/include/utils.h | 11 +- Program/src/csp_server_provider.c | 7 + Program/src/file_delivery_app.c | 5 + Program/src/filesystem_funcs.c | 6 + Program/src/list.c | 6 + Program/src/main.c | 40 +--- Program/src/makefile | 2 +- Program/src/mib.c | 5 + Program/src/packet.c | 19 +- Program/src/port.c | 63 ++--- Program/src/posix_server_provider.c | 6 + Program/src/protocol_handler.c | 21 +- Program/src/requests.c | 5 + Program/src/tasks.c | 295 ++++++++++++++---------- Program/src/utils.c | 6 + 28 files changed, 361 insertions(+), 229 deletions(-) delete mode 100644 Program/include/config.h diff --git a/Program/include/config.h b/Program/include/config.h deleted file mode 100644 index d433022..0000000 --- a/Program/include/config.h +++ /dev/null @@ -1 +0,0 @@ -//#define TEST \ No newline at end of file diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index 0336284..375f74b 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -1,9 +1,8 @@ /*------------------------------------------------------------------------------ -CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks -Assignment #1 -Evan Giese 1689223 +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. -This file is the header file for server.c +Author: Evan Giese ------------------------------------------------------------------------------*/ #ifndef CSP_SERVER_H #define CSP_SERVER_H diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index f5eb6e6..9fb55e8 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -1,6 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. - - +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef FTP_APP_H #define FTP_APP_H #include "types.h" diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index a5a94df..518dae5 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef FILESYSTEM_FUNCS_H #define FILESYSTEM_FUNCS_H #include "types.h" diff --git a/Program/include/list.h b/Program/include/list.h index 7eba12f..c3a1656 100644 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -1,5 +1,10 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef MY_LIST_H #define MY_LIST_H #include diff --git a/Program/include/mib.h b/Program/include/mib.h index 69d58c2..4ba5edb 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -1,8 +1,9 @@ -//the management information base (MIB) - -//default faul handle - +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef MIB_H #define MIB_H diff --git a/Program/include/packet.h b/Program/include/packet.h index 3a95d21..7200537 100644 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -1,5 +1,10 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef PACKET_H #define PACKET_H diff --git a/Program/include/port.h b/Program/include/port.h index 21e97ea..9a8f1d5 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef PORT_H #define PORT_H @@ -25,7 +30,6 @@ #ifdef POSIX_FILESYSTEM #include - #define SSP_O_RDWR O_RDWR #define SSP_O_CREAT O_CREAT #define SSP_O_TRUNC O_TRUNC @@ -35,10 +39,27 @@ #ifdef POSIX_PORT #include #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN + #define SSP_AF_INET AF_INET + #define ssp_htonl htonl + #define ssp_ntohl ntohl + #define ssp_htons htons + #define ssp_stonl stonl #endif +#ifdef COMPLETELY_GENERIC_OS + #define ssp_htonl htonl + #define ssp_ntohl ntohl + #define ssp_htons htons + #define ssp_stonl stonl + #define SSP_INET_ADDRSTRLEN 16 + #define SSP_AF_INET 2 +#endif + + -void ssp_error( char *msg); +//don't change these in the header file here, if you need to change them +//change them in the .c file +void ssp_error(char *msg); void ssp_printf(char *stuff, ...); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); diff --git a/Program/include/posix_server_provider.h b/Program/include/posix_server_provider.h index b4d20f2..0f2be5b 100644 --- a/Program/include/posix_server_provider.h +++ b/Program/include/posix_server_provider.h @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef POSIX_SERVER_H #define POSIX_SERVER_H diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index e993faf..53d5e65 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef PROTOCOL_H #define PROTOCOL_H #include "types.h" diff --git a/Program/include/requests.h b/Program/include/requests.h index 6f6e7c7..2799ad5 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef REQUESTS_H #define REQUESTS_H @@ -34,7 +39,6 @@ Message_cont_part_request *create_message_cont_partial_request(uint32_t benefici uint8_t transaction_id_length); void print_request_state(Request *req); -//Frees a message struct void ssp_free_message(void *params); uint16_t copy_lv_to_buffer(char *buffer, LV lv); void copy_lv_from_buffer(LV *lv, char *packet, uint32_t start); diff --git a/Program/include/tasks.h b/Program/include/tasks.h index 19aee65..7f19966 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef SSP_TASKS_H #define SSP_TASKS_H diff --git a/Program/include/types.h b/Program/include/types.h index 54c67b9..b3a8678 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #ifndef SSP_TYPES_H #define SSP_TYPES_H @@ -14,7 +20,6 @@ Packet structs for building packets - ------------------------------------------------------------------------------*/ typedef struct pdu_header{ diff --git a/Program/include/utils.h b/Program/include/utils.h index 0bd4d07..c10274d 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -1,9 +1,8 @@ /*------------------------------------------------------------------------------ -CMPT-361-AS50(1) - 2017 Fall - Introduction to Networks -Assignment #1 -Evan Giese 1689223 +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. -This file is the header file for utils.c +Author: Evan Giese ------------------------------------------------------------------------------*/ #ifndef UTILS_H #define UTILS_H @@ -11,8 +10,8 @@ This file is the header file for utils.c #include //https://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c -#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) -#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) +#define htonll(x) ((1==ssp_htonl(1)) ? (x) : ((uint64_t)ssp_htonl((x) & 0xFFFFFFFF) << 32) | ssp_htonl((x) >> 32)) +#define ntohll(x) ((1==ssp_ntohl(1)) ? (x) : ((uint64_t)ssp_ntohl((x) & 0xFFFFFFFF) << 32) | ssp_ntohl((x) >> 32)) void ssp_print_hex(char *stuff, int size); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 513f4ca..2a8ceb7 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -1,3 +1,10 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ + #include "csp.h" #include "csp_server_provider.h" #include "port.h" diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 6da0a93..082dffe 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "mib.h" #include "port.h" #include "file_delivery_app.h" diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 532538e..d3a94a4 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #include #include "port.h" #include "filesystem_funcs.h" diff --git a/Program/src/list.c b/Program/src/list.c index aec2209..6f6df52 100644 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "list.h" #include "port.h" diff --git a/Program/src/main.c b/Program/src/main.c index 7a6f674..e02f830 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #include #include #include @@ -7,7 +12,7 @@ #include //Have to include these files - +#include //for types #include "protocol_handler.h" //for conf @@ -121,45 +126,12 @@ int main(int argc, char** argv) { //create a client if (conf->client_cfdp_id != 0){ - - start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", UN_ACKNOWLEDGED_MODE, app)); //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy3.jpg", UN_ACKNOWLEDGED_MODE, app)); Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/tcp.jpg", ACKNOWLEDGED_MODE, app); start_request(req); - /* - req = put_request(conf->client_cfdp_id, NULL, NULL, UN_ACKNOWLEDGED_MODE, app); - if (req != NULL) - add_proxy_message_to_request(2, 1, "pictures/pic.jpeg", "pictures/Proxy.jpg", req); - - start_request(req); - */ - - /* - req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy2.jpg", req); - start_request(req); - - - req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(2, 1, "pic.jpeg", "proxy3.jpg", req); - start_request(req); - - Request *req; - for (int i=0; i < 4; i++) { - sleep(10); - req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - char filename[11] = {'p','r','o','x','y', (char) (48+i), '.', 'j', 'p', 'g', '\0'}; - - - add_proxy_message_to_request(2, 1, "pic.jpeg", filename, req); - start_request(req); - - } -*/ - } ssp_thread_join(app->server_handle); diff --git a/Program/src/makefile b/Program/src/makefile index db4d40a..ea840cc 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -91,7 +91,7 @@ all: $(MAIN) .PHONY: clean lib $(MAIN): $(OBJS_FILES) $(STATIC_FILES) - mv *.o obj +# mv *.o obj lib: $(OBJS_FILES) ar -rsc file_delivery_app.a $(OBJS_FILES) diff --git a/Program/src/mib.c b/Program/src/mib.c index 5b6ab8f..69ecdf9 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "mib.h" #include "port.h" #include "types.h" diff --git a/Program/src/packet.c b/Program/src/packet.c index b6b4180..ddc7e00 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "types.h" #include "packet.h" #include "utils.h" @@ -5,9 +11,6 @@ #include "filesystem_funcs.h" #include "requests.h" -//hton -#include - /*------------------------------------------------------------------------------ creating packets @@ -15,7 +18,7 @@ ------------------------------------------------------------------------------*/ -// if is_data_packet is false, then is directive packet +// if is_data_packet is false, then is directive pacnket static void set_packet_header(char *packet, uint16_t data_len, bool is_data_packet) { Pdu_header *header = (Pdu_header *) packet; @@ -98,7 +101,7 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { packet_index++; //4 bytes - uint32_t network_bytes = htonl(req->file_size); + uint32_t network_bytes = ssp_htonl(req->file_size); network_bytes = network_bytes; memcpy(&packet[packet_index], &network_bytes, sizeof(uint32_t)); packet_index += 4; @@ -220,7 +223,7 @@ void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t packet_index++; //4 bytes - eof_packet->file_size = ntohl(file_size); + eof_packet->file_size = ssp_ntohl(file_size); packet_index += 4; eof_packet->checksum = checksum; packet_index += 4; @@ -241,8 +244,8 @@ void fill_nak_array_callback(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; - holder->offsets[holder->i].start = htonl(offset->start); - holder->offsets[holder->i].end = htonl(offset->end); + holder->offsets[holder->i].start = ssp_htonl(offset->start); + holder->offsets[holder->i].end = ssp_htonl(offset->end); holder->i++; } diff --git a/Program/src/port.c b/Program/src/port.c index ebd9a0f..77362c2 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "port.h" #ifdef POSIX_PORT @@ -76,38 +82,36 @@ int ssp_close(int fd) { ------------------------------------------------------------------------------*/ void ssp_sendto(Response res) { - - - + if (res.type_of_network == csp /*&& res.transmission_mode == UN_ACKNOWLEDGED_MODE*/) { - - csp_packet_t *packet = (csp_packet_t *) res.addr; - csp_packet_t *packet_sending; - - if (csp_buffer_remaining() != 0) { - packet_sending = csp_buffer_get(1); - - memcpy(packet_sending->data, res.msg, res.packet_len); - int err = csp_sendto(0, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 10); - - if (err < 0) { - ssp_error("ERROR in ssp_sento"); - csp_buffer_free(packet_sending); + #ifdef CSP_NETWORK + csp_packet_t *packet = (csp_packet_t *) res.addr; + csp_packet_t *packet_sending; + + if (csp_buffer_remaining() != 0) { + packet_sending = csp_buffer_get(1); + + memcpy(packet_sending->data, res.msg, res.packet_len); + int err = csp_sendto(0, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 10); + + if (err < 0) { + ssp_error("ERROR in ssp_sento"); + csp_buffer_free(packet_sending); + } } - - } - else - ssp_error("couldn't get new packet for sending!\n"); - + else + ssp_error("couldn't get new packet for sending!\n"); + #endif } else { + #ifdef POSIX_PORT + struct sockaddr* addr = (struct sockaddr*) res.addr; - struct sockaddr* addr = (struct sockaddr*) res.addr; - - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); - if (err < 0) { - ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); - ssp_error("ERROR in sendto"); - } + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); + if (err < 0) { + ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); + ssp_error("ERROR in sendto"); + } + #endif } } @@ -154,7 +158,8 @@ void ssp_error(char *error){ #endif } -void ssp_printf( char *stuff, ...) { +//this can be switched to +void ssp_printf(char *stuff, ...) { #ifdef POSIX_PORT va_list args; va_start(args, stuff); diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index e447c33..b2b6de9 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #include #include #include diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e039df5..87d660e 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -1,4 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "mib.h" #include "port.h" #include "protocol_handler.h" @@ -8,9 +13,6 @@ #include "types.h" #include "utils.h" -//htons -#include - //snprintf #include @@ -240,7 +242,7 @@ uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) uint8_t packet_index = 1; uint32_t *network_bytes = (uint32_t*) &meta_data_packet[packet_index]; - uint32_t file_size = ntohl(*network_bytes); + uint32_t file_size = ssp_ntohl(*network_bytes); req_to_fill->file_size = file_size; packet_index += 4; @@ -346,8 +348,8 @@ static void send_data(Request *req, Response res) { int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; - //uint32_t offset_first = ntohl(nak->start_scope); - //uint32_t offset_last = ntohl(nak->end_scope); + //uint32_t offset_first = ssp_ntohl(nak->start_scope); + //uint32_t offset_last = ssp_ntohl(nak->end_scope); uint64_t segments = ntohll(nak->segment_requests); packet_index += 16; @@ -362,10 +364,10 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien for (int i = 0; i < segments; i++){ //outgoing_packet_index memcpy(&offset_start, &packet[packet_index], 4); - offset_start = ntohl(offset_start); + offset_start = ssp_ntohl(offset_start); packet_index += 4; memcpy(&offset_end, &packet[packet_index], 4); - offset_end = ntohl(offset_end); + offset_end = ssp_ntohl(offset_end); packet_index += 4; build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); ssp_sendto(res); @@ -536,7 +538,7 @@ void process_pdu_eof(char *packet, Request *req, Response res) { ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); Pdu_eof *eof_packet = (Pdu_eof *) packet; - uint32_t file_size = ntohl(eof_packet->file_size); + uint32_t file_size = ssp_ntohl(eof_packet->file_size); if (req->file == NULL && req->local_entity.Metadata_recv_indication) { build_temperary_file(req, file_size); @@ -707,7 +709,6 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); req->local_entity.transaction_finished_indication = true; - /* code */ break; default: diff --git a/Program/src/requests.c b/Program/src/requests.c index c9d272b..a0c1e0b 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -1,5 +1,10 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. +Author: Evan Giese +------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------ USER STUFF diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 78561f0..97cee31 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -1,13 +1,23 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "protocol_handler.h" #include "tasks.h" #include "port.h" #include "mib.h" #include "filesystem_funcs.h" - #include "types.h" +#ifdef POSIX_PORT #include "posix_server_provider.h" +#endif + +#ifdef CSP_NETWORK #include "csp_server_provider.h" +#endif //snprintf #include @@ -310,10 +320,10 @@ static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port) return -1; } - uint32_t ut_addr = htonl(remote_entity.UT_address); + uint32_t ut_addr = ssp_htonl(remote_entity.UT_address); //convert uint id to char * - const char *ret = inet_ntop(AF_INET, &ut_addr, host_name, SSP_INET_ADDRSTRLEN); + const char *ret = inet_ntop(SSP_AF_INET, &ut_addr, host_name, SSP_INET_ADDRSTRLEN); if (ret == NULL) { ssp_error("inet_ntop"); return -1; @@ -324,171 +334,204 @@ static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port) void *ssp_connectionless_server_task(void *params) { - ssp_printf("starting posix connectionless server task\n"); - FTP* app = (FTP*) params; - app->transaction_sequence_number = 1; - - char port[10]; - char host_name[SSP_INET_ADDRSTRLEN]; - - int error = get_ip_port(app->remote_entity, host_name, port); - if (error < 0) { - ssp_cleanup_ftp(app); - return NULL; - } + #ifdef POSIX_PORT + ssp_printf("starting posix connectionless server task\n"); + FTP* app = (FTP*) params; + app->transaction_sequence_number = 1; + + char port[10]; + char host_name[SSP_INET_ADDRSTRLEN]; + + int error = get_ip_port(app->remote_entity, host_name, port); + if (error < 0) { + ssp_cleanup_ftp(app); + return NULL; + } - connectionless_server(host_name, port, - app->packet_len, - on_recv_server_callback, - on_time_out_callback_server, - on_stdin_callback, - check_exit_server_callback, - on_exit_server_callback, - app); - + connectionless_server(host_name, port, + app->packet_len, + on_recv_server_callback, + on_time_out_callback_server, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, + app); + #endif + #ifndef POSIX_PORT + ssp_printf("can't start posix connectionless server, no drivers\n"); + #endif return NULL; } void *ssp_connectionless_client_task(void* params){ - ssp_printf("starting posix connectionless client task \n"); - Client *client = (Client *) params; + #ifdef POSIX_PORT + ssp_printf("starting posix connectionless client task \n"); + Client *client = (Client *) params; - char port[10]; - char host_name[SSP_INET_ADDRSTRLEN]; + char port[10]; + char host_name[SSP_INET_ADDRSTRLEN]; - int error = get_ip_port(client->remote_entity, host_name, port); - if (error < 0) { - ssp_cleanup_client(client); - return NULL; - } + int error = get_ip_port(client->remote_entity, host_name, port); + if (error < 0) { + ssp_cleanup_client(client); + return NULL; + } - connectionless_client(host_name, - port, - client->packet_len, - client, - on_send_client_callback, - on_recv_client_callback, - check_exit_client_callback, - on_exit_client_callback); - - return NULL; + connectionless_client(host_name, + port, + client->packet_len, + client, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback); + + return NULL; + #endif + #ifndef POSIX_PORT + ssp_printf("can't start posix connectionless client, no drivers\n"); + #endif } void *ssp_connection_server_task(void *params) { - ssp_printf("starting posix connection server\n"); - FTP* app = (FTP*) params; - app->transaction_sequence_number = 1; - - char port[10]; - char host_name[SSP_INET_ADDRSTRLEN]; - - int error = get_ip_port(app->remote_entity, host_name, port); - if (error < 0) { - ssp_cleanup_ftp(app); - return NULL; - } - - //1024 is the connection max limit - connection_server(host_name, - port, - app->packet_len, - 10, - on_recv_server_callback, - on_time_out_callback_server, - on_stdin_callback, - check_exit_server_callback, - on_exit_server_callback, - app); + #ifdef POSIX_PORT + ssp_printf("starting posix connection server\n"); + FTP* app = (FTP*) params; + app->transaction_sequence_number = 1; + + char port[10]; + char host_name[SSP_INET_ADDRSTRLEN]; + + int error = get_ip_port(app->remote_entity, host_name, port); + if (error < 0) { + ssp_cleanup_ftp(app); + return NULL; + } + //1024 is the connection max limit + connection_server(host_name, + port, + app->packet_len, + 10, + on_recv_server_callback, + on_time_out_callback_server, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, + app); + #endif + #ifndef POSIX_PORT + ssp_printf("can't start posix connection server, no drivers\n"); + #endif return NULL; } void *ssp_connection_client_task(void *params) { - ssp_printf("starting posix connection client\n"); - Client *client = (Client *) params; + #ifdef POSIX_PORT + ssp_printf("starting posix connection client\n"); + Client *client = (Client *) params; - char port[10]; - char host_name[SSP_INET_ADDRSTRLEN]; + char port[10]; + char host_name[SSP_INET_ADDRSTRLEN]; - int error = get_ip_port(client->remote_entity, host_name, port); - if (error < 0) { - ssp_cleanup_client(client); - return NULL; - } + int error = get_ip_port(client->remote_entity, host_name, port); + if (error < 0) { + ssp_cleanup_client(client); + return NULL; + } - connection_client(host_name, - port, - client->packet_len, - client, - on_send_client_callback, - on_recv_client_callback, - check_exit_client_callback, - on_exit_client_callback); - + connection_client(host_name, + port, + client->packet_len, + client, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback); + #endif + #ifndef POSIX_PORT + ssp_printf("can't start posix connection client, no drivers\n"); + #endif return NULL; } void *ssp_csp_connectionless_server_task(void *params) { - ssp_printf("starting csp connectionless server\n"); - FTP *app = (FTP *) params; - - csp_connectionless_server( - app->remote_entity.UT_port, - on_recv_server_callback, - on_time_out_callback_server, - on_stdin_callback, - check_exit_server_callback, - on_exit_server_callback, - app); - + #ifdef CSP_NETWORK + ssp_printf("starting csp connectionless server\n"); + FTP *app = (FTP *) params; + + csp_connectionless_server( + app->remote_entity.UT_port, + on_recv_server_callback, + on_time_out_callback_server, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, + app); + #endif + #ifndef CSP_NETWORK + ssp_printf("can't start csp connectionless server, no drivers\n"); + #endif return NULL; } void *ssp_csp_connectionless_client_task(void *params) { - ssp_printf("starting csp connectionless client\n"); - Client *client = (Client *) params; - - csp_connectionless_client(client->remote_entity.UT_address, - client->remote_entity.UT_port, - client->app->remote_entity.UT_port, - on_send_client_callback, - on_recv_client_callback, - check_exit_client_callback, - on_exit_client_callback, - client); - + #ifdef CSP_NETWORK + ssp_printf("starting csp connectionless client\n"); + Client *client = (Client *) params; + + csp_connectionless_client(client->remote_entity.UT_address, + client->remote_entity.UT_port, + client->app->remote_entity.UT_port, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback, + client); + #endif + #ifndef CSP_NETWORK + ssp_printf("can't start csp connectionless client, no drivers\n"); + #endif return NULL; } void *ssp_csp_connection_server_task(void *params) { + #ifdef CSP_NETWORK ssp_printf("starting csp connection server\n"); FTP *app = (FTP *) params; - csp_connection_server(app->remote_entity.UT_port, - on_recv_server_callback, - on_time_out_callback_server, - on_stdin_callback, - check_exit_server_callback, - on_exit_server_callback, - params); - + csp_connection_server(app->remote_entity.UT_port, + on_recv_server_callback, + on_time_out_callback_server, + on_stdin_callback, + check_exit_server_callback, + on_exit_server_callback, + params); + #endif + #ifndef CSP_NETWORK + ssp_printf("can't start csp connection server, no drivers\n"); + #endif return NULL; } void *ssp_csp_connection_client_task(void *params) { + #ifdef CSP_NETWORK ssp_printf("starting csp connection client\n"); Client *client = (Client *) params; - - csp_connection_client(client->remote_entity.UT_address, - client->remote_entity.UT_port, - on_send_client_callback, - on_recv_client_callback, - check_exit_client_callback, - on_exit_client_callback, - params); - + csp_connection_client(client->remote_entity.UT_address, + client->remote_entity.UT_port, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback, + params); + + #endif + #ifndef CSP_NETWORK + ssp_printf("can't start csp connection client, no drivers\n"); + #endif return NULL; } /*------------------------------------------------------------------------------ diff --git a/Program/src/utils.c b/Program/src/utils.c index 17e92c2..044d889 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -1,3 +1,9 @@ +/*------------------------------------------------------------------------------ +This file is protected under copyright. If you want to use it, +please include this text, that is my only stipulation. + +Author: Evan Giese +------------------------------------------------------------------------------*/ #include "port.h" #include "utils.h" //size is the number of bytes we want to print From 51200804f11ed18a2dd139fec8af517a4bc0af0c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 23 May 2020 13:30:59 -0600 Subject: [PATCH 217/400] update tests --- Program/include/port.h | 14 ++-- Program/src/filesystem_funcs.c | 6 +- Program/src/mib.c | 45 +++++------ Program/src/port.c | 8 -- Program/src/protocol_handler.c | 8 +- Program/src/tasks.c | 13 ++-- Program/test/filesystem_tests.c | 4 +- Program/test/list_tests.c | 8 +- Program/test/main.c | 31 ++------ Program/test/makefile | 13 ++-- Program/test/mib/peer_1.json | 3 +- Program/test/mib/peer_2.json | 3 +- Program/test/mock.c | 43 +++++------ Program/test/packet_tests.c | 29 ++++---- Program/test/protocol_handler_tests.c | 70 +++++++----------- Program/test/request_tests.c | 16 ++-- Program/test/server_tests.c | 2 +- Program/test/tasks_tests.c | 9 --- .../test/temp/pending_req_id:1:num:1.binary | Bin 0 -> 749 bytes Program/test/temp/test_file_save | Bin 0 -> 56 bytes Program/test/test_files/empty.txt | 0 Program/test/testfile | 1 - Program/test/unit_tests.h | 34 ++++----- 23 files changed, 142 insertions(+), 218 deletions(-) create mode 100644 Program/test/temp/pending_req_id:1:num:1.binary create mode 100644 Program/test/temp/test_file_save create mode 100644 Program/test/test_files/empty.txt diff --git a/Program/include/port.h b/Program/include/port.h index 9a8f1d5..451fd3c 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -24,7 +24,6 @@ Author: Evan Giese uint8_t src_id; uint8_t src_port; csp_packet_t *packet; - } csp_packet_wrapper; #endif @@ -44,15 +43,12 @@ Author: Evan Giese #define ssp_ntohl ntohl #define ssp_htons htons #define ssp_stonl stonl -#endif -#ifdef COMPLETELY_GENERIC_OS - #define ssp_htonl htonl - #define ssp_ntohl ntohl - #define ssp_htons htons - #define ssp_stonl stonl - #define SSP_INET_ADDRSTRLEN 16 - #define SSP_AF_INET 2 + #include + #define ssp_snprintf snprintf + + #include "stdlib.h" + #define ssp_atol atol #endif diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index d3a94a4..58c189a 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -9,8 +9,6 @@ Author: Evan Giese #include "filesystem_funcs.h" #include "jsmn.h" #include "requests.h" -//snprintf -#include uint32_t get_file_size(char *source_file_name) { @@ -545,7 +543,7 @@ static int write_file_present_bool(int fd, File *file) { int save_req_to_file(Request *req) { char file_name[255]; - snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); + ssp_snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { @@ -691,7 +689,7 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Reque char file_name[255]; - snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); + ssp_snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { diff --git a/Program/src/mib.c b/Program/src/mib.c index 69ecdf9..408b57d 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -9,11 +9,6 @@ Author: Evan Giese #include "types.h" #include "filesystem_funcs.h" -//atoi -#include "stdlib.h" - -//snprintf -#include "stdio.h" int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { @@ -96,61 +91,61 @@ static void parse_mib(char *key, char *value, void *params) { switch (i) { case PARSE_cfdp_id: - remote->cfdp_id = atol(value); + remote->cfdp_id = ssp_atol(value); break; case PARSE_UT_address: - remote->UT_address = atol(value); + remote->UT_address = ssp_atol(value); break; case PARSE_UT_port: - remote->UT_port = atol(value); + remote->UT_port = ssp_atol(value); break; case PARSE_type_of_network: - remote->type_of_network = atol(value); + remote->type_of_network = ssp_atol(value); break; case PARSE_default_transmission_mode: - remote->default_transmission_mode = atol(value); + remote->default_transmission_mode = ssp_atol(value); break; case PARSE_one_way_light_time: - remote->one_way_light_time = atol(value); + remote->one_way_light_time = ssp_atol(value); break; case PARSE_total_round_trip_allowance: - remote->total_round_trip_allowance = atol(value); + remote->total_round_trip_allowance = ssp_atol(value); break; case PARSE_async_NAK_interval: - remote->async_NAK_interval = atol(value); + remote->async_NAK_interval = ssp_atol(value); break; case PARSE_async_keep_alive_interval: - remote->async_keep_alive_interval = atol(value); + remote->async_keep_alive_interval = ssp_atol(value); break; case PARSE_async_report_interval: - remote->async_report_interval = atol(value); + remote->async_report_interval = ssp_atol(value); break; case PARSE_immediate_nak_mode_enabled: - remote->immediate_nak_mode_enabled = atol(value); + remote->immediate_nak_mode_enabled = ssp_atol(value); break; case PARSE_prompt_transmission_interval: - remote->prompt_transmission_interval = atol(value); + remote->prompt_transmission_interval = ssp_atol(value); break; case PARSE_disposition_of_incomplete: - remote->disposition_of_incomplete = atol(value); + remote->disposition_of_incomplete = ssp_atol(value); break; case PARSE_CRC_required: - remote->CRC_required = atol(value); + remote->CRC_required = ssp_atol(value); break; case PARSE_mtu: - remote->mtu = atol(value); + remote->mtu = ssp_atol(value); break; case PARSE_keep_alive_discrepancy_limit: - remote->keep_alive_discrepancy_limit = atol(value); + remote->keep_alive_discrepancy_limit = ssp_atol(value); break; case PARSE_positive_ack_timer_expiration_limit: - remote->positive_ack_timer_expiration_limit = atol(value); + remote->positive_ack_timer_expiration_limit = ssp_atol(value); break; case PARSE_nak_timer_expiration_limit: - remote->nak_timer_expiration_limit = atol(value); + remote->nak_timer_expiration_limit = ssp_atol(value); break; case PARSE_transaction_inactivity_limit: - remote->transaction_inactivity_limit = atol(value); + remote->transaction_inactivity_limit = ssp_atol(value); break; default: break; @@ -161,7 +156,7 @@ static void parse_mib(char *key, char *value, void *params) { int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { char file_name[50]; - snprintf(file_name, 50, "%s%d%s", "mib/peer_", cfdp_id, ".json"); + ssp_snprintf(file_name, 50, "%s%d%s", "mib/peer_", cfdp_id, ".json"); int error = read_json(file_name, parse_mib, remote); diff --git a/Program/src/port.c b/Program/src/port.c index 77362c2..2bccef5 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -171,7 +171,6 @@ void ssp_printf(char *stuff, ...) { //returns seconds elapsed int ssp_time_count() { - #ifdef POSIX_PORT struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); @@ -181,18 +180,11 @@ int ssp_time_count() { return ts.tv_sec; #endif - - - - #ifdef FREE_RTOS_PORT //some kind of ticks #endif } - - - /*------------------------------------------------------------------------------ Threading and task functions ------------------------------------------------------------------------------*/ diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 87d660e..45e6c81 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -13,14 +13,10 @@ Author: Evan Giese #include "types.h" #include "utils.h" -//snprintf -#include - - static void build_temperary_file(Request *req, uint32_t size) { - snprintf(req->source_file_name, 75, "%s%llu%s", "incomplete_requests/.temp_", req->transaction_sequence_number, ".jpeg"); + ssp_snprintf(req->source_file_name, 75, "%s%llu%s", "incomplete_requests/.temp_", req->transaction_sequence_number, ".jpeg"); ssp_printf("haven't received metadata yet, building temperary file %s\n", req->source_file_name); req->file = create_temp_file(req->source_file_name, size); } @@ -557,7 +553,7 @@ int process_file_request_metadata(Request *req) { req->file = create_file(req->destination_file_name, 1); else if (req->file->is_temp) { - snprintf(temp, 75, "%s%llu%s", "incomplete_requests/.temp_", req->transaction_sequence_number, ".jpeg"); + ssp_snprintf(temp, 75, "%s%llu%s", "incomplete_requests/.temp_", req->transaction_sequence_number, ".jpeg"); change_tempfile_to_actual(temp, req->destination_file_name, req->file_size, req->file); return 1; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 97cee31..77e5b9a 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -19,9 +19,6 @@ Author: Evan Giese #include "csp_server_provider.h" #endif -//snprintf -#include - //for print_request_state #include "requests.h" @@ -61,8 +58,7 @@ static int check_timeout(int *prevtime, uint32_t timeout) { ------------------------------------------------------------------------------*/ - -//sets request procedure as clean_up if ttl passed +//sets request procedure as clean_up if ttl has passed static void timeout(Request *req) { bool is_timeout = check_timeout(&req->timeout, TIMEOUT_BEFORE_CANCEL_REQUEST); @@ -265,7 +261,8 @@ static void on_exit_server_callback (void *params) { } -//this function is just for posix fun +//this function is just for stdin fun, I haven't decided if we need need to use +//std in for anything, but we could use it to pass in args to the daemon. static int on_stdin_callback(void *other) { /* @@ -314,9 +311,9 @@ static int on_stdin_callback(void *other) { static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port){ //convert int to char * - int error = snprintf(port, 10, "%d", remote_entity.UT_port); + int error = ssp_snprintf(port, 10, "%d", remote_entity.UT_port); if (error < 0) { - ssp_error("snprintf"); + ssp_error("ssp_snprintf"); return -1; } diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 3fd4c3b..7080b23 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -117,7 +117,7 @@ static int test_saving_request(){ DECLARE_NEW_TEST("test saving requests"); - Request *req = init_request(1000); + Request *req = mock_empty_request(); req->dest_cfdp_id = 1; req->transaction_sequence_number = 1; @@ -179,7 +179,7 @@ static int test_saving_request(){ int file_system_tests() { int error = 0; error = test_saving_request(); - error = test_save_file(); + //error = test_save_file(); return error; } diff --git a/Program/test/list_tests.c b/Program/test/list_tests.c index 8572d9d..3d4e2d0 100644 --- a/Program/test/list_tests.c +++ b/Program/test/list_tests.c @@ -18,7 +18,7 @@ List *populate_request_list() { List *list = linked_list(); Request *r; for (int i = 0; i < 5; i++) { - r = init_request(100); + r = mock_empty_request(); r->dest_cfdp_id = i; list->push(list, r, i); } @@ -59,11 +59,11 @@ void test_remove_node() { int list_tests() { - DECLARE_NEW_TEST("list.c"); + DECLARE_NEW_TEST("list.c tests"); List *list = linked_list(); - Request *r = init_request(10000); - Request *r2 = init_request(10000); + Request *r = mock_empty_request(); + Request *r2 = mock_empty_request(); memcpy(r->source_file_name, "mybestfriend", 12); memcpy(r2->source_file_name, "secondrequest", 12); diff --git a/Program/test/main.c b/Program/test/main.c index 7935b23..389b11e 100644 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -1,36 +1,15 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "types.h" #include "unit_tests.h" - - int main () { - int error = 0; - //error = request_tests(); + error = request_tests(); error = packet_tests(); - //error = protocol_handler_test(); + error = protocol_handler_test(); + error = list_tests(); + error = tasks_tests(); + error = file_system_tests(); - - //error = list_tests(); - //error = file_system_tests(); - //error = tasks_tests(); - - /* - if (strcmp(argv[1], "1") == 0) - error = server_tests(0); - else - error = server_tests(1); - */ return error; } \ No newline at end of file diff --git a/Program/test/makefile b/Program/test/makefile index ff00eba..cd476d3 100644 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -17,7 +17,8 @@ CC = gcc CFILES += $(PROJDIR)/src/utils.c CFILES += $(PROJDIR)/src/filesystem_funcs.c CFILES += $(PROJDIR)/src/port.c -CFILES += $(PROJDIR)/src/server.c +CFILES += $(PROJDIR)/src/posix_server_provider.c +CFILES += $(PROJDIR)/src/csp_server_provider.c CFILES += $(PROJDIR)/src/protocol_handler.c CFILES += $(PROJDIR)/src/mib.c CFILES += $(PROJDIR)/src/requests.c @@ -29,14 +30,14 @@ CFILES += $(PROJDIR)/src/packet.c CFILES += $(PROJDIR)/test/packet_tests.c CFILES += $(PROJDIR)/test/test.c -#CFILES += $(PROJDIR)/test/mock.c +CFILES += $(PROJDIR)/test/mock.c CFILES += $(PROJDIR)/test/request_tests.c -#CFILES += $(PROJDIR)/test/tasks_tests.c -#CFILES += $(PROJDIR)/test/list_tests.c +CFILES += $(PROJDIR)/test/tasks_tests.c +CFILES += $(PROJDIR)/test/list_tests.c CFILES += $(PROJDIR)/test/filesystem_tests.c -#CFILES += $(PROJDIR)/test/protocol_handler_tests.c -#CFILES += $(PROJDIR)/test/list_tests.c +CFILES += $(PROJDIR)/test/protocol_handler_tests.c +CFILES += $(PROJDIR)/test/list_tests.c #CFILES += $(PROJDIR)/test/server_tests.c diff --git a/Program/test/mib/peer_1.json b/Program/test/mib/peer_1.json index 467b35e..5fbf6b4 100644 --- a/Program/test/mib/peer_1.json +++ b/Program/test/mib/peer_1.json @@ -4,7 +4,8 @@ "UT_port" : 1111, "type_of_network" : 1, "default_transmission_mode" : 1, - + "MTU" : 1500, + "one_way_light_time" : 123, "total_round_trip_allowance" : 123, "async_NAK_interval" : 123, diff --git a/Program/test/mib/peer_2.json b/Program/test/mib/peer_2.json index dbf2600..30a15e5 100644 --- a/Program/test/mib/peer_2.json +++ b/Program/test/mib/peer_2.json @@ -4,7 +4,8 @@ "UT_port" : 1112, "type_of_network" : 1, "default_transmission_mode" : 1, - + "MTU" : 1500, + "one_way_light_time" : 123, "total_round_trip_allowance" : 123, "async_NAK_interval" : 123, diff --git a/Program/test/mock.c b/Program/test/mock.c index a8fd483..0e7c31e 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -43,9 +43,9 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { Pdu_header pdu_header; Remote_entity remote_entity; - mock_mock_remote_entity(&remote_entity, src_id); + mock_mock_remote_entity(&remote_entity, dest_id); - int error = get_header_from_mib(&pdu_header, remote_entity, dest_id); + int error = get_header_from_mib(&pdu_header, remote_entity, src_id); int packet_index = build_pdu_header(packet, 1, 0, &pdu_header); return packet_index; @@ -55,6 +55,7 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *fil int packet_index = mock_packet(packet, dest_id, src_id); File *file = create_file(file_name, false); + file->partial_checksum = check_sum_file(file, 1000); build_eof_packet(packet, packet_index, file->total_size, check_sum_file(file, 1000)); return file; @@ -68,21 +69,30 @@ Response *mock_response() { res->sfd = 1; res->packet_len = 1500; res->size_of_addr = 16; - res->type_of_network = posix; + res->type_of_network = posix_connection_less; res->transmission_mode = UN_ACKNOWLEDGED_MODE; return res; } +Request *mock_empty_request() { + char *buff = ssp_alloc(1500, 1); + Request *req = ssp_alloc(1, sizeof(Request)); + req->messages_to_user = linked_list(); + req->buff = buff; + req->file = NULL; + return req; +} Request *mock_request() { - Request *req = init_request(5000); - char *dest = "dest"; - char *src = "src"; + Request *req = mock_empty_request(); + + char *dest = "test_files/dest"; + char *src = "test_files/src"; uint32_t id = 1; req->dest_cfdp_id = id; - req->file = create_file("dest_received.jpg", true); + req->file = create_file("test_files/dest_received.jpg", true); memcpy (req->source_file_name, dest, strnlen(dest, 255)); memcpy (req->destination_file_name, src, strnlen(src, 255)); @@ -96,24 +106,11 @@ Request *mock_request() { req->res.sfd = 1; req->res.packet_len = 2000; req->res.size_of_addr = 16; - req->res.type_of_network = posix; + req->res.type_of_network = posix_connection_less; req->res.transmission_mode = UN_ACKNOWLEDGED_MODE; req->res.msg = req->buff; + req->messages_to_user = linked_list(); return req; -} - - -/* -static int test_process_pdu_eof() { -//char *packet, Request *req, Response res - - - //process_pdu_eof(packet, Request *req, Response res); - return 0; -} - - -*/ - +} \ No newline at end of file diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index a81ee4d..55a266e 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -50,7 +50,7 @@ static int test_build_eof_packet(char *packet, int packet_start) { Pdu_eof *eof_pdu = (Pdu_eof*) &packet[packet_index]; ASSERT_EQUALS_INT("condition_code should equal NO_ERROR", eof_pdu->condition_code, COND_NO_ERROR); - ASSERT_EQUALS_INT("filesize should equal", htonl(eof_pdu->file_size), file->total_size); + ASSERT_EQUALS_INT("filesize should equal", ssp_htonl(eof_pdu->file_size), file->total_size); ASSERT_EQUALS_INT("checksum should equal", eof_pdu->checksum, file->partial_checksum); free_file(file); @@ -60,7 +60,7 @@ static int test_build_eof_packet(char *packet, int packet_start) { } static int test_respond_to_naks(char *packet, uint32_t packet_index) { - Request *req = init_request(5000); + Request *req = mock_empty_request(); ssp_cleanup_req(req); return 0; @@ -75,12 +75,12 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ DECLARE_NEW_TEST("testing data packet"); - File *file = create_file("testfile", 0); + File *file = create_file("test_files/testfile", 0); build_data_packet(packet, packet_index, file, 1000); ASSERT_EQUALS_INT("test proper datapacket offset set", (uint64_t)packet[packet_index], 0); - ASSERT_EQUALS_STR("test proper datapacket creation", &packet[packet_index + 4], "tempfileyo", 10); + ASSERT_EQUALS_STR("test proper datapacket creation", &packet[packet_index + 4], "testfileyo", 10); free_file(file); } @@ -94,7 +94,7 @@ static void nak_print(void *element, void *args){ static int test_build_nak_packet(char* packet, uint32_t start) { DECLARE_NEW_TEST("testing build nak packet"); - Request *req = init_request(5000); + Request *req = mock_empty_request(); req->file_size = 100000; memcpy(req->destination_file_name, "testestest", 15); @@ -274,8 +274,8 @@ int test_build_metadata_packet(char *packet, uint32_t start) { memset(&packet[start], 0, 20); DECLARE_NEW_TEST("testing metadata packets"); - Request *req = init_request(1000); - Request *recv_request = init_request(1000); + Request *req = mock_empty_request(); + Request *recv_request = mock_empty_request(); uint8_t len = build_put_packet_metadata(packet, start, req); fill_request_pdu_metadata(&packet[start + 1], recv_request); @@ -312,7 +312,7 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ uint32_t packet_index = start; - Request *req = init_request(1000); + Request *req = mock_empty_request(); int error = add_cont_partial_message_to_request(1,1,1,1,1,1,req); memset(&packet[start], 0, 100); @@ -358,7 +358,7 @@ int test_add_messages_to_packet(char *packet, uint32_t start) { uint32_t packet_index = start; DECLARE_NEW_TEST("testing add_messages_to_packet"); - Request *req = init_request(1000); + Request *req = mock_empty_request(); int error = add_proxy_message_to_request(id, len, src, dest, req); memset(&packet[start], 0, 100); @@ -402,12 +402,12 @@ int test_get_message_from_packet(char *packet, uint32_t start) { uint32_t packet_index = start; - Request *req = init_request(1000); + Request *req = mock_empty_request(); int error = add_proxy_message_to_request(id, len, src, dest, req); uint32_t length_of_message = add_messages_to_packet(packet, start, req->messages_to_user); - Request *req2 = init_request(1000); + Request *req2 = mock_empty_request(); uint32_t next_message = get_message_from_packet(packet, start, req2); Message *m = req2->messages_to_user->pop(req2->messages_to_user); @@ -442,7 +442,7 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { uint32_t packet_index = start; - Request *req = init_request(1000); + Request *req = mock_empty_request(); int error = add_proxy_message_to_request(id, len, src, dest, req); @@ -451,7 +451,7 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { length_of_message = add_messages_to_packet(packet, length_of_message, req->messages_to_user); length_of_message = add_messages_to_packet(packet, length_of_message, req->messages_to_user); - Request *req2 = init_request(1000); + Request *req2 = mock_empty_request(); get_messages_from_packet(packet, start, 1000 - start, req2); int message_count = req2->messages_to_user->count; @@ -478,9 +478,6 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { int packet_tests() { - - printf("starting Packet Tests (creating and changing packet values)\n"); - //setting host name for testing char *host_name = "127.0.0.1"; diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index c7c037a..b4d3d8b 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -16,52 +16,36 @@ static int test_process_pdu_eof() { DECLARE_NEW_TEST("testing process eof pdu"); - - char *packet = malloc(2000); + char packet[2000]; //test images File *file = mock_eof_packet(packet, 1, 2, "test_files/dest.jpg"); - Request *req = mock_request(); + Request *req = mock_empty_request(); + req->file = file; + process_pdu_eof(&packet[10], req, req->res); - ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity->EOF_recv_indication, true); + ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity.EOF_recv_indication, true); ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); - free_file(file); + free(req->buff); ssp_cleanup_req(req); //test empty files file = mock_eof_packet(packet, 1, 2, "test_files/empty.txt"); - req = mock_request(); + req = mock_empty_request(); + req->file = file; process_pdu_eof(&packet[10], req, req->res); - ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity->EOF_recv_indication, true); + ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity.EOF_recv_indication, true); ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); - - free_file(file); - ssp_cleanup_req(req); - - //test empty filestruct - file = mock_eof_packet(packet, 1, 2, "test_files/empty.txt"); - req = mock_request(); - free_file(req->file); - req->file = NULL; - - process_pdu_eof(&packet[10], req, req->res); - ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity->EOF_recv_indication, true); - ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); - ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); - - - free(packet); - free_file(file); + free(req->buff); ssp_cleanup_req(req); - return 0; } @@ -75,16 +59,16 @@ int test_on_server_time_out() { //no meta data received, sending request for new one (can't send NAKs yet, because we don't know filesize) on_server_time_out(req->res, req); - req->local_entity->Metadata_recv_indication = true; + req->local_entity.Metadata_recv_indication = true; on_server_time_out(req->res, req); - req->local_entity->EOF_recv_indication = true; + req->local_entity.EOF_recv_indication = true; on_server_time_out(req->res, req); - req->local_entity->transaction_finished_indication = true; + req->local_entity.transaction_finished_indication = true; on_server_time_out(req->res, req); - on_server_time_out_different(req->res, req); + on_server_time_out(req->res, req); //file equals null, should return. //on_server_time_out(req->res, req); @@ -101,8 +85,11 @@ static int test_wrong_id(FTP *app) { int packet_index = mock_packet(packet, 2, 1); Request **req_container = &app->current_request; - process_pdu_header(packet, true, *res, req_container, app->request_list, app); + + error = process_pdu_header(packet, true, *res, req_container, app->request_list, app); + error = ASSERT_EQUALS_INT("process pdu should error", -1, error); Request *req = (*req_container); + error = ASSERT_NULL("Test wrong id, Request should be NULL", req); error = ASSERT_EQUALS_INT("Length of request list should be 0", app->request_list->count, 0); @@ -120,34 +107,31 @@ static int test_correct_id(FTP *app) { process_pdu_header(packet, true, *res, req_container, app->request_list, app); Request *req = (*req_container); - error = ASSERT_NOT_NULL("Test wrong id, Request should not be NULL", req); + error = ASSERT_NOT_NULL("Test request, Request should not be NULL", req); error = ASSERT_EQUALS_INT("Length of request should be 1", app->request_list->count, 1); error = ASSERT_EQUALS_INT("request transaction number should equal", req->transaction_sequence_number, 1); - error = ASSERT_EQUALS_INT("souce id should equal 2", req->dest_cfdp_id, 2); + error = ASSERT_EQUALS_INT("source id should equal 2", req->dest_cfdp_id, 2); free(res); return error; } -static int test_process_pdu_header() { +static int test_process_pdu_header(FTP *app) { int error = 0; - FTP *app = init_ftp(1); - error = test_wrong_id(app); error = test_correct_id(app); - - app->close = true; - ssp_thread_join(app->server_handle); return error; } int protocol_handler_test() { int error = 0; - //error = test_process_pdu_header(); - //error = test_process_pdu_eof(); - - error = test_on_server_time_out(); + FTP *app = init_ftp(1); + error = test_process_pdu_header(app); + error = test_process_pdu_eof(); + //error = test_on_server_time_out(); + app->close = true; + ssp_thread_join(app->server_handle); return error; } \ No newline at end of file diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 21f1819..e68cf34 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -38,17 +38,17 @@ static int request_finding_test() { List *list = linked_list(); - Request *req = init_request(2000); + Request *req = mock_empty_request(); req->dest_cfdp_id = 1; req->transaction_sequence_number = 1; list->push(list, req, req->dest_cfdp_id); - Request *req2 = init_request(2000); + Request *req2 = mock_empty_request(); req2->dest_cfdp_id = 3; req2->transaction_sequence_number = 1; list->push(list, req2, req2->dest_cfdp_id); - Request *req3 = init_request(2000); + Request *req3 = mock_empty_request(); req3->dest_cfdp_id = 2; req3->transaction_sequence_number = 2; list->push(list, req3, req3->dest_cfdp_id); @@ -83,19 +83,19 @@ static int request_finding_test() { static void request_test_list_storage() { - Request *req = init_request(5000); + Request *req = mock_empty_request(); List *list = linked_list(); req->file = create_file("testfile.txt", 0); memcpy(req->source_file_name, "stuff", 6); list->insert(list, req, 1); - Request *req2 = init_request(5000); + Request *req2 = mock_empty_request(); req2->file = create_file("testfile.txt", 0); memcpy(req2->source_file_name, "stuff2", 7); list->insert(list, req2, 2); - Request *req3 = init_request(5000); + Request *req3 = mock_empty_request(); req3->file = create_file("testfile.txt", 0); memcpy(req3->source_file_name, "stuff3", 7); list->insert(list, req3, 3); @@ -108,7 +108,7 @@ static void request_test_list_storage() { static int add_proxy_message() { - Request *req = init_request(5000); + Request *req = mock_empty_request(); char *dest = "dest"; char *src = "src"; @@ -133,7 +133,7 @@ static int add_proxy_message() { static int add_continue_partial_message() { int error = 0; - Request *req = init_request(5000); + Request *req = mock_empty_request(); uint32_t src_id = 1; uint32_t dest_id = 1; diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 6c1463c..18e7d36 100644 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -1,7 +1,7 @@ #include "unit_tests.h" #include -#include "server.h" +#include "posix_server_provider.h" #include "port.h" #include "tasks.h" diff --git a/Program/test/tasks_tests.c b/Program/test/tasks_tests.c index edbd4c2..742f349 100644 --- a/Program/test/tasks_tests.c +++ b/Program/test/tasks_tests.c @@ -18,11 +18,8 @@ void test_remove_request() { request->procedure = clean_up; //run a task here, or a removal function - - l->iterate(l, check_request_callback, NULL); l->free(l, ssp_cleanup_req); - } @@ -30,14 +27,8 @@ void test_remove_request() { int tasks_tests() { DECLARE_NEW_TEST("Tasks"); - test_remove_request(); - int error = 0; - - - - return error; } \ No newline at end of file diff --git a/Program/test/temp/pending_req_id:1:num:1.binary b/Program/test/temp/pending_req_id:1:num:1.binary new file mode 100644 index 0000000000000000000000000000000000000000..5ddffaa391597e2087fd6bbb0192e378203af0cf GIT binary patch literal 749 zcmZQzU|?VbVi17Q5Z)*`(nH{<%A`0@7*H!+2txx@V2yM53uXoeg%!@>*uof>I0G{S WTX9KgS{egaZhlcJgvrQAydVH6sTpek literal 0 HcmV?d00001 diff --git a/Program/test/temp/test_file_save b/Program/test/temp/test_file_save new file mode 100644 index 0000000000000000000000000000000000000000..0a8273adefcf1d71e05a1044fbcf3002778e7b3a GIT binary patch literal 56 acmZQzzzzg9IEOPsrG5eF6d(rCFbn`%$pxwa literal 0 HcmV?d00001 diff --git a/Program/test/test_files/empty.txt b/Program/test/test_files/empty.txt new file mode 100644 index 0000000..e69de29 diff --git a/Program/test/testfile b/Program/test/testfile index 3a62505..e69de29 100644 --- a/Program/test/testfile +++ b/Program/test/testfile @@ -1 +0,0 @@ -tempfileyo \ No newline at end of file diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index 9e227f0..d63cb25 100644 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -1,27 +1,27 @@ #ifndef SSP_UNIT_TEST_H #define SSP_UNIT_TEST_H - #include "types.h" - #include "test.h" +#include "types.h" +#include "test.h" - List *populate_request_list(); - //int tasks_tests(); - //int request_tests(); - //int test_header(char *packet, Pdu_header *header, uint64_t sequence_number); - int packet_tests(); - int protocol_handler_test(); - +int tasks_tests(); +int packet_tests(); +int protocol_handler_test(); +int list_tests(); +int file_system_tests(); +int request_tests(); +int protocol_handler_test(); - int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); - Response *mock_response(); +int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); +Response *mock_response(); File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *file_name); - Request *mock_request(); - int file_system_tests(); - int request_tests(); - - #define TEMP_FILESIZE 1000 +Request *mock_request(); +Request *mock_empty_request(); +List *populate_request_list(); - //int server_tests(int client ); +#define TEMP_FILESIZE 1000 + +//int server_tests(int client ); #endif \ No newline at end of file From 34f7a3610691f44614ac71fd1f5c6ea15bd203e5 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 23 May 2020 13:32:17 -0600 Subject: [PATCH 218/400] remove comments --- Program/test/packet_tests.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 55a266e..b4032c8 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -16,22 +16,6 @@ #define PACKET_TEST_SIZE 2000 -/* -typedef struct pdu_eof { - unsigned int condition_code : 4; - unsigned int spare : 4; - uint32_t checksum; - - uint32_t file_size; - - //Omitted if condition code is ‘No error’. Otherwise, entity ID in the - //TLV is the ID of the entity at which transaction cancellation was - //initiated. - TLV fault_location; - -} Pdu_eof; -*/ - static int test_build_eof_packet(char *packet, int packet_start) { DECLARE_NEW_TEST("testing eof_packet"); From 66744b7608665927880680d22fa7294fde38ed3a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 23 May 2020 13:55:48 -0600 Subject: [PATCH 219/400] add test support files --- .gitignore | 14 ++++++++++- Program/.gitignore | 5 ---- Program/src/mib/peer_3.json | 23 ++++++++++++++++++ Program/src/mib/peer_4.json | 23 ++++++++++++++++++ .../pending_req_id:1:num:1.binary | Bin 0 -> 745 bytes Program/test/test_files/testfile | 1 + Program/test/testestest | 0 Program/test/testfile | 0 8 files changed, 60 insertions(+), 6 deletions(-) delete mode 100644 Program/.gitignore create mode 100644 Program/src/mib/peer_3.json create mode 100644 Program/src/mib/peer_4.json create mode 100644 Program/test/incomplete_requests/pending_req_id:1:num:1.binary create mode 100644 Program/test/test_files/testfile delete mode 100644 Program/test/testestest delete mode 100644 Program/test/testfile diff --git a/.gitignore b/.gitignore index f0a1c07..dd2194f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,16 @@ Program/src/*.o Documents main settings.json -SpaceProjects.odt \ No newline at end of file +SpaceProjects.odt +Program/src/incomplete_requests +Program/src/obj + +*.o +*.a +TODO +Program/FreeRTOSv10.2.1 +Program/libcsp +.vscode* +*.jpg +*.jpeg +.gitignore diff --git a/Program/.gitignore b/Program/.gitignore deleted file mode 100644 index 8110d87..0000000 --- a/Program/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -*.o -*.a -TODO -FreeRTOSv10.2.1 -libcsp \ No newline at end of file diff --git a/Program/src/mib/peer_3.json b/Program/src/mib/peer_3.json new file mode 100644 index 0000000..daed8d0 --- /dev/null +++ b/Program/src/mib/peer_3.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 3, + "UT_address" : 2130706433, + "UT_port" : 1113, + "type_of_network" : 0, + "default_transmission_mode" : 1, + "MTU" : 1500, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/src/mib/peer_4.json b/Program/src/mib/peer_4.json new file mode 100644 index 0000000..8b31a83 --- /dev/null +++ b/Program/src/mib/peer_4.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 4, + "UT_address" : 2130706433, + "UT_port" : 1114, + "type_of_network" : 0, + "default_transmission_mode" : 1, + "MTU" : 1500, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/incomplete_requests/pending_req_id:1:num:1.binary b/Program/test/incomplete_requests/pending_req_id:1:num:1.binary new file mode 100644 index 0000000000000000000000000000000000000000..fc8dcb0a72820c67deb154dff52562871bd35133 GIT binary patch literal 745 zcmZQzU|?VbVi17Q5Z)*`8UoY{0b!_74llNaftk(QAvCd8Ff*_fmz1WZF>vMP7o|d& JjEuw!0ss}2790Qo literal 0 HcmV?d00001 diff --git a/Program/test/test_files/testfile b/Program/test/test_files/testfile new file mode 100644 index 0000000..184be45 --- /dev/null +++ b/Program/test/test_files/testfile @@ -0,0 +1 @@ +testfileyo \ No newline at end of file diff --git a/Program/test/testestest b/Program/test/testestest deleted file mode 100644 index e69de29..0000000 diff --git a/Program/test/testfile b/Program/test/testfile deleted file mode 100644 index e69de29..0000000 From 6792a928386de3a9b5a5a7bdbbb3714d7653fb1d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 23 May 2020 14:04:04 -0600 Subject: [PATCH 220/400] add to git ignore --- .gitignore | 1 - Documents/mib.txt | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 Documents/mib.txt diff --git a/.gitignore b/.gitignore index dd2194f..07c1777 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ Program/src/*.o -Documents main settings.json SpaceProjects.odt diff --git a/Documents/mib.txt b/Documents/mib.txt new file mode 100644 index 0000000..63de342 --- /dev/null +++ b/Documents/mib.txt @@ -0,0 +1,64 @@ +The MIB is known as the management information base. +This base holds the configuration information for users (peers or applications). +This data is used for determining how and who we can send file or commands +to. Files will not be sent to users that are not included in the MIB. + +The MIB is currently configured as key value pairs. These pairs are formatted +in the JSON format. + +Here is an example of a MIB entry: +{ + "cfdp_id": 1, + "UT_address" : 2130706433, + "UT_port" : 1111, + "type_of_network" : 1, + "default_transmission_mode" : 1, + "MTU" : 1500, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} + + +Below are the meanings of the fields for the MIB + +cfdp_id + This is the unique identifier of a peer on the network. We can start it at 1 + and increment it from there. This is an unsigned integer (32 bit) value; + + +UT_address + This is an Underlying Transmission address. For example, in an IP stack, this + would be an IP4 Ip address. This value is a decimal represenstation of an IP + address. This particular one is 127.0.0.1. + + +UT_port + This os an Underlying Transmission port. For example, in an IP stack, this + would be a 16 bit value -- like port 8080. Combinded with the UT_address, + together they form a complete UT address. The one above would be equal to + 127.0.0.1:1111. This is an unsigned integer (16 bit) value + +type_of_network + This number represents what type of network the underlying UT address takes. + currently, the only acceptable values are 0 and 1. + + +default_transmission_mode: + not implmented + +MTU + This number represents the 'maximum transmissable unit' -- this will also + take the form of a buffer in the program. This value is the maximum size + packet that the application will receive. From 471f0a953b4fede439eafdfaa26c96263970243b Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 23 May 2020 14:44:22 -0600 Subject: [PATCH 221/400] make sure it works on first go --- Program/include/port.h | 7 +++++-- Program/src/file_delivery_app.c | 17 ++++++++++------- Program/src/filesystem_funcs.c | 2 +- Program/src/main.c | 4 ++-- Program/src/makefile | 5 +++-- Program/src/port.c | 3 ++- Program/src/posix_server_provider.c | 6 +++--- Program/src/protocol_handler.c | 16 ++++++++-------- Program/src/requests.c | 10 +++++----- Program/src/tasks.c | 4 ++-- Program/test/list_tests.c | 4 ++-- Program/test/mock.c | 6 +++--- Program/test/packet_tests.c | 26 +++++++++++++------------- Program/test/request_tests.c | 6 +++--- Program/test/udpClient.c | 2 +- 15 files changed, 63 insertions(+), 55 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 189ab98..2ec8402 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -11,8 +11,8 @@ Author: Evan Giese #define POSIX_PORT #define POSIX_FILESYSTEM -#define CSP_NETWORK -*/ +//#define CSP_NETWORK + #include "types.h" #ifdef CSP_NETWORK @@ -43,6 +43,9 @@ Author: Evan Giese #define ssp_htons htons #define ssp_stonl stonl + #include + #define ssp_memcpy memcpy + #include #define ssp_snprintf snprintf diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 082dffe..6d5ccd5 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -55,16 +55,19 @@ FTP *init_ftp(uint32_t my_cfdp_address) { if (remote_entity.type_of_network == csp) { - ssp_printf("Initialising CSP\r\n"); + #ifdef CSP_NETWORK + ssp_printf("Initialising CSP\r\n"); - /* Init CSP with address MY_ADDRESS */ - csp_init(remote_entity.UT_address); + /* Init CSP with address MY_ADDRESS */ + csp_init(remote_entity.UT_address); - /* Init buffer system with 10 packets of maximum PACKET_LEN bytes each */ - csp_buffer_init(10, remote_entity.mtu); + /* Init buffer system with 10 packets of maximum PACKET_LEN bytes each */ + csp_buffer_init(10, remote_entity.mtu); - /* Start router task with 500 word stack, OS task priority 1 */ - csp_route_start_task(500, 1); + /* Start router task with 500 word stack, OS task priority 1 */ + csp_route_start_task(500, 1); + + #endif } FTP *app = ssp_alloc(sizeof(FTP), 1); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 58c189a..cea7598 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -435,7 +435,7 @@ int get_file_from_file(int fd, File *file) { return -1; } - memcpy(new_offset, &offset, sizeof(Offset)); + ssp_memcpy(new_offset, &offset, sizeof(Offset)); missing_offsets->push(missing_offsets, new_offset, -1); } diff --git a/Program/src/main.c b/Program/src/main.c index e02f830..eae74e4 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -126,10 +126,10 @@ int main(int argc, char** argv) { //create a client if (conf->client_cfdp_id != 0){ - start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); + start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", UN_ACKNOWLEDGED_MODE, app)); //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy3.jpg", UN_ACKNOWLEDGED_MODE, app)); - Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/tcp.jpg", ACKNOWLEDGED_MODE, app); + Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpg", "pictures/tcp.jpg", ACKNOWLEDGED_MODE, app); start_request(req); } diff --git a/Program/src/makefile b/Program/src/makefile index ea840cc..a37d93b 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -29,7 +29,7 @@ CFILES += file_delivery_app.c CFILES += utils.c CFILES += tasks.c CFILES += posix_server_provider.c #used for poxix port -CFILES += csp_server_provider.c +#CFILES += csp_server_provider.c CFILES += protocol_handler.c CFILES += mib.c CFILES += filesystem_funcs.c @@ -67,7 +67,8 @@ CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = LIBS = -pthread -STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a +STATIC_FILES = +#STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a #---------------------------Compiler flags--------------------------- diff --git a/Program/src/port.c b/Program/src/port.c index 7e6ce3b..0193176 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -14,6 +14,7 @@ Author: Evan Giese #include #include #include + #include #endif #ifdef POSIX_FILESYSTEM @@ -92,7 +93,7 @@ void ssp_sendto(Response res) { if (csp_buffer_remaining() != 0) { packet_sending = csp_buffer_get(1); - memcpy(packet_sending->data, res.msg, res.packet_len); + ssp_memcpy(packet_sending->data, res.msg, res.packet_len); int err = csp_sendto(0, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 10); if (err < 0) { diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index b2b6de9..2c2a513 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -123,7 +123,7 @@ static int prepareHost(char *host_name, void *addr, size_t *size_of_addr, char * } } - memcpy(addr, cur->ai_addr, cur->ai_addrlen); + ssp_memcpy(addr, cur->ai_addr, cur->ai_addrlen); *size_of_addr = cur->ai_addrlen; freeaddrinfo(cur); @@ -231,7 +231,7 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c break; } - memcpy(read_socket_set, socket_set, size_of_socket_struct); + ssp_memcpy(read_socket_set, socket_set, size_of_socket_struct); int nrdy = ssp_select(connection_limit + 1, read_socket_set, NULL, NULL, 100e3); if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ @@ -351,7 +351,7 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, break; } - memcpy(read_socket_set, socket_set, size_of_socket_struct); + ssp_memcpy(read_socket_set, socket_set, size_of_socket_struct); int nrdy = ssp_select(sfd + 1, read_socket_set, NULL, NULL, 100e3); if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 45e6c81..c26efd7 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -113,7 +113,7 @@ static int find_request(void *element, void *args) { return NULL; } - memcpy(found_req->res.addr, res.addr, res.size_of_addr); + ssp_memcpy(found_req->res.addr, res.addr, res.size_of_addr); found_req->res.packet_len = remote_entity.mtu; found_req->res.sfd = res.sfd; @@ -135,16 +135,16 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r Pdu_header *header = (Pdu_header *) packet; uint32_t source_id = 0; - memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); + ssp_memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; //TODO the transaction number should get the request from data structure hosting requests uint32_t transaction_sequence_number = 0; - memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); + ssp_memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); packet_index += header->transaction_seq_num_len; uint32_t dest_id = 0; - memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); + ssp_memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); packet_index += header->length_of_entity_IDs; if (app->my_cfdp_id != dest_id){ @@ -246,12 +246,12 @@ uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) uint8_t file_name_len = meta_data_packet[packet_index]; packet_index++; - memcpy(req_to_fill->source_file_name, &meta_data_packet[packet_index], file_name_len); + ssp_memcpy(req_to_fill->source_file_name, &meta_data_packet[packet_index], file_name_len); packet_index += file_name_len; file_name_len = meta_data_packet[packet_index]; packet_index++; - memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); + ssp_memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); packet_index += file_name_len; @@ -359,10 +359,10 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien for (int i = 0; i < segments; i++){ //outgoing_packet_index - memcpy(&offset_start, &packet[packet_index], 4); + ssp_memcpy(&offset_start, &packet[packet_index], 4); offset_start = ssp_ntohl(offset_start); packet_index += 4; - memcpy(&offset_end, &packet[packet_index], 4); + ssp_memcpy(&offset_end, &packet[packet_index], 4); offset_end = ssp_ntohl(offset_end); packet_index += 4; build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); diff --git a/Program/src/requests.c b/Program/src/requests.c index a0c1e0b..eddcc84 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -24,7 +24,7 @@ uint16_t copy_lv_to_buffer(char *buffer, LV lv){ uint16_t packet_index = 0; buffer[packet_index] = lv.length; packet_index++; - memcpy(&buffer[packet_index], lv.value, lv.length); + ssp_memcpy(&buffer[packet_index], lv.value, lv.length); packet_index += lv.length; return packet_index; } @@ -36,7 +36,7 @@ void free_lv(LV lv) { void create_lv(LV *lv, int len, void *value) { lv->value = ssp_alloc(len, sizeof(char)); - memcpy(lv->value, value, len); + ssp_memcpy(lv->value, value, len); lv->length = len; } @@ -56,7 +56,7 @@ Message *create_message(uint8_t type) { return NULL; //message->header.message_id_cfdp = ssp_alloc(5, sizeof(char)); - memcpy(message->header.message_id_cfdp, "cfdp", 5); + ssp_memcpy(message->header.message_id_cfdp, "cfdp", 5); message->header.message_type = type; return message; } @@ -319,8 +319,8 @@ Request *put_request( req->transmission_mode = transmission_mode; req->procedure = sending_start; - memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); - memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + ssp_memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); return req; } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 77e5b9a..8d23043 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -279,11 +279,11 @@ static int on_stdin_callback(void *other) { ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); return 0; } - memcpy(app->newClient->req->source_file_name, input, MAX_PATH); + ssp_memcpy(app->newClient->req->source_file_name, input, MAX_PATH); ssp_printf("Enter a destination file name:\n"); } else if (strnlen(req->destination_file_name, MAX_PATH) == 0){ - memcpy(app->newClient->req->destination_file_name, input, MAX_PATH); + ssp_memcpy(app->newClient->req->destination_file_name, input, MAX_PATH); ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", app->newClient->req->source_file_name, app->newClient->req->destination_file_name, app->newClient->cfdp_id); ssp_printf("cancel connection mode (yes):\n"); } diff --git a/Program/test/list_tests.c b/Program/test/list_tests.c index 3d4e2d0..e3ab60e 100644 --- a/Program/test/list_tests.c +++ b/Program/test/list_tests.c @@ -65,8 +65,8 @@ int list_tests() { Request *r = mock_empty_request(); Request *r2 = mock_empty_request(); - memcpy(r->source_file_name, "mybestfriend", 12); - memcpy(r2->source_file_name, "secondrequest", 12); + ssp_memcpy(r->source_file_name, "mybestfriend", 12); + ssp_memcpy(r2->source_file_name, "secondrequest", 12); list->push(list, r, 1); ASSERT_EQUALS_INT("should equal 1", 1, list->count); diff --git a/Program/test/mock.c b/Program/test/mock.c index 0e7c31e..21317c2 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -93,8 +93,8 @@ Request *mock_request() { req->dest_cfdp_id = id; req->file = create_file("test_files/dest_received.jpg", true); - memcpy (req->source_file_name, dest, strnlen(dest, 255)); - memcpy (req->destination_file_name, src, strnlen(src, 255)); + ssp_memcpy (req->source_file_name, dest, strnlen(dest, 255)); + ssp_memcpy (req->destination_file_name, src, strnlen(src, 255)); mock_mock_remote_entity(&req->remote_entity, id); @@ -102,7 +102,7 @@ Request *mock_request() { int addr = 16; req->res.addr = malloc(5); - memcpy(req->res.addr, &addr, 4); + ssp_memcpy(req->res.addr, &addr, 4); req->res.sfd = 1; req->res.packet_len = 2000; req->res.size_of_addr = 16; diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index b4032c8..04096ee 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -81,8 +81,8 @@ static int test_build_nak_packet(char* packet, uint32_t start) { Request *req = mock_empty_request(); req->file_size = 100000; - memcpy(req->destination_file_name, "testestest", 15); - memcpy(req->source_file_name, "someotherfile", 15); + ssp_memcpy(req->destination_file_name, "testestest", 15); + ssp_memcpy(req->source_file_name, "someotherfile", 15); process_file_request_metadata(req); @@ -106,7 +106,7 @@ static int test_build_nak_packet(char* packet, uint32_t start) { ASSERT_EQUALS_INT("number of segments == 1 ", number_of_segments, 1); Offset offset[count]; - memcpy(offset, &nak->segments, sizeof(Offset) * count); + ssp_memcpy(offset, &nak->segments, sizeof(Offset) * count); start_scope = ntohl(offset->start); end_scope = ntohl(offset->end); @@ -132,37 +132,37 @@ static int test_build_nak_packet(char* packet, uint32_t start) { packet_index += 16; //outgoing_packet_index - memcpy(&start_scope, &packet[packet_index], 4); + ssp_memcpy(&start_scope, &packet[packet_index], 4); start_scope = ntohl(start_scope); packet_index += 4; - memcpy(&end_scope, &packet[packet_index], 4); + ssp_memcpy(&end_scope, &packet[packet_index], 4); end_scope = ntohl(end_scope); packet_index += 4; ASSERT_EQUALS_INT("correct packet offset 0 start", start_scope, 0); ASSERT_EQUALS_INT("correct packet offset 0 end", end_scope, 1250); - memcpy(&start_scope, &packet[packet_index], 4); + ssp_memcpy(&start_scope, &packet[packet_index], 4); start_scope = ntohl(start_scope); packet_index += 4; - memcpy(&end_scope, &packet[packet_index], 4); + ssp_memcpy(&end_scope, &packet[packet_index], 4); end_scope = ntohl(end_scope); packet_index += 4; ASSERT_EQUALS_INT("correct packet offset 1 start", start_scope, 5000); ASSERT_EQUALS_INT("correct packet offset 1 end", end_scope, 6000); - memcpy(&start_scope, &packet[packet_index], 4); + ssp_memcpy(&start_scope, &packet[packet_index], 4); start_scope = ntohl(start_scope); packet_index += 4; - memcpy(&end_scope, &packet[packet_index], 4); + ssp_memcpy(&end_scope, &packet[packet_index], 4); end_scope = ntohl(end_scope); packet_index += 4; ASSERT_EQUALS_INT("correct packet offset 2 start", start_scope, 9000); ASSERT_EQUALS_INT("correct packet offset 2 end", end_scope, 10000); - memcpy(&start_scope, &packet[packet_index], 4); + ssp_memcpy(&start_scope, &packet[packet_index], 4); start_scope = ntohl(start_scope); packet_index += 4; - memcpy(&end_scope, &packet[packet_index], 4); + ssp_memcpy(&end_scope, &packet[packet_index], 4); end_scope = ntohl(end_scope); packet_index += 4; ASSERT_EQUALS_INT("correct packet offset 3 start", start_scope, 15000); @@ -270,8 +270,8 @@ int test_build_metadata_packet(char *packet, uint32_t start) { char *str = "HELLO WORLD"; - memcpy(req->destination_file_name, str, strnlen(str, MAX_PATH) ); - memcpy(req->source_file_name, str, strnlen(str, MAX_PATH) ); + ssp_memcpy(req->destination_file_name, str, strnlen(str, MAX_PATH) ); + ssp_memcpy(req->source_file_name, str, strnlen(str, MAX_PATH) ); len = build_put_packet_metadata(packet, start, req); fill_request_pdu_metadata(&packet[start + 1], recv_request); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index e68cf34..2ffb130 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -87,17 +87,17 @@ static void request_test_list_storage() { List *list = linked_list(); req->file = create_file("testfile.txt", 0); - memcpy(req->source_file_name, "stuff", 6); + ssp_memcpy(req->source_file_name, "stuff", 6); list->insert(list, req, 1); Request *req2 = mock_empty_request(); req2->file = create_file("testfile.txt", 0); - memcpy(req2->source_file_name, "stuff2", 7); + ssp_memcpy(req2->source_file_name, "stuff2", 7); list->insert(list, req2, 2); Request *req3 = mock_empty_request(); req3->file = create_file("testfile.txt", 0); - memcpy(req3->source_file_name, "stuff3", 7); + ssp_memcpy(req3->source_file_name, "stuff3", 7); list->insert(list, req3, 3); ssp_cleanup_req(list->pop(list)); diff --git a/Program/test/udpClient.c b/Program/test/udpClient.c index 87a6779..373acfe 100644 --- a/Program/test/udpClient.c +++ b/Program/test/udpClient.c @@ -59,7 +59,7 @@ int main(int argc, char **argv) { int msg = "some stuff to send"; /* get a message from the user */ - memcpy(buf, msg, strnlen(msg, BUFSIZE)); + ssp_memcpy(buf, msg, strnlen(msg, BUFSIZE)); for (;;) { //bzero(buf, BUFSIZE); //printf("Please enter msg: "); From 6b9190f8319b2fc36a9e734167f2963261b74881 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 25 May 2020 09:16:41 -0600 Subject: [PATCH 222/400] update readme --- Program/src/makefile | 1 + README.md | 164 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 159 insertions(+), 6 deletions(-) diff --git a/Program/src/makefile b/Program/src/makefile index a37d93b..3e12590 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -69,6 +69,7 @@ LINKFLAGS = LIBS = -pthread STATIC_FILES = #STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a +#STATIC_FILES += $(PROJDIR)/FreeRtos #---------------------------Compiler flags--------------------------- diff --git a/README.md b/README.md index b756cd0..00e1560 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,168 @@ This is not finished! - currently working on it! This is a FTP protocol that adheres to the CCSDS (Consultative Committee for Space Data Systems) spec for sending files into space. This project is being built for a student lead space initiative at the Univerity of Alberta called ABsat. -I want to eventually make it opensource, but there is a lot of work to do before it is in any condition for use. +Supported operation systems: + - Posix, + - FREE-RTOS -if you want to get in contact with me -email me at evangiese77@gmail.com +Supported network stacks: + - tcp + - udp + - csp (cube sate protocol) + - generic (other, including no network at all!) + + +#Compilation Notes: + +If you are compiling on linux, it should compile posix compliant by default. + +###Compiling CSP: + first, one needs to build the .a file for your specific cpu architecture. + instructions can be found here. https://github.com/libcsp/libcsp + + archive file: + Once one has the .a file. simply link to it my adding the path to + STATIC_FILES in our makefile: STATIC_FILES += /path/to/libcsp.a + + .h files: + We need to include the .h files to our include path. We can do this + by linking the .h files to our INCLUDES in our makefile. + INCLUDES += /path/to/libcsp/include + + The last thing you need to do to let this app integrate seemlessly with csp, + is to make sure that CSP_NETWORK is defined in port.h + + run make to compile! + +###Compiling with FreeRTOS: + The best way to compile with FreeRTOS is to do the same thing as we did + with libscp -- create a .a file, and link to the .h files. + + There are examples to help you with linking in the makefile. + + Once again, make sure that FREE_RTOS_PORT is definted in port.h + and that POSIX_PORT is not defined. + + +#Getting started: + + The app has some startup requirements. init the app with: + + FTP *app = init_ftp(my_cfdp_id); + if (app == NULL) { + return 1; + } + + this will spin up a thread in posix, or a task in FreeRTOS. + if you want to join this thread (make the current executing thread wait) + and it is a posix thread you can run: + ssp_thread_join(app->server_handle); + + if you want to exit this task for any reason set app->close = 1; + this will run the exiting subroutines for us. + + if you wish to send a file to a peer: + + params: + id of destination, + source file name, + name of the file as it will arrive at destination, + ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + app. + + example: + Request *req = put_request(, "pictures/src.jpg", "pictures/desination.jpg", ACKNOWLEDGED_MODE, app); + start_request(req); + + + if you wish to get a file from a peer, we need to add a 'message' onto a put request, + we can specify that there is no associated put request if we set the filenames to NULL: + params: + id of destination, + source file name, + name of the file as it will arrive at destination, + ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + app. + example: -Compilation Notes: - for compiling with free rtos, first we need to specifiy the locatifon of the free RTOS header files that we need within - our makefile. Then we can compile our .a file. To use this file, just staticly link to the file_delivery_app.a. + Request *req = put_request(, NULL, NULL, ACKNOWLEDGED_MODE, app); + add_proxy_message_to_request(, , "source_file_name" "destination_file_name", req); + start_request(req); + + hint, if you want to 'get' a file, set the to your id. + + +#MIB (management information base) + +This base holds the configuration information for users (peers or applications). +This data is used for determining how and who we can send file or commands +to. Files will not be sent to users that are not included in the MIB. + +The MIB is currently configured as key value pairs. These pairs are formatted +in the JSON format, the name of the file is peer_. + +Here is an example of a MIB entry: +{ + "cfdp_id": 1, + "UT_address" : 2130706433, + "UT_port" : 1111, + "type_of_network" : 1, + "default_transmission_mode" : 1, + "MTU" : 1500, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} + + +Below are the meanings of the fields for the MIB + +cfdp_id + This is the unique identifier of a peer on the network. We can start it at 1 + and increment it from there. This is an unsigned integer (32 bit) value; + + +UT_address + This is an Underlying Transmission address. For example, in an IP stack, this + would be an IP4 Ip address. This value is a decimal represenstation of an IP + address. This particular one is 127.0.0.1. + + +UT_port + This os an Underlying Transmission port. For example, in an IP stack, this + would be a 16 bit value -- like port 8080. Combinded with the UT_address, + together they form a complete UT address. The one above would be equal to + 127.0.0.1:1111. This is an unsigned integer (16 bit) value + +type_of_network + This number represents what type of network the underlying UT address takes. + currently, the only acceptable values are 0 and 1. + +default_transmission_mode: + not implmented + +MTU + This number represents the 'maximum transmissable unit' -- this will also + take the form of a buffer in the program. This value is the maximum size + packet that the application will receive. + + + +if you want to get in contact with me +email me at evangiese77@gmail.com From e372824fbbc8c986950444b372628361708148bc Mon Sep 17 00:00:00 2001 From: Evan G Date: Mon, 25 May 2020 09:24:05 -0600 Subject: [PATCH 223/400] Update README.md --- README.md | 110 +++++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 00e1560..cd6644c 100644 --- a/README.md +++ b/README.md @@ -3,73 +3,73 @@ This is not finished! - currently working on it! This is a FTP protocol that adheres to the CCSDS (Consultative Committee for Space Data Systems) spec for sending files into space. This project is being built for a student lead space initiative at the Univerity of Alberta called ABsat. Supported operation systems: - - Posix, - - FREE-RTOS +- Posix, +- FREE-RTOS Supported network stacks: - - tcp - - udp - - csp (cube sate protocol) - - generic (other, including no network at all!) +- tcp +- udp +- csp (cube sate protocol) +- generic (other, including no network at all!) -#Compilation Notes: +# Compilation Notes: If you are compiling on linux, it should compile posix compliant by default. -###Compiling CSP: - first, one needs to build the .a file for your specific cpu architecture. - instructions can be found here. https://github.com/libcsp/libcsp +### Compiling CSP: +first, one needs to build the .a file for your specific cpu architecture. +instructions can be found here. https://github.com/libcsp/libcsp - archive file: - Once one has the .a file. simply link to it my adding the path to - STATIC_FILES in our makefile: STATIC_FILES += /path/to/libcsp.a +archive file: +Once one has the .a file. simply link to it my adding the path to +STATIC_FILES in our makefile: STATIC_FILES += /path/to/libcsp.a - .h files: - We need to include the .h files to our include path. We can do this - by linking the .h files to our INCLUDES in our makefile. - INCLUDES += /path/to/libcsp/include +.h files: +We need to include the .h files to our include path. We can do this +by linking the .h files to our INCLUDES in our makefile. +INCLUDES += /path/to/libcsp/include - The last thing you need to do to let this app integrate seemlessly with csp, - is to make sure that CSP_NETWORK is defined in port.h +The last thing you need to do to let this app integrate seemlessly with csp, +is to make sure that CSP_NETWORK is defined in port.h - run make to compile! +run make to compile! -###Compiling with FreeRTOS: - The best way to compile with FreeRTOS is to do the same thing as we did - with libscp -- create a .a file, and link to the .h files. +### Compiling with FreeRTOS: +The best way to compile with FreeRTOS is to do the same thing as we did +with libscp -- create a .a file, and link to the .h files. - There are examples to help you with linking in the makefile. +There are examples to help you with linking in the makefile. - Once again, make sure that FREE_RTOS_PORT is definted in port.h - and that POSIX_PORT is not defined. +Once again, make sure that FREE_RTOS_PORT is definted in port.h +and that POSIX_PORT is not defined. -#Getting started: +# Getting started: + +The app has some startup requirements. init the app with: - The app has some startup requirements. init the app with: - FTP *app = init_ftp(my_cfdp_id); if (app == NULL) { return 1; } - - this will spin up a thread in posix, or a task in FreeRTOS. - if you want to join this thread (make the current executing thread wait) - and it is a posix thread you can run: - ssp_thread_join(app->server_handle); - if you want to exit this task for any reason set app->close = 1; - this will run the exiting subroutines for us. +this will spin up a thread in posix, or a task in FreeRTOS. +if you want to join this thread (make the current executing thread wait) +and it is a posix thread you can run: +ssp_thread_join(app->server_handle); - if you wish to send a file to a peer: +if you want to exit this task for any reason set app->close = 1; +this will run the exiting subroutines for us. - params: - id of destination, - source file name, - name of the file as it will arrive at destination, - ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), - app. +if you wish to send a file to a peer: + +params: +id of destination, +source file name, +name of the file as it will arrive at destination, +ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), +app. example: Request *req = put_request(, "pictures/src.jpg", "pictures/desination.jpg", ACKNOWLEDGED_MODE, app); @@ -77,17 +77,17 @@ If you are compiling on linux, it should compile posix compliant by default. start_request(req); - if you wish to get a file from a peer, we need to add a 'message' onto a put request, - we can specify that there is no associated put request if we set the filenames to NULL: +if you wish to get a file from a peer, we need to add a 'message' onto a put request, +we can specify that there is no associated put request if we set the filenames to NULL: - params: - id of destination, - source file name, - name of the file as it will arrive at destination, - ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), - app. +params: +id of destination, +source file name, +name of the file as it will arrive at destination, +ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), +app. - example: +example: Request *req = put_request(, NULL, NULL, ACKNOWLEDGED_MODE, app); @@ -98,7 +98,7 @@ If you are compiling on linux, it should compile posix compliant by default. hint, if you want to 'get' a file, set the to your id. -#MIB (management information base) +# MIB (management information base) This base holds the configuration information for users (peers or applications). This data is used for determining how and who we can send file or commands @@ -108,7 +108,7 @@ The MIB is currently configured as key value pairs. These pairs are formatted in the JSON format, the name of the file is peer_. Here is an example of a MIB entry: -{ + { "cfdp_id": 1, "UT_address" : 2130706433, "UT_port" : 1111, @@ -129,7 +129,7 @@ Here is an example of a MIB entry: "positive_ack_timer_expiration_limit" : 123, "nak_timer_expiration_limit" : 123, "transaction_inactivity_limit" : 123 -} + } Below are the meanings of the fields for the MIB From ee85354abcd0360ea91abcbfc86bea6f325baf7e Mon Sep 17 00:00:00 2001 From: Evan G Date: Mon, 25 May 2020 09:26:19 -0600 Subject: [PATCH 224/400] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cd6644c..f086812 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,10 @@ If you are compiling on linux, it should compile posix compliant by default. ### Compiling CSP: first, one needs to build the .a file for your specific cpu architecture. -instructions can be found here. https://github.com/libcsp/libcsp +instructions can be found here: https://github.com/libcsp/libcsp archive file: -Once one has the .a file. simply link to it my adding the path to +Once one has the .a file by following the above instructions. simply link to it my adding the path to STATIC_FILES in our makefile: STATIC_FILES += /path/to/libcsp.a .h files: @@ -44,6 +44,7 @@ There are examples to help you with linking in the makefile. Once again, make sure that FREE_RTOS_PORT is definted in port.h and that POSIX_PORT is not defined. +run make to compile! # Getting started: From cc962b226ae848195785efd2538d95132eb86b9b Mon Sep 17 00:00:00 2001 From: Evan G Date: Mon, 25 May 2020 09:29:53 -0600 Subject: [PATCH 225/400] Update README.md --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f086812..26e84af 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,11 @@ The app has some startup requirements. init the app with: } this will spin up a thread in posix, or a task in FreeRTOS. -if you want to join this thread (make the current executing thread wait) -and it is a posix thread you can run: +if you want to join this thread, and it is a posix thread, you can run: ssp_thread_join(app->server_handle); if you want to exit this task for any reason set app->close = 1; -this will run the exiting subroutines for us. +this will run the exiting subroutines and close the task if it is a FreeRTOS task. if you wish to send a file to a peer: @@ -72,9 +71,9 @@ name of the file as it will arrive at destination, ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), app. - example: - Request *req = put_request(, "pictures/src.jpg", "pictures/desination.jpg", ACKNOWLEDGED_MODE, app); +example: + Request *req = put_request(, "pictures/src.jpg", "pictures/desination.jpg", ACKNOWLEDGED_MODE, app); start_request(req); @@ -96,8 +95,7 @@ example: start_request(req); - hint, if you want to 'get' a file, set the to your id. - +hint, if you want to 'get' a file, set the to your id. # MIB (management information base) @@ -109,6 +107,7 @@ The MIB is currently configured as key value pairs. These pairs are formatted in the JSON format, the name of the file is peer_. Here is an example of a MIB entry: + { "cfdp_id": 1, "UT_address" : 2130706433, @@ -116,7 +115,6 @@ Here is an example of a MIB entry: "type_of_network" : 1, "default_transmission_mode" : 1, "MTU" : 1500, - "one_way_light_time" : 123, "total_round_trip_allowance" : 123, "async_NAK_interval" : 123, From 72363858e5d68cb2fac22318f857107bf715dd98 Mon Sep 17 00:00:00 2001 From: Evan G Date: Mon, 25 May 2020 09:32:46 -0600 Subject: [PATCH 226/400] Update README.md --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 26e84af..613dbbd 100644 --- a/README.md +++ b/README.md @@ -133,31 +133,32 @@ Here is an example of a MIB entry: Below are the meanings of the fields for the MIB -cfdp_id +- cfdp_id This is the unique identifier of a peer on the network. We can start it at 1 and increment it from there. This is an unsigned integer (32 bit) value; - -UT_address +- UT_address This is an Underlying Transmission address. For example, in an IP stack, this would be an IP4 Ip address. This value is a decimal represenstation of an IP address. This particular one is 127.0.0.1. - -UT_port +- UT_port This os an Underlying Transmission port. For example, in an IP stack, this would be a 16 bit value -- like port 8080. Combinded with the UT_address, together they form a complete UT address. The one above would be equal to 127.0.0.1:1111. This is an unsigned integer (16 bit) value -type_of_network +- type_of_network This number represents what type of network the underlying UT address takes. - currently, the only acceptable values are 0 and 1. + currently, the only acceptable values are 0 and 1. + - 0: UDP + - 1: TCP + - 2: csp -default_transmission_mode: +- default_transmission_mode: not implmented -MTU +- MTU This number represents the 'maximum transmissable unit' -- this will also take the form of a buffer in the program. This value is the maximum size packet that the application will receive. From c4dacb0a3cd901a38c55a35605b870e2c837e8d4 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 26 May 2020 09:39:33 -0600 Subject: [PATCH 227/400] update readme --- README.md | 64 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 613dbbd..e8709bf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,17 @@ This is not finished! - currently working on it! -This is a FTP protocol that adheres to the CCSDS (Consultative Committee for Space Data Systems) spec for sending files into space. This project is being built for a student lead space initiative at the Univerity of Alberta called ABsat. +This is a FTP protocol that is partially (mostly) adheres to the CCSDS (Consultative Committee for Space Data Systems) spec for sending files into space CCSDS 727.0-B-4 (https://public.ccsds.org/pubs/727x0b4.pdf). This project is being built for a student lead space initiative at the Univerity of Alberta called ABsat. + + The main difference this implementation offers that has deviates from the above + specifications is that this implementation offers a metadata nak (non acknowledgment) + letting the file sender user quickly resend a metadata packet if it was dropped, + Since metadata packets are crucial to file management, and round trip times + can range to minutes or hours in space, I thought it prudent to handle + this edge case. Furthermore, this implementation will build a + 'temporary file' if it has missed a metadata packet. This temporary file + will allow storage of data packets until a metadata packet is received, + allowing us to save minutes on data re-transmissions in the event a Metadata + packet is missed. Supported operation systems: - Posix, @@ -15,7 +26,7 @@ Supported network stacks: # Compilation Notes: -If you are compiling on linux, it should compile posix compliant by default. +If you are compiling on Linux, it should compile posix compliant by default. ### Compiling CSP: first, one needs to build the .a file for your specific cpu architecture. @@ -30,25 +41,26 @@ We need to include the .h files to our include path. We can do this by linking the .h files to our INCLUDES in our makefile. INCLUDES += /path/to/libcsp/include -The last thing you need to do to let this app integrate seemlessly with csp, -is to make sure that CSP_NETWORK is defined in port.h +The last thing you need to do to let this app integrate seamlessly with csp, +is to make sure that CSP_NETWORK is defined in port.h and csp_server_provider.c +is uncommented in the makefile. run make to compile! ### Compiling with FreeRTOS: The best way to compile with FreeRTOS is to do the same thing as we did -with libscp -- create a .a file, and link to the .h files. +with libscp -- create an .a file, and link to the .h files. There are examples to help you with linking in the makefile. -Once again, make sure that FREE_RTOS_PORT is definted in port.h +Once again, make sure that FREE_RTOS_PORT is defined in port.h and that POSIX_PORT is not defined. run make to compile! # Getting started: -The app has some startup requirements. init the app with: +init the app with: FTP *app = init_ftp(my_cfdp_id); if (app == NULL) { @@ -64,14 +76,14 @@ this will run the exiting subroutines and close the task if it is a FreeRTOS tas if you wish to send a file to a peer: -params: -id of destination, -source file name, -name of the file as it will arrive at destination, -ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), -app. +params: +id of destination, +source file name, +name of the file as it will arrive at destination, +ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), +app -example: +example: Request *req = put_request(, "pictures/src.jpg", "pictures/desination.jpg", ACKNOWLEDGED_MODE, app); start_request(req); @@ -91,7 +103,7 @@ example: Request *req = put_request(, NULL, NULL, ACKNOWLEDGED_MODE, app); - add_proxy_message_to_request(, , "source_file_name" "destination_file_name", req); + add_proxy_message_to_request(, , "source_file_name" "destination_file_name", req); start_request(req); @@ -139,12 +151,12 @@ Below are the meanings of the fields for the MIB - UT_address This is an Underlying Transmission address. For example, in an IP stack, this - would be an IP4 Ip address. This value is a decimal represenstation of an IP + would be an IP4 Ip address. This value is a decimal representation of an IP address. This particular one is 127.0.0.1. - UT_port This os an Underlying Transmission port. For example, in an IP stack, this - would be a 16 bit value -- like port 8080. Combinded with the UT_address, + would be a 16 bit value -- like port 8080. combined with the UT_address, together they form a complete UT address. The one above would be equal to 127.0.0.1:1111. This is an unsigned integer (16 bit) value @@ -156,14 +168,26 @@ Below are the meanings of the fields for the MIB - 2: csp - default_transmission_mode: - not implmented + not implemented - MTU - This number represents the 'maximum transmissable unit' -- this will also + This number represents the 'maximum transmissible unit' -- this will also take the form of a buffer in the program. This value is the maximum size packet that the application will receive. - +- one_way_light_time : not implemented +- total_round_trip_allowance : not implemented +- async_NAK_interval : not implemented +- async_keep_alive_interval : not implemented +- async_report_interval : not implemented +- immediate_nak_mode_enabled : not implemented +- prompt_transmission_interval : not implemented +- disposition_of_incomplete : not implemented +- CRC_required : not implemented +- keep_alive_discrepancy_limit : not implemented +- positive_ack_timer_expiration_limit : not implemented +- nak_timer_expiration_limit : not implemented +- transaction_inactivity_limit : not implemented if you want to get in contact with me email me at evangiese77@gmail.com From 5519db68bbf25c9ba5ed70b30ea5e79765fcfbaf Mon Sep 17 00:00:00 2001 From: Evan G Date: Tue, 26 May 2020 09:41:03 -0600 Subject: [PATCH 228/400] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8709bf..6d9f547 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ This is not finished! - currently working on it! This is a FTP protocol that is partially (mostly) adheres to the CCSDS (Consultative Committee for Space Data Systems) spec for sending files into space CCSDS 727.0-B-4 (https://public.ccsds.org/pubs/727x0b4.pdf). This project is being built for a student lead space initiative at the Univerity of Alberta called ABsat. The main difference this implementation offers that has deviates from the above - specifications is that this implementation offers a metadata nak (non acknowledgment) - letting the file sender user quickly resend a metadata packet if it was dropped, + specifications is that this implementation offers a metadata nak (non acknowledgment). + This Nak lets the file sender user quickly resend a metadata packet if it was dropped. Since metadata packets are crucial to file management, and round trip times can range to minutes or hours in space, I thought it prudent to handle this edge case. Furthermore, this implementation will build a From 3895daa6008d89c48dc30a4d92e0fcae529ac6b6 Mon Sep 17 00:00:00 2001 From: Evan G Date: Tue, 26 May 2020 09:41:43 -0600 Subject: [PATCH 229/400] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d9f547..f96a73b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This is a FTP protocol that is partially (mostly) adheres to the CCSDS (Consulta this edge case. Furthermore, this implementation will build a 'temporary file' if it has missed a metadata packet. This temporary file will allow storage of data packets until a metadata packet is received, - allowing us to save minutes on data re-transmissions in the event a Metadata + allowing us to save minutes on data re-transmissions in the event a metadata packet is missed. Supported operation systems: From a2572ad19a5c5d309d8a0635e2518c3ebb6bafb5 Mon Sep 17 00:00:00 2001 From: Evan G Date: Tue, 26 May 2020 09:42:49 -0600 Subject: [PATCH 230/400] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f96a73b..cfb3b0e 100644 --- a/README.md +++ b/README.md @@ -92,14 +92,14 @@ example: if you wish to get a file from a peer, we need to add a 'message' onto a put request, we can specify that there is no associated put request if we set the filenames to NULL: -params: -id of destination, -source file name, -name of the file as it will arrive at destination, -ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), -app. - -example: +params: +id of destination, +source file name, +name of the file as it will arrive at destination, +ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), +app + +example: Request *req = put_request(, NULL, NULL, ACKNOWLEDGED_MODE, app); From a72040f14b662d8fc1aa0f9a3a42f67c8d741a05 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 27 May 2020 19:26:43 -0600 Subject: [PATCH 231/400] remove stdint dependency --- Program/include/csp_server_provider.h | 2 +- Program/include/jsmn.h | 7 ++++++- Program/include/list.h | 3 ++- Program/include/port.h | 5 +++++ Program/include/posix_server_provider.h | 2 +- Program/include/stdint.h | 9 +++++++++ Program/include/types.h | 22 ++++++++++++++++++---- Program/include/utils.h | 2 +- Program/src/filesystem_funcs.c | 2 +- Program/src/main.c | 6 +++--- Program/src/tasks.c | 2 +- 11 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 Program/include/stdint.h diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index 375f74b..a3fb60e 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -6,7 +6,7 @@ Author: Evan Giese ------------------------------------------------------------------------------*/ #ifndef CSP_SERVER_H #define CSP_SERVER_H -#include +#include "stdint.h" void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), diff --git a/Program/include/jsmn.h b/Program/include/jsmn.h index cb27ca1..6d9524f 100644 --- a/Program/include/jsmn.h +++ b/Program/include/jsmn.h @@ -24,7 +24,12 @@ #ifndef JSMN_H #define JSMN_H -#include +//#include removed this, added just _SIZE_T + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif #ifdef __cplusplus extern "C" { diff --git a/Program/include/list.h b/Program/include/list.h index c3a1656..0006dd8 100644 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -7,7 +7,8 @@ Author: Evan Giese ------------------------------------------------------------------------------*/ #ifndef MY_LIST_H #define MY_LIST_H -#include +#include "stdint.h" + /*------------------------------------------------------------------------------ Purpose: This is a node for the link list bellow ------------------------------------------------------------------------------*/ diff --git a/Program/include/port.h b/Program/include/port.h index 2ec8402..5e01aa6 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -42,6 +42,7 @@ Author: Evan Giese #define ssp_ntohl ntohl #define ssp_htons htons #define ssp_stonl stonl + #define ssp_inet_ntop inet_ntop #include #define ssp_memcpy memcpy @@ -53,6 +54,10 @@ Author: Evan Giese #define ssp_atol atol #endif +#ifdef FREE_RTOS_PORT + //TODO need the above POSIX_PORT definitions to work, if we are bigendian, then the + //htonl etc are empty. +#endif //don't change these in the header file here, if you need to change them diff --git a/Program/include/posix_server_provider.h b/Program/include/posix_server_provider.h index 0f2be5b..f46da18 100644 --- a/Program/include/posix_server_provider.h +++ b/Program/include/posix_server_provider.h @@ -7,7 +7,7 @@ Author: Evan Giese #ifndef POSIX_SERVER_H #define POSIX_SERVER_H -#include +#include "stdint.h" int *prepareSignalHandler(void); /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. diff --git a/Program/include/stdint.h b/Program/include/stdint.h new file mode 100644 index 0000000..32c5e82 --- /dev/null +++ b/Program/include/stdint.h @@ -0,0 +1,9 @@ + +#ifndef _BITS_STDINT_UINTN_H +#define _BITS_STDINT_UINTN_H 1 + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +#endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index b3a8678..7f642bb 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -7,15 +7,26 @@ Author: Evan Giese #ifndef SSP_TYPES_H #define SSP_TYPES_H -#include #include "list.h" -#include -#include - #define MAX_PATH 255 #define ACKNOWLEDGED_MODE 0 #define UN_ACKNOWLEDGED_MODE 1 + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +typedef enum { false, true } bool; + + + + + + + + /*----------------------------------------------------------------------------- Packet structs for building packets @@ -627,6 +638,7 @@ typedef struct request { Response res; } Request; + //add "client" in here to represent local entity typedef struct ftp { @@ -635,6 +647,8 @@ typedef struct ftp { //buffer for making packets, is length of packet_len char* buff; + + void *server_handle; uint32_t my_cfdp_id; diff --git a/Program/include/utils.h b/Program/include/utils.h index c10274d..ace4a43 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -7,7 +7,7 @@ Author: Evan Giese #ifndef UTILS_H #define UTILS_H -#include +#include "stdint.h" //https://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c #define htonll(x) ((1==ssp_htonl(1)) ? (x) : ((uint64_t)ssp_htonl((x) & 0xFFFFFFFF) << 32) | ssp_htonl((x) >> 32)) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index cea7598..f276d9a 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -4,7 +4,7 @@ please include this text, that is my only stipulation. Author: Evan Giese ------------------------------------------------------------------------------*/ -#include +#include "stdint.h" #include "port.h" #include "filesystem_funcs.h" #include "jsmn.h" diff --git a/Program/src/main.c b/Program/src/main.c index eae74e4..075b233 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -5,7 +5,7 @@ please include this text, that is my only stipulation. Author: Evan Giese ------------------------------------------------------------------------------*/ #include -#include +#include "stdint.h" #include #include #include @@ -126,10 +126,10 @@ int main(int argc, char** argv) { //create a client if (conf->client_cfdp_id != 0){ - start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); + start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", UN_ACKNOWLEDGED_MODE, app)); //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy3.jpg", UN_ACKNOWLEDGED_MODE, app)); - Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpg", "pictures/tcp.jpg", ACKNOWLEDGED_MODE, app); + Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/tcp.jpg", ACKNOWLEDGED_MODE, app); start_request(req); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 8d23043..c803f67 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -320,7 +320,7 @@ static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port) uint32_t ut_addr = ssp_htonl(remote_entity.UT_address); //convert uint id to char * - const char *ret = inet_ntop(SSP_AF_INET, &ut_addr, host_name, SSP_INET_ADDRSTRLEN); + const char *ret = ssp_inet_ntop(SSP_AF_INET, &ut_addr, host_name, SSP_INET_ADDRSTRLEN); if (ret == NULL) { ssp_error("inet_ntop"); return -1; From 21b1a03f58f807872f7098d8c85cd7ecbdcc5a58 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 29 May 2020 10:06:12 -0600 Subject: [PATCH 232/400] more basic cleanup --- Program/include/_stdint.h | 9 ++++++++ Program/src/file_delivery_app.c | 31 ++++++------------------- Program/src/main.c | 40 ++++++++++++++++++++------------- Program/src/mib/peer_5.json | 23 +++++++++++++++++++ Program/src/mib/peer_6.json | 23 +++++++++++++++++++ Program/src/protocol_handler.c | 30 ++++++++++--------------- Program/src/requests.c | 5 +++++ Program/src/tasks.c | 5 +++-- 8 files changed, 107 insertions(+), 59 deletions(-) create mode 100644 Program/include/_stdint.h create mode 100644 Program/src/mib/peer_5.json create mode 100644 Program/src/mib/peer_6.json diff --git a/Program/include/_stdint.h b/Program/include/_stdint.h new file mode 100644 index 0000000..32c5e82 --- /dev/null +++ b/Program/include/_stdint.h @@ -0,0 +1,9 @@ + +#ifndef _BITS_STDINT_UINTN_H +#define _BITS_STDINT_UINTN_H 1 + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +#endif \ No newline at end of file diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 6d5ccd5..62eb97e 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -17,12 +17,12 @@ static void create_ssp_server_drivers(FTP *app) { } else if(app->remote_entity.type_of_network == posix_connection) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); - } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + } else if (app->remote_entity.type_of_network == csp) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); - } else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); - } + } //else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { + // app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); + // } } static void create_ssp_client_drivers(Client *client) { @@ -34,10 +34,10 @@ static void create_ssp_client_drivers(Client *client) { } else if(remote_entity.type_of_network == posix_connection) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); - } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); + // } else if (remote_entity.type_of_network == csp) { + // client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); - } else if (remote_entity.type_of_network == csp && remote_entity.default_transmission_mode == UN_ACKNOWLEDGED_MODE) { + } else if (remote_entity.type_of_network == csp) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); } @@ -52,23 +52,6 @@ FTP *init_ftp(uint32_t my_cfdp_address) { ssp_error("couldn't start server\n"); return NULL; } - - if (remote_entity.type_of_network == csp) { - - #ifdef CSP_NETWORK - ssp_printf("Initialising CSP\r\n"); - - /* Init CSP with address MY_ADDRESS */ - csp_init(remote_entity.UT_address); - - /* Init buffer system with 10 packets of maximum PACKET_LEN bytes each */ - csp_buffer_init(10, remote_entity.mtu); - - /* Start router task with 500 word stack, OS task priority 1 */ - csp_route_start_task(500, 1); - - #endif - } FTP *app = ssp_alloc(sizeof(FTP), 1); if (app == NULL) diff --git a/Program/src/main.c b/Program/src/main.c index 075b233..5d051e9 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -5,7 +5,7 @@ please include this text, that is my only stipulation. Author: Evan Giese ------------------------------------------------------------------------------*/ #include -#include "stdint.h" +#include #include #include #include @@ -111,33 +111,43 @@ int main(int argc, char** argv) { exit_now = prepareSignalHandler(); //get-opt configuration + /* Config *conf = configuration(argc, argv); - if (conf->my_cfdp_id == 0){ printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } + */ + + + #ifdef CSP_NETWORK + ssp_printf("Initialising CSP\r\n"); + + /* Init CSP with address MY_ADDRESS */ + csp_init(1); + + /* Init buffer system with 10 packets of maximum bytes each */ + csp_buffer_init(1000, 250); + + /* Start router task with 500 word stack, OS task priority 1 */ + csp_route_start_task(500, 1); + + #endif - FTP *app = init_ftp(conf->my_cfdp_id); + FTP *app = init_ftp(5); if (app == NULL) { return 1; } - //create a client - if (conf->client_cfdp_id != 0){ - - start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); - //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", UN_ACKNOWLEDGED_MODE, app)); - //start_request(put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy3.jpg", UN_ACKNOWLEDGED_MODE, app)); - Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/tcp.jpg", ACKNOWLEDGED_MODE, app); - start_request(req); - + FTP *app2 = init_ftp(6); + if (app2 == NULL) { + return 1; } + + start_request(put_request(6, "pictures/pic.jpeg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); ssp_thread_join(app->server_handle); - free(conf); - - + //free(conf); return 0; } diff --git a/Program/src/mib/peer_5.json b/Program/src/mib/peer_5.json new file mode 100644 index 0000000..41b5969 --- /dev/null +++ b/Program/src/mib/peer_5.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 5, + "UT_address" : 1, + "UT_port" : 1, + "type_of_network" : 2, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/src/mib/peer_6.json b/Program/src/mib/peer_6.json new file mode 100644 index 0000000..2d8f164 --- /dev/null +++ b/Program/src/mib/peer_6.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 6, + "UT_address" : 1, + "UT_port" : 2, + "type_of_network" : 2, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index c26efd7..06d4c75 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -148,6 +148,10 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r packet_index += header->length_of_entity_IDs; if (app->my_cfdp_id != dest_id){ + if (is_server) + ssp_printf("SERVER: "); + else + ssp_printf("CLIENT: "); ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); return -1; } @@ -182,6 +186,8 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r transaction_sequence_number, res, app); + + ssp_printf("source id %d my id: %d, dest id %d\n ", source_id, app->my_cfdp_id, found_req->dest_cfdp_id); if (found_req == NULL) { ssp_error("could not create request for incomming transmission"); @@ -319,6 +325,7 @@ static void send_eof_pdu(Request *req, Response res) { return; } +//if no file attached to request, set procedure to none static void start_sequence(Request *req, Response res) { send_put_metadata(req, res); @@ -344,8 +351,6 @@ static void send_data(Request *req, Response res) { int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; - //uint32_t offset_first = ssp_ntohl(nak->start_scope); - //uint32_t offset_last = ssp_ntohl(nak->end_scope); uint64_t segments = ntohll(nak->segment_requests); packet_index += 16; @@ -378,11 +383,8 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { - //Pdu_header *header = (Pdu_header *) packet; - //uint16_t incoming_packet_data_len = ntohs(header->PDU_data_field_len); uint8_t directive = packet[packet_index]; packet_index += 1; - switch(directive) { case FINISHED_PDU: req->local_entity.transaction_finished_indication = true; @@ -390,8 +392,8 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ ssp_printf("received finished pdu transaction: %d\n", req->transaction_sequence_number); break; case NAK_PDU: - nak_response(packet, packet_index, req, res, client); ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); + nak_response(packet, packet_index, req, res, client); break; case ACK_PDU: @@ -487,16 +489,6 @@ void user_request_handler(Response res, Request *req, Client* client) { ------------------------------------------------------------------------------*/ - - -/* -static void print_offsets(void *element, void *args) { - - Offset *off = (Offset *) element; - ssp_printf("missing offset start: %d end:%d\n", off->start, off->end); -} -*/ - static void request_eof(Request *req, Response res) { ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); @@ -585,7 +577,6 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, process_file_request_metadata(req); else { printf("just receiving messages, closing request\n"); - //req->local_entity.transaction_finished_indication = true; req->local_entity.EOF_recv_indication = true; req->procedure = none; } @@ -602,7 +593,10 @@ void on_server_time_out(Response res, Request *req) { req->local_entity.transaction_finished_indication) return; - + if (req->local_entity.transaction_finished_indication == true && RESEND_FINISHED_TIMES != req->resent_finished){ + resend_finished_pdu(req, res); + return; + } if (req->resent_finished == RESEND_FINISHED_TIMES && req->local_entity.transaction_finished_indication) { req->procedure = clean_up; ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); diff --git a/Program/src/requests.c b/Program/src/requests.c index eddcc84..7efb236 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -267,6 +267,7 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { req->dest_cfdp_id = client->remote_entity.cfdp_id; req->pdu_header = client->pdu_header; req->res.packet_len = client->packet_len; + req->buff = client->buff; client->request_list->insert(client->request_list, req, 0); @@ -365,6 +366,10 @@ void print_request_state(Request *req) { ssp_printf("Resume indication %d\n", req->local_entity.resumed_indication); ssp_printf("Suspended indication %d\n", req->local_entity.suspended_indication); ssp_printf("Transaction finished indication %d\n", req->local_entity.transaction_finished_indication); + + if (req->file != NULL) + ssp_printf("checksum received = %u checksum calculated = %u\n", req->file->eof_checksum, req->file->partial_checksum); + print_request_procedure(req); ssp_printf("current messages: \n"); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index c803f67..7e8b773 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -88,7 +88,7 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, u res.addr = addr; res.sfd = sfd; res.size_of_addr = size_of_addr; - + Request **request_container = &app->current_request; int packet_index = process_pdu_header(packet, true, res, request_container, app->request_list, app); if (packet_index < 0) { @@ -125,6 +125,7 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u res.size_of_addr = size_of_addr; res.transmission_mode = client->remote_entity.default_transmission_mode; res.msg = client->buff; + res.packet_len = packet_len; Request **request_container = &client->current_request; @@ -173,7 +174,7 @@ static void user_request_check(Node *node, void *request, void *args) { remove_request_check(node, request, params->client->request_list); } -//TODO can getrid of res here I think, well at least the addr + static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, void *other) { Response res; From 6f55e8a6867e32631c933a5e0b327484c28a49e2 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 31 May 2020 19:09:17 -0600 Subject: [PATCH 233/400] add working connection csp --- Program/include/csp_server_provider.h | 10 ++- Program/include/protocol_handler.h | 4 +- Program/include/types.h | 3 +- Program/src/csp_server_provider.c | 104 +++++++++++++++----------- Program/src/file_delivery_app.c | 17 ++--- Program/src/mib/peer_7.json | 23 ++++++ Program/src/mib/peer_8.json | 23 ++++++ Program/src/port.c | 37 +++++++-- Program/src/posix_server_provider.c | 2 +- Program/src/protocol_handler.c | 16 +--- Program/src/tasks.c | 7 +- 11 files changed, 169 insertions(+), 77 deletions(-) create mode 100644 Program/src/mib/peer_7.json create mode 100644 Program/src/mib/peer_8.json diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index a3fb60e..1400a6f 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -8,14 +8,16 @@ Author: Evan Giese #define CSP_SERVER_H #include "stdint.h" -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, +#define CSP_CLIENT_PORT 28 + +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, uint32_t packet_len, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params), void *params); -void csp_connectionless_server(uint8_t my_port, +void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -23,7 +25,7 @@ void csp_connectionless_server(uint8_t my_port, void (*onExit)(void *other), void *other); -void csp_connection_server(uint8_t my_port, +void csp_connection_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -31,7 +33,7 @@ void csp_connection_server(uint8_t my_port, void (*onExit)(void *other), void *other); -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 53d5e65..2527ffa 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -9,8 +9,8 @@ Author: Evan Giese #include "types.h" #define RESEND_EOF_TIMES 3 -#define RESEND_FINISHED_TIMES 3 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 10 +#define RESEND_FINISHED_TIMES 10 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 30 int parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); void user_request_handler(Response res, Request *req, Client *client); diff --git a/Program/include/types.h b/Program/include/types.h index 7f642bb..86f017b 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -500,7 +500,8 @@ typedef struct local_entity { typedef enum Network_type { posix_connection_less, posix_connection, - csp + csp_connectionless, + csp_connection, } Network_type; diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 2a8ceb7..5efb381 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -5,10 +5,13 @@ please include this text, that is my only stipulation. Author: Evan Giese ------------------------------------------------------------------------------*/ +#include "port.h" #include "csp.h" #include "csp_server_provider.h" -#include "port.h" -static int exit_now; +#include "csp_conn.h" + + +int exit_now; /*------------------------------------------------------------------------------ @@ -17,7 +20,7 @@ static int exit_now; ------------------------------------------------------------------------------*/ //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c -void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, +void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, uint32_t packet_len, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *params), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *params) , int (*checkExit)(void *params), @@ -30,9 +33,12 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); csp_socket_t *soc = csp_socket(CSP_SO_CONN_LESS); + if (soc == NULL) { + ssp_error("ERROR: csp socket queue empty\n"); + return; + } - - err = csp_bind(soc, CSP_ANY); + err = csp_bind(soc, src_port); if (err < 0) { ssp_error("ERROR: couldn't bind csp\n"); return; @@ -41,7 +47,6 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p csp_packet_t *packet_sending; csp_packet_t *packet_recieved; - if (csp_buffer_remaining() != 0) { packet_sending = csp_buffer_get(1); @@ -55,26 +60,29 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p ssp_error("couldn't get new packet for sending!\n"); exit_now = 1; } + char buff[packet_len]; + memset(buff, 0, packet_len); for (;;) { if (exit_now || checkExit(params)){ - ssp_printf("exiting server thread\n"); + ssp_printf("exiting client thread\n"); break; } - onSend(-1, packet_sending, sizeof(*packet_sending), params); - + onSend(-1, packet_sending, sizeof(csp_packet_t), params); + packet_recieved = csp_recvfrom(soc, 10); - //timout - if (packet_recieved == NULL) + if (packet_recieved == NULL) { continue; - + } else { - ssp_printf("CLIENT DATA Length: %d\n", packet_recieved->length); - if (onRecv(-1, (char *)packet_recieved->data, packet_recieved->length, NULL, packet_recieved, sizeof(packet_recieved), params) == -1) - ssp_printf("recv failed\n"); + + memcpy(buff, packet_recieved->data, packet_len); + + if (onRecv(-1, buff, packet_len, NULL, packet_recieved, sizeof(csp_packet_t), params) == -1) + ssp_printf("recv failed\n"); csp_buffer_free(packet_recieved); } @@ -85,7 +93,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p -void csp_connectionless_server(uint8_t my_port, +void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -112,15 +120,25 @@ void csp_connectionless_server(uint8_t my_port, } csp_packet_t *packet = csp_recvfrom(soc, 10); - - //timout + //timeout if (packet == NULL) { onTimeOut(other); } else { - if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(packet), other) == -1) - ssp_printf("recv failed\n"); + //switch ids, we do this for the sendto function, to reply + uint8_t d_id = packet->id.dst; + uint8_t s_id = packet->id.src; + packet->id.dst = s_id; + packet->id.src = d_id; + + uint8_t d_port = packet->id.dport; + uint8_t s_port = packet->id.sport; + packet->id.dport = s_port; + packet->id.sport = d_port; + + if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(csp_packet_t), other) == -1) + ssp_printf("recv failed\n"); csp_buffer_free(packet); } @@ -128,8 +146,7 @@ void csp_connectionless_server(uint8_t my_port, } } -//This doesn't work because it can't have multiple connections, maybe revisit? -void csp_connection_server(uint8_t my_port, +void csp_connection_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), @@ -138,6 +155,8 @@ void csp_connection_server(uint8_t my_port, void *other) { + //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); + /* Create socket without any socket options */ csp_socket_t *sock = csp_socket(CSP_SO_NONE); @@ -151,6 +170,9 @@ void csp_connection_server(uint8_t my_port, csp_conn_t *conn; csp_packet_t *packet; + char buff[packet_len]; + memset(buff, 0, packet_len); + /* Process incoming connections */ for (;;) { @@ -160,7 +182,7 @@ void csp_connection_server(uint8_t my_port, } /* Wait for connection, 1000 ms timeout */ - if ((conn = csp_accept(sock, 1000)) == NULL) { + if ((conn = csp_accept(sock, 10)) == NULL) { onTimeOut(other); continue; } @@ -169,29 +191,26 @@ void csp_connection_server(uint8_t my_port, if (exit_now || checkExit(other)) break; - + onTimeOut(other); - - while ((packet = csp_read(conn, 100)) != NULL) { - if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), other) == -1) + + while ((packet = csp_read(conn, 100)) != NULL) { + memcpy(buff, (char *)packet->data, packet_len); + + if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), other) == -1) ssp_printf("recv failed\n"); csp_buffer_free(packet); - } } - csp_close(conn); onExit(other); } - - /* Close current connection, and handle next */ - csp_close(conn); } -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), @@ -203,8 +222,10 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, csp_conn_t * conn; - while (1) { + char buff[packet_len]; + memset(buff, 0, packet_len); + while (1) { if (exit_now || checkExit(params)){ ssp_printf("exiting client thread\n"); @@ -212,24 +233,24 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, } /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ - conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_O_NONE); + conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_CONNECTION_SO); if (conn == NULL) { /* Connect failed */ ssp_printf("Connection failed\n"); return; } - - for (;;) { + for (;;) { if (exit_now || checkExit(params)){ ssp_printf("exiting client thread\n"); break; } - onSend(-1, conn, sizeof(conn), params); + while ((packet = csp_read(conn, 10)) != NULL) { + + memcpy(buff, (char *)packet->data, packet_len); - while ((packet = csp_read(conn, 100)) != NULL) { - if (onRecv(-1, (char *)packet->data, packet->length, NULL, conn, sizeof(conn), params) == -1) + if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), params) == -1) ssp_printf("recv failed\n"); csp_buffer_free(packet); @@ -241,5 +262,4 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, csp_close(conn); onExit(params); } -} - +} \ No newline at end of file diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 62eb97e..9702035 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -17,12 +17,12 @@ static void create_ssp_server_drivers(FTP *app) { } else if(app->remote_entity.type_of_network == posix_connection) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); - } else if (app->remote_entity.type_of_network == csp) { + } else if (app->remote_entity.type_of_network == csp_connectionless) { app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); - } //else if (app->remote_entity.type_of_network == csp && app->remote_entity.default_transmission_mode == ACKNOWLEDGED_MODE) { - // app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); - // } + } else if (app->remote_entity.type_of_network == csp_connection) { + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); + } } static void create_ssp_client_drivers(Client *client) { @@ -34,13 +34,12 @@ static void create_ssp_client_drivers(Client *client) { } else if(remote_entity.type_of_network == posix_connection) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); - // } else if (remote_entity.type_of_network == csp) { - // client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); - - } else if (remote_entity.type_of_network == csp) { + } else if (remote_entity.type_of_network == csp_connectionless) { client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); } - + else if (remote_entity.type_of_network == csp_connection) { + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); + } } FTP *init_ftp(uint32_t my_cfdp_address) { diff --git a/Program/src/mib/peer_7.json b/Program/src/mib/peer_7.json new file mode 100644 index 0000000..c71bac5 --- /dev/null +++ b/Program/src/mib/peer_7.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 7, + "UT_address" : 1, + "UT_port" : 5, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/src/mib/peer_8.json b/Program/src/mib/peer_8.json new file mode 100644 index 0000000..7ef170c --- /dev/null +++ b/Program/src/mib/peer_8.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 8, + "UT_address" : 1, + "UT_port" : 4, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/src/port.c b/Program/src/port.c index 0193176..97fcc1b 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -85,16 +85,23 @@ int ssp_close(int fd) { void ssp_sendto(Response res) { - if (res.type_of_network == csp /*&& res.transmission_mode == UN_ACKNOWLEDGED_MODE*/) { + if (res.type_of_network == csp_connectionless) { #ifdef CSP_NETWORK csp_packet_t *packet = (csp_packet_t *) res.addr; csp_packet_t *packet_sending; if (csp_buffer_remaining() != 0) { packet_sending = csp_buffer_get(1); - + if (packet_sending == NULL) { + ssp_printf("couldn't get packet, is NULL"); + } + + ssp_printf("sending packet to dest %d port %d srcaddr %d srcport %d \n", packet->id.dst, packet->id.dport, packet->id.src, packet->id.sport); + ssp_memcpy(packet_sending->data, res.msg, res.packet_len); - int err = csp_sendto(0, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 10); + packet_sending->length = res.packet_len; + + int err = csp_sendto(packet->id.pri, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 100); if (err < 0) { ssp_error("ERROR in ssp_sento"); @@ -104,10 +111,30 @@ void ssp_sendto(Response res) { else ssp_error("couldn't get new packet for sending!\n"); #endif - } else { + } else if (res.type_of_network == csp_connection) { + #ifdef CSP_NETWORK + csp_conn_t *conn = (csp_conn_t*) res.addr; + csp_packet_t *packet_sending; + + if (csp_buffer_remaining() != 0) { + packet_sending = csp_buffer_get(1); + if (packet_sending == NULL) { + ssp_printf("couldn't get packet, is NULL"); + } + ssp_memcpy(packet_sending->data, res.msg, res.packet_len); + packet_sending->length = res.packet_len; + /* 5. Send packet */ + if (!csp_send(conn, packet_sending, 1000)) { + /* Send failed */ + csp_log_error("Send failed"); + csp_buffer_free(packet_sending); + } + } + #endif + } + else { #ifdef POSIX_PORT struct sockaddr* addr = (struct sockaddr*) res.addr; - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); if (err < 0) { ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index 2c2a513..69bc794 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -13,7 +13,7 @@ Author: Evan Giese #include "port.h" #include -static int exit_now; +extern int exit_now; static int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { int count = 0; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 06d4c75..6836c08 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -148,14 +148,9 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r packet_index += header->length_of_entity_IDs; if (app->my_cfdp_id != dest_id){ - if (is_server) - ssp_printf("SERVER: "); - else - ssp_printf("CLIENT: "); ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); return -1; } - //if packet is from the same request, don't' change current request Request *current_req = (*req); @@ -187,8 +182,6 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r res, app); - ssp_printf("source id %d my id: %d, dest id %d\n ", source_id, app->my_cfdp_id, found_req->dest_cfdp_id); - if (found_req == NULL) { ssp_error("could not create request for incomming transmission"); return -1; @@ -385,6 +378,7 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ uint8_t directive = packet[packet_index]; packet_index += 1; + switch(directive) { case FINISHED_PDU: req->local_entity.transaction_finished_indication = true; @@ -586,11 +580,7 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, void on_server_time_out(Response res, Request *req) { - if (req->paused) - return; - - if (req->transmission_mode == UN_ACKNOWLEDGED_MODE || - req->local_entity.transaction_finished_indication) + if (req->paused || req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; if (req->local_entity.transaction_finished_indication == true && RESEND_FINISHED_TIMES != req->resent_finished){ @@ -644,6 +634,8 @@ void on_server_time_out(Response res, Request *req) { } ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); + //uint32_t checksum = check_sum_file(req->file, 1000); + //ssp_printf("checksum re-calculated: %u\n", checksum); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 7e8b773..bae000d 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -461,6 +461,7 @@ void *ssp_csp_connectionless_server_task(void *params) { csp_connectionless_server( app->remote_entity.UT_port, + app->remote_entity.mtu, on_recv_server_callback, on_time_out_callback_server, on_stdin_callback, @@ -481,7 +482,8 @@ void *ssp_csp_connectionless_client_task(void *params) { csp_connectionless_client(client->remote_entity.UT_address, client->remote_entity.UT_port, - client->app->remote_entity.UT_port, + CSP_CLIENT_PORT, + client->remote_entity.mtu, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, @@ -501,6 +503,7 @@ void *ssp_csp_connection_server_task(void *params) { FTP *app = (FTP *) params; csp_connection_server(app->remote_entity.UT_port, + app->remote_entity.mtu, on_recv_server_callback, on_time_out_callback_server, on_stdin_callback, @@ -520,6 +523,8 @@ void *ssp_csp_connection_client_task(void *params) { Client *client = (Client *) params; csp_connection_client(client->remote_entity.UT_address, client->remote_entity.UT_port, + CSP_CLIENT_PORT, + client->remote_entity.mtu, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, From d14aebc2d68787b1150df5e577df329372866d15 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Jun 2020 09:12:21 -0600 Subject: [PATCH 234/400] update mib.txt --- Documents/mib.txt | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/Documents/mib.txt b/Documents/mib.txt index 63de342..41e8e1c 100644 --- a/Documents/mib.txt +++ b/Documents/mib.txt @@ -14,7 +14,6 @@ Here is an example of a MIB entry: "type_of_network" : 1, "default_transmission_mode" : 1, "MTU" : 1500, - "one_way_light_time" : 123, "total_round_trip_allowance" : 123, "async_NAK_interval" : 123, @@ -33,32 +32,49 @@ Here is an example of a MIB entry: Below are the meanings of the fields for the MIB -cfdp_id +- cfdp_id This is the unique identifier of a peer on the network. We can start it at 1 and increment it from there. This is an unsigned integer (32 bit) value; - -UT_address +- UT_address This is an Underlying Transmission address. For example, in an IP stack, this - would be an IP4 Ip address. This value is a decimal represenstation of an IP + would be an IP4 Ip address. This value is a decimal representation of an IP address. This particular one is 127.0.0.1. - -UT_port +- UT_port This os an Underlying Transmission port. For example, in an IP stack, this - would be a 16 bit value -- like port 8080. Combinded with the UT_address, + would be a 16 bit value -- like port 8080. combined with the UT_address, together they form a complete UT address. The one above would be equal to 127.0.0.1:1111. This is an unsigned integer (16 bit) value -type_of_network +- type_of_network This number represents what type of network the underlying UT address takes. - currently, the only acceptable values are 0 and 1. + currently, the only acceptable values are 0 and 1. + - 0: UDP + - 1: TCP + - 2: csp +- default_transmission_mode: + not implemented -default_transmission_mode: - not implmented - -MTU - This number represents the 'maximum transmissable unit' -- this will also +- MTU + This number represents the 'maximum transmissible unit' -- this will also take the form of a buffer in the program. This value is the maximum size packet that the application will receive. + +- one_way_light_time : not implemented +- total_round_trip_allowance : not implemented +- async_NAK_interval : not implemented +- async_keep_alive_interval : not implemented +- async_report_interval : not implemented +- immediate_nak_mode_enabled : not implemented +- prompt_transmission_interval : not implemented +- disposition_of_incomplete : not implemented +- CRC_required : not implemented +- keep_alive_discrepancy_limit : not implemented +- positive_ack_timer_expiration_limit : not implemented +- nak_timer_expiration_limit : not implemented +- transaction_inactivity_limit : not implemented + +if you want to get in contact with me +email me at evangiese77@gmail.com From c54d3a64eed5afb18d18d45d6a39cb5b98cda6b8 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Jun 2020 09:14:40 -0600 Subject: [PATCH 235/400] remove undeed experiment stdint --- Program/include/_stdint.h | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 Program/include/_stdint.h diff --git a/Program/include/_stdint.h b/Program/include/_stdint.h deleted file mode 100644 index 32c5e82..0000000 --- a/Program/include/_stdint.h +++ /dev/null @@ -1,9 +0,0 @@ - -#ifndef _BITS_STDINT_UINTN_H -#define _BITS_STDINT_UINTN_H 1 - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -#endif \ No newline at end of file From 8265c1fb5b73af8c717ac08efabd3604449dac68 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Jun 2020 09:38:33 -0600 Subject: [PATCH 236/400] cleanup if statements --- Program/include/types.h | 2 +- Program/src/file_delivery_app.c | 56 ++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index 86f017b..02ed0c4 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -498,7 +498,7 @@ typedef struct local_entity { typedef enum Network_type { - posix_connection_less, + posix_connectionless, posix_connection, csp_connectionless, csp_connection, diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 9702035..268e683 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -11,34 +11,46 @@ Author: Evan Giese static void create_ssp_server_drivers(FTP *app) { - if (app->remote_entity.type_of_network == posix_connection_less) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); - - } else if(app->remote_entity.type_of_network == posix_connection) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); - - } else if (app->remote_entity.type_of_network == csp_connectionless) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); - - } else if (app->remote_entity.type_of_network == csp_connection) { - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); + switch (app->remote_entity.type_of_network) + { + case posix_connectionless: + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); + break; + case posix_connection: + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); + break; + case csp_connectionless: + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); + break; + case csp_connection: + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); + break; + default: + ssp_printf("server couldn't start, 'type of network' not recognized\n"); + break; } } static void create_ssp_client_drivers(Client *client) { Remote_entity remote_entity = client->remote_entity; - if (remote_entity.type_of_network == posix_connection_less) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); - - } else if(remote_entity.type_of_network == posix_connection) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); - - } else if (remote_entity.type_of_network == csp_connectionless) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); - } - else if (remote_entity.type_of_network == csp_connection) { - client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); + switch (remote_entity.type_of_network) + { + case posix_connectionless: + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_client_task, client); + break; + case posix_connection: + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_client_task, client); + break; + case csp_connectionless: + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_client_task, client); + break; + case csp_connection: + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); + break; + default: + ssp_printf("client couldn't start, 'type of network' not recognized\n"); + break; } } From 901452554cf58155d5fd907dcb3df39ec57cc1a1 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 3 Jun 2020 10:27:53 -0600 Subject: [PATCH 237/400] Change port, will need to flush out functions in future --- Program/src/port.c | 104 +++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 66 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 97fcc1b..85ab683 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -35,7 +35,7 @@ Author: Evan Giese /*------------------------------------------------------------------------------ File system port functions, these are used to interchange different - File systems + File systems, will add RELIANCE_EDGE here in the future ------------------------------------------------------------------------------*/ int ssp_rename(const char *old, const char *new) { #ifdef POSIX_FILESYSTEM @@ -153,16 +153,15 @@ void ssp_sendto(Response res) { void *ssp_alloc(uint32_t n_memb, size_t size) { - #ifdef POSIX_PORT + #ifdef FREE_RTOS_PORT + return pvPortMalloc(n_memb * size); + #else void *mem = calloc(n_memb, size); if (mem == NULL) ssp_error("Memory failed to alloc!\n"); return mem; #endif - #ifdef FREE_RTOS_PORT - return pvPortMalloc(n_memb * size); - #endif } @@ -170,62 +169,35 @@ void ssp_free(void *pointer) { if (pointer == NULL) return; - - #ifdef POSIX_PORT - free(pointer); - #endif - + #ifdef FREE_RTOS_PORT vPortFree(pointer); + #else + free(pointer); #endif } +//what kind of errorno functions do we have in RED_FS? void ssp_error(char *error){ - #ifdef POSIX_PORT - perror(error); - #endif - #ifdef FREE_RTOS_PORT - perror(error); - #endif - + perror(error); } -//this can be switched to +//this can be switched to printing to a log file in the future, not sure +//if FREE_RTOS has va_list void ssp_printf(char *stuff, ...) { - #ifdef POSIX_PORT - va_list args; - va_start(args, stuff); - vfprintf(stdout, stuff, args); - va_end (args); - fflush(stdout); - #endif - - #ifdef FREE_RTOS_PORT - va_list args; - va_start(args, stuff); - vfprintf(stdout, stuff, args); - va_end (args); - fflush(stdout); - #endif - + va_list args; + va_start(args, stuff); + vfprintf(stdout, stuff, args); + va_end (args); + fflush(stdout); } -//returns seconds elapsed +//returns seconds elapsed, need FREE RTOS realtime clock lib to properly port int ssp_time_count() { - #ifdef POSIX_PORT - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - //clock_t c = clock(); - //c = c / CLOCKS_PER_SEC; - return ts.tv_sec; - #endif - - #ifdef FREE_RTOS_PORT - //some kind of ticks - #endif - return -1; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return ts.tv_sec; } /*------------------------------------------------------------------------------ @@ -233,8 +205,25 @@ int ssp_time_count() { ------------------------------------------------------------------------------*/ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params) { + #ifdef FREE_RTOS_PORT - #ifdef POSIX_PORT + TaskHandle_t *xHandle = ssp_alloc(1, sizeof(TaskHandle_t)); + BaseType_t xReturned; + + /* Create the task, storing the handle. */ + xReturned = xTaskCreate( + thread_func, /* Function that implements the task. */ + "FTP", /* Text name for the task. */ + stack_size, /* Stack size in words, not bytes. */ + params, /* Parameter passed into the task. */ + tskIDLE_PRIORITY,/* Priority at which the task is created. */ + xHandle ); /* Used to pass out the created task's handle. */ + if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) + ssp_error("Not enough memory to start task\n"); + + return xHandle; + + #else //pthreads pthread_t *handler = ssp_alloc(1, sizeof(pthread_t)); if (handler == NULL) return NULL; @@ -270,24 +259,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void return handler; #endif - #ifdef FREE_RTOS_PORT - TaskHandle_t *xHandle = ssp_alloc(1, sizeof(TaskHandle_t)); - BaseType_t xReturned; - - /* Create the task, storing the handle. */ - xReturned = xTaskCreate( - thread_func, /* Function that implements the task. */ - "FTP", /* Text name for the task. */ - stack_size, /* Stack size in words, not bytes. */ - params, /* Parameter passed into the task. */ - tskIDLE_PRIORITY,/* Priority at which the task is created. */ - xHandle ); /* Used to pass out the created task's handle. */ - if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) - ssp_error("Not enough memory to start task\n"); - - return xHandle; - #endif } From b8315e5606768f396875e16a3e5c32100ddfc47e Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 6 Jun 2020 11:56:47 -0600 Subject: [PATCH 238/400] add read and write lv --- Program/include/filesystem_funcs.h | 3 +++ Program/include/stdint.h | 9 ------- Program/src/file_delivery_app.c | 2 +- Program/src/filesystem_funcs.c | 38 ++++++++++++++++++++++++++-- Program/test/filesystem_tests.c | 40 +++++++++++++++++++++++++++++- Program/test/list_tests.c | 4 +-- Program/test/mock.c | 4 +-- 7 files changed, 83 insertions(+), 17 deletions(-) delete mode 100644 Program/include/stdint.h diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 518dae5..d541b0e 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -30,6 +30,9 @@ File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); +int write_lv(int fd, LV lv); +int read_lv(int fd, LV *lv); + int save_req_to_file(Request *req); int save_file_to_file(int fd, File *file); int get_file_from_file(int fd, File *file); diff --git a/Program/include/stdint.h b/Program/include/stdint.h deleted file mode 100644 index 32c5e82..0000000 --- a/Program/include/stdint.h +++ /dev/null @@ -1,9 +0,0 @@ - -#ifndef _BITS_STDINT_UINTN_H -#define _BITS_STDINT_UINTN_H 1 - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -#endif \ No newline at end of file diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 268e683..3e7919b 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -60,7 +60,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { Remote_entity remote_entity; int error = get_remote_entity_from_json(&remote_entity, my_cfdp_address); if (error == -1) { - ssp_error("couldn't start server\n"); + ssp_error("can't get configuration data, can't start server.\n"); return NULL; } diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index f276d9a..3032612 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -447,6 +447,42 @@ int get_file_from_file(int fd, File *file) { //dest_file //length //src_file + +int write_lv(int fd, LV lv){ + + char *error_message = "failed to write lv\n"; + int err = ssp_write(fd, (char*)&lv.length, sizeof(uint8_t)); + if (err < 0) { + ssp_error(error_message); + return -1; + } + err = ssp_write(fd, (char*)&lv.value, lv.length); + if (err < 0) { + ssp_error(error_message); + return -1; + } + return 1; +} +int read_lv(int fd, LV *lv){ + + char *error_message = "failed to read lv\n"; + int err = ssp_read(fd, (char*)&lv->length, sizeof(uint8_t)); + if (err < 0) { + ssp_error(error_message); + return -1; + } + lv->value = ssp_alloc(lv->length, sizeof(uint8_t)); + if(lv->value == NULL) { + return -1; + } + err = ssp_read(fd, (char*)lv->value, lv->length); + if (err < 0) { + ssp_error(error_message); + return -1; + } + return 1; +} + static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy_message) { char *error_message = "failed to write put proxy message\n"; @@ -639,7 +675,6 @@ static Message *read_in_proxy_message(int fd) { return NULL; //why does this not work? - Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, src_file_name, destination_file_name); if (proxy_message == NULL) { ssp_free(message); @@ -671,7 +706,6 @@ static int get_messages_from_file(int fd, List *messages){ { case PROXY_PUT_REQUEST: message = read_in_proxy_message(fd); - break; default: diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 7080b23..44dca9c 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -6,6 +6,8 @@ #include #include "test.h" + + static void nak_print(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; ssp_printf("start: %u end: %u\n", offset->start, offset->end); @@ -41,6 +43,41 @@ int read_json_file_test() { return 1; } + +int test_write_lv() { + + DECLARE_NEW_TEST("test write lv"); + char *my_file_name = "temp/test_lv_write"; + int fd = ssp_open(my_file_name, O_RDWR | O_CREAT); + if (fd < 0) { + ssp_error("couldn't open file\n"); + return -1; + } + + LV lv; + lv.value = my_file_name; + lv.length = strnlen(my_file_name, 255); + + int error = write_lv(fd, lv); + if (error < 0) { + return -1; + } + //seek back to start of file + ssp_lseek(fd, 0, 0); + + LV new_lv; + error = read_lv(fd, &new_lv); + if (error < 0) { + return -1; + } + + ASSERT_EQUALS_STR("write&read lv value to file", lv.value, my_file_name, lv.length); + ASSERT_EQUALS_INT("write&read lv length", new_lv.length, lv.length); + free_lv(new_lv); + + return 1; +} + int test_save_file() { @@ -178,8 +215,9 @@ static int test_saving_request(){ int file_system_tests() { int error = 0; + error = test_write_lv(); error = test_saving_request(); - //error = test_save_file(); + error = test_save_file(); return error; } diff --git a/Program/test/list_tests.c b/Program/test/list_tests.c index e3ab60e..3d4e2d0 100644 --- a/Program/test/list_tests.c +++ b/Program/test/list_tests.c @@ -65,8 +65,8 @@ int list_tests() { Request *r = mock_empty_request(); Request *r2 = mock_empty_request(); - ssp_memcpy(r->source_file_name, "mybestfriend", 12); - ssp_memcpy(r2->source_file_name, "secondrequest", 12); + memcpy(r->source_file_name, "mybestfriend", 12); + memcpy(r2->source_file_name, "secondrequest", 12); list->push(list, r, 1); ASSERT_EQUALS_INT("should equal 1", 1, list->count); diff --git a/Program/test/mock.c b/Program/test/mock.c index 21317c2..ab2aa12 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -69,7 +69,7 @@ Response *mock_response() { res->sfd = 1; res->packet_len = 1500; res->size_of_addr = 16; - res->type_of_network = posix_connection_less; + res->type_of_network = posix_connectionless; res->transmission_mode = UN_ACKNOWLEDGED_MODE; return res; } @@ -106,7 +106,7 @@ Request *mock_request() { req->res.sfd = 1; req->res.packet_len = 2000; req->res.size_of_addr = 16; - req->res.type_of_network = posix_connection_less; + req->res.type_of_network = posix_connectionless; req->res.transmission_mode = UN_ACKNOWLEDGED_MODE; req->res.msg = req->buff; req->messages_to_user = linked_list(); From 7af27bbdfe7d7b2706bb532443a2545bd0c5f042 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 6 Jun 2020 12:08:17 -0600 Subject: [PATCH 239/400] incorporate write_lv --- Program/src/filesystem_funcs.c | 41 +++++++++++----------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 3032612..7c8753a 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -443,11 +443,6 @@ int get_file_from_file(int fd, File *file) { return 0; } -//length -//dest_file -//length -//src_file - int write_lv(int fd, LV lv){ char *error_message = "failed to write lv\n"; @@ -456,7 +451,7 @@ int write_lv(int fd, LV lv){ ssp_error(error_message); return -1; } - err = ssp_write(fd, (char*)&lv.value, lv.length); + err = ssp_write(fd, (char*)lv.value, lv.length); if (err < 0) { ssp_error(error_message); return -1; @@ -483,46 +478,35 @@ int read_lv(int fd, LV *lv){ return 1; } +//length +//dest_file +//length +//src_file + static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy_message) { char *error_message = "failed to write put proxy message\n"; - int err = ssp_write(fd, &proxy_message->destination_file_name.length, sizeof(uint8_t)); - if (err < 0) { - *error = err; - ssp_error(error_message); - return; - } - err = ssp_write(fd, proxy_message->destination_file_name.value, proxy_message->destination_file_name.length); - if (err < 0) { - *error = err; - ssp_error(error_message); - return; - } - err = ssp_write(fd, &proxy_message->source_file_name.length, sizeof(uint8_t)); - if (err < 0) { - *error = err; - ssp_error(error_message); - return; - } - err = ssp_write(fd, proxy_message->source_file_name.value, proxy_message->source_file_name.length); + + int err = write_lv(fd, proxy_message->destination_file_name); if (err < 0) { *error = err; ssp_error(error_message); return; } - err = ssp_write(fd, &proxy_message->destination_id.length, sizeof(uint8_t)); + + err = write_lv(fd, proxy_message->source_file_name); if (err < 0) { *error = err; ssp_error(error_message); return; } - err = ssp_write(fd, proxy_message->destination_id.value, proxy_message->destination_id.length); + + err = write_lv(fd, proxy_message->destination_id); if (err < 0) { *error = err; ssp_error(error_message); return; } - } static void write_message_callback(Node *node, void *element, void *param) { @@ -639,6 +623,7 @@ static Message *read_in_proxy_message(int fd) { uint32_t dest_id = 0; char *error_message = "failed to read put proxy message\n"; + int err = ssp_read(fd, (char*) &destination_file_name_len, sizeof(uint8_t)); if (err < 0) { ssp_error(error_message); From 51c85de77af274f3d0262581ab68beaca9116f1f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 6 Jun 2020 12:20:37 -0600 Subject: [PATCH 240/400] incorporate read_lv --- Program/src/filesystem_funcs.c | 39 +++++++++++----------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 7c8753a..c1924f4 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -615,41 +615,24 @@ int save_req_to_file(Request *req) { static Message *read_in_proxy_message(int fd) { - uint8_t destination_file_name_len = 0; - char destination_file_name[255]; - uint8_t src_file_name_len = 0; - char src_file_name[255]; - uint8_t dest_id_len = 0; - uint32_t dest_id = 0; char *error_message = "failed to read put proxy message\n"; - - int err = ssp_read(fd, (char*) &destination_file_name_len, sizeof(uint8_t)); - if (err < 0) { - ssp_error(error_message); - return NULL; - } - err = ssp_read(fd, destination_file_name, destination_file_name_len); - if (err < 0) { - ssp_error(error_message); - return NULL; - } - err = ssp_read(fd, (char*) &src_file_name_len, sizeof(uint8_t)); - if (err < 0) { - ssp_error(error_message); - return NULL; - } - err = ssp_read(fd, src_file_name, src_file_name_len); + + LV destination_file; + LV src_file_name; + LV dest_id; + + int err = read_lv(fd, &destination_file); if (err < 0) { ssp_error(error_message); return NULL; } - err = ssp_read(fd, (char*) &dest_id_len, sizeof(uint8_t)); + err = read_lv(fd, &src_file_name); if (err < 0) { ssp_error(error_message); return NULL; } - err = ssp_read(fd, (char *)&dest_id, dest_id_len); + err = read_lv(fd, &dest_id); if (err < 0) { ssp_error(error_message); return NULL; @@ -659,12 +642,14 @@ static Message *read_in_proxy_message(int fd) { if (message == NULL) return NULL; - //why does this not work? - Message_put_proxy *proxy_message = create_message_put_proxy(dest_id, dest_id_len, src_file_name, destination_file_name); + Message_put_proxy *proxy_message = ssp_alloc(1, sizeof(Message_put_proxy)); if (proxy_message == NULL) { ssp_free(message); return NULL; } + proxy_message->destination_file_name = destination_file; + proxy_message->source_file_name = src_file_name; + proxy_message->destination_id = dest_id; message->value = proxy_message; return message; From 43979469be6831165a35ef633fbbdba478932a89 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 7 Jun 2020 13:13:41 -0600 Subject: [PATCH 241/400] Turn partial request into scheduled request --- Program/include/mib.h | 2 - Program/include/requests.h | 1 + Program/include/types.h | 2 +- Program/src/filesystem_funcs.c | 25 ++++++++--- Program/src/packet.c | 14 +++--- Program/src/protocol_handler.c | 47 ++++++++++++++------ Program/src/requests.c | 60 ++++++++++++++++++++----- Program/test/filesystem_tests.c | 79 +++++++++++++++++++++++++++++++-- Program/test/packet_tests.c | 4 +- Program/test/request_tests.c | 19 ++++++++ 10 files changed, 205 insertions(+), 48 deletions(-) diff --git a/Program/include/mib.h b/Program/include/mib.h index 4ba5edb..623f8ef 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -12,8 +12,6 @@ Author: Evan Giese int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); void ssp_cleanup_pdu_header(Pdu_header *pdu_header); -Remote_entity *get_remote_entity(MIB *mib, uint32_t dest_id); -Remote_entity *get_remote_entity2(uint32_t dest_id); int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id); #endif \ No newline at end of file diff --git a/Program/include/requests.h b/Program/include/requests.h index 2799ad5..08be30f 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -38,6 +38,7 @@ Message_cont_part_request *create_message_cont_partial_request(uint32_t benefici uint32_t transaction_id, uint8_t transaction_id_length); +int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uint32_t buff_len); void print_request_state(Request *req); void ssp_free_message(void *params); uint16_t copy_lv_to_buffer(char *buffer, LV lv); diff --git a/Program/include/types.h b/Program/include/types.h index 02ed0c4..90e835a 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -140,7 +140,7 @@ typedef struct tlv { #define PROXY_PUT_CANCEL 09 //custom -#define PROXY_CONTINUE_PARTIAL 10 +#define CONTINUE_PARTIAL 10 typedef struct message_header { diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index c1924f4..eafccc7 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -395,7 +395,7 @@ int save_file_to_file(int fd, File *file) { file->missing_offsets->iterate(file->missing_offsets, save_file_callback, ¶m); return param.error; } - +//[file][length][offsets] int get_file_from_file(int fd, File *file) { uint32_t length = 0; @@ -411,7 +411,6 @@ int get_file_from_file(int fd, File *file) { ssp_error(error_msg); return -1; } - Offset offset; memset(&offset, 0, sizeof(Offset)); @@ -564,7 +563,7 @@ int save_req_to_file(Request *req) { char file_name[255]; ssp_snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); - + int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { ssp_error("couldn't open file\n"); @@ -693,9 +692,11 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Reque char file_name[255]; + ssp_snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); + ssp_printf("opening %s\n", file_name); - int fd = ssp_open(file_name, O_RDWR | O_CREAT); + int fd = ssp_open(file_name, O_RDWR); if (fd < 0) { ssp_error("couldn't open file\n"); return -1; @@ -712,22 +713,32 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Reque if (error == -1) return -1; - File *file; + File *file = NULL; if (is_file_present) { file = ssp_alloc(1, sizeof(File)); if (file == NULL) { return -1; } error = get_file_from_file(fd, file); + if (error < 0) { + ssp_free(file); + return -1; + } + req->file = file; } List *messages = linked_list(); - if (messages == NULL) + if (messages == NULL) { + ssp_free(file); return -1; + } error = get_messages_from_file(fd, messages); - if (error == -1) + if (error == -1) { + ssp_free(file); + messages->freeOnlyList(messages); return -1; + } req->messages_to_user = messages; diff --git a/Program/src/packet.c b/Program/src/packet.c index ddc7e00..e4f8884 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -125,7 +125,7 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { packet_index += destination_file_length; //add messages to metadata - packet_index = add_messages_to_packet(packet, packet_index, req->messages_to_user); + packet_index += add_messages_to_packet(packet, packet_index, req->messages_to_user); uint8_t data_len = packet_index - start; set_packet_header(packet, data_len, DIRECTIVE); @@ -336,7 +336,6 @@ static void add_messages_callback(Node *node, void *element, void *args) { Message_put_proxy *proxy_put; Message_cont_part_request *proxy_cont_part; - switch (message->header.message_type) { case PROXY_PUT_REQUEST: @@ -346,7 +345,7 @@ static void add_messages_callback(Node *node, void *element, void *args) { packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_put->destination_file_name); break; - case PROXY_CONTINUE_PARTIAL: + case CONTINUE_PARTIAL: proxy_cont_part = (Message_cont_part_request *) message->value; packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->destination_id); packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->originator_id); @@ -384,8 +383,9 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { Message_cont_part_request *proxy_cont_part; uint32_t message_start = start + 6; + uint32_t message_type = start + 5; - switch (packet[start + 5]) + switch (packet[message_type]) { case PROXY_PUT_REQUEST: m = create_message(PROXY_PUT_REQUEST); @@ -403,8 +403,8 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { message_start += proxy_put->destination_file_name.length + 1; break; - case PROXY_CONTINUE_PARTIAL: - m = create_message(PROXY_CONTINUE_PARTIAL); + case CONTINUE_PARTIAL: + m = create_message(CONTINUE_PARTIAL); m->value = ssp_alloc(1, sizeof(Message_cont_part_request)); proxy_cont_part = (Message_cont_part_request *) m->value; @@ -431,12 +431,12 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req) { uint32_t packet_index = start; - while (packet_index < data_length - 5) { if (strncmp(&packet[packet_index], "cfdp", 5)) break; + packet_index = get_message_from_packet(packet, packet_index, req); } return packet_index; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 6836c08..1a76221 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -257,25 +257,47 @@ uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) return packet_index; } - void process_messages(Request *req, FTP *app) { if (req->messages_to_user->count == 0) return; Message *message = req->messages_to_user->pop(req->messages_to_user); - if (message->header.message_type == PROXY_PUT_REQUEST){ - - Message_put_proxy *p = (Message_put_proxy *) message->value; - ssp_printf("received proxy request for source file name: %s dest file name %s, to id %d\n", - (char *)p->source_file_name.value, - (char *)p->destination_file_name.value, - *(uint8_t*)p->destination_id.value); + Message_put_proxy *p_put; + Message_cont_part_request *p_cont; + //int error = 0; - start_request(put_request(*(uint8_t*)p->destination_id.value, - (char *)p->source_file_name.value, - (char *)p->destination_file_name.value, ACKNOWLEDGED_MODE, app)); - ssp_free_message(message); + switch (message->header.message_type) + { + case PROXY_PUT_REQUEST: + + p_put = (Message_put_proxy *) message->value; + ssp_printf("received proxy request for source file name: %s dest file name %s, to id %d\n", + (char *)p_put->source_file_name.value, + (char *)p_put->destination_file_name.value, + *(uint8_t*)p_put->destination_id.value); + + start_request(put_request(*(uint8_t*)p_put->destination_id.value, + (char *)p_put->source_file_name.value, + (char *)p_put->destination_file_name.value, ACKNOWLEDGED_MODE, app)); + ssp_free_message(message); + break; + + case CONTINUE_PARTIAL: + + p_cont = (Message_cont_part_request *) message->value; + ssp_printf("received message request to continue one way communication destination id %d, originator id %d, transaction id %d\n", + *(uint32_t*)p_cont->destination_id.value, *(uint32_t*)p_cont->originator_id.value, *(uint32_t*)p_cont->transaction_id.value); + + + //error = get_req_from_file(*(uint32_t*)p_cont->destination_id.value, *(uint64_t*)p_cont->transaction_id.value, req); + + + default: + break; + } + if (message->header.message_type == PROXY_PUT_REQUEST){ + } @@ -559,7 +581,6 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); packet_index += fill_request_pdu_metadata(&packet[packet_index], req); - uint16_t data_len = get_data_length(packet); get_messages_from_packet(packet, packet_index, data_len, req); diff --git a/Program/src/requests.c b/Program/src/requests.c index 7efb236..3db2d50 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -17,6 +17,7 @@ Author: Evan Giese #include "types.h" #include "filesystem_funcs.h" #include "file_delivery_app.h" +#include "mib.h" //returns total space taken up in the packet from the added lv @@ -68,6 +69,36 @@ Message *create_message(uint8_t type) { Messages (additional minor requests, things like mv files) ------------------------------------------------------------------------------*/ +//this will turn a incoming request to a request that will go out later +int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uint32_t buff_len) { + + Request req; + + uint32_t dest_id = *(uint32_t*)p_cont->destination_id.value; + uint64_t trans_num = *(uint64_t*)p_cont->transaction_id.value; + uint32_t ord_id = *(uint32_t*)p_cont->originator_id.value; + + int error = get_req_from_file(ord_id, trans_num, &req); + if (error < 0) { + ssp_error("couldn't get request from file system\n"); + return error; + } + req.dest_cfdp_id = dest_id; + error = get_remote_entity_from_json(&req.remote_entity, dest_id); + if (error < 0) { + ssp_error("couldn't get remote config from file system\n"); + return error; + } + req.local_entity.EOF_sent_indication = req.local_entity.EOF_recv_indication; + req.local_entity.Metadata_sent_indication = req.local_entity.Metadata_recv_indication; + req.local_entity.resumed_indication = 1; + req.local_entity.suspended_indication = 0; + req.local_entity.transaction_finished_indication = 0; + + get_header_from_mib(&req.pdu_header, req.remote_entity, req.dest_cfdp_id); + save_req_to_file(&req); + return 1; +} //Omission of source and destination filenames shall indicate that only Meta @@ -137,7 +168,7 @@ int add_cont_partial_message_to_request(uint32_t beneficial_cfid, uint8_t transaction_id_length, Request *req){ - Message *message = create_message(PROXY_CONTINUE_PARTIAL); + Message *message = create_message(CONTINUE_PARTIAL); if (message == NULL) return -1; @@ -185,7 +216,7 @@ void ssp_free_message(void *params) { ssp_free_put_proxy_message(proxy_request); break; - case PROXY_CONTINUE_PARTIAL: + case CONTINUE_PARTIAL: proxy_cont_partial_request = (Message_cont_part_request *) message->value; ssp_free_proxy_cont_partial_request(proxy_cont_partial_request); break; @@ -289,14 +320,8 @@ Request *put_request( Request *req; uint32_t file_size = 0; - bool exists = does_file_exist(source_file_name); - if (exists == false) { - ssp_printf("ERROR: File does not exist\n"); - return NULL; - } - ssp_printf("trying to start new request\n"); - if (source_file_name == NULL || destination_file_name == NULL) { + if (source_file_name == NULL && destination_file_name == NULL) { req = start_new_client_request(app, dest_id); req->transmission_mode = transmission_mode; req->procedure = sending_start; @@ -308,6 +333,12 @@ Request *put_request( return NULL; } + bool exists = does_file_exist(source_file_name); + if (exists == false) { + ssp_printf("ERROR: File does not exist\n"); + return NULL; + } + req = start_new_client_request(app, dest_id); file_size = get_file_size(source_file_name); @@ -358,7 +389,10 @@ static void print_messages_callback(Node *node, void *element, void *args) { void print_request_state(Request *req) { ssp_printf("----------------Transaction %d---------------\n", req->transaction_sequence_number); - ssp_printf("local_entity stats: \n"); + + ssp_printf("local_entity id and stats: \n"); + + ssp_printf("destination id %d: \n", req->dest_cfdp_id); ssp_printf("EOF_recv indication %d\n", req->local_entity.EOF_recv_indication); ssp_printf("EOF_sent indication %d\n", req->local_entity.EOF_sent_indication); ssp_printf("Metadata_recv indication %d\n", req->local_entity.Metadata_recv_indication); @@ -367,11 +401,13 @@ void print_request_state(Request *req) { ssp_printf("Suspended indication %d\n", req->local_entity.suspended_indication); ssp_printf("Transaction finished indication %d\n", req->local_entity.transaction_finished_indication); - if (req->file != NULL) + if (req->file != NULL) { ssp_printf("checksum received = %u checksum calculated = %u\n", req->file->eof_checksum, req->file->partial_checksum); - + ssp_printf("offset list count %d\n", req->file->missing_offsets->count); + } print_request_procedure(req); + ssp_printf("current message count %d\n", req->messages_to_user->count); ssp_printf("current messages: \n"); req->messages_to_user->iterate(req->messages_to_user, print_messages_callback, NULL); diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 44dca9c..a5ef170 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -207,17 +207,88 @@ static int test_saving_request(){ ssp_cleanup_req(req); got_req.messages_to_user->free(got_req.messages_to_user, ssp_free_message); - //need to free list return error; } +int test_save_file_and_messages() { + + DECLARE_NEW_TEST("test saving file and messages"); + int error = 0; + Request *req = mock_empty_request(); + + req->dest_cfdp_id = 2; + req->transaction_sequence_number = 2; + req->local_entity.EOF_recv_indication = 1; + req->local_entity.EOF_sent_indication = 1; + req->local_entity.suspended_indication = 1; + char *dest_file = "stuff"; + char *src_file = "morestuff"; + + Message *m = create_message(PROXY_PUT_REQUEST); + m->value = create_message_put_proxy(1, 1, src_file, dest_file); + req->messages_to_user->push(req->messages_to_user, m, 0); + + m = create_message(PROXY_PUT_REQUEST); + m->value = create_message_put_proxy(1, 1, src_file, dest_file); + req->messages_to_user->push(req->messages_to_user, m, 0); + + m = create_message(PROXY_PUT_REQUEST); + m->value = create_message_put_proxy(1, 1, src_file, dest_file); + req->messages_to_user->push(req->messages_to_user, m, 0); + + error = save_req_to_file(req); + if (error == -1) + printf("failed to write\n"); + + File file; + memset(&file, 0, sizeof(File)); + + file.missing_offsets = linked_list(); + + Offset one = { + 0, 250 + }; + Offset two = { + 100, 250 + }; + Offset three = { + 250, 250 + }; + + file.missing_offsets->push(file.missing_offsets, &one, -1); + file.missing_offsets->push(file.missing_offsets, &two, -1); + file.missing_offsets->push(file.missing_offsets, &three, -1); + req->file = &file; + + + Request got_req; + + error = save_req_to_file(req); + if (error < 0) + printf("failed to write\n"); + + error = get_req_from_file(2, 2, &got_req); + if (error < 0) + printf("failed to write\n"); + + + print_request_state(&got_req); + + return 1; +} + + + + + int file_system_tests() { int error = 0; - error = test_write_lv(); - error = test_saving_request(); - error = test_save_file(); + //error = test_write_lv(); + //error = test_saving_request(); + //error = test_save_file(); + error = test_save_file_and_messages(); return error; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 04096ee..afca593 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -303,7 +303,7 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ packet_index = add_messages_to_packet(packet, packet_index, req->messages_to_user); ASSERT_EQUALS_STR("'cfdp' should be at the start of the message", &packet[start], "cfdp", 5); - ASSERT_EQUALS_INT("testing PROXY_PUT_REQUEST code", (uint8_t) packet[start + 5], PROXY_CONTINUE_PARTIAL); + ASSERT_EQUALS_INT("testing CONTINUE_PARTIAL code", (uint8_t) packet[start + 5], CONTINUE_PARTIAL); LV dest_id, original_id, transaction_id; @@ -493,7 +493,7 @@ int packet_tests() { test_add_messages_to_packet(packet, data_start_index); test_get_message_from_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); - + test_add_cont_part_to_packet(packet, data_start_index); return 0; } diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 2ffb130..62e7b1d 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -191,6 +191,24 @@ int test_lv_functions() { } +int init_cont_partial_request_test() { + Message_cont_part_request p_cont; + uint32_t dest_id = 3; + uint32_t org_id = 4; + uint64_t tran_id = 1; + + p_cont.destination_id.value = &dest_id; + p_cont.originator_id.value = &org_id; + p_cont.transaction_id.value = &tran_id; + uint32_t buff_len = 1500; + char buff[buff_len]; + + int error = init_cont_partial_request(&p_cont, buff, buff_len); + if (error < 0) { + ssp_error("whoops\n"); + return -1; + } +} int request_user_input_tests() { @@ -210,5 +228,6 @@ int request_tests() { error = test_lv_functions(); error = add_continue_partial_message(); + error = init_cont_partial_request_test(); return error; } \ No newline at end of file From 97b49ca1d396b689dd9bdeb6240c7bb8f7a1dca1 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 9 Jun 2020 10:35:37 -0600 Subject: [PATCH 242/400] Add continue partial functionality --- Program/include/filesystem_funcs.h | 3 +- Program/include/port.h | 2 +- Program/include/types.h | 1 + Program/src/filesystem_funcs.c | 63 +++++++++++++++++++----------- Program/src/port.c | 5 +++ Program/src/protocol_handler.c | 27 ++++++++----- Program/src/requests.c | 53 +++++++++++++++++-------- Program/test/filesystem_tests.c | 4 +- 8 files changed, 106 insertions(+), 52 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index d541b0e..b279614 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -36,6 +36,7 @@ int read_lv(int fd, LV *lv); int save_req_to_file(Request *req); int save_file_to_file(int fd, File *file); int get_file_from_file(int fd, File *file); -int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req); +int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint32_t my_cfdp_id, Request *req); +int delete_saved_request(Request *req); #endif diff --git a/Program/include/port.h b/Program/include/port.h index 5e01aa6..c485d37 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -78,7 +78,7 @@ int ssp_write(int fd, const void *buf, size_t count); int ssp_close(int fd); void ssp_free(void *pointer); void ssp_thread_join(void *thread_handle); - +int ssp_remove(char *pathname); int ssp_rename(const char *old, const char *new); void reset_request(Request *req); diff --git a/Program/include/types.h b/Program/include/types.h index 90e835a..261ff89 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -597,6 +597,7 @@ typedef struct request { uint64_t transaction_sequence_number; uint32_t dest_cfdp_id; + uint32_t my_cfdp_id; File *file; uint32_t file_size; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index eafccc7..cd7d6e1 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -557,13 +557,25 @@ static int write_file_present_bool(int fd, File *file) { return error; } +static void get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id, uint64_t trans) { + ssp_snprintf(filename, 255, "%s%u%s%u%s%llu%s", "incomplete_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); +} + +int delete_saved_request(Request *req) { + char file_name[255]; + get_file_name(file_name, req->dest_cfdp_id, req->my_cfdp_id, req->transaction_sequence_number); + ssp_printf("deleting %s\n", file_name); + int error = ssp_remove(file_name); + return error; +} + //work in progress //[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] int save_req_to_file(Request *req) { char file_name[255]; - ssp_snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", req->dest_cfdp_id, ":num:", req->transaction_sequence_number, ".binary"); - + get_file_name(file_name, req->dest_cfdp_id, req->my_cfdp_id, req->transaction_sequence_number); + int fd = ssp_open(file_name, O_RDWR | O_CREAT); if (fd < 0) { ssp_error("couldn't open file\n"); @@ -572,8 +584,10 @@ int save_req_to_file(Request *req) { //writing request struct int error = ssp_write(fd, req, sizeof(Request)); - if (error == -1) + if (error == -1) { + ssp_printf("couldnt write request struct\n"); return -1; + } struct params param = { 0, @@ -582,32 +596,41 @@ int save_req_to_file(Request *req) { //writing is file present error = write_file_present_bool(fd, req->file); - if (error < 0) + if (error < 0){ + ssp_printf("couldnt write bool\n"); return -1; + } //writing file if (req->file != NULL) { error = save_file_to_file(fd, req->file); - if (error < 0) + if (error < 0) { + ssp_printf("couldnt write file\n"); return -1; + } } //writing message count error = ssp_write(fd, &req->messages_to_user->count, sizeof(uint8_t)); - if (error == -1) + if (error == -1) { + ssp_printf("couldnt write message count\n"); return -1; + } if (!req->messages_to_user->count) return 0; //writing messages req->messages_to_user->iterate(req->messages_to_user, write_message_callback, ¶m); - if (param.error < 0) + if (param.error < 0) { + ssp_printf("couldnt write messsages\n"); return -1; + } error = ssp_close(fd); if (error < 0) { ssp_error("couldn't close file descriptor\n"); + return -1; } return 0; } @@ -676,9 +699,12 @@ static int get_messages_from_file(int fd, List *messages){ case PROXY_PUT_REQUEST: message = read_in_proxy_message(fd); break; - + case CONTINUE_PARTIAL: + ssp_printf("this type of message is not implmeneted yet\n"); + continue; default: - break; + ssp_printf("failed to read in message, no known message type\n"); + continue; } message->header.message_type = message_type; messages->push(messages, message, -1); @@ -688,12 +714,13 @@ static int get_messages_from_file(int fd, List *messages){ } //[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] -int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Request *req) { +int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint32_t my_cfdp_id, Request *req) { char file_name[255]; - + //will overwrite messages pointer, so we need to save it + List *messages = req->messages_to_user; - ssp_snprintf(file_name, 255, "%s%u%s%llu%s", "incomplete_requests/pending_req_id:", dest_cfdp_id, ":num:", transaction_seq_num, ".binary"); + get_file_name(file_name, dest_cfdp_id, my_cfdp_id, transaction_seq_num); ssp_printf("opening %s\n", file_name); int fd = ssp_open(file_name, O_RDWR); @@ -727,21 +754,13 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, Reque req->file = file; } - List *messages = linked_list(); - if (messages == NULL) { - ssp_free(file); - return -1; - } - - error = get_messages_from_file(fd, messages); + req->messages_to_user = messages; + error = get_messages_from_file(fd, req->messages_to_user); if (error == -1) { ssp_free(file); - messages->freeOnlyList(messages); return -1; } - req->messages_to_user = messages; - error = ssp_close(fd); if (error < 0) { ssp_error("couldn't close file descriptor \n"); diff --git a/Program/src/port.c b/Program/src/port.c index 85ab683..7f1e179 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -77,6 +77,11 @@ int ssp_close(int fd) { #endif } +int ssp_remove(char *pathname){ + #ifdef POSIX_FILESYSTEM + return remove(pathname); + #endif +} /*------------------------------------------------------------------------------ Network port functions, these are used to interchange different network diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1a76221..2e06963 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -102,7 +102,7 @@ static int find_request(void *element, void *args) { found_req->transaction_sequence_number = transaction_sequence_number; found_req->dest_cfdp_id = source_id; found_req->pdu_header = pdu_header; - + found_req->my_cfdp_id = app->my_cfdp_id; found_req->remote_entity = remote_entity; found_req->procedure = sending_put_metadata; @@ -265,8 +265,10 @@ void process_messages(Request *req, FTP *app) { Message *message = req->messages_to_user->pop(req->messages_to_user); Message_put_proxy *p_put; Message_cont_part_request *p_cont; - //int error = 0; + int error = 0; + char *error_msg = "couldn't process messages: %s"; + //on failure, these will send back an error message to the requester switch (message->header.message_type) { case PROXY_PUT_REQUEST: @@ -280,26 +282,31 @@ void process_messages(Request *req, FTP *app) { start_request(put_request(*(uint8_t*)p_put->destination_id.value, (char *)p_put->source_file_name.value, (char *)p_put->destination_file_name.value, ACKNOWLEDGED_MODE, app)); - ssp_free_message(message); break; case CONTINUE_PARTIAL: p_cont = (Message_cont_part_request *) message->value; + uint32_t dest_id = *(uint8_t*)p_cont->destination_id.value; + uint32_t orig_id = *(uint8_t*)p_cont->originator_id.value; + uint32_t tran_id = *(uint8_t*)p_cont->transaction_id.value; + ssp_printf("received message request to continue one way communication destination id %d, originator id %d, transaction id %d\n", - *(uint32_t*)p_cont->destination_id.value, *(uint32_t*)p_cont->originator_id.value, *(uint32_t*)p_cont->transaction_id.value); - + dest_id, orig_id, tran_id); - //error = get_req_from_file(*(uint32_t*)p_cont->destination_id.value, *(uint64_t*)p_cont->transaction_id.value, req); + if (orig_id != app->my_cfdp_id) { + ssp_printf(error_msg, "continue partial request, wrong originator ID"); + return; + } + error = init_cont_partial_request(p_cont, app->buff, app->packet_len); + if (error < 0) + ssp_printf(error_msg, "continue partial request"); default: break; } - if (message->header.message_type == PROXY_PUT_REQUEST){ - - - } + ssp_free_message(message); } diff --git a/Program/src/requests.c b/Program/src/requests.c index 3db2d50..a516659 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -72,31 +72,51 @@ Message *create_message(uint8_t type) { //this will turn a incoming request to a request that will go out later int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uint32_t buff_len) { - Request req; + //don't need these params, just using this function for the req + Request *req = init_request(buff, buff_len); + if (req == NULL) + return -1; - uint32_t dest_id = *(uint32_t*)p_cont->destination_id.value; - uint64_t trans_num = *(uint64_t*)p_cont->transaction_id.value; - uint32_t ord_id = *(uint32_t*)p_cont->originator_id.value; + uint32_t dest_id = *(uint8_t*)p_cont->destination_id.value; + uint64_t trans_num = *(uint8_t*)p_cont->transaction_id.value; + uint32_t src_id = *(uint8_t*)p_cont->originator_id.value; - int error = get_req_from_file(ord_id, trans_num, &req); + int error = get_req_from_file(src_id, trans_num, dest_id, req); if (error < 0) { ssp_error("couldn't get request from file system\n"); return error; } - req.dest_cfdp_id = dest_id; - error = get_remote_entity_from_json(&req.remote_entity, dest_id); + Request old_request = *req; + + req->dest_cfdp_id = dest_id; + req->res.addr = NULL; + + error = get_remote_entity_from_json(&req->remote_entity, dest_id); if (error < 0) { ssp_error("couldn't get remote config from file system\n"); return error; } - req.local_entity.EOF_sent_indication = req.local_entity.EOF_recv_indication; - req.local_entity.Metadata_sent_indication = req.local_entity.Metadata_recv_indication; - req.local_entity.resumed_indication = 1; - req.local_entity.suspended_indication = 0; - req.local_entity.transaction_finished_indication = 0; - - get_header_from_mib(&req.pdu_header, req.remote_entity, req.dest_cfdp_id); - save_req_to_file(&req); + req->local_entity.EOF_sent_indication = req->local_entity.EOF_recv_indication; + req->local_entity.Metadata_sent_indication = req->local_entity.Metadata_recv_indication; + req->local_entity.resumed_indication = 1; + req->local_entity.suspended_indication = 0; + req->local_entity.transaction_finished_indication = 0; + req->my_cfdp_id = src_id; + get_header_from_mib(&req->pdu_header, req->remote_entity, req->dest_cfdp_id); + + error = save_req_to_file(req); + if (error < 0) { + ssp_error("couldn't save req to file\n"); + return -1; + } + //delete old file + error = delete_saved_request(&old_request); + if (error < 0) { + ssp_error("couldn't remove saved request\n"); + return -1; + } + ssp_cleanup_req(req); + return 1; } @@ -299,7 +319,8 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { req->pdu_header = client->pdu_header; req->res.packet_len = client->packet_len; req->buff = client->buff; - + req->my_cfdp_id = app->my_cfdp_id; + client->request_list->insert(client->request_list, req, 0); return req; diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index a5ef170..d4c2f3d 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -182,7 +182,7 @@ static int test_saving_request(){ //---------------------------GETTING REQUEST-------------------------------- Request got_req; - error = get_req_from_file(1, 1, &got_req); + error = get_req_from_file(1, 1, 1, &got_req); if (error < 0) printf("failed to write\n"); @@ -269,7 +269,7 @@ int test_save_file_and_messages() { if (error < 0) printf("failed to write\n"); - error = get_req_from_file(2, 2, &got_req); + error = get_req_from_file(2, 2, 2, &got_req); if (error < 0) printf("failed to write\n"); From 6e844f3626d231b103ee0cab827c13cc8c2a0c06 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 12 Jun 2020 20:11:24 -0600 Subject: [PATCH 243/400] Fix memory cleanup on error, add better tests --- Program/src/requests.c | 7 ++++- Program/test/mib/peer_1.json | 3 +-- Program/test/mib/peer_2.json | 3 +-- Program/test/mib/peer_3.json | 23 ++++++++++++++++ Program/test/mib/peer_4.json | 23 ++++++++++++++++ Program/test/mib/peer_5.json | 23 ++++++++++++++++ Program/test/mib/peer_6.json | 23 ++++++++++++++++ Program/test/mib/peer_7.json | 23 ++++++++++++++++ Program/test/mib/peer_8.json | 23 ++++++++++++++++ Program/test/request_tests.c | 52 +++++++++++++++++++++++++++++++----- 10 files changed, 191 insertions(+), 12 deletions(-) create mode 100644 Program/test/mib/peer_3.json create mode 100644 Program/test/mib/peer_4.json create mode 100644 Program/test/mib/peer_5.json create mode 100644 Program/test/mib/peer_6.json create mode 100644 Program/test/mib/peer_7.json create mode 100644 Program/test/mib/peer_8.json diff --git a/Program/src/requests.c b/Program/src/requests.c index a516659..335563c 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -84,6 +84,7 @@ int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uin int error = get_req_from_file(src_id, trans_num, dest_id, req); if (error < 0) { ssp_error("couldn't get request from file system\n"); + ssp_cleanup_req(req); return error; } Request old_request = *req; @@ -94,25 +95,29 @@ int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uin error = get_remote_entity_from_json(&req->remote_entity, dest_id); if (error < 0) { ssp_error("couldn't get remote config from file system\n"); + ssp_cleanup_req(req); return error; } req->local_entity.EOF_sent_indication = req->local_entity.EOF_recv_indication; req->local_entity.Metadata_sent_indication = req->local_entity.Metadata_recv_indication; - req->local_entity.resumed_indication = 1; + req->local_entity.resumed_indication = 0; req->local_entity.suspended_indication = 0; req->local_entity.transaction_finished_indication = 0; req->my_cfdp_id = src_id; + get_header_from_mib(&req->pdu_header, req->remote_entity, req->dest_cfdp_id); error = save_req_to_file(req); if (error < 0) { ssp_error("couldn't save req to file\n"); + ssp_cleanup_req(req); return -1; } //delete old file error = delete_saved_request(&old_request); if (error < 0) { ssp_error("couldn't remove saved request\n"); + ssp_cleanup_req(req); return -1; } ssp_cleanup_req(req); diff --git a/Program/test/mib/peer_1.json b/Program/test/mib/peer_1.json index 5fbf6b4..9ae6348 100644 --- a/Program/test/mib/peer_1.json +++ b/Program/test/mib/peer_1.json @@ -5,7 +5,7 @@ "type_of_network" : 1, "default_transmission_mode" : 1, "MTU" : 1500, - + "one_way_light_time" : 123, "total_round_trip_allowance" : 123, "async_NAK_interval" : 123, @@ -16,7 +16,6 @@ "disposition_of_incomplete" : 123, "CRC_required" : 0, - "max_file_segment_len" : 1200, "keep_alive_discrepancy_limit" : 8, "positive_ack_timer_expiration_limit" : 123, "nak_timer_expiration_limit" : 123, diff --git a/Program/test/mib/peer_2.json b/Program/test/mib/peer_2.json index 30a15e5..7ef92a4 100644 --- a/Program/test/mib/peer_2.json +++ b/Program/test/mib/peer_2.json @@ -5,7 +5,7 @@ "type_of_network" : 1, "default_transmission_mode" : 1, "MTU" : 1500, - + "one_way_light_time" : 123, "total_round_trip_allowance" : 123, "async_NAK_interval" : 123, @@ -16,7 +16,6 @@ "disposition_of_incomplete" : 123, "CRC_required" : 0, - "max_file_segment_len" : 1200, "keep_alive_discrepancy_limit" : 8, "positive_ack_timer_expiration_limit" : 123, "nak_timer_expiration_limit" : 123, diff --git a/Program/test/mib/peer_3.json b/Program/test/mib/peer_3.json new file mode 100644 index 0000000..daed8d0 --- /dev/null +++ b/Program/test/mib/peer_3.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 3, + "UT_address" : 2130706433, + "UT_port" : 1113, + "type_of_network" : 0, + "default_transmission_mode" : 1, + "MTU" : 1500, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/mib/peer_4.json b/Program/test/mib/peer_4.json new file mode 100644 index 0000000..8b31a83 --- /dev/null +++ b/Program/test/mib/peer_4.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 4, + "UT_address" : 2130706433, + "UT_port" : 1114, + "type_of_network" : 0, + "default_transmission_mode" : 1, + "MTU" : 1500, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/mib/peer_5.json b/Program/test/mib/peer_5.json new file mode 100644 index 0000000..41b5969 --- /dev/null +++ b/Program/test/mib/peer_5.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 5, + "UT_address" : 1, + "UT_port" : 1, + "type_of_network" : 2, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/mib/peer_6.json b/Program/test/mib/peer_6.json new file mode 100644 index 0000000..2d8f164 --- /dev/null +++ b/Program/test/mib/peer_6.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 6, + "UT_address" : 1, + "UT_port" : 2, + "type_of_network" : 2, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/mib/peer_7.json b/Program/test/mib/peer_7.json new file mode 100644 index 0000000..c71bac5 --- /dev/null +++ b/Program/test/mib/peer_7.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 7, + "UT_address" : 1, + "UT_port" : 5, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/mib/peer_8.json b/Program/test/mib/peer_8.json new file mode 100644 index 0000000..7ef170c --- /dev/null +++ b/Program/test/mib/peer_8.json @@ -0,0 +1,23 @@ +{ + "cfdp_id": 8, + "UT_address" : 1, + "UT_port" : 4, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 62e7b1d..aaf0015 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -191,12 +191,39 @@ int test_lv_functions() { } +int init_cont_partial_request_test_fail() { + Message_cont_part_request p_cont; + uint32_t dest_id = 0; + uint32_t org_id = 1; + uint64_t tran_id = 0; + Request *req = mock_request(); + + p_cont.destination_id.value = &dest_id; + p_cont.originator_id.value = &org_id; + p_cont.transaction_id.value = &tran_id; + uint32_t buff_len = 1500; + char buff[buff_len]; + + int error = init_cont_partial_request(&p_cont, buff, buff_len); + ASSERT_EQUALS_INT("failed to write, errored", error, -1); + ssp_cleanup_req(req); +} + int init_cont_partial_request_test() { Message_cont_part_request p_cont; uint32_t dest_id = 3; - uint32_t org_id = 4; + uint32_t org_id = 2; uint64_t tran_id = 1; - + + Request *req = mock_request(); + req->transaction_sequence_number = 1; + req->dest_cfdp_id = 2; + req->my_cfdp_id = 3; + req->local_entity.EOF_recv_indication = 1; + req->local_entity.Metadata_recv_indication = 1; + + save_req_to_file(req); + p_cont.destination_id.value = &dest_id; p_cont.originator_id.value = &org_id; p_cont.transaction_id.value = &tran_id; @@ -204,10 +231,19 @@ int init_cont_partial_request_test() { char buff[buff_len]; int error = init_cont_partial_request(&p_cont, buff, buff_len); - if (error < 0) { - ssp_error("whoops\n"); - return -1; - } + + Request *req2 = mock_empty_request(); + get_req_from_file(dest_id, tran_id, org_id, req2); + ASSERT_EQUALS_INT("eof received, don't resend. local_entity.eof_recv = 1", + req->local_entity.EOF_recv_indication, + req2->local_entity.EOF_sent_indication); + + ASSERT_EQUALS_INT("metadata received, don't resend. local_entity.Metadata_sent = 1", + req->local_entity.Metadata_recv_indication, + req2->local_entity.Metadata_sent_indication); + + ssp_cleanup_req(req); + ssp_cleanup_req(req2); } int request_user_input_tests() { @@ -222,12 +258,14 @@ int request_user_input_tests() { int request_tests() { int error = 0; + error = request_finding_test(); error = request_user_input_tests(); error = add_proxy_message(); error = test_lv_functions(); error = add_continue_partial_message(); - + error = init_cont_partial_request_test_fail(); error = init_cont_partial_request_test(); + return error; } \ No newline at end of file From e3d77f3758fd36c443f083ad02447db719a81008 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 12 Jun 2020 21:37:25 -0600 Subject: [PATCH 244/400] fix some unit test stuff --- Program/include/port.h | 3 + Program/src/port.c | 4 +- Program/test/filesystem_tests.c | 98 +++++++++++++++------------ Program/test/mock.c | 22 +++--- Program/test/protocol_handler_tests.c | 29 ++++---- 5 files changed, 86 insertions(+), 70 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index c485d37..cd0c18f 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -13,6 +13,9 @@ Author: Evan Giese #define POSIX_FILESYSTEM //#define CSP_NETWORK +//comment this out if you want to sendto function to actually work +#define TEST + #include "types.h" #ifdef CSP_NETWORK diff --git a/Program/src/port.c b/Program/src/port.c index 7f1e179..cc0a13b 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -89,7 +89,9 @@ int ssp_remove(char *pathname){ ------------------------------------------------------------------------------*/ void ssp_sendto(Response res) { - + #ifdef TEST + return; + #endif if (res.type_of_network == csp_connectionless) { #ifdef CSP_NETWORK csp_packet_t *packet = (csp_packet_t *) res.addr; diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index d4c2f3d..3728e0b 100644 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -158,6 +158,8 @@ static int test_saving_request(){ req->dest_cfdp_id = 1; req->transaction_sequence_number = 1; + req->my_cfdp_id = 1; + req->local_entity.EOF_recv_indication = 1; req->local_entity.EOF_sent_indication = 1; req->local_entity.suspended_indication = 1; @@ -168,50 +170,58 @@ static int test_saving_request(){ m->value = create_message_put_proxy(1, 1, src_file, dest_file); req->messages_to_user->push(req->messages_to_user, m, 0); - m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m, 0); + Message *m2 = create_message(PROXY_PUT_REQUEST); + m2->value = create_message_put_proxy(1, 1, src_file, dest_file); + req->messages_to_user->push(req->messages_to_user, m2, 0); - m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m, 0); + Message *m3 = create_message(PROXY_PUT_REQUEST); + m3->value = create_message_put_proxy(1, 1, src_file, dest_file); + req->messages_to_user->push(req->messages_to_user, m3, 0); error = save_req_to_file(req); if (error == -1) printf("failed to write\n"); - //---------------------------GETTING REQUEST-------------------------------- - Request got_req; - error = get_req_from_file(1, 1, 1, &got_req); + ssp_cleanup_req(req); +} + +int test_get_file(){ + DECLARE_NEW_TEST("test getting requests"); + Request *req = mock_empty_request(); + char *dest_file = "stuff"; + char *src_file = "morestuff"; + + int error = get_req_from_file(1, 1, 1, req); if (error < 0) - printf("failed to write\n"); + printf("failed to read\n"); - Message *message = got_req.messages_to_user->pop(got_req.messages_to_user); + Message *message = req->messages_to_user->pop(req->messages_to_user); Message_put_proxy *proxy_message = (Message_put_proxy *) message->value; - + ASSERT_EQUALS_STR("third message src file name", proxy_message->destination_file_name.value, dest_file, proxy_message->destination_file_name.length); ASSERT_EQUALS_STR("third message src file name", proxy_message->source_file_name.value, src_file, proxy_message->source_file_name.length); ASSERT_EQUALS_INT("third message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + ssp_free_message(message); - message = got_req.messages_to_user->pop(got_req.messages_to_user); + message = req->messages_to_user->pop(req->messages_to_user); proxy_message = (Message_put_proxy *) message->value; ASSERT_EQUALS_STR("second message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); ASSERT_EQUALS_STR("second message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); ASSERT_EQUALS_INT("second message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + ssp_free_message(message); - message = got_req.messages_to_user->pop(got_req.messages_to_user); + message = req->messages_to_user->pop(req->messages_to_user); proxy_message = (Message_put_proxy *) message->value; ASSERT_EQUALS_STR("first message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); ASSERT_EQUALS_STR("first message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); ASSERT_EQUALS_INT("first message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + ssp_free_message(message); ssp_cleanup_req(req); - got_req.messages_to_user->free(got_req.messages_to_user, ssp_free_message); //need to free list return error; } - int test_save_file_and_messages() { DECLARE_NEW_TEST("test saving file and messages"); @@ -220,9 +230,11 @@ int test_save_file_and_messages() { req->dest_cfdp_id = 2; req->transaction_sequence_number = 2; + req->my_cfdp_id = 2; req->local_entity.EOF_recv_indication = 1; req->local_entity.EOF_sent_indication = 1; req->local_entity.suspended_indication = 1; + req->file = NULL; char *dest_file = "stuff"; char *src_file = "morestuff"; @@ -242,39 +254,40 @@ int test_save_file_and_messages() { if (error == -1) printf("failed to write\n"); - File file; - memset(&file, 0, sizeof(File)); - file.missing_offsets = linked_list(); + File *file = ssp_alloc(1, sizeof(File)); + file->missing_offsets = linked_list(); - Offset one = { - 0, 250 - }; - Offset two = { - 100, 250 - }; - Offset three = { - 250, 250 - }; - - file.missing_offsets->push(file.missing_offsets, &one, -1); - file.missing_offsets->push(file.missing_offsets, &two, -1); - file.missing_offsets->push(file.missing_offsets, &three, -1); - req->file = &file; - - - Request got_req; + + Offset *one = ssp_alloc(1, sizeof(Offset)); + Offset *two = ssp_alloc(1, sizeof(Offset)); + Offset *three = ssp_alloc(1, sizeof(Offset)); + + one->start = 0; + one->end = 250; + two->start = 100; + two->end = 250; + three->start = 250; + three->end = 250; + + file->missing_offsets->push(file->missing_offsets, one, -1); + file->missing_offsets->push(file->missing_offsets, two, -1); + file->missing_offsets->push(file->missing_offsets, three, -1); + req->file = file; error = save_req_to_file(req); if (error < 0) printf("failed to write\n"); + + Request *got_req = mock_empty_request(); - error = get_req_from_file(2, 2, 2, &got_req); + error = get_req_from_file(2, 2, 2, got_req); if (error < 0) printf("failed to write\n"); - - print_request_state(&got_req); + print_request_state(got_req); + ssp_cleanup_req(req); + ssp_cleanup_req(got_req); return 1; } @@ -285,9 +298,10 @@ int test_save_file_and_messages() { int file_system_tests() { int error = 0; - //error = test_write_lv(); - //error = test_saving_request(); - //error = test_save_file(); + error = test_write_lv(); + error = test_saving_request(); + error = test_save_file(); + error = test_get_file(); error = test_save_file_and_messages(); return error; } diff --git a/Program/test/mock.c b/Program/test/mock.c index ab2aa12..61ea0c9 100644 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -13,6 +13,7 @@ #include #include +char buff[1500]; void mock_mock_remote_entity(Remote_entity *remote_entity, uint32_t cfdp_id) { @@ -29,7 +30,7 @@ void mock_mock_remote_entity(Remote_entity *remote_entity, uint32_t cfdp_id) { remote_entity->default_transmission_mode= 1; remote_entity->disposition_of_incomplete= 1; remote_entity->CRC_required= 1; - remote_entity->mtu= 1500; + remote_entity->mtu = 1500; remote_entity->keep_alive_discrepancy_limit= 1; remote_entity->positive_ack_timer_expiration_limit= 1; remote_entity->nak_timer_expiration_limit= 1; @@ -47,7 +48,6 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { int error = get_header_from_mib(&pdu_header, remote_entity, src_id); int packet_index = build_pdu_header(packet, 1, 0, &pdu_header); - return packet_index; } @@ -62,7 +62,7 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *fil } -Response *mock_response() { +Response *mock_response(char *buffer) { Response *res = calloc(1, sizeof(Response)); int addr = 16; res->addr = &addr; @@ -71,20 +71,17 @@ Response *mock_response() { res->size_of_addr = 16; res->type_of_network = posix_connectionless; res->transmission_mode = UN_ACKNOWLEDGED_MODE; + res->msg = buffer; return res; } Request *mock_empty_request() { - char *buff = ssp_alloc(1500, 1); - Request *req = ssp_alloc(1, sizeof(Request)); - req->messages_to_user = linked_list(); - req->buff = buff; - req->file = NULL; - return req; - + return init_request(buff, sizeof(buff)); } + Request *mock_request() { + Request *req = mock_empty_request(); char *dest = "test_files/dest"; @@ -95,7 +92,6 @@ Request *mock_request() { req->file = create_file("test_files/dest_received.jpg", true); ssp_memcpy (req->source_file_name, dest, strnlen(dest, 255)); ssp_memcpy (req->destination_file_name, src, strnlen(src, 255)); - mock_mock_remote_entity(&req->remote_entity, id); get_header_from_mib(&req->pdu_header, req->remote_entity, 1); @@ -104,13 +100,11 @@ Request *mock_request() { req->res.addr = malloc(5); ssp_memcpy(req->res.addr, &addr, 4); req->res.sfd = 1; - req->res.packet_len = 2000; + req->res.packet_len = sizeof(buff); req->res.size_of_addr = 16; req->res.type_of_network = posix_connectionless; req->res.transmission_mode = UN_ACKNOWLEDGED_MODE; req->res.msg = req->buff; - req->messages_to_user = linked_list(); - return req; } \ No newline at end of file diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index b4d3d8b..ed8e5f5 100644 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -29,7 +29,6 @@ static int test_process_pdu_eof() { ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); - free(req->buff); ssp_cleanup_req(req); //test empty files @@ -43,8 +42,6 @@ static int test_process_pdu_eof() { ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); - - free(req->buff); ssp_cleanup_req(req); return 0; } @@ -70,8 +67,7 @@ int test_on_server_time_out() { on_server_time_out(req->res, req); - //file equals null, should return. - //on_server_time_out(req->res, req); + ssp_cleanup_req(req); return 0; } @@ -81,7 +77,7 @@ static int test_wrong_id(FTP *app) { int error = 0; Response *res = mock_response(); char packet[2000]; - + int packet_index = mock_packet(packet, 2, 1); Request **req_container = &app->current_request; @@ -103,6 +99,7 @@ static int test_correct_id(FTP *app) { char packet[2000]; int packet_index = mock_packet(packet, 1, 2); + set_data_length(packet, 100); Request **req_container = &app->current_request; process_pdu_header(packet, true, *res, req_container, app->request_list, app); Request *req = (*req_container); @@ -116,22 +113,28 @@ static int test_correct_id(FTP *app) { return error; } -static int test_process_pdu_header(FTP *app) { - +static int test_process_pdu_header() { + char buff[1500]; int error = 0; + FTP *app = ssp_alloc(1, sizeof(FTP)); + app->request_list = linked_list(); + app->packet_len = 1500; + app->buff = buff; + app->my_cfdp_id = 1; + error = test_wrong_id(app); error = test_correct_id(app); + app->request_list->free(app->request_list, ssp_cleanup_req); + ssp_free(app); + return error; } int protocol_handler_test() { int error = 0; - FTP *app = init_ftp(1); - error = test_process_pdu_header(app); + error = test_process_pdu_header(); error = test_process_pdu_eof(); - //error = test_on_server_time_out(); - app->close = true; - ssp_thread_join(app->server_handle); + error = test_on_server_time_out(); return error; } \ No newline at end of file From 0f94a4770fcfb2e4c5dd295361a2edf4c615d0be Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 15 Jun 2020 21:51:20 -0600 Subject: [PATCH 245/400] add directories to partial requests --- Program/include/port.h | 4 +- Program/include/protocol_handler.h | 1 + Program/include/types.h | 3 +- Program/src/port.c | 24 ++++++ Program/src/protocol_handler.c | 96 +++++++++++------------ Program/src/requests.c | 4 +- Program/src/tasks.c | 14 +++- Program/test/request_tests.c | 119 +++++++++++++++-------------- 8 files changed, 154 insertions(+), 111 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index cd0c18f..52ccbb2 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -14,7 +14,7 @@ Author: Evan Giese //#define CSP_NETWORK //comment this out if you want to sendto function to actually work -#define TEST +//#define TEST #include "types.h" @@ -31,6 +31,7 @@ Author: Evan Giese #ifdef POSIX_FILESYSTEM #include + #include #define SSP_O_RDWR O_RDWR #define SSP_O_CREAT O_CREAT #define SSP_O_TRUNC O_TRUNC @@ -83,6 +84,7 @@ void ssp_free(void *pointer); void ssp_thread_join(void *thread_handle); int ssp_remove(char *pathname); int ssp_rename(const char *old, const char *new); +int ssp_mkdir(char *dir_name); void reset_request(Request *req); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 2527ffa..23162a9 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -11,6 +11,7 @@ Author: Evan Giese #define RESEND_EOF_TIMES 3 #define RESEND_FINISHED_TIMES 10 #define TIMEOUT_BEFORE_CANCEL_REQUEST 30 +#define TIMEOUT_BEFORE_SAVE_REQUEST 5 int parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); void user_request_handler(Response res, Request *req, Client *client); diff --git a/Program/include/types.h b/Program/include/types.h index 261ff89..ae79485 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -606,7 +606,8 @@ typedef struct request { char destination_file_name[MAX_PATH]; //previous timeout time in seconds - int timeout; + int timeout_before_cancel; + int timeout_before_journal; uint8_t segmentation_control; uint8_t fault_handler_overides; diff --git a/Program/src/port.c b/Program/src/port.c index cc0a13b..2c32b2b 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -41,12 +41,14 @@ int ssp_rename(const char *old, const char *new) { #ifdef POSIX_FILESYSTEM return rename(old, new); #endif + return -1; } int ssp_write(int fd, const void *buf, size_t count) { #ifdef POSIX_FILESYSTEM return write(fd, buf, count); #endif + return -1; } @@ -54,6 +56,7 @@ int ssp_read(int fd, char* buff, size_t size) { #ifdef POSIX_FILESYSTEM return read(fd, buff, size); #endif + return -1; } @@ -62,6 +65,7 @@ int ssp_lseek(int fd, int offset, int whence) { #ifdef POSIX_FILESYSTEM return lseek(fd, offset, whence); #endif + return -1; } int ssp_open(char *pathname, int flags) { @@ -69,20 +73,40 @@ int ssp_open(char *pathname, int flags) { //open with read and write permissions return open(pathname, flags, 0666); #endif + return -1; } int ssp_close(int fd) { #ifdef POSIX_FILESYSTEM return close(fd); #endif + return -1; } int ssp_remove(char *pathname){ #ifdef POSIX_FILESYSTEM return remove(pathname); #endif + return -1; } +int ssp_mkdir(char *dir_name) { + #ifdef POSIX_FILESYSTEM + int error = mkdir(dir_name, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (error < 0) { + if(errno == EEXIST) { + return 1; + } + ssp_printf("couldn't make dir\n"); + return -1; + } + else { + return 1; + } + return -1; + + #endif +} /*------------------------------------------------------------------------------ Network port functions, these are used to interchange different network stacks diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2e06963..d93f527 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -257,56 +257,58 @@ uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) return packet_index; } + void process_messages(Request *req, FTP *app) { - if (req->messages_to_user->count == 0) - return; - - Message *message = req->messages_to_user->pop(req->messages_to_user); - Message_put_proxy *p_put; - Message_cont_part_request *p_cont; - int error = 0; - char *error_msg = "couldn't process messages: %s"; - - //on failure, these will send back an error message to the requester - switch (message->header.message_type) - { - case PROXY_PUT_REQUEST: - - p_put = (Message_put_proxy *) message->value; - ssp_printf("received proxy request for source file name: %s dest file name %s, to id %d\n", - (char *)p_put->source_file_name.value, - (char *)p_put->destination_file_name.value, - *(uint8_t*)p_put->destination_id.value); - - start_request(put_request(*(uint8_t*)p_put->destination_id.value, - (char *)p_put->source_file_name.value, - (char *)p_put->destination_file_name.value, ACKNOWLEDGED_MODE, app)); - break; + while (req->messages_to_user->count) { + Message *message = req->messages_to_user->pop(req->messages_to_user); + Message_put_proxy *p_put; + Message_cont_part_request *p_cont; + int error = 0; + char *error_msg = "couldn't process messages: %s"; + + //on failure, these will send back an error message to the requester + switch (message->header.message_type) + { + case PROXY_PUT_REQUEST: + + p_put = (Message_put_proxy *) message->value; + ssp_printf("received proxy request for source file name: %s dest file name %s, to id %d\n", + (char *)p_put->source_file_name.value, + (char *)p_put->destination_file_name.value, + *(uint8_t*)p_put->destination_id.value); + + start_request(put_request(*(uint8_t*)p_put->destination_id.value, + (char *)p_put->source_file_name.value, + (char *)p_put->destination_file_name.value, ACKNOWLEDGED_MODE, app)); + break; - case CONTINUE_PARTIAL: - - p_cont = (Message_cont_part_request *) message->value; - uint32_t dest_id = *(uint8_t*)p_cont->destination_id.value; - uint32_t orig_id = *(uint8_t*)p_cont->originator_id.value; - uint32_t tran_id = *(uint8_t*)p_cont->transaction_id.value; - - ssp_printf("received message request to continue one way communication destination id %d, originator id %d, transaction id %d\n", - dest_id, orig_id, tran_id); - - if (orig_id != app->my_cfdp_id) { - ssp_printf(error_msg, "continue partial request, wrong originator ID"); - return; - } - - error = init_cont_partial_request(p_cont, app->buff, app->packet_len); - if (error < 0) - ssp_printf(error_msg, "continue partial request"); - - default: - break; - } - ssp_free_message(message); + case CONTINUE_PARTIAL: + + p_cont = (Message_cont_part_request *) message->value; + uint32_t dest_id = *(uint8_t*)p_cont->destination_id.value; + uint32_t orig_id = *(uint8_t*)p_cont->originator_id.value; + uint32_t tran_id = *(uint8_t*)p_cont->transaction_id.value; + + ssp_printf("received message request to continue one way communication destination id %d, originator id %d, transaction id %d\n", + dest_id, orig_id, tran_id); + + if (orig_id != app->my_cfdp_id) { + ssp_printf(error_msg, "continue partial request, wrong originator ID"); + return; + } + + error = init_cont_partial_request(p_cont, app->buff, app->packet_len); + if (error < 0) + ssp_printf(error_msg, "continue partial request\n"); + break; + + default: + ssp_printf("message type not recognized\n"); + break; + } + ssp_free_message(message); + } } diff --git a/Program/src/requests.c b/Program/src/requests.c index 335563c..37881c3 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -121,7 +121,6 @@ int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uin return -1; } ssp_cleanup_req(req); - return 1; } @@ -289,7 +288,8 @@ Request *init_request(char *buff, uint32_t buff_len) { req->buff = buff; req->procedure = none; req->paused = true; - req->timeout = ssp_time_count(); + req->timeout_before_cancel = ssp_time_count(); + req->timeout_before_journal = ssp_time_count(); req->res.msg = req->buff; req->messages_to_user = linked_list(); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index bae000d..13a9234 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -61,7 +61,7 @@ static int check_timeout(int *prevtime, uint32_t timeout) { //sets request procedure as clean_up if ttl has passed static void timeout(Request *req) { - bool is_timeout = check_timeout(&req->timeout, TIMEOUT_BEFORE_CANCEL_REQUEST); + bool is_timeout = check_timeout(&req->timeout_before_cancel, TIMEOUT_BEFORE_CANCEL_REQUEST); if (is_timeout) { if (req->local_entity.transaction_finished_indication){ ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); @@ -71,6 +71,14 @@ static void timeout(Request *req) { save_req_to_file(req); } req->procedure = clean_up; + } + + is_timeout = check_timeout(&req->timeout_before_journal, TIMEOUT_BEFORE_SAVE_REQUEST); + if (is_timeout) { + int error = save_req_to_file(req); + if (error < 0) { + ssp_printf("couldn't journal file\n"); + } } } @@ -101,7 +109,7 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, u int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); - reset_timeout(¤t_request->timeout); + reset_timeout(¤t_request->timeout_before_cancel); memset(packet, 0, count); @@ -139,7 +147,7 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u parse_packet_client(packet, packet_index, res, current_request, client); - reset_timeout(¤t_request->timeout); + reset_timeout(¤t_request->timeout_before_cancel); memset(packet, 0, packet_len); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index aaf0015..eb3e7e6 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -103,7 +103,6 @@ static void request_test_list_storage() { ssp_cleanup_req(list->pop(list)); list->iterate(list, list_print, NULL); list->free(list, ssp_cleanup_req); - } static int add_proxy_message() { @@ -128,10 +127,65 @@ static int add_proxy_message() { ssp_free_message(message); ssp_cleanup_req(req); return 0; +} + +int init_cont_partial_request_test_fail() { + Message_cont_part_request p_cont; + uint32_t dest_id = 0; + uint32_t org_id = 1; + uint64_t tran_id = 0; + Request *req = mock_request(); + + p_cont.destination_id.value = &dest_id; + p_cont.originator_id.value = &org_id; + p_cont.transaction_id.value = &tran_id; + uint32_t buff_len = 1500; + char buff[buff_len]; + + int error = init_cont_partial_request(&p_cont, buff, buff_len); + ASSERT_EQUALS_INT("failed to write, errored", error, -1); + ssp_cleanup_req(req); } -static int add_continue_partial_message() { +int init_cont_partial_request_test() { + Message_cont_part_request p_cont; + uint32_t dest_id = 3; + uint32_t org_id = 2; + uint64_t tran_id = 1; + + Request *req = mock_request(); + req->transaction_sequence_number = 1; + req->dest_cfdp_id = 2; + req->my_cfdp_id = 3; + req->local_entity.EOF_recv_indication = 1; + req->local_entity.Metadata_recv_indication = 1; + + save_req_to_file(req); + + p_cont.destination_id.value = &dest_id; + p_cont.originator_id.value = &org_id; + p_cont.transaction_id.value = &tran_id; + uint32_t buff_len = 1500; + char buff[buff_len]; + + int error = init_cont_partial_request(&p_cont, buff, buff_len); + + Request *req2 = mock_empty_request(); + get_req_from_file(dest_id, tran_id, org_id, req2); + ASSERT_EQUALS_INT("eof received, don't resend. local_entity.eof_recv = 1", + req->local_entity.EOF_recv_indication, + req2->local_entity.EOF_sent_indication); + + ASSERT_EQUALS_INT("metadata received, don't resend. local_entity.Metadata_sent = 1", + req->local_entity.Metadata_recv_indication, + req2->local_entity.Metadata_sent_indication); + + ssp_cleanup_req(req); + ssp_cleanup_req(req2); +} + +static int add_continue_partial_message_test() { int error = 0; Request *req = mock_empty_request(); @@ -191,60 +245,6 @@ int test_lv_functions() { } -int init_cont_partial_request_test_fail() { - Message_cont_part_request p_cont; - uint32_t dest_id = 0; - uint32_t org_id = 1; - uint64_t tran_id = 0; - Request *req = mock_request(); - - p_cont.destination_id.value = &dest_id; - p_cont.originator_id.value = &org_id; - p_cont.transaction_id.value = &tran_id; - uint32_t buff_len = 1500; - char buff[buff_len]; - - int error = init_cont_partial_request(&p_cont, buff, buff_len); - ASSERT_EQUALS_INT("failed to write, errored", error, -1); - ssp_cleanup_req(req); -} - -int init_cont_partial_request_test() { - Message_cont_part_request p_cont; - uint32_t dest_id = 3; - uint32_t org_id = 2; - uint64_t tran_id = 1; - - Request *req = mock_request(); - req->transaction_sequence_number = 1; - req->dest_cfdp_id = 2; - req->my_cfdp_id = 3; - req->local_entity.EOF_recv_indication = 1; - req->local_entity.Metadata_recv_indication = 1; - - save_req_to_file(req); - - p_cont.destination_id.value = &dest_id; - p_cont.originator_id.value = &org_id; - p_cont.transaction_id.value = &tran_id; - uint32_t buff_len = 1500; - char buff[buff_len]; - - int error = init_cont_partial_request(&p_cont, buff, buff_len); - - Request *req2 = mock_empty_request(); - get_req_from_file(dest_id, tran_id, org_id, req2); - ASSERT_EQUALS_INT("eof received, don't resend. local_entity.eof_recv = 1", - req->local_entity.EOF_recv_indication, - req2->local_entity.EOF_sent_indication); - - ASSERT_EQUALS_INT("metadata received, don't resend. local_entity.Metadata_sent = 1", - req->local_entity.Metadata_recv_indication, - req2->local_entity.Metadata_sent_indication); - - ssp_cleanup_req(req); - ssp_cleanup_req(req2); -} int request_user_input_tests() { @@ -255,6 +255,11 @@ int request_user_input_tests() { ssp_thread_join(app->server_handle); } +int test_process_messages() { + + process_messages(Request *req, FTP *app) +} + int request_tests() { int error = 0; @@ -263,7 +268,7 @@ int request_tests() { error = request_user_input_tests(); error = add_proxy_message(); error = test_lv_functions(); - error = add_continue_partial_message(); + error = add_continue_partial_message_test(); error = init_cont_partial_request_test_fail(); error = init_cont_partial_request_test(); From cc62deae9fe75709e53e20c97d8b4452ec63cc34 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 27 Jun 2020 14:19:14 -0600 Subject: [PATCH 246/400] Fix Nak bug, where datapackets were stack smashing if NAK was too big --- Program/src/packet.c | 55 ++++++++++++++++++++-------------- Program/src/protocol_handler.c | 6 ++-- Program/test/packet_tests.c | 36 +++++++++++++++++++++- Program/test/request_tests.c | 3 +- 4 files changed, 74 insertions(+), 26 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index e4f8884..6a30eb6 100644 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -234,19 +234,29 @@ void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t } //this is a callback for building nak_array server side -struct offset_holder { - Offset *offsets; - int i; +struct packet_nak_helper { + char*packet; + uint64_t max_number_of_nak_segments; + uint64_t current_number_of_segments; + uint32_t start_scope; + uint32_t end_scope; }; void fill_nak_array_callback(Node *node, void *element, void *args){ - struct offset_holder *holder = (struct offset_holder *)args; - + struct packet_nak_helper *holder = (struct packet_nak_helper *)args; + + if (holder->current_number_of_segments == holder->max_number_of_nak_segments) + return; + Offset *offset = (Offset *)element; + Offset offset_to_copy; + offset_to_copy.start = ssp_htonl(offset->start); + offset_to_copy.end = ssp_htonl(offset->end); + + memcpy(holder->packet, &offset_to_copy, sizeof(Offset)); - holder->offsets[holder->i].start = ssp_htonl(offset->start); - holder->offsets[holder->i].end = ssp_htonl(offset->end); - holder->i++; + holder->current_number_of_segments++; + holder->packet+=sizeof(Offset); } uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { @@ -254,26 +264,27 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet[start] = NAK_PDU; uint32_t packet_index = start + 1; Pdu_nak *pdu_nak = (Pdu_nak *) &packet[packet_index]; - uint64_t count = req->file->missing_offsets->count; + packet_index += 16; - //fill offset array with all missing offsets [holder.offsets] - struct offset_holder holder; - holder.offsets = ssp_alloc(count, sizeof(Offset)); - holder.i = 0; + struct packet_nak_helper holder; + + holder.max_number_of_nak_segments = (req->buff_len - packet_index) / sizeof(Offset); + + holder.packet = &packet[packet_index]; + holder.current_number_of_segments = 0; + holder.start_scope = 0; + holder.end_scope = 0; req->file->missing_offsets->iterate(req->file->missing_offsets, fill_nak_array_callback, &holder); - - pdu_nak->start_scope = holder.offsets[0].start; - pdu_nak->end_scope = holder.offsets[holder.i-1].end; + uint32_t start_scope = ((Offset *)req->file->missing_offsets->head->next->element)->start; + uint32_t end_scope = ((Offset *)req->file->missing_offsets->tail->prev->element)->end; - pdu_nak->segment_requests = htonll(count); - packet_index+=16; - - memcpy(&packet[packet_index], holder.offsets, sizeof(Offset) * count); - ssp_free(holder.offsets); + pdu_nak->start_scope = htonl(start_scope); + pdu_nak->end_scope = htonl(end_scope); + pdu_nak->segment_requests = htonll(holder.current_number_of_segments); - packet_index += sizeof(Offset) * count; + packet_index += sizeof(Offset) * holder.current_number_of_segments; uint16_t data_len = packet_index - start; set_packet_header(packet, data_len, DIRECTIVE); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index d93f527..6257c5b 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -365,7 +365,7 @@ static void send_data(Request *req, Response res) { if (build_data_packet(req->buff, start, req->file, res.packet_len)) { req->procedure = sending_eof; - ssp_printf("sending data blast transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending data burst transaction: %d\n", req->transaction_sequence_number); } ssp_sendto(res); } @@ -406,6 +406,9 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { + //if client is still sending the first data_burst, don't accepts packets + if (req->procedure == sending_data) + return; uint8_t directive = packet[packet_index]; packet_index += 1; @@ -579,7 +582,6 @@ int process_file_request_metadata(Request *req) { offset->end = req->file_size; offset->start = 0; req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); - return 1; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index afca593..8734c0a 100644 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -87,7 +87,6 @@ static int test_build_nak_packet(char* packet, uint32_t start) { process_file_request_metadata(req); uint64_t count = req->file->missing_offsets->count; - uint32_t data_len = build_nak_packet(packet, start, req); ASSERT_EQUALS_INT("NAK directive code set", packet[start], NAK_PDU); @@ -108,7 +107,9 @@ static int test_build_nak_packet(char* packet, uint32_t start) { Offset offset[count]; ssp_memcpy(offset, &nak->segments, sizeof(Offset) * count); start_scope = ntohl(offset->start); + ssp_printf("test start_scope %d\n", start_scope); end_scope = ntohl(offset->end); + ssp_printf("test end_scope %d\n", end_scope); ASSERT_EQUALS_INT("start offset == 0 ", start_scope, 0); ASSERT_EQUALS_INT("end scope == 100000 ", end_scope, 100000); @@ -176,6 +177,36 @@ static int test_build_nak_packet(char* packet, uint32_t start) { return 0; } + +static int test_build_very_large_nak_packet(char* packet, uint32_t start) { + + DECLARE_NEW_TEST("testing build very large nak packet"); + + File *file = create_file("test_files/vid.mp4", 0); + Request *req = mock_empty_request(); + + req->file = file; + req->file_size = file->total_size; + process_file_request_metadata(req); + + for (int i = 0; i < 10000; i+=10) { + receive_offset(file, 0, i, i+10); + i++; + } + uint64_t count = file->missing_offsets->count; + + ssp_printf("len %d", count); + uint32_t data_len = build_nak_packet(packet, start, req); + uint32_t offsets_sent = (data_len - 17) / sizeof(Offset); + ssp_printf("offsets that fit in packet %d\n", offsets_sent); + + ASSERT_EQUALS_INT("data length of NAK fits in the packet", 1489, data_len); + + ssp_printf("data_len = %d", data_len); + + ssp_cleanup_req(req); + return 0; +} int test_build_ack_finished_pdu(char *packet, uint32_t start) { DECLARE_NEW_TEST("testing finish ack packet"); @@ -482,6 +513,8 @@ int packet_tests() { test_build_ack_eof_pdu(packet, data_start_index); test_build_nak_packet(packet, data_start_index); + test_build_very_large_nak_packet(packet, data_start_index); + /* test_respond_to_naks(packet, data_start_index); memset(packet, 0, PACKET_TEST_SIZE); @@ -494,6 +527,7 @@ int packet_tests() { test_get_message_from_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); test_add_cont_part_to_packet(packet, data_start_index); + */ return 0; } diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index eb3e7e6..31e66d6 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -257,7 +257,8 @@ int request_user_input_tests() { int test_process_messages() { - process_messages(Request *req, FTP *app) + //process_messages(Request *req, FTP *app) + return 0; } int request_tests() { From 70ff7f50416473d0e3b7051a55d00af5b29ce28f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 3 Jul 2020 08:56:09 -0600 Subject: [PATCH 247/400] get_file_name now makes directories if they don't exist --- Program/src/filesystem_funcs.c | 17 ++++++++++++++--- Program/src/makefile | 5 +++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index cd7d6e1..c991995 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -10,6 +10,7 @@ Author: Evan Giese #include "jsmn.h" #include "requests.h" + uint32_t get_file_size(char *source_file_name) { int fd = ssp_open(source_file_name, 0); @@ -557,12 +558,22 @@ static int write_file_present_bool(int fd, File *file) { return error; } -static void get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id, uint64_t trans) { - ssp_snprintf(filename, 255, "%s%u%s%u%s%llu%s", "incomplete_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); +static int get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id, uint64_t trans) { + + char dir_name[MAX_PATH]; + ssp_snprintf(dir_name, MAX_PATH, "%s%u%s", "incomplete_requests/CFID:", cfdp_id, "_requests"); + + int error = ssp_mkdir(dir_name); + if (error < 0) + return -1; + + ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%llu%s", "incomplete_requests/CFID:", cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); + + return 1; } int delete_saved_request(Request *req) { - char file_name[255]; + char file_name[MAX_PATH]; get_file_name(file_name, req->dest_cfdp_id, req->my_cfdp_id, req->transaction_sequence_number); ssp_printf("deleting %s\n", file_name); int error = ssp_remove(file_name); diff --git a/Program/src/makefile b/Program/src/makefile index 3e12590..cea6403 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -20,6 +20,7 @@ INCLUDE += -I$(PROJDIR)/include INCLUDE += -I$(PROJDIR)/libcsp/include/csp INCLUDE += -I$(PROJDIR)/libcsp/include INCLUDE += -I$(PROJDIR)/libcsp/build/include +INCLUDE += -I$(PROJDIR)/libcsp/src #------------------------------------------------------------------------------- CC = gcc @@ -29,7 +30,7 @@ CFILES += file_delivery_app.c CFILES += utils.c CFILES += tasks.c CFILES += posix_server_provider.c #used for poxix port -#CFILES += csp_server_provider.c +CFILES += csp_server_provider.c CFILES += protocol_handler.c CFILES += mib.c CFILES += filesystem_funcs.c @@ -68,7 +69,7 @@ CWARNS += -Wmissing-prototypes LINKFLAGS = LIBS = -pthread STATIC_FILES = -#STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a +STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a #STATIC_FILES += $(PROJDIR)/FreeRtos #---------------------------Compiler flags--------------------------- From 92b495d5dcb000834a7cd52ab753d00cd5014db9 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 6 Jul 2020 09:17:47 -0600 Subject: [PATCH 248/400] add initate all scheduled requests --- Program/include/filesystem_funcs.h | 2 +- Program/include/mib.h | 1 - Program/include/port.h | 2 + Program/include/requests.h | 2 +- Program/src/filesystem_funcs.c | 37 +++++---- Program/src/port.c | 3 + Program/src/requests.c | 129 ++++++++++++++++++++++++++++- 7 files changed, 158 insertions(+), 18 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index b279614..e8714eb 100644 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -38,5 +38,5 @@ int save_file_to_file(int fd, File *file); int get_file_from_file(int fd, File *file); int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint32_t my_cfdp_id, Request *req); int delete_saved_request(Request *req); - +int read_request_from_file(int fd, Request *req); #endif diff --git a/Program/include/mib.h b/Program/include/mib.h index 623f8ef..e3eaf8c 100644 --- a/Program/include/mib.h +++ b/Program/include/mib.h @@ -10,7 +10,6 @@ Author: Evan Giese #include "types.h" int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id); - void ssp_cleanup_pdu_header(Pdu_header *pdu_header); int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id); diff --git a/Program/include/port.h b/Program/include/port.h index 52ccbb2..863ed00 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -32,6 +32,8 @@ Author: Evan Giese #ifdef POSIX_FILESYSTEM #include #include + #include + #define SSP_O_RDWR O_RDWR #define SSP_O_CREAT O_CREAT #define SSP_O_TRUNC O_TRUNC diff --git a/Program/include/requests.h b/Program/include/requests.h index 08be30f..f66e9e9 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -47,6 +47,6 @@ Message *create_message(uint8_t type); void create_lv(LV *lv, int len, void *value); void free_lv(LV lv); void print_request_procedure(Request *req); - +int start_scheduled_requests(uint32_t dest_id, FTP *app); #endif \ No newline at end of file diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index c991995..dcbb01a 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -561,7 +561,7 @@ static int write_file_present_bool(int fd, File *file) { static int get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id, uint64_t trans) { char dir_name[MAX_PATH]; - ssp_snprintf(dir_name, MAX_PATH, "%s%u%s", "incomplete_requests/CFID:", cfdp_id, "_requests"); + ssp_snprintf(dir_name, MAX_PATH, "%s%u%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests"); int error = ssp_mkdir(dir_name); if (error < 0) @@ -724,21 +724,10 @@ static int get_messages_from_file(int fd, List *messages){ return 0; } -//[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] -int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint32_t my_cfdp_id, Request *req) { - - char file_name[255]; +int read_request_from_file(int fd, Request *req){ + //will overwrite messages pointer, so we need to save it List *messages = req->messages_to_user; - - get_file_name(file_name, dest_cfdp_id, my_cfdp_id, transaction_seq_num); - ssp_printf("opening %s\n", file_name); - - int fd = ssp_open(file_name, O_RDWR); - if (fd < 0) { - ssp_error("couldn't open file\n"); - return -1; - } //read in request struct int error = ssp_read(fd, (char *)req, sizeof(Request)); @@ -778,4 +767,24 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint3 } return error; +} + +//[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] +int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint32_t my_cfdp_id, Request *req) { + + char file_name[255]; + + get_file_name(file_name, dest_cfdp_id, my_cfdp_id, transaction_seq_num); + ssp_printf("opening %s\n", file_name); + + int fd = ssp_open(file_name, O_RDWR); + if (fd < 0) { + ssp_error("couldn't open file\n"); + return -1; + } + int error = read_request_from_file(fd, req); + if (error < 0) { + return -1; + } + return 0; } \ No newline at end of file diff --git a/Program/src/port.c b/Program/src/port.c index 2c32b2b..0f6cc41 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -20,6 +20,7 @@ Author: Evan Giese #ifdef POSIX_FILESYSTEM #include #include + #include #endif #ifdef FREE_RTOS_PORT @@ -107,6 +108,8 @@ int ssp_mkdir(char *dir_name) { #endif } + + /*------------------------------------------------------------------------------ Network port functions, these are used to interchange different network stacks diff --git a/Program/src/requests.c b/Program/src/requests.c index 37881c3..b756af7 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -319,7 +319,6 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { Request *req = init_request(client->buff, client->packet_len); //build a request - req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = client->remote_entity.cfdp_id; req->pdu_header = client->pdu_header; req->res.packet_len = client->packet_len; @@ -351,6 +350,7 @@ Request *put_request( req = start_new_client_request(app, dest_id); req->transmission_mode = transmission_mode; req->procedure = sending_start; + req->transaction_sequence_number = app->transaction_sequence_number++; return req; } @@ -376,6 +376,7 @@ Request *put_request( req->transmission_mode = transmission_mode; req->procedure = sending_start; + req->transaction_sequence_number = app->transaction_sequence_number++; ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); ssp_memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); @@ -383,6 +384,130 @@ Request *put_request( return req; } + + +/*NULL for source and destination filenames shall indicate that only Meta +data will be delivered. Side effect: add request to client request list +returns the request*/ +int schedule_put_request( + uint32_t dest_id, + char *source_file_name, + char *destination_file_name, + uint8_t transmission_mode, + FTP *app + ) { + + Request *req; + uint32_t file_size = 0; + + ssp_printf("scheduling request\n"); + + Remote_entity remote; + int error = get_remote_entity_from_json(&remote, dest_id); + if (error < 0) { + ssp_error("couldn't schedule request, reading from MIB failed\n"); + return -1; + } + + Pdu_header pdu_header; + error = get_header_from_mib(&pdu_header, remote, dest_id); + if (error < 0) { + ssp_error("couldn't get PDU header\n"); + return -1; + } + + char temp_buff[remote.mtu]; + req = init_request(temp_buff, remote.mtu); + + //build a request + req->transaction_sequence_number = app->transaction_sequence_number++; + req->dest_cfdp_id = dest_id; + req->pdu_header = pdu_header; + req->res.packet_len = remote.mtu; + req->buff = temp_buff; + req->my_cfdp_id = app->my_cfdp_id; + req->transmission_mode = transmission_mode; + req->procedure = sending_start; + + if (source_file_name == NULL && destination_file_name == NULL) { + save_req_to_file(req); + return 1; + } + if (strnlen(source_file_name, MAX_PATH) == 0 || strnlen(destination_file_name, MAX_PATH) == 0) { + ssp_printf("ERROR: no file names present in put request, if you want to just send messages, make both source and dest NULL\n"); + return -1; + } + + bool exists = does_file_exist(source_file_name); + if (exists == false) { + ssp_printf("ERROR: File does not exist\n"); + return -1; + } + + file_size = get_file_size(source_file_name); + if (file_size == 0) + return -1; + + req->file = create_file(source_file_name, false); + req->file_size = file_size; + + ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + ssp_memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + save_req_to_file(req); + return 1; +} + +int start_scheduled_requests(uint32_t dest_id, FTP *app){ + + char dir_name[MAX_PATH]; + ssp_snprintf(dir_name, MAX_PATH, "%s%u%s", "incomplete_requests/CFID:", dest_id, "_requests"); + ssp_printf("opening dir %s\n", dir_name); + + DIR *dir; + struct dirent *file; + + dir = opendir(dir_name); + if(dir == NULL){ + ssp_error("Unable to open directory"); + return -1; + } + int error, fd = 0; + Request *req; + + while( (file=readdir(dir)) ) + { + + if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0) + continue; + + fd = ssp_open(file->d_name, O_RDWR); + if (fd < 0) { + ssp_error("couldn't open request data file"); + return -1; + } + + req = start_new_client_request(app, dest_id); + if (req == NULL) { + ssp_error("couldn't start new request"); + continue; + } + + error = read_request_from_file(fd, req); + if (error < 0) { + return -1; + } + + error = ssp_close(fd); + if (error < 0) { + ssp_error("there was an error closing the file descriptor"); + } + } + + closedir(dir); + return 0; +} + + void start_request(Request *req){ if (req == NULL) { ssp_printf("ERROR: couldn't start request\n"); @@ -392,6 +517,8 @@ void start_request(Request *req){ req->paused = false; } + + static void print_messages_callback(Node *node, void *element, void *args) { Message *m = (Message*) element; From aad2641a67fe3806f2d45cecbb6112f3c34cdeca Mon Sep 17 00:00:00 2001 From: EvanGee Date: Mon, 13 Jul 2020 10:56:51 -0600 Subject: [PATCH 249/400] Scheduling put request --- Program/include/requests.h | 2 +- Program/include/types.h | 4 +- Program/src/filesystem_funcs.c | 19 ++++++--- Program/src/posix_server_provider.c | 2 +- Program/src/requests.c | 61 +++++++++++++++++++++-------- Program/src/tasks.c | 6 ++- 6 files changed, 66 insertions(+), 28 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index f66e9e9..bf3ed51 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -48,5 +48,5 @@ void create_lv(LV *lv, int len, void *value); void free_lv(LV lv); void print_request_procedure(Request *req); int start_scheduled_requests(uint32_t dest_id, FTP *app); - +int schedule_put_request(uint32_t dest_id,char *source_file_name,char *destination_file_name,uint8_t transmission_mode, FTP *app); #endif \ No newline at end of file diff --git a/Program/include/types.h b/Program/include/types.h index ae79485..1f6589d 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -568,13 +568,11 @@ typedef struct response { char *msg; //this is type (struct sockaddr_in) in posix void *addr; + size_t size_of_addr; enum Network_type type_of_network; int transmission_mode; - //getting rid of this soon in favour of client based packet sizes - size_t size_of_addr; - uint32_t packet_len; } Response; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index dcbb01a..cc6722e 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -567,7 +567,7 @@ static int get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id if (error < 0) return -1; - ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%llu%s", "incomplete_requests/CFID:", cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); + ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%llu%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); return 1; } @@ -728,6 +728,9 @@ int read_request_from_file(int fd, Request *req){ //will overwrite messages pointer, so we need to save it List *messages = req->messages_to_user; + int timeout_before_cancel = req->timeout_before_cancel; + int timeout_before_journal = req->timeout_before_journal; + void *addr = req->res.addr; //read in request struct int error = ssp_read(fd, (char *)req, sizeof(Request)); @@ -755,17 +758,16 @@ int read_request_from_file(int fd, Request *req){ } req->messages_to_user = messages; + req->timeout_before_cancel = timeout_before_cancel; + req->timeout_before_journal = timeout_before_journal; + req->res.addr = addr; + error = get_messages_from_file(fd, req->messages_to_user); if (error == -1) { ssp_free(file); return -1; } - error = ssp_close(fd); - if (error < 0) { - ssp_error("couldn't close file descriptor \n"); - } - return error; } @@ -786,5 +788,10 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint3 if (error < 0) { return -1; } + error = ssp_close(fd); + if (error < 0) { + ssp_error("couldn't close file descriptor \n"); + } + return 0; } \ No newline at end of file diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index 69bc794..d1e5eea 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -132,7 +132,7 @@ static int prepareHost(char *host_name, void *addr, size_t *size_of_addr, char * if (cur == NULL) { - ssp_printf("error could not create server\n"); + ssp_printf("failed connecting with server\n"); freeaddrinfo(res); return -1; } diff --git a/Program/src/requests.c b/Program/src/requests.c index b756af7..dcdf542 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -300,6 +300,7 @@ Request *init_request(char *buff, uint32_t buff_len) { return req; } + //starts a new client, adding it to app->active_clients, as well as //starting a new request and adding it to the client, returns a pointer //to the request @@ -321,8 +322,6 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { //build a request req->dest_cfdp_id = client->remote_entity.cfdp_id; req->pdu_header = client->pdu_header; - req->res.packet_len = client->packet_len; - req->buff = client->buff; req->my_cfdp_id = app->my_cfdp_id; client->request_list->insert(client->request_list, req, 0); @@ -410,7 +409,7 @@ int schedule_put_request( } Pdu_header pdu_header; - error = get_header_from_mib(&pdu_header, remote, dest_id); + error = get_header_from_mib(&pdu_header, remote, app->my_cfdp_id); if (error < 0) { ssp_error("couldn't get PDU header\n"); return -1; @@ -420,41 +419,52 @@ int schedule_put_request( req = init_request(temp_buff, remote.mtu); //build a request - req->transaction_sequence_number = app->transaction_sequence_number++; req->dest_cfdp_id = dest_id; req->pdu_header = pdu_header; - req->res.packet_len = remote.mtu; - req->buff = temp_buff; req->my_cfdp_id = app->my_cfdp_id; req->transmission_mode = transmission_mode; req->procedure = sending_start; if (source_file_name == NULL && destination_file_name == NULL) { - save_req_to_file(req); - return 1; + error = save_req_to_file(req); + if (error < 0) + ssp_cleanup_req(req); + return error; } + if (strnlen(source_file_name, MAX_PATH) == 0 || strnlen(destination_file_name, MAX_PATH) == 0) { ssp_printf("ERROR: no file names present in put request, if you want to just send messages, make both source and dest NULL\n"); + ssp_cleanup_req(req); return -1; } bool exists = does_file_exist(source_file_name); if (exists == false) { ssp_printf("ERROR: File does not exist\n"); + ssp_cleanup_req(req); return -1; } file_size = get_file_size(source_file_name); - if (file_size == 0) + if (file_size == 0) { + ssp_cleanup_req(req); return -1; + } req->file = create_file(source_file_name, false); + if (req->file == NULL) { + ssp_cleanup_req(req); + return -1; + } req->file_size = file_size; - + req->transaction_sequence_number = app->transaction_sequence_number++; + ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); ssp_memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); - save_req_to_file(req); - return 1; + error = save_req_to_file(req); + ssp_cleanup_req(req); + + return error; } int start_scheduled_requests(uint32_t dest_id, FTP *app){ @@ -474,13 +484,18 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ int error, fd = 0; Request *req; + + //adding +2 here because file->name is of max 256 size, and then we add a /. + char file_path[MAX_PATH + 2]; + while( (file=readdir(dir)) ) { - if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0) continue; - fd = ssp_open(file->d_name, O_RDWR); + ssp_snprintf(file_path, sizeof(file_path), "%s/%s", dir_name, file->d_name); + + fd = ssp_open(file_path, O_RDWR); if (fd < 0) { ssp_error("couldn't open request data file"); return -1; @@ -491,12 +506,15 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ ssp_error("couldn't start new request"); continue; } - + char *buff = req->buff; error = read_request_from_file(fd, req); if (error < 0) { return -1; } - + req->buff = buff; //add buffer from client + + start_request(req); + error = ssp_close(fd); if (error < 0) { ssp_error("there was an error closing the file descriptor"); @@ -564,6 +582,17 @@ void print_request_state(Request *req) { ssp_printf("current messages: \n"); req->messages_to_user->iterate(req->messages_to_user, print_messages_callback, NULL); + ssp_printf("request header destination id: %d\n", req->pdu_header.destination_id); + ssp_printf("request header source id: %d\n", req->pdu_header.source_id); + ssp_printf("request header crc flag: %d\n", req->pdu_header.CRC_flag); + ssp_printf("request header direction: %d\n", req->pdu_header.direction); + ssp_printf("request header length of Ids: %d\n", req->pdu_header.length_of_entity_IDs); + ssp_printf("request header PDU_data_field_len: %d\n", req->pdu_header.PDU_data_field_len); + ssp_printf("request header pdu type: %d\n", req->pdu_header.PDU_type); + ssp_printf("request header transaction_seq_num_len: %d\n", req->pdu_header.transaction_seq_num_len); + ssp_printf("request header transaction_sequence_number: %d\n", req->pdu_header.transaction_sequence_number); + ssp_printf("request header transmission_mode: %d\n", req->pdu_header.transmission_mode); + ssp_printf("request header version: %d\n", req->pdu_header.version); ssp_printf("---------------------------------------------\n"); } diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 13a9234..3b91ae7 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -72,7 +72,7 @@ static void timeout(Request *req) { } req->procedure = clean_up; } - + is_timeout = check_timeout(&req->timeout_before_journal, TIMEOUT_BEFORE_SAVE_REQUEST); if (is_timeout) { int error = save_req_to_file(req); @@ -162,6 +162,10 @@ void remove_request_check(Node *node, void *request, void *args) { if (req->procedure == clean_up) { ssp_printf("removing request\n"); Request *remove_this = req_list->removeNode(req_list, node); + //int error = delete_saved_request(req); + //if (error < 0) + // ssp_error("couldn't delete finished request\n"); + ssp_cleanup_req(remove_this); } } From dbc4f5f772e83f138692ba815b79ae5dfe2ddf29 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 16 Jul 2020 09:49:35 -0600 Subject: [PATCH 250/400] move read_dir to port --- Program/include/port.h | 3 +++ Program/src/port.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Program/include/port.h b/Program/include/port.h index 863ed00..c6c37ed 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -87,6 +87,9 @@ void ssp_thread_join(void *thread_handle); int ssp_remove(char *pathname); int ssp_rename(const char *old, const char *new); int ssp_mkdir(char *dir_name); +void *ssp_opendir(char *dir_name); +int ssp_readdir(void *dir, char *file); + void reset_request(Request *req); diff --git a/Program/src/port.c b/Program/src/port.c index 0f6cc41..0e1a712 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -109,6 +109,33 @@ int ssp_mkdir(char *dir_name) { #endif } +void *ssp_opendir(char *dir_name) { + + #ifdef POSIX_FILESYSTEM + DIR *dir; + dir = opendir(dir_name); + if(dir == NULL){ + ssp_error("Unable to open directory"); + return NULL; + } + return dir; + #endif +} + +int ssp_readdir(void *dir, char *file){ + #ifdef POSIX_FILESYSTEM + struct dirent *file_read; + DIR *d = (DIR*)dir; + + file_read=readdir(d); + if (file_read == NULL) { + return 0; + } + ssp_memcpy(file, file_read->d_name, MAX_PATH); + + return 1; + #endif +} /*------------------------------------------------------------------------------ Network port functions, these are used to interchange different network From b5ff79531fcd8aae6145663b9caf12dc962b0f95 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 16 Jul 2020 09:50:25 -0600 Subject: [PATCH 251/400] add 'new' put request framework, remove old one? --- Program/include/requests.h | 13 +++++ Program/src/requests.c | 109 ++++++++++++++++++++++++++++++++--- Program/test/request_tests.c | 34 +++++++++++ 3 files changed, 149 insertions(+), 7 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index bf3ed51..9818c13 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -49,4 +49,17 @@ void free_lv(LV lv); void print_request_procedure(Request *req); int start_scheduled_requests(uint32_t dest_id, FTP *app); int schedule_put_request(uint32_t dest_id,char *source_file_name,char *destination_file_name,uint8_t transmission_mode, FTP *app); + +//----------------------------new stuff for users starting request--------------- +int put_request_new( + Request *req, + char *source_file_name, + char *destination_file_name, + uint8_t transmission_mode, + FTP *app); + +void add_request_to_client(Request *req, Client *client); +Client *start_client(FTP *app, uint8_t dest_id); +Request *init_request_new(); + #endif \ No newline at end of file diff --git a/Program/src/requests.c b/Program/src/requests.c index dcdf542..711f9f3 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -275,6 +275,28 @@ void ssp_cleanup_req(void *request) { } +Request *init_request_new() { + + Request *req = ssp_alloc(1, sizeof(Request)); + if (req == NULL) + return NULL; + + req->file = NULL; + //req->buff_len = buff_len; + //req->buff = buff; + req->procedure = none; + req->paused = true; + req->timeout_before_cancel = ssp_time_count(); + req->timeout_before_journal = ssp_time_count(); + //req->res.msg = req->buff; + + req->messages_to_user = linked_list(); + if (req->messages_to_user == NULL) { + ssp_free(req->buff); + return NULL; + } + return req; +} Request *init_request(char *buff, uint32_t buff_len) { @@ -329,7 +351,80 @@ static Request *start_new_client_request(FTP *app, uint8_t dest_id) { return req; } +Client *start_client(FTP *app, uint8_t dest_id) { + //spin up a new client thread + Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); + + if (client == NULL) { + ssp_printf("Spinning up a new client thread\n"); + client = ssp_client(dest_id, app); + if (client == NULL) + return NULL; + + app->active_clients->insert(app->active_clients, client, dest_id); + } else { + ssp_printf("adding request to existing client thread\n"); + } + return client; +} + + +//adds generic request to client, will set the pdu_header to new client +void add_request_to_client(Request *req, Client *client) { + + req->dest_cfdp_id = client->remote_entity.cfdp_id; + req->pdu_header = client->pdu_header; + req->my_cfdp_id = client->app->my_cfdp_id; + req->buff = client->buff; + req->buff_len = client->packet_len; + client->request_list->insert(client->request_list, req, 0); + start_request(req); +} +int put_request_new( + Request *req, + char *source_file_name, + char *destination_file_name, + uint8_t transmission_mode, + FTP *app) { + + uint32_t file_size = 0; + + //build a request + req->my_cfdp_id = app->my_cfdp_id; + req->transmission_mode = transmission_mode; + req->procedure = sending_start; + + if (source_file_name == NULL && destination_file_name == NULL) { + req->transaction_sequence_number = app->transaction_sequence_number++; + return 0; + } + + if (strnlen(source_file_name, MAX_PATH) == 0 || strnlen(destination_file_name, MAX_PATH) == 0) { + ssp_printf("ERROR: no file names present in put request, if you want to just send messages, make both source and dest NULL\n"); + return -1; + } + + bool exists = does_file_exist(source_file_name); + if (exists == false) { + ssp_printf("ERROR: File does not exist\n"); + return -1; + } + + file_size = get_file_size(source_file_name); + if (file_size == 0) + return -1; + + req->file = create_file(source_file_name, false); + if (req->file == NULL) + return -1; + + req->file_size = file_size; + req->transaction_sequence_number = app->transaction_sequence_number++; + ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); + ssp_memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); + return 0; +} /*NULL for source and destination filenames shall indicate that only Meta data will be delivered. Side effect: add request to client request list returns the request*/ @@ -473,10 +568,10 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ ssp_snprintf(dir_name, MAX_PATH, "%s%u%s", "incomplete_requests/CFID:", dest_id, "_requests"); ssp_printf("opening dir %s\n", dir_name); - DIR *dir; - struct dirent *file; + void *dir; + char file[MAX_PATH]; - dir = opendir(dir_name); + dir = ssp_opendir(dir_name); if(dir == NULL){ ssp_error("Unable to open directory"); return -1; @@ -484,16 +579,16 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ int error, fd = 0; Request *req; - //adding +2 here because file->name is of max 256 size, and then we add a /. char file_path[MAX_PATH + 2]; - while( (file=readdir(dir)) ) + while( (ssp_readdir(dir, file)) ) { - if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0) + if (strncmp(file, ".", 1) == 0 || strncmp(file, "..", 2) == 0) continue; - ssp_snprintf(file_path, sizeof(file_path), "%s/%s", dir_name, file->d_name); + ssp_snprintf(file_path, sizeof(file_path), "%s/%s", dir_name, file); + ssp_printf("reading: %s\n", file_path); fd = ssp_open(file_path, O_RDWR); if (fd < 0) { diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 31e66d6..4f90405 100644 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -254,6 +254,34 @@ int request_user_input_tests() { app->close = true; ssp_thread_join(app->server_handle); } +int scheduled_requests_test() { + + FTP *app = init_ftp(2); + int error = schedule_put_request(1, "test_files/dest.jpg", "test_files/scheduled_file_sent", ACKNOWLEDGED_MODE, app); + ASSERT_EQUALS_INT("couldn't schedule request when should have been able to ", error, 0); + + //error = schedule_put_request(1, "test_files/dest.jp", "test_files/scheduled_file_fail", ACKNOWLEDGED_MODE, app); + //ASSERT_EQUALS_INT("couldn't schedule request, file not found", error, -1); + + //error = schedule_put_request(1, NULL, NULL, ACKNOWLEDGED_MODE, app); + //ASSERT_EQUALS_INT("scheduling just messages", error, 0); + + sleep(1); + app->close = true; + ssp_thread_join(app->server_handle); + return 0; +} + +int schedule_requests_start_test(){ + sleep(1); + FTP *app = init_ftp(2); + + int error = start_scheduled_requests(1, app); + ASSERT_EQUALS_INT("start request batch successfully", error, 0); + + //app->close = true; + ssp_thread_join(app->server_handle); +} int test_process_messages() { @@ -265,6 +293,7 @@ int request_tests() { int error = 0; + /* error = request_finding_test(); error = request_user_input_tests(); error = add_proxy_message(); @@ -272,6 +301,11 @@ int request_tests() { error = add_continue_partial_message_test(); error = init_cont_partial_request_test_fail(); error = init_cont_partial_request_test(); + */ + + + scheduled_requests_test(); + schedule_requests_start_test(); return error; } \ No newline at end of file From fe5eb7e674813ce380fb2a53005ecdf58ba1c635 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 22 Jul 2020 12:58:29 -0600 Subject: [PATCH 252/400] refacator request functions --- Program/include/requests.h | 4 +- Program/src/requests.c | 194 ++++++++++--------------------------- 2 files changed, 53 insertions(+), 145 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 9818c13..797b0e7 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -51,7 +51,7 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app); int schedule_put_request(uint32_t dest_id,char *source_file_name,char *destination_file_name,uint8_t transmission_mode, FTP *app); //----------------------------new stuff for users starting request--------------- -int put_request_new( +int put_request_no_client( Request *req, char *source_file_name, char *destination_file_name, @@ -60,6 +60,6 @@ int put_request_new( void add_request_to_client(Request *req, Client *client); Client *start_client(FTP *app, uint8_t dest_id); -Request *init_request_new(); +Request *init_request_no_client(); #endif \ No newline at end of file diff --git a/Program/src/requests.c b/Program/src/requests.c index 711f9f3..36587e8 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -275,20 +275,17 @@ void ssp_cleanup_req(void *request) { } -Request *init_request_new() { +Request *init_request_no_client() { Request *req = ssp_alloc(1, sizeof(Request)); if (req == NULL) return NULL; req->file = NULL; - //req->buff_len = buff_len; - //req->buff = buff; req->procedure = none; req->paused = true; req->timeout_before_cancel = ssp_time_count(); req->timeout_before_journal = ssp_time_count(); - //req->res.msg = req->buff; req->messages_to_user = linked_list(); if (req->messages_to_user == NULL) { @@ -301,56 +298,18 @@ Request *init_request_new() { Request *init_request(char *buff, uint32_t buff_len) { - Request *req = ssp_alloc(1, sizeof(Request)); + Request *req = init_request_no_client(); if (req == NULL) return NULL; - req->file = NULL; req->buff_len = buff_len; req->buff = buff; - req->procedure = none; - req->paused = true; - req->timeout_before_cancel = ssp_time_count(); - req->timeout_before_journal = ssp_time_count(); req->res.msg = req->buff; - req->messages_to_user = linked_list(); - if (req->messages_to_user == NULL) { - ssp_free(req->buff); - return NULL; - } return req; } -//starts a new client, adding it to app->active_clients, as well as -//starting a new request and adding it to the client, returns a pointer -//to the request -static Request *start_new_client_request(FTP *app, uint8_t dest_id) { - - //spin up a new client thread - Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); - - if (client == NULL) { - ssp_printf("Spinning up a new client thread\n"); - client = ssp_client(dest_id, app); - app->active_clients->insert(app->active_clients, client, dest_id); - } else { - ssp_printf("adding request to existing client thread\n"); - } - - Request *req = init_request(client->buff, client->packet_len); - - //build a request - req->dest_cfdp_id = client->remote_entity.cfdp_id; - req->pdu_header = client->pdu_header; - req->my_cfdp_id = app->my_cfdp_id; - - client->request_list->insert(client->request_list, req, 0); - - return req; -} - Client *start_client(FTP *app, uint8_t dest_id) { //spin up a new client thread Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); @@ -381,7 +340,7 @@ void add_request_to_client(Request *req, Client *client) { start_request(req); } -int put_request_new( +int put_request_no_client( Request *req, char *source_file_name, char *destination_file_name, @@ -436,50 +395,28 @@ Request *put_request( FTP *app ) { - Request *req; - uint32_t file_size = 0; - - ssp_printf("trying to start new request\n"); - if (source_file_name == NULL && destination_file_name == NULL) { - req = start_new_client_request(app, dest_id); - req->transmission_mode = transmission_mode; - req->procedure = sending_start; - req->transaction_sequence_number = app->transaction_sequence_number++; - return req; - } - if (strnlen(source_file_name, MAX_PATH) == 0 || strnlen(destination_file_name, MAX_PATH) == 0) { - ssp_printf("ERROR: no file names present in put request, if you want to just send messages, make both source and dest NULL\n"); + Request *req = init_request_no_client(); + if (req == NULL) { + ssp_error("couldn't init request"); return NULL; - } + } - bool exists = does_file_exist(source_file_name); - if (exists == false) { - ssp_printf("ERROR: File does not exist\n"); + if (put_request_no_client(req, source_file_name, destination_file_name, transmission_mode, app) < 0){ + ssp_error("couldn't configure request"); return NULL; } - req = start_new_client_request(app, dest_id); - - file_size = get_file_size(source_file_name); - if (file_size == 0) + Client *client = start_client(app, dest_id); + if (client == NULL) { + ssp_printf("client failed to start\n"); return NULL; - - req->file = create_file(source_file_name, false); - req->file_size = file_size; - - req->transmission_mode = transmission_mode; - req->procedure = sending_start; - req->transaction_sequence_number = app->transaction_sequence_number++; + } - ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); - ssp_memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); - + add_request_to_client(req, client); return req; } - - /*NULL for source and destination filenames shall indicate that only Meta data will be delivered. Side effect: add request to client request list returns the request*/ @@ -490,76 +427,36 @@ int schedule_put_request( uint8_t transmission_mode, FTP *app ) { + int error = -1; + Request *req = init_request_no_client(); + if (req == NULL) { + ssp_error("couldn't init request"); + return error; + } - Request *req; - uint32_t file_size = 0; - - ssp_printf("scheduling request\n"); - - Remote_entity remote; - int error = get_remote_entity_from_json(&remote, dest_id); - if (error < 0) { - ssp_error("couldn't schedule request, reading from MIB failed\n"); - return -1; - } - - Pdu_header pdu_header; - error = get_header_from_mib(&pdu_header, remote, app->my_cfdp_id); - if (error < 0) { - ssp_error("couldn't get PDU header\n"); - return -1; + if (put_request_no_client(req, source_file_name, destination_file_name, transmission_mode, app) < 0){ + ssp_error("couldn't configure request"); + return error; } - char temp_buff[remote.mtu]; - req = init_request(temp_buff, remote.mtu); - - //build a request req->dest_cfdp_id = dest_id; - req->pdu_header = pdu_header; req->my_cfdp_id = app->my_cfdp_id; req->transmission_mode = transmission_mode; req->procedure = sending_start; + error = save_req_to_file(req); + return error; +} - if (source_file_name == NULL && destination_file_name == NULL) { - error = save_req_to_file(req); - if (error < 0) - ssp_cleanup_req(req); - return error; - } - - if (strnlen(source_file_name, MAX_PATH) == 0 || strnlen(destination_file_name, MAX_PATH) == 0) { - ssp_printf("ERROR: no file names present in put request, if you want to just send messages, make both source and dest NULL\n"); - ssp_cleanup_req(req); - return -1; - } - - bool exists = does_file_exist(source_file_name); - if (exists == false) { - ssp_printf("ERROR: File does not exist\n"); - ssp_cleanup_req(req); - return -1; - } - - file_size = get_file_size(source_file_name); - if (file_size == 0) { - ssp_cleanup_req(req); - return -1; - } +static void clean_up_start_scheduled_requests(int fd, Request *req){ - req->file = create_file(source_file_name, false); - if (req->file == NULL) { + if (req != NULL) ssp_cleanup_req(req); - return -1; - } - req->file_size = file_size; - req->transaction_sequence_number = app->transaction_sequence_number++; - ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); - ssp_memcpy(req->destination_file_name, destination_file_name, strnlen(destination_file_name, MAX_PATH)); - error = save_req_to_file(req); - ssp_cleanup_req(req); + int error = ssp_close(fd); + if (error < 0) { + ssp_error("there was an error closing the file descriptor"); + } - return error; } int start_scheduled_requests(uint32_t dest_id, FTP *app){ @@ -577,7 +474,8 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ return -1; } int error, fd = 0; - Request *req; + Request *req = NULL; + Client *client = NULL; //adding +2 here because file->name is of max 256 size, and then we add a /. char file_path[MAX_PATH + 2]; @@ -588,26 +486,36 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ continue; ssp_snprintf(file_path, sizeof(file_path), "%s/%s", dir_name, file); - ssp_printf("reading: %s\n", file_path); fd = ssp_open(file_path, O_RDWR); if (fd < 0) { + clean_up_start_scheduled_requests(fd, req); ssp_error("couldn't open request data file"); - return -1; + continue; } - req = start_new_client_request(app, dest_id); - if (req == NULL) { + client = start_client(app, dest_id); + if (client == NULL) { + clean_up_start_scheduled_requests(fd, req); ssp_error("couldn't start new request"); continue; } - char *buff = req->buff; + + req = init_request_no_client(); + if (req == NULL) { + clean_up_start_scheduled_requests(fd, req); + ssp_error("couldn't init request"); + continue; + } + error = read_request_from_file(fd, req); if (error < 0) { - return -1; + clean_up_start_scheduled_requests(fd, req); + ssp_error("couldn't read in request"); + continue; } - req->buff = buff; //add buffer from client + add_request_to_client(req, client); start_request(req); error = ssp_close(fd); From 3416be766fd225f151db6d852d808a2c008b5a8d Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 22 Jul 2020 13:16:42 -0600 Subject: [PATCH 253/400] strengthen error reporting for threads --- Program/src/file_delivery_app.c | 21 ++++++++++++++++++--- Program/src/port.c | 28 ++++++++++++++-------------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 3e7919b..da338f0 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -9,7 +9,7 @@ Author: Evan Giese #include "file_delivery_app.h" #include "tasks.h" -static void create_ssp_server_drivers(FTP *app) { +static int create_ssp_server_drivers(FTP *app) { switch (app->remote_entity.type_of_network) { @@ -29,9 +29,14 @@ static void create_ssp_server_drivers(FTP *app) { ssp_printf("server couldn't start, 'type of network' not recognized\n"); break; } + if (app->server_handle == NULL) { + return -1; + } + return 0; + } -static void create_ssp_client_drivers(Client *client) { +static int create_ssp_client_drivers(Client *client) { Remote_entity remote_entity = client->remote_entity; switch (remote_entity.type_of_network) @@ -52,6 +57,10 @@ static void create_ssp_client_drivers(Client *client) { ssp_printf("client couldn't start, 'type of network' not recognized\n"); break; } + if (client->client_handle == NULL) { + return -1; + } + return 0; } FTP *init_ftp(uint32_t my_cfdp_address) { @@ -133,7 +142,13 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { client->current_request = NULL; client->app = app; - create_ssp_client_drivers(client); + error = create_ssp_client_drivers(client); + if (error < 0) { + ssp_free(client); + ssp_free(client->buff); + client->request_list->freeOnlyList(client->request_list); + return NULL; + } return client; } diff --git a/Program/src/port.c b/Program/src/port.c index 0e1a712..5e0d46d 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -261,6 +261,7 @@ int ssp_time_count() { return ts.tv_sec; } + /*------------------------------------------------------------------------------ Threading and task functions ------------------------------------------------------------------------------*/ @@ -286,42 +287,41 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void #else //pthreads pthread_t *handler = ssp_alloc(1, sizeof(pthread_t)); - if (handler == NULL) + if (handler == NULL) return NULL; - pthread_attr_t *attr = ssp_alloc(1, sizeof(pthread_attr_t)); - if (attr == NULL) { ssp_free(handler); return NULL; } int err = pthread_attr_init(attr); - if (0 != err) + if (0 != err) { perror("pthread_init failed"); - - + ssp_free(attr); + ssp_free(handler); + } err = pthread_attr_setstacksize(attr, stack_size); - if (0 != err) ssp_error("ERROR pthread_attr_setstacksize %d"); - + if (EINVAL == err) { - printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + ssp_error("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + ssp_free(attr); + ssp_free(handler); + return NULL; } err = pthread_create(handler, attr, thread_func, params); - if (0 != err) + if (0 != err) { perror("ERROR pthread_create"); - + ssp_free(handler); + } ssp_free(attr); return handler; #endif - - - } From 3607379e96ba0e62c14536b362d7a67094c299f3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 23 Jul 2020 10:24:04 -0600 Subject: [PATCH 254/400] fix printf bug --- Program/src/port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/port.c b/Program/src/port.c index 5e0d46d..b9d54f1 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -307,7 +307,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void ssp_error("ERROR pthread_attr_setstacksize %d"); if (EINVAL == err) { - ssp_error("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); + ssp_printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); ssp_free(attr); ssp_free(handler); return NULL; From 402673f71365c53a3891b23a5e34acb5538444b1 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 24 Jul 2020 11:27:27 -0600 Subject: [PATCH 255/400] master update to work with satsim --- Program/include/port.h | 24 ++++++++++--- Program/include/types.h | 9 +---- Program/src/csp_server_provider.c | 3 ++ Program/src/main.c | 59 +++++++++++++++++++++++++------ Program/src/makefile | 19 +++++----- Program/src/port.c | 16 ++++++++- 6 files changed, 97 insertions(+), 33 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index c6c37ed..5869ce8 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,9 +9,10 @@ Author: Evan Giese #define STACK_ALLOCATION 16384 -#define POSIX_PORT +//#define POSIX_PORT +#define FREE_RTOS_PORT #define POSIX_FILESYSTEM -//#define CSP_NETWORK +#define CSP_NETWORK //comment this out if you want to sendto function to actually work //#define TEST @@ -61,8 +62,23 @@ Author: Evan Giese #endif #ifdef FREE_RTOS_PORT - //TODO need the above POSIX_PORT definitions to work, if we are bigendian, then the - //htonl etc are empty. + #include + #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN + #define SSP_AF_INET AF_INET + #define ssp_htonl htonl + #define ssp_ntohl ntohl + #define ssp_htons htons + #define ssp_stonl stonl + #define ssp_inet_ntop inet_ntop + + #include + #define ssp_memcpy memcpy + + #include + #define ssp_snprintf snprintf + + #include "stdlib.h" + #define ssp_atol atol #endif diff --git a/Program/include/types.h b/Program/include/types.h index 1f6589d..888ccfc 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -8,6 +8,7 @@ Author: Evan Giese #define SSP_TYPES_H #include "list.h" +#include #define MAX_PATH 255 #define ACKNOWLEDGED_MODE 0 @@ -18,14 +19,6 @@ Author: Evan Giese typedef unsigned int size_t; #endif -typedef enum { false, true } bool; - - - - - - - /*----------------------------------------------------------------------------- diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 5efb381..1c22ad3 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -160,6 +160,9 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, /* Create socket without any socket options */ csp_socket_t *sock = csp_socket(CSP_SO_NONE); + uint8_t src_id = csp_get_address(); + ssp_printf("CSP ID: %d\n", src_id); + /* Bind all ports to socket */ csp_bind(sock, my_port); diff --git a/Program/src/main.c b/Program/src/main.c index 5d051e9..7d3d5ee 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -111,14 +111,12 @@ int main(int argc, char** argv) { exit_now = prepareSignalHandler(); //get-opt configuration - /* Config *conf = configuration(argc, argv); if (conf->my_cfdp_id == 0){ printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } - */ - + #ifdef CSP_NETWORK ssp_printf("Initialising CSP\r\n"); @@ -130,23 +128,62 @@ int main(int argc, char** argv) { csp_buffer_init(1000, 250); /* Start router task with 500 word stack, OS task priority 1 */ - csp_route_start_task(500, 1); + csp_route_start_task(5000, 1); #endif - FTP *app = init_ftp(5); + FTP *app = init_ftp(conf->my_cfdp_id); if (app == NULL) { return 1; } - - FTP *app2 = init_ftp(6); - if (app2 == NULL) { - return 1; + sleep(1); + + if (conf->client_cfdp_id == 1) { + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled.jpg", ACKNOWLEDGED_MODE, app); + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled2.jpg", ACKNOWLEDGED_MODE, app); + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled3.jpg", ACKNOWLEDGED_MODE, app); + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled4.jpg", ACKNOWLEDGED_MODE, app); + start_scheduled_requests(conf->client_cfdp_id, app); } - - start_request(put_request(6, "pictures/pic.jpeg", "pictures/noProxy.jpg", ACKNOWLEDGED_MODE, app)); + else if (conf->client_cfdp_id == 2) { + Request *req = init_request_no_client(); + put_request_no_client(req, "pictures/pic.jpeg", "pictures/scheduled.jpg", ACKNOWLEDGED_MODE, app); + + Client *client = start_client(app, conf->client_cfdp_id); + if (client == NULL) { + ssp_printf("client failed to start\n"); + } else + add_request_to_client(req, client); + } else if (conf->client_cfdp_id == 3) { + Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/udp.jpg", ACKNOWLEDGED_MODE, app); + start_request(req); + //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); + //add_cont_partial_message_to_request(4, 1, conf->client_cfdp_id, 1, 0, 1, req); + //start_request(req); + } + //Request *req = put_request(conf->my_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", ACKNOWLEDGED_MODE, app); + //start_request(req); + + /* + if (conf->my_cfdp_id == 1) { + Request *re + if (conf->client_cfdp_id == 3) { + }q = put_request(conf->client_cfdp_id, "pictures/videoplayback.mp4", "pictures/vid_tcp.jpg", ACKNOWLEDGED_MODE, app); + start_request(req); + } + if (conf->client_cfdp_id == 4) { + //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, UN_ACKNOWLEDGED_MODE, app); + //add_cont_partial_message_to_request(conf->my_cfdp_id, 3, 1, 4, 1, 1, req); + //add_proxy_message_to_request(7, 1, "pictures/pic.jpeg","pictures/proxy_yo!.jpeg", req); + + Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", UN_ACKNOWLEDGED_MODE, app); + //add_proxy_message_to_request(7, 1, "pictures/pic.jpeg","pictures/proxy_yo!.jpeg", req); + start_request(req); + } + */ ssp_thread_join(app->server_handle); + //ssp_thread_join(app2->server_handle); //free(conf); return 0; } diff --git a/Program/src/makefile b/Program/src/makefile index cea6403..5e60dad 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -1,18 +1,19 @@ -PROJDIR = $(CURDIR)/.. -INCLUDE += -I$(PROJDIR)/include +#PROJDIR = $(CURDIR)/.. +PROJDIR = $(CURDIR)/../../../../../ +INCLUDE += -I$(CURDIR)/../include #---------------------------FOR FREE RTOS INTEGRATION--------------------------- #path to source includes -#INCLUDE += -I$(PROJDIR)/../../../../Source/include +INCLUDE += -I$(PROJDIR)/Source/include #path to compiler includes (portmacro.h) -#INCLUDE += -I$(PROJDIR)/../../../../Source/portable/GCC/POSIX/ +INCLUDE += -I$(PROJDIR)/Source/portable/GCC/POSIX/ #path to FreeRTOSconfig -#INCLUDE += -I$(PROJDIR)/../../../../Project/ +INCLUDE += -I$(PROJDIR)/Project/ #------------------------------------------------------------------------------- #---------------------------FOR CSP INTEGRATION--------------------------------- @@ -68,15 +69,15 @@ CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = LIBS = -pthread -STATIC_FILES = -STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a +#STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a #STATIC_FILES += $(PROJDIR)/FreeRtos #---------------------------Compiler flags--------------------------- #32 bit machines, leave this out if your machine is 64 bit -CFLAGS += -m32 -#CFLAGS += -m64 +#CFLAGS += -m32 +CFLAGS += -m64 + CFLAGS += -g -UUSE_STDIO -D__GCC_POSIX__=1 CFLAGS += -pthread CFLAGS += -DDEBUG=1 diff --git a/Program/src/port.c b/Program/src/port.c index b9d54f1..1b7766c 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -15,6 +15,8 @@ Author: Evan Giese #include #include #include + #include + #endif #ifdef POSIX_FILESYSTEM @@ -27,6 +29,16 @@ Author: Evan Giese #include "FreeRTOS.h" #include "task.h" #include "portable.h" + + //make sure these are available in FREERTOS + #include + #include + #include + #include + #include + #include + #include + #endif #ifdef CSP_NETWORK @@ -280,8 +292,10 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void params, /* Parameter passed into the task. */ tskIDLE_PRIORITY,/* Priority at which the task is created. */ xHandle ); /* Used to pass out the created task's handle. */ - if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) + if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) { ssp_error("Not enough memory to start task\n"); + return NULL; + } return xHandle; From 80d64950ccd782b02665e324217b500cc437388a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 24 Jul 2020 11:57:53 -0600 Subject: [PATCH 256/400] new csp changes --- Program/src/csp_server_provider.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 1c22ad3..e086f19 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -236,7 +236,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, } /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ - conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_CONNECTION_SO); + conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_SO_NONE); if (conn == NULL) { /* Connect failed */ ssp_printf("Connection failed\n"); From 0de8f92c5cca05fed1cfd7e2fa7ec415dc0141b0 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 8 Aug 2020 14:03:12 -0600 Subject: [PATCH 257/400] Moved the necessary stuff for scheduling a request to a user function --- Program/include/requests.h | 5 +++-- Program/src/requests.c | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 797b0e7..6153285 100644 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -49,8 +49,10 @@ void free_lv(LV lv); void print_request_procedure(Request *req); int start_scheduled_requests(uint32_t dest_id, FTP *app); int schedule_put_request(uint32_t dest_id,char *source_file_name,char *destination_file_name,uint8_t transmission_mode, FTP *app); +int schedule_request(Request *req, uint32_t dest_id, uint8_t transmission_mode, FTP *app); -//----------------------------new stuff for users starting request--------------- + +Request *init_request_no_client(); int put_request_no_client( Request *req, char *source_file_name, @@ -60,6 +62,5 @@ int put_request_no_client( void add_request_to_client(Request *req, Client *client); Client *start_client(FTP *app, uint8_t dest_id); -Request *init_request_no_client(); #endif \ No newline at end of file diff --git a/Program/src/requests.c b/Program/src/requests.c index 36587e8..6ba9874 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -420,6 +420,16 @@ Request *put_request( /*NULL for source and destination filenames shall indicate that only Meta data will be delivered. Side effect: add request to client request list returns the request*/ + +int schedule_request(Request *req, uint32_t dest_id, uint8_t transmission_mode, FTP *app) { + req->dest_cfdp_id = dest_id; + req->my_cfdp_id = app->my_cfdp_id; + req->transmission_mode = transmission_mode; + req->procedure = sending_start; + int error = save_req_to_file(req); + return error; +} + int schedule_put_request( uint32_t dest_id, char *source_file_name, @@ -427,7 +437,7 @@ int schedule_put_request( uint8_t transmission_mode, FTP *app ) { - int error = -1; + int error = 0; Request *req = init_request_no_client(); if (req == NULL) { ssp_error("couldn't init request"); @@ -439,11 +449,7 @@ int schedule_put_request( return error; } - req->dest_cfdp_id = dest_id; - req->my_cfdp_id = app->my_cfdp_id; - req->transmission_mode = transmission_mode; - req->procedure = sending_start; - error = save_req_to_file(req); + error = schedule_request(req, dest_id, transmission_mode, app); return error; } From b8dc607151196c99cd03e63e0df88ca7075194a3 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 8 Aug 2020 14:48:52 -0600 Subject: [PATCH 258/400] Delete requests from filesystem when they are successfully finished --- Program/src/tasks.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 3b91ae7..9dba48e 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -162,9 +162,12 @@ void remove_request_check(Node *node, void *request, void *args) { if (req->procedure == clean_up) { ssp_printf("removing request\n"); Request *remove_this = req_list->removeNode(req_list, node); - //int error = delete_saved_request(req); - //if (error < 0) - // ssp_error("couldn't delete finished request\n"); + + if (req->local_entity.transaction_finished_indication) { + int error = delete_saved_request(req); + if (error < 0) + ssp_error("couldn't delete finished request, the request may have finished before journaling it\n"); + } ssp_cleanup_req(remove_this); } From 0a0450b7410b0030e4ba0ba778045c1ad6474b91 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 8 Aug 2020 15:01:36 -0600 Subject: [PATCH 259/400] change message on timeout for un acked requests --- Program/src/tasks.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 9dba48e..01d6419 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -64,9 +64,12 @@ static void timeout(Request *req) { bool is_timeout = check_timeout(&req->timeout_before_cancel, TIMEOUT_BEFORE_CANCEL_REQUEST); if (is_timeout) { if (req->local_entity.transaction_finished_indication){ - ssp_printf("file successfully sent without issue transaction: %d\n", req->transaction_sequence_number); - } else { - ssp_printf("stopped early, timed out without finishing transaction, saving req to be reopened later: %d\n", req->transaction_sequence_number); + ssp_printf("ACKNOWLEDGED request successfully sent without issue transaction: %d\n", req->transaction_sequence_number); + } else if (req->transmission_mode == UN_ACKNOWLEDGED_MODE){ + ssp_printf("UN_ACKNOWLEDGED request successfully sent without issue transaction: %d\n", req->transaction_sequence_number); + } + else { + ssp_printf("stopped early, timed out without finishing request, saving req to be reopened later: %d\n", req->transaction_sequence_number); print_request_state(req); save_req_to_file(req); } @@ -163,7 +166,7 @@ void remove_request_check(Node *node, void *request, void *args) { ssp_printf("removing request\n"); Request *remove_this = req_list->removeNode(req_list, node); - if (req->local_entity.transaction_finished_indication) { + if (req->local_entity.transaction_finished_indication || req->transmission_mode == UN_ACKNOWLEDGED_MODE) { int error = delete_saved_request(req); if (error < 0) ssp_error("couldn't delete finished request, the request may have finished before journaling it\n"); From 4f54cf6d679d62885042c4d46ab0a9aeb6789b7f Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sat, 22 Aug 2020 14:37:32 -0600 Subject: [PATCH 260/400] create generic server provider to just use queues --- Program/include/tasks.h | 2 + Program/src/generic_server_provider.c | 68 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 Program/src/generic_server_provider.c diff --git a/Program/include/tasks.h b/Program/include/tasks.h index 7f19966..24ea558 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -22,6 +22,8 @@ void *ssp_csp_connectionless_server_task(void *params); void *ssp_csp_connection_client_task(void *params); void *ssp_csp_connection_server_task(void *params); void ssp_client_join(Client *client); +void *ssp_generic_client_task(void *params); +void *ssp_generic_server_task(void *params); void remove_request_check(Node *node, void *request, void *args); diff --git a/Program/src/generic_server_provider.c b/Program/src/generic_server_provider.c new file mode 100644 index 0000000..c496e01 --- /dev/null +++ b/Program/src/generic_server_provider.c @@ -0,0 +1,68 @@ + +/* +void connection_server(char *host_name, char* port, int initial_buff_size, int connection_limit, + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*onTimeOut)(void *other), + int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), + void *other); +*/ +#include "port.h" +#include "csp.h" +#include "csp_server_provider.h" +#include "csp_conn.h" +#include "queue.h" + +extern int exit_now; + +void ssp_generic_server( + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), + int (*checkExit)(void *app), + void (*onExit)(void *app), + void *app) { + + FTP *ftp = (FTP *)app; + QueueHandle_t *xQueue = (QueueHandle_t*) ftp->incoming_packets; + + for (;;) { + + if (exit_now || checkExit(app)){ + ssp_printf("exiting server thread\n"); + break; + } + + csp_packet_t *packet; + bool is_not_empty = xQueueReceive(*xQueue, packet, 5); + + if (!is_not_empty) + onTimeOut(app); + return; + + //switch ids, we do this for the sendto function, to reply + uint8_t d_id = packet->id.dst; + uint8_t s_id = packet->id.src; + packet->id.dst = s_id; + packet->id.src = d_id; + + uint8_t d_port = packet->id.dport; + uint8_t s_port = packet->id.sport; + packet->id.dport = s_port; + packet->id.sport = d_port; + + if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(csp_packet_t), app) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet); + + } + onExit(app); + +} + + + +void ssp_generic_client() { + + return; +} \ No newline at end of file From c852bf76dfeabaac4aed1b4eccd2731458bb4e62 Mon Sep 17 00:00:00 2001 From: EvanGee Date: Sun, 23 Aug 2020 12:08:42 -0600 Subject: [PATCH 261/400] Add generic server boilerplate --- Program/include/generic_server_provider.h | 11 +++++ Program/include/types.h | 14 +++++- Program/src/file_delivery_app.c | 8 +++ Program/src/generic_server_provider.c | 59 ++++++++++++++++++----- Program/src/tasks.c | 11 +++++ 5 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 Program/include/generic_server_provider.h diff --git a/Program/include/generic_server_provider.h b/Program/include/generic_server_provider.h new file mode 100644 index 0000000..b45caec --- /dev/null +++ b/Program/include/generic_server_provider.h @@ -0,0 +1,11 @@ +#ifndef SSP_GENERIC_PROVIDER_H +#define SSP_GENERIC_PROVIDER_H +#include "stdint.h" + + + + + + + +#endif diff --git a/Program/include/types.h b/Program/include/types.h index 1f6589d..f7f53c8 100644 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -502,6 +502,7 @@ typedef enum Network_type { posix_connection, csp_connectionless, csp_connection, + generic } Network_type; @@ -640,6 +641,15 @@ typedef struct request { } Request; +typedef struct custom_queue { + + //used for generic drivers (aka no drivers) cast to a QueueHandle_t in our implementation + void* queue; + //used for csp connection struct + void* connection; +} Custom_queue; + + //add "client" in here to represent local entity typedef struct ftp { @@ -648,9 +658,9 @@ typedef struct ftp { //buffer for making packets, is length of packet_len char* buff; - - + Custom_queue custom_queue; + void *server_handle; uint32_t my_cfdp_id; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index da338f0..4ba3778 100644 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -25,6 +25,9 @@ static int create_ssp_server_drivers(FTP *app) { case csp_connection: app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); break; + case generic: + app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_generic_server_task, app); + break; default: ssp_printf("server couldn't start, 'type of network' not recognized\n"); break; @@ -53,6 +56,9 @@ static int create_ssp_client_drivers(Client *client) { case csp_connection: client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_client_task, client); break; + case generic: + client->client_handle = ssp_thread_create(STACK_ALLOCATION, ssp_generic_client_task, client); + break; default: ssp_printf("client couldn't start, 'type of network' not recognized\n"); break; @@ -63,6 +69,8 @@ static int create_ssp_client_drivers(Client *client) { return 0; } + + FTP *init_ftp(uint32_t my_cfdp_address) { diff --git a/Program/src/generic_server_provider.c b/Program/src/generic_server_provider.c index c496e01..a02ec32 100644 --- a/Program/src/generic_server_provider.c +++ b/Program/src/generic_server_provider.c @@ -1,12 +1,12 @@ /* void connection_server(char *host_name, char* port, int initial_buff_size, int connection_limit, - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), - int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), - int (*checkExit)(void *other), - void (*onExit)(void *other), - void *other); + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), + int (*onTimeOut)(void *app), + int (*onStdIn)(void *app), + int (*checkExit)(void *app), + void (*onExit)(void *app), + void *app); */ #include "port.h" #include "csp.h" @@ -16,14 +16,15 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c extern int exit_now; -void ssp_generic_server( - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), +void ssp_generic_connectionless_server( + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), + int (*onTimeOut)(void *app), int (*checkExit)(void *app), void (*onExit)(void *app), void *app) { FTP *ftp = (FTP *)app; - QueueHandle_t *xQueue = (QueueHandle_t*) ftp->incoming_packets; + csp_packet_t *packet; for (;;) { @@ -31,8 +32,8 @@ void ssp_generic_server( ssp_printf("exiting server thread\n"); break; } - - csp_packet_t *packet; + + QueueHandle_t *xQueue = (QueueHandle_t*) ftp->custom_queue.queue; bool is_not_empty = xQueueReceive(*xQueue, packet, 5); if (!is_not_empty) @@ -61,8 +62,40 @@ void ssp_generic_server( } +void csp_connection_server( + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), + int (*onTimeOut)(void *app), + int (*checkExit)(void *app), + void (*onExit)(void *app), + void *app) +{ + /* Pointer to current connection and packet */ + csp_packet_t *packet; + + FTP *ftp = (FTP *)app; + + /* Process incoming connections */ + for (;;) { -void ssp_generic_client() { + //bit of an issue, since this can change during runtime, this exists outside of the driver + csp_conn_t *conn = (csp_conn_t*) ftp->custom_queue.connection; + QueueHandle_t *xQueue = (QueueHandle_t*) ftp->custom_queue.queue; + + bool is_not_empty = xQueueReceive(*xQueue, packet, 5); - return; + if (!is_not_empty) + onTimeOut(app); + return; + + if (exit_now || checkExit(app)) + break; + + if (onRecv(-1, packet->data, packet_len, NULL, conn, sizeof(struct csp_conn_s), app) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet); + + } + + onExit(app); } \ No newline at end of file diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 01d6419..a173ec1 100644 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -555,6 +555,17 @@ void *ssp_csp_connection_client_task(void *params) { #endif return NULL; } + + +void *ssp_generic_client_task(void *params) { + ssp_printf("starting generic server task\n"); + return NULL; +} + +void *ssp_generic_server_task(void *params) { + ssp_printf("starting generic server task\n"); + return NULL; +} /*------------------------------------------------------------------------------ free functions From 16a691bec36d863b43b6429b3a743ce1d2e7fc7c Mon Sep 17 00:00:00 2001 From: EvanGee Date: Tue, 25 Aug 2020 20:57:19 -0600 Subject: [PATCH 262/400] add generic queue handlers --- Program/include/generic_server_provider.h | 18 ++- Program/include/port.h | 14 +- Program/src/generic_server_provider.c | 150 ++++++++++++---------- Program/src/makefile | 3 +- Program/src/port.c | 20 ++- 5 files changed, 123 insertions(+), 82 deletions(-) diff --git a/Program/include/generic_server_provider.h b/Program/include/generic_server_provider.h index b45caec..306f950 100644 --- a/Program/include/generic_server_provider.h +++ b/Program/include/generic_server_provider.h @@ -1,11 +1,19 @@ #ifndef SSP_GENERIC_PROVIDER_H #define SSP_GENERIC_PROVIDER_H -#include "stdint.h" - - - - +#include "port.h" +void csp_generic_server( + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), + int (*onTimeOut)(void *app), + int (*checkExit)(void *app), + void (*onExit)(void *app), + void *app); +void csp_generic_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params); #endif diff --git a/Program/include/port.h b/Program/include/port.h index c6c37ed..64347d0 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -11,8 +11,8 @@ Author: Evan Giese #define POSIX_PORT #define POSIX_FILESYSTEM -//#define CSP_NETWORK - +#define CSP_NETWORK +//#define FREE_RTOS_PORT //comment this out if you want to sendto function to actually work //#define TEST @@ -40,6 +40,11 @@ Author: Evan Giese #define SSP_SEEK_SET SEEK_SET #endif +//#ifdef FREE_RTOS_PORT + //TODO need the above POSIX_PORT definitions to work, if we are bigendian, then the + //htonl etc are empty. +//#else + #ifdef POSIX_PORT #include #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN @@ -60,10 +65,7 @@ Author: Evan Giese #define ssp_atol atol #endif -#ifdef FREE_RTOS_PORT - //TODO need the above POSIX_PORT definitions to work, if we are bigendian, then the - //htonl etc are empty. -#endif + //don't change these in the header file here, if you need to change them diff --git a/Program/src/generic_server_provider.c b/Program/src/generic_server_provider.c index a02ec32..cd38591 100644 --- a/Program/src/generic_server_provider.c +++ b/Program/src/generic_server_provider.c @@ -1,87 +1,39 @@ -/* -void connection_server(char *host_name, char* port, int initial_buff_size, int connection_limit, - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), - int (*onTimeOut)(void *app), - int (*onStdIn)(void *app), - int (*checkExit)(void *app), - void (*onExit)(void *app), - void *app); -*/ -#include "port.h" -#include "csp.h" -#include "csp_server_provider.h" -#include "csp_conn.h" -#include "queue.h" +//strong dependency for FreeRTOS here +#include "generic_server_provider.h" +#ifdef FREE_RTOS_PORT extern int exit_now; -void ssp_generic_connectionless_server( - int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), - int (*onTimeOut)(void *app), - int (*checkExit)(void *app), - void (*onExit)(void *app), - void *app) { - - FTP *ftp = (FTP *)app; - csp_packet_t *packet; - - for (;;) { +#include "queue.h" +#include "port.h" +#include "csp.h" - if (exit_now || checkExit(app)){ - ssp_printf("exiting server thread\n"); - break; - } - - QueueHandle_t *xQueue = (QueueHandle_t*) ftp->custom_queue.queue; - bool is_not_empty = xQueueReceive(*xQueue, packet, 5); +QueueHandle_t xQueueFtpServerReceive; +QueueHandle_t xQueueFtpClientReceive; - if (!is_not_empty) - onTimeOut(app); - return; - - //switch ids, we do this for the sendto function, to reply - uint8_t d_id = packet->id.dst; - uint8_t s_id = packet->id.src; - packet->id.dst = s_id; - packet->id.src = d_id; - - uint8_t d_port = packet->id.dport; - uint8_t s_port = packet->id.sport; - packet->id.dport = s_port; - packet->id.sport = d_port; - - if (onRecv(-1, (char *)packet->data, packet->length, NULL, packet, sizeof(csp_packet_t), app) == -1) - ssp_printf("recv failed\n"); - csp_buffer_free(packet); - - } - onExit(app); - +void _init_queues(int server_size, int client_size){ + if (xQueueFtpServerReceive == NULL) + xQueueFtpServerReceive = xQueueCreate(server_size, sizeof (csp_packet_t*)); + if (xQueueFtpClientReceive == NULL) + xQueueFtpClientReceive = xQueueCreate(client_size, sizeof (csp_packet_t*)); } - -void csp_connection_server( +void csp_generic_server( int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), int (*onTimeOut)(void *app), int (*checkExit)(void *app), void (*onExit)(void *app), void *app) { - /* Pointer to current connection and packet */ - csp_packet_t *packet; - FTP *ftp = (FTP *)app; + csp_packet_t *packet; + _init_queues(10, 10); - /* Process incoming connections */ for (;;) { - - //bit of an issue, since this can change during runtime, this exists outside of the driver - csp_conn_t *conn = (csp_conn_t*) ftp->custom_queue.connection; - QueueHandle_t *xQueue = (QueueHandle_t*) ftp->custom_queue.queue; - bool is_not_empty = xQueueReceive(*xQueue, packet, 5); + bool is_not_empty = xQueueReceive(xQueueFtpServerReceive, packet, 100); if (!is_not_empty) onTimeOut(app); @@ -90,12 +42,74 @@ void csp_connection_server( if (exit_now || checkExit(app)) break; - if (onRecv(-1, packet->data, packet_len, NULL, conn, sizeof(struct csp_conn_s), app) == -1) - ssp_printf("recv failed\n"); + if (onRecv(-1, packet->data, packet->length, packet, sizeof(csp_packet_t), 0, app) == -1) + ssp_printf("recv failed\n"); csp_buffer_free(packet); } onExit(app); -} \ No newline at end of file +} + + + + +void csp_generic_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params) +{ + + csp_packet_t packet_send; + packet_send.id.dst=dest_id; + packet_send.id.src=csp_get_address(); + packet_send.id.dport=dest_port; + packet_send.id.sport=my_port; + + csp_packet_t *packet_recv; + + for (;;) { + if (exit_now || checkExit(params)){ + ssp_printf("exiting client thread\n"); + break; + } + + onSend(-1, &packet_send, sizeof(csp_packet_t), params); + + bool is_not_empty = xQueueReceive(xQueueFtpServerReceive, packet_recv, 100); + + if (!is_not_empty) + return; + + if (onRecv(-1, packet_recv->data, packet_recv->length, NULL, packet_recv, sizeof(csp_packet_t), params) == -1) + ssp_printf("recv failed\n"); + + csp_buffer_free(packet_recv); + + } + + onExit(params); +} +#else +//for compiling without freeRTOS, but these functions do nothing. +void csp_generic_server( + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *app), + int (*onTimeOut)(void *app), + int (*checkExit)(void *app), + void (*onExit)(void *app), + void *app){ + ssp_printf("free Rtos not defined, can't do shit\n"); + } + +void csp_generic_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, + int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), + int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params), + void *params){ + ssp_printf("free Rtos not defined, can't do shit\n"); + } +#endif \ No newline at end of file diff --git a/Program/src/makefile b/Program/src/makefile index cea6403..2df4381 100644 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -2,8 +2,6 @@ PROJDIR = $(CURDIR)/.. INCLUDE += -I$(PROJDIR)/include - - #---------------------------FOR FREE RTOS INTEGRATION--------------------------- #path to source includes #INCLUDE += -I$(PROJDIR)/../../../../Source/include @@ -37,6 +35,7 @@ CFILES += filesystem_funcs.c CFILES += requests.c CFILES += list.c CFILES += packet.c +CFILES += generic_server_provider.c #----------------------------test files------------------------- #entrypoint diff --git a/Program/src/port.c b/Program/src/port.c index b9d54f1..a77de77 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -141,12 +141,30 @@ int ssp_readdir(void *dir, char *file){ Network port functions, these are used to interchange different network stacks ------------------------------------------------------------------------------*/ +#ifdef FREE_RTOS_PORT +extern QueueHandle_t sendQueue; +#endif void ssp_sendto(Response res) { #ifdef TEST return; #endif - if (res.type_of_network == csp_connectionless) { + + if (res.type_of_network == generic) { + + #ifdef FREE_RTOS_PORT + while (true) { + if (xQueueSendToBack(sendQueue, res.msg, 100) != pdPASS) + ssp_printf("queue full, failed to post packet, blocking task untill sent\n"); + else + break; + } + return; + #else + ssp_printf("FreeRtos not defined, can't use generic queues"); + #endif + } + else if (res.type_of_network == csp_connectionless) { #ifdef CSP_NETWORK csp_packet_t *packet = (csp_packet_t *) res.addr; csp_packet_t *packet_sending; From d7b66fb6896fc16bf9aadd536ec92c156c6f32dc Mon Sep 17 00:00:00 2001 From: EvanGee Date: Wed, 25 Nov 2020 18:26:54 -0700 Subject: [PATCH 263/400] fuck externs --- Program/include/port.h | 36 +++++++++++++--------- Program/include/posix_server_provider.h | 2 +- Program/src/csp_server_provider.c | 16 +++++----- Program/src/generic_server_provider.c | 5 ++- Program/src/port.c | 8 +++++ Program/src/posix_server_provider.c | 41 ++++++++++++------------- 6 files changed, 60 insertions(+), 48 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 5117fe1..9f8c489 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,11 +9,14 @@ Author: Evan Giese #define STACK_ALLOCATION 16384 -//#define POSIX_PORT -#define FREE_RTOS_PORT -#define POSIX_FILESYSTEM -#define CSP_NETWORK //#define FREE_RTOS_PORT +#define POSIX_PORT + +//#define RED_FS +#define POSIX_FILESYSTEM + +//#define CSP_NETWORK + //comment this out if you want to sendto function to actually work //#define TEST @@ -42,11 +45,6 @@ Author: Evan Giese #define SSP_SEEK_SET SEEK_SET #endif -//#ifdef FREE_RTOS_PORT - //TODO need the above POSIX_PORT definitions to work, if we are bigendian, then the - //htonl etc are empty. -//#else - #ifdef POSIX_PORT #include #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN @@ -67,11 +65,10 @@ Author: Evan Giese #define ssp_atol atol #endif - #ifdef FREE_RTOS_PORT - #include - #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN - #define SSP_AF_INET AF_INET + #include + #define SSP_INET_ADDRSTRLEN 16 + #define SSP_AF_INET 2 #define ssp_htonl htonl #define ssp_ntohl ntohl #define ssp_htons htons @@ -88,6 +85,15 @@ Author: Evan Giese #define ssp_atol atol #endif +#ifdef RED_FS + + #include + #define SSP_O_RDWR RED_O_RDWR + #define SSP_O_CREAT RED_O_CREAT + #define SSP_O_TRUNC RED_O_TRUNC + #define SSP_SEEK_SET RED_SEEK_SET + +#endif //don't change these in the header file here, if you need to change them //change them in the .c file @@ -112,8 +118,10 @@ int ssp_rename(const char *old, const char *new); int ssp_mkdir(char *dir_name); void *ssp_opendir(char *dir_name); int ssp_readdir(void *dir, char *file); +int get_exit(); +void set_exit(); void reset_request(Request *req); -#endif \ No newline at end of file +#endif diff --git a/Program/include/posix_server_provider.h b/Program/include/posix_server_provider.h index f46da18..641ecae 100644 --- a/Program/include/posix_server_provider.h +++ b/Program/include/posix_server_provider.h @@ -8,7 +8,7 @@ Author: Evan Giese #define POSIX_SERVER_H #include "stdint.h" -int *prepareSignalHandler(void); +int prepareSignalHandler(void); /*------------------------------------------------------------------------------ Purpose: This function creates a udp select server on the socket sfd. Perameters: int sfd: The socket descriptor created by prepareUdpHost diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index e086f19..597bc6e 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -11,8 +11,6 @@ Author: Evan Giese #include "csp_conn.h" -int exit_now; - /*------------------------------------------------------------------------------ CSP STUFF! @@ -58,14 +56,14 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p } else { ssp_error("couldn't get new packet for sending!\n"); - exit_now = 1; + set_exit(); } char buff[packet_len]; memset(buff, 0, packet_len); for (;;) { - if (exit_now || checkExit(params)){ + if (get_exit() || checkExit(params)){ ssp_printf("exiting client thread\n"); break; } @@ -114,7 +112,7 @@ void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, for (;;) { - if (exit_now || checkExit(other)){ + if (get_exit() || checkExit(other)){ ssp_printf("exiting server thread\n"); break; } @@ -179,7 +177,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, /* Process incoming connections */ for (;;) { - if (exit_now || checkExit(other)){ + if (get_exit() || checkExit(other)){ ssp_printf("exiting serv thread\n"); break; } @@ -192,7 +190,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, for (;;) { - if (exit_now || checkExit(other)) + if (get_exit() || checkExit(other)) break; onTimeOut(other); @@ -230,7 +228,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, while (1) { - if (exit_now || checkExit(params)){ + if (get_exit() || checkExit(params)){ ssp_printf("exiting client thread\n"); break; } @@ -244,7 +242,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, } for (;;) { - if (exit_now || checkExit(params)){ + if (get_exit() || checkExit(params)){ ssp_printf("exiting client thread\n"); break; } diff --git a/Program/src/generic_server_provider.c b/Program/src/generic_server_provider.c index cd38591..ba8efea 100644 --- a/Program/src/generic_server_provider.c +++ b/Program/src/generic_server_provider.c @@ -3,7 +3,6 @@ #include "generic_server_provider.h" #ifdef FREE_RTOS_PORT -extern int exit_now; #include "queue.h" #include "port.h" @@ -39,7 +38,7 @@ void csp_generic_server( onTimeOut(app); return; - if (exit_now || checkExit(app)) + if (get_exit() || checkExit(app)) break; if (onRecv(-1, packet->data, packet->length, packet, sizeof(csp_packet_t), 0, app) == -1) @@ -72,7 +71,7 @@ void csp_generic_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uin csp_packet_t *packet_recv; for (;;) { - if (exit_now || checkExit(params)){ + if (get_exit() || checkExit(params)){ ssp_printf("exiting client thread\n"); break; } diff --git a/Program/src/port.c b/Program/src/port.c index 45546be..564db05 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -6,6 +6,7 @@ Author: Evan Giese ------------------------------------------------------------------------------*/ #include "port.h" +static int exit_now = 0; #ifdef POSIX_PORT #include @@ -45,6 +46,13 @@ Author: Evan Giese #include "csp.h" #endif +int get_exit() { + return exit_now; +} + +void set_exit() { + exit_now = 1; +} /*------------------------------------------------------------------------------ File system port functions, these are used to interchange different diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index d1e5eea..35c57f4 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -12,8 +12,6 @@ Author: Evan Giese #include "posix_server_provider.h" #include "port.h" #include - -extern int exit_now; static int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { int count = 0; @@ -149,14 +147,14 @@ static void interuptHandler(int signum) switch (signum) { case SIGINT: - exit_now = 1; + set_exit(); break; } } //see header file -int *prepareSignalHandler() +int prepareSignalHandler() { struct sigaction actionData; sigemptyset(&actionData.sa_mask); @@ -168,6 +166,7 @@ int *prepareSignalHandler() ssp_error("sigaction sigint failed\n"); exit(EXIT_FAILURE); } + int exit_now = get_exit(); return &exit_now; } @@ -196,7 +195,7 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c int sfd = prepareHost(host_name, addr, &size_of_addr, port, SOCK_STREAM, 1); if (sfd < 0) - exit_now = 1; + set_exit(); int err = listen(sfd, connection_limit); @@ -214,19 +213,19 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); if (buff_size == NULL) - exit_now = true; + set_exit(); *buff_size = initial_buff_size; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), *buff_size); if (buff_size == NULL) - exit_now = true; + set_exit(); for (;;) { - if (exit_now || checkExit(other)){ + if (get_exit() || checkExit(other)){ ssp_printf("exiting server thread\n"); break; } @@ -322,7 +321,7 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, int sfd = prepareHost(host_name, addr, &size_of_addr, port, SOCK_DGRAM, 1); if (sfd < 0) - exit_now = 1; + set_exit(); size_t size_of_socket_struct = 0; @@ -335,18 +334,18 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); if (buff_size == NULL) - exit_now = true; + set_exit(); *buff_size = initial_buff_size + 10; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(sizeof(char), *buff_size); if (buff == NULL) - exit_now = true; + set_exit(); for (;;) { - if (exit_now || checkExit(other)){ + if (get_exit() || checkExit(other)){ ssp_printf("exiting server thread\n"); break; } @@ -417,11 +416,11 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *para sfd = prepareHost(hostname, addr, &size_of_addr, port, SOCK_DGRAM, 0); if (sfd < 0) - exit_now = 1; + set_exit(); uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); if (buff_size == NULL) - exit_now = true; + set_exit(); *buff_size = packet_len + 10; @@ -429,11 +428,11 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *para char *buff = ssp_alloc(sizeof(char), prev_buff_size); if (buff == NULL) - exit_now = true; + set_exit(); for (;;) { - if (exit_now || checkExit(params)) + if (get_exit() || checkExit(params)) break; if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ @@ -482,23 +481,23 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, sfd = prepareHost(hostname, addr, &size_of_addr, port, SOCK_STREAM, 0); if (sfd < 0) - exit_now = 1; + set_exit(); uint32_t *buff_size = ssp_alloc(1, sizeof(uint32_t)); if (buff_size == NULL) - exit_now = true; + set_exit(); *buff_size = packet_len; uint32_t prev_buff_size = *buff_size; char *buff = ssp_alloc(prev_buff_size, sizeof(char)); if (buff == NULL) - exit_now = true; + set_exit(); for (;;) { - if (exit_now || checkExit(params)) + if (get_exit() || checkExit(params)) break; if(!resizeBuff(&buff, buff_size, &prev_buff_size)){ @@ -515,7 +514,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, params) == -1) { ssp_error("recv failed\n"); - exit_now = 1; + set_exit(); } } From 7cc9023d88962f81c108762b28a3390200c289cd Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 26 Nov 2020 17:23:42 -0700 Subject: [PATCH 264/400] update to change code to be sat build complient --- Program/src/filesystem_funcs.c | 31 +++++++++++++++++-------------- Program/src/main.c | 5 +---- Program/src/mib.c | 9 ++------- Program/src/port.c | 33 ++++++++++++++++++++------------- Program/src/protocol_handler.c | 4 ++-- Program/src/requests.c | 4 ++-- Program/src/utils.c | 4 ++-- 7 files changed, 46 insertions(+), 44 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index cc6722e..6faabc4 100644 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -139,7 +139,8 @@ uint32_t calc_check_sum(char *data, uint32_t length) { uint8_t remaining_bytes = length % 4; uint32_t check_sum = 0; uint32_t end = length - 4; - for (unsigned int i = 0; i < end; i+= 4){ + unsigned int i = 0; + for (i = 0; i < end; i+= 4){ check_sum += *((uint32_t *) &data[i]); } @@ -148,9 +149,9 @@ uint32_t calc_check_sum(char *data, uint32_t length) { memset(last_chunk, 0, 4); end = length - remaining_bytes; - - for (uint8_t i = 0; i < remaining_bytes; i++) { - last_chunk[i] = data[end + i];; + unsigned int i = 0; + for (i = 0; i < remaining_bytes; i++) { + last_chunk[i] = data[end + i]; } check_sum += *((uint32_t*) &last_chunk); @@ -166,7 +167,8 @@ uint32_t check_sum_file(File *file, uint16_t stack_buffer) { char buff[stack_buffer]; uint32_t checksum = 0; uint32_t bytes_read = 0; - for (int i = 0; i < file->total_size; i++) { + int i = 0; + for (i = 0; i < file->total_size; i++) { bytes_read = get_offset(file, buff, stack_buffer, (int) stack_buffer); if (bytes_read > 0) @@ -308,7 +310,7 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa char buff[total_size]; - int fd = ssp_open(file_name, O_RDWR); + int fd = ssp_open(file_name, SSP_O_RDWR); if (fd < 0) { ssp_error("couldn't open file\n"); return -1; @@ -325,8 +327,8 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa ssp_error("Failed to parse JSON\n"); return -1; } - - for (int i = 1; i < r; i++) { + int i = 1; + for (i = 1; i < r; i++) { int key_size = tok[i].end - tok[i].start; int value_size = tok[i+1].end - tok[i+1].start; @@ -419,8 +421,8 @@ int get_file_from_file(int fd, File *file) { if (missing_offsets == NULL) { return -1; } - - for (int i = 0; i < length; i++) { + int i = 0; + for (i = 0; i < length; i++) { r = ssp_read(fd, (char*)&offset, sizeof(Offset)); @@ -587,7 +589,7 @@ int save_req_to_file(Request *req) { char file_name[255]; get_file_name(file_name, req->dest_cfdp_id, req->my_cfdp_id, req->transaction_sequence_number); - int fd = ssp_open(file_name, O_RDWR | O_CREAT); + int fd = ssp_open(file_name, SSP_O_RDWR | SSP_O_CREAT); if (fd < 0) { ssp_error("couldn't open file\n"); return -1; @@ -697,7 +699,8 @@ static int get_messages_from_file(int fd, List *messages){ } if (number_of_messages > 0) { - for (int i = 0; i < number_of_messages; i++) { + int i = 0; + for (i = 0; i < number_of_messages; i++) { uint8_t message_type = 0; error = ssp_read(fd, (char *) &message_type, sizeof(uint8_t)); @@ -779,7 +782,7 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint3 get_file_name(file_name, dest_cfdp_id, my_cfdp_id, transaction_seq_num); ssp_printf("opening %s\n", file_name); - int fd = ssp_open(file_name, O_RDWR); + int fd = ssp_open(file_name, SSP_O_RDWR); if (fd < 0) { ssp_error("couldn't open file\n"); return -1; @@ -794,4 +797,4 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint3 } return 0; -} \ No newline at end of file +} diff --git a/Program/src/main.c b/Program/src/main.c index 7d3d5ee..992ccff 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -29,9 +29,6 @@ Author: Evan Giese #include "port.h" #include "tasks.h" -//exit handler variable for the main thread -static int *exit_now; - /*------------------------------------------------------------------------------ Purpose: This struct if our configuration for this program, these elements are set with getopt @@ -108,7 +105,7 @@ int main(int argc, char** argv) { //exit handler for the main thread; - exit_now = prepareSignalHandler(); + prepareSignalHandler(); //get-opt configuration Config *conf = configuration(argc, argv); diff --git a/Program/src/mib.c b/Program/src/mib.c index 408b57d..4ad6031 100644 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -80,7 +80,8 @@ static char *parse_list[PARSE_TOTAL] = { static void parse_mib(char *key, char *value, void *params) { int len = 0; - for (int i = 0; i < PARSE_TOTAL; i++) { + int i = 0; + for (i = 0; i < PARSE_TOTAL; i++) { len = strnlen(parse_list[i], 50); if (strncmp(key, parse_list[i], len) != 0) @@ -173,9 +174,3 @@ int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { void ssp_cleanup_pdu_header(Pdu_header *pdu_header) { ssp_free(pdu_header); } - - - - - - diff --git a/Program/src/port.c b/Program/src/port.c index 564db05..4361cd0 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -29,7 +29,7 @@ static int exit_now = 0; #ifdef FREE_RTOS_PORT #include "FreeRTOS.h" #include "task.h" - #include "portable.h" + //#include "portable.h" //not sure what i need here for sat build //make sure these are available in FREERTOS #include @@ -37,7 +37,6 @@ static int exit_now = 0; #include #include #include - #include #include #endif @@ -46,13 +45,6 @@ static int exit_now = 0; #include "csp.h" #endif -int get_exit() { - return exit_now; -} - -void set_exit() { - exit_now = 1; -} /*------------------------------------------------------------------------------ File system port functions, these are used to interchange different @@ -111,6 +103,15 @@ int ssp_remove(char *pathname){ return -1; } +int get_exit() { + return exit_now; +} + +void set_exit() { + exit_now = 1; +} + + int ssp_mkdir(char *dir_name) { #ifdef POSIX_FILESYSTEM int error = mkdir(dir_name, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); @@ -162,6 +163,7 @@ int ssp_readdir(void *dir, char *file){ stacks ------------------------------------------------------------------------------*/ #ifdef FREE_RTOS_PORT +#include "queue.h" extern QueueHandle_t sendQueue; #endif @@ -294,9 +296,14 @@ void ssp_printf(char *stuff, ...) { //returns seconds elapsed, need FREE RTOS realtime clock lib to properly port int ssp_time_count() { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - return ts.tv_sec; + + #ifdef FREE_RTOS_PORT + return 1;//INSERT TIME FUNCTIONS get delta time since last call + #else + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return ts.tv_sec; + #endif } @@ -373,4 +380,4 @@ void ssp_thread_join(void *thread_handle) { pthread_join(*handle, NULL); ssp_free(thread_handle); #endif -} \ No newline at end of file +} diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 6257c5b..75740b5 100644 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -385,8 +385,8 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, &client->pdu_header); uint32_t offset_start = 0; uint32_t offset_end = 0; - - for (int i = 0; i < segments; i++){ + int i = 0; + for (i = 0; i < segments; i++){ //outgoing_packet_index ssp_memcpy(&offset_start, &packet[packet_index], 4); offset_start = ssp_ntohl(offset_start); diff --git a/Program/src/requests.c b/Program/src/requests.c index 6ba9874..4f22ac3 100644 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -493,7 +493,7 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ ssp_snprintf(file_path, sizeof(file_path), "%s/%s", dir_name, file); - fd = ssp_open(file_path, O_RDWR); + fd = ssp_open(file_path, SSP_O_RDWR); if (fd < 0) { clean_up_start_scheduled_requests(fd, req); ssp_error("couldn't open request data file"); @@ -642,4 +642,4 @@ void print_request_procedure(Request *req){ default: break; } -} \ No newline at end of file +} diff --git a/Program/src/utils.c b/Program/src/utils.c index 044d889..8d36b4a 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -11,8 +11,8 @@ void ssp_print_hex(char *stuff, int size){ uint32_t current_packet_index = 0; ssp_printf("printing number of bytes: %u\n", size); - - for (int j = 0; j < size; j += 1) { + int j = 0; + for (j = 0; j < size; j += 1) { ssp_printf("%x.", stuff[current_packet_index]); current_packet_index += 1; From 24c3d178e6121199dcf182876622989816c04b7a Mon Sep 17 00:00:00 2001 From: EvanGee Date: Thu, 26 Nov 2020 20:02:48 -0600 Subject: [PATCH 265/400] add some compiler guards so code composer doesn't auto compile --- Program/include/port.h | 8 ++++---- Program/src/csp_server_provider.c | 5 +++-- Program/src/main.c | 3 ++- Program/src/posix_server_provider.c | 6 +++++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 9f8c489..12aa1f5 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,11 +9,11 @@ Author: Evan Giese #define STACK_ALLOCATION 16384 -//#define FREE_RTOS_PORT -#define POSIX_PORT +#define FREE_RTOS_PORT +//#define POSIX_PORT -//#define RED_FS -#define POSIX_FILESYSTEM +#define RED_FS +//#define POSIX_FILESYSTEM //#define CSP_NETWORK diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 597bc6e..20c2751 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -1,3 +1,4 @@ + /*------------------------------------------------------------------------------ This file is protected under copyright. If you want to use it, please include this text, that is my only stipulation. @@ -8,7 +9,7 @@ Author: Evan Giese #include "port.h" #include "csp.h" #include "csp_server_provider.h" -#include "csp_conn.h" +//#include "csp_conn.h" /*------------------------------------------------------------------------------ @@ -263,4 +264,4 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_close(conn); onExit(params); } -} \ No newline at end of file +} diff --git a/Program/src/main.c b/Program/src/main.c index 992ccff..8370027 100644 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -1,3 +1,4 @@ +#ifdef POSIX_PORT /*------------------------------------------------------------------------------ This file is protected under copyright. If you want to use it, please include this text, that is my only stipulation. @@ -184,4 +185,4 @@ int main(int argc, char** argv) { //free(conf); return 0; } - +#endif diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index 35c57f4..a6da953 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -1,3 +1,5 @@ +#ifdef POSIX_PORT + /*------------------------------------------------------------------------------ This file is protected under copyright. If you want to use it, please include this text, that is my only stipulation. @@ -523,4 +525,6 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, ssp_free(buff); ssp_close(sfd); onExit(params); -} \ No newline at end of file +} + +#endif From 599f79f66553e52e58eec3285d265db77a4b3991 Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 15 Jan 2021 18:58:08 -0700 Subject: [PATCH 266/400] make master work with CCS, just don't include posix in build --- Program/include/port.h | 2 +- Program/src/csp_server_provider.c | 4 ++-- Program/src/generic_server_provider.c | 7 ++++--- Program/src/port.c | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 12aa1f5..d2f6720 100644 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -66,7 +66,7 @@ Author: Evan Giese #endif #ifdef FREE_RTOS_PORT - #include + #include #define SSP_INET_ADDRSTRLEN 16 #define SSP_AF_INET 2 #define ssp_htonl htonl diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 20c2751..7a08073 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -7,9 +7,9 @@ Author: Evan Giese ------------------------------------------------------------------------------*/ #include "port.h" -#include "csp.h" +#include "csp/csp.h" #include "csp_server_provider.h" -//#include "csp_conn.h" +#include "csp_conn.h" /*------------------------------------------------------------------------------ diff --git a/Program/src/generic_server_provider.c b/Program/src/generic_server_provider.c index ba8efea..32c1ee3 100644 --- a/Program/src/generic_server_provider.c +++ b/Program/src/generic_server_provider.c @@ -3,13 +3,14 @@ #include "generic_server_provider.h" #ifdef FREE_RTOS_PORT - +#include "FreeRTOS.h" #include "queue.h" #include "port.h" -#include "csp.h" +#include "csp/csp.h" QueueHandle_t xQueueFtpServerReceive; QueueHandle_t xQueueFtpClientReceive; +QueueHandle_t sendQueue; void _init_queues(int server_size, int client_size){ @@ -111,4 +112,4 @@ void csp_generic_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uin void *params){ ssp_printf("free Rtos not defined, can't do shit\n"); } -#endif \ No newline at end of file +#endif diff --git a/Program/src/port.c b/Program/src/port.c index 4361cd0..e5d92d6 100644 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -338,7 +338,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void return NULL; pthread_attr_t *attr = ssp_alloc(1, sizeof(pthread_attr_t)); - if (attr == NULL) { + if (attr == NULL) ssp_free(handler); return NULL; } From 70c7e4ed82b251ec89da951cbe0a936219ec5bc7 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 16 Jan 2021 14:49:34 -0700 Subject: [PATCH 267/400] I don't know why this happened, but I can't change the permissions --- Documents/SpaceProjects.odt | Bin Documents/mib.txt | 0 Program/include/changeNotes | 0 Program/include/file_delivery_app.h | 0 Program/include/filesystem_funcs.h | 0 Program/include/generic_server_provider.h | 0 Program/include/jsmn.h | 0 Program/include/list.h | 0 Program/include/mib.h | 0 Program/include/packet.h | 0 Program/include/port.h | 0 Program/include/posix_server_provider.h | 0 Program/include/protocol_handler.h | 0 Program/include/requests.h | 0 Program/include/tasks.h | 0 Program/include/types.h | 0 Program/src/file_delivery_app.c | 0 Program/src/filesystem_funcs.c | 0 Program/src/generic_server_provider.c | 0 Program/src/list.c | 0 Program/src/main.c | 0 Program/src/makefile | 0 Program/src/mib.c | 0 Program/src/mib/peer_1.json | 0 Program/src/mib/peer_2.json | 0 Program/src/mib/peer_3.json | 0 Program/src/mib/peer_4.json | 0 Program/src/mib/peer_5.json | 0 Program/src/mib/peer_6.json | 0 Program/src/mib/peer_7.json | 0 Program/src/mib/peer_8.json | 0 Program/src/packet.c | 0 Program/src/port.c | 0 Program/src/protocol_handler.c | 0 Program/src/requests.c | 0 Program/src/tasks.c | 0 Program/test/filesystem_tests.c | 0 .../pending_req_id:1:num:1.binary | Bin Program/test/list_tests.c | 0 Program/test/main.c | 0 Program/test/makefile | 0 Program/test/mib/peer_1.json | 0 Program/test/mib/peer_2.json | 0 Program/test/mib/peer_3.json | 0 Program/test/mib/peer_4.json | 0 Program/test/mib/peer_5.json | 0 Program/test/mib/peer_6.json | 0 Program/test/mib/peer_7.json | 0 Program/test/mib/peer_8.json | 0 Program/test/mock.c | 0 Program/test/packet_tests.c | 0 Program/test/protocol_handler_tests.c | 0 Program/test/request_tests.c | 0 Program/test/server_tests.c | 0 Program/test/tasks_tests.c | 0 Program/test/temp/pending_req_id:1:num:1.binary | Bin Program/test/temp/test_file_save | Bin Program/test/test.c | 0 Program/test/test.h | 0 Program/test/test_files/empty.txt | 0 Program/test/test_files/testfile | 0 Program/test/udpClient.c | 0 Program/test/unit_tests.h | 0 Program/test/utils.c | 0 README.md | 0 65 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Documents/SpaceProjects.odt mode change 100644 => 100755 Documents/mib.txt mode change 100644 => 100755 Program/include/changeNotes mode change 100644 => 100755 Program/include/file_delivery_app.h mode change 100644 => 100755 Program/include/filesystem_funcs.h mode change 100644 => 100755 Program/include/generic_server_provider.h mode change 100644 => 100755 Program/include/jsmn.h mode change 100644 => 100755 Program/include/list.h mode change 100644 => 100755 Program/include/mib.h mode change 100644 => 100755 Program/include/packet.h mode change 100644 => 100755 Program/include/port.h mode change 100644 => 100755 Program/include/posix_server_provider.h mode change 100644 => 100755 Program/include/protocol_handler.h mode change 100644 => 100755 Program/include/requests.h mode change 100644 => 100755 Program/include/tasks.h mode change 100644 => 100755 Program/include/types.h mode change 100644 => 100755 Program/src/file_delivery_app.c mode change 100644 => 100755 Program/src/filesystem_funcs.c mode change 100644 => 100755 Program/src/generic_server_provider.c mode change 100644 => 100755 Program/src/list.c mode change 100644 => 100755 Program/src/main.c mode change 100644 => 100755 Program/src/makefile mode change 100644 => 100755 Program/src/mib.c mode change 100644 => 100755 Program/src/mib/peer_1.json mode change 100644 => 100755 Program/src/mib/peer_2.json mode change 100644 => 100755 Program/src/mib/peer_3.json mode change 100644 => 100755 Program/src/mib/peer_4.json mode change 100644 => 100755 Program/src/mib/peer_5.json mode change 100644 => 100755 Program/src/mib/peer_6.json mode change 100644 => 100755 Program/src/mib/peer_7.json mode change 100644 => 100755 Program/src/mib/peer_8.json mode change 100644 => 100755 Program/src/packet.c mode change 100644 => 100755 Program/src/port.c mode change 100644 => 100755 Program/src/protocol_handler.c mode change 100644 => 100755 Program/src/requests.c mode change 100644 => 100755 Program/src/tasks.c mode change 100644 => 100755 Program/test/filesystem_tests.c mode change 100644 => 100755 Program/test/incomplete_requests/pending_req_id:1:num:1.binary mode change 100644 => 100755 Program/test/list_tests.c mode change 100644 => 100755 Program/test/main.c mode change 100644 => 100755 Program/test/makefile mode change 100644 => 100755 Program/test/mib/peer_1.json mode change 100644 => 100755 Program/test/mib/peer_2.json mode change 100644 => 100755 Program/test/mib/peer_3.json mode change 100644 => 100755 Program/test/mib/peer_4.json mode change 100644 => 100755 Program/test/mib/peer_5.json mode change 100644 => 100755 Program/test/mib/peer_6.json mode change 100644 => 100755 Program/test/mib/peer_7.json mode change 100644 => 100755 Program/test/mib/peer_8.json mode change 100644 => 100755 Program/test/mock.c mode change 100644 => 100755 Program/test/packet_tests.c mode change 100644 => 100755 Program/test/protocol_handler_tests.c mode change 100644 => 100755 Program/test/request_tests.c mode change 100644 => 100755 Program/test/server_tests.c mode change 100644 => 100755 Program/test/tasks_tests.c mode change 100644 => 100755 Program/test/temp/pending_req_id:1:num:1.binary mode change 100644 => 100755 Program/test/temp/test_file_save mode change 100644 => 100755 Program/test/test.c mode change 100644 => 100755 Program/test/test.h mode change 100644 => 100755 Program/test/test_files/empty.txt mode change 100644 => 100755 Program/test/test_files/testfile mode change 100644 => 100755 Program/test/udpClient.c mode change 100644 => 100755 Program/test/unit_tests.h mode change 100644 => 100755 Program/test/utils.c mode change 100644 => 100755 README.md diff --git a/Documents/SpaceProjects.odt b/Documents/SpaceProjects.odt old mode 100644 new mode 100755 diff --git a/Documents/mib.txt b/Documents/mib.txt old mode 100644 new mode 100755 diff --git a/Program/include/changeNotes b/Program/include/changeNotes old mode 100644 new mode 100755 diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h old mode 100644 new mode 100755 diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h old mode 100644 new mode 100755 diff --git a/Program/include/generic_server_provider.h b/Program/include/generic_server_provider.h old mode 100644 new mode 100755 diff --git a/Program/include/jsmn.h b/Program/include/jsmn.h old mode 100644 new mode 100755 diff --git a/Program/include/list.h b/Program/include/list.h old mode 100644 new mode 100755 diff --git a/Program/include/mib.h b/Program/include/mib.h old mode 100644 new mode 100755 diff --git a/Program/include/packet.h b/Program/include/packet.h old mode 100644 new mode 100755 diff --git a/Program/include/port.h b/Program/include/port.h old mode 100644 new mode 100755 diff --git a/Program/include/posix_server_provider.h b/Program/include/posix_server_provider.h old mode 100644 new mode 100755 diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h old mode 100644 new mode 100755 diff --git a/Program/include/requests.h b/Program/include/requests.h old mode 100644 new mode 100755 diff --git a/Program/include/tasks.h b/Program/include/tasks.h old mode 100644 new mode 100755 diff --git a/Program/include/types.h b/Program/include/types.h old mode 100644 new mode 100755 diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c old mode 100644 new mode 100755 diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c old mode 100644 new mode 100755 diff --git a/Program/src/generic_server_provider.c b/Program/src/generic_server_provider.c old mode 100644 new mode 100755 diff --git a/Program/src/list.c b/Program/src/list.c old mode 100644 new mode 100755 diff --git a/Program/src/main.c b/Program/src/main.c old mode 100644 new mode 100755 diff --git a/Program/src/makefile b/Program/src/makefile old mode 100644 new mode 100755 diff --git a/Program/src/mib.c b/Program/src/mib.c old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_1.json b/Program/src/mib/peer_1.json old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_2.json b/Program/src/mib/peer_2.json old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_3.json b/Program/src/mib/peer_3.json old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_4.json b/Program/src/mib/peer_4.json old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_5.json b/Program/src/mib/peer_5.json old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_6.json b/Program/src/mib/peer_6.json old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_7.json b/Program/src/mib/peer_7.json old mode 100644 new mode 100755 diff --git a/Program/src/mib/peer_8.json b/Program/src/mib/peer_8.json old mode 100644 new mode 100755 diff --git a/Program/src/packet.c b/Program/src/packet.c old mode 100644 new mode 100755 diff --git a/Program/src/port.c b/Program/src/port.c old mode 100644 new mode 100755 diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c old mode 100644 new mode 100755 diff --git a/Program/src/requests.c b/Program/src/requests.c old mode 100644 new mode 100755 diff --git a/Program/src/tasks.c b/Program/src/tasks.c old mode 100644 new mode 100755 diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c old mode 100644 new mode 100755 diff --git a/Program/test/incomplete_requests/pending_req_id:1:num:1.binary b/Program/test/incomplete_requests/pending_req_id:1:num:1.binary old mode 100644 new mode 100755 diff --git a/Program/test/list_tests.c b/Program/test/list_tests.c old mode 100644 new mode 100755 diff --git a/Program/test/main.c b/Program/test/main.c old mode 100644 new mode 100755 diff --git a/Program/test/makefile b/Program/test/makefile old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_1.json b/Program/test/mib/peer_1.json old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_2.json b/Program/test/mib/peer_2.json old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_3.json b/Program/test/mib/peer_3.json old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_4.json b/Program/test/mib/peer_4.json old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_5.json b/Program/test/mib/peer_5.json old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_6.json b/Program/test/mib/peer_6.json old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_7.json b/Program/test/mib/peer_7.json old mode 100644 new mode 100755 diff --git a/Program/test/mib/peer_8.json b/Program/test/mib/peer_8.json old mode 100644 new mode 100755 diff --git a/Program/test/mock.c b/Program/test/mock.c old mode 100644 new mode 100755 diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c old mode 100644 new mode 100755 diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c old mode 100644 new mode 100755 diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c old mode 100644 new mode 100755 diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c old mode 100644 new mode 100755 diff --git a/Program/test/tasks_tests.c b/Program/test/tasks_tests.c old mode 100644 new mode 100755 diff --git a/Program/test/temp/pending_req_id:1:num:1.binary b/Program/test/temp/pending_req_id:1:num:1.binary old mode 100644 new mode 100755 diff --git a/Program/test/temp/test_file_save b/Program/test/temp/test_file_save old mode 100644 new mode 100755 diff --git a/Program/test/test.c b/Program/test/test.c old mode 100644 new mode 100755 diff --git a/Program/test/test.h b/Program/test/test.h old mode 100644 new mode 100755 diff --git a/Program/test/test_files/empty.txt b/Program/test/test_files/empty.txt old mode 100644 new mode 100755 diff --git a/Program/test/test_files/testfile b/Program/test/test_files/testfile old mode 100644 new mode 100755 diff --git a/Program/test/udpClient.c b/Program/test/udpClient.c old mode 100644 new mode 100755 diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h old mode 100644 new mode 100755 diff --git a/Program/test/utils.c b/Program/test/utils.c old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 From 3eca3c7bbffdfff405df81115135c320ae84f39c Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 16 Jan 2021 15:20:55 -0700 Subject: [PATCH 268/400] missing curly braces, add port to before header guard --- Program/src/port.c | 2 +- Program/src/posix_server_provider.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index e5d92d6..4361cd0 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -338,7 +338,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void return NULL; pthread_attr_t *attr = ssp_alloc(1, sizeof(pthread_attr_t)); - if (attr == NULL) + if (attr == NULL) { ssp_free(handler); return NULL; } diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index a6da953..8a44001 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -1,3 +1,4 @@ +#include "port.h" #ifdef POSIX_PORT /*------------------------------------------------------------------------------ @@ -12,7 +13,7 @@ Author: Evan Giese #include #include #include "posix_server_provider.h" -#include "port.h" + #include static int ssp_recvfrom(int sfd, void *buff, size_t packet_len, int flags, void *server_addr, uint32_t *server_addr_len) { From 9fb9e795d98de1eb0c43e291180b80a39958ec5b Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 16 Jan 2021 19:13:07 -0700 Subject: [PATCH 269/400] add default peer file for sat --- Program/src/file_delivery_app.c | 46 ++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 4ba3778..78d1a9a 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -73,9 +73,53 @@ static int create_ssp_client_drivers(Client *client) { FTP *init_ftp(uint32_t my_cfdp_address) { + int error = ssp_mkdir("incomplete_requests"); + if (error < 0) { + ssp_error("couldn't make directory incomplete_requests \n"); + return NULL; + } + error = ssp_mkdir("mib"); + if (error < 0) { + ssp_error("couldn't make directory mib\n"); + return NULL; + } + + int fd = ssp_open("mib/peer_0.json", SSP_O_CREAT | SSP_O_RDWR); + if (fd < 0) { + ssp_error("couldn't create default peer_0.json file\n"); + return NULL; + } + + const char *peer_file = "{\n\ + \"cfdp_id\": 7,\n\ + \"UT_address\" : 0,\n\ + \"UT_port\" : 1,\n\ + \"type_of_network\" : 3,\n\ + \"default_transmission_mode\" : 1,\n\ + \"MTU\" : 250,\n\ + \"one_way_light_time\" : 123,\n\ + \"total_round_trip_allowance\" : 123,\n\ + \"async_NAK_interval\" : 123,\n\ + \"async_keep_alive_interval\" : 123,\n\ + \"async_report_interval\" : 123,\n\ + \"immediate_nak_mode_enabled\" : 123,\n\ + \"prompt_transmission_interval\" : 123,\n\ + \"disposition_of_incomplete\" : 123,\n\ + \"CRC_required\" : 0,\n\ + \"keep_alive_discrepancy_limit\" : 8,\n\ + \"positive_ack_timer_expiration_limit\" : 123,\n\ + \"nak_timer_expiration_limit\" : 123,\n\ + \"transaction_inactivity_limit\" : 123\n\ +}"; + + error = ssp_write(fd, peer_file, strnlen(peer_file, 1000)); + if (error < 0) { + ssp_error("couldn't write default file\n"); + } + Remote_entity remote_entity; - int error = get_remote_entity_from_json(&remote_entity, my_cfdp_address); + error = get_remote_entity_from_json(&remote_entity, my_cfdp_address); if (error == -1) { ssp_error("can't get configuration data, can't start server.\n"); return NULL; From c2f5ce1e45dce54e98abffedb9e3c0fd14e6c2da Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 16 Jan 2021 19:28:09 -0700 Subject: [PATCH 270/400] add remove dir port --- Program/src/port.c | 12 ++++++++++++ Program/src/requests.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Program/src/port.c b/Program/src/port.c index 4361cd0..3d98d3f 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -143,6 +143,18 @@ void *ssp_opendir(char *dir_name) { #endif } +int ssp_closedir(char *dir_name) { + + #ifdef POSIX_FILESYSTEM + int error = closedir(dir_name); + if(error < 0){ + ssp_error("Unable to close directory"); + return NULL; + } + return error; + #endif +} + int ssp_readdir(void *dir, char *file){ #ifdef POSIX_FILESYSTEM struct dirent *file_read; diff --git a/Program/src/requests.c b/Program/src/requests.c index 4f22ac3..6ca8548 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -530,7 +530,7 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ } } - closedir(dir); + ssp_closedir(dir); return 0; } From 1fed18de8e0f45c9303e9191e021f64a71431712 Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 19 Jan 2021 17:19:42 -0700 Subject: [PATCH 271/400] Remove portable wrapping functions in favor of macro definitions --- Program/include/port.h | 42 +++++++++++++++++---------- Program/src/port.c | 64 ------------------------------------------ 2 files changed, 27 insertions(+), 79 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index d2f6720..cb8d430 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,13 +9,13 @@ Author: Evan Giese #define STACK_ALLOCATION 16384 -#define FREE_RTOS_PORT -//#define POSIX_PORT +//#define FREE_RTOS_PORT +#define POSIX_PORT -#define RED_FS -//#define POSIX_FILESYSTEM +//#define RED_FS +#define POSIX_FILESYSTEM -//#define CSP_NETWORK +#define CSP_NETWORK //comment this out if you want to sendto function to actually work @@ -38,13 +38,25 @@ Author: Evan Giese #include #include #include - + #include + #define SSP_O_RDWR O_RDWR #define SSP_O_CREAT O_CREAT #define SSP_O_TRUNC O_TRUNC #define SSP_SEEK_SET SEEK_SET + #define ssp_open open + #define ssp_rename rename + #define ssp_close close + #define ssp_read read + #define ssp_write write + #define ssp_closedir closedir + #define ssp_lseek lseek + #define ssp_remove remove + #endif + + #ifdef POSIX_PORT #include #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN @@ -92,6 +104,15 @@ Author: Evan Giese #define SSP_O_CREAT RED_O_CREAT #define SSP_O_TRUNC RED_O_TRUNC #define SSP_SEEK_SET RED_SEEK_SET + #define ssp_open red_open + #define ssp_rename red_rename + #define ssp_close red_close + #define ssp_read red_read + #define ssp_write red_write + #define ssp_closedir red_closedir + #define ssp_lseek red_lseek + #define ssp_remove red_remove + #endif @@ -101,20 +122,11 @@ void ssp_error(char *msg); void ssp_printf(char *stuff, ...); void *ssp_alloc(uint32_t u_memb, size_t size); void ssp_sendto(Response res); - void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void *params); int ssp_time_count(void); - -int ssp_open(char *pathname, int flags); -int ssp_read(int fd, char* buff, size_t size); -int ssp_lseek(int fd, int offset, int whence); void ssp_error(char *error); -int ssp_write(int fd, const void *buf, size_t count); -int ssp_close(int fd); void ssp_free(void *pointer); void ssp_thread_join(void *thread_handle); -int ssp_remove(char *pathname); -int ssp_rename(const char *old, const char *new); int ssp_mkdir(char *dir_name); void *ssp_opendir(char *dir_name); int ssp_readdir(void *dir, char *file); diff --git a/Program/src/port.c b/Program/src/port.c index 3d98d3f..da7b539 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -50,58 +50,6 @@ static int exit_now = 0; File system port functions, these are used to interchange different File systems, will add RELIANCE_EDGE here in the future ------------------------------------------------------------------------------*/ -int ssp_rename(const char *old, const char *new) { - #ifdef POSIX_FILESYSTEM - return rename(old, new); - #endif - return -1; -} - -int ssp_write(int fd, const void *buf, size_t count) { - #ifdef POSIX_FILESYSTEM - return write(fd, buf, count); - #endif - return -1; -} - - -int ssp_read(int fd, char* buff, size_t size) { - #ifdef POSIX_FILESYSTEM - return read(fd, buff, size); - #endif - return -1; - -} - -//SEEK_END 2 SEEK_CUR 1 SEEK_SET 0 -int ssp_lseek(int fd, int offset, int whence) { - #ifdef POSIX_FILESYSTEM - return lseek(fd, offset, whence); - #endif - return -1; -} - -int ssp_open(char *pathname, int flags) { - #ifdef POSIX_FILESYSTEM - //open with read and write permissions - return open(pathname, flags, 0666); - #endif - return -1; -} - -int ssp_close(int fd) { - #ifdef POSIX_FILESYSTEM - return close(fd); - #endif - return -1; -} - -int ssp_remove(char *pathname){ - #ifdef POSIX_FILESYSTEM - return remove(pathname); - #endif - return -1; -} int get_exit() { return exit_now; @@ -143,18 +91,6 @@ void *ssp_opendir(char *dir_name) { #endif } -int ssp_closedir(char *dir_name) { - - #ifdef POSIX_FILESYSTEM - int error = closedir(dir_name); - if(error < 0){ - ssp_error("Unable to close directory"); - return NULL; - } - return error; - #endif -} - int ssp_readdir(void *dir, char *file){ #ifdef POSIX_FILESYSTEM struct dirent *file_read; From b65c505f66f26597ca68b293b9b1c5e49d66de5d Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 19 Jan 2021 17:20:53 -0700 Subject: [PATCH 272/400] change some syntax (remove multiple definitions) --- Program/src/filesystem_funcs.c | 2 +- Program/src/posix_server_provider.c | 6 +++--- Program/src/requests.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 6faabc4..cc4ca88 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -149,7 +149,7 @@ uint32_t calc_check_sum(char *data, uint32_t length) { memset(last_chunk, 0, 4); end = length - remaining_bytes; - unsigned int i = 0; + i = 0; for (i = 0; i < remaining_bytes; i++) { last_chunk[i] = data[end + i]; } diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index 8a44001..f721dce 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -167,10 +167,10 @@ int prepareSignalHandler() if (sigaction(SIGINT, &actionData, NULL) == -1) { ssp_error("sigaction sigint failed\n"); - exit(EXIT_FAILURE); + return -1; } - int exit_now = get_exit(); - return &exit_now; + return 1; + } static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buff_size) { diff --git a/Program/src/requests.c b/Program/src/requests.c index 6ca8548..8c85f25 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -11,8 +11,8 @@ Author: Evan Giese aka: request from person ------------------------------------------------------------------------------*/ -#include "requests.h" #include "port.h" +#include "requests.h" #include "utils.h" #include "types.h" #include "filesystem_funcs.h" From 199c57c123fd83e09baca25194da5d5e54c3a2c3 Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 19 Jan 2021 17:59:09 -0700 Subject: [PATCH 273/400] Add necessary RED_FS function wrappers --- Program/include/port.h | 36 ++++++++++++++-------------- Program/src/port.c | 53 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index cb8d430..224022a 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -55,7 +55,24 @@ Author: Evan Giese #endif +#ifdef RED_FS + + #include + #define SSP_O_RDWR RED_O_RDWR + #define SSP_O_CREAT RED_O_CREAT + #define SSP_O_TRUNC RED_O_TRUNC + #define SSP_SEEK_SET RED_SEEK_SET + #define ssp_open red_open + #define ssp_rename red_rename + #define ssp_close red_close + #define ssp_read red_read + #define ssp_write red_write + #define ssp_closedir red_closedir + #define ssp_lseek red_lseek + #define ssp_remove red_remove + +#endif #ifdef POSIX_PORT #include @@ -97,25 +114,6 @@ Author: Evan Giese #define ssp_atol atol #endif -#ifdef RED_FS - - #include - #define SSP_O_RDWR RED_O_RDWR - #define SSP_O_CREAT RED_O_CREAT - #define SSP_O_TRUNC RED_O_TRUNC - #define SSP_SEEK_SET RED_SEEK_SET - #define ssp_open red_open - #define ssp_rename red_rename - #define ssp_close red_close - #define ssp_read red_read - #define ssp_write red_write - #define ssp_closedir red_closedir - #define ssp_lseek red_lseek - #define ssp_remove red_remove - - -#endif - //don't change these in the header file here, if you need to change them //change them in the .c file void ssp_error(char *msg); diff --git a/Program/src/port.c b/Program/src/port.c index da7b539..5370d73 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -26,6 +26,10 @@ static int exit_now = 0; #include #endif +#ifdef RED_FS + #include +#endif + #ifdef FREE_RTOS_PORT #include "FreeRTOS.h" #include "task.h" @@ -71,11 +75,30 @@ int ssp_mkdir(char *dir_name) { return -1; } else { + ssp_printf("%s directory already exists\n", dirname); return 1; } return -1; #endif + #ifdef RED_FS + + int error = red_mkdir(dir_name); + if (error < 0) { + if(red_errno == RED_EEXIST) { + return 1; + } + ssp_printf("couldn't make dir\n"); + return -1; + } + else { + ssp_printf("%s directory already exists\n", dirname); + return 1; + } + return -1; + #endif + return -1; + } void *ssp_opendir(char *dir_name) { @@ -89,6 +112,18 @@ void *ssp_opendir(char *dir_name) { } return dir; #endif + #ifdef RED_FS + + REDDIR *dir: + dir = red_opendir(dir_name); + if(dir == NULL){ + ssp_error("Unable to open directory"); + return NULL; + } + return dir; + + #endif + return NULL; } int ssp_readdir(void *dir, char *file){ @@ -103,7 +138,23 @@ int ssp_readdir(void *dir, char *file){ ssp_memcpy(file, file_read->d_name, MAX_PATH); return 1; - #endif + #endif + #ifdef RED_FS + + REDDIRENT *file_read; + REDDIR *d = (REDDIR*)dir; + + file_read=red_readdir(d); + if (file_read == NULL) { + return 0; + } + ssp_memcpy(file, file_read->d_name, MAX_PATH); + + return 1; + #endif + + return -1; + } /*------------------------------------------------------------------------------ From 62ccc5d47061183476482e944d27b96f790dc51b Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 19 Jan 2021 19:14:28 -0700 Subject: [PATCH 274/400] fix dirname --- Program/include/port.h | 2 +- Program/src/port.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 224022a..b71fb2f 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -24,7 +24,7 @@ Author: Evan Giese #include "types.h" #ifdef CSP_NETWORK - #include "csp.h" + #include "csp/csp.h" typedef struct csp_packet_wrapper { uint8_t dest_id; uint8_t dest_port; diff --git a/Program/src/port.c b/Program/src/port.c index 5370d73..81c290a 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -46,7 +46,7 @@ static int exit_now = 0; #endif #ifdef CSP_NETWORK - #include "csp.h" + #include "csp/csp.h" #endif @@ -75,7 +75,7 @@ int ssp_mkdir(char *dir_name) { return -1; } else { - ssp_printf("%s directory already exists\n", dirname); + ssp_printf("%s directory already exists\n", dir_name); return 1; } return -1; @@ -92,7 +92,7 @@ int ssp_mkdir(char *dir_name) { return -1; } else { - ssp_printf("%s directory already exists\n", dirname); + ssp_printf("%s directory already exists\n", dir_name); return 1; } return -1; From bf43ca86745d51d501cb53b7fd6a81fbbd949789 Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 19 Jan 2021 19:59:55 -0700 Subject: [PATCH 275/400] Compiles --- Program/include/list.h | 3 +-- Program/include/packet.h | 3 +-- Program/include/port.h | 30 ++++++++++++++++-------------- Program/include/requests.h | 3 +-- Program/src/file_delivery_app.c | 1 + Program/src/packet.c | 8 ++++---- Program/src/port.c | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Program/include/list.h b/Program/include/list.h index 0006dd8..f6e6458 100755 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -52,5 +52,4 @@ Node *createNode(void *element, uint32_t id); Return: returns a pointer to an initilized LIST * ------------------------------------------------------------------------------*/ List *linked_list(void); - -#endif \ No newline at end of file +#endif diff --git a/Program/include/packet.h b/Program/include/packet.h index 7200537..0380a50 100755 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -31,5 +31,4 @@ uint16_t get_data_length(char*packet); uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req); uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req); uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_user); - -#endif \ No newline at end of file +#endif diff --git a/Program/include/port.h b/Program/include/port.h index b71fb2f..7111638 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,11 +9,11 @@ Author: Evan Giese #define STACK_ALLOCATION 16384 -//#define FREE_RTOS_PORT -#define POSIX_PORT +#define FREE_RTOS_PORT +//#define POSIX_PORT -//#define RED_FS -#define POSIX_FILESYSTEM +#define RED_FS +//#define POSIX_FILESYSTEM #define CSP_NETWORK @@ -32,6 +32,16 @@ Author: Evan Giese uint8_t src_port; csp_packet_t *packet; } csp_packet_wrapper; + + #include + #define SSP_INET_ADDRSTRLEN 16 + #define SSP_AF_INET 2 + #define ssp_htonl csp_hton32 + #define ssp_ntohl csp_ntoh32 + #define ssp_htons csp_ntoh16 + #define ssp_stonl csp_hton16 + #define ssp_inet_ntop inet_ntop + #endif #ifdef POSIX_FILESYSTEM @@ -69,7 +79,7 @@ Author: Evan Giese #define ssp_write red_write #define ssp_closedir red_closedir #define ssp_lseek red_lseek - #define ssp_remove red_remove + #define ssp_remove red_unlink #endif @@ -94,15 +104,7 @@ Author: Evan Giese #define ssp_atol atol #endif -#ifdef FREE_RTOS_PORT - #include - #define SSP_INET_ADDRSTRLEN 16 - #define SSP_AF_INET 2 - #define ssp_htonl htonl - #define ssp_ntohl ntohl - #define ssp_htons htons - #define ssp_stonl stonl - #define ssp_inet_ntop inet_ntop +#ifdef FREE_RTOS_PORT #include #define ssp_memcpy memcpy diff --git a/Program/include/requests.h b/Program/include/requests.h index 6153285..5c357b7 100755 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -62,5 +62,4 @@ int put_request_no_client( void add_request_to_client(Request *req, Client *client); Client *start_client(FTP *app, uint8_t dest_id); - -#endif \ No newline at end of file +#endif diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 78d1a9a..1d57896 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -78,6 +78,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { ssp_error("couldn't make directory incomplete_requests \n"); return NULL; } + error = ssp_mkdir("mib"); if (error < 0) { ssp_error("couldn't make directory mib\n"); diff --git a/Program/src/packet.c b/Program/src/packet.c index 6a30eb6..6f9744e 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -280,8 +280,8 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { uint32_t start_scope = ((Offset *)req->file->missing_offsets->head->next->element)->start; uint32_t end_scope = ((Offset *)req->file->missing_offsets->tail->prev->element)->end; - pdu_nak->start_scope = htonl(start_scope); - pdu_nak->end_scope = htonl(end_scope); + pdu_nak->start_scope = ssp_htonl(start_scope); + pdu_nak->end_scope = ssp_htonl(end_scope); pdu_nak->segment_requests = htonll(holder.current_number_of_segments); packet_index += sizeof(Offset) * holder.current_number_of_segments; @@ -317,7 +317,7 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { void set_data_length(char*packet, uint16_t data_len){ Pdu_header *header = (Pdu_header*) packet; - header->PDU_data_field_len = htons(data_len);; + header->PDU_data_field_len = ssp_htons(data_len);; } uint16_t get_data_length(char*packet) { @@ -451,4 +451,4 @@ uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_le packet_index = get_message_from_packet(packet, packet_index, req); } return packet_index; -} \ No newline at end of file +} diff --git a/Program/src/port.c b/Program/src/port.c index 81c290a..ee57d8b 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -114,7 +114,7 @@ void *ssp_opendir(char *dir_name) { #endif #ifdef RED_FS - REDDIR *dir: + REDDIR *dir; dir = red_opendir(dir_name); if(dir == NULL){ ssp_error("Unable to open directory"); From 04e90bcf2331c0b34ab476ad542b0217c567dd6c Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 29 Jan 2021 17:58:01 -0700 Subject: [PATCH 276/400] Change priority of task to actually run --- Program/src/port.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index ee57d8b..7b7531f 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -288,9 +288,9 @@ void ssp_error(char *error){ void ssp_printf(char *stuff, ...) { va_list args; va_start(args, stuff); - vfprintf(stdout, stuff, args); + //vfprintf(stdout, stuff, args); va_end (args); - fflush(stdout); + //fflush(stdout); } //returns seconds elapsed, need FREE RTOS realtime clock lib to properly port @@ -316,20 +316,21 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void TaskHandle_t *xHandle = ssp_alloc(1, sizeof(TaskHandle_t)); BaseType_t xReturned; - /* Create the task, storing the handle. */ + // Create the task, storing the handle. xReturned = xTaskCreate( - thread_func, /* Function that implements the task. */ - "FTP", /* Text name for the task. */ - stack_size, /* Stack size in words, not bytes. */ - params, /* Parameter passed into the task. */ - tskIDLE_PRIORITY,/* Priority at which the task is created. */ - xHandle ); /* Used to pass out the created task's handle. */ + thread_func, // Function that implements the task. + "FTP", // Text name for the task. + stack_size, // Stack size in words, not bytes. + params, // Parameter passed into the task. + 1,// Priority at which the task is created. + xHandle ); // Used to pass out the created task's handle. + if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) { ssp_error("Not enough memory to start task\n"); return NULL; } - return xHandle; + return xReturned; #else //pthreads pthread_t *handler = ssp_alloc(1, sizeof(pthread_t)); From 30269eab36353965601836e475401a6032d83647 Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 29 Jan 2021 18:02:36 -0700 Subject: [PATCH 277/400] Add temperary task functions --- Program/include/file_delivery_app.h | 4 ++- Program/src/file_delivery_app.c | 53 +++++++++++++++++++---------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 9fb55e8..eeacbd3 100755 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -11,5 +11,7 @@ Author: Evan Giese FTP *init_ftp(uint32_t my_cfdp_address); Client *ssp_client(uint32_t cfdp_id, FTP *app); void create_ssp_server(FTP *app); +int create_ssp_server_drivers(FTP *app); +int create_ftp_task(); -#endif \ No newline at end of file +#endif diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 1d57896..664cc5f 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -9,30 +9,32 @@ Author: Evan Giese #include "file_delivery_app.h" #include "tasks.h" -static int create_ssp_server_drivers(FTP *app) { +int create_ssp_server_drivers(FTP *app) { + + void *error = NULL; switch (app->remote_entity.type_of_network) { case posix_connectionless: - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, app); + error = ssp_connectionless_server_task(app); break; case posix_connection: - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connection_server_task, app); + error = ssp_connection_server_task(app); break; case csp_connectionless: - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connectionless_server_task, app); + error = ssp_csp_connectionless_server_task(app); break; case csp_connection: - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_csp_connection_server_task, app); + error = ssp_csp_connection_server_task(app); break; case generic: - app->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_generic_server_task, app); + error = ssp_generic_server_task(app); break; default: ssp_printf("server couldn't start, 'type of network' not recognized\n"); break; } - if (app->server_handle == NULL) { + if (error = NULL) { return -1; } return 0; @@ -72,29 +74,31 @@ static int create_ssp_client_drivers(Client *client) { FTP *init_ftp(uint32_t my_cfdp_address) { + int error = 0; - int error = ssp_mkdir("incomplete_requests"); + error = ssp_mkdir("incomplete_requests"); if (error < 0) { - ssp_error("couldn't make directory incomplete_requests \n"); - return NULL; + ssp_error("couldn't make directory incomplete_requests it either already exists or there is an issue\n"); } error = ssp_mkdir("mib"); if (error < 0) { - ssp_error("couldn't make directory mib\n"); - return NULL; + ssp_error("couldn't make directory mib it either already exists or there is an issue\n"); } - int fd = ssp_open("mib/peer_0.json", SSP_O_CREAT | SSP_O_RDWR); + int fd = ssp_open("mib/peer_0.json", SSP_O_CREAT | RED_O_RDWR); if (fd < 0) { - ssp_error("couldn't create default peer_0.json file\n"); - return NULL; + if (fd == SSP_EEXIST) { + ssp_error("file exists\n"); + } + else + ssp_error("couldn't create default peer_0.json it either already exists or there is an issue\n"); } const char *peer_file = "{\n\ \"cfdp_id\": 7,\n\ \"UT_address\" : 0,\n\ - \"UT_port\" : 1,\n\ + \"UT_port\" : 20,\n\ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 250,\n\ @@ -118,11 +122,10 @@ FTP *init_ftp(uint32_t my_cfdp_address) { ssp_error("couldn't write default file\n"); } - Remote_entity remote_entity; error = get_remote_entity_from_json(&remote_entity, my_cfdp_address); if (error == -1) { - ssp_error("can't get configuration data, can't start server.\n"); + ssp_error("can't get configuration data, can't start server failed to start ftp.\n"); return NULL; } @@ -157,11 +160,25 @@ FTP *init_ftp(uint32_t my_cfdp_address) { } app->current_request = NULL; + create_ssp_server_drivers(app); + return app; } +static void init_ftp_task(void *arg){ + FTP *app = init_ftp(0); +} + +int create_ftp_task(){ + + if (xTaskCreate((TaskFunction_t)init_ftp_task, "FTP_CSP_SERVER", STACK_ALLOCATION, NULL, + 1, NULL) != pdPASS) { + return -1; + } + return 0; +} Client *ssp_client(uint32_t cfdp_id, FTP *app) { From e18b073d9730eb7e6da62c57dcaacb29144646bc Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 29 Jan 2021 18:03:56 -0700 Subject: [PATCH 278/400] add reliance edge function headers and some port stuff --- Program/include/port.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Program/include/port.h b/Program/include/port.h index 7111638..3caae6c 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -7,7 +7,7 @@ Author: Evan Giese #ifndef PORT_H #define PORT_H -#define STACK_ALLOCATION 16384 +#define STACK_ALLOCATION 5000 #define FREE_RTOS_PORT //#define POSIX_PORT @@ -54,6 +54,7 @@ Author: Evan Giese #define SSP_O_CREAT O_CREAT #define SSP_O_TRUNC O_TRUNC #define SSP_SEEK_SET SEEK_SET + #define SSP_EEXIST EEXIST #define ssp_open open #define ssp_rename rename #define ssp_close close @@ -63,14 +64,21 @@ Author: Evan Giese #define ssp_lseek lseek #define ssp_remove remove + #endif #ifdef RED_FS + #include + #include + #include + #include + #include #include #define SSP_O_RDWR RED_O_RDWR #define SSP_O_CREAT RED_O_CREAT #define SSP_O_TRUNC RED_O_TRUNC + #define SSP_EEXIST RED_EEXIST #define SSP_SEEK_SET RED_SEEK_SET #define ssp_open red_open #define ssp_rename red_rename From 90656c237403e403d8991333dab1fd971891a711 Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 29 Jan 2021 18:04:08 -0700 Subject: [PATCH 279/400] Change read_json to use alloc --- Program/src/filesystem_funcs.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index cc4ca88..022d44d 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -13,7 +13,7 @@ Author: Evan Giese uint32_t get_file_size(char *source_file_name) { - int fd = ssp_open(source_file_name, 0); + int fd = ssp_open(source_file_name, SSP_O_RDWR); if (fd == -1){ ssp_error("could not open file\n"); return 0; @@ -296,19 +296,19 @@ int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params) { - jsmn_parser p; int number_of_tokens = 255; - jsmntok_t tok[number_of_tokens]; - + jsmn_parser p; jsmn_init(&p); + jsmntok_t *tok = ssp_alloc(number_of_tokens, sizeof(jsmntok_t)); + uint32_t total_size = get_file_size(file_name); if (total_size == 0){ ssp_error("couldn't get file size\n"); return -1; } - char buff[total_size]; + char *buff = ssp_alloc(total_size, sizeof(char)); int fd = ssp_open(file_name, SSP_O_RDWR); if (fd < 0) { @@ -316,7 +316,7 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa return -1; } - int r = ssp_read(fd, buff, sizeof(buff)); + int r = ssp_read(fd, buff, total_size); if (r < 0) { ssp_error("read failed\n"); return -1; @@ -333,18 +333,24 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa int key_size = tok[i].end - tok[i].start; int value_size = tok[i+1].end - tok[i+1].start; - char key[key_size + 1]; + //char key[key_size + 1]; + char *key = ssp_alloc(key_size + 1, sizeof(char)); key[key_size] = '\0'; strncpy(key, &buff[tok[i].start], key_size); - char value[value_size + 1]; + char *value = ssp_alloc(value_size + 1, sizeof(char)); value[value_size] = '\0'; strncpy(value, &buff[tok[i+1].start], value_size); callback(key, value, params); + ssp_free(key); + ssp_free(value); i++; } + ssp_free(buff); + ssp_free(tok); + return 0; } From 01a2f8c7263e5b50c1d6213f6ea1a4a68000062f Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 30 Jan 2021 18:09:37 -0700 Subject: [PATCH 280/400] Moving all allocations inside of a thread/task context. For Ti compiler --- Program/include/file_delivery_app.h | 4 +- Program/include/port.h | 19 +++-- Program/src/file_delivery_app.c | 73 ++++++++-------- Program/src/filesystem_funcs.c | 24 +++++- Program/src/main.c | 126 ++++++++++++++++++++++------ Program/src/mib.c | 1 + Program/src/port.c | 9 +- Program/src/tasks.c | 1 - 8 files changed, 176 insertions(+), 81 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index eeacbd3..21f14a0 100755 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -8,10 +8,10 @@ Author: Evan Giese #define FTP_APP_H #include "types.h" -FTP *init_ftp(uint32_t my_cfdp_address); +int init_ftp(uint32_t my_cfdp_address, FTP *app); Client *ssp_client(uint32_t cfdp_id, FTP *app); void create_ssp_server(FTP *app); int create_ssp_server_drivers(FTP *app); -int create_ftp_task(); +void *create_ftp_task(uint32_t cfdp_id, FTP *app); #endif diff --git a/Program/include/port.h b/Program/include/port.h index 3caae6c..6e7c384 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -7,15 +7,14 @@ Author: Evan Giese #ifndef PORT_H #define PORT_H -#define STACK_ALLOCATION 5000 -#define FREE_RTOS_PORT -//#define POSIX_PORT +//#define FREE_RTOS_PORT +//#define RED_FS -#define RED_FS -//#define POSIX_FILESYSTEM +//#define CSP_NETWORK +#define POSIX_FILESYSTEM +#define POSIX_PORT -#define CSP_NETWORK //comment this out if you want to sendto function to actually work @@ -49,6 +48,7 @@ Author: Evan Giese #include #include #include + #include #define SSP_O_RDWR O_RDWR #define SSP_O_CREAT O_CREAT @@ -94,14 +94,19 @@ Author: Evan Giese #ifdef POSIX_PORT #include + #include + #include + #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN + #define STACK_ALLOCATION 20000 + #define SSP_AF_INET AF_INET #define ssp_htonl htonl #define ssp_ntohl ntohl #define ssp_htons htons #define ssp_stonl stonl #define ssp_inet_ntop inet_ntop - + #include #define ssp_memcpy memcpy diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 664cc5f..d2565ca 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -34,7 +34,7 @@ int create_ssp_server_drivers(FTP *app) { ssp_printf("server couldn't start, 'type of network' not recognized\n"); break; } - if (error = NULL) { + if (error == NULL) { return -1; } return 0; @@ -73,7 +73,7 @@ static int create_ssp_client_drivers(Client *client) { -FTP *init_ftp(uint32_t my_cfdp_address) { +int init_ftp(uint32_t my_cfdp_address, FTP *app) { int error = 0; error = ssp_mkdir("incomplete_requests"); @@ -85,16 +85,6 @@ FTP *init_ftp(uint32_t my_cfdp_address) { if (error < 0) { ssp_error("couldn't make directory mib it either already exists or there is an issue\n"); } - - int fd = ssp_open("mib/peer_0.json", SSP_O_CREAT | RED_O_RDWR); - if (fd < 0) { - if (fd == SSP_EEXIST) { - ssp_error("file exists\n"); - } - else - ssp_error("couldn't create default peer_0.json it either already exists or there is an issue\n"); - } - const char *peer_file = "{\n\ \"cfdp_id\": 7,\n\ \"UT_address\" : 0,\n\ @@ -116,28 +106,36 @@ FTP *init_ftp(uint32_t my_cfdp_address) { \"nak_timer_expiration_limit\" : 123,\n\ \"transaction_inactivity_limit\" : 123\n\ }"; - - error = ssp_write(fd, peer_file, strnlen(peer_file, 1000)); - if (error < 0) { - ssp_error("couldn't write default file\n"); + + int fd = ssp_open("mib/peer_0.json", SSP_O_CREAT | SSP_O_RDWR); + if (fd < 0) { + if (fd == SSP_EEXIST) { + ssp_error("file exists\n"); + } + else + ssp_error("couldn't create default peer_0.json it either already exists or there is an issue\n"); + } else { + error = ssp_write(fd, peer_file, strnlen(peer_file, 1000)); + if (error < 0) { + ssp_error("couldn't write default file\n"); + } } Remote_entity remote_entity; + memset(&remote_entity, 0, sizeof(Remote_entity)); + error = get_remote_entity_from_json(&remote_entity, my_cfdp_address); if (error == -1) { ssp_error("can't get configuration data, can't start server failed to start ftp.\n"); - return NULL; + return -1; } - - FTP *app = ssp_alloc(sizeof(FTP), 1); - if (app == NULL) - return NULL; app->packet_len = remote_entity.mtu; app->buff = ssp_alloc(1, app->packet_len); + if (app->buff == NULL) { ssp_free(app); - return NULL; + return -1; } app->my_cfdp_id = my_cfdp_address; @@ -148,7 +146,7 @@ FTP *init_ftp(uint32_t my_cfdp_address) { if (app->active_clients == NULL) { ssp_free(app->buff); ssp_free(app); - return NULL; + return -1; } app->request_list = linked_list(); @@ -156,28 +154,31 @@ FTP *init_ftp(uint32_t my_cfdp_address) { ssp_free(app->buff); ssp_free(app); app->active_clients->freeOnlyList(app->active_clients); - return NULL; + return -1; } app->current_request = NULL; + + return create_ssp_server_drivers(app); +} - create_ssp_server_drivers(app); - return app; -} +static void init_ftp_task(void *app){ + FTP *ap = (FTP *) app; -static void init_ftp_task(void *arg){ - FTP *app = init_ftp(0); + int error = init_ftp(ap->my_cfdp_id, app); + if (error < 0) { + //task failed to start destroy task/thread + } } +void *create_ftp_task(uint32_t cfdp_id, FTP *app){ -int create_ftp_task(){ - - if (xTaskCreate((TaskFunction_t)init_ftp_task, "FTP_CSP_SERVER", STACK_ALLOCATION, NULL, - 1, NULL) != pdPASS) { - return -1; - } - return 0; + app->my_cfdp_id = cfdp_id; + void *handler = ssp_thread_create(STACK_ALLOCATION, init_ftp_task, app); + app->server_handle = handler; + + return handler; } Client *ssp_client(uint32_t cfdp_id, FTP *app) { diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 022d44d..7370363 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -300,30 +300,38 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa jsmn_parser p; jsmn_init(&p); - jsmntok_t *tok = ssp_alloc(number_of_tokens, sizeof(jsmntok_t)); + ssp_printf("%s\n", file_name); + + jsmntok_t tok[255]; uint32_t total_size = get_file_size(file_name); + if (total_size == 0){ ssp_error("couldn't get file size\n"); return -1; } char *buff = ssp_alloc(total_size, sizeof(char)); + if (buff == NULL) + return -1; int fd = ssp_open(file_name, SSP_O_RDWR); if (fd < 0) { + ssp_free(buff); ssp_error("couldn't open file\n"); return -1; } int r = ssp_read(fd, buff, total_size); if (r < 0) { + ssp_free(buff); ssp_error("read failed\n"); return -1; } r = jsmn_parse(&p, buff, total_size, tok, number_of_tokens); if (r < 0) { + ssp_free(buff); ssp_error("Failed to parse JSON\n"); return -1; } @@ -335,10 +343,21 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa //char key[key_size + 1]; char *key = ssp_alloc(key_size + 1, sizeof(char)); + if (key == NULL) { + ssp_free(buff); + return -1; + } + key[key_size] = '\0'; strncpy(key, &buff[tok[i].start], key_size); char *value = ssp_alloc(value_size + 1, sizeof(char)); + if (value == NULL) { + ssp_free(buff); + ssp_free(value); + return -1; + } + value[value_size] = '\0'; strncpy(value, &buff[tok[i+1].start], value_size); @@ -346,10 +365,9 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa ssp_free(key); ssp_free(value); i++; - } + ssp_free(buff); - ssp_free(tok); return 0; } diff --git a/Program/src/main.c b/Program/src/main.c index 8370027..725f6ac 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -1,4 +1,3 @@ -#ifdef POSIX_PORT /*------------------------------------------------------------------------------ This file is protected under copyright. If you want to use it, please include this text, that is my only stipulation. @@ -12,6 +11,7 @@ Author: Evan Giese #include #include +#include "port.h" //Have to include these files #include //for types @@ -27,8 +27,14 @@ Author: Evan Giese //for signal handler, because its nice #include "posix_server_provider.h" //for ssp_thread_join, can use p_thread join on linux -#include "port.h" + #include "tasks.h" +#include "mib.h" + +#ifdef CSP_NETWORK + #include + #include +#endif /*------------------------------------------------------------------------------ Purpose: This struct if our configuration for this program, these elements @@ -40,6 +46,8 @@ typedef struct config uint32_t client_cfdp_id; uint32_t my_cfdp_id; uint8_t verbose_level; + uint32_t baudrate; + char *uart_device; } Config; @@ -55,9 +63,12 @@ static Config *configuration(int argc, char **argv) conf->verbose_level = 0; conf->client_cfdp_id = 0; conf->my_cfdp_id = 0; + conf->baudrate = 9600; + conf->uart_device = NULL; + uint32_t tmp; - while ((ch = getopt(argc, argv, "t: i: c: v: h")) != -1) + while ((ch = getopt(argc, argv, "t: i: c: v: k: h ")) != -1) { switch (ch) { @@ -81,17 +92,28 @@ static Config *configuration(int argc, char **argv) conf->client_cfdp_id = tmp; break; + case 'k': + conf->uart_device = optarg; + break; + + case 'b': + tmp = strtol(optarg, NULL, 10); + conf->baudrate = tmp; + break; + case 'h': ssp_printf("\n-----------HELP MESSAGE------------\n"); ssp_printf("\nusage: %s [options] \n\n", basename(argv[0])); ssp_printf("Options: %s%s%s%s\n", - "-t timeout\n", - "-i my cfdp id for server\n", - "-c client id\n", - "-v verbose level (1-3)" + "-t \n", + "-i \n", + "-c \n", + "-v eg (1-3)" + "-k eg /dev/ttyUSB0\n" + "-b default is 9600" "-h HelpMessage"); - ssp_printf("Default port number mis 1111\n"); + ssp_printf("Default port number is 1111\n"); ssp_printf("\n---------------END----------------\n"); break; default: @@ -117,30 +139,78 @@ int main(int argc, char** argv) { #ifdef CSP_NETWORK - ssp_printf("Initialising CSP\r\n"); - /* Init CSP with address MY_ADDRESS */ - csp_init(1); + csp_debug_level_t debug_level = CSP_INFO; + // enable/disable debug levels + for (csp_debug_level_t i = 0; i <= CSP_LOCK; ++i) { + csp_debug_set_level(i, (i <= debug_level) ? true : false); + } - /* Init buffer system with 10 packets of maximum bytes each */ - csp_buffer_init(1000, 250); + Remote_entity remote_entity; + int error = get_remote_entity_from_json(&remote_entity, conf->my_cfdp_id); + if (error < 0) { + ssp_error("couldn't get client remote_entity from mib\n"); + return 1; + } - /* Start router task with 500 word stack, OS task priority 1 */ - csp_route_start_task(5000, 1); - + csp_conf_t csp_conf; + csp_conf_get_defaults(&csp_conf); + csp_conf.address = remote_entity.UT_address; + + error = csp_init(&csp_conf); + if (error != CSP_ERR_NONE) { + csp_log_error("csp_init() failed, error: %d", error); + exit(1); + } + + // Start router task with 10000 bytes of stack (priority is only supported on FreeRTOS) + csp_route_start_task(500, 0); + + // Add interface(s) + csp_iface_t * default_iface = NULL; + if (conf->uart_device != NULL) { + csp_usart_conf_t uart_conf = {.device = conf->uart_device, + .baudrate = conf->baudrate, // supported on all platforms + .databits = 8, + .stopbits = 2, + .paritysetting = 0, + .checkparity = 0}; + error = csp_usart_open_and_add_kiss_interface(&uart_conf, CSP_IF_KISS_DEFAULT_NAME, &default_iface); + if (error != CSP_ERR_NONE) { + ssp_printf("failed to add KISS interface, error: %d", error); + exit(1); + } + } + + //printf("Connection table\r\n"); + //csp_conn_print_table(); + + printf("Interfaces\r\n"); + csp_route_print_interfaces(); + + //printf("Route table\r\n"); + //csp_route_print_table(); #endif - FTP *app = init_ftp(conf->my_cfdp_id); - if (app == NULL) { + + + FTP app; + //init_ftp(conf->my_cfdp_id, &app); + uint32_t id = conf->my_cfdp_id; + void *handler = create_ftp_task(id, &app); + if (handler == NULL) { return 1; } - sleep(1); + + uint32_t client_id = conf->client_cfdp_id; + Request *req = put_request(client_id, "pictures/pic.jpeg", "pictures/udp.jpg", ACKNOWLEDGED_MODE, &app); +/* if (conf->client_cfdp_id == 1) { - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled.jpg", ACKNOWLEDGED_MODE, app); - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled2.jpg", ACKNOWLEDGED_MODE, app); - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled3.jpg", ACKNOWLEDGED_MODE, app); - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled4.jpg", ACKNOWLEDGED_MODE, app); + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled5.jpg", ACKNOWLEDGED_MODE, app); + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled6.jpg", ACKNOWLEDGED_MODE, app); + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled7.jpg", UN_ACKNOWLEDGED_MODE, app); + schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled8.jpg", UN_ACKNOWLEDGED_MODE, app); start_scheduled_requests(conf->client_cfdp_id, app); } else if (conf->client_cfdp_id == 2) { @@ -160,6 +230,8 @@ int main(int argc, char** argv) { //start_request(req); } + +*/ //Request *req = put_request(conf->my_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", ACKNOWLEDGED_MODE, app); //start_request(req); @@ -180,9 +252,11 @@ int main(int argc, char** argv) { start_request(req); } */ - ssp_thread_join(app->server_handle); + + free(conf); + ssp_thread_join(handler); + //ssp_thread_join(app2->server_handle); - //free(conf); + return 0; } -#endif diff --git a/Program/src/mib.c b/Program/src/mib.c index 4ad6031..cca6bd3 100755 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -157,6 +157,7 @@ static void parse_mib(char *key, char *value, void *params) { int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { char file_name[50]; + memset(file_name, 0, 50); ssp_snprintf(file_name, 50, "%s%d%s", "mib/peer_", cfdp_id, ".json"); int error = read_json(file_name, parse_mib, remote); diff --git a/Program/src/port.c b/Program/src/port.c index 7b7531f..e7ec6e2 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -9,7 +9,6 @@ Author: Evan Giese static int exit_now = 0; #ifdef POSIX_PORT - #include #include #include #include @@ -260,9 +259,7 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { if (mem == NULL) ssp_error("Memory failed to alloc!\n"); return mem; - #endif - - + #endif } void ssp_free(void *pointer) { @@ -288,9 +285,9 @@ void ssp_error(char *error){ void ssp_printf(char *stuff, ...) { va_list args; va_start(args, stuff); - //vfprintf(stdout, stuff, args); + vfprintf(stdout, stuff, args); va_end (args); - //fflush(stdout); + fflush(stdout); } //returns seconds elapsed, need FREE RTOS realtime clock lib to properly port diff --git a/Program/src/tasks.c b/Program/src/tasks.c index a173ec1..b8999a5 100755 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -594,5 +594,4 @@ void ssp_cleanup_ftp(FTP *app) { app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); app->active_clients->freeOnlyList(app->active_clients); ssp_free(app->buff); - ssp_free(app); } From 955092220b213e81885c60c123c960e7ea423407 Mon Sep 17 00:00:00 2001 From: evanGee Date: Mon, 1 Feb 2021 17:58:17 -0700 Subject: [PATCH 281/400] improve csp error handling, and remove VLA --- Program/include/port.h | 12 +++++----- Program/src/csp_server_provider.c | 39 +++++++++++++++++++++---------- Program/src/port.c | 4 ++-- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 6e7c384..e3467ac 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -8,12 +8,12 @@ Author: Evan Giese #define PORT_H -//#define FREE_RTOS_PORT -//#define RED_FS +#define FREE_RTOS_PORT +#define RED_FS +#define CSP_NETWORK -//#define CSP_NETWORK -#define POSIX_FILESYSTEM -#define POSIX_PORT +//#define POSIX_FILESYSTEM +//#define POSIX_PORT @@ -21,6 +21,7 @@ Author: Evan Giese //#define TEST #include "types.h" +#define STACK_ALLOCATION 20000 #ifdef CSP_NETWORK #include "csp/csp.h" @@ -98,7 +99,6 @@ Author: Evan Giese #include #define SSP_INET_ADDRSTRLEN INET_ADDRSTRLEN - #define STACK_ALLOCATION 20000 #define SSP_AF_INET AF_INET #define ssp_htonl htonl diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 7a08073..919c90b 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -154,25 +154,37 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, void *other) { + int error = 0; //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); - - /* Create socket without any socket options */ - csp_socket_t *sock = csp_socket(CSP_SO_NONE); + //Create socket without any socket options + csp_socket_t *sock = csp_socket(CSP_SO_NONE); + if (sock == NULL) { + ssp_error("csp socket failed to initialize"); + return; + } uint8_t src_id = csp_get_address(); - ssp_printf("CSP ID: %d\n", src_id); - - /* Bind all ports to socket */ - csp_bind(sock, my_port); - /* Create 10 connections backlog queue */ - csp_listen(sock, 10); - - /* Pointer to current connection and packet */ + //Bind all ports to socket + error = csp_bind(sock, my_port); + if (error != CSP_ERR_NONE) { + ssp_error("csp socket failed to bind"); + return; + } + //Create 10 connections backlog queue + error = csp_listen(sock, 10); + if (error != CSP_ERR_NONE) { + ssp_error("csp socket failed to listen"); + return; + } + //Pointer to current connection and packet csp_conn_t *conn; csp_packet_t *packet; - char buff[packet_len]; + char *buff = ssp_alloc(packet_len, sizeof(char)); + if (buff == NULL) { + return; + } memset(buff, 0, packet_len); /* Process incoming connections */ @@ -205,10 +217,13 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, csp_buffer_free(packet); } } + csp_close(conn); onExit(other); } + + ssp_free(buff); } diff --git a/Program/src/port.c b/Program/src/port.c index e7ec6e2..9930cf1 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -74,7 +74,7 @@ int ssp_mkdir(char *dir_name) { return -1; } else { - ssp_printf("%s directory already exists\n", dir_name); + ssp_printf("%s directory created\n", dir_name); return 1; } return -1; @@ -91,7 +91,7 @@ int ssp_mkdir(char *dir_name) { return -1; } else { - ssp_printf("%s directory already exists\n", dir_name); + ssp_printf("%s directory created\n", dir_name); return 1; } return -1; From cf863673a50840a020d55e0f07aa2eb7f8225773 Mon Sep 17 00:00:00 2001 From: evanGee Date: Mon, 1 Feb 2021 18:38:37 -0700 Subject: [PATCH 282/400] add htonl functions on build_pdu_header and process_pdu_header --- Program/include/csp_server_provider.h | 2 +- Program/src/csp_server_provider.c | 45 +++++++++++++++++++++++++++ Program/src/file_delivery_app.c | 2 ++ Program/src/filesystem_funcs.c | 2 -- Program/src/packet.c | 10 ++++-- Program/src/protocol_handler.c | 5 ++- 6 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index 1400a6f..142b18d 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -39,5 +39,5 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, int (*checkExit)(void *checkExitParams), void (*onExit)(void *params), void *params); - +int csp_custom_ftp_ping(uint32_t dest_id); #endif diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 919c90b..e23166b 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -145,6 +145,51 @@ void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, } } +int csp_custom_ftp_ping(uint32_t dest_id){ + + char buff[255]; + memset(buff, 0, 255); + + csp_packet_t * packet; + csp_conn_t * conn; + /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ + conn = csp_connect(CSP_PRIO_NORM, dest_id, 1, 1000, CSP_SO_NONE); + if (conn == NULL) { + /* Connect failed */ + ssp_printf("Connection failed\n"); + return; + } + + ssp_printf("connection established, sending ping to id %d port %d \n", dest_id, 1); + packet = csp_buffer_get(100); + if (packet == NULL) { + ssp_printf("couldn't get packet for ping\n"); + } + + snprintf((char *) packet->data, csp_buffer_data_size(), "FTP ping"); + packet->length = (strlen((char *) packet->data) + 1); + if (!csp_send(conn, packet, 1000)) { + ssp_printf("Send failed"); + csp_buffer_free(packet); + } + + csp_packet_t *p = csp_read(conn, 1000); + if (p == NULL) { + ssp_printf("ping failed\n"); + } else { + + memcpy(buff, (char *)p->data, p->length); + ssp_printf("%s\n", buff); + + csp_close(conn); + return 1; + } + + csp_close(conn); + return -1; +} + + void csp_connection_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index d2565ca..4041d75 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -76,6 +76,8 @@ static int create_ssp_client_drivers(Client *client) { int init_ftp(uint32_t my_cfdp_address, FTP *app) { int error = 0; + memset(app, 0, sizeof(FTP)); + error = ssp_mkdir("incomplete_requests"); if (error < 0) { ssp_error("couldn't make directory incomplete_requests it either already exists or there is an issue\n"); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 7370363..6cc0f34 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -300,8 +300,6 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa jsmn_parser p; jsmn_init(&p); - ssp_printf("%s\n", file_name); - jsmntok_t tok[255]; uint32_t total_size = get_file_size(file_name); diff --git a/Program/src/packet.c b/Program/src/packet.c index 6f9744e..ec49706 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -37,21 +37,25 @@ uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uin Pdu_header *header = (Pdu_header *)packet; header->transmission_mode = transmission_mode; + uint64_t tsn = htonll(transaction_sequence_number); + uint32_t src_id = htonl(pdu_header->source_id); + uint32_t dest_id = htonl(pdu_header->destination_id); + //copy variable length src id memcpy(&packet[packet_index], - &pdu_header->source_id, + &src_id, pdu_header->length_of_entity_IDs); packet_index += pdu_header->length_of_entity_IDs; //copy variable length transaction number id memcpy(&packet[packet_index], - &transaction_sequence_number, + &tsn, pdu_header->transaction_seq_num_len); packet_index += pdu_header->transaction_seq_num_len; //copy variable length destination id memcpy(&packet[packet_index], - &pdu_header->destination_id, + &dest_id, pdu_header->length_of_entity_IDs); uint8_t total_bytes = PACKET_STATIC_HEADER_LEN diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 75740b5..d76351b 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -136,15 +136,18 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r uint32_t source_id = 0; ssp_memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); + source_id = ntohl(source_id); packet_index += header->length_of_entity_IDs; //TODO the transaction number should get the request from data structure hosting requests uint32_t transaction_sequence_number = 0; ssp_memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); + transaction_sequence_number = ntohl(transaction_sequence_number); packet_index += header->transaction_seq_num_len; uint32_t dest_id = 0; ssp_memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); + dest_id = ntohl(dest_id); packet_index += header->length_of_entity_IDs; if (app->my_cfdp_id != dest_id){ @@ -687,7 +690,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque if (header->PDU_type == 1) { if (!req->local_entity.Metadata_recv_indication) { if (req->file == NULL) { - printf("file is null\n"); + ssp_printf("file is null\n"); build_temperary_file(req, TEMP_FILESIZE); } } From af5b894d032ca1c31b6e96372e61598acc264dae Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 2 Feb 2021 19:42:34 -0700 Subject: [PATCH 283/400] add bit print function --- Program/include/utils.h | 2 +- Program/src/utils.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Program/include/utils.h b/Program/include/utils.h index ace4a43..db0ed38 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -14,6 +14,6 @@ Author: Evan Giese #define ntohll(x) ((1==ssp_ntohl(1)) ? (x) : ((uint64_t)ssp_ntohl((x) & 0xFFFFFFFF) << 32) | ssp_ntohl((x) >> 32)) void ssp_print_hex(char *stuff, int size); - +void ssp_print_bits(char *stuff, int size); #endif //UTILS_H diff --git a/Program/src/utils.c b/Program/src/utils.c index 8d36b4a..8d22503 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -19,3 +19,28 @@ void ssp_print_hex(char *stuff, int size){ } ssp_printf("\n"); } + +void ssp_print_bits(char *stuff, int size){ + + uint32_t current_packet_index = 0; + ssp_printf("printing number of bytes: %u\n", size); + int j, i, bit_set, byte = 0; + unsigned char bit_mask = 0; + + for (i = size - 1; i >= 0; i--) { + byte = stuff[i]; + bit_mask = 128; + for (j = 7; j >= 0 ; j--) { + bit_set = bit_mask & byte; + bit_mask = bit_mask >> 1; + + if (bit_set){ + ssp_printf("1"); + } else { + ssp_printf("0"); + } + } + ssp_printf(" "); + } + ssp_printf("\n"); +} \ No newline at end of file From 6312e5b55086379481415825cc560f50aef430ab Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 3 Feb 2021 15:53:36 -0700 Subject: [PATCH 284/400] testing pdu_handler functions --- Program/src/packet.c | 6 +++--- Program/src/protocol_handler.c | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index ec49706..f8b0cf4 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -37,9 +37,9 @@ uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uin Pdu_header *header = (Pdu_header *)packet; header->transmission_mode = transmission_mode; - uint64_t tsn = htonll(transaction_sequence_number); - uint32_t src_id = htonl(pdu_header->source_id); - uint32_t dest_id = htonl(pdu_header->destination_id); + uint64_t tsn = transaction_sequence_number; + uint32_t src_id = pdu_header->source_id; + uint32_t dest_id = pdu_header->destination_id; //copy variable length src id memcpy(&packet[packet_index], diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index d76351b..5abcb38 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -132,23 +132,27 @@ where the data portion is, returns -1 on fail*/ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; - Pdu_header *header = (Pdu_header *) packet; + Pdu_header *header = ssp_ntohl((Pdu_header *) packet); + + ssp_printf("packet header values\n"); + ssp_print_bits(header, 4); + ssp_printf("%d\n", header->length_of_entity_IDs); uint32_t source_id = 0; ssp_memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); - source_id = ntohl(source_id); packet_index += header->length_of_entity_IDs; + ssp_printf("source_id %d\n", source_id); //TODO the transaction number should get the request from data structure hosting requests uint32_t transaction_sequence_number = 0; ssp_memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); - transaction_sequence_number = ntohl(transaction_sequence_number); packet_index += header->transaction_seq_num_len; + ssp_printf("transaction_sequence_number %d\n", transaction_sequence_number); uint32_t dest_id = 0; ssp_memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); - dest_id = ntohl(dest_id); packet_index += header->length_of_entity_IDs; + ssp_printf("dest_id %d\n", dest_id ); if (app->my_cfdp_id != dest_id){ ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); From 5dd3571e8100acd355cf710d663e25dbae81f055 Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 5 Feb 2021 16:40:54 -0700 Subject: [PATCH 285/400] big change to protocol building and parsing, starting with pdu header --- Program/include/packet.h | 4 +- Program/include/port.h | 14 +-- Program/include/types.h | 6 +- Program/src/mib.c | 2 +- Program/src/packet.c | 157 +++++++++++++++++++++++++-------- Program/src/protocol_handler.c | 62 ++++++------- Program/src/utils.c | 2 +- Program/test/packet_tests.c | 73 ++++++++------- Program/test/request_tests.c | 30 ++++--- 9 files changed, 218 insertions(+), 132 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 0380a50..ffca6d4 100755 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -14,7 +14,7 @@ Author: Evan Giese #include "types.h" #include "list.h" -uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); +int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); uint8_t build_finished_pdu(char *packet, uint32_t start); uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); @@ -27,6 +27,8 @@ uint8_t build_ack(char*packet, uint32_t start, uint8_t type); uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) ; void set_data_length(char*packet, uint16_t data_len); uint16_t get_data_length(char*packet); +int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header); + uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req); uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req); diff --git a/Program/include/port.h b/Program/include/port.h index e3467ac..710c056 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -8,12 +8,12 @@ Author: Evan Giese #define PORT_H -#define FREE_RTOS_PORT -#define RED_FS +//#define FREE_RTOS_PORT +//#define RED_FS #define CSP_NETWORK -//#define POSIX_FILESYSTEM -//#define POSIX_PORT +#define POSIX_FILESYSTEM +#define POSIX_PORT @@ -38,8 +38,8 @@ Author: Evan Giese #define SSP_AF_INET 2 #define ssp_htonl csp_hton32 #define ssp_ntohl csp_ntoh32 - #define ssp_htons csp_ntoh16 - #define ssp_stonl csp_hton16 + #define ssp_ntohs csp_ntoh16 + #define ssp_htons csp_hton16 #define ssp_inet_ntop inet_ntop #endif @@ -104,7 +104,7 @@ Author: Evan Giese #define ssp_htonl htonl #define ssp_ntohl ntohl #define ssp_htons htons - #define ssp_stonl stonl + #define ssp_ntohs ntohs #define ssp_inet_ntop inet_ntop #include diff --git a/Program/include/types.h b/Program/include/types.h index 4d99997..24565d3 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -63,11 +63,15 @@ typedef struct pdu_header{ uint32_t source_id; //variable in size (for actual packet), and will get memory allocated based on the length variables above - void *transaction_sequence_number; + uint32_t transaction_sequence_number; //variable in size (for actual packet), and will get memory allocated based on the length variables above uint32_t destination_id; + //this is how much space is reserved for the entire header. Since the IDs are variable length, we need + //to calculate how much space we need based on the size of IDs. + uint32_t reserved_space_for_header; + } Pdu_header; typedef struct originating_tranaction_id_message { diff --git a/Program/src/mib.c b/Program/src/mib.c index cca6bd3..ca7aaa0 100755 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -19,7 +19,7 @@ int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t m pdu_header->CRC_flag = remote.CRC_required; pdu_header->direction = 1; pdu_header->PDU_type = 0; - pdu_header->transaction_seq_num_len = 3; + pdu_header->transaction_seq_num_len = 2; pdu_header->length_of_entity_IDs = 1; pdu_header->transmission_mode = remote.default_transmission_mode; pdu_header->destination_id = remote.cfdp_id; diff --git a/Program/src/packet.c b/Program/src/packet.c index f8b0cf4..43cfc1e 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -20,50 +20,132 @@ Author: Evan Giese // if is_data_packet is false, then is directive pacnket static void set_packet_header(char *packet, uint16_t data_len, bool is_data_packet) { - - Pdu_header *header = (Pdu_header *) packet; - header->PDU_type = is_data_packet; + push_bits_to_protocol_byte(&packet[0], 3,3, is_data_packet); set_data_length(packet, data_len); } +void push_bits_to_protocol_byte(char *byte, uint8_t from_position, uint8_t to_position, uint8_t value) { + char bit_mask = value; + uint8_t bits_to_shift_left = 7-to_position; + char bits_to_add = bit_mask << bits_to_shift_left; + *byte = *byte | bits_to_add; +} +//get bits fromleft to right +uint8_t get_bits_from_protocol_byte(char byte, uint8_t from_position, uint8_t to_position){ + uint8_t bits_to_shift_left = from_position; + uint8_t bits_to_shift_right = 8 - (to_position - from_position + 1); + uint8_t bits_to_get = byte << bits_to_shift_left; + uint32_t value = bits_to_get >> bits_to_shift_right; + return value; +} -//returns the location in the packet where the next pointer for tthe packet will start after the header -uint8_t build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { +int copy_id_to_packet(char *bytes, uint32_t id, uint32_t length_of_ids) { + + if (length_of_ids == 4) { + uint32_t network_byte_order = ssp_htonl(id); + memcpy(bytes, &network_byte_order, sizeof(uint32_t)); + } else if (length_of_ids == 2) { + uint16_t network_byte_order = ssp_htons((uint16_t) id); + memcpy(bytes, &network_byte_order, sizeof(uint16_t)); + } else if (length_of_ids == 1) { + uint8_t network_byte_order = id; + memcpy(bytes, &network_byte_order, sizeof(uint8_t)); + } else { + ssp_error("id size is not supported, please user 1, 2 or 4"); + return -1; + } + return 0; +} - memcpy(packet, pdu_header, PACKET_STATIC_HEADER_LEN); - uint32_t packet_index = PACKET_STATIC_HEADER_LEN; - - Pdu_header *header = (Pdu_header *)packet; - header->transmission_mode = transmission_mode; +uint32_t get_id_from_packet(char *bytes, uint32_t length_of_ids) { + uint32_t host_byte_order = 0; + if (length_of_ids == 4) { + host_byte_order = ssp_ntohl(*(uint32_t*) bytes); + } else if (length_of_ids == 2) { + host_byte_order = ssp_ntohs(*(uint16_t*) bytes); + } else if (length_of_ids == 1){ + host_byte_order = *bytes; + } else { + ssp_error("id size is not supported, please user 1, 2 or 4"); + return -1; + } + return host_byte_order; +} - uint64_t tsn = transaction_sequence_number; - uint32_t src_id = pdu_header->source_id; - uint32_t dest_id = pdu_header->destination_id; - - //copy variable length src id - memcpy(&packet[packet_index], - &src_id, - pdu_header->length_of_entity_IDs); - packet_index += pdu_header->length_of_entity_IDs; - - //copy variable length transaction number id - memcpy(&packet[packet_index], - &tsn, - pdu_header->transaction_seq_num_len); - packet_index += pdu_header->transaction_seq_num_len; - - //copy variable length destination id - memcpy(&packet[packet_index], - &dest_id, - pdu_header->length_of_entity_IDs); - - uint8_t total_bytes = PACKET_STATIC_HEADER_LEN - + pdu_header->length_of_entity_IDs - + pdu_header->transaction_seq_num_len - + pdu_header->length_of_entity_IDs; +int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ + + pdu_header->version = get_bits_from_protocol_byte(packet[0], 0, 2); + pdu_header->PDU_type = get_bits_from_protocol_byte(packet[0], 3, 3); + pdu_header->direction = get_bits_from_protocol_byte(packet[0], 4, 4); + pdu_header->transmission_mode = get_bits_from_protocol_byte(packet[0], 5, 5); + pdu_header->CRC_flag = get_bits_from_protocol_byte(packet[0], 6, 6); + pdu_header->reserved_bit_0 = get_bits_from_protocol_byte(packet[0], 7, 7); + pdu_header->PDU_data_field_len = ssp_ntohs(packet[1]); + pdu_header->reserved_bit_1 = get_bits_from_protocol_byte(packet[3], 0, 0); + pdu_header->length_of_entity_IDs = get_bits_from_protocol_byte(packet[3], 1, 3); + pdu_header->reserved_bit_2 = get_bits_from_protocol_byte(packet[3], 4, 4); + pdu_header->transaction_seq_num_len = get_bits_from_protocol_byte(packet[3], 5, 7); + + int32_t source_id_location = PACKET_STATIC_HEADER_LEN; + pdu_header->source_id = get_id_from_packet(&packet[source_id_location], pdu_header->length_of_entity_IDs); + if (pdu_header->source_id < 0) { + ssp_error("failed to get source_id"); + return -1; + } + int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; + pdu_header->transaction_sequence_number = get_id_from_packet(&packet[transaction_number_location], pdu_header->transaction_seq_num_len); + if (pdu_header->transaction_sequence_number < 0) { + ssp_error("failed to get transaction_sequence_number"); + return -1; + } + int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; + pdu_header->destination_id = get_id_from_packet(&packet[dest_id_location], pdu_header->length_of_entity_IDs); + if (pdu_header->destination_id < 0) { + ssp_error("failed to get destination_id"); + return -1; + } + pdu_header->reserved_space_for_header = dest_id_location + pdu_header->length_of_entity_IDs; + return pdu_header->reserved_space_for_header; +} - return total_bytes; +//returns the location in the packet where the next pointer for tthe packet will start after the header +int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { + memset(packet, 0, 4); + push_bits_to_protocol_byte(&packet[0], 0,2, pdu_header->version); + push_bits_to_protocol_byte(&packet[0], 3,3, pdu_header->PDU_type); + push_bits_to_protocol_byte(&packet[0], 4,4, pdu_header->direction); + push_bits_to_protocol_byte(&packet[0], 5,5, pdu_header->transmission_mode); + push_bits_to_protocol_byte(&packet[0], 6,6, pdu_header->CRC_flag); + push_bits_to_protocol_byte(&packet[0], 7,7, pdu_header->reserved_bit_0); + //bytes 1 and 2 are resevered for data_length, which gets calculated later and is added with set_data_length + //if the build_pdu_header is called later, after we build the packet, we know the data length, we just have to + //reserve the start of the packet, this space can be calculated when we construct the request. + push_bits_to_protocol_byte(&packet[3], 0,0, pdu_header->reserved_bit_1); + push_bits_to_protocol_byte(&packet[3], 1,3, pdu_header->length_of_entity_IDs); + push_bits_to_protocol_byte(&packet[3], 4,4, pdu_header->reserved_bit_2); + push_bits_to_protocol_byte(&packet[3], 5,7, pdu_header->transaction_seq_num_len); + + int32_t source_id_location = PACKET_STATIC_HEADER_LEN; + int error = copy_id_to_packet(&packet[source_id_location], pdu_header->source_id, pdu_header->length_of_entity_IDs); + if (error < 0) { + ssp_error("failed copy source_id"); + return -1; + } + int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; + error = copy_id_to_packet(&packet[transaction_number_location], pdu_header->source_id, pdu_header->length_of_entity_IDs); + if (error < 0) { + ssp_error("failed copy transaction_number_location"); + return -1; + } + int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; + error = copy_id_to_packet(&packet[dest_id_location], pdu_header->destination_id, pdu_header->length_of_entity_IDs); + if (error < 0) { + ssp_error("failed copy destination_id"); + return -1; + } + + return dest_id_location + pdu_header->length_of_entity_IDs; } uint8_t build_finished_pdu(char *packet, uint32_t start) { @@ -320,8 +402,7 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { } void set_data_length(char*packet, uint16_t data_len){ - Pdu_header *header = (Pdu_header*) packet; - header->PDU_data_field_len = ssp_htons(data_len);; + packet[2] = ssp_htons(data_len); } uint16_t get_data_length(char*packet) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 5abcb38..5b0f4d0 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -129,52 +129,42 @@ static int find_request(void *element, void *args) { /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet where the data portion is, returns -1 on fail*/ + int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; - Pdu_header *header = ssp_ntohl((Pdu_header *) packet); - - ssp_printf("packet header values\n"); - ssp_print_bits(header, 4); - ssp_printf("%d\n", header->length_of_entity_IDs); - - uint32_t source_id = 0; - ssp_memcpy(&source_id, &packet[packet_index], header->length_of_entity_IDs); - packet_index += header->length_of_entity_IDs; - ssp_printf("source_id %d\n", source_id); - - //TODO the transaction number should get the request from data structure hosting requests - uint32_t transaction_sequence_number = 0; - ssp_memcpy(&transaction_sequence_number, &packet[packet_index], header->transaction_seq_num_len); - packet_index += header->transaction_seq_num_len; - ssp_printf("transaction_sequence_number %d\n", transaction_sequence_number); - - uint32_t dest_id = 0; - ssp_memcpy(&dest_id, &packet[packet_index], header->length_of_entity_IDs); - packet_index += header->length_of_entity_IDs; - ssp_printf("dest_id %d\n", dest_id ); - - if (app->my_cfdp_id != dest_id){ - ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, dest_id); + ssp_print_bits(packet, 10); + + Pdu_header header; + memset(&header, 0, sizeof(Pdu_header)); + + int error = get_pdu_header_from_packet(packet, &header); + if (error < 0) { + ssp_error("failed to get pdu header, bad formatting"); + return -1; + } + if (app->my_cfdp_id != header.destination_id){ + ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, header.destination_id); return -1; } - //if packet is from the same request, don't' change current request - Request *current_req = (*req); - uint16_t len = get_data_length(packet); + uint16_t len = header.PDU_data_field_len; if (len > app->packet_len){ ssp_printf("packet received %d that was too big for our buffer %d\n", len, app->packet_len); return -1; } - if (current_req != NULL && current_req->transaction_sequence_number == transaction_sequence_number && current_req->dest_cfdp_id == source_id){ - return packet_index; + //if packet is from the same request, don't' change current request + Request *current_req = (*req); + + if (current_req != NULL && current_req->transaction_sequence_number == header.transaction_sequence_number && current_req->dest_cfdp_id == header.source_id){ + return header.reserved_space_for_header; } //look for active request in list struct request_search_params params = { - source_id, - transaction_sequence_number, + header.source_id, + header.transaction_sequence_number, }; Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); @@ -183,9 +173,9 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r if (found_req == NULL && is_server) { - found_req = new_incomming_request(source_id, - header->transmission_mode, - transaction_sequence_number, + found_req = new_incomming_request(header.source_id, + header.transmission_mode, + header.transaction_sequence_number, res, app); @@ -194,7 +184,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r return -1; } - app->request_list->push(app->request_list, found_req, transaction_sequence_number); + app->request_list->push(app->request_list, found_req, header.transaction_sequence_number); } else if (found_req == NULL) { @@ -203,7 +193,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r } *req = found_req; - return packet_index; + return header.reserved_space_for_header; } diff --git a/Program/src/utils.c b/Program/src/utils.c index 8d22503..9ca4728 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -27,7 +27,7 @@ void ssp_print_bits(char *stuff, int size){ int j, i, bit_set, byte = 0; unsigned char bit_mask = 0; - for (i = size - 1; i >= 0; i--) { + for (i = 0; i < size; i++) { byte = stuff[i]; bit_mask = 128; for (j = 7; j >= 0 ; j--) { diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 8734c0a..0b1d8d6 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -248,39 +248,41 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_number) { + header->PDU_data_field_len = 0; + header->destination_id = 32; + header->source_id = 35; + header->length_of_entity_IDs = 1; + header->transaction_sequence_number = 12; + header->transaction_seq_num_len = 1; + DECLARE_NEW_TEST("testing header creation"); + uint32_t packet_index = 0; + //ssp_print_bits(header, 4); + Pdu_header new_header; + memset(&new_header, 0, 4); + uint8_t length = build_pdu_header(packet, sequence_number, 0, header); - uint32_t packet_index = PACKET_STATIC_HEADER_LEN; - - ASSERT_EQUALS_INT("packet length: ", length, 9); - ASSERT_EQUALS_STR("packet source id ", &packet[packet_index], &header->source_id, header->length_of_entity_IDs); - - - packet_index += header->length_of_entity_IDs; - - ASSERT_NOT_EQUALS_INT("transaction_sequence_number correctly placed ", packet[packet_index], sequence_number); - packet_index += header->transaction_seq_num_len; - - ASSERT_NOT_EQUALS_STR("packet destination not equal to source id ", &packet[packet_index], &header->source_id, header->length_of_entity_IDs); - ASSERT_EQUALS_STR("packet destination id ", &packet[packet_index], &header->destination_id, header->length_of_entity_IDs); - - packet_index += header->length_of_entity_IDs; - Pdu_header *new_header = (Pdu_header *)packet; - - ASSERT_EQUALS_INT("CRC = CRC", header->CRC_flag, new_header->CRC_flag); - ASSERT_EQUALS_INT("direction = direction", header->direction, new_header->direction); - ASSERT_EQUALS_INT("length_of_entity_IDs = length_of_entity_IDs ", header->length_of_entity_IDs, new_header->length_of_entity_IDs); - //ASSERT_EQUALS_INT("PDU data_field_len = PDU_data_field_len ", header->PDU_data_field_len, new_header->PDU_data_field_len); - ASSERT_EQUALS_INT("PDU_type = PDU_type", header->PDU_type, new_header->PDU_type); - ASSERT_EQUALS_INT("reserved_bit_0 = reserved_bit_0 ", header->reserved_bit_0, new_header->reserved_bit_0); - ASSERT_EQUALS_INT("reserved_bit_1 = reserved_bit_1 ", header->reserved_bit_1, new_header->reserved_bit_1); - ASSERT_EQUALS_INT("reserved_bit_2 = reserved_bit_2 ", header->reserved_bit_2, new_header->reserved_bit_2); - //ASSERT_EQUALS_INT("version = version", header->version, new_header->version); - ASSERT_EQUALS_INT("transaction_seq_num_len = transaction_seq_num_len ", header->transaction_seq_num_len, new_header->transaction_seq_num_len); - ASSERT_EQUALS_INT("transmission_mode = transmission_mode ", 0, new_header->transmission_mode); - ASSERT_EQUALS_INT("total header length equal ", packet_index, length); - - return packet_index; + + get_pdu_header_from_packet(packet, &new_header); + + ASSERT_EQUALS_INT("CRC = CRC", header->CRC_flag, new_header.CRC_flag); + ASSERT_EQUALS_INT("direction = direction", header->direction, new_header.direction); + ASSERT_EQUALS_INT("length_of_entity_IDs = length_of_entity_IDs ", header->length_of_entity_IDs, new_header.length_of_entity_IDs); + ASSERT_EQUALS_INT("PDU data_field_len = PDU_data_field_len ", header->PDU_data_field_len, new_header.PDU_data_field_len); + ASSERT_EQUALS_INT("PDU_type = PDU_type", header->PDU_type, new_header.PDU_type); + ASSERT_EQUALS_INT("reserved_bit_0 = reserved_bit_0 ", header->reserved_bit_0, new_header.reserved_bit_0); + ASSERT_EQUALS_INT("reserved_bit_1 = reserved_bit_1 ", header->reserved_bit_1, new_header.reserved_bit_1); + ASSERT_EQUALS_INT("reserved_bit_2 = reserved_bit_2 ", header->reserved_bit_2, new_header.reserved_bit_2); + ASSERT_EQUALS_INT("version = version", header->version, new_header.version); + ASSERT_EQUALS_INT("transaction_seq_num_len = transaction_seq_num_len ", header->transaction_seq_num_len, new_header.transaction_seq_num_len); + ASSERT_EQUALS_INT("transmission_mode = transmission_mode ", header->transmission_mode, new_header.transmission_mode); + + ASSERT_EQUALS_INT("packet length: ", length, (header->transaction_seq_num_len + (header->length_of_entity_IDs * 2) + 4)); + ASSERT_EQUALS_INT("packet source id ", header->source_id, new_header.source_id); + ASSERT_EQUALS_INT("transaction_sequence_number correctly placed ", header->source_id, new_header.source_id); + ASSERT_EQUALS_INT("packet destination id ", header->destination_id, new_header.destination_id); + + return length; } @@ -509,11 +511,14 @@ int packet_tests() { int error = get_remote_entity_from_json (&remote_entity, 1); get_header_from_mib(&pdu_header, remote_entity, 2); + + int data_start_index = test_build_pdu_header(packet, &pdu_header, sequence_number); + - test_build_ack_eof_pdu(packet, data_start_index); - test_build_nak_packet(packet, data_start_index); - test_build_very_large_nak_packet(packet, data_start_index); + //test_build_ack_eof_pdu(packet, data_start_index); + //test_build_nak_packet(packet, data_start_index); + //test_build_very_large_nak_packet(packet, data_start_index); /* test_respond_to_naks(packet, data_start_index); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 4f90405..583e10f 100755 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -248,16 +248,18 @@ int test_lv_functions() { int request_user_input_tests() { - FTP *app = init_ftp(1); - put_request(2, "", "", 0, app); - put_request(2, NULL, NULL, 0, app); - app->close = true; - ssp_thread_join(app->server_handle); + FTP app; + void *handler = create_ftp_task(1, &app); + put_request(2, "", "", 0, &app); + put_request(2, NULL, NULL, 0, &app); + (&app)->close = true; + ssp_thread_join(handler); } int scheduled_requests_test() { - FTP *app = init_ftp(2); - int error = schedule_put_request(1, "test_files/dest.jpg", "test_files/scheduled_file_sent", ACKNOWLEDGED_MODE, app); + FTP app; + void *handler = create_ftp_task(1, &app); + int error = schedule_put_request(1, "test_files/dest.jpg", "test_files/scheduled_file_sent", ACKNOWLEDGED_MODE, &app); ASSERT_EQUALS_INT("couldn't schedule request when should have been able to ", error, 0); //error = schedule_put_request(1, "test_files/dest.jp", "test_files/scheduled_file_fail", ACKNOWLEDGED_MODE, app); @@ -267,20 +269,22 @@ int scheduled_requests_test() { //ASSERT_EQUALS_INT("scheduling just messages", error, 0); sleep(1); - app->close = true; - ssp_thread_join(app->server_handle); + app.close = true; + ssp_thread_join(handler); return 0; } int schedule_requests_start_test(){ sleep(1); - FTP *app = init_ftp(2); - - int error = start_scheduled_requests(1, app); + + FTP app; + void *handler = create_ftp_task(1, &app); + + int error = start_scheduled_requests(1, &app); ASSERT_EQUALS_INT("start request batch successfully", error, 0); //app->close = true; - ssp_thread_join(app->server_handle); + ssp_thread_join(handler); } int test_process_messages() { From e7b577060fb612507f334d81bebd6887611c5039 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 11 Feb 2021 20:43:40 -0700 Subject: [PATCH 286/400] Metadata packets refactoring --- Program/include/packet.h | 6 +- Program/include/protocol_handler.h | 7 +- Program/include/types.h | 2 +- Program/src/filesystem_funcs.c | 3 +- Program/src/mib.c | 3 +- Program/src/packet.c | 125 ++++++++++++++++++-------- Program/src/protocol_handler.c | 95 +++++++++++++------- Program/src/requests.c | 2 +- Program/src/tasks.c | 13 +-- Program/test/mock.c | 2 +- Program/test/packet_tests.c | 83 ++++++++--------- Program/test/protocol_handler_tests.c | 7 +- 12 files changed, 221 insertions(+), 127 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index ffca6d4..f1a03e4 100755 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -14,7 +14,7 @@ Author: Evan Giese #include "types.h" #include "list.h" -int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header); +int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, uint16_t data_len, Pdu_header *pdu_header); uint8_t build_finished_pdu(char *packet, uint32_t start); uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); @@ -28,8 +28,8 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) ; void set_data_length(char*packet, uint16_t data_len); uint16_t get_data_length(char*packet); int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header); - - +uint8_t get_bits_from_protocol_byte(char byte, uint8_t from_position, uint8_t to_position); +void ssp_print_header(Pdu_header *pdu_header); uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req); uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req); uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_user); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 23162a9..9626c28 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -13,11 +13,12 @@ Author: Evan Giese #define TIMEOUT_BEFORE_CANCEL_REQUEST 30 #define TIMEOUT_BEFORE_SAVE_REQUEST 5 -int parse_packet_server(char* buff, uint32_t packet_index, Response res, Request *req, FTP *app); +int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app); void user_request_handler(Response res, Request *req, Client *client); void parse_packet_client(char* buff, uint32_t packet_index, Response res, Request *req, Client *client); void on_server_time_out(Response res, Request *current_request); -int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app); +int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_header, Response res, Request **req, List *request_list, FTP *app); + uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); void process_pdu_eof(char *packet, Request *req, Response res); @@ -27,7 +28,7 @@ void process_pdu_eof(char *packet, Request *req, Response res); Response res, FTP *app); -uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill); +uint32_t parse_metadata_packet(char *meta_data_packet, uint32_t start, Request *req_to_fill); void process_messages(Request *req, FTP *app); uint8_t build_ack (char *packet, uint32_t start, uint8_t type); diff --git a/Program/include/types.h b/Program/include/types.h index 24565d3..98838ee 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -63,7 +63,7 @@ typedef struct pdu_header{ uint32_t source_id; //variable in size (for actual packet), and will get memory allocated based on the length variables above - uint32_t transaction_sequence_number; + uint64_t transaction_sequence_number; //variable in size (for actual packet), and will get memory allocated based on the length variables above uint32_t destination_id; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 6cc0f34..ff2d9f6 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -182,7 +182,6 @@ static int find_nak(void *element, void* args) { Offset *offset_in_list = (Offset *) element; Offset *offset_to_insert = (Offset *) args; - if (offset_to_insert->start >= offset_in_list->start && offset_to_insert->start <= offset_in_list->end && offset_to_insert->end <= offset_in_list->end && offset_to_insert->end >= offset_in_list->start) { return 1; @@ -199,7 +198,7 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs Offset offset_to_insert; offset_to_insert.start = offset_start; offset_to_insert.end = offset_end; - + Node *node = nak_list->findNode(nak_list, -1, find_nak, &offset_to_insert); if (node == NULL){ diff --git a/Program/src/mib.c b/Program/src/mib.c index ca7aaa0..96c32c8 100755 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -8,6 +8,7 @@ Author: Evan Giese #include "port.h" #include "types.h" #include "filesystem_funcs.h" +#include "packet.h" @@ -24,7 +25,7 @@ int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t m pdu_header->transmission_mode = remote.default_transmission_mode; pdu_header->destination_id = remote.cfdp_id; pdu_header->source_id = my_cfdp_id; - + pdu_header->reserved_space_for_header = (pdu_header->length_of_entity_IDs * 2) + (pdu_header->transaction_seq_num_len) + PACKET_STATIC_HEADER_LEN; return 0; } diff --git a/Program/src/packet.c b/Program/src/packet.c index 43cfc1e..7d14f2a 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -20,12 +20,11 @@ Author: Evan Giese // if is_data_packet is false, then is directive pacnket static void set_packet_header(char *packet, uint16_t data_len, bool is_data_packet) { - push_bits_to_protocol_byte(&packet[0], 3,3, is_data_packet); + set_bits_to_protocol_byte(&packet[0], 3,3, is_data_packet); set_data_length(packet, data_len); - } -void push_bits_to_protocol_byte(char *byte, uint8_t from_position, uint8_t to_position, uint8_t value) { +void set_bits_to_protocol_byte(char *byte, uint8_t from_position, uint8_t to_position, uint8_t value) { char bit_mask = value; uint8_t bits_to_shift_left = 7-to_position; char bits_to_add = bit_mask << bits_to_shift_left; @@ -40,8 +39,12 @@ uint8_t get_bits_from_protocol_byte(char byte, uint8_t from_position, uint8_t to return value; } -int copy_id_to_packet(char *bytes, uint32_t id, uint32_t length_of_ids) { +void set_packet_directive(char *packet, uint32_t location, uint8_t directive){ + packet[location] = directive; +} +int copy_id_to_packet(char *bytes, uint32_t id, uint32_t length_of_ids) { + if (length_of_ids == 4) { uint32_t network_byte_order = ssp_htonl(id); memcpy(bytes, &network_byte_order, sizeof(uint32_t)); @@ -73,6 +76,26 @@ uint32_t get_id_from_packet(char *bytes, uint32_t length_of_ids) { return host_byte_order; } +void ssp_print_header(Pdu_header *pdu_header){ + + ssp_printf("pdu_header->version %d\n",pdu_header->version); + ssp_printf("pdu_header->PDU_type %d\n",pdu_header->PDU_type); + ssp_printf("pdu_header->direction %d\n",pdu_header->direction); + ssp_printf("pdu_header->transmission_mode %d\n",pdu_header->transmission_mode); + ssp_printf("pdu_header->CRC_flag %d\n",pdu_header->CRC_flag); + ssp_printf("pdu_header->reserved_bit_0 %d\n",pdu_header->reserved_bit_0); + ssp_printf("pdu_header->PDU_data_field_len %d\n",pdu_header->PDU_data_field_len); + ssp_printf("pdu_header->reserved_bit_1 %d\n",pdu_header->reserved_bit_1 ); + ssp_printf("pdu_header->length_of_entity_IDs %d\n",pdu_header->length_of_entity_IDs); + ssp_printf("pdu_header->reserved_bit_2 %d\n",pdu_header->reserved_bit_2); + ssp_printf("pdu_header->transaction_seq_num_len %d\n",pdu_header->transaction_seq_num_len); + ssp_printf("pdu_header->source_id %d\n",pdu_header->source_id); + ssp_printf("pdu_header->transaction_sequence_number %d\n",pdu_header->transaction_sequence_number); + ssp_printf("pdu_header->destination_id %d\n",pdu_header->destination_id); + + +} + int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ pdu_header->version = get_bits_from_protocol_byte(packet[0], 0, 2); @@ -81,11 +104,14 @@ int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ pdu_header->transmission_mode = get_bits_from_protocol_byte(packet[0], 5, 5); pdu_header->CRC_flag = get_bits_from_protocol_byte(packet[0], 6, 6); pdu_header->reserved_bit_0 = get_bits_from_protocol_byte(packet[0], 7, 7); - pdu_header->PDU_data_field_len = ssp_ntohs(packet[1]); + + pdu_header->PDU_data_field_len = get_data_length(packet); + pdu_header->reserved_bit_1 = get_bits_from_protocol_byte(packet[3], 0, 0); pdu_header->length_of_entity_IDs = get_bits_from_protocol_byte(packet[3], 1, 3); pdu_header->reserved_bit_2 = get_bits_from_protocol_byte(packet[3], 4, 4); pdu_header->transaction_seq_num_len = get_bits_from_protocol_byte(packet[3], 5, 7); + int32_t source_id_location = PACKET_STATIC_HEADER_LEN; pdu_header->source_id = get_id_from_packet(&packet[source_id_location], pdu_header->length_of_entity_IDs); @@ -93,12 +119,14 @@ int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ ssp_error("failed to get source_id"); return -1; } + int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; pdu_header->transaction_sequence_number = get_id_from_packet(&packet[transaction_number_location], pdu_header->transaction_seq_num_len); if (pdu_header->transaction_sequence_number < 0) { ssp_error("failed to get transaction_sequence_number"); return -1; } + int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; pdu_header->destination_id = get_id_from_packet(&packet[dest_id_location], pdu_header->length_of_entity_IDs); if (pdu_header->destination_id < 0) { @@ -110,21 +138,20 @@ int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ } //returns the location in the packet where the next pointer for tthe packet will start after the header -int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, Pdu_header *pdu_header) { +int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_t transmission_mode, uint16_t data_len, Pdu_header *pdu_header) { memset(packet, 0, 4); - push_bits_to_protocol_byte(&packet[0], 0,2, pdu_header->version); - push_bits_to_protocol_byte(&packet[0], 3,3, pdu_header->PDU_type); - push_bits_to_protocol_byte(&packet[0], 4,4, pdu_header->direction); - push_bits_to_protocol_byte(&packet[0], 5,5, pdu_header->transmission_mode); - push_bits_to_protocol_byte(&packet[0], 6,6, pdu_header->CRC_flag); - push_bits_to_protocol_byte(&packet[0], 7,7, pdu_header->reserved_bit_0); - //bytes 1 and 2 are resevered for data_length, which gets calculated later and is added with set_data_length - //if the build_pdu_header is called later, after we build the packet, we know the data length, we just have to - //reserve the start of the packet, this space can be calculated when we construct the request. - push_bits_to_protocol_byte(&packet[3], 0,0, pdu_header->reserved_bit_1); - push_bits_to_protocol_byte(&packet[3], 1,3, pdu_header->length_of_entity_IDs); - push_bits_to_protocol_byte(&packet[3], 4,4, pdu_header->reserved_bit_2); - push_bits_to_protocol_byte(&packet[3], 5,7, pdu_header->transaction_seq_num_len); + + set_bits_to_protocol_byte(&packet[0], 0,2, pdu_header->version); + set_bits_to_protocol_byte(&packet[0], 3,3, pdu_header->PDU_type); + set_bits_to_protocol_byte(&packet[0], 4,4, pdu_header->direction); + set_bits_to_protocol_byte(&packet[0], 5,5, transmission_mode); + set_bits_to_protocol_byte(&packet[0], 6,6, pdu_header->CRC_flag); + set_bits_to_protocol_byte(&packet[0], 7,7, pdu_header->reserved_bit_0); + set_data_length(packet, data_len); + set_bits_to_protocol_byte(&packet[3], 0,0, pdu_header->reserved_bit_1); + set_bits_to_protocol_byte(&packet[3], 1,3, pdu_header->length_of_entity_IDs); + set_bits_to_protocol_byte(&packet[3], 4,4, pdu_header->reserved_bit_2); + set_bits_to_protocol_byte(&packet[3], 5,7, pdu_header->transaction_seq_num_len); int32_t source_id_location = PACKET_STATIC_HEADER_LEN; int error = copy_id_to_packet(&packet[source_id_location], pdu_header->source_id, pdu_header->length_of_entity_IDs); @@ -132,8 +159,9 @@ int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_ ssp_error("failed copy source_id"); return -1; } + int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; - error = copy_id_to_packet(&packet[transaction_number_location], pdu_header->source_id, pdu_header->length_of_entity_IDs); + error = copy_id_to_packet(&packet[transaction_number_location], (uint32_t) transaction_sequence_number, pdu_header->transaction_seq_num_len); if (error < 0) { ssp_error("failed copy transaction_number_location"); return -1; @@ -168,6 +196,29 @@ uint8_t build_finished_pdu(char *packet, uint32_t start) { set_packet_header(packet, data_len, DIRECTIVE); return data_len; } +/* +typedef struct pdu_meta_data { + //0 Record boundaries respeced (read as array of octets), 1 not respected (variable length) + unsigned int segmentation_control : 1; + + unsigned int reserved_bits: 7; + + //length of the file in octets, set all 0 for unbounded size + uint32_t file_size; + LV source_file_name; + LV destination_file_name; + + + //Options include: + // Filestore requests, + // Messages to user. + // Fault Handler overrides. + // Flow Label. + + TLV *options; + +} Pdu_meta_data; +*/ //returns packet_index for data, to get length of meta data, subtract start from return value uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { @@ -175,29 +226,24 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { uint8_t packet_index = start; //set directive 1 byte - Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; - directive->directive_code = META_DATA_PDU; + set_packet_directive(packet, packet_index, META_DATA_PDU); packet_index += SIZE_OF_DIRECTIVE_CODE; - Pdu_meta_data *meta_data_packet = (Pdu_meta_data *) &packet[packet_index]; - - //1 bytes - meta_data_packet->segmentation_control = req->segmentation_control; - meta_data_packet->reserved_bits = 0; + //Set segmentation_control bit and 7 reserved bits (to 0) + set_bits_to_protocol_byte(&packet[packet_index], 0, 0, req->segmentation_control); packet_index++; //4 bytes uint32_t network_bytes = ssp_htonl(req->file_size); - network_bytes = network_bytes; memcpy(&packet[packet_index], &network_bytes, sizeof(uint32_t)); packet_index += 4; - + //variable length params uint8_t src_file_name_length = strnlen(req->source_file_name, MAX_PATH); uint8_t destination_file_length = strnlen(req->destination_file_name, MAX_PATH); - + //copy source length to packet (1 bytes) - memcpy(&packet[packet_index], &src_file_name_length, src_file_name_length); + memcpy(&packet[packet_index], &src_file_name_length, 1); packet_index++; //copy source name to packet (length bytes) memcpy(&packet[packet_index], req->source_file_name, src_file_name_length); @@ -205,7 +251,6 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { //copy length to packet (1 byte) memcpy(&packet[packet_index], &destination_file_length, 1); packet_index++; - //copy destination name to packet (length bytes) memcpy(&packet[packet_index], req->destination_file_name, destination_file_length); packet_index += destination_file_length; @@ -402,12 +447,15 @@ uint8_t build_nak_directive(char *packet, uint32_t start, uint8_t directive) { } void set_data_length(char*packet, uint16_t data_len){ - packet[2] = ssp_htons(data_len); + uint16_t bytes = ssp_htons(data_len); + memcpy(&packet[1], &bytes, sizeof(uint16_t)); } uint16_t get_data_length(char*packet) { - Pdu_header *header = (Pdu_header*) packet; - return ntohs(header->PDU_data_field_len); + uint16_t bytes = 0; + memcpy(&bytes, &packet[1], sizeof(uint16_t)); + uint16_t len = ssp_ntohs(bytes); + return len; } struct packet_callback_params { @@ -527,9 +575,12 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req) { uint32_t packet_index = start; - while (packet_index < data_length - 5) { + char *cfdp = "cfdp"; + uint32_t len = strnlen(cfdp, 5); + + while (packet_index < data_length - len) { - if (strncmp(&packet[packet_index], "cfdp", 5)) + if (strncmp(&packet[packet_index], cfdp, len)) break; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 5b0f4d0..8485d83 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -26,7 +26,7 @@ static void send_ack(Request *req, Response res, unsigned int type){ if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); build_ack(req->buff, start, type); ssp_sendto(res); } @@ -35,7 +35,7 @@ static void send_nak(Request *req, Response res, unsigned int type) { if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); build_nak_directive(req->buff, start, type); ssp_sendto(res); } @@ -128,17 +128,21 @@ static int find_request(void *element, void *args) { /*creates a request struct if there is none for the incomming request based on transaction sequence number or finds the correct request struct and replaces req with the new pointer. Returns the possition in the packet -where the data portion is, returns -1 on fail*/ +where the data portion is, also sets incoming_pdu_header... returns -1 on fail*/ -int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **req, List *request_list, FTP *app) { +int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_header, Response res, Request **req, List *request_list, FTP *app) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; - ssp_print_bits(packet, 10); + ssp_print_bits(packet, 30); Pdu_header header; memset(&header, 0, sizeof(Pdu_header)); int error = get_pdu_header_from_packet(packet, &header); + *incoming_pdu_header = header; + + ssp_print_header(&header); + if (error < 0) { ssp_error("failed to get pdu header, bad formatting"); return -1; @@ -169,7 +173,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); - //if server, create new request + //if server, create new request (can probably move this out of this function) if (found_req == NULL && is_server) { @@ -193,6 +197,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Response res, Request **r } *req = found_req; + return header.reserved_space_for_header; } @@ -227,27 +232,54 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File } -uint32_t fill_request_pdu_metadata(char *meta_data_packet, Request *req_to_fill) { +/* +typedef struct pdu_meta_data { + //0 Record boundaries respeced (read as array of octets), 1 not respected (variable length) + unsigned int segmentation_control : 1; + + unsigned int reserved_bits: 7; + + //length of the file in octets, set all 0 for unbounded size + uint32_t file_size; + LV source_file_name; + LV destination_file_name; + + + //Options include: + // Filestore requests, + // Messages to user. + // Fault Handler overrides. + // Flow Label. + + TLV *options; + +} Pdu_meta_data; +*/ +uint32_t parse_metadata_packet(char *packet, uint32_t start, Request *req_to_fill) { - Pdu_meta_data *meta_data = (Pdu_meta_data *) meta_data_packet; - req_to_fill->segmentation_control = meta_data->segmentation_control; + + memset(req_to_fill->source_file_name, 0, MAX_PATH); + memset(req_to_fill->destination_file_name, 0, MAX_PATH); + + req_to_fill->segmentation_control = get_bits_from_protocol_byte(packet[start], 0, 0); + uint8_t packet_index = start + 1; - uint8_t packet_index = 1; - uint32_t *network_bytes = (uint32_t*) &meta_data_packet[packet_index]; - uint32_t file_size = ssp_ntohl(*network_bytes); + uint32_t file_len = 0; + memcpy(&file_len, &packet[packet_index], 4); - req_to_fill->file_size = file_size; + req_to_fill->file_size = ssp_ntohl(file_len); packet_index += 4; - uint8_t file_name_len = meta_data_packet[packet_index]; + uint8_t file_name_len = packet[packet_index]; packet_index++; - ssp_memcpy(req_to_fill->source_file_name, &meta_data_packet[packet_index], file_name_len); + ssp_memcpy(req_to_fill->source_file_name, &packet[packet_index], file_name_len); packet_index += file_name_len; - file_name_len = meta_data_packet[packet_index]; + file_name_len = packet[packet_index]; packet_index++; - ssp_memcpy(req_to_fill->destination_file_name, &meta_data_packet[packet_index], file_name_len); + + ssp_memcpy(req_to_fill->destination_file_name, &packet[packet_index], file_name_len); packet_index += file_name_len; @@ -326,15 +358,16 @@ static void resend_finished_ack(Request *req, Response res) { static void send_put_metadata(Request *req, Response res) { - uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, &req->pdu_header); + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); start = build_put_packet_metadata(req->buff, start, req); + req->local_entity.Metadata_sent_indication = true; ssp_sendto(res); } static void send_eof_pdu(Request *req, Response res) { - uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, &req->pdu_header); + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); if (req->file_size == 0) build_eof_packet(req->buff, start, 0, 0); @@ -358,7 +391,7 @@ static void start_sequence(Request *req, Response res) { } static void send_data(Request *req, Response res) { - uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, &req->pdu_header); + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); if (build_data_packet(req->buff, start, req->file, res.packet_len)) { req->procedure = sending_eof; @@ -379,7 +412,7 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien ssp_printf("req->buff is null\n"); } - uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, &client->pdu_header); + uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, 0, &client->pdu_header); uint32_t offset_start = 0; uint32_t offset_end = 0; int i = 0; @@ -474,25 +507,26 @@ void user_request_handler(Response res, Request *req, Client* client) { return; check_req_status(req); + switch (req->procedure) { case sending_eof: - send_eof_pdu(req, res); + //send_eof_pdu(req, res); req->procedure = none; break; case sending_data: - send_data(req, res); + //send_data(req, res); break; case sending_put_metadata: - send_put_metadata(req, res); + //send_put_metadata(req, res); req->procedure = none; break; case sending_finished: - resend_finished_ack(req, res); + //resend_finished_ack(req, res); req->procedure = none; break; @@ -528,7 +562,7 @@ static void request_metadata(Request *req, Response res) { static void request_data(Request *req, Response res) { - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); build_nak_packet(req->buff, start, req); ssp_sendto(res); @@ -537,7 +571,7 @@ static void request_data(Request *req, Response res) { static void resend_finished_pdu(Request *req, Response res) { - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, &req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); ssp_printf("sending finished pdu transaction: %d\n", req->transaction_sequence_number); build_finished_pdu(req->buff, start); ssp_sendto(res); @@ -588,7 +622,7 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, req->local_entity.Metadata_recv_indication = true; ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); - packet_index += fill_request_pdu_metadata(&packet[packet_index], req); + packet_index += parse_metadata_packet(packet, packet_index, req); uint16_t data_len = get_data_length(packet); get_messages_from_packet(packet, packet_index, data_len, req); @@ -671,17 +705,16 @@ void on_server_time_out(Response res, Request *req) { } //fills the current_request struct for the server, incomming requests -int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, FTP *app) { +int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app) { if (packet_index == 0) return -1; - Pdu_header *header = (Pdu_header *) packet; uint16_t data_len = get_data_length(packet); uint32_t packet_len = packet_index + data_len; //process file data - if (header->PDU_type == 1) { + if (incoming_header.PDU_type == DATA) { if (!req->local_entity.Metadata_recv_indication) { if (req->file == NULL) { ssp_printf("file is null\n"); diff --git a/Program/src/requests.c b/Program/src/requests.c index 8c85f25..8cd271c 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -21,7 +21,7 @@ Author: Evan Giese //returns total space taken up in the packet from the added lv -uint16_t copy_lv_to_buffer(char *buffer, LV lv){ +uint16_t copy_lv_to_buffer(char *buffer, LV lv) { uint16_t packet_index = 0; buffer[packet_index] = lv.length; packet_index++; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index b8999a5..236df0b 100755 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -100,8 +100,10 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, u res.sfd = sfd; res.size_of_addr = size_of_addr; + Pdu_header incoming_pdu_header; Request **request_container = &app->current_request; - int packet_index = process_pdu_header(packet, true, res, request_container, app->request_list, app); + + int packet_index = process_pdu_header(packet, true, &incoming_pdu_header, res, request_container, app->request_list, app); if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; @@ -110,7 +112,7 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, u Request *current_request = (*request_container); app->current_request = current_request; - int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, app); + int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, incoming_pdu_header, app); reset_timeout(¤t_request->timeout_before_cancel); @@ -139,8 +141,9 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u res.packet_len = packet_len; Request **request_container = &client->current_request; - - int packet_index = process_pdu_header(packet, false, res, request_container, client->request_list, client->app); + Pdu_header incoming_pdu_header; + + int packet_index = process_pdu_header(packet, false, &incoming_pdu_header, res, request_container, client->request_list, client->app); if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; @@ -215,7 +218,6 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi res, client }; - client->request_list->iterate(client->request_list, user_request_check, ¶ms); return 0; } @@ -457,6 +459,7 @@ void *ssp_connection_client_task(void *params) { return NULL; } + connection_client(host_name, port, client->packet_len, diff --git a/Program/test/mock.c b/Program/test/mock.c index 61ea0c9..e9636c8 100755 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -47,7 +47,7 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { mock_mock_remote_entity(&remote_entity, dest_id); int error = get_header_from_mib(&pdu_header, remote_entity, src_id); - int packet_index = build_pdu_header(packet, 1, 0, &pdu_header); + int packet_index = build_pdu_header(packet, 1, 0, 0, &pdu_header); return packet_index; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 0b1d8d6..3781740 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -169,9 +169,7 @@ static int test_build_nak_packet(char* packet, uint32_t start) { ASSERT_EQUALS_INT("correct packet offset 3 start", start_scope, 15000); ASSERT_EQUALS_INT("correct packet offset 3 end", end_scope, 100000); - Pdu_header *header = (Pdu_header*) packet; - - ASSERT_EQUALS_INT("correct packet data_len", data_len, ntohs(header->PDU_data_field_len)); + ASSERT_EQUALS_INT("correct packet data_len", data_len, get_data_length(packet)); ssp_cleanup_req(req); return 0; @@ -189,15 +187,19 @@ static int test_build_very_large_nak_packet(char* packet, uint32_t start) { req->file_size = file->total_size; process_file_request_metadata(req); + //fail receiving weird offsets for (int i = 0; i < 10000; i+=10) { receive_offset(file, 0, i, i+10); i++; } uint64_t count = file->missing_offsets->count; - ssp_printf("len %d", count); uint32_t data_len = build_nak_packet(packet, start, req); + ssp_printf("data length%d\n", data_len); + ssp_printf("start%d\n", start); + uint32_t offsets_sent = (data_len - 17) / sizeof(Offset); + ssp_printf("offsets that fit in packet %d\n", offsets_sent); ASSERT_EQUALS_INT("data length of NAK fits in the packet", 1489, data_len); @@ -234,8 +236,8 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { Request *req; uint8_t len = build_ack (packet, start, EOF_PDU); - Pdu_directive *pdu_d = (Pdu_directive *) &packet[start]; - ASSERT_EQUALS_INT("ACK_PDU directive correct", pdu_d->directive_code, ACK_PDU); + uint8_t directive = packet[start]; + ASSERT_EQUALS_INT("ACK_PDU directive correct", directive, ACK_PDU); Pdu_ack *ack = (Pdu_ack *)&packet[start + 1]; ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack->directive_code); @@ -245,24 +247,19 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { return 0; } -int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_number) { +int test_build_pdu_header(char *packet, Pdu_header *header) { - header->PDU_data_field_len = 0; - header->destination_id = 32; - header->source_id = 35; - header->length_of_entity_IDs = 1; - header->transaction_sequence_number = 12; - header->transaction_seq_num_len = 1; - DECLARE_NEW_TEST("testing header creation"); uint32_t packet_index = 0; //ssp_print_bits(header, 4); Pdu_header new_header; + header->transaction_sequence_number = 321; + memset(&new_header, 0, 4); - - uint8_t length = build_pdu_header(packet, sequence_number, 0, header); - + + uint8_t length = build_pdu_header(packet, header->transaction_sequence_number, header->direction, header->PDU_data_field_len, header); + get_pdu_header_from_packet(packet, &new_header); ASSERT_EQUALS_INT("CRC = CRC", header->CRC_flag, new_header.CRC_flag); @@ -279,9 +276,10 @@ int test_build_pdu_header(char *packet, Pdu_header *header, uint64_t sequence_nu ASSERT_EQUALS_INT("packet length: ", length, (header->transaction_seq_num_len + (header->length_of_entity_IDs * 2) + 4)); ASSERT_EQUALS_INT("packet source id ", header->source_id, new_header.source_id); - ASSERT_EQUALS_INT("transaction_sequence_number correctly placed ", header->source_id, new_header.source_id); + + ASSERT_EQUALS_INT("transaction_sequence_number correctly placed ", header->transaction_sequence_number, new_header.transaction_sequence_number); ASSERT_EQUALS_INT("packet destination id ", header->destination_id, new_header.destination_id); - + return length; } @@ -291,23 +289,29 @@ int test_build_metadata_packet(char *packet, uint32_t start) { memset(&packet[start], 0, 20); DECLARE_NEW_TEST("testing metadata packets"); - Request *req = mock_empty_request(); + Request *req = mock_request(); Request *recv_request = mock_empty_request(); + req->file_size = 35; + + ssp_printf("%s\n", req->source_file_name); + uint8_t len = build_put_packet_metadata(packet, start, req); - fill_request_pdu_metadata(&packet[start + 1], recv_request); + parse_metadata_packet(packet, start + SIZE_OF_DIRECTIVE_CODE, recv_request); + + ssp_printf("%s\n", recv_request->source_file_name); + ASSERT_EQUALS_INT("test packet filesize", req->file_size, recv_request->file_size); ASSERT_EQUALS_STR("test src_file_name", req->source_file_name, recv_request->source_file_name, strnlen(req->source_file_name, MAX_PATH)); ASSERT_EQUALS_STR("test dest_file_name", req->destination_file_name, recv_request->destination_file_name, strnlen(req->source_file_name, MAX_PATH)); - - char *str = "HELLO WORLD"; + char *str = "HELLO WORLDSSSSSSSSSSSSSS"; ssp_memcpy(req->destination_file_name, str, strnlen(str, MAX_PATH) ); ssp_memcpy(req->source_file_name, str, strnlen(str, MAX_PATH) ); len = build_put_packet_metadata(packet, start, req); - fill_request_pdu_metadata(&packet[start + 1], recv_request); + parse_metadata_packet(packet, start + SIZE_OF_DIRECTIVE_CODE, recv_request); ASSERT_EQUALS_INT("test packet filesize", req->file_size, recv_request->file_size); ASSERT_EQUALS_STR("test src_file_name", req->source_file_name, recv_request->source_file_name, strnlen(req->source_file_name, MAX_PATH)); @@ -503,35 +507,34 @@ int packet_tests() { char packet[PACKET_TEST_SIZE]; - uint64_t sequence_number = 12345663234; - Pdu_header pdu_header; Remote_entity remote_entity; int error = get_remote_entity_from_json (&remote_entity, 1); get_header_from_mib(&pdu_header, remote_entity, 2); - - - int data_start_index = test_build_pdu_header(packet, &pdu_header, sequence_number); + int data_start_index = test_build_pdu_header(packet, &pdu_header); + test_build_metadata_packet(packet, data_start_index); + /* + test_build_ack_eof_pdu(packet, data_start_index); + test_build_nak_packet(packet, data_start_index); - - //test_build_ack_eof_pdu(packet, data_start_index); - //test_build_nak_packet(packet, data_start_index); + //Skip for now, will fix after connection server works //test_build_very_large_nak_packet(packet, data_start_index); - /* - test_respond_to_naks(packet, data_start_index); + //test_respond_to_naks(packet, data_start_index); memset(packet, 0, PACKET_TEST_SIZE); - + + //need to fix this for byte order test_build_data_packet(packet, data_start_index); - test_build_metadata_packet(packet, data_start_index); + + //need to fix this for byte order test_build_eof_packet(packet, data_start_index); - test_add_messages_to_packet(packet, data_start_index); - test_get_message_from_packet(packet, data_start_index); - test_get_messages_from_packet(packet, data_start_index); - test_add_cont_part_to_packet(packet, data_start_index); + //test_add_messages_to_packet(packet, data_start_index); + //test_get_message_from_packet(packet, data_start_index); + //test_get_messages_from_packet(packet, data_start_index); + //test_add_cont_part_to_packet(packet, data_start_index); */ return 0; diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index ed8e5f5..b3eff62 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -81,8 +81,9 @@ static int test_wrong_id(FTP *app) { int packet_index = mock_packet(packet, 2, 1); Request **req_container = &app->current_request; + Pdu_header incoming_pdu_header; - error = process_pdu_header(packet, true, *res, req_container, app->request_list, app); + error = process_pdu_header(packet, true, &incoming_pdu_header, *res, req_container, app->request_list, app); error = ASSERT_EQUALS_INT("process pdu should error", -1, error); Request *req = (*req_container); @@ -101,7 +102,9 @@ static int test_correct_id(FTP *app) { set_data_length(packet, 100); Request **req_container = &app->current_request; - process_pdu_header(packet, true, *res, req_container, app->request_list, app); + Pdu_header incoming_pdu_header; + + process_pdu_header(packet, true, &incoming_pdu_header,*res, req_container, app->request_list, app); Request *req = (*req_container); error = ASSERT_NOT_NULL("Test request, Request should not be NULL", req); From da197ebcfeb5171143df7e4cb710f637760b8233 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Feb 2021 13:23:35 -0700 Subject: [PATCH 287/400] add new LV functions for big endian ID parsing --- Program/src/packet.c | 88 ++++++++++++++++++++++++++-------- Program/src/protocol_handler.c | 2 +- Program/src/requests.c | 1 + 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 7d14f2a..9750484 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -43,10 +43,14 @@ void set_packet_directive(char *packet, uint32_t location, uint8_t directive){ packet[location] = directive; } -int copy_id_to_packet(char *bytes, uint32_t id, uint32_t length_of_ids) { +//returns length of ids or -1 on error +int copy_id_to_packet(char *bytes, uint64_t id, uint32_t length_of_ids) { - if (length_of_ids == 4) { - uint32_t network_byte_order = ssp_htonl(id); + if (length_of_ids == 8) { + uint64_t network_byte_order = ssp_htonll(id); + memcpy(bytes, &network_byte_order, sizeof(uint64_t)); + } else if (length_of_ids == 4) { + uint32_t network_byte_order = ssp_htonl((uint32_t) id); memcpy(bytes, &network_byte_order, sizeof(uint32_t)); } else if (length_of_ids == 2) { uint16_t network_byte_order = ssp_htons((uint16_t) id); @@ -58,12 +62,15 @@ int copy_id_to_packet(char *bytes, uint32_t id, uint32_t length_of_ids) { ssp_error("id size is not supported, please user 1, 2 or 4"); return -1; } - return 0; + return length_of_ids; } -uint32_t get_id_from_packet(char *bytes, uint32_t length_of_ids) { - uint32_t host_byte_order = 0; - if (length_of_ids == 4) { +//returns id or -1 on error +uint64_t copy_id_from_packet(char *bytes, uint32_t length_of_ids) { + uint64_t host_byte_order = 0; + if (length_of_ids == 8) { + host_byte_order = ssp_ntohll(*(uint64_t*) bytes); + }else if (length_of_ids == 4) { host_byte_order = ssp_ntohl(*(uint32_t*) bytes); } else if (length_of_ids == 2) { host_byte_order = ssp_ntohs(*(uint16_t*) bytes); @@ -76,6 +83,33 @@ uint32_t get_id_from_packet(char *bytes, uint32_t length_of_ids) { return host_byte_order; } +//returns amount of bytes written or -1 on error +int copy_id_lv_to_packet(char *bytes, LV id) { + + memcpy(bytes, &id.length, sizeof(uint8_t)); + int len = copy_id_to_packet(&bytes[1], *(uint64_t*)id.value, id.length); + if (len < 0) { + return -1; + } + return len + 1; +} + +//returns 0 on success and sets LV memory, or -1 on error +int copy_id_lv_from_packet(char *bytes, LV *lv){ + + uint8_t len = 0; + memcpy(&len, bytes, sizeof(uint8_t)); + + uint64_t id = copy_id_from_packet(&bytes[1], len); + if (id < 0) { + ssp_printf("failed to copy id from packet %d\n", id); + return -1; + } + create_lv(lv, len, &id); + return 0; +} + + void ssp_print_header(Pdu_header *pdu_header){ ssp_printf("pdu_header->version %d\n",pdu_header->version); @@ -114,21 +148,21 @@ int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ int32_t source_id_location = PACKET_STATIC_HEADER_LEN; - pdu_header->source_id = get_id_from_packet(&packet[source_id_location], pdu_header->length_of_entity_IDs); + pdu_header->source_id = copy_id_from_packet(&packet[source_id_location], pdu_header->length_of_entity_IDs); if (pdu_header->source_id < 0) { ssp_error("failed to get source_id"); return -1; } int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; - pdu_header->transaction_sequence_number = get_id_from_packet(&packet[transaction_number_location], pdu_header->transaction_seq_num_len); + pdu_header->transaction_sequence_number = copy_id_from_packet(&packet[transaction_number_location], pdu_header->transaction_seq_num_len); if (pdu_header->transaction_sequence_number < 0) { ssp_error("failed to get transaction_sequence_number"); return -1; } int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; - pdu_header->destination_id = get_id_from_packet(&packet[dest_id_location], pdu_header->length_of_entity_IDs); + pdu_header->destination_id = copy_id_from_packet(&packet[dest_id_location], pdu_header->length_of_entity_IDs); if (pdu_header->destination_id < 0) { ssp_error("failed to get destination_id"); return -1; @@ -413,7 +447,7 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { pdu_nak->start_scope = ssp_htonl(start_scope); pdu_nak->end_scope = ssp_htonl(end_scope); - pdu_nak->segment_requests = htonll(holder.current_number_of_segments); + pdu_nak->segment_requests = ssp_htonll(holder.current_number_of_segments); packet_index += sizeof(Offset) * holder.current_number_of_segments; @@ -467,9 +501,12 @@ static void add_messages_callback(Node *node, void *element, void *args) { struct packet_callback_params *params = (struct packet_callback_params *) args; char *packet = params->packet; uint32_t packet_index = *(params->packet_index); - Message *message = (Message *) element; - + int error = 0; + + //since this is a callback functions, we can't return -1, intead we just log + char *error_msg = "there was an issue copying bytes for the put proxy request"; + //5 bytes to copy cfdp\0 into the buffer memcpy(&packet[packet_index], message->header.message_id_cfdp, 5); packet_index += 5; @@ -484,7 +521,13 @@ static void add_messages_callback(Node *node, void *element, void *args) { { case PROXY_PUT_REQUEST: proxy_put = (Message_put_proxy *) message->value; - packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_put->destination_id); + + int bytes = copy_id_lv_to_packet(&packet[packet_index], proxy_put->destination_id); + if (bytes < 0) { + ssp_printf(error_msg); + return; + } + packet_index += bytes; packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_put->source_file_name); packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_put->destination_file_name); break; @@ -517,7 +560,7 @@ uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_ //adds messages from packet into request, returns the location of the next message uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { - if (strncmp(&packet[start], "cfdp", 5)) { + if (strncmp(&packet[start], "cfdp", 5) != 0) { ssp_error("messages are poorly formatted\n"); return 0; } @@ -526,8 +569,8 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { Message_put_proxy *proxy_put; Message_cont_part_request *proxy_cont_part; - uint32_t message_start = start + 6; uint32_t message_type = start + 5; + uint32_t message_start = start + 6; switch (packet[message_type]) { @@ -535,9 +578,17 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { m = create_message(PROXY_PUT_REQUEST); m->value = ssp_alloc(1, sizeof(Message_put_proxy)); + if (m->value == NULL) { + return -1; + } proxy_put = (Message_put_proxy *) m->value; - copy_lv_from_buffer(&proxy_put->destination_id, packet, message_start); + int error = copy_id_lv_from_packet(&packet[message_start], &proxy_put->destination_id); + if (error < 0) { + ssp_free(m->value); + return -1; + } + message_start += proxy_put->destination_id.length + 1; copy_lv_from_buffer(&proxy_put->source_file_name, packet, message_start); @@ -580,10 +631,9 @@ uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_le while (packet_index < data_length - len) { - if (strncmp(&packet[packet_index], cfdp, len)) + if (strncmp(&packet[packet_index], cfdp, len) != 0) break; - packet_index = get_message_from_packet(packet, packet_index, req); } return packet_index; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 8485d83..5b1d391 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -405,7 +405,7 @@ static void send_data(Request *req, Response res) { int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; - uint64_t segments = ntohll(nak->segment_requests); + uint64_t segments = ssp_ntohll(nak->segment_requests); packet_index += 16; if (req->buff == NULL){ diff --git a/Program/src/requests.c b/Program/src/requests.c index 8cd271c..edf9878 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -34,6 +34,7 @@ void free_lv(LV lv) { ssp_free(lv.value); } +//this should return -1 on alloc fail void create_lv(LV *lv, int len, void *value) { lv->value = ssp_alloc(len, sizeof(char)); From d4ac3f9ad23ec167d8dffb3ee70a2725e338427f Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Feb 2021 16:49:43 -0700 Subject: [PATCH 288/400] add propper big endian messages that contain IDs --- Program/include/port.h | 5 +++ Program/include/utils.h | 4 -- Program/src/packet.c | 58 ++++++++++++++++++------ Program/test/packet_tests.c | 86 +++++++++++++++++++++++++++++++----- Program/test/request_tests.c | 10 +++-- 5 files changed, 129 insertions(+), 34 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 710c056..5a67250 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -129,6 +129,11 @@ Author: Evan Giese #define ssp_atol atol #endif + +//https://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c +#define ssp_htonll(x) ((1==ssp_htonl(1)) ? (x) : ((uint64_t)ssp_htonl((x) & 0xFFFFFFFF) << 32) | ssp_htonl((x) >> 32)) +#define ssp_ntohll(x) ((1==ssp_ntohl(1)) ? (x) : ((uint64_t)ssp_ntohl((x) & 0xFFFFFFFF) << 32) | ssp_ntohl((x) >> 32)) + //don't change these in the header file here, if you need to change them //change them in the .c file void ssp_error(char *msg); diff --git a/Program/include/utils.h b/Program/include/utils.h index db0ed38..231b4e4 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -9,10 +9,6 @@ Author: Evan Giese #include "stdint.h" -//https://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c -#define htonll(x) ((1==ssp_htonl(1)) ? (x) : ((uint64_t)ssp_htonl((x) & 0xFFFFFFFF) << 32) | ssp_htonl((x) >> 32)) -#define ntohll(x) ((1==ssp_ntohl(1)) ? (x) : ((uint64_t)ssp_ntohl((x) & 0xFFFFFFFF) << 32) | ssp_ntohl((x) >> 32)) - void ssp_print_hex(char *stuff, int size); void ssp_print_bits(char *stuff, int size); diff --git a/Program/src/packet.c b/Program/src/packet.c index 9750484..0914889 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -502,10 +502,10 @@ static void add_messages_callback(Node *node, void *element, void *args) { char *packet = params->packet; uint32_t packet_index = *(params->packet_index); Message *message = (Message *) element; - int error = 0; + int error, bytes = 0; //since this is a callback functions, we can't return -1, intead we just log - char *error_msg = "there was an issue copying bytes for the put proxy request"; + char *error_msg = "there was an issue copying bytes for the message: %s\n"; //5 bytes to copy cfdp\0 into the buffer memcpy(&packet[packet_index], message->header.message_id_cfdp, 5); @@ -522,9 +522,9 @@ static void add_messages_callback(Node *node, void *element, void *args) { case PROXY_PUT_REQUEST: proxy_put = (Message_put_proxy *) message->value; - int bytes = copy_id_lv_to_packet(&packet[packet_index], proxy_put->destination_id); + bytes = copy_id_lv_to_packet(&packet[packet_index], proxy_put->destination_id); if (bytes < 0) { - ssp_printf(error_msg); + ssp_printf(error_msg, "PROXY_PUT_REQUEST"); return; } packet_index += bytes; @@ -534,9 +534,27 @@ static void add_messages_callback(Node *node, void *element, void *args) { case CONTINUE_PARTIAL: proxy_cont_part = (Message_cont_part_request *) message->value; - packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->destination_id); - packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->originator_id); - packet_index += copy_lv_to_buffer(&packet[packet_index], proxy_cont_part->transaction_id); + + bytes = copy_id_lv_to_packet(&packet[packet_index], proxy_cont_part->destination_id); + if (bytes < 0) { + ssp_printf(error_msg, "CONTINUE_PARTIAL"); + return; + } + packet_index += bytes; + + bytes = copy_id_lv_to_packet(&packet[packet_index], proxy_cont_part->originator_id); + if (bytes < 0) { + ssp_printf(error_msg, "CONTINUE_PARTIAL"); + return; + } + packet_index += bytes; + + bytes = copy_id_lv_to_packet(&packet[packet_index], proxy_cont_part->transaction_id); + if (bytes < 0) { + ssp_printf(error_msg, "CONTINUE_PARTIAL"); + return; + } + packet_index += bytes; break; default: @@ -572,6 +590,7 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { uint32_t message_type = start + 5; uint32_t message_start = start + 6; + int error = 0; switch (packet[message_type]) { case PROXY_PUT_REQUEST: @@ -583,7 +602,7 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { } proxy_put = (Message_put_proxy *) m->value; - int error = copy_id_lv_from_packet(&packet[message_start], &proxy_put->destination_id); + error = copy_id_lv_from_packet(&packet[message_start], &proxy_put->destination_id); if (error < 0) { ssp_free(m->value); return -1; @@ -603,17 +622,28 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { m->value = ssp_alloc(1, sizeof(Message_cont_part_request)); proxy_cont_part = (Message_cont_part_request *) m->value; - - copy_lv_from_buffer(&proxy_cont_part->destination_id, packet, message_start); + + error = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->destination_id); + if (error < 0) { + ssp_free(m->value); + return -1; + } message_start += proxy_cont_part->destination_id.length + 1; - - copy_lv_from_buffer(&proxy_cont_part->originator_id, packet, message_start); + + error = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->originator_id); + if (error < 0) { + ssp_free(m->value); + return -1; + } message_start += proxy_cont_part->originator_id.length + 1; - copy_lv_from_buffer(&proxy_cont_part->transaction_id, packet, message_start); + error = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->transaction_id); + if (error < 0) { + ssp_free(m->value); + return -1; + } message_start += proxy_cont_part->transaction_id.length + 1; - default: break; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 3781740..74b9a66 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -101,7 +101,7 @@ static int test_build_nak_packet(char* packet, uint32_t start) { ASSERT_EQUALS_INT("start offset == 0 ", start_scope, 0); ASSERT_EQUALS_INT("end scope == 100000 ", end_scope, 100000); - uint64_t number_of_segments = ntohll(nak->segment_requests); + uint64_t number_of_segments = ssp_ntohll(nak->segment_requests); ASSERT_EQUALS_INT("number of segments == 1 ", number_of_segments, 1); Offset offset[count]; @@ -122,7 +122,7 @@ static int test_build_nak_packet(char* packet, uint32_t start) { data_len = build_nak_packet(packet, start, req); set_data_length(packet, data_len); - number_of_segments = ntohll(nak->segment_requests); + number_of_segments = ssp_ntohll(nak->segment_requests); ASSERT_EQUALS_INT("number of segments == 4 ", number_of_segments, 4); @@ -320,6 +320,7 @@ int test_build_metadata_packet(char *packet, uint32_t start) { uint16_t data_len = get_data_length(packet); ASSERT_EQUALS_INT("test metadata set data length", data_len, len-start); + ssp_cleanup_req(req); ssp_cleanup_req(recv_request); @@ -342,30 +343,46 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ ASSERT_EQUALS_STR("'cfdp' should be at the start of the message", &packet[start], "cfdp", 5); ASSERT_EQUALS_INT("testing CONTINUE_PARTIAL code", (uint8_t) packet[start + 5], CONTINUE_PARTIAL); - LV dest_id, original_id, transaction_id; packet_index = start + 6; - copy_lv_from_buffer(&dest_id, packet, packet_index); + error = copy_id_lv_from_packet(&packet[packet_index], &dest_id); + if (error < 0) { + ssp_printf("failed to copy contents from buffer \n"); + return -1; + } + ASSERT_EQUALS_INT("dest_id.length", dest_id.length, 1); ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*) (dest_id.value), 1); packet_index += dest_id.length + 1; free_lv(dest_id); - - copy_lv_from_buffer(&original_id, packet, packet_index); + error = copy_id_lv_from_packet(&packet[packet_index], &original_id); + if (error < 0) { + ssp_printf("failed to copy contents from buffer \n"); + return -1; + } + ASSERT_EQUALS_INT("original_id.length", original_id.length, 1); ASSERT_EQUALS_INT("original_id.value", *(uint8_t*)original_id.value, 1); packet_index += original_id.length + 1; free_lv(original_id); - - copy_lv_from_buffer(&transaction_id, packet, packet_index); + error = copy_id_lv_from_packet(&packet[packet_index], &transaction_id); + if (error < 0) { + ssp_printf("failed to copy contents from buffer \n"); + return -1; + } + ASSERT_EQUALS_INT("dest_file.length", transaction_id.length, 1); ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*)transaction_id.value, transaction_id.length); free_lv(transaction_id); - ssp_cleanup_req(req); + + + + + } @@ -421,6 +438,8 @@ int test_get_message_from_packet(char *packet, uint32_t start) { uint32_t id = 2; uint8_t len = 1; + DECLARE_NEW_TEST("testing add_messages_from_packet"); + uint32_t packet_index = start; Request *req = mock_empty_request(); @@ -452,10 +471,48 @@ int test_get_message_from_packet(char *packet, uint32_t start) { } +int test_get_cont_partial_from_packet(char *packet, uint32_t start){ + + DECLARE_NEW_TEST("testing add_message_cont_part_to_packet"); + + uint32_t packet_index = start; + + Request *req = mock_empty_request(); + int error = add_cont_partial_message_to_request(1,1,1,1,1,1,req); + + memset(&packet[start], 0, 100); + add_messages_to_packet(packet, packet_index, req->messages_to_user); + + Request *req2 = mock_empty_request(); + get_message_from_packet(packet, packet_index, req2); + + Message *m = req2->messages_to_user->pop(req2->messages_to_user); + Message_cont_part_request *p_message = (Message_cont_part_request *) m->value; + + + ASSERT_EQUALS_INT("destination_id.length", p_message->destination_id.length, 1); + ASSERT_EQUALS_INT("destination_id.value", *(uint8_t*) (p_message->destination_id.value), 1); + packet_index += p_message->destination_id.length + 1; + free_lv(p_message->destination_id); + + ASSERT_EQUALS_INT("originator_id.length", p_message->originator_id.length, 1); + ASSERT_EQUALS_INT("originator_id.value", *(uint8_t*) (p_message->originator_id.value), 1); + packet_index += p_message->originator_id.length + 1; + free_lv(p_message->originator_id); + + ASSERT_EQUALS_INT("transaction_id.length", p_message->transaction_id.length, 1); + ASSERT_EQUALS_INT("transaction_id.value", *(uint8_t*) (p_message->transaction_id.value), 1); + packet_index += p_message->transaction_id.length + 1; + free_lv(p_message->transaction_id); + +} //test multiple messages int test_get_messages_from_packet(char *packet, uint32_t start) { + + DECLARE_NEW_TEST("testing get_messages_from_packet"); + char *dest = "dest"; char *src = "src"; uint32_t id = 2; @@ -471,7 +528,7 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { uint32_t length_of_message = add_messages_to_packet(packet, start, req->messages_to_user); length_of_message = add_messages_to_packet(packet, length_of_message, req->messages_to_user); length_of_message = add_messages_to_packet(packet, length_of_message, req->messages_to_user); - + Request *req2 = mock_empty_request(); get_messages_from_packet(packet, start, 1000 - start, req2); @@ -489,6 +546,7 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { ASSERT_EQUALS_STR("received proxy messages: dest file", dest, (char *) p_message->destination_file_name.value, p_message->destination_file_name.length); } + ssp_free_message(message); } @@ -514,7 +572,12 @@ int packet_tests() { get_header_from_mib(&pdu_header, remote_entity, 2); int data_start_index = test_build_pdu_header(packet, &pdu_header); - test_build_metadata_packet(packet, data_start_index); + //test_build_metadata_packet(packet, data_start_index); + //test_get_messages_from_packet(packet, data_start_index); + + + test_add_cont_part_to_packet(packet, data_start_index); + test_get_cont_partial_from_packet(packet, data_start_index); /* test_build_ack_eof_pdu(packet, data_start_index); test_build_nak_packet(packet, data_start_index); @@ -533,7 +596,6 @@ int packet_tests() { //test_add_messages_to_packet(packet, data_start_index); //test_get_message_from_packet(packet, data_start_index); - //test_get_messages_from_packet(packet, data_start_index); //test_add_cont_part_to_packet(packet, data_start_index); */ return 0; diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 583e10f..75a6022 100755 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -250,6 +250,8 @@ int request_user_input_tests() { FTP app; void *handler = create_ftp_task(1, &app); + //need to let task initialize first. + sleep(1); put_request(2, "", "", 0, &app); put_request(2, NULL, NULL, 0, &app); (&app)->close = true; @@ -297,19 +299,19 @@ int request_tests() { int error = 0; - /* + error = request_finding_test(); + error = request_user_input_tests(); + /* error = add_proxy_message(); error = test_lv_functions(); error = add_continue_partial_message_test(); error = init_cont_partial_request_test_fail(); error = init_cont_partial_request_test(); - */ - scheduled_requests_test(); schedule_requests_start_test(); - + */ return error; } \ No newline at end of file From 0da5140587239c6c4b2c4e05d0a144b7e03befb9 Mon Sep 17 00:00:00 2001 From: evanGee Date: Mon, 15 Feb 2021 14:55:29 -0700 Subject: [PATCH 289/400] refactor 'ack' packet --- Program/src/packet.c | 47 ++++++++++++++++++++++++++++++---- Program/src/protocol_handler.c | 6 +++-- Program/test/packet_tests.c | 31 ++++++++++++---------- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 0914889..7bc089b 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -457,15 +457,52 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { return data_len; } +/* + +typedef struct pdu_ack { + //Directive code of the acknowledged PDU. + unsigned int directive_code : 4; + + //Values depend on directive code. For ACK of Finished PDU: binary ‘0000’ + //if Finished PDU is generated by waypoint, binary ‘0001’ if Finished + //PDU is generated by end system. (NOTE: this discrimination is + //meaningful if the Extended Procedures are implemented.) + //Binary ‘0000’ for ACKs of all other file directives. + + unsigned int directive_subtype_code : 4; + + //Condition code of the acknowledged PDU. + unsigned int condition_code : 4; + unsigned int spare : 2; + + //Status of the transaction in the context of the entity that is issuing the acknowledgment. + unsigned int transaction_status : 2; + +} Pdu_ack; +*/ + +//this function should be called at the buffer location after an ACK_PDU bits were set +void get_ack_from_packet(char *packet, Pdu_ack *ack){ + ack->directive_code = get_bits_from_protocol_byte(packet[0], 0, 3); + ack->directive_subtype_code = get_bits_from_protocol_byte(packet[0], 4, 7); + ack->condition_code = get_bits_from_protocol_byte(packet[1], 0, 3); + ack->spare = get_bits_from_protocol_byte(packet[1], 4, 5); + ack->transaction_status = get_bits_from_protocol_byte(packet[1], 6, 7); +} + uint8_t build_ack(char*packet, uint32_t start, uint8_t type) { + //first byte indicates that its a ACK_PDU packet[start] = ACK_PDU; uint32_t packet_index = start + 1; - Pdu_ack *pdu_ack = (Pdu_ack *) &packet[packet_index]; - pdu_ack->directive_code = type; - pdu_ack->directive_subtype_code = ACK_FINISHED_END; - pdu_ack->condition_code = COND_NO_ERROR; - packet_index += 2; + set_bits_to_protocol_byte(&packet[packet_index], 0, 3, type); + set_bits_to_protocol_byte(&packet[packet_index], 4, 7, ACK_FINISHED_END); + + packet_index += 1; + //will need more/propper conditions + set_bits_to_protocol_byte(&packet[packet_index], 0, 3, COND_NO_ERROR); + + packet_index += 1; uint16_t data_len = packet_index - start; set_packet_header(packet, data_len, DIRECTIVE); return data_len; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 5b1d391..74f2860 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -746,8 +746,10 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque case ACK_PDU: ssp_printf("received Ack transaction: %d\n", req->transaction_sequence_number); - Pdu_ack* ack_packet = (Pdu_ack *) &packet[packet_index]; - switch (ack_packet->directive_code) + Pdu_ack ack_packet; + get_ack_from_packet(&packet[packet_index], &ack_packet); + + switch (ack_packet.directive_code) { case FINISHED_PDU: diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 74b9a66..f81ef42 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -234,15 +234,20 @@ int test_build_ack_eof_pdu(char *packet, uint32_t start) { DECLARE_NEW_TEST("testing eof ack packet"); Request *req; - uint8_t len = build_ack (packet, start, EOF_PDU); + memset(&packet[start], 0, 10); + + uint8_t len = build_ack(packet, start, EOF_PDU); uint8_t directive = packet[start]; ASSERT_EQUALS_INT("ACK_PDU directive correct", directive, ACK_PDU); + uint32_t packet_index = start + 1; - Pdu_ack *ack = (Pdu_ack *)&packet[start + 1]; - ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack->directive_code); - ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack->condition_code); - ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack->directive_subtype_code, ACK_FINISHED_END); + Pdu_ack ack; + get_ack_from_packet(&packet[packet_index], &ack); + + ASSERT_EQUALS_INT("EOF_PDU directive correct", EOF_PDU, ack.directive_code); + ASSERT_EQUALS_INT("COND_NO_ERROR correct", COND_NO_ERROR, ack.condition_code); + ASSERT_EQUALS_INT("ACK_FINISHED_END correct", ack.directive_subtype_code, ACK_FINISHED_END); return 0; } @@ -574,13 +579,11 @@ int packet_tests() { int data_start_index = test_build_pdu_header(packet, &pdu_header); //test_build_metadata_packet(packet, data_start_index); //test_get_messages_from_packet(packet, data_start_index); - - - test_add_cont_part_to_packet(packet, data_start_index); - test_get_cont_partial_from_packet(packet, data_start_index); - /* + //test_add_cont_part_to_packet(packet, data_start_index); + //test_get_cont_partial_from_packet(packet, data_start_index); + test_build_ack_eof_pdu(packet, data_start_index); - test_build_nak_packet(packet, data_start_index); + //test_build_nak_packet(packet, data_start_index); //Skip for now, will fix after connection server works //test_build_very_large_nak_packet(packet, data_start_index); @@ -589,15 +592,15 @@ int packet_tests() { memset(packet, 0, PACKET_TEST_SIZE); //need to fix this for byte order - test_build_data_packet(packet, data_start_index); + //test_build_data_packet(packet, data_start_index); //need to fix this for byte order - test_build_eof_packet(packet, data_start_index); + //test_build_eof_packet(packet, data_start_index); //test_add_messages_to_packet(packet, data_start_index); //test_get_message_from_packet(packet, data_start_index); //test_add_cont_part_to_packet(packet, data_start_index); - */ + return 0; } From 8bfdbf285f36a3eea29a8a4c5faf400cdc27b3b7 Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 17 Feb 2021 17:52:04 -0700 Subject: [PATCH 290/400] refactor eof packet --- Program/src/packet.c | 69 ++++++++++++++++++++++++++-------- Program/src/protocol_handler.c | 25 ++++++------ Program/test/packet_tests.c | 28 +++++++++----- 3 files changed, 84 insertions(+), 38 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 7bc089b..05ee176 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -366,34 +366,73 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len return 0; } +/* +typedef struct pdu_eof { + unsigned int condition_code : 4; + unsigned int spare : 4; + uint32_t checksum; -void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t checksum) { + //In octets. This value shall be the total number of file data octets + //transmitted by the sender, regardless of the condition code + //(i.e., it shall be supplied even if the condition code is other than + //‘No error’). + uint32_t file_size; - Pdu_header *header = (Pdu_header *) packet; - //set header to file directive 0 is directive, 1 is data - header->PDU_type = 0; - uint8_t packet_index = (uint8_t) start; - Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; - directive->directive_code = EOF_PDU; + //Omitted if condition code is ‘No error’. Otherwise, entity ID in the + //TLV is the ID of the entity at which transaction cancellation was + //initiated. + TLV fault_location; + +} Pdu_eof; +*/ +void get_eof_from_packet(char *packet, Pdu_eof *eof){ + uint32_t packet_index = 0; + uint32_t filesize = 0; + uint32_t checksum = 0; + + eof->condition_code = get_bits_from_protocol_byte(packet[packet_index], 0, 3); + eof->spare = get_bits_from_protocol_byte(packet[packet_index], 4, 7); + packet_index++; + memcpy(&filesize, &packet[packet_index], sizeof(uint32_t)); + eof->file_size = ssp_ntohl(filesize); + + packet_index += sizeof(uint32_t); + memcpy(&checksum, &packet[packet_index], sizeof(uint32_t)); + eof->checksum = ssp_ntohl(checksum); + + //todo add fault location parsing +} + +void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t checksum) { + + uint8_t packet_index = start; - Pdu_eof *eof_packet = (Pdu_eof *) &packet[packet_index]; + //set directive 1 byte + set_packet_directive(packet, packet_index, EOF_PDU); + packet_index += SIZE_OF_DIRECTIVE_CODE; //this will be need to set from the req struct probably. - //4 bits, - eof_packet->condition_code = COND_NO_ERROR; + set_bits_to_protocol_byte(&packet[packet_index], 0, 3, COND_NO_ERROR); + //4 bits reserved bits - eof_packet->spare = 0; + set_bits_to_protocol_byte(&packet[packet_index], 4, 7, 0); + packet_index++; //4 bytes - eof_packet->file_size = ssp_ntohl(file_size); - packet_index += 4; - eof_packet->checksum = checksum; - packet_index += 4; + uint32_t network_file_size = ssp_htonl(file_size); + memcpy(&packet[packet_index], &network_file_size, sizeof(uint32_t)); + packet_index += sizeof(uint32_t); + + //4 bytes + uint32_t network_checksum = ssp_htonl(checksum); + memcpy(&packet[packet_index], &network_checksum, sizeof(uint32_t)); + packet_index += sizeof(uint32_t); //TODO addTLV fault_location + uint16_t data_len = packet_index - start; set_packet_header(packet, data_len, DIRECTIVE); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 74f2860..62c695e 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -133,16 +133,13 @@ where the data portion is, also sets incoming_pdu_header... returns -1 on fail*/ int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_header, Response res, Request **req, List *request_list, FTP *app) { uint8_t packet_index = PACKET_STATIC_HEADER_LEN; - ssp_print_bits(packet, 30); - + Pdu_header header; memset(&header, 0, sizeof(Pdu_header)); int error = get_pdu_header_from_packet(packet, &header); *incoming_pdu_header = header; - ssp_print_header(&header); - if (error < 0) { ssp_error("failed to get pdu header, bad formatting"); return -1; @@ -512,21 +509,21 @@ void user_request_handler(Response res, Request *req, Client* client) { switch (req->procedure) { case sending_eof: - //send_eof_pdu(req, res); + send_eof_pdu(req, res); req->procedure = none; break; case sending_data: - //send_data(req, res); + send_data(req, res); break; case sending_put_metadata: - //send_put_metadata(req, res); + send_put_metadata(req, res); req->procedure = none; break; case sending_finished: - //resend_finished_ack(req, res); + resend_finished_ack(req, res); req->procedure = none; break; @@ -582,18 +579,18 @@ static void resend_finished_pdu(Request *req, Response res) { //processes the eof packet, sets checksum, indication, and filesize. void process_pdu_eof(char *packet, Request *req, Response res) { - ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); - Pdu_eof *eof_packet = (Pdu_eof *) packet; - uint32_t file_size = ssp_ntohl(eof_packet->file_size); + Pdu_eof eof_packet; + get_eof_from_packet(packet, &eof_packet); + if (req->file == NULL && req->local_entity.Metadata_recv_indication) { - build_temperary_file(req, file_size); + build_temperary_file(req, eof_packet.file_size); } req->local_entity.EOF_recv_indication = 1; - req->file->eof_checksum = eof_packet->checksum; - req->file->total_size = file_size; + req->file->eof_checksum = eof_packet.checksum; + req->file->total_size = eof_packet.file_size; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index f81ef42..45d0c30 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -24,18 +24,27 @@ static int test_build_eof_packet(char *packet, int packet_start) { //need to set partialcheckus to checksum, because it gets set from reading in data file->partial_checksum = check_sum_file(file, 1000); + memset(&packet[packet_start], 0, 10); + + file->partial_checksum = 1231251; + file->total_size = 141254; build_eof_packet(packet, packet_start, file->total_size, file->partial_checksum); int packet_index = packet_start; - Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; - directive->directive_code = EOF_PDU; + + uint8_t directive = packet[packet_index]; + ASSERT_EQUALS_INT("EOF_PDU directive correct", directive, EOF_PDU); + packet_index++; - Pdu_eof *eof_pdu = (Pdu_eof*) &packet[packet_index]; - ASSERT_EQUALS_INT("condition_code should equal NO_ERROR", eof_pdu->condition_code, COND_NO_ERROR); - ASSERT_EQUALS_INT("filesize should equal", ssp_htonl(eof_pdu->file_size), file->total_size); - ASSERT_EQUALS_INT("checksum should equal", eof_pdu->checksum, file->partial_checksum); + Pdu_eof eof; + + get_eof_from_packet(&packet[packet_index], &eof); + + ASSERT_EQUALS_INT("condition_code should equal COND_NO_ERROR", eof.condition_code, COND_NO_ERROR); + ASSERT_EQUALS_INT("filesize should equal", eof.file_size, file->total_size); + ASSERT_EQUALS_INT("checksum should equal", eof.checksum, file->partial_checksum); free_file(file); @@ -581,8 +590,9 @@ int packet_tests() { //test_get_messages_from_packet(packet, data_start_index); //test_add_cont_part_to_packet(packet, data_start_index); //test_get_cont_partial_from_packet(packet, data_start_index); - - test_build_ack_eof_pdu(packet, data_start_index); + //test_build_ack_eof_pdu(packet, data_start_index); + + test_build_eof_packet(packet, data_start_index); //test_build_nak_packet(packet, data_start_index); //Skip for now, will fix after connection server works @@ -595,7 +605,7 @@ int packet_tests() { //test_build_data_packet(packet, data_start_index); //need to fix this for byte order - //test_build_eof_packet(packet, data_start_index); + //test_add_messages_to_packet(packet, data_start_index); //test_get_message_from_packet(packet, data_start_index); From a3226ca2f4be12c4deecd9407e8e3328239338a8 Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 17 Feb 2021 19:38:54 -0700 Subject: [PATCH 291/400] refactor data_packet, need to write parse_data_packet unit test --- Program/include/packet.h | 9 +++++++- Program/include/protocol_handler.h | 1 - Program/src/packet.c | 37 ++++++++++++++++++++++-------- Program/src/protocol_handler.c | 17 ++++++++------ Program/test/packet_tests.c | 10 +++++--- 5 files changed, 53 insertions(+), 21 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index f1a03e4..33f9504 100755 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -18,9 +18,13 @@ int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_ uint8_t build_finished_pdu(char *packet, uint32_t start); uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); -uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); + +uint32_t get_data_offset_from_packet(packet); +int build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t checksum); +void get_eof_from_packet(char *packet, Pdu_eof *eof); + void fill_nak_array_callback(Node *node, void *element, void *args); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); uint8_t build_ack(char*packet, uint32_t start, uint8_t type); @@ -33,4 +37,7 @@ void ssp_print_header(Pdu_header *pdu_header); uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req); uint32_t get_messages_from_packet(char *packet, uint32_t start, uint32_t data_length, Request *req); uint32_t add_messages_to_packet(char *packet, uint32_t start, List *messages_to_user); +void get_ack_from_packet(char *packet, Pdu_ack *ack); + + #endif diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 9626c28..d7a9e99 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -19,7 +19,6 @@ void parse_packet_client(char* buff, uint32_t packet_index, Response res, Reques void on_server_time_out(Response res, Request *current_request); int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_header, Response res, Request **req, List *request_list, FTP *app); -uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); void process_pdu_eof(char *packet, Request *req, Response res); Request *new_incomming_request(uint32_t source_id, diff --git a/Program/src/packet.c b/Program/src/packet.c index 05ee176..e12ab6d 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -327,20 +327,39 @@ uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Reques } -//requires a req->file to be created -//returns 1 on end of file -//length is the total size of the packet -uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { +/* +typedef struct file_data_pdu_contents { + //in octets + uint32_t offset; + //variable sized + unsigned char *data; +} File_data_pdu_contents; +*/ + +//returns the offset in the file (for the data packet) +uint32_t get_data_offset_from_packet(char *packet) { + uint32_t offset = 0; + memcpy(&offset, packet, sizeof(uint32_t)); + + offset = ssp_ntohl(offset); + return offset; +} + +int build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { + + //don't accidently send more than file size, this can probably be outside this packet if (file->next_offset_to_send >= file->total_size){ return 0; } uint16_t packet_index = start; - File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; + + uint32_t offset = 0; + offset = ssp_htonl(file->next_offset_to_send); + + memcpy(&packet[packet_index], &offset, sizeof(uint32_t)); - //4 bytes is the size of the offset paramater - packet_offset->offset = file->next_offset_to_send; packet_index += 4; uint16_t data_size = length - packet_index; @@ -349,17 +368,17 @@ uint8_t build_data_packet(char *packet, uint32_t start, File *file, uint32_t len int bytes = get_offset(file, &packet[packet_index], data_size, file->next_offset_to_send); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); - return 1; + return -1; } //calculate checksum for data packet, this is used to calculate in transit checksums file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); file->next_offset_to_send += bytes; - //add bytes read, and the packet offset to the data_field length uint16_t data_len = bytes + 4; set_packet_header(packet, data_len, DATA); + if (bytes < data_size) return 1; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 62c695e..d7ce0de 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -199,7 +199,8 @@ int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_ } -static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File *file) { +//rename to process_data_packet +static void process_data_packet(char *packet, uint32_t data_len, File *file) { if(file == NULL) { @@ -207,21 +208,23 @@ static void write_packet_data_to_file(char *data_packet, uint32_t data_len, File return; } - File_data_pdu_contents *packet = (File_data_pdu_contents *)data_packet; + uint32_t offset_start = get_data_offset_from_packet(packet); + uint32_t packet_index = 4; - uint32_t offset_start = packet->offset; - uint32_t offset_end = offset_start + data_len - 4; + //- size of 'offset' bytes in packet + uint32_t offset_end = offset_start + data_len - packet_index; if (!receive_offset(file, 0, offset_start, offset_end)) return; - int bytes = write_offset(file, &data_packet[4], data_len - 4, offset_start); + uint32_t remaining_buffer_length = data_len - packet_index; + int bytes = write_offset(file, &packet[packet_index], remaining_buffer_length, offset_start); if (bytes <= 0) { ssp_error("no new data was written\n"); return; } - file->partial_checksum += calc_check_sum(&data_packet[4], bytes); + file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); if (file->missing_offsets->count == 0) return; @@ -718,7 +721,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque build_temperary_file(req, TEMP_FILESIZE); } } - write_packet_data_to_file(&packet[packet_index], data_len, req->file); + process_data_packet(&packet[packet_index], data_len, req->file); ssp_printf("received data packet transaction: %d\n", req->transaction_sequence_number); return packet_len; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 45d0c30..29761b2 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -72,7 +72,9 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ build_data_packet(packet, packet_index, file, 1000); - ASSERT_EQUALS_INT("test proper datapacket offset set", (uint64_t)packet[packet_index], 0); + uint32_t offset = get_data_offset_from_packet(&packet[packet_index]); + + ASSERT_EQUALS_INT("test proper datapacket offset set", offset, 0); ASSERT_EQUALS_STR("test proper datapacket creation", &packet[packet_index + 4], "testfileyo", 10); free_file(file); @@ -592,7 +594,10 @@ int packet_tests() { //test_get_cont_partial_from_packet(packet, data_start_index); //test_build_ack_eof_pdu(packet, data_start_index); - test_build_eof_packet(packet, data_start_index); + //test_build_eof_packet(packet, data_start_index); + //test_build_data_packet(packet, data_start_index); + + //next up //test_build_nak_packet(packet, data_start_index); //Skip for now, will fix after connection server works @@ -602,7 +607,6 @@ int packet_tests() { memset(packet, 0, PACKET_TEST_SIZE); //need to fix this for byte order - //test_build_data_packet(packet, data_start_index); //need to fix this for byte order From ce853280d7c4378aae00bdc6bd22d40f2c891548 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 18 Feb 2021 19:24:19 -0700 Subject: [PATCH 292/400] add process_data_packet test --- Program/include/filesystem_funcs.h | 4 ++- Program/include/packet.h | 2 +- Program/include/protocol_handler.h | 1 + Program/src/filesystem_funcs.c | 2 +- Program/src/protocol_handler.c | 9 +++--- Program/src/requests.c | 2 +- Program/test/packet_tests.c | 5 ++-- Program/test/protocol_handler_tests.c | 40 +++++++++++++++++++++++++-- 8 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index e8714eb..47450d5 100755 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -15,11 +15,13 @@ struct params { int fd; }; + uint32_t get_file_size(char *source_file_name); //allocates space for a file pointer File *create_file(char *source_file_name, int clear_file_contents); -void free_file(void *file); +void ssp_free_file(void *file); + int does_file_exist(char *source_file_name); int get_offset(File *file, void *buff, uint32_t buf_size, int offset); int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); diff --git a/Program/include/packet.h b/Program/include/packet.h index 33f9504..0faae05 100755 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -19,7 +19,7 @@ uint8_t build_finished_pdu(char *packet, uint32_t start); uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); -uint32_t get_data_offset_from_packet(packet); +uint32_t get_data_offset_from_packet(char *packet); int build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t checksum); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index d7a9e99..9bbf5f8 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -29,6 +29,7 @@ void process_pdu_eof(char *packet, Request *req, Response res); uint32_t parse_metadata_packet(char *meta_data_packet, uint32_t start, Request *req_to_fill); void process_messages(Request *req, FTP *app); +void process_data_packet(char *packet, uint32_t data_len, File *file); uint8_t build_ack (char *packet, uint32_t start, uint8_t type); int process_file_request_metadata(Request *req); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index ff2d9f6..7f50d1a 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -126,7 +126,7 @@ int write_offset(File *file, void *buff, uint32_t size, uint32_t offset) { return bytes; } -void free_file(void *file) { +void ssp_free_file(void *file) { File *f = (File *) file; f->missing_offsets->free(f->missing_offsets, ssp_free); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index d7ce0de..cfc398b 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -199,9 +199,10 @@ int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_ } -//rename to process_data_packet -static void process_data_packet(char *packet, uint32_t data_len, File *file) { - +// receives the offset +// writes offset to a file +// calclulates checksum +void process_data_packet(char *packet, uint32_t data_len, File *file) { if(file == NULL) { ssp_error("file struct is null, can't write to file"); @@ -211,7 +212,7 @@ static void process_data_packet(char *packet, uint32_t data_len, File *file) { uint32_t offset_start = get_data_offset_from_packet(packet); uint32_t packet_index = 4; - //- size of 'offset' bytes in packet + // size of 'offset' bytes in packet uint32_t offset_end = offset_start + data_len - packet_index; if (!receive_offset(file, 0, offset_start, offset_end)) diff --git a/Program/src/requests.c b/Program/src/requests.c index edf9878..1c973aa 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -264,7 +264,7 @@ void ssp_cleanup_req(void *request) { Request *req = (Request *) request; if (req->file != NULL) - free_file(req->file); + ssp_free_file(req->file); if (req->messages_to_user->count > 0) req->messages_to_user->free(req->messages_to_user, ssp_free_message); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 29761b2..a4890d5 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -5,6 +5,7 @@ #include "utils.h" #include #include "filesystem_funcs.h" + #include "port.h" #include "protocol_handler.h" #include "mib.h" @@ -46,7 +47,7 @@ static int test_build_eof_packet(char *packet, int packet_start) { ASSERT_EQUALS_INT("filesize should equal", eof.file_size, file->total_size); ASSERT_EQUALS_INT("checksum should equal", eof.checksum, file->partial_checksum); - free_file(file); + ssp_free_file(file); //testing this return 0; @@ -77,7 +78,7 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ ASSERT_EQUALS_INT("test proper datapacket offset set", offset, 0); ASSERT_EQUALS_STR("test proper datapacket creation", &packet[packet_index + 4], "testfileyo", 10); - free_file(file); + ssp_free_file(file); } diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index b3eff62..d29f862 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -132,12 +132,46 @@ static int test_process_pdu_header() { return error; } +int test_process_data_packet() { + + char packet[1500]; + uint32_t start = 20; + uint32_t data_len = sizeof(packet) - start; + memset(packet, 0, 1500); + + File *file = create_file("test_files/dest.jpg", 0); + int error = build_data_packet(packet, start, file, data_len); + + File *file2 = create_file("test_files/test_file.jpg", 1); + + //mimics process_file_request_metadata function + Offset *offset = ssp_alloc(1, sizeof(Offset)); + offset->end = file->total_size; + offset->start = 0; + file2->missing_offsets->push(file2->missing_offsets, offset, 0); + + process_data_packet(&packet[start], data_len, file2); + ASSERT_EQUALS_INT("Checksum", file2->partial_checksum, 1439747840); + ASSERT_EQUALS_INT("Length of offset list should equal 1 ", file2->missing_offsets->count, 1); + Offset* offset2 = (Offset*) file2->missing_offsets->pop(file2->missing_offsets); + + + //data_len - 4 byte offset value + ASSERT_EQUALS_INT("offset start should equal datasize ", offset2->start, data_len - 4); + ASSERT_EQUALS_INT("offset end equal end of file ", offset2->end, file->total_size); + + ssp_free_file(file); + ssp_free_file(file2); + +} int protocol_handler_test() { int error = 0; - error = test_process_pdu_header(); - error = test_process_pdu_eof(); - error = test_on_server_time_out(); + //error = test_process_pdu_header(); + //error = test_process_pdu_eof(); + //error = test_on_server_time_out(); + error = test_process_data_packet(); + return error; } \ No newline at end of file From 432d9c0cdc65d354d0ea11314582782eacbf29ef Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 19 Feb 2021 20:22:09 -0700 Subject: [PATCH 293/400] decouple data_packet and change endianess of NAKS --- Program/include/packet.h | 2 +- Program/include/protocol_handler.h | 2 + Program/src/packet.c | 106 ++++++++++++-------------- Program/src/protocol_handler.c | 25 +++++- Program/test/packet_tests.c | 14 ++-- Program/test/protocol_handler_tests.c | 2 +- 6 files changed, 85 insertions(+), 66 deletions(-) diff --git a/Program/include/packet.h b/Program/include/packet.h index 0faae05..2776e16 100755 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -20,8 +20,8 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); uint32_t get_data_offset_from_packet(char *packet); -int build_data_packet(char *packet, uint32_t start, File *file, uint32_t length); +int build_data_packet(char *packet, uint32_t start, uint32_t end, uint32_t offset, File *file); void build_eof_packet(char *packet, uint32_t start, uint32_t file_size, uint32_t checksum); void get_eof_from_packet(char *packet, Pdu_eof *eof); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 9bbf5f8..c65e732 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -30,6 +30,8 @@ void process_pdu_eof(char *packet, Request *req, Response res); uint32_t parse_metadata_packet(char *meta_data_packet, uint32_t start, Request *req_to_fill); void process_messages(Request *req, FTP *app); void process_data_packet(char *packet, uint32_t data_len, File *file); +int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t length); + uint8_t build_ack (char *packet, uint32_t start, uint8_t type); int process_file_request_metadata(Request *req); diff --git a/Program/src/packet.c b/Program/src/packet.c index e12ab6d..6cee98f 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -297,6 +297,36 @@ uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req) { return packet_index; } + +/* +typedef struct file_data_pdu_contents { + //in octets + uint32_t offset; + //variable sized + unsigned char *data; +} File_data_pdu_contents; +*/ +//returns the length of the packet, or -1 on error +int build_data_packet(char *packet, uint32_t start, uint32_t end, uint32_t offset, File *file){ + + uint16_t data_size = end - start; + uint32_t packet_index = start; + + uint32_t net_offset = ssp_ntohl(offset); + memcpy(&packet[packet_index], &net_offset, sizeof(uint32_t)); + packet_index += 4; + int bytes = get_offset(file, &packet[packet_index], data_size, offset); + if (bytes <= 0){ + ssp_error("could not get offset, this could because the file is empty!\n"); + return -1; + } + + uint16_t data_len = bytes + sizeof(uint32_t); + set_packet_header(packet, data_len, DATA); + return data_len; +} + +//sets the offset, datasize, uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { if (offset > req->file->total_size) { @@ -327,16 +357,6 @@ uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Reques } - -/* -typedef struct file_data_pdu_contents { - //in octets - uint32_t offset; - //variable sized - unsigned char *data; -} File_data_pdu_contents; -*/ - //returns the offset in the file (for the data packet) uint32_t get_data_offset_from_packet(char *packet) { uint32_t offset = 0; @@ -346,44 +366,6 @@ uint32_t get_data_offset_from_packet(char *packet) { return offset; } -int build_data_packet(char *packet, uint32_t start, File *file, uint32_t length) { - - //don't accidently send more than file size, this can probably be outside this packet - if (file->next_offset_to_send >= file->total_size){ - return 0; - } - - uint16_t packet_index = start; - - uint32_t offset = 0; - offset = ssp_htonl(file->next_offset_to_send); - - memcpy(&packet[packet_index], &offset, sizeof(uint32_t)); - - packet_index += 4; - - uint16_t data_size = length - packet_index; - - //fill the rest of the packet with data - int bytes = get_offset(file, &packet[packet_index], data_size, file->next_offset_to_send); - if (bytes <= 0){ - ssp_error("could not get offset, this could because the file is empty!\n"); - return -1; - } - - //calculate checksum for data packet, this is used to calculate in transit checksums - file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); - file->next_offset_to_send += bytes; - - //add bytes read, and the packet offset to the data_field length - uint16_t data_len = bytes + 4; - set_packet_header(packet, data_len, DATA); - - if (bytes < data_size) - return 1; - - return 0; -} /* typedef struct pdu_eof { @@ -461,8 +443,6 @@ struct packet_nak_helper { char*packet; uint64_t max_number_of_nak_segments; uint64_t current_number_of_segments; - uint32_t start_scope; - uint32_t end_scope; }; void fill_nak_array_callback(Node *node, void *element, void *args){ @@ -482,31 +462,41 @@ void fill_nak_array_callback(Node *node, void *element, void *args){ holder->packet+=sizeof(Offset); } + +//this function is weird because it uses a callback into an iterator. We fill the array +//with as many 'offsets' as we can. uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet[start] = NAK_PDU; + uint32_t packet_index = start + 1; - Pdu_nak *pdu_nak = (Pdu_nak *) &packet[packet_index]; packet_index += 16; struct packet_nak_helper holder; - holder.max_number_of_nak_segments = (req->buff_len - packet_index) / sizeof(Offset); - holder.packet = &packet[packet_index]; holder.current_number_of_segments = 0; - holder.start_scope = 0; - holder.end_scope = 0; req->file->missing_offsets->iterate(req->file->missing_offsets, fill_nak_array_callback, &holder); uint32_t start_scope = ((Offset *)req->file->missing_offsets->head->next->element)->start; uint32_t end_scope = ((Offset *)req->file->missing_offsets->tail->prev->element)->end; - pdu_nak->start_scope = ssp_htonl(start_scope); - pdu_nak->end_scope = ssp_htonl(end_scope); - pdu_nak->segment_requests = ssp_htonll(holder.current_number_of_segments); + uint32_t net_start_scope = ssp_htonl(start_scope); + uint32_t net_end_scope = ssp_htonl(end_scope); + uint64_t net_segments_number = ssp_htonll(holder.current_number_of_segments); + + packet_index = start + 1; + + memcpy(&packet[packet_index], &net_start_scope, sizeof(uint32_t)); + packet_index += sizeof(uint32_t); + memcpy(&packet[packet_index], &net_end_scope, sizeof(uint32_t)); + packet_index += sizeof(uint32_t); + + memcpy(&packet[packet_index], &net_segments_number, sizeof(uint64_t)); + packet_index += sizeof(uint64_t); + packet_index += sizeof(Offset) * holder.current_number_of_segments; uint16_t data_len = packet_index - start; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index cfc398b..590cac4 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -391,10 +391,33 @@ static void start_sequence(Request *req, Response res) { req->procedure = sending_data; } +int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t length) { + + if (file->next_offset_to_send >= file->total_size){ + return 0; + } + + uint32_t packet_index = start; + uint32_t size_of_offset_bytes = 4; + + int data_len = build_data_packet(packet, packet_index, length, file->next_offset_to_send, file); + packet_index += size_of_offset_bytes; + int bytes = data_len - size_of_offset_bytes; + + //calculate checksum for data packet, this is used to calculate in transit checksums + file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); + file->next_offset_to_send += bytes; + + if (data_len < length - packet_index) + return 1; + + return 0; +} + static void send_data(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); - if (build_data_packet(req->buff, start, req->file, res.packet_len)) { + if (create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { req->procedure = sending_eof; ssp_printf("sending data burst transaction: %d\n", req->transaction_sequence_number); } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index a4890d5..af1d029 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -56,6 +56,9 @@ static int test_build_eof_packet(char *packet, int packet_start) { static int test_respond_to_naks(char *packet, uint32_t packet_index) { Request *req = mock_empty_request(); + + + ssp_cleanup_req(req); return 0; } @@ -71,7 +74,7 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ File *file = create_file("test_files/testfile", 0); - build_data_packet(packet, packet_index, file, 1000); + create_data_burst_packets(packet, packet_index, file, 1000); uint32_t offset = get_data_offset_from_packet(&packet[packet_index]); @@ -596,14 +599,15 @@ int packet_tests() { //test_build_ack_eof_pdu(packet, data_start_index); //test_build_eof_packet(packet, data_start_index); - //test_build_data_packet(packet, data_start_index); - - //next up + test_build_data_packet(packet, data_start_index); //test_build_nak_packet(packet, data_start_index); + + //next up + //Skip for now, will fix after connection server works //test_build_very_large_nak_packet(packet, data_start_index); - //test_respond_to_naks(packet, data_start_index); + test_respond_to_naks(packet, data_start_index); memset(packet, 0, PACKET_TEST_SIZE); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index d29f862..994aa31 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -140,7 +140,7 @@ int test_process_data_packet() { memset(packet, 0, 1500); File *file = create_file("test_files/dest.jpg", 0); - int error = build_data_packet(packet, start, file, data_len); + int error = create_data_burst_packets(packet, start, file, data_len); File *file2 = create_file("test_files/test_file.jpg", 1); From 575b3da113ede15278086c6a5ba9d40bb067ad53 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 20 Feb 2021 20:16:26 -0700 Subject: [PATCH 294/400] Add new nak packet and parsing functions --- Program/include/types.h | 1 + Program/src/packet.c | 41 +++++++++++++++++++++++ Program/src/protocol_handler.c | 60 +++++++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/Program/include/types.h b/Program/include/types.h index 98838ee..c6d0524 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -582,6 +582,7 @@ typedef enum procedure { sending_put_metadata, sending_eof, sending_data, + sending_nak_data, clean_up, sending_start, diff --git a/Program/src/packet.c b/Program/src/packet.c index 6cee98f..df0b7d9 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -327,6 +327,7 @@ int build_data_packet(char *packet, uint32_t start, uint32_t end, uint32_t offse } //sets the offset, datasize, +//outdated uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { if (offset > req->file->total_size) { @@ -463,6 +464,46 @@ void fill_nak_array_callback(Node *node, void *element, void *args){ } +/* +typedef struct pdu_nak { + uint32_t start_scope; + uint32_t end_scope; + + //number of Nak_segments + uint64_t segment_requests; + void *segments; +} Pdu_nak; +*/ +//return length of Nak packet +int get_nak_packet(char *packet, Pdu_nak *nak) { + + + uint32_t packet_index = 0; + uint32_t start_scope = 0; + uint32_t offset_start = 0; + uint32_t offset_end = 0; + + memcpy(&start_scope, &packet[packet_index], sizeof(uint32_t)); + nak->start_scope = ssp_ntohl(start_scope); + + packet_index += sizeof(uint32_t); + + uint32_t end_scope = 0; + memcpy(&end_scope, &packet[packet_index], sizeof(uint32_t)); + nak->end_scope = ssp_ntohl(end_scope); + + packet_index += sizeof(uint32_t); + + uint64_t segment_requests = 0; + memcpy(&segment_requests, &packet[packet_index], sizeof(uint32_t)); + nak->segment_requests = ssp_ntohl(segment_requests); + + packet_index += sizeof(uint64_t); + nak->segments = &packet[packet_index]; + + return packet_index; +} + //this function is weird because it uses a callback into an iterator. We fill the array //with as many 'offsets' as we can. uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 590cac4..dad10e1 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -414,6 +414,52 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t return 0; } + +//returns -1 on error +int process_nak_pdu(char *packet, File *file){ + + Pdu_nak nak; + get_nak_packet(packet, &nak); + + if (file->missing_offsets->count == 0){ + + Offset *offset = ssp_alloc(1, sizeof(Offset)); + if (offset == NULL) { + return -1; + } + + offset->start = nak.start_scope; + offset->end = nak.end_scope; + file->missing_offsets->push(file->missing_offsets, offset, 0); + } + + uint32_t packet_index = 0; + uint32_t offset_start = 0; + uint32_t offset_end = 0; + int completed = 0; + + + int i = 0; + for (i = 0; i < nak.segment_requests; i++){ + packet_index = 0; + + memcpy(&offset_start, &nak.segments[packet_index], sizeof(uint32_t)); + offset_start = ssp_ntohl(offset_start); + packet_index += 4; + + memcpy(&offset_end, &nak.segments[packet_index], sizeof(uint32_t)); + offset_end = ssp_ntohl(offset_end); + packet_index += 4; + + completed = receive_offset(file, 0, offset_start, offset_end); + if (!completed) { + return -1; + } + offset_end = 0; + offset_start = 0; + } +} + static void send_data(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); @@ -425,7 +471,7 @@ static void send_data(Request *req, Response res) { } - +//outdated int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { uint32_t packet_index = start; Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; @@ -457,6 +503,7 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien } + //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { @@ -475,6 +522,14 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ break; case NAK_PDU: ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); + /* + if (process_nak_pdu(packet, req->file) < 0){ + ssp_printf("couldn't process Nak Pdu transaction: %d\n", req->transaction_sequence_number); + break; + } + req->procedure = sending_nak_data; + */ + nak_response(packet, packet_index, req, res, client); break; case ACK_PDU: @@ -535,6 +590,9 @@ void user_request_handler(Response res, Request *req, Client* client) { switch (req->procedure) { + case sending_nak_data: + break; + case sending_eof: send_eof_pdu(req, res); req->procedure = none; From f782e434ed3683ef519cb5ca33d9cc387cafcec2 Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 24 Feb 2021 18:41:33 -0700 Subject: [PATCH 295/400] add client_recv_nak_test --- Program/include/filesystem_funcs.h | 1 + Program/src/filesystem_funcs.c | 19 ++++++++--- Program/src/protocol_handler.c | 36 +++++++++++---------- Program/src/requests.c | 9 +++++- Program/test/mock.c | 7 ++++ Program/test/packet_tests.c | 14 ++------ Program/test/protocol_handler_tests.c | 46 ++++++++++++++++++++++----- 7 files changed, 90 insertions(+), 42 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 47450d5..b8fb0b1 100755 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -21,6 +21,7 @@ uint32_t get_file_size(char *source_file_name); //allocates space for a file pointer File *create_file(char *source_file_name, int clear_file_contents); void ssp_free_file(void *file); +int add_first_offset(File *file, uint32_t file_size); int does_file_exist(char *source_file_name); int get_offset(File *file, void *buff, uint32_t buf_size, int offset); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 7f50d1a..d98d5eb 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -251,16 +251,27 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs } +int add_first_offset(File *file, uint32_t file_size){ + Offset *offset = ssp_alloc(1, sizeof(Offset)); + if (offset == NULL) + return -1; + + offset->end = file_size; + offset->start = 0; + file->missing_offsets->insert(file->missing_offsets, offset, file_size); +} + File *create_temp_file(char *file_name, uint32_t size) { File *file = create_file(file_name, 1); file->is_temp = 1; file->total_size = size; ssp_printf("mode acknowledged, building offset map\n"); - Offset *offset = ssp_alloc(1, sizeof(Offset)); - offset->end = size; - offset->start = 0; - file->missing_offsets->insert(file->missing_offsets, offset, size); + int error = add_first_offset(file, size); + if (error < 0) { + ssp_free_file(file); + return NULL; + } return file; } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index dad10e1..be36ec2 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -416,29 +416,22 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t //returns -1 on error +//adds start and end if there is no start and end (end will likely have to be the file size and start should be 0) int process_nak_pdu(char *packet, File *file){ - Pdu_nak nak; - get_nak_packet(packet, &nak); - if (file->missing_offsets->count == 0){ - - Offset *offset = ssp_alloc(1, sizeof(Offset)); - if (offset == NULL) { - return -1; - } - - offset->start = nak.start_scope; - offset->end = nak.end_scope; - file->missing_offsets->push(file->missing_offsets, offset, 0); + ssp_error("can't receive offset without knowing the file size, please add the first offset with start=0 and end=filesize"); + return -1; } + Pdu_nak nak; + get_nak_packet(packet, &nak); + uint32_t packet_index = 0; uint32_t offset_start = 0; uint32_t offset_end = 0; int completed = 0; - int i = 0; for (i = 0; i < nak.segment_requests; i++){ packet_index = 0; @@ -458,6 +451,7 @@ int process_nak_pdu(char *packet, File *file){ offset_end = 0; offset_start = 0; } + return 1; } static void send_data(Request *req, Response res) { @@ -679,6 +673,8 @@ void process_pdu_eof(char *packet, Request *req, Response res) { } + + int process_file_request_metadata(Request *req) { char temp[75]; @@ -690,11 +686,17 @@ int process_file_request_metadata(Request *req) { change_tempfile_to_actual(temp, req->destination_file_name, req->file_size, req->file); return 1; } + + if (req->file == NULL) { + return -1; + } - Offset *offset = ssp_alloc(1, sizeof(Offset)); - offset->end = req->file_size; - offset->start = 0; - req->file->missing_offsets->insert(req->file->missing_offsets, offset, req->file_size); + int error = add_first_offset(req->file, req->file_size); + if (error < 0) { + ssp_free_file(req->file); + return -1; + } + return 1; } diff --git a/Program/src/requests.c b/Program/src/requests.c index 1c973aa..c4f0c9e 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -378,7 +378,14 @@ int put_request_no_client( req->file = create_file(source_file_name, false); if (req->file == NULL) return -1; - + + //this could probably go into 'create_file' + int error = add_first_offset(req->file, req->file->total_size); + if (error < 0) { + ssp_free_file(req->file); + return NULL; + } + req->file_size = file_size; req->transaction_sequence_number = app->transaction_sequence_number++; ssp_memcpy(req->source_file_name, source_file_name ,strnlen(source_file_name, MAX_PATH)); diff --git a/Program/test/mock.c b/Program/test/mock.c index e9636c8..dcd72f0 100755 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -90,6 +90,13 @@ Request *mock_request() { req->dest_cfdp_id = id; req->file = create_file("test_files/dest_received.jpg", true); + + int error = add_first_offset(req->file, req->file->total_size); + if (error < 0) { + ssp_free_file(req->file); + return NULL; + } + ssp_memcpy (req->source_file_name, dest, strnlen(dest, 255)); ssp_memcpy (req->destination_file_name, src, strnlen(src, 255)); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index af1d029..9e92215 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -53,15 +53,6 @@ static int test_build_eof_packet(char *packet, int packet_start) { return 0; } -static int test_respond_to_naks(char *packet, uint32_t packet_index) { - Request *req = mock_empty_request(); - - - - - ssp_cleanup_req(req); - return 0; -} static int test_respond_metadata_request() { @@ -599,15 +590,14 @@ int packet_tests() { //test_build_ack_eof_pdu(packet, data_start_index); //test_build_eof_packet(packet, data_start_index); - test_build_data_packet(packet, data_start_index); - //test_build_nak_packet(packet, data_start_index); + //test_build_data_packet(packet, data_start_index); + test_build_nak_packet(packet, data_start_index); //next up //Skip for now, will fix after connection server works //test_build_very_large_nak_packet(packet, data_start_index); - test_respond_to_naks(packet, data_start_index); memset(packet, 0, PACKET_TEST_SIZE); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 994aa31..332d1e0 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -139,19 +139,16 @@ int test_process_data_packet() { uint32_t data_len = sizeof(packet) - start; memset(packet, 0, 1500); - File *file = create_file("test_files/dest.jpg", 0); + File *file = create_file("test_files/data_pdu_test.jpg", 0); int error = create_data_burst_packets(packet, start, file, data_len); File *file2 = create_file("test_files/test_file.jpg", 1); //mimics process_file_request_metadata function - Offset *offset = ssp_alloc(1, sizeof(Offset)); - offset->end = file->total_size; - offset->start = 0; - file2->missing_offsets->push(file2->missing_offsets, offset, 0); - + add_first_offset(file2, file->total_size); process_data_packet(&packet[start], data_len, file2); - ASSERT_EQUALS_INT("Checksum", file2->partial_checksum, 1439747840); + + ASSERT_EQUALS_INT("Checksum", file2->partial_checksum, -606714363); ASSERT_EQUALS_INT("Length of offset list should equal 1 ", file2->missing_offsets->count, 1); Offset* offset2 = (Offset*) file2->missing_offsets->pop(file2->missing_offsets); @@ -165,6 +162,39 @@ int test_process_data_packet() { } +int test_process_nak() { + + DECLARE_NEW_TEST("testing nak client response"); + char packet[2000]; + uint32_t start = 20; + uint32_t data_len = sizeof(packet) - start; + memset(packet, 0, 1500); + + Request *req = mock_request(); + ssp_free_file(req->file); + req->file = create_file("test_files/nak_test.jpg", 0); + + add_first_offset(req->file, req->file->total_size); + build_nak_packet(packet, start, req); + + File *file = create_file(req->destination_file_name, 1); + add_first_offset(file, req->file->total_size); + + process_nak_pdu(&packet[start + SIZE_OF_DIRECTIVE_CODE], file); + + int error = 0; + error = ASSERT_EQUALS_INT("Nak list count should be of size 1", file->missing_offsets->count, 1); + + Offset *offset = (Offset*) file->missing_offsets->pop(file->missing_offsets); + + error = ASSERT_EQUALS_INT("offset start should be 0", offset->start, 0); + error = ASSERT_EQUALS_INT("offset end should be file size", offset->end, 150033); + + ssp_cleanup_req(req); + return error; +} + + int protocol_handler_test() { int error = 0; @@ -172,6 +202,6 @@ int protocol_handler_test() { //error = test_process_pdu_eof(); //error = test_on_server_time_out(); error = test_process_data_packet(); - + error = test_process_nak(); return error; } \ No newline at end of file From 8758f8a4c4f0dc9e34dfdc1fc59cca4668a12042 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 25 Feb 2021 18:48:05 -0700 Subject: [PATCH 296/400] add new and improved NAK response for client --- Program/src/packet.c | 50 +++++------------------ Program/src/port.c | 12 +++++- Program/src/protocol_handler.c | 73 ++++++++++++++++++++++++++++------ 3 files changed, 81 insertions(+), 54 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index df0b7d9..4fdfdbd 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -307,6 +307,7 @@ typedef struct file_data_pdu_contents { } File_data_pdu_contents; */ //returns the length of the packet, or -1 on error +//end is how long the buffer/mtu is, offset is the place in the file we want to read from int build_data_packet(char *packet, uint32_t start, uint32_t end, uint32_t offset, File *file){ uint16_t data_size = end - start; @@ -314,50 +315,19 @@ int build_data_packet(char *packet, uint32_t start, uint32_t end, uint32_t offse uint32_t net_offset = ssp_ntohl(offset); memcpy(&packet[packet_index], &net_offset, sizeof(uint32_t)); + packet_index += 4; int bytes = get_offset(file, &packet[packet_index], data_size, offset); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); return -1; } - + uint16_t data_len = bytes + sizeof(uint32_t); set_packet_header(packet, data_len, DATA); return data_len; } -//sets the offset, datasize, -//outdated -uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client) { - - if (offset > req->file->total_size) { - return 1; - } - - uint16_t packet_index = start; - File_data_pdu_contents *packet_offset = (File_data_pdu_contents *) &packet[packet_index]; - packet_offset->offset = offset; - - //4 bytes is the size of the offset paramater - packet_index += 4; - uint16_t data_size = client->packet_len - packet_index; - //fill the rest of the packet with data - int bytes = get_offset(req->file, &packet[packet_index], data_size, offset); - if (bytes <= 0){ - ssp_error("could not get offset, this could because the file is empty!\n"); - return 1; - } - - uint16_t data_len = bytes + 4; - set_packet_header(packet, data_len, DATA); - - if (bytes < data_size) - return 1; - - return 0; -} - - //returns the offset in the file (for the data packet) uint32_t get_data_offset_from_packet(char *packet) { uint32_t offset = 0; @@ -480,27 +450,27 @@ int get_nak_packet(char *packet, Pdu_nak *nak) { uint32_t packet_index = 0; uint32_t start_scope = 0; - uint32_t offset_start = 0; - uint32_t offset_end = 0; - + uint32_t end_scope = 0; + uint64_t segment_requests = 0; + memcpy(&start_scope, &packet[packet_index], sizeof(uint32_t)); nak->start_scope = ssp_ntohl(start_scope); packet_index += sizeof(uint32_t); - uint32_t end_scope = 0; memcpy(&end_scope, &packet[packet_index], sizeof(uint32_t)); nak->end_scope = ssp_ntohl(end_scope); packet_index += sizeof(uint32_t); - uint64_t segment_requests = 0; - memcpy(&segment_requests, &packet[packet_index], sizeof(uint32_t)); - nak->segment_requests = ssp_ntohl(segment_requests); + memcpy(&segment_requests, &packet[packet_index], sizeof(uint64_t)); + nak->segment_requests = ssp_ntohll(segment_requests); packet_index += sizeof(uint64_t); nak->segments = &packet[packet_index]; + + return packet_index; } diff --git a/Program/src/port.c b/Program/src/port.c index 9930cf1..e838ea5 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -156,6 +156,7 @@ int ssp_readdir(void *dir, char *file){ } +#include "packet.h" /*------------------------------------------------------------------------------ Network port functions, these are used to interchange different network stacks @@ -169,7 +170,7 @@ void ssp_sendto(Response res) { #ifdef TEST return; #endif - + if (res.type_of_network == generic) { #ifdef FREE_RTOS_PORT @@ -234,9 +235,16 @@ void ssp_sendto(Response res) { else { #ifdef POSIX_PORT struct sockaddr* addr = (struct sockaddr*) res.addr; + + //ssp_print_bits(res.msg, 10); + //Pdu_header header; + //memset(&header, 0, sizeof(Pdu_header)); + //get_pdu_header_from_packet(res.msg, &header); + //ssp_print_header(&header); + int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); if (err < 0) { - ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, *addr, sizeof(struct sockaddr)); + ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, addr, sizeof(struct sockaddr)); ssp_error("ERROR in sendto"); } #endif diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index be36ec2..f8cdae2 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -417,6 +417,7 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t //returns -1 on error //adds start and end if there is no start and end (end will likely have to be the file size and start should be 0) +//for remembering packets? int process_nak_pdu(char *packet, File *file){ if (file->missing_offsets->count == 0){ @@ -448,12 +449,69 @@ int process_nak_pdu(char *packet, File *file){ if (!completed) { return -1; } - offset_end = 0; - offset_start = 0; } return 1; } +void segment_offset_into_data_packets(char *packet, uint32_t start, uint32_t offset_start, uint32_t offset_end, Request *req, Response res){ + + int i = 0; + int error = 0; + uint32_t segment_len = req->buff_len - start; + + for (i = offset_start; i < offset_end; i+= segment_len) { + + if (offset_end - i < segment_len){ + segment_len = offset_end - i; + } + + //ssp_printf("sending offset start %d to %d\n", i, i + segment_len); + //ssp_printf("segment len %d\n",segment_len); + + error = build_data_packet(packet, start, segment_len + start, i, req->file); + if (error < 0) { + return -1; + } + + ssp_sendto(res); + } +} + +int process_nak_pdu_response(char *packet, Request *req, Response res, Client *client){ + Pdu_nak nak; + get_nak_packet(packet, &nak); + + uint32_t packet_index = 0; + uint32_t offset_start = 0; + uint32_t offset_end = 0; + //build new header for outgoing packets + uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, 0, &client->pdu_header); + int error = 0; + int i = 0; + + + ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); + //This needs to send naks based on start and end scope, not segment requests. + for (i = 0; i < nak.segment_requests; i++){ + + packet_index = 0; + + memcpy(&offset_start, &nak.segments[packet_index], sizeof(uint32_t)); + offset_start = ssp_ntohl(offset_start); + packet_index += 4; + + memcpy(&offset_end, &nak.segments[packet_index], sizeof(uint32_t)); + offset_end = ssp_ntohl(offset_end); + packet_index += 4; + + //ssp_printf("sending offset start %d offset end %d\n", offset_start, offset_end); + segment_offset_into_data_packets(req->buff, outgoing_packet_index, offset_start, offset_end, req, res); + } + + return 1; + +} + static void send_data(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); @@ -497,7 +555,6 @@ int nak_response(char *packet, uint32_t start, Request *req, Response res, Clien } - //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { @@ -516,15 +573,7 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ break; case NAK_PDU: ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); - /* - if (process_nak_pdu(packet, req->file) < 0){ - ssp_printf("couldn't process Nak Pdu transaction: %d\n", req->transaction_sequence_number); - break; - } - req->procedure = sending_nak_data; - */ - - nak_response(packet, packet_index, req, res, client); + process_nak_pdu_response(&packet[packet_index], req, res, client); break; case ACK_PDU: From c2a04637c627e840b0e2bc189113ecd71c7b45ca Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 26 Feb 2021 20:17:17 -0700 Subject: [PATCH 297/400] add refactored incomplete finished pdu --- Program/src/packet.c | 50 +++++++++++++++++++++++++++++++------ Program/test/packet_tests.c | 21 ++++++++++++++++ 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 4fdfdbd..6f119dc 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -210,6 +210,33 @@ int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_ return dest_id_location + pdu_header->length_of_entity_IDs; } +/* +typedef struct pdu_finished { + unsigned int condition_code : 4; + + // 0 generated by waypoint 1 generated by end system. + unsigned int end_system_status : 1; + + //0 data complete, 1 data incomplete + unsigned int delivery_code : 1; + + //see above + unsigned int file_status : 2; + TLV file_store_responses; + TLV fault_location; + +}Pdu_finished; +*/ +uint32_t get_finished_pdu(char *packet, Pdu_finished *pdu_finished) { + + pdu_finished->condition_code = get_bits_from_protocol_byte(packet[0], 0, 3); + pdu_finished->end_system_status = get_bits_from_protocol_byte(packet[0], 4, 4); + pdu_finished->delivery_code = get_bits_from_protocol_byte(packet[0], 5, 5); + pdu_finished->file_status = get_bits_from_protocol_byte(packet[0], 6, 7); + +} + + uint8_t build_finished_pdu(char *packet, uint32_t start) { uint32_t packet_index = start; @@ -217,17 +244,24 @@ uint8_t build_finished_pdu(char *packet, uint32_t start) { packet[packet_index] = FINISHED_PDU; packet_index++; - data_len++; - - //one byte - Pdu_finished *pdu_finished = (Pdu_finished *) &packet[packet_index]; - pdu_finished->condition_code = COND_NO_ERROR; - pdu_finished->delivery_code = 0; - pdu_finished->file_status = FILE_RETAINED_SUCCESSFULLY; - data_len += 1; + + set_bits_to_protocol_byte(&packet[packet_index], 0, 3, COND_NO_ERROR); + + // 0 generated by waypoint 1 generated by end system (ext features) + set_bits_to_protocol_byte(&packet[packet_index], 4, 4, 0); + + //0 data complete, 1 data incomplete (ext features) + set_bits_to_protocol_byte(&packet[packet_index], 5, 5, 0); + + //file_status + set_bits_to_protocol_byte(&packet[packet_index], 6, 7, FILE_RETAINED_SUCCESSFULLY); + packet_index += 1; + data_len = packet_index - start; + set_packet_header(packet, data_len, DIRECTIVE); + return data_len; } /* diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 9e92215..dec99b4 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -566,6 +566,26 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { } +int test_build_finished_pdu(char *packet, uint32_t start) { + + + DECLARE_NEW_TEST("testing creation and parsing of finished pdu"); + memset(&packet[start], 0, 100); + + uint32_t packet_index = start; + + uint32_t data_len = build_finished_pdu(packet, start); + + packet_index += SIZE_OF_DIRECTIVE_CODE; + + Pdu_finished fin; + get_finished_pdu(&packet[packet_index], &fin); + + ASSERT_EQUALS_INT("condition_code set", fin.condition_code, COND_NO_ERROR); + ASSERT_EQUALS_INT("delivery_code not set", fin.delivery_code, 0); + ASSERT_EQUALS_INT("end_system_status not set", fin.end_system_status, 0); + ASSERT_EQUALS_INT("file_status FILE_RETAINED_SUCCESSFULLY set", fin.file_status, FILE_RETAINED_SUCCESSFULLY); +} int packet_tests() { @@ -592,6 +612,7 @@ int packet_tests() { //test_build_eof_packet(packet, data_start_index); //test_build_data_packet(packet, data_start_index); test_build_nak_packet(packet, data_start_index); + test_build_finished_pdu(packet, data_start_index); //next up From eda8396977018696af68755023a61433da000ad9 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 27 Feb 2021 13:24:51 -0700 Subject: [PATCH 298/400] remove old function for naks --- Program/src/protocol_handler.c | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index f8cdae2..91152d2 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -523,38 +523,6 @@ static void send_data(Request *req, Response res) { } -//outdated -int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client) { - uint32_t packet_index = start; - Pdu_nak *nak = (Pdu_nak *) &packet[packet_index]; - uint64_t segments = ssp_ntohll(nak->segment_requests); - packet_index += 16; - - if (req->buff == NULL){ - ssp_printf("req->buff is null\n"); - } - - uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, 0, &client->pdu_header); - uint32_t offset_start = 0; - uint32_t offset_end = 0; - int i = 0; - for (i = 0; i < segments; i++){ - //outgoing_packet_index - ssp_memcpy(&offset_start, &packet[packet_index], 4); - offset_start = ssp_ntohl(offset_start); - packet_index += 4; - ssp_memcpy(&offset_end, &packet[packet_index], 4); - offset_end = ssp_ntohl(offset_end); - packet_index += 4; - build_nak_response(req->buff, outgoing_packet_index, offset_start, req, client); - ssp_sendto(res); - } - - return packet_index; - -} - - //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { @@ -885,7 +853,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque switch (ack_packet.directive_code) { case FINISHED_PDU: - + //get_finished_pdu(char *packet, Pdu_finished *pdu_finished) ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); req->local_entity.transaction_finished_indication = true; break; From 09dd00ff012fcdfe6925ab536506739fd9e2f63d Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 27 Feb 2021 17:49:32 -0700 Subject: [PATCH 299/400] change some print statements, and include configs for ground --- Program/include/protocol_handler.h | 6 ++--- Program/src/file_delivery_app.c | 42 +++++++++++++++++++++++++++--- Program/src/protocol_handler.c | 22 +++++++++------- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index c65e732..a8b7ece 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -10,8 +10,8 @@ Author: Evan Giese #define RESEND_EOF_TIMES 3 #define RESEND_FINISHED_TIMES 10 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 30 -#define TIMEOUT_BEFORE_SAVE_REQUEST 5 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 1200 +#define TIMEOUT_BEFORE_SAVE_REQUEST 30 int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app); void user_request_handler(Response res, Request *req, Client *client); @@ -42,4 +42,4 @@ uint16_t get_data_length(char*packet); -#endif \ No newline at end of file +#endif diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 4041d75..7945340 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -87,8 +87,8 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { if (error < 0) { ssp_error("couldn't make directory mib it either already exists or there is an issue\n"); } - const char *peer_file = "{\n\ - \"cfdp_id\": 7,\n\ + const char *peer_file_sat = "{\n\ + \"cfdp_id\": 0,\n\ \"UT_address\" : 0,\n\ \"UT_port\" : 20,\n\ \"type_of_network\" : 3,\n\ @@ -109,6 +109,28 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { \"transaction_inactivity_limit\" : 123\n\ }"; + const char *peer_file_ground_station = "{\n\ + \"cfdp_id\": 10,\n\ + \"UT_address\" : 10,\n\ + \"UT_port\" : 1,\n\ + \"type_of_network\" : 3,\n\ + \"default_transmission_mode\" : 1,\n\ + \"MTU\" : 250,\n\ + \"one_way_light_time\" : 123,\n\ + \"total_round_trip_allowance\" : 123,\n\ + \"async_NAK_interval\" : 123,\n\ + \"async_keep_alive_interval\" : 123,\n\ + \"async_report_interval\" : 123,\n\ + \"immediate_nak_mode_enabled\" : 123,\n\ + \"prompt_transmission_interval\" : 123,\n\ + \"disposition_of_incomplete\" : 123,\n\ + \"CRC_required\" : 0,\n\ + \"keep_alive_discrepancy_limit\" : 8,\n\ + \"positive_ack_timer_expiration_limit\" : 123,\n\ + \"nak_timer_expiration_limit\" : 123,\n\ + \"transaction_inactivity_limit\" : 123\n\ +}"; + int fd = ssp_open("mib/peer_0.json", SSP_O_CREAT | SSP_O_RDWR); if (fd < 0) { if (fd == SSP_EEXIST) { @@ -117,7 +139,21 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { else ssp_error("couldn't create default peer_0.json it either already exists or there is an issue\n"); } else { - error = ssp_write(fd, peer_file, strnlen(peer_file, 1000)); + error = ssp_write(fd, peer_file_sat, strnlen(peer_file_sat, 1000)); + if (error < 0) { + ssp_error("couldn't write default file\n"); + } + } + + fd = ssp_open("mib/peer_10.json", SSP_O_CREAT | SSP_O_RDWR); + if (fd < 0) { + if (fd == SSP_EEXIST) { + ssp_error("file exists\n"); + } + else + ssp_error("couldn't create default peer_10.json it either already exists or there is an issue\n"); + } else { + error = ssp_write(fd, peer_file_ground_station, strnlen(peer_file_ground_station, 1000)); if (error < 0) { ssp_error("couldn't write default file\n"); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 91152d2..e85e95d 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -209,9 +209,12 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { return; } + + uint32_t offset_start = get_data_offset_from_packet(packet); uint32_t packet_index = 4; - + + ssp_printf("received data packet offset:%d\n", offset_start); // size of 'offset' bytes in packet uint32_t offset_end = offset_start + data_len - packet_index; @@ -537,10 +540,10 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ case FINISHED_PDU: req->local_entity.transaction_finished_indication = true; req->procedure = sending_finished; - ssp_printf("received finished pdu transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received finished pdu transaction: %llu\n", req->transaction_sequence_number); break; case NAK_PDU: - ssp_printf("received Nak pdu transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received Nak pdu transaction: %llu\n", req->transaction_sequence_number); process_nak_pdu_response(&packet[packet_index], req, res, client); break; case ACK_PDU: @@ -548,12 +551,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch (packet[packet_index]) { case EOF_PDU: - ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received Eof ack transaction: %llu\n", req->transaction_sequence_number); req->local_entity.EOF_recv_indication = true; break; case META_DATA_PDU: - ssp_printf("received Eof ack transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received Eof ack transaction: %llu\n", req->transaction_sequence_number); req->local_entity.Metadata_recv_indication = true; default: @@ -565,12 +568,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch (packet[packet_index]) { case META_DATA_PDU: - ssp_printf("resending metadata transaction: %d\n", req->transaction_sequence_number); + ssp_printf("resending metadata transaction: %llu\n", req->transaction_sequence_number); req->procedure = sending_put_metadata; break; case EOF_PDU: - ssp_printf("resending eof transaction: %d\n", req->transaction_sequence_number); + ssp_printf("resending eof transaction: %llu\n", req->transaction_sequence_number); req->procedure = sending_eof; break; @@ -656,7 +659,7 @@ static void request_metadata(Request *req, Response res) { static void request_data(Request *req, Response res) { uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); - ssp_printf("sending Nak data transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending Nak data transaction: %llu\n", req->transaction_sequence_number); build_nak_packet(req->buff, start, req); ssp_sendto(res); } @@ -722,7 +725,7 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, req->procedure = sending_put_metadata; req->local_entity.Metadata_recv_indication = true; - ssp_printf("received metadata packet transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received metadata packet transaction: %llu\n", req->transaction_sequence_number); packet_index += parse_metadata_packet(packet, packet_index, req); uint16_t data_len = get_data_length(packet); @@ -823,7 +826,6 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque } } process_data_packet(&packet[packet_index], data_len, req->file); - ssp_printf("received data packet transaction: %d\n", req->transaction_sequence_number); return packet_len; } From da458f4149f6f6490a921928463db7213f4bc904 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 27 Feb 2021 18:00:32 -0700 Subject: [PATCH 300/400] change some print statements to print llu --- Program/src/protocol_handler.c | 28 +++++++++++++++------------- Program/src/requests.c | 2 +- Program/src/tasks.c | 6 +++--- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index e85e95d..5e60879 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -42,7 +42,7 @@ static void send_nak(Request *req, Response res, unsigned int type) { static void resend_eof_ack(Request *req, Response res) { - ssp_printf("sending eof ack transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending eof ack transaction: %llu\n", req->transaction_sequence_number); send_ack(req,res, EOF_PDU); req->resent_eof++; } @@ -355,7 +355,7 @@ void process_messages(Request *req, FTP *app) { static void resend_finished_ack(Request *req, Response res) { - ssp_printf("sending finished packet transaction ack: %d\n", req->transaction_sequence_number); + ssp_printf("sending finished packet transaction ack: %llu\n", req->transaction_sequence_number); send_ack(req, res, FINISHED_PDU); req->resent_finished++; } @@ -363,7 +363,7 @@ static void resend_finished_ack(Request *req, Response res) { static void send_put_metadata(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); - ssp_printf("sending metadata transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending metadata transaction: %llu\n", req->transaction_sequence_number); start = build_put_packet_metadata(req->buff, start, req); req->local_entity.Metadata_sent_indication = true; @@ -372,7 +372,7 @@ static void send_put_metadata(Request *req, Response res) { static void send_eof_pdu(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); - ssp_printf("sending eof transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending eof transaction: %llu\n", req->transaction_sequence_number); if (req->file_size == 0) build_eof_packet(req->buff, start, 0, 0); else @@ -411,7 +411,9 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); file->next_offset_to_send += bytes; - if (data_len < length - packet_index) + ssp_printf("sending packet data offset:size %d:%d\n", file->next_offset_to_send, file->total_size); + + if (file->next_offset_to_send == file->total_size) return 1; return 0; @@ -520,7 +522,7 @@ static void send_data(Request *req, Response res) { if (create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { req->procedure = sending_eof; - ssp_printf("sending data burst transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending data burst transaction: %llu\n", req->transaction_sequence_number); } ssp_sendto(res); } @@ -646,13 +648,13 @@ void user_request_handler(Response res, Request *req, Client* client) { static void request_eof(Request *req, Response res) { - ssp_printf("sending eof nak transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending eof nak transaction: %llu\n", req->transaction_sequence_number); send_nak(req, res, EOF_PDU); } static void request_metadata(Request *req, Response res) { - ssp_printf("sending request for new metadata packet %d\n", req->transaction_sequence_number); + ssp_printf("sending request for new metadata packet %llu\n", req->transaction_sequence_number); send_nak(req, res, META_DATA_PDU); } @@ -668,7 +670,7 @@ static void request_data(Request *req, Response res) { static void resend_finished_pdu(Request *req, Response res) { uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); - ssp_printf("sending finished pdu transaction: %d\n", req->transaction_sequence_number); + ssp_printf("sending finished pdu transaction: %llu\n", req->transaction_sequence_number); build_finished_pdu(req->buff, start); ssp_sendto(res); req->resent_finished++; @@ -678,7 +680,7 @@ static void resend_finished_pdu(Request *req, Response res) { //processes the eof packet, sets checksum, indication, and filesize. void process_pdu_eof(char *packet, Request *req, Response res) { - ssp_printf("received eof packet transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received eof packet transaction: %llu\n", req->transaction_sequence_number); Pdu_eof eof_packet; get_eof_from_packet(packet, &eof_packet); @@ -756,7 +758,7 @@ void on_server_time_out(Response res, Request *req) { } if (req->resent_finished == RESEND_FINISHED_TIMES && req->local_entity.transaction_finished_indication) { req->procedure = clean_up; - ssp_printf("file sent, closing request transaction: %d\n", req->transaction_sequence_number); + ssp_printf("file sent, closing request transaction: %llu\n", req->transaction_sequence_number); return; } //send request for metadata @@ -848,7 +850,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque break; case ACK_PDU: - ssp_printf("received Ack transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received Ack transaction: %llu\n", req->transaction_sequence_number); Pdu_ack ack_packet; get_ack_from_packet(&packet[packet_index], &ack_packet); @@ -856,7 +858,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque { case FINISHED_PDU: //get_finished_pdu(char *packet, Pdu_finished *pdu_finished) - ssp_printf("received finished packet transaction: %d\n", req->transaction_sequence_number); + ssp_printf("received finished packet transaction: %llu\n", req->transaction_sequence_number); req->local_entity.transaction_finished_indication = true; break; diff --git a/Program/src/requests.c b/Program/src/requests.c index c4f0c9e..64c60f9 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -576,7 +576,7 @@ static void print_messages_callback(Node *node, void *element, void *args) { void print_request_state(Request *req) { - ssp_printf("----------------Transaction %d---------------\n", req->transaction_sequence_number); + ssp_printf("----------------Transaction %llu---------------\n", req->transaction_sequence_number); ssp_printf("local_entity id and stats: \n"); diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 236df0b..744c7ef 100755 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -64,12 +64,12 @@ static void timeout(Request *req) { bool is_timeout = check_timeout(&req->timeout_before_cancel, TIMEOUT_BEFORE_CANCEL_REQUEST); if (is_timeout) { if (req->local_entity.transaction_finished_indication){ - ssp_printf("ACKNOWLEDGED request successfully sent without issue transaction: %d\n", req->transaction_sequence_number); + ssp_printf("ACKNOWLEDGED request successfully sent without issue transaction: %llu\n", req->transaction_sequence_number); } else if (req->transmission_mode == UN_ACKNOWLEDGED_MODE){ - ssp_printf("UN_ACKNOWLEDGED request successfully sent without issue transaction: %d\n", req->transaction_sequence_number); + ssp_printf("UN_ACKNOWLEDGED request successfully sent without issue transaction: %llu\n", req->transaction_sequence_number); } else { - ssp_printf("stopped early, timed out without finishing request, saving req to be reopened later: %d\n", req->transaction_sequence_number); + ssp_printf("stopped early, timed out without finishing request, saving req to be reopened later: %llu\n", req->transaction_sequence_number); print_request_state(req); save_req_to_file(req); } From 7ede48246983ef6314cac50470e9b1488a01455f Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 27 Feb 2021 19:36:32 -0700 Subject: [PATCH 301/400] remove uncessary enums --- Program/include/csp_server_provider.h | 2 - Program/include/protocol_handler.h | 2 + Program/include/types.h | 4 -- Program/src/protocol_handler.c | 99 ++++++++++++++------------- Program/src/requests.c | 17 +---- Program/src/tasks.c | 4 +- 6 files changed, 57 insertions(+), 71 deletions(-) diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index 142b18d..c7f784a 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -8,8 +8,6 @@ Author: Evan Giese #define CSP_SERVER_H #include "stdint.h" -#define CSP_CLIENT_PORT 28 - void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_port, uint32_t packet_len, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index a8b7ece..5a3a1b3 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -10,6 +10,8 @@ Author: Evan Giese #define RESEND_EOF_TIMES 3 #define RESEND_FINISHED_TIMES 10 +#define RESEND_META_TIMES 3 + #define TIMEOUT_BEFORE_CANCEL_REQUEST 1200 #define TIMEOUT_BEFORE_SAVE_REQUEST 30 diff --git a/Program/include/types.h b/Program/include/types.h index c6d0524..d8a1e39 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -578,10 +578,6 @@ typedef struct response { typedef enum procedure { none, - sending_finished, - sending_put_metadata, - sending_eof, - sending_data, sending_nak_data, clean_up, sending_start, diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 5e60879..9303acc 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -21,7 +21,6 @@ static void build_temperary_file(Request *req, uint32_t size) { req->file = create_temp_file(req->source_file_name, size); } - static void send_ack(Request *req, Response res, unsigned int type){ if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; @@ -104,7 +103,7 @@ static int find_request(void *element, void *args) { found_req->pdu_header = pdu_header; found_req->my_cfdp_id = app->my_cfdp_id; found_req->remote_entity = remote_entity; - found_req->procedure = sending_put_metadata; + found_req->procedure = none; found_req->res.addr = ssp_alloc(1, res.size_of_addr); @@ -209,8 +208,6 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { return; } - - uint32_t offset_start = get_data_offset_from_packet(packet); uint32_t packet_index = 4; @@ -383,16 +380,6 @@ static void send_eof_pdu(Request *req, Response res) { return; } -//if no file attached to request, set procedure to none -static void start_sequence(Request *req, Response res) { - - send_put_metadata(req, res); - if (req->file_size == 0 ){ - req->procedure = none; - return; - } - req->procedure = sending_data; -} int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t length) { @@ -496,7 +483,7 @@ int process_nak_pdu_response(char *packet, Request *req, Response res, Client *c ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); - //This needs to send naks based on start and end scope, not segment requests. + for (i = 0; i < nak.segment_requests; i++){ packet_index = 0; @@ -509,7 +496,6 @@ int process_nak_pdu_response(char *packet, Request *req, Response res, Client *c offset_end = ssp_ntohl(offset_end); packet_index += 4; - //ssp_printf("sending offset start %d offset end %d\n", offset_start, offset_end); segment_offset_into_data_packets(req->buff, outgoing_packet_index, offset_start, offset_end, req, res); } @@ -517,22 +503,62 @@ int process_nak_pdu_response(char *packet, Request *req, Response res, Client *c } -static void send_data(Request *req, Response res) { +static void acknowledged_start(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); + + send_put_metadata(req, res); + if (req->file_size == 0 ){ + req->procedure = none; + return; + } + while (!create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { + ssp_sendto(res); + } + send_eof_pdu(req, res); + req->procedure = none; +} - if (create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { - req->procedure = sending_eof; - ssp_printf("sending data burst transaction: %llu\n", req->transaction_sequence_number); +static void unacknowledged_start(Request *req, Response res){ + + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); + int i = 0; + + for (i = 0; i < RESEND_META_TIMES; i++) { + send_put_metadata(req, res); } - ssp_sendto(res); + if (req->file_size == 0 ){ + req->procedure = none; + return; + } + + while (!create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { + ssp_sendto(res); + } + + for (i = 0; i < RESEND_EOF_TIMES; i++) { + send_eof_pdu(req, res); + } + + req->procedure = none; +} + +//if no file attached to request, set procedure to none +static void start_sequence(Request *req, Response res) { + + if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) { + unacknowledged_start(req, res); + return; + } + acknowledged_start(req, res); } + //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { //if client is still sending the first data_burst, don't accepts packets - if (req->procedure == sending_data) + if (req->procedure == sending_start) return; uint8_t directive = packet[packet_index]; @@ -540,9 +566,9 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch(directive) { case FINISHED_PDU: - req->local_entity.transaction_finished_indication = true; - req->procedure = sending_finished; ssp_printf("received finished pdu transaction: %llu\n", req->transaction_sequence_number); + req->local_entity.transaction_finished_indication = true; + resend_finished_ack(req, res); break; case NAK_PDU: ssp_printf("received Nak pdu transaction: %llu\n", req->transaction_sequence_number); @@ -571,12 +597,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ { case META_DATA_PDU: ssp_printf("resending metadata transaction: %llu\n", req->transaction_sequence_number); - req->procedure = sending_put_metadata; + send_put_metadata(req, res); break; case EOF_PDU: ssp_printf("resending eof transaction: %llu\n", req->transaction_sequence_number); - req->procedure = sending_eof; + send_eof_pdu(req, res); break; default: @@ -603,31 +629,11 @@ void user_request_handler(Response res, Request *req, Client* client) { check_req_status(req); - switch (req->procedure) { case sending_nak_data: break; - case sending_eof: - send_eof_pdu(req, res); - req->procedure = none; - break; - - case sending_data: - send_data(req, res); - break; - - case sending_put_metadata: - send_put_metadata(req, res); - req->procedure = none; - break; - - case sending_finished: - resend_finished_ack(req, res); - req->procedure = none; - break; - case sending_start: start_sequence(req, res); break; @@ -724,7 +730,6 @@ int process_file_request_metadata(Request *req) { static void process_metadata(char *packet, uint32_t packet_index, Response res, Request *req, FTP *app) { - req->procedure = sending_put_metadata; req->local_entity.Metadata_recv_indication = true; ssp_printf("received metadata packet transaction: %llu\n", req->transaction_sequence_number); diff --git a/Program/src/requests.c b/Program/src/requests.c index 64c60f9..15850a6 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -619,22 +619,7 @@ void print_request_procedure(Request *req){ ssp_printf("current procedure: "); switch (req->procedure) { - case sending_eof: - ssp_printf("sending_eof\n"); - break; - - case sending_data: - ssp_printf("sending_data\n"); - break; - - case sending_put_metadata: - ssp_printf("sending_put_metadata\n"); - break; - - case sending_finished: - ssp_printf("sending_finished\n"); - break; - + case sending_start: ssp_printf("sending_start\n"); break; diff --git a/Program/src/tasks.c b/Program/src/tasks.c index 744c7ef..c6861cd 100755 --- a/Program/src/tasks.c +++ b/Program/src/tasks.c @@ -503,7 +503,7 @@ void *ssp_csp_connectionless_client_task(void *params) { csp_connectionless_client(client->remote_entity.UT_address, client->remote_entity.UT_port, - CSP_CLIENT_PORT, + CSP_ANY, client->remote_entity.mtu, on_send_client_callback, on_recv_client_callback, @@ -544,7 +544,7 @@ void *ssp_csp_connection_client_task(void *params) { Client *client = (Client *) params; csp_connection_client(client->remote_entity.UT_address, client->remote_entity.UT_port, - CSP_CLIENT_PORT, + CSP_ANY, client->remote_entity.mtu, on_send_client_callback, on_recv_client_callback, From 5746cdd9060b6aa94fe477bfed51897645c5805b Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 3 Mar 2021 19:55:34 -0700 Subject: [PATCH 302/400] Sanitize request memory --- Program/src/protocol_handler.c | 6 +++--- Program/src/requests.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 9303acc..6d6719b 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -369,7 +369,7 @@ static void send_put_metadata(Request *req, Response res) { static void send_eof_pdu(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); - ssp_printf("sending eof transaction: %llu\n", req->transaction_sequence_number); + ssp_printf("sending eof transaction: %llu file_size %d\n", req->transaction_sequence_number, req->file_size); if (req->file_size == 0) build_eof_packet(req->buff, start, 0, 0); else @@ -695,7 +695,7 @@ void process_pdu_eof(char *packet, Request *req, Response res) { build_temperary_file(req, eof_packet.file_size); } - req->local_entity.EOF_recv_indication = 1; + req->local_entity.EOF_recv_indication = true; req->file->eof_checksum = eof_packet.checksum; req->file->total_size = eof_packet.file_size; @@ -733,7 +733,7 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, req->local_entity.Metadata_recv_indication = true; ssp_printf("received metadata packet transaction: %llu\n", req->transaction_sequence_number); - packet_index += parse_metadata_packet(packet, packet_index, req); + packet_index = parse_metadata_packet(packet, packet_index, req); uint16_t data_len = get_data_length(packet); get_messages_from_packet(packet, packet_index, data_len, req); diff --git a/Program/src/requests.c b/Program/src/requests.c index 15850a6..0e77fcf 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -281,6 +281,8 @@ Request *init_request_no_client() { Request *req = ssp_alloc(1, sizeof(Request)); if (req == NULL) return NULL; + + memset(req, 0, sizeof(Request)); req->file = NULL; req->procedure = none; @@ -636,3 +638,15 @@ void print_request_procedure(Request *req){ break; } } + + +void print_res(Response res){ + + ssp_printf("addr %d\n", res.addr); + ssp_printf("msg %d\n", res.msg); + ssp_printf("packet_len %d\n", res.packet_len); + ssp_printf("sfd %d\n", res.sfd); + ssp_printf("size_of_addr %d\n", res.size_of_addr); + ssp_printf("transmission_mode %d\n", res.transmission_mode); + ssp_printf("type_of_network %d\n", res.type_of_network); +} From 7c8dc75f8cd85cdaf384e4fc2b9f4e89dac4e000 Mon Sep 17 00:00:00 2001 From: evanGee Date: Fri, 5 Mar 2021 21:38:02 -0700 Subject: [PATCH 303/400] add some error handling --- Program/include/filesystem_funcs.h | 2 +- Program/include/protocol_handler.h | 2 +- Program/src/csp_server_provider.c | 16 ++++++++++++---- Program/src/file_delivery_app.c | 2 ++ Program/src/filesystem_funcs.c | 12 +++++++----- Program/src/port.c | 4 ++-- Program/src/requests.c | 10 +++++++--- 7 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index b8fb0b1..9e801f6 100755 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -16,7 +16,7 @@ struct params { }; -uint32_t get_file_size(char *source_file_name); +int get_file_size(char *source_file_name); //allocates space for a file pointer File *create_file(char *source_file_name, int clear_file_contents); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 5a3a1b3..6e92850 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -12,7 +12,7 @@ Author: Evan Giese #define RESEND_FINISHED_TIMES 10 #define RESEND_META_TIMES 3 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 1200 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 60 #define TIMEOUT_BEFORE_SAVE_REQUEST 30 int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index e23166b..d0b41bf 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -224,6 +224,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, } //Pointer to current connection and packet csp_conn_t *conn; + csp_conn_t *conn_waiting; csp_packet_t *packet; char *buff = ssp_alloc(packet_len, sizeof(char)); @@ -247,15 +248,22 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, } for (;;) { - + if (get_exit() || checkExit(other)) break; + conn_waiting = csp_accept(sock, 1000); + if (conn_waiting != NULL) { + csp_close(conn); + conn = conn_waiting; + } + onTimeOut(other); - - while ((packet = csp_read(conn, 100)) != NULL) { + + while ((packet = csp_read(conn, 1000)) != NULL) { + memcpy(buff, (char *)packet->data, packet_len); - + if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), other) == -1) ssp_printf("recv failed\n"); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 7945340..37595af 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -77,6 +77,8 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { int error = 0; memset(app, 0, sizeof(FTP)); + + ssp_printf("initializing ftp server task"); error = ssp_mkdir("incomplete_requests"); if (error < 0) { diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index d98d5eb..e0ea013 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -11,25 +11,25 @@ Author: Evan Giese #include "requests.h" -uint32_t get_file_size(char *source_file_name) { +int get_file_size(char *source_file_name) { int fd = ssp_open(source_file_name, SSP_O_RDWR); if (fd == -1){ ssp_error("could not open file\n"); - return 0; + return -1; } int bytes = ssp_lseek(fd, 0, 2); if (bytes == -1){ ssp_error("could not seek file for file size\n"); - return 0; + return -1; } ssp_lseek(fd, 0, 0); if (ssp_close(fd) == -1){ ssp_error("could not close file\n"); - return 0; + return -1; } return bytes; @@ -77,9 +77,11 @@ int does_file_exist(char *source_file_name) { int fd = ssp_open(source_file_name, SSP_O_RDWR); if (fd == -1){ - return 0; + ssp_printf("ERROR: couldn't open file\n"); + return -1; } if (ssp_close(fd) == -1){ + ssp_printf("ERROR: couldn't close file\n"); return -1; } diff --git a/Program/src/port.c b/Program/src/port.c index e838ea5..322a524 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -70,11 +70,11 @@ int ssp_mkdir(char *dir_name) { if(errno == EEXIST) { return 1; } - ssp_printf("couldn't make dir\n"); + //ssp_printf("couldn't make dir\n"); return -1; } else { - ssp_printf("%s directory created\n", dir_name); + //ssp_printf("%s directory created\n", dir_name); return 1; } return -1; diff --git a/Program/src/requests.c b/Program/src/requests.c index 0e77fcf..19ecb9b 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -374,13 +374,17 @@ int put_request_no_client( } file_size = get_file_size(source_file_name); - if (file_size == 0) + if (file_size == -1) { + ssp_printf("ERROR: couldn't get file size\n"); return -1; + } req->file = create_file(source_file_name, false); - if (req->file == NULL) + if (req->file == NULL) { + ssp_printf("ERROR: couldn't create file\n"); return -1; - + } + //this could probably go into 'create_file' int error = add_first_offset(req->file, req->file->total_size); if (error < 0) { From 8d91b69d20e7005447239de5663715a574126cb5 Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 10 Mar 2021 16:10:07 -0700 Subject: [PATCH 304/400] change message types to use uint64_t ids --- Program/include/filesystem_funcs.h | 3 + Program/include/requests.h | 8 +- Program/include/types.h | 8 +- Program/src/filesystem_funcs.c | 34 +++++++- Program/src/main.c | 40 +++++++-- Program/src/packet.c | 103 ++++++++++++---------- Program/src/protocol_handler.c | 30 +++++-- Program/src/requests.c | 38 +++----- Program/test/filesystem_tests.c | 6 +- Program/test/packet_tests.c | 136 +++++++++++++++++++---------- Program/test/request_tests.c | 29 +++--- 11 files changed, 271 insertions(+), 164 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 9e801f6..5ff7d95 100755 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -36,6 +36,9 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa int write_lv(int fd, LV lv); int read_lv(int fd, LV *lv); +int read_id(int fd, uint64_t *id); +int write_id(int fd, uint64_t id); + int save_req_to_file(Request *req); int save_file_to_file(int fd, File *file); int get_file_from_file(int fd, File *file); diff --git a/Program/include/requests.h b/Program/include/requests.h index 5c357b7..2564e36 100755 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -23,20 +23,14 @@ Request *put_request( int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); int add_cont_partial_message_to_request(uint32_t beneficial_cfid, - uint8_t beneficial_id_length, uint32_t originator_id, - uint8_t originator_id_length, uint32_t transaction_id, - uint8_t transaction_id_length, Request *req); Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name); Message_cont_part_request *create_message_cont_partial_request(uint32_t beneficial_cfid, - uint8_t beneficial_id_length, uint32_t originator_id, - uint8_t originator_id_length, - uint32_t transaction_id, - uint8_t transaction_id_length); + uint32_t transaction_id); int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uint32_t buff_len); void print_request_state(Request *req); diff --git a/Program/include/types.h b/Program/include/types.h index d8a1e39..6feec9f 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -150,7 +150,7 @@ typedef struct message_header { //type PROXY_PUT_REQUEST typedef struct message_put_proxy { - LV destination_id; + uint64_t destination_id; LV source_file_name; LV destination_file_name; @@ -158,9 +158,9 @@ typedef struct message_put_proxy { typedef struct message_cont_part_request { - LV destination_id; - LV originator_id; - LV transaction_id; + uint64_t destination_id; + uint64_t originator_id; + uint64_t transaction_id; } Message_cont_part_request; diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index e0ea013..c12eded 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -479,6 +479,34 @@ int get_file_from_file(int fd, File *file) { return 0; } +int write_id(int fd, uint64_t id){ + + char *error_message = "failed to write id\n"; + uint64_t network_byte_order = 0; + network_byte_order = ssp_htonll(id); + + int err = ssp_write(fd, &network_byte_order, sizeof(uint64_t)); + if (err < 0) { + ssp_error(error_message); + return -1; + } +} + +int read_id(int fd, uint64_t *id){ + + char *error_message = "failed to write id\n"; + uint64_t host_byte_order = 0; + + int err = ssp_read(fd, &host_byte_order, sizeof(uint64_t)); + if (err < 0) { + ssp_error(error_message); + return -1; + } + + *id = ssp_ntohll(host_byte_order); + return 1; +} + int write_lv(int fd, LV lv){ char *error_message = "failed to write lv\n"; @@ -537,7 +565,7 @@ static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy return; } - err = write_lv(fd, proxy_message->destination_id); + err = write_id(fd, proxy_message->destination_id); if (err < 0) { *error = err; ssp_error(error_message); @@ -689,7 +717,7 @@ static Message *read_in_proxy_message(int fd) { LV destination_file; LV src_file_name; - LV dest_id; + uint64_t dest_id; int err = read_lv(fd, &destination_file); if (err < 0) { @@ -701,7 +729,7 @@ static Message *read_in_proxy_message(int fd) { ssp_error(error_message); return NULL; } - err = read_lv(fd, &dest_id); + err = read_id(fd, &dest_id); if (err < 0) { ssp_error(error_message); return NULL; diff --git a/Program/src/main.c b/Program/src/main.c index 725f6ac..e1854a1 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -61,7 +61,7 @@ static Config *configuration(int argc, char **argv) conf->timer = 15; conf->verbose_level = 0; - conf->client_cfdp_id = 0; + conf->client_cfdp_id = -1; conf->my_cfdp_id = 0; conf->baudrate = 9600; conf->uart_device = NULL; @@ -138,6 +138,8 @@ int main(int argc, char** argv) { } + + #ifdef CSP_NETWORK csp_debug_level_t debug_level = CSP_INFO; @@ -154,9 +156,10 @@ int main(int argc, char** argv) { } csp_conf_t csp_conf; - csp_conf_get_defaults(&csp_conf); + csp_conf_get_defaults(&csp_conf); + csp_conf.buffers = 4096; csp_conf.address = remote_entity.UT_address; - + error = csp_init(&csp_conf); if (error != CSP_ERR_NONE) { csp_log_error("csp_init() failed, error: %d", error); @@ -182,18 +185,20 @@ int main(int argc, char** argv) { } } + csp_rtable_set(CSP_DEFAULT_ROUTE, 0, default_iface, CSP_NO_VIA_ADDRESS); //printf("Connection table\r\n"); //csp_conn_print_table(); printf("Interfaces\r\n"); csp_route_print_interfaces(); - //printf("Route table\r\n"); - //csp_route_print_table(); + printf("Route table\r\n"); + csp_route_print_table(); #endif + FTP app; //init_ftp(conf->my_cfdp_id, &app); uint32_t id = conf->my_cfdp_id; @@ -202,8 +207,31 @@ int main(int argc, char** argv) { return 1; } + + //sleep(5); uint32_t client_id = conf->client_cfdp_id; - Request *req = put_request(client_id, "pictures/pic.jpeg", "pictures/udp.jpg", ACKNOWLEDGED_MODE, &app); + // + if (client_id != -1) { + + sleep(5); + + //csp_custom_ftp_ping(conf->client_cfdp_id); + //Request *req = put_request(client_id, "test.txt", "test-received.txt", UN_ACKNOWLEDGED_MODE, &app); + + + Request *req2 = init_request_no_client(); + put_request_no_client(req2, NULL, NULL, UN_ACKNOWLEDGED_MODE, &app); + add_proxy_message_to_request(app.my_cfdp_id, 1, "mib/peer_0.json","GET_REQUEST", req2); + + Client *client = start_client(&app,client_id); + if (client == NULL) { + ssp_printf("client failed to start\n"); + } else + add_request_to_client(req2, client); + + + } + /* if (conf->client_cfdp_id == 1) { diff --git a/Program/src/packet.c b/Program/src/packet.c index 6f119dc..7196589 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -44,29 +44,36 @@ void set_packet_directive(char *packet, uint32_t location, uint8_t directive){ } //returns length of ids or -1 on error -int copy_id_to_packet(char *bytes, uint64_t id, uint32_t length_of_ids) { +int copy_id_to_packet(char *bytes, uint64_t id) { - if (length_of_ids == 8) { + uint32_t length = 0; + if (id < 0xFF){ + uint8_t network_byte_order = (uint8_t) id; + memcpy(bytes, &network_byte_order, sizeof(uint8_t)); + length = 1; + } else if (id < 0xFFFF) { + uint16_t network_byte_order = ssp_htons((uint16_t) id); + memcpy(bytes, &network_byte_order, sizeof(uint16_t)); + length = 2; + } else if (id < 0xFFFFFF) { + uint32_t network_byte_order = ssp_htonl((uint32_t) id); + memcpy(bytes, &network_byte_order, sizeof(uint32_t)); + length = 4; + } else if (id < 0xFFFFFFFF) { uint64_t network_byte_order = ssp_htonll(id); memcpy(bytes, &network_byte_order, sizeof(uint64_t)); - } else if (length_of_ids == 4) { - uint32_t network_byte_order = ssp_htonl((uint32_t) id); - memcpy(bytes, &network_byte_order, sizeof(uint32_t)); - } else if (length_of_ids == 2) { - uint16_t network_byte_order = ssp_htons((uint16_t) id); - memcpy(bytes, &network_byte_order, sizeof(uint16_t)); - } else if (length_of_ids == 1) { - uint8_t network_byte_order = id; - memcpy(bytes, &network_byte_order, sizeof(uint8_t)); + length = 8; } else { - ssp_error("id size is not supported, please user 1, 2 or 4"); + ssp_error("copying to packet, id size is not supported, please user 1, 2 or 4"); return -1; } - return length_of_ids; + + return length; } //returns id or -1 on error uint64_t copy_id_from_packet(char *bytes, uint32_t length_of_ids) { + uint64_t host_byte_order = 0; if (length_of_ids == 8) { host_byte_order = ssp_ntohll(*(uint64_t*) bytes); @@ -75,43 +82,45 @@ uint64_t copy_id_from_packet(char *bytes, uint32_t length_of_ids) { } else if (length_of_ids == 2) { host_byte_order = ssp_ntohs(*(uint16_t*) bytes); } else if (length_of_ids == 1){ - host_byte_order = *bytes; + host_byte_order = (uint8_t)bytes[0]; } else { - ssp_error("id size is not supported, please user 1, 2 or 4"); + ssp_error("copying from packet id size is not supported, please user 1, 2 or 4"); return -1; } + return host_byte_order; } //returns amount of bytes written or -1 on error -int copy_id_lv_to_packet(char *bytes, LV id) { +int copy_id_lv_to_packet(char *bytes, uint64_t id) { - memcpy(bytes, &id.length, sizeof(uint8_t)); - int len = copy_id_to_packet(&bytes[1], *(uint64_t*)id.value, id.length); + int len = copy_id_to_packet(&bytes[1], id); if (len < 0) { return -1; } + bytes[0] = len; + return len + 1; } -//returns 0 on success and sets LV memory, or -1 on error -int copy_id_lv_from_packet(char *bytes, LV *lv){ +//returns length of the id on success and sets id to the id, or -1 on error +int copy_id_lv_from_packet(char *bytes, uint32_t *id){ - uint8_t len = 0; - memcpy(&len, bytes, sizeof(uint8_t)); + uint8_t len = bytes[0]; - uint64_t id = copy_id_from_packet(&bytes[1], len); - if (id < 0) { - ssp_printf("failed to copy id from packet %d\n", id); + uint64_t id_recv = copy_id_from_packet(&bytes[1], len); + if (id_recv < 0) { + ssp_printf("failed to copy id from packet %d\n", id_recv); return -1; } - create_lv(lv, len, &id); - return 0; + + *id = id_recv; + return len; } void ssp_print_header(Pdu_header *pdu_header){ - + ssp_printf("---------------------------------------------\n"); ssp_printf("pdu_header->version %d\n",pdu_header->version); ssp_printf("pdu_header->PDU_type %d\n",pdu_header->PDU_type); ssp_printf("pdu_header->direction %d\n",pdu_header->direction); @@ -126,6 +135,7 @@ void ssp_print_header(Pdu_header *pdu_header){ ssp_printf("pdu_header->source_id %d\n",pdu_header->source_id); ssp_printf("pdu_header->transaction_sequence_number %d\n",pdu_header->transaction_sequence_number); ssp_printf("pdu_header->destination_id %d\n",pdu_header->destination_id); + ssp_printf("---------------------------------------------\n"); } @@ -147,6 +157,8 @@ int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ pdu_header->transaction_seq_num_len = get_bits_from_protocol_byte(packet[3], 5, 7); + //ssp_printf("length of entities %d\n", pdu_header->length_of_entity_IDs); + int32_t source_id_location = PACKET_STATIC_HEADER_LEN; pdu_header->source_id = copy_id_from_packet(&packet[source_id_location], pdu_header->length_of_entity_IDs); if (pdu_header->source_id < 0) { @@ -167,6 +179,7 @@ int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ ssp_error("failed to get destination_id"); return -1; } + pdu_header->reserved_space_for_header = dest_id_location + pdu_header->length_of_entity_IDs; return pdu_header->reserved_space_for_header; } @@ -188,20 +201,20 @@ int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_ set_bits_to_protocol_byte(&packet[3], 5,7, pdu_header->transaction_seq_num_len); int32_t source_id_location = PACKET_STATIC_HEADER_LEN; - int error = copy_id_to_packet(&packet[source_id_location], pdu_header->source_id, pdu_header->length_of_entity_IDs); + int error = copy_id_to_packet(&packet[source_id_location], pdu_header->source_id); if (error < 0) { ssp_error("failed copy source_id"); return -1; } int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; - error = copy_id_to_packet(&packet[transaction_number_location], (uint32_t) transaction_sequence_number, pdu_header->transaction_seq_num_len); + error = copy_id_to_packet(&packet[transaction_number_location], (uint32_t) transaction_sequence_number); if (error < 0) { ssp_error("failed copy transaction_number_location"); return -1; } int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; - error = copy_id_to_packet(&packet[dest_id_location], pdu_header->destination_id, pdu_header->length_of_entity_IDs); + error = copy_id_to_packet(&packet[dest_id_location], pdu_header->destination_id); if (error < 0) { ssp_error("failed copy destination_id"); return -1; @@ -721,6 +734,7 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { uint32_t message_start = start + 6; int error = 0; + int id_len = 0; switch (packet[message_type]) { case PROXY_PUT_REQUEST: @@ -732,17 +746,18 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { } proxy_put = (Message_put_proxy *) m->value; - error = copy_id_lv_from_packet(&packet[message_start], &proxy_put->destination_id); - if (error < 0) { + id_len = copy_id_lv_from_packet(&packet[message_start], &proxy_put->destination_id); + if (id_len < 0) { ssp_free(m->value); return -1; } - - message_start += proxy_put->destination_id.length + 1; + //ssp_printf("idlen %d %d\n", id_len, proxy_put->destination_id); + message_start += id_len + 1; copy_lv_from_buffer(&proxy_put->source_file_name, packet, message_start); message_start += proxy_put->source_file_name.length + 1; + copy_lv_from_buffer(&proxy_put->destination_file_name, packet, message_start); message_start += proxy_put->destination_file_name.length + 1; break; @@ -753,26 +768,26 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { m->value = ssp_alloc(1, sizeof(Message_cont_part_request)); proxy_cont_part = (Message_cont_part_request *) m->value; - error = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->destination_id); - if (error < 0) { + id_len = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->destination_id); + if (id_len < 0) { ssp_free(m->value); return -1; } - message_start += proxy_cont_part->destination_id.length + 1; + message_start += id_len + 1; - error = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->originator_id); - if (error < 0) { + id_len = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->originator_id); + if (id_len < 0) { ssp_free(m->value); return -1; } - message_start += proxy_cont_part->originator_id.length + 1; + message_start += id_len + 1; - error = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->transaction_id); - if (error < 0) { + id_len = copy_id_lv_from_packet(&packet[message_start], &proxy_cont_part->transaction_id); + if (id_len < 0) { ssp_free(m->value); return -1; } - message_start += proxy_cont_part->transaction_id.length + 1; + message_start += id_len + 1; default: break; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 6d6719b..db7315e 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -65,6 +65,8 @@ static int find_request(void *element, void *args) { if (req->dest_cfdp_id == params->source_id && req->transaction_sequence_number == params->transaction_sequence_number){ return 1; } + + //ssp_printf("cant find request req->dest_cfdp_id %d params->source_id %d transaction_sequence_number %d:%d\n", req->dest_cfdp_id, params->source_id,req->transaction_sequence_number, params->transaction_sequence_number ); return 0; } @@ -139,6 +141,9 @@ int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_ int error = get_pdu_header_from_packet(packet, &header); *incoming_pdu_header = header; + //ssp_printf("received packet is server %d\n", is_server); + //ssp_print_header(&header); + if (error < 0) { ssp_error("failed to get pdu header, bad formatting"); return -1; @@ -167,7 +172,7 @@ int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_ header.transaction_sequence_number, }; - Request *found_req = (Request *) request_list->find(request_list, 0, find_request, ¶ms); + Request *found_req = (Request *) request_list->find(request_list, -1, find_request, ¶ms); //if server, create new request (can probably move this out of this function) if (found_req == NULL && is_server) @@ -303,24 +308,26 @@ void process_messages(Request *req, FTP *app) { case PROXY_PUT_REQUEST: p_put = (Message_put_proxy *) message->value; - ssp_printf("received proxy request for source file name: %s dest file name %s, to id %d\n", + ssp_printf("received proxy request for source file name: %s dest file name %s, to id %llu\n", (char *)p_put->source_file_name.value, (char *)p_put->destination_file_name.value, - *(uint8_t*)p_put->destination_id.value); + p_put->destination_id); - start_request(put_request(*(uint8_t*)p_put->destination_id.value, + put_request(p_put->destination_id, (char *)p_put->source_file_name.value, - (char *)p_put->destination_file_name.value, ACKNOWLEDGED_MODE, app)); + (char *)p_put->destination_file_name.value, UN_ACKNOWLEDGED_MODE, app); + break; case CONTINUE_PARTIAL: p_cont = (Message_cont_part_request *) message->value; - uint32_t dest_id = *(uint8_t*)p_cont->destination_id.value; - uint32_t orig_id = *(uint8_t*)p_cont->originator_id.value; - uint32_t tran_id = *(uint8_t*)p_cont->transaction_id.value; + + uint64_t dest_id = p_cont->destination_id; + uint64_t orig_id = p_cont->originator_id; + uint64_t tran_id = p_cont->transaction_id; - ssp_printf("received message request to continue one way communication destination id %d, originator id %d, transaction id %d\n", + ssp_printf("received message request to continue one way communication destination id %llu, originator id %llu, transaction id %llu\n", dest_id, orig_id, tran_id); if (orig_id != app->my_cfdp_id) { @@ -514,6 +521,8 @@ static void acknowledged_start(Request *req, Response res) { while (!create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { ssp_sendto(res); } + ssp_sendto(res); + send_eof_pdu(req, res); req->procedure = none; } @@ -535,6 +544,8 @@ static void unacknowledged_start(Request *req, Response res){ ssp_sendto(res); } + ssp_sendto(res); + for (i = 0; i < RESEND_EOF_TIMES; i++) { send_eof_pdu(req, res); } @@ -826,6 +837,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque //process file data if (incoming_header.PDU_type == DATA) { + ssp_printf("received data packet\n"); if (!req->local_entity.Metadata_recv_indication) { if (req->file == NULL) { ssp_printf("file is null\n"); diff --git a/Program/src/requests.c b/Program/src/requests.c index 19ecb9b..58ff8d1 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -78,9 +78,9 @@ int init_cont_partial_request(Message_cont_part_request *p_cont, char *buff, uin if (req == NULL) return -1; - uint32_t dest_id = *(uint8_t*)p_cont->destination_id.value; - uint64_t trans_num = *(uint8_t*)p_cont->transaction_id.value; - uint32_t src_id = *(uint8_t*)p_cont->originator_id.value; + uint32_t dest_id = p_cont->destination_id; + uint64_t trans_num = p_cont->transaction_id; + uint32_t src_id = p_cont->originator_id; int error = get_req_from_file(src_id, trans_num, dest_id, req); if (error < 0) { @@ -140,7 +140,8 @@ create_message_put_proxy(uint32_t beneficial_cfid, create_lv(&message->destination_file_name, strnlen(dest_name, MAX_PATH) + 1, dest_name); create_lv(&message->source_file_name, strnlen(source_name, MAX_PATH) + 1, source_name); - create_lv(&message->destination_id, length_of_id, &beneficial_cfid); + message->destination_id = beneficial_cfid; + return message; } @@ -167,30 +168,24 @@ int add_proxy_message_to_request(uint32_t beneficial_cfid, Message_cont_part_request * create_message_cont_partial_request(uint32_t beneficial_cfid, - uint8_t beneficial_id_length, uint32_t originator_id, - uint8_t originator_id_length, - uint32_t transaction_id, - uint8_t transaction_id_length) { + uint32_t transaction_id) { Message_cont_part_request *message = ssp_alloc(1, sizeof(Message_cont_part_request)); if (message == NULL) return NULL; - create_lv(&message->destination_id, beneficial_id_length, &beneficial_cfid); - create_lv(&message->originator_id, originator_id_length, &originator_id); - create_lv(&message->transaction_id, transaction_id_length, &transaction_id); + message->destination_id = beneficial_cfid; + message->originator_id = originator_id; + message->transaction_id = transaction_id; return message; } //beneficial_cfid is the destination id that the proxy will send to, originator //is the sender's id int add_cont_partial_message_to_request(uint32_t beneficial_cfid, - uint8_t beneficial_id_length, uint32_t originator_id, - uint8_t originator_id_length, uint32_t transaction_id, - uint8_t transaction_id_length, Request *req){ Message *message = create_message(CONTINUE_PARTIAL); @@ -198,11 +193,8 @@ int add_cont_partial_message_to_request(uint32_t beneficial_cfid, return -1; message->value = create_message_cont_partial_request(beneficial_cfid, - beneficial_id_length, originator_id, - originator_id_length, - transaction_id, - transaction_id_length + transaction_id ); if (message->value == NULL) { ssp_free(message); @@ -218,14 +210,10 @@ static void ssp_free_put_proxy_message(Message_put_proxy* message) { free_lv(message->destination_file_name); free_lv(message->source_file_name); - free_lv(message->destination_id); } static void ssp_free_proxy_cont_partial_request(Message_cont_part_request *message) { - free_lv(message->destination_id); - free_lv(message->originator_id); - free_lv(message->transaction_id); } void ssp_free_message(void *params) { @@ -339,7 +327,7 @@ void add_request_to_client(Request *req, Client *client) { req->my_cfdp_id = client->app->my_cfdp_id; req->buff = client->buff; req->buff_len = client->packet_len; - client->request_list->insert(client->request_list, req, 0); + client->request_list->insert(client->request_list, req, -1); start_request(req); } @@ -536,7 +524,6 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ } add_request_to_client(req, client); - start_request(req); error = ssp_close(fd); if (error < 0) { @@ -573,8 +560,7 @@ static void print_messages_callback(Node *node, void *element, void *args) { ssp_printf("Message type: PROXY_PUT_REQUST\n"); ssp_printf("dest filename: %s\n", proxy->destination_file_name.value); ssp_printf("source filename: %s\n", proxy->source_file_name.value); - ssp_printf("id lendth: %d\n", proxy->destination_id.length); - ssp_printf("id: %d\n", *(uint8_t*) proxy->destination_id.value); + ssp_printf("id: %d\n", *(uint8_t*) proxy->destination_id); } diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 3728e0b..21f4d53 100755 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -200,21 +200,21 @@ int test_get_file(){ ASSERT_EQUALS_STR("third message src file name", proxy_message->destination_file_name.value, dest_file, proxy_message->destination_file_name.length); ASSERT_EQUALS_STR("third message src file name", proxy_message->source_file_name.value, src_file, proxy_message->source_file_name.length); - ASSERT_EQUALS_INT("third message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + ASSERT_EQUALS_INT("third message id", proxy_message->destination_id, req->dest_cfdp_id); ssp_free_message(message); message = req->messages_to_user->pop(req->messages_to_user); proxy_message = (Message_put_proxy *) message->value; ASSERT_EQUALS_STR("second message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); ASSERT_EQUALS_STR("second message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); - ASSERT_EQUALS_INT("second message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + ASSERT_EQUALS_INT("second message id", proxy_message->destination_id, req->dest_cfdp_id); ssp_free_message(message); message = req->messages_to_user->pop(req->messages_to_user); proxy_message = (Message_put_proxy *) message->value; ASSERT_EQUALS_STR("first message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); ASSERT_EQUALS_STR("first message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); - ASSERT_EQUALS_INT("first message id", *(uint8_t*)proxy_message->destination_id.value, req->dest_cfdp_id); + ASSERT_EQUALS_INT("first message id", proxy_message->destination_id, req->dest_cfdp_id); ssp_free_message(message); ssp_cleanup_req(req); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index dec99b4..7655cf2 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -345,8 +345,12 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ uint32_t packet_index = start; + uint64_t dest_id_original = 5; + uint64_t original_id_original = 33; + uint64_t transaction_id_original = 66; + Request *req = mock_empty_request(); - int error = add_cont_partial_message_to_request(1,1,1,1,1,1,req); + int error = add_cont_partial_message_to_request(dest_id_original,original_id_original,transaction_id_original,req); memset(&packet[start], 0, 100); packet_index = add_messages_to_packet(packet, packet_index, req->messages_to_user); @@ -354,7 +358,7 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ ASSERT_EQUALS_STR("'cfdp' should be at the start of the message", &packet[start], "cfdp", 5); ASSERT_EQUALS_INT("testing CONTINUE_PARTIAL code", (uint8_t) packet[start + 5], CONTINUE_PARTIAL); - LV dest_id, original_id, transaction_id; + uint64_t dest_id, original_id, transaction_id; packet_index = start + 6; error = copy_id_lv_from_packet(&packet[packet_index], &dest_id); @@ -363,10 +367,8 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ return -1; } - ASSERT_EQUALS_INT("dest_id.length", dest_id.length, 1); - ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*) (dest_id.value), 1); - packet_index += dest_id.length + 1; - free_lv(dest_id); + ASSERT_EQUALS_INT("dest_id", dest_id, dest_id_original); + packet_index += 1 + 1; error = copy_id_lv_from_packet(&packet[packet_index], &original_id); if (error < 0) { @@ -374,10 +376,8 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ return -1; } - ASSERT_EQUALS_INT("original_id.length", original_id.length, 1); - ASSERT_EQUALS_INT("original_id.value", *(uint8_t*)original_id.value, 1); - packet_index += original_id.length + 1; - free_lv(original_id); + ASSERT_EQUALS_INT("original_id", original_id, original_id_original); + packet_index += 1 + 1; error = copy_id_lv_from_packet(&packet[packet_index], &transaction_id); if (error < 0) { @@ -385,9 +385,7 @@ int test_add_cont_part_to_packet(char *packet, uint32_t start){ return -1; } - ASSERT_EQUALS_INT("dest_file.length", transaction_id.length, 1); - ASSERT_EQUALS_INT("dest_file.value", *(uint8_t*)transaction_id.value, transaction_id.length); - free_lv(transaction_id); + ASSERT_EQUALS_INT("transaction_id", transaction_id, transaction_id_original); ssp_cleanup_req(req); @@ -464,14 +462,9 @@ int test_get_message_from_packet(char *packet, uint32_t start) { Message *m = req2->messages_to_user->pop(req2->messages_to_user); Message_put_proxy *p_message = m->value; - ASSERT_EQUALS_INT("dest_file.length", p_message->destination_file_name.length, strnlen(dest, 100) + 1); ASSERT_EQUALS_STR("dest_file.value", p_message->destination_file_name.value, dest, strnlen(dest, 100)); - - ASSERT_EQUALS_INT("src_file.length", p_message->source_file_name.length, strnlen(src, 100) + 1); ASSERT_EQUALS_STR("src_file.value", src, p_message->source_file_name.value, strnlen(src, 100)); - - ASSERT_EQUALS_INT("dest_id.length", p_message->destination_id.length, len); - ASSERT_EQUALS_INT("dest_id.value", *(uint8_t*)p_message->destination_id.value, id); + ASSERT_EQUALS_INT("dest_id.value", p_message->destination_id, id); ASSERT_EQUALS_INT("next message should be at index ", next_message, length_of_message); @@ -489,7 +482,7 @@ int test_get_cont_partial_from_packet(char *packet, uint32_t start){ uint32_t packet_index = start; Request *req = mock_empty_request(); - int error = add_cont_partial_message_to_request(1,1,1,1,1,1,req); + int error = add_cont_partial_message_to_request(1,1,1,req); memset(&packet[start], 0, 100); add_messages_to_packet(packet, packet_index, req->messages_to_user); @@ -501,20 +494,13 @@ int test_get_cont_partial_from_packet(char *packet, uint32_t start){ Message_cont_part_request *p_message = (Message_cont_part_request *) m->value; - ASSERT_EQUALS_INT("destination_id.length", p_message->destination_id.length, 1); - ASSERT_EQUALS_INT("destination_id.value", *(uint8_t*) (p_message->destination_id.value), 1); - packet_index += p_message->destination_id.length + 1; - free_lv(p_message->destination_id); + ASSERT_EQUALS_INT("destination_id.value", p_message->destination_id, 1); + + ASSERT_EQUALS_INT("originator_id.value", p_message->originator_id, 1); + + ASSERT_EQUALS_INT("transaction_id.value", p_message->transaction_id, 1); - ASSERT_EQUALS_INT("originator_id.length", p_message->originator_id.length, 1); - ASSERT_EQUALS_INT("originator_id.value", *(uint8_t*) (p_message->originator_id.value), 1); - packet_index += p_message->originator_id.length + 1; - free_lv(p_message->originator_id); - ASSERT_EQUALS_INT("transaction_id.length", p_message->transaction_id.length, 1); - ASSERT_EQUALS_INT("transaction_id.value", *(uint8_t*) (p_message->transaction_id.value), 1); - packet_index += p_message->transaction_id.length + 1; - free_lv(p_message->transaction_id); } @@ -552,7 +538,7 @@ int test_get_messages_from_packet(char *packet, uint32_t start) { if (message->header.message_type == PROXY_PUT_REQUEST) { Message_put_proxy *p_message = (Message_put_proxy *) message->value; - ASSERT_EQUALS_INT("received proxy messages: dest.id", *(uint8_t*) p_message->destination_id.value, id); + ASSERT_EQUALS_INT("received proxy messages: dest.id", p_message->destination_id, id); ASSERT_EQUALS_STR("received proxy messages: src file", src, (char *) p_message->source_file_name.value, p_message->source_file_name.length); ASSERT_EQUALS_STR("received proxy messages: dest file", dest, (char *) p_message->destination_file_name.value, p_message->destination_file_name.length); @@ -587,6 +573,61 @@ int test_build_finished_pdu(char *packet, uint32_t start) { ASSERT_EQUALS_INT("file_status FILE_RETAINED_SUCCESSFULLY set", fin.file_status, FILE_RETAINED_SUCCESSFULLY); } + +int test_copying_lvs(){ + + DECLARE_NEW_TEST("testing copying and reading LVs "); + uint64_t id = 184; + char packet[250]; + + int error = copy_id_lv_to_packet(packet, id); + + uint64_t id_received = 0; + uint64_t len = copy_id_lv_from_packet(packet, &id_received); + if (len < 0) { + ssp_printf("failed to copy contents from buffer \n"); + return -1; + } + ASSERT_EQUALS_INT("ids should equal 232", (uint32_t)id_received, 184); + ASSERT_EQUALS_INT("len should be 1", len, 1); + + + id = 6699; + error = copy_id_lv_to_packet(packet, id); + + id_received = 0; + len = copy_id_lv_from_packet(packet, &id_received); + if (len < 0) { + ssp_printf("failed to copy contents from buffer \n"); + return -1; + } + ASSERT_EQUALS_INT("ids should equal 6699", (uint32_t)id_received, 6699); + ASSERT_EQUALS_INT("len should be 2", len, 2); + + id = 15406584; + error = copy_id_lv_to_packet(packet, id); + + id_received = 0; + len = copy_id_lv_from_packet(packet, &id_received); + if (len < 0) { + ssp_printf("failed to copy contents from buffer \n"); + return -1; + } + ASSERT_EQUALS_INT("ids should equal 15406584", (uint32_t)id_received, 15406584); + ASSERT_EQUALS_INT("len should be 4", len, 4); + id = 32500405; + error = copy_id_lv_to_packet(packet, id); + + id_received = 0; + len = copy_id_lv_from_packet(packet, &id_received); + if (len < 0) { + ssp_printf("failed to copy contents from buffer \n"); + return -1; + } + ASSERT_EQUALS_INT("ids should equal 32500405", (uint32_t)id_received, 32500405); + ASSERT_EQUALS_INT("len should be 8", len, 8); + +} int packet_tests() { //setting host name for testing @@ -602,21 +643,27 @@ int packet_tests() { int error = get_remote_entity_from_json (&remote_entity, 1); get_header_from_mib(&pdu_header, remote_entity, 2); + error = test_copying_lvs(); int data_start_index = test_build_pdu_header(packet, &pdu_header); - //test_build_metadata_packet(packet, data_start_index); - //test_get_messages_from_packet(packet, data_start_index); - //test_add_cont_part_to_packet(packet, data_start_index); - //test_get_cont_partial_from_packet(packet, data_start_index); - //test_build_ack_eof_pdu(packet, data_start_index); - - //test_build_eof_packet(packet, data_start_index); - //test_build_data_packet(packet, data_start_index); + + test_build_metadata_packet(packet, data_start_index); + test_get_messages_from_packet(packet, data_start_index); + + + test_add_cont_part_to_packet(packet, data_start_index); + + test_get_cont_partial_from_packet(packet, data_start_index); + test_build_ack_eof_pdu(packet, data_start_index); + + test_build_eof_packet(packet, data_start_index); + test_build_data_packet(packet, data_start_index); test_build_nak_packet(packet, data_start_index); test_build_finished_pdu(packet, data_start_index); + test_add_messages_to_packet(packet, data_start_index); + test_get_message_from_packet(packet, data_start_index); //next up - //Skip for now, will fix after connection server works //test_build_very_large_nak_packet(packet, data_start_index); @@ -625,11 +672,8 @@ int packet_tests() { //need to fix this for byte order //need to fix this for byte order - - //test_add_messages_to_packet(packet, data_start_index); - //test_get_message_from_packet(packet, data_start_index); - //test_add_cont_part_to_packet(packet, data_start_index); + return 0; diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index 75a6022..fca1181 100755 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -59,13 +59,13 @@ static int request_finding_test() { req->transaction_sequence_number, }; - Request *found = list->find(list, 0, find_request, ¶ms); + Request *found = list->find(list, -1, find_request, ¶ms); params.source_id = 3; params.transaction_sequence_number = 1; - Request *found2 = list->find(list, 0, find_request, ¶ms); + Request *found2 = list->find(list, -1, find_request, ¶ms); params.source_id = 2; params.transaction_sequence_number = 2; - Request *found3 = list->find(list, 0, find_request, ¶ms); + Request *found3 = list->find(list, -1, find_request, ¶ms); if (found == NULL) { ssp_printf("CAN't FIND request IS NULL\n"); @@ -120,7 +120,7 @@ static int add_proxy_message() { ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); Message_put_proxy *proxy = (Message_put_proxy *) message->value; - ASSERT_EQUALS_STR("proxy dest_id should equal 2", proxy->destination_id.value, &id, len); + ASSERT_EQUALS_STR("proxy dest_id should equal 2", proxy->destination_id, &id, len); ASSERT_EQUALS_STR("proxy src file", proxy->source_file_name.value, src, proxy->source_file_name.length); ASSERT_EQUALS_STR("proxy dest file", proxy->destination_file_name.value, dest, proxy->destination_file_name.length); @@ -137,9 +137,9 @@ int init_cont_partial_request_test_fail() { uint64_t tran_id = 0; Request *req = mock_request(); - p_cont.destination_id.value = &dest_id; - p_cont.originator_id.value = &org_id; - p_cont.transaction_id.value = &tran_id; + p_cont.destination_id = &dest_id; + p_cont.originator_id = &org_id; + p_cont.transaction_id = &tran_id; uint32_t buff_len = 1500; char buff[buff_len]; @@ -163,9 +163,9 @@ int init_cont_partial_request_test() { save_req_to_file(req); - p_cont.destination_id.value = &dest_id; - p_cont.originator_id.value = &org_id; - p_cont.transaction_id.value = &tran_id; + p_cont.destination_id = &dest_id; + p_cont.originator_id = &org_id; + p_cont.transaction_id = &tran_id; uint32_t buff_len = 1500; char buff[buff_len]; @@ -197,20 +197,17 @@ static int add_continue_partial_message_test() { error = add_cont_partial_message_to_request( dest_id, - len, src_id, - len, transaction_id, - 4, req); Message *message = req->messages_to_user->pop(req->messages_to_user); ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); Message_cont_part_request *proxy = (Message_cont_part_request *) message->value; - ASSERT_EQUALS_STR("proxy dest_id should equal 1", proxy->destination_id.value, &dest_id, proxy->destination_id.length); - ASSERT_EQUALS_STR("proxy originator id should equal 1", proxy->originator_id.value, &src_id, proxy->originator_id.length); - ASSERT_EQUALS_STR("proxy transaction id should equal 4444", proxy->transaction_id.value, &transaction_id, proxy->transaction_id.length); + ASSERT_EQUALS_STR("proxy dest_id should equal 1", proxy->destination_id, &dest_id, proxy->destination_id); + ASSERT_EQUALS_STR("proxy originator id should equal 1", proxy->originator_id, &src_id, proxy->originator_id); + ASSERT_EQUALS_STR("proxy transaction id should equal 4444", proxy->transaction_id, &transaction_id, proxy->transaction_id); ssp_free_message(message); ssp_cleanup_req(req); From 2dc505420713de4004da9da455ca880bcf2c60e2 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 11 Mar 2021 12:31:45 -0700 Subject: [PATCH 305/400] better error haling for creating packets. id length --- Program/src/packet.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Program/src/packet.c b/Program/src/packet.c index 7196589..aee326a 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -64,7 +64,7 @@ int copy_id_to_packet(char *bytes, uint64_t id) { memcpy(bytes, &network_byte_order, sizeof(uint64_t)); length = 8; } else { - ssp_error("copying to packet, id size is not supported, please user 1, 2 or 4"); + ssp_error("copying to packet, id size is not supported, please user 1, 2 or 4, 8"); return -1; } @@ -94,6 +94,8 @@ uint64_t copy_id_from_packet(char *bytes, uint32_t length_of_ids) { //returns amount of bytes written or -1 on error int copy_id_lv_to_packet(char *bytes, uint64_t id) { + + int len = copy_id_to_packet(&bytes[1], id); if (len < 0) { return -1; @@ -104,7 +106,7 @@ int copy_id_lv_to_packet(char *bytes, uint64_t id) { } //returns length of the id on success and sets id to the id, or -1 on error -int copy_id_lv_from_packet(char *bytes, uint32_t *id){ +int copy_id_lv_from_packet(char *bytes, uint64_t *id){ uint8_t len = bytes[0]; @@ -201,21 +203,21 @@ int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_ set_bits_to_protocol_byte(&packet[3], 5,7, pdu_header->transaction_seq_num_len); int32_t source_id_location = PACKET_STATIC_HEADER_LEN; - int error = copy_id_to_packet(&packet[source_id_location], pdu_header->source_id); - if (error < 0) { + int len = copy_id_to_packet(&packet[source_id_location], pdu_header->source_id); + if (len < 0 || len != pdu_header->length_of_entity_IDs) { ssp_error("failed copy source_id"); return -1; } int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; - error = copy_id_to_packet(&packet[transaction_number_location], (uint32_t) transaction_sequence_number); - if (error < 0) { + len = copy_id_to_packet(&packet[transaction_number_location], transaction_sequence_number); + if (len < 0 || len != pdu_header->transaction_seq_num_len) { ssp_error("failed copy transaction_number_location"); return -1; } int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; - error = copy_id_to_packet(&packet[dest_id_location], pdu_header->destination_id); - if (error < 0) { + len = copy_id_to_packet(&packet[dest_id_location], pdu_header->destination_id); + if (len < 0 || len != pdu_header->length_of_entity_IDs) { ssp_error("failed copy destination_id"); return -1; } @@ -664,7 +666,7 @@ static void add_messages_callback(Node *node, void *element, void *args) { { case PROXY_PUT_REQUEST: proxy_put = (Message_put_proxy *) message->value; - + bytes = copy_id_lv_to_packet(&packet[packet_index], proxy_put->destination_id); if (bytes < 0) { ssp_printf(error_msg, "PROXY_PUT_REQUEST"); From 00163e98dccdd212d8ee28ff5f95d8650d587de9 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 11 Mar 2021 12:32:38 -0700 Subject: [PATCH 306/400] going through protocol handler unit tests --- Program/test/mock.c | 5 +++++ Program/test/packet_tests.c | 23 +++++++++-------------- Program/test/protocol_handler_tests.c | 22 +++++++++++++++++----- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/Program/test/mock.c b/Program/test/mock.c index dcd72f0..41363bf 100755 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -47,6 +47,11 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { mock_mock_remote_entity(&remote_entity, dest_id); int error = get_header_from_mib(&pdu_header, remote_entity, src_id); + + pdu_header.transaction_seq_num_len = 1; + pdu_header.transaction_sequence_number = 1; + + int packet_index = build_pdu_header(packet, 1, 0, 0, &pdu_header); return packet_index; } diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 7655cf2..4d3e891 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -265,14 +265,20 @@ int test_build_pdu_header(char *packet, Pdu_header *header) { uint32_t packet_index = 0; //ssp_print_bits(header, 4); Pdu_header new_header; - header->transaction_sequence_number = 321; + header->transaction_sequence_number = 325; + header->transaction_seq_num_len = 2; memset(&new_header, 0, 4); - uint8_t length = build_pdu_header(packet, header->transaction_sequence_number, header->direction, header->PDU_data_field_len, header); + int length = build_pdu_header(packet, header->transaction_sequence_number, header->direction, header->PDU_data_field_len, header); + if (length < 0) { + ssp_printf("failed to build pdu header\n"); + } + ssp_print_bits(&packet[4], 10); get_pdu_header_from_packet(packet, &new_header); + ASSERT_EQUALS_INT("CRC = CRC", header->CRC_flag, new_header.CRC_flag); ASSERT_EQUALS_INT("direction = direction", header->direction, new_header.direction); ASSERT_EQUALS_INT("length_of_entity_IDs = length_of_entity_IDs ", header->length_of_entity_IDs, new_header.length_of_entity_IDs); @@ -288,6 +294,7 @@ int test_build_pdu_header(char *packet, Pdu_header *header) { ASSERT_EQUALS_INT("packet length: ", length, (header->transaction_seq_num_len + (header->length_of_entity_IDs * 2) + 4)); ASSERT_EQUALS_INT("packet source id ", header->source_id, new_header.source_id); + ssp_printf("%d\n", new_header.transaction_sequence_number); ASSERT_EQUALS_INT("transaction_sequence_number correctly placed ", header->transaction_sequence_number, new_header.transaction_sequence_number); ASSERT_EQUALS_INT("packet destination id ", header->destination_id, new_header.destination_id); @@ -648,10 +655,7 @@ int packet_tests() { test_build_metadata_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); - - test_add_cont_part_to_packet(packet, data_start_index); - test_get_cont_partial_from_packet(packet, data_start_index); test_build_ack_eof_pdu(packet, data_start_index); @@ -666,15 +670,6 @@ int packet_tests() { //Skip for now, will fix after connection server works //test_build_very_large_nak_packet(packet, data_start_index); - - memset(packet, 0, PACKET_TEST_SIZE); - - //need to fix this for byte order - - //need to fix this for byte order - - - return 0; } diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index 332d1e0..a858829 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -52,7 +52,6 @@ int test_on_server_time_out() { //Response res, Request *req Request *req = mock_request(); req->paused = false; - req->procedure = sending_data; //no meta data received, sending request for new one (can't send NAKs yet, because we don't know filesize) on_server_time_out(req->res, req); @@ -74,6 +73,10 @@ int test_on_server_time_out() { static int test_wrong_id(FTP *app) { + + + DECLARE_NEW_TEST("testing wrong id"); + int error = 0; Response *res = mock_response(); char packet[2000]; @@ -95,6 +98,9 @@ static int test_wrong_id(FTP *app) { } static int test_correct_id(FTP *app) { + + DECLARE_NEW_TEST("testing correct id"); + int error = 0; Response *res = mock_response(); char packet[2000]; @@ -104,7 +110,7 @@ static int test_correct_id(FTP *app) { Request **req_container = &app->current_request; Pdu_header incoming_pdu_header; - process_pdu_header(packet, true, &incoming_pdu_header,*res, req_container, app->request_list, app); + process_pdu_header(packet, true, &incoming_pdu_header, *res, req_container, app->request_list, app); Request *req = (*req_container); error = ASSERT_NOT_NULL("Test request, Request should not be NULL", req); @@ -120,6 +126,7 @@ static int test_process_pdu_header() { char buff[1500]; int error = 0; FTP *app = ssp_alloc(1, sizeof(FTP)); + app->request_list = linked_list(); app->packet_len = 1500; app->buff = buff; @@ -127,6 +134,7 @@ static int test_process_pdu_header() { error = test_wrong_id(app); error = test_correct_id(app); + app->request_list->free(app->request_list, ssp_cleanup_req); ssp_free(app); @@ -194,14 +202,18 @@ int test_process_nak() { return error; } +void test_send_data_from_nak_array(){ +} + int protocol_handler_test() { int error = 0; - //error = test_process_pdu_header(); + error = test_process_pdu_header(); //error = test_process_pdu_eof(); //error = test_on_server_time_out(); - error = test_process_data_packet(); - error = test_process_nak(); + //error = test_process_data_packet(); + //error = test_process_nak(); + return error; } \ No newline at end of file From 05312cb10ba307ffda6b850e51721cdc9a244535 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 11 Mar 2021 16:45:13 -0700 Subject: [PATCH 307/400] repair data_packet, fix checksum function, add tests --- Program/src/filesystem_funcs.c | 5 ++- Program/src/packet.c | 5 ++- Program/src/protocol_handler.c | 11 ++++- Program/test/mib/peer_0.json | 21 +++++++++ Program/test/mib/peer_10.json | 21 +++++++++ Program/test/mock.c | 3 +- Program/test/protocol_handler_tests.c | 51 +++++++++++++--------- Program/test/test_files/eof_test | 0 Program/test/test_files/peer_0.json | 21 +++++++++ Program/test/test_files/received_peer.json | 21 +++++++++ 10 files changed, 131 insertions(+), 28 deletions(-) create mode 100755 Program/test/mib/peer_0.json create mode 100755 Program/test/mib/peer_10.json create mode 100755 Program/test/test_files/eof_test create mode 100755 Program/test/test_files/peer_0.json create mode 100755 Program/test/test_files/received_peer.json diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index c12eded..0cbcc37 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -170,9 +170,10 @@ uint32_t check_sum_file(File *file, uint16_t stack_buffer) { uint32_t checksum = 0; uint32_t bytes_read = 0; int i = 0; - for (i = 0; i < file->total_size; i++) { + + for (i = 0; i < file->total_size; i+= stack_buffer) { - bytes_read = get_offset(file, buff, stack_buffer, (int) stack_buffer); + bytes_read = get_offset(file, buff, stack_buffer, i); if (bytes_read > 0) checksum += calc_check_sum(buff, bytes_read); } diff --git a/Program/src/packet.c b/Program/src/packet.c index aee326a..c06b249 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -365,8 +365,9 @@ int build_data_packet(char *packet, uint32_t start, uint32_t end, uint32_t offse uint32_t net_offset = ssp_ntohl(offset); memcpy(&packet[packet_index], &net_offset, sizeof(uint32_t)); - packet_index += 4; - int bytes = get_offset(file, &packet[packet_index], data_size, offset); + packet_index += sizeof(uint32_t); + + int bytes = get_offset(file, &packet[packet_index], data_size - 4, offset); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); return -1; diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index db7315e..358b731 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -220,8 +220,10 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { // size of 'offset' bytes in packet uint32_t offset_end = offset_start + data_len - packet_index; - if (!receive_offset(file, 0, offset_start, offset_end)) + if (!receive_offset(file, 0, offset_start, offset_end)) { + ssp_printf("throwing out packet\n"); return; + } uint32_t remaining_buffer_length = data_len - packet_index; int bytes = write_offset(file, &packet[packet_index], remaining_buffer_length, offset_start); @@ -395,10 +397,15 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t } uint32_t packet_index = start; - uint32_t size_of_offset_bytes = 4; + uint32_t size_of_offset_bytes = sizeof(uint32_t); int data_len = build_data_packet(packet, packet_index, length, file->next_offset_to_send, file); + + ssp_printf("%d\n", data_len); + packet_index += size_of_offset_bytes; + + //number of bytes sent int bytes = data_len - size_of_offset_bytes; //calculate checksum for data packet, this is used to calculate in transit checksums diff --git a/Program/test/mib/peer_0.json b/Program/test/mib/peer_0.json new file mode 100755 index 0000000..48f258f --- /dev/null +++ b/Program/test/mib/peer_0.json @@ -0,0 +1,21 @@ +{ + "cfdp_id": 0, + "UT_address" : 0, + "UT_port" : 20, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/mib/peer_10.json b/Program/test/mib/peer_10.json new file mode 100755 index 0000000..db30b59 --- /dev/null +++ b/Program/test/mib/peer_10.json @@ -0,0 +1,21 @@ +{ + "cfdp_id": 10, + "UT_address" : 10, + "UT_port" : 1, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/mock.c b/Program/test/mock.c index 41363bf..9485911 100755 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -58,10 +58,9 @@ int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id) { File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *file_name) { - int packet_index = mock_packet(packet, dest_id, src_id); File *file = create_file(file_name, false); file->partial_checksum = check_sum_file(file, 1000); - build_eof_packet(packet, packet_index, file->total_size, check_sum_file(file, 1000)); + build_eof_packet(packet, 10, file->total_size, file->partial_checksum); return file; } diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index a858829..f14751b 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -18,16 +18,19 @@ static int test_process_pdu_eof() { char packet[2000]; - //test images + //builds the packet at offset 10 File *file = mock_eof_packet(packet, 1, 2, "test_files/dest.jpg"); + uint32_t first_checksum = file->partial_checksum; + uint32_t first_file_size = file->total_size; + Request *req = mock_empty_request(); - req->file = file; + req->file = create_file("test_files/eof_test", true); - process_pdu_eof(&packet[10], req, req->res); + process_pdu_eof(&packet[11], req, req->res); ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity.EOF_recv_indication, true); - ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); - ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); + ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, first_checksum); + ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, first_file_size); ssp_cleanup_req(req); @@ -36,8 +39,8 @@ static int test_process_pdu_eof() { req = mock_empty_request(); req->file = file; - process_pdu_eof(&packet[10], req, req->res); - + process_pdu_eof(&packet[11], req, req->res); + ASSERT_EQUALS_INT("received eof, increment EOF_rec_indication", req->local_entity.EOF_recv_indication, true); ASSERT_EQUALS_INT("received eof, checksum should equal", req->file->eof_checksum, file->partial_checksum); ASSERT_EQUALS_INT("received eof, filesize should equal", req->file->total_size, file->total_size); @@ -142,28 +145,36 @@ static int test_process_pdu_header() { } int test_process_data_packet() { + + DECLARE_NEW_TEST("testing process data packet"); + char packet[1500]; uint32_t start = 20; - uint32_t data_len = sizeof(packet) - start; + uint32_t packet_len = 120; memset(packet, 0, 1500); - File *file = create_file("test_files/data_pdu_test.jpg", 0); - int error = create_data_burst_packets(packet, start, file, data_len); - - File *file2 = create_file("test_files/test_file.jpg", 1); + File *file = create_file("test_files/peer_0.json", 0); + File *file2 = create_file("test_files/received_peer.json", 1); //mimics process_file_request_metadata function add_first_offset(file2, file->total_size); + + + int error = create_data_burst_packets(packet, start, file, packet_len); + uint32_t data_len = get_data_length(packet); process_data_packet(&packet[start], data_len, file2); - ASSERT_EQUALS_INT("Checksum", file2->partial_checksum, -606714363); - ASSERT_EQUALS_INT("Length of offset list should equal 1 ", file2->missing_offsets->count, 1); - Offset* offset2 = (Offset*) file2->missing_offsets->pop(file2->missing_offsets); + int i = 0; + for (i = 0; i < 7; i++) { + create_data_burst_packets(packet, start, file, packet_len); + data_len = get_data_length(packet); + process_data_packet(&packet[start], data_len, file2); + } + uint32_t checksum = check_sum_file(file, packet_len-start-4); - //data_len - 4 byte offset value - ASSERT_EQUALS_INT("offset start should equal datasize ", offset2->start, data_len - 4); - ASSERT_EQUALS_INT("offset end equal end of file ", offset2->end, file->total_size); + ASSERT_EQUALS_INT("Checksum", file2->partial_checksum, checksum); + ASSERT_EQUALS_INT("Length of offset list should equal 1 ", file2->missing_offsets->count, 0); ssp_free_file(file); ssp_free_file(file2); @@ -210,9 +221,9 @@ void test_send_data_from_nak_array(){ int protocol_handler_test() { int error = 0; error = test_process_pdu_header(); - //error = test_process_pdu_eof(); + error = test_process_pdu_eof(); //error = test_on_server_time_out(); - //error = test_process_data_packet(); + error = test_process_data_packet(); //error = test_process_nak(); return error; diff --git a/Program/test/test_files/eof_test b/Program/test/test_files/eof_test new file mode 100755 index 0000000..e69de29 diff --git a/Program/test/test_files/peer_0.json b/Program/test/test_files/peer_0.json new file mode 100755 index 0000000..48f258f --- /dev/null +++ b/Program/test/test_files/peer_0.json @@ -0,0 +1,21 @@ +{ + "cfdp_id": 0, + "UT_address" : 0, + "UT_port" : 20, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file diff --git a/Program/test/test_files/received_peer.json b/Program/test/test_files/received_peer.json new file mode 100755 index 0000000..48f258f --- /dev/null +++ b/Program/test/test_files/received_peer.json @@ -0,0 +1,21 @@ +{ + "cfdp_id": 0, + "UT_address" : 0, + "UT_port" : 20, + "type_of_network" : 3, + "default_transmission_mode" : 1, + "MTU" : 250, + "one_way_light_time" : 123, + "total_round_trip_allowance" : 123, + "async_NAK_interval" : 123, + "async_keep_alive_interval" : 123, + "async_report_interval" : 123, + "immediate_nak_mode_enabled" : 123, + "prompt_transmission_interval" : 123, + "disposition_of_incomplete" : 123, + "CRC_required" : 0, + "keep_alive_discrepancy_limit" : 8, + "positive_ack_timer_expiration_limit" : 123, + "nak_timer_expiration_limit" : 123, + "transaction_inactivity_limit" : 123 +} \ No newline at end of file From eacc2de45881115a5f8e5bfa922935eb3d43f10c Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 11 Mar 2021 17:06:17 -0700 Subject: [PATCH 308/400] fix mib bug, id sizes and seq num sizes need to be predefined --- Program/src/file_delivery_app.c | 3 ++- Program/src/mib.c | 4 ++-- Program/src/packet.c | 13 +++++++------ Program/src/protocol_handler.c | 3 --- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 37595af..ddf0d95 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -172,7 +172,8 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { app->packet_len = remote_entity.mtu; app->buff = ssp_alloc(1, app->packet_len); - + app->transaction_sequence_number = 0; + if (app->buff == NULL) { ssp_free(app); return -1; diff --git a/Program/src/mib.c b/Program/src/mib.c index 96c32c8..7a846e3 100755 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -11,7 +11,7 @@ Author: Evan Giese #include "packet.h" - +//todo int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t my_cfdp_id) { pdu_header->reserved_bit_0 = 0; @@ -20,7 +20,7 @@ int get_header_from_mib(Pdu_header *pdu_header, Remote_entity remote, uint32_t m pdu_header->CRC_flag = remote.CRC_required; pdu_header->direction = 1; pdu_header->PDU_type = 0; - pdu_header->transaction_seq_num_len = 2; + pdu_header->transaction_seq_num_len = 1; pdu_header->length_of_entity_IDs = 1; pdu_header->transmission_mode = remote.default_transmission_mode; pdu_header->destination_id = remote.cfdp_id; diff --git a/Program/src/packet.c b/Program/src/packet.c index c06b249..08dc317 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -46,10 +46,10 @@ void set_packet_directive(char *packet, uint32_t location, uint8_t directive){ //returns length of ids or -1 on error int copy_id_to_packet(char *bytes, uint64_t id) { + uint32_t length = 0; if (id < 0xFF){ - uint8_t network_byte_order = (uint8_t) id; - memcpy(bytes, &network_byte_order, sizeof(uint8_t)); + bytes[0] = (uint8_t) id; length = 1; } else if (id < 0xFFFF) { uint16_t network_byte_order = ssp_htons((uint16_t) id); @@ -68,6 +68,7 @@ int copy_id_to_packet(char *bytes, uint64_t id) { return -1; } + return length; } @@ -202,20 +203,20 @@ int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_ set_bits_to_protocol_byte(&packet[3], 4,4, pdu_header->reserved_bit_2); set_bits_to_protocol_byte(&packet[3], 5,7, pdu_header->transaction_seq_num_len); - int32_t source_id_location = PACKET_STATIC_HEADER_LEN; + uint32_t source_id_location = PACKET_STATIC_HEADER_LEN; int len = copy_id_to_packet(&packet[source_id_location], pdu_header->source_id); if (len < 0 || len != pdu_header->length_of_entity_IDs) { ssp_error("failed copy source_id"); return -1; } - int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; + uint32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; len = copy_id_to_packet(&packet[transaction_number_location], transaction_sequence_number); if (len < 0 || len != pdu_header->transaction_seq_num_len) { - ssp_error("failed copy transaction_number_location"); + ssp_printf("failed copy transaction_number_location %d suppose to be %d\n", len, pdu_header->transaction_seq_num_len); return -1; } - int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; + uint32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; len = copy_id_to_packet(&packet[dest_id_location], pdu_header->destination_id); if (len < 0 || len != pdu_header->length_of_entity_IDs) { ssp_error("failed copy destination_id"); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 358b731..8a5c227 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -401,8 +401,6 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t int data_len = build_data_packet(packet, packet_index, length, file->next_offset_to_send, file); - ssp_printf("%d\n", data_len); - packet_index += size_of_offset_bytes; //number of bytes sent @@ -844,7 +842,6 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque //process file data if (incoming_header.PDU_type == DATA) { - ssp_printf("received data packet\n"); if (!req->local_entity.Metadata_recv_indication) { if (req->file == NULL) { ssp_printf("file is null\n"); From f525d473bbf6b969a4399116ffa1490ae911d543 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 11 Mar 2021 17:09:08 -0700 Subject: [PATCH 309/400] set client-> close to false on init (TI problems) --- Program/src/file_delivery_app.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index ddf0d95..dbb744b 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -230,11 +230,12 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { ssp_error("couldn't get client remote_entity from mib\n"); return NULL; } - + + Client *client = ssp_alloc(sizeof(Client), 1); if (client == NULL) return NULL; - + client->request_list = linked_list(); if (client->request_list == NULL) { ssp_free(client); @@ -249,6 +250,7 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { return NULL; } + client->close = 0; client->remote_entity = remote_entity; get_header_from_mib(&client->pdu_header, remote_entity, app->my_cfdp_id); From 577be3e3876b660152097bf7424c3831960480b2 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 11 Mar 2021 17:11:26 -0700 Subject: [PATCH 310/400] improve ssp_alloc --- Program/src/port.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 322a524..908cb52 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -261,13 +261,16 @@ void ssp_sendto(Response res) { void *ssp_alloc(uint32_t n_memb, size_t size) { #ifdef FREE_RTOS_PORT - return pvPortMalloc(n_memb * size); + void *mem = pvPortMalloc(n_memb * size); + memset(mem, 0, n_memb * size); + return mem #else void *mem = calloc(n_memb, size); - if (mem == NULL) - ssp_error("Memory failed to alloc!\n"); - return mem; - #endif + #endif + if (mem == NULL) + ssp_error("Memory failed to alloc!\n"); + + return mem; } void ssp_free(void *pointer) { From fc1c658fd83bb77830159595ff42aca0b7447ad6 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Mar 2021 10:04:09 -0700 Subject: [PATCH 311/400] fix list --- Program/src/list.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Program/src/list.c b/Program/src/list.c index 6f6df52..9f7bbcd 100755 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -152,7 +152,7 @@ static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void if (f != NULL) found_with_func = f(cur->element, args); - if (id == cur->id) + if (id >= 0 && id == cur->id) found_with_id = 1; if (found_with_func || found_with_id) @@ -222,7 +222,7 @@ static void *findElement(List *list, uint32_t id, int (*f)(void *element, void * if (f != NULL) found_with_func = f(cur->element, args); - if(id != 0 && cur->id == id) + if(id >= 0 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id){ @@ -243,7 +243,7 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme if (f != NULL) found_with_func = f(cur->element, args); - if(id != 0 && cur->id == id) + if(id >= 0 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id) { @@ -271,7 +271,7 @@ static Node *findNode(List *list, uint32_t id, int (*f)(void *element, void *arg if (f != NULL) found_with_func = f(cur->element, args); - if(id != 0 && cur->id == id) + if(id >= 0 && cur->id == id) found_with_id = 1; if (found_with_func || found_with_id){ From 3fd25fb5a8af98f8587136b51781ab0333cd14d8 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Mar 2021 10:11:40 -0700 Subject: [PATCH 312/400] change some logging --- Program/src/posix_server_provider.c | 6 +++--- Program/src/protocol_handler.c | 13 +++++++------ Program/test/protocol_handler_tests.c | 8 ++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index f721dce..2893709 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -387,7 +387,7 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, } else { if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, other) == -1) - ssp_printf("recv failed\n"); + ssp_printf("recv failed server\n"); } } } @@ -456,7 +456,7 @@ void connectionless_client(char *hostname, char*port, int packet_len, void *para } else{ if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, params) == -1) - ssp_error("recv failed\n"); + ssp_error("recv failed client\n"); } } @@ -516,7 +516,7 @@ void connection_client(char *hostname, char*port, int packet_len, void *params, continue; if (onRecv(sfd, buff, count, buff_size, addr, size_of_addr, params) == -1) { - ssp_error("recv failed\n"); + ssp_error("recv failed client\n"); set_exit(); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 8a5c227..b47a03c 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -702,8 +702,6 @@ static void resend_finished_pdu(Request *req, Response res) { //processes the eof packet, sets checksum, indication, and filesize. void process_pdu_eof(char *packet, Request *req, Response res) { - ssp_printf("received eof packet transaction: %llu\n", req->transaction_sequence_number); - Pdu_eof eof_packet; get_eof_from_packet(packet, &eof_packet); @@ -748,7 +746,6 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, req->local_entity.Metadata_recv_indication = true; - ssp_printf("received metadata packet transaction: %llu\n", req->transaction_sequence_number); packet_index = parse_metadata_packet(packet, packet_index, req); uint16_t data_len = get_data_length(packet); @@ -839,6 +836,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque uint16_t data_len = get_data_length(packet); uint32_t packet_len = packet_index + data_len; + ssp_printf("transaction: %d ", incoming_header.transaction_sequence_number); //process file data if (incoming_header.PDU_type == DATA) { @@ -861,17 +859,20 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque case META_DATA_PDU: if (req->local_entity.Metadata_recv_indication) break; + + ssp_printf("received metadata packet transaction \n"); process_metadata(packet, packet_index, res, req, app); break; case EOF_PDU: if (req->local_entity.EOF_recv_indication) break; + + ssp_printf("received eof packet\n"); process_pdu_eof(&packet[packet_index], req, res); break; - case ACK_PDU: - ssp_printf("received Ack transaction: %llu\n", req->transaction_sequence_number); + case ACK_PDU: Pdu_ack ack_packet; get_ack_from_packet(&packet[packet_index], &ack_packet); @@ -879,7 +880,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque { case FINISHED_PDU: //get_finished_pdu(char *packet, Pdu_finished *pdu_finished) - ssp_printf("received finished packet transaction: %llu\n", req->transaction_sequence_number); + ssp_printf("received finished packet Ack\n"); req->local_entity.transaction_finished_indication = true; break; diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index f14751b..b0c15a5 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -160,15 +160,15 @@ int test_process_data_packet() { add_first_offset(file2, file->total_size); - int error = create_data_burst_packets(packet, start, file, packet_len); - uint32_t data_len = get_data_length(packet); - process_data_packet(&packet[start], data_len, file2); + int error = 0; + uint32_t data_len = 0; int i = 0; - for (i = 0; i < 7; i++) { + for (i = 0; i < 10; i++) { create_data_burst_packets(packet, start, file, packet_len); data_len = get_data_length(packet); process_data_packet(&packet[start], data_len, file2); + ASSERT_EQUALS_INT("Checksum parital calculations", file2->partial_checksum, file->partial_checksum); } uint32_t checksum = check_sum_file(file, packet_len-start-4); From 265067a2da542aa8622ab21c5dd258d2985e06fb Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Mar 2021 11:09:27 -0700 Subject: [PATCH 313/400] switch checksum to calculate using network byte order --- Program/src/filesystem_funcs.c | 5 ++++- Program/src/protocol_handler.c | 15 +++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 0cbcc37..08cf42c 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -142,8 +142,11 @@ uint32_t calc_check_sum(char *data, uint32_t length) { uint32_t check_sum = 0; uint32_t end = length - 4; unsigned int i = 0; + uint32_t bytes_to_add = 0; + for (i = 0; i < end; i+= 4){ - check_sum += *((uint32_t *) &data[i]); + bytes_to_add = ssp_htonl(*(uint32_t *) &data[i]); + check_sum += bytes_to_add; } if (remaining_bytes){ diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index b47a03c..1f8f2e6 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -231,8 +231,9 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { ssp_error("no new data was written\n"); return; } - + ssp_printf("processing checksum before %lu\n", file->partial_checksum); file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); + ssp_printf("processing checksum after %lu\n", file->partial_checksum); if (file->missing_offsets->count == 0) return; @@ -407,10 +408,15 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t int bytes = data_len - size_of_offset_bytes; //calculate checksum for data packet, this is used to calculate in transit checksums + ssp_printf("processing checksum before %lu\n", file->partial_checksum); file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); + ssp_printf("processing checksum after %lu\n", file->partial_checksum); + ssp_printf("sending packet data offset:size %d:%d\n", file->next_offset_to_send, file->next_offset_to_send + bytes); + + file->next_offset_to_send += bytes; - ssp_printf("sending packet data offset:size %d:%d\n", file->next_offset_to_send, file->total_size); + if (file->next_offset_to_send == file->total_size) return 1; @@ -836,7 +842,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque uint16_t data_len = get_data_length(packet); uint32_t packet_len = packet_index + data_len; - ssp_printf("transaction: %d ", incoming_header.transaction_sequence_number); + ssp_printf("transaction: %llu ", incoming_header.transaction_sequence_number); //process file data if (incoming_header.PDU_type == DATA) { @@ -852,6 +858,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque Pdu_directive *directive = (Pdu_directive *) &packet[packet_index]; + Pdu_ack ack_packet; packet_index++; switch (directive->directive_code) @@ -873,7 +880,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque break; case ACK_PDU: - Pdu_ack ack_packet; + get_ack_from_packet(&packet[packet_index], &ack_packet); switch (ack_packet.directive_code) From 3a5950e91aa45f51eaabdd15743a304fee5c34df Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Mar 2021 11:16:09 -0700 Subject: [PATCH 314/400] add one more network byte conversion to calc checksum --- Program/src/filesystem_funcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 08cf42c..7c999d1 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -159,7 +159,7 @@ uint32_t calc_check_sum(char *data, uint32_t length) { last_chunk[i] = data[end + i]; } - check_sum += *((uint32_t*) &last_chunk); + check_sum += ssp_htonl(*((uint32_t*) &last_chunk)); } return check_sum; From 697f8b584236712e103f8cf4d4fcce2085bae7f7 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Mar 2021 11:36:34 -0700 Subject: [PATCH 315/400] fix checksums for big endian --- Program/src/filesystem_funcs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 7c999d1..ca2679c 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -147,7 +147,7 @@ uint32_t calc_check_sum(char *data, uint32_t length) { for (i = 0; i < end; i+= 4){ bytes_to_add = ssp_htonl(*(uint32_t *) &data[i]); check_sum += bytes_to_add; - } + } if (remaining_bytes){ uint8_t last_chunk[4]; @@ -159,7 +159,8 @@ uint32_t calc_check_sum(char *data, uint32_t length) { last_chunk[i] = data[end + i]; } - check_sum += ssp_htonl(*((uint32_t*) &last_chunk)); + check_sum += ssp_htonl(*((uint32_t*) &last_chunk)); + } return check_sum; From 094926feab24c0d5a1d8ffe2670ff8bbb95ff129 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Mar 2021 14:48:02 -0700 Subject: [PATCH 316/400] change name of task file, and move some stuff around --- Program/include/{tasks.h => app_control.h} | 0 Program/src/{tasks.c => app_control.c} | 182 +++++++++++++-------- Program/src/csp_server_provider.c | 11 +- Program/src/file_delivery_app.c | 2 +- Program/src/main.c | 13 +- Program/src/makefile | 13 +- Program/src/protocol_handler.c | 4 - Program/test/makefile | 4 +- Program/test/server_tests.c | 2 +- 9 files changed, 138 insertions(+), 93 deletions(-) rename Program/include/{tasks.h => app_control.h} (100%) rename Program/src/{tasks.c => app_control.c} (91%) diff --git a/Program/include/tasks.h b/Program/include/app_control.h similarity index 100% rename from Program/include/tasks.h rename to Program/include/app_control.h diff --git a/Program/src/tasks.c b/Program/src/app_control.c similarity index 91% rename from Program/src/tasks.c rename to Program/src/app_control.c index c6861cd..de50a5e 100755 --- a/Program/src/tasks.c +++ b/Program/src/app_control.c @@ -5,7 +5,7 @@ please include this text, that is my only stipulation. Author: Evan Giese ------------------------------------------------------------------------------*/ #include "protocol_handler.h" -#include "tasks.h" +#include "app_control.h" #include "port.h" #include "mib.h" #include "filesystem_funcs.h" @@ -22,6 +22,13 @@ Author: Evan Giese //for print_request_state #include "requests.h" + +/*------------------------------------------------------------------------------ + + Generic functions + +------------------------------------------------------------------------------*/ + /* //usefull for cpu clocks static int is_negative(int number) { @@ -52,12 +59,6 @@ static int check_timeout(int *prevtime, uint32_t timeout) { return 0; } -/*------------------------------------------------------------------------------ - - Callbacks for the tasks bellow - -------------------------------------------------------------------------------*/ - //sets request procedure as clean_up if ttl has passed static void timeout(Request *req) { @@ -85,42 +86,29 @@ static void timeout(Request *req) { } } +void remove_request_check(Node *node, void *request, void *args) { + Request *req = (Request *) request; + List *req_list = (List *) args; -static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { - - - FTP *app = (FTP *) other; - if (packet_len > app->packet_len) { - ssp_printf("packet received is too big for app\n"); - return -1; - } + if (req->procedure == clean_up) { + ssp_printf("removing request\n"); + Request *remove_this = req_list->removeNode(req_list, node); - Response res; - res.addr = addr; - res.sfd = sfd; - res.size_of_addr = size_of_addr; - - Pdu_header incoming_pdu_header; - Request **request_container = &app->current_request; + if (req->local_entity.transaction_finished_indication || req->transmission_mode == UN_ACKNOWLEDGED_MODE) { + int error = delete_saved_request(req); + if (error < 0) + ssp_error("couldn't delete finished request, the request may have finished before journaling it\n"); + } - int packet_index = process_pdu_header(packet, true, &incoming_pdu_header, res, request_container, app->request_list, app); - if (packet_index < 0) { - ssp_printf("error parsing header\n"); - return -1; + ssp_cleanup_req(remove_this); } +} - Request *current_request = (*request_container); - app->current_request = current_request; +/*------------------------------------------------------------------------------ - int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, incoming_pdu_header, app); - - reset_timeout(¤t_request->timeout_before_cancel); - - memset(packet, 0, count); - - return count; + client callbacks -} +------------------------------------------------------------------------------*/ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { @@ -161,24 +149,6 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u } -void remove_request_check(Node *node, void *request, void *args) { - Request *req = (Request *) request; - List *req_list = (List *) args; - - if (req->procedure == clean_up) { - ssp_printf("removing request\n"); - Request *remove_this = req_list->removeNode(req_list, node); - - if (req->local_entity.transaction_finished_indication || req->transmission_mode == UN_ACKNOWLEDGED_MODE) { - int error = delete_saved_request(req); - if (error < 0) - ssp_error("couldn't delete finished request, the request may have finished before journaling it\n"); - } - - ssp_cleanup_req(remove_this); - } -} - struct user_request_check_params { Response res; Client *client; @@ -222,15 +192,11 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi return 0; } +/*------------------------------------------------------------------------------ + + Server callbacks - -static void timeout_check_callback_server(Node *node, void *request, void *args) { - Request *req = (Request *) request; - on_server_time_out(req->res, req); - timeout(req); - remove_request_check(node, request, args); -} - +------------------------------------------------------------------------------*/ static void client_check_callback(Node *node, void *client, void *args) { Client *c = (Client *) client; @@ -240,10 +206,35 @@ static void client_check_callback(Node *node, void *client, void *args) { ssp_printf("removing client, from server \n"); ssp_client_join(remove_this); } +} + + +int refresh_response_struct(Response old_res, Response new_res){ + + if (old_res.addr == new_res.addr) + return 1; + + if (old_res.size_of_addr != new_res.size_of_addr){ + ssp_printf("res struct sizes are not the same\n"); + return -1; + } + + if (memcmp(old_res.addr, new_res.addr, old_res.size_of_addr) == 0 ) { + return 1; + } + + ssp_printf("setting response struct\n"); + memcpy(new_res.addr, old_res.addr, old_res.size_of_addr); } -//this function is a callback for servers +static void timeout_check_callback_server(Node *node, void *request, void *args) { + Request *req = (Request *) request; + on_server_time_out(req->res, req); + timeout(req); + remove_request_check(node, request, args); +} + static int on_time_out_callback_server(void *other) { FTP *app = (FTP*) other; @@ -258,6 +249,53 @@ static int on_time_out_callback_server(void *other) { return 0; } +static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { + + FTP *app = (FTP *) other; + if (packet_len > app->packet_len) { + ssp_printf("packet received is too big for app\n"); + return -1; + } + + Response res; + res.addr = addr; + res.sfd = sfd; + res.size_of_addr = size_of_addr; + + Pdu_header incoming_pdu_header; + Request **request_container = &app->current_request; + + int packet_index = process_pdu_header(packet, true, &incoming_pdu_header, res, request_container, app->request_list, app); + if (packet_index < 0) { + ssp_printf("error parsing header\n"); + return -1; + } + + Request *current_request = (*request_container); + app->current_request = current_request; + + //refresh response + int error = refresh_response_struct(current_request->res, res); + if (error < 0) { + ssp_printf("failed to connect to new client\n"); + return -1; + } + + int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, incoming_pdu_header, app); + + reset_timeout(¤t_request->timeout_before_cancel); + + memset(packet, 0, count); + + return count; + +} +/*------------------------------------------------------------------------------ + + check exit callbacks, will exit the app if returns 1 + +------------------------------------------------------------------------------*/ + static int check_exit_server_callback(void *params) { FTP *app = (FTP*) params; if (app->close) @@ -272,6 +310,12 @@ static int check_exit_client_callback(void *params) { return 0; } +/*------------------------------------------------------------------------------ + + on Exit callbacks, used for cleaning up memory when exiting app + +------------------------------------------------------------------------------*/ + static void on_exit_client_callback (void *params) { } @@ -281,9 +325,11 @@ static void on_exit_server_callback (void *params) { ssp_cleanup_ftp(app); } +/*------------------------------------------------------------------------------ + + on std in -//this function is just for stdin fun, I haven't decided if we need need to use -//std in for anything, but we could use it to pass in args to the daemon. +------------------------------------------------------------------------------*/ static int on_stdin_callback(void *other) { /* @@ -324,12 +370,10 @@ static int on_stdin_callback(void *other) { /*------------------------------------------------------------------------------ - Tasks + different server/client drivers ------------------------------------------------------------------------------*/ - - static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port){ //convert int to char * int error = ssp_snprintf(port, 10, "%d", remote_entity.UT_port); @@ -348,8 +392,6 @@ static int get_ip_port(Remote_entity remote_entity, char *host_name, char *port) } return 0; } -//------------------------------------------------------------------------------ - void *ssp_connectionless_server_task(void *params) { #ifdef POSIX_PORT diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index d0b41bf..1296fb9 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -229,9 +229,9 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, char *buff = ssp_alloc(packet_len, sizeof(char)); if (buff == NULL) { + ssp_printf("exiting serv thread\n"); return; } - memset(buff, 0, packet_len); /* Process incoming connections */ for (;;) { @@ -292,13 +292,15 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_conn_t * conn; - char buff[packet_len]; - memset(buff, 0, packet_len); + char *buff = ssp_alloc(packet_len, sizeof(char)); + if (buff == NULL) { + ssp_printf("exiting client thread\n"); + return; + } while (1) { if (get_exit() || checkExit(params)){ - ssp_printf("exiting client thread\n"); break; } @@ -332,4 +334,5 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_close(conn); onExit(params); } + ssp_free(buff); } diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index dbb744b..b4217d6 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -7,7 +7,7 @@ Author: Evan Giese #include "mib.h" #include "port.h" #include "file_delivery_app.h" -#include "tasks.h" +#include "app_control.h" int create_ssp_server_drivers(FTP *app) { diff --git a/Program/src/main.c b/Program/src/main.c index e1854a1..9d69112 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -28,7 +28,7 @@ Author: Evan Giese #include "posix_server_provider.h" //for ssp_thread_join, can use p_thread join on linux -#include "tasks.h" +#include "app_control.h" #include "mib.h" #ifdef CSP_NETWORK @@ -216,9 +216,12 @@ int main(int argc, char** argv) { sleep(5); //csp_custom_ftp_ping(conf->client_cfdp_id); - //Request *req = put_request(client_id, "test.txt", "test-received.txt", UN_ACKNOWLEDGED_MODE, &app); - - + //put_request(client_id, "test.txt", "test-received.txt", UN_ACKNOWLEDGED_MODE, &app); + + put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); + //sleep(5); + //put_request(client_id, "test.txt", "test-received.txt", UN_ACKNOWLEDGED_MODE, &app); + /* Request *req2 = init_request_no_client(); put_request_no_client(req2, NULL, NULL, UN_ACKNOWLEDGED_MODE, &app); add_proxy_message_to_request(app.my_cfdp_id, 1, "mib/peer_0.json","GET_REQUEST", req2); @@ -228,7 +231,7 @@ int main(int argc, char** argv) { ssp_printf("client failed to start\n"); } else add_request_to_client(req2, client); - + */ } diff --git a/Program/src/makefile b/Program/src/makefile index ad6e4bb..a0980f1 100755 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -1,7 +1,7 @@ -#PROJDIR = $(CURDIR)/.. -PROJDIR = $(CURDIR)/../../../../../ -INCLUDE += -I$(CURDIR)/../include +PROJDIR = $(CURDIR)/.. +#PROJDIR = $(CURDIR)/../../../../../ +INCLUDE += -I$(PROJDIR)/include #---------------------------FOR FREE RTOS INTEGRATION--------------------------- #path to source includes @@ -20,6 +20,7 @@ INCLUDE += -I$(PROJDIR)/libcsp/include/csp INCLUDE += -I$(PROJDIR)/libcsp/include INCLUDE += -I$(PROJDIR)/libcsp/build/include INCLUDE += -I$(PROJDIR)/libcsp/src +INCLUDE += -I$(PROJDIR)/libcsp #------------------------------------------------------------------------------- CC = gcc @@ -27,8 +28,7 @@ CC = gcc CFILES += port.c CFILES += file_delivery_app.c CFILES += utils.c -CFILES += tasks.c -CFILES += posix_server_provider.c #used for poxix port +CFILES += app_control.c CFILES += csp_server_provider.c CFILES += protocol_handler.c CFILES += mib.c @@ -37,6 +37,7 @@ CFILES += requests.c CFILES += list.c CFILES += packet.c CFILES += generic_server_provider.c +CFILES += posix_server_provider.c #used for poxix port #----------------------------test files------------------------- #entrypoint @@ -68,7 +69,7 @@ CWARNS += -Wmissing-prototypes #---------------------------Libs--------------------------- LINKFLAGS = LIBS = -pthread -#STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a +STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a #STATIC_FILES += $(PROJDIR)/FreeRtos #---------------------------Compiler flags--------------------------- diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 1f8f2e6..421ac7d 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -231,9 +231,7 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { ssp_error("no new data was written\n"); return; } - ssp_printf("processing checksum before %lu\n", file->partial_checksum); file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); - ssp_printf("processing checksum after %lu\n", file->partial_checksum); if (file->missing_offsets->count == 0) return; @@ -408,9 +406,7 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t int bytes = data_len - size_of_offset_bytes; //calculate checksum for data packet, this is used to calculate in transit checksums - ssp_printf("processing checksum before %lu\n", file->partial_checksum); file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); - ssp_printf("processing checksum after %lu\n", file->partial_checksum); ssp_printf("sending packet data offset:size %d:%d\n", file->next_offset_to_send, file->next_offset_to_send + bytes); diff --git a/Program/test/makefile b/Program/test/makefile index cd476d3..3f3489f 100755 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -22,7 +22,7 @@ CFILES += $(PROJDIR)/src/csp_server_provider.c CFILES += $(PROJDIR)/src/protocol_handler.c CFILES += $(PROJDIR)/src/mib.c CFILES += $(PROJDIR)/src/requests.c -CFILES += $(PROJDIR)/src/tasks.c +CFILES += $(PROJDIR)/src/app_control.c CFILES += $(PROJDIR)/src/file_delivery_app.c CFILES += $(PROJDIR)/src/list.c CFILES += $(PROJDIR)/src/packet.c @@ -73,7 +73,7 @@ STATIC_FILES += $(PROJDIR)/libcsp/build/libcsp.a #---------------------------Compiler flags--------------------------- #32 bit machines, leave this out if your machine is 64 bit -CFLAGS += -m32 +#CFLAGS += -m32 CFLAGS += -g -UUSE_STDIO -D__GCC_POSIX__=1 CFLAGS += -pthread CFLAGS += -DDEBUG=1 diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 18e7d36..9e05a70 100755 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -3,7 +3,7 @@ #include #include "posix_server_provider.h" #include "port.h" -#include "tasks.h" +#include "app_control.h" //-------------------------------- From 1ceb4db07ca514bb373ff583f749f6e1b9219537 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 13 Mar 2021 15:20:52 -0700 Subject: [PATCH 317/400] Change logging and move stuff around --- Program/src/app_control.c | 3 - Program/src/file_delivery_app.c | 2 +- Program/src/protocol_handler.c | 178 ++++++++++++++++---------------- 3 files changed, 91 insertions(+), 92 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index de50a5e..259b56c 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -211,9 +211,6 @@ static void client_check_callback(Node *node, void *client, void *args) { int refresh_response_struct(Response old_res, Response new_res){ - if (old_res.addr == new_res.addr) - return 1; - if (old_res.size_of_addr != new_res.size_of_addr){ ssp_printf("res struct sizes are not the same\n"); return -1; diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index b4217d6..c30eaaa 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -78,7 +78,6 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { memset(app, 0, sizeof(FTP)); - ssp_printf("initializing ftp server task"); error = ssp_mkdir("incomplete_requests"); if (error < 0) { @@ -200,6 +199,7 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { app->current_request = NULL; + ssp_printf("initializing ftp server task: "); return create_ssp_server_drivers(app); } diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 421ac7d..698db5f 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -13,6 +13,11 @@ Author: Evan Giese #include "types.h" #include "utils.h" +static void transasction_log(char *msg, uint32_t transaction_sequence_number){ + ssp_printf("transaction: %llu ", transaction_sequence_number); + ssp_printf(msg); + ssp_printf("\n"); +} static void build_temperary_file(Request *req, uint32_t size) { @@ -41,7 +46,7 @@ static void send_nak(Request *req, Response res, unsigned int type) { static void resend_eof_ack(Request *req, Response res) { - ssp_printf("sending eof ack transaction: %llu\n", req->transaction_sequence_number); + transasction_log("sending eof ack", req->transaction_sequence_number); send_ack(req,res, EOF_PDU); req->resent_eof++; } @@ -95,8 +100,7 @@ static int find_request(void *element, void *args) { ssp_error("could not get allocate for new request \n"); return NULL; } - - ssp_printf("incoming new request\n"); + transasction_log("incoming new request", transaction_sequence_number); //Make new request and add it found_req->transmission_mode = transmission_mode; @@ -121,6 +125,7 @@ static int find_request(void *element, void *args) { found_req->res.transmission_mode = app->remote_entity.default_transmission_mode; found_req->res.type_of_network = app->remote_entity.type_of_network; found_req->res.msg = found_req->buff; + found_req->res.size_of_addr = res.size_of_addr; found_req->paused = false; return found_req; @@ -216,7 +221,8 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { uint32_t offset_start = get_data_offset_from_packet(packet); uint32_t packet_index = 4; - ssp_printf("received data packet offset:%d\n", offset_start); + + //ssp_printf("received data packet offset:%d\n", offset_start); // size of 'offset' bytes in packet uint32_t offset_end = offset_start + data_len - packet_index; @@ -353,14 +359,13 @@ void process_messages(Request *req, FTP *app) { /*------------------------------------------------------------------------------ - REMOTE SIDE + Client aka: handles responses from server ------------------------------------------------------------------------------*/ static void resend_finished_ack(Request *req, Response res) { - - ssp_printf("sending finished packet transaction ack: %llu\n", req->transaction_sequence_number); + transasction_log("sending finished ack", req->transaction_sequence_number); send_ack(req, res, FINISHED_PDU); req->resent_finished++; } @@ -368,7 +373,7 @@ static void resend_finished_ack(Request *req, Response res) { static void send_put_metadata(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); - ssp_printf("sending metadata transaction: %llu\n", req->transaction_sequence_number); + transasction_log("sending metadata pdu", req->transaction_sequence_number); start = build_put_packet_metadata(req->buff, start, req); req->local_entity.Metadata_sent_indication = true; @@ -377,7 +382,7 @@ static void send_put_metadata(Request *req, Response res) { static void send_eof_pdu(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); - ssp_printf("sending eof transaction: %llu file_size %d\n", req->transaction_sequence_number, req->file_size); + transasction_log("sending eof pdu", req->transaction_sequence_number); if (req->file_size == 0) build_eof_packet(req->buff, start, 0, 0); else @@ -409,11 +414,8 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); ssp_printf("sending packet data offset:size %d:%d\n", file->next_offset_to_send, file->next_offset_to_send + bytes); - file->next_offset_to_send += bytes; - - if (file->next_offset_to_send == file->total_size) return 1; @@ -459,63 +461,6 @@ int process_nak_pdu(char *packet, File *file){ return 1; } -void segment_offset_into_data_packets(char *packet, uint32_t start, uint32_t offset_start, uint32_t offset_end, Request *req, Response res){ - - int i = 0; - int error = 0; - uint32_t segment_len = req->buff_len - start; - - for (i = offset_start; i < offset_end; i+= segment_len) { - - if (offset_end - i < segment_len){ - segment_len = offset_end - i; - } - - //ssp_printf("sending offset start %d to %d\n", i, i + segment_len); - //ssp_printf("segment len %d\n",segment_len); - - error = build_data_packet(packet, start, segment_len + start, i, req->file); - if (error < 0) { - return -1; - } - - ssp_sendto(res); - } -} - -int process_nak_pdu_response(char *packet, Request *req, Response res, Client *client){ - Pdu_nak nak; - get_nak_packet(packet, &nak); - - uint32_t packet_index = 0; - uint32_t offset_start = 0; - uint32_t offset_end = 0; - //build new header for outgoing packets - uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, 0, &client->pdu_header); - int error = 0; - int i = 0; - - - ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); - - for (i = 0; i < nak.segment_requests; i++){ - - packet_index = 0; - - memcpy(&offset_start, &nak.segments[packet_index], sizeof(uint32_t)); - offset_start = ssp_ntohl(offset_start); - packet_index += 4; - - memcpy(&offset_end, &nak.segments[packet_index], sizeof(uint32_t)); - offset_end = ssp_ntohl(offset_end); - packet_index += 4; - - segment_offset_into_data_packets(req->buff, outgoing_packet_index, offset_start, offset_end, req, res); - } - - return 1; - -} static void acknowledged_start(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); @@ -579,17 +524,20 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ if (req->procedure == sending_start) return; + + ssp_printf("transaction: %llu ", req->transaction_sequence_number); + uint8_t directive = packet[packet_index]; packet_index += 1; switch(directive) { case FINISHED_PDU: - ssp_printf("received finished pdu transaction: %llu\n", req->transaction_sequence_number); + transasction_log("received finished pdu", req->transaction_sequence_number); req->local_entity.transaction_finished_indication = true; resend_finished_ack(req, res); break; case NAK_PDU: - ssp_printf("received Nak pdu transaction: %llu\n", req->transaction_sequence_number); + transasction_log("received Nak pdu", req->transaction_sequence_number); process_nak_pdu_response(&packet[packet_index], req, res, client); break; case ACK_PDU: @@ -597,12 +545,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch (packet[packet_index]) { case EOF_PDU: - ssp_printf("received Eof ack transaction: %llu\n", req->transaction_sequence_number); + transasction_log("received Eof ack", req->transaction_sequence_number); req->local_entity.EOF_recv_indication = true; break; case META_DATA_PDU: - ssp_printf("received Eof ack transaction: %llu\n", req->transaction_sequence_number); + transasction_log("received meta_data ack", req->transaction_sequence_number); req->local_entity.Metadata_recv_indication = true; default: @@ -614,12 +562,12 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ switch (packet[packet_index]) { case META_DATA_PDU: - ssp_printf("resending metadata transaction: %llu\n", req->transaction_sequence_number); + transasction_log("resending metadata pdu", req->transaction_sequence_number); send_put_metadata(req, res); break; case EOF_PDU: - ssp_printf("resending eof transaction: %llu\n", req->transaction_sequence_number); + transasction_log("resending eof pdu", req->transaction_sequence_number); send_eof_pdu(req, res); break; @@ -671,30 +619,26 @@ void user_request_handler(Response res, Request *req, Client* client) { ------------------------------------------------------------------------------*/ static void request_eof(Request *req, Response res) { - - ssp_printf("sending eof nak transaction: %llu\n", req->transaction_sequence_number); + transasction_log("sending eof nak pdu", req->transaction_sequence_number); send_nak(req, res, EOF_PDU); } static void request_metadata(Request *req, Response res) { - - ssp_printf("sending request for new metadata packet %llu\n", req->transaction_sequence_number); + transasction_log("sending meta_data nak pdu", req->transaction_sequence_number); send_nak(req, res, META_DATA_PDU); } static void request_data(Request *req, Response res) { - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); - ssp_printf("sending Nak data transaction: %llu\n", req->transaction_sequence_number); + transasction_log("sending data nak pdu", req->transaction_sequence_number); build_nak_packet(req->buff, start, req); ssp_sendto(res); } - static void resend_finished_pdu(Request *req, Response res) { uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); - ssp_printf("sending finished pdu transaction: %llu\n", req->transaction_sequence_number); + transasction_log("sending finished pdu", req->transaction_sequence_number); build_finished_pdu(req->buff, start); ssp_sendto(res); req->resent_finished++; @@ -719,6 +663,64 @@ void process_pdu_eof(char *packet, Request *req, Response res) { +void segment_offset_into_data_packets(char *packet, uint32_t start, uint32_t offset_start, uint32_t offset_end, Request *req, Response res){ + + int i = 0; + int error = 0; + uint32_t segment_len = req->buff_len - start; + + for (i = offset_start; i < offset_end; i+= segment_len) { + + if (offset_end - i < segment_len){ + segment_len = offset_end - i; + } + + //ssp_printf("sending offset start %d to %d\n", i, i + segment_len); + //ssp_printf("segment len %d\n",segment_len); + + error = build_data_packet(packet, start, segment_len + start, i, req->file); + if (error < 0) { + return -1; + } + + ssp_sendto(res); + } +} + +int process_nak_pdu_response(char *packet, Request *req, Response res, Client *client){ + Pdu_nak nak; + get_nak_packet(packet, &nak); + + uint32_t packet_index = 0; + uint32_t offset_start = 0; + uint32_t offset_end = 0; + //build new header for outgoing packets + uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, 0, &client->pdu_header); + int error = 0; + int i = 0; + + + ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); + + for (i = 0; i < nak.segment_requests; i++){ + + packet_index = 0; + + memcpy(&offset_start, &nak.segments[packet_index], sizeof(uint32_t)); + offset_start = ssp_ntohl(offset_start); + packet_index += 4; + + memcpy(&offset_end, &nak.segments[packet_index], sizeof(uint32_t)); + offset_end = ssp_ntohl(offset_end); + packet_index += 4; + + segment_offset_into_data_packets(req->buff, outgoing_packet_index, offset_start, offset_end, req, res); + } + + return 1; + +} + int process_file_request_metadata(Request *req) { char temp[75]; @@ -838,13 +840,13 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque uint16_t data_len = get_data_length(packet); uint32_t packet_len = packet_index + data_len; - ssp_printf("transaction: %llu ", incoming_header.transaction_sequence_number); //process file data if (incoming_header.PDU_type == DATA) { if (!req->local_entity.Metadata_recv_indication) { if (req->file == NULL) { - ssp_printf("file is null\n"); + + transasction_log("file is null", incoming_header.transaction_sequence_number); build_temperary_file(req, TEMP_FILESIZE); } } @@ -863,7 +865,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque if (req->local_entity.Metadata_recv_indication) break; - ssp_printf("received metadata packet transaction \n"); + transasction_log("received metadata packet transaction", incoming_header.transaction_sequence_number); process_metadata(packet, packet_index, res, req, app); break; @@ -871,7 +873,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque if (req->local_entity.EOF_recv_indication) break; - ssp_printf("received eof packet\n"); + transasction_log("received eof packet", incoming_header.transaction_sequence_number); process_pdu_eof(&packet[packet_index], req, res); break; @@ -883,7 +885,7 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque { case FINISHED_PDU: //get_finished_pdu(char *packet, Pdu_finished *pdu_finished) - ssp_printf("received finished packet Ack\n"); + transasction_log("received finished packet Ack", incoming_header.transaction_sequence_number); req->local_entity.transaction_finished_indication = true; break; From 25e73d2c9d78cf68bd3471b1b372e1b7658a007a Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 14 Mar 2021 13:31:58 -0600 Subject: [PATCH 318/400] fix some compiler warnings --- Program/include/list.h | 14 +- Program/include/packet.h | 10 ++ Program/include/protocol_handler.h | 9 +- Program/include/requests.h | 3 +- Program/src/app_control.c | 1 + Program/src/csp_server_provider.c | 44 ++----- Program/src/file_delivery_app.c | 17 ++- Program/src/filesystem_funcs.c | 6 +- Program/src/list.c | 14 +- Program/src/packet.c | 29 +++-- Program/src/protocol_handler.c | 199 ++++++++++++----------------- Program/src/requests.c | 2 +- 12 files changed, 156 insertions(+), 192 deletions(-) diff --git a/Program/include/list.h b/Program/include/list.h index f6e6458..58eb843 100755 --- a/Program/include/list.h +++ b/Program/include/list.h @@ -29,23 +29,23 @@ typedef struct List struct Node *head; struct Node *tail; uint32_t count; - int (*push)(struct List *list, void *element, uint32_t id); - void *(*remove)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + int (*push)(struct List *list, void *element, int id); + void *(*remove)(struct List *list, int id, int (*f)(void *element, void *args), void *args); void (*iterate)(struct List *list, void (*f)(Node *node, void *element, void *args), void *args); void (*free)(struct List *list, void (*f)(void *element)); void *(*pop) (struct List *list); - int (*insert) (struct List *list, void *element, uint32_t id); - int (*insertAt)(struct List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args); + int (*insert) (struct List *list, void *element, int id); + int (*insertAt)(struct List *list, void *element, int id, int (*f)(void *element, void *args), void *args); //returns a void pointer that should be cast to the type - void *(*find)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); - struct Node *(*findNode)(struct List *list, uint32_t id, int (*f)(void *element, void *args), void *args); + void *(*find)(struct List *list, int id, int (*f)(void *element, void *args), void *args); + struct Node *(*findNode)(struct List *list, int id, int (*f)(void *element, void *args), void *args); void (*freeOnlyList)(struct List *list); void (*freeNode)(Node *node); void *(*removeNode)(struct List *list, Node *node); } List; -Node *createNode(void *element, uint32_t id); +Node *createNode(void *element, int id); /*------------------------------------------------------------------------------ Purpose: This function initializes a linked list LIST *. Perameters: empty is just for the compiler errors, TODO use it for something diff --git a/Program/include/packet.h b/Program/include/packet.h index 2776e16..580d007 100755 --- a/Program/include/packet.h +++ b/Program/include/packet.h @@ -18,6 +18,16 @@ int build_pdu_header(char *packet, uint64_t transaction_sequence_number, uint32_ uint8_t build_finished_pdu(char *packet, uint32_t start); uint8_t build_put_packet_metadata(char *packet, uint32_t start, Request *req); uint8_t build_nak_response(char *packet, uint32_t start, uint32_t offset, Request *req, Client* client); +void get_finished_pdu(char *packet, Pdu_finished *pdu_finished); +int get_nak_packet(char *packet, Pdu_nak *nak); + +int copy_id_to_packet(char *bytes, uint64_t id); +int copy_id_lv_to_packet(char *bytes, uint64_t id); +int copy_id_lv_from_packet(char *bytes, uint64_t *id); +uint64_t copy_id_from_packet(char *bytes, uint32_t length_of_ids); +void set_packet_directive(char *packet, uint32_t location, uint8_t directive); +void set_bits_to_protocol_byte(char *byte, uint8_t from_position, uint8_t to_position, uint8_t value); + uint32_t get_data_offset_from_packet(char *packet); diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 6e92850..4e57240 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -8,9 +8,9 @@ Author: Evan Giese #define PROTOCOL_H #include "types.h" -#define RESEND_EOF_TIMES 3 -#define RESEND_FINISHED_TIMES 10 -#define RESEND_META_TIMES 3 +#define RESEND_EOF_TIMES 1 +#define RESEND_FINISHED_TIMES 1 +#define RESEND_META_TIMES 1 #define TIMEOUT_BEFORE_CANCEL_REQUEST 60 #define TIMEOUT_BEFORE_SAVE_REQUEST 30 @@ -34,10 +34,9 @@ void process_messages(Request *req, FTP *app); void process_data_packet(char *packet, uint32_t data_len, File *file); int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t length); - +int process_nak_pdu(char *packet, Request *req, Response res, Client *client); uint8_t build_ack (char *packet, uint32_t start, uint8_t type); int process_file_request_metadata(Request *req); -int nak_response(char *packet, uint32_t start, Request *req, Response res, Client *client); void set_data_length(char*packet, uint16_t data_len); uint32_t build_nak_packet(char *packet, uint32_t start, Request *req); uint16_t get_data_length(char*packet); diff --git a/Program/include/requests.h b/Program/include/requests.h index 2564e36..1e64881 100755 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -45,8 +45,8 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app); int schedule_put_request(uint32_t dest_id,char *source_file_name,char *destination_file_name,uint8_t transmission_mode, FTP *app); int schedule_request(Request *req, uint32_t dest_id, uint8_t transmission_mode, FTP *app); - Request *init_request_no_client(); + int put_request_no_client( Request *req, char *source_file_name, @@ -54,6 +54,7 @@ int put_request_no_client( uint8_t transmission_mode, FTP *app); +void print_res(Response res); void add_request_to_client(Request *req, Client *client); Client *start_client(FTP *app, uint8_t dest_id); #endif diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 259b56c..1caef22 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -222,6 +222,7 @@ int refresh_response_struct(Response old_res, Response new_res){ ssp_printf("setting response struct\n"); memcpy(new_res.addr, old_res.addr, old_res.size_of_addr); + return 1; } diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 1296fb9..ca88115 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -157,7 +157,7 @@ int csp_custom_ftp_ping(uint32_t dest_id){ if (conn == NULL) { /* Connect failed */ ssp_printf("Connection failed\n"); - return; + return -1; } ssp_printf("connection established, sending ping to id %d port %d \n", dest_id, 1); @@ -208,8 +208,6 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, return; } - uint8_t src_id = csp_get_address(); - //Bind all ports to socket error = csp_bind(sock, my_port); if (error != CSP_ERR_NONE) { @@ -224,7 +222,6 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, } //Pointer to current connection and packet csp_conn_t *conn; - csp_conn_t *conn_waiting; csp_packet_t *packet; char *buff = ssp_alloc(packet_len, sizeof(char)); @@ -233,43 +230,28 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, return; } - /* Process incoming connections */ - for (;;) { - if (get_exit() || checkExit(other)){ - ssp_printf("exiting serv thread\n"); + for (;;) { + + if (get_exit() || checkExit(other)) break; - } - - /* Wait for connection, 1000 ms timeout */ - if ((conn = csp_accept(sock, 10)) == NULL) { + + conn = csp_accept(sock, 1000); + if (conn == NULL) { onTimeOut(other); continue; } - for (;;) { + while ((packet = csp_read(conn, 1000)) != NULL) { - if (get_exit() || checkExit(other)) - break; - - conn_waiting = csp_accept(sock, 1000); - if (conn_waiting != NULL) { - csp_close(conn); - conn = conn_waiting; - } - - onTimeOut(other); + memcpy(buff, (char *)packet->data, packet_len); - while ((packet = csp_read(conn, 1000)) != NULL) { + if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), other) == -1) + ssp_printf("recv failed\n"); - memcpy(buff, (char *)packet->data, packet_len); - - if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), other) == -1) - ssp_printf("recv failed\n"); - - csp_buffer_free(packet); - } + csp_buffer_free(packet); } + csp_close(conn); onExit(other); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index c30eaaa..c5b3b1b 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -72,14 +72,9 @@ static int create_ssp_client_drivers(Client *client) { } +static void make_default_data(){ -int init_ftp(uint32_t my_cfdp_address, FTP *app) { - int error = 0; - - memset(app, 0, sizeof(FTP)); - - - error = ssp_mkdir("incomplete_requests"); + int error = ssp_mkdir("incomplete_requests"); if (error < 0) { ssp_error("couldn't make directory incomplete_requests it either already exists or there is an issue\n"); } @@ -159,6 +154,14 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { ssp_error("couldn't write default file\n"); } } +} + +int init_ftp(uint32_t my_cfdp_address, FTP *app) { + int error = 0; + + memset(app, 0, sizeof(FTP)); + make_default_data(); + Remote_entity remote_entity; memset(&remote_entity, 0, sizeof(Remote_entity)); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index ca2679c..b116a64 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -103,6 +103,8 @@ int get_offset(File *file, void *buff, uint32_t buf_size, int offset) { int bytes = ssp_read(file->fd, buff, buf_size); if (bytes == -1){ ssp_error("Could not read anything from file\n"); + } else if (bytes == 0) { + ssp_error("Bytes read 0\n"); } return bytes; @@ -266,6 +268,7 @@ int add_first_offset(File *file, uint32_t file_size){ offset->end = file_size; offset->start = 0; file->missing_offsets->insert(file->missing_offsets, offset, file_size); + return 1; } File *create_temp_file(char *file_name, uint32_t size) { @@ -495,6 +498,7 @@ int write_id(int fd, uint64_t id){ ssp_error(error_message); return -1; } + return 1; } int read_id(int fd, uint64_t *id){ @@ -636,7 +640,7 @@ static int get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id if (error < 0) return -1; - ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%llu%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); + ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%lu%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); return 1; } diff --git a/Program/src/list.c b/Program/src/list.c index 9f7bbcd..366fde0 100755 --- a/Program/src/list.c +++ b/Program/src/list.c @@ -12,7 +12,7 @@ Author: Evan Giese new node, or NULL if failed ------------------------------------------------------------------------------*/ -Node *createNode(void *element, uint32_t id) +Node *createNode(void *element, int id) { Node *newNode = ssp_alloc(sizeof(Node), 1); if (newNode == NULL) { @@ -57,7 +57,7 @@ static void *pop(List *list) { linked list, returns the new node. ------------------------------------------------------------------------------*/ -static int insert(List *list, void *element, uint32_t id) { +static int insert(List *list, void *element, int id) { Node *head = list->head; Node *node = createNode(element, id); @@ -79,7 +79,7 @@ static int insert(List *list, void *element, uint32_t id) { 0 if failed. ------------------------------------------------------------------------------*/ -static int push(List *list, void *element, uint32_t id) +static int push(List *list, void *element, int id) { Node *newNode = createNode(element, id); @@ -142,7 +142,7 @@ static void *removeNode(List *list, Node *node) { element (callback can be the find function) ------------------------------------------------------------------------------*/ -static void *removeElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) +static void *removeElement(List *list, int id, int (*f)(void *element, void *args), void *args) { Node *cur = list->head; int found_with_func = 0; @@ -211,7 +211,7 @@ static void freeNodes(List *list) { either a callback, or id ------------------------------------------------------------------------------*/ -static void *findElement(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) +static void *findElement(List *list, int id, int (*f)(void *element, void *args), void *args) { Node *cur = list->head->next; @@ -233,7 +233,7 @@ static void *findElement(List *list, uint32_t id, int (*f)(void *element, void * return NULL; } -static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *element, void *args), void *args) { +static int insertAt(List *list, void *element, int id, int (*f)(void *element, void *args), void *args) { Node *cur = list->head->next; int found_with_func = 0; @@ -261,7 +261,7 @@ static int insertAt(List *list, void *element, uint32_t id, int (*f)(void *eleme } -static Node *findNode(List *list, uint32_t id, int (*f)(void *element, void *args), void *args) { +static Node *findNode(List *list, int id, int (*f)(void *element, void *args), void *args) { Node *cur = list->head->next; int found_with_func = 0; diff --git a/Program/src/packet.c b/Program/src/packet.c index 08dc317..4a151c1 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -16,7 +16,12 @@ Author: Evan Giese creating packets ------------------------------------------------------------------------------*/ - +void set_bits_to_protocol_byte(char *byte, uint8_t from_position, uint8_t to_position, uint8_t value) { + char bit_mask = value; + uint8_t bits_to_shift_left = 7-to_position; + char bits_to_add = bit_mask << bits_to_shift_left; + *byte = *byte | bits_to_add; +} // if is_data_packet is false, then is directive pacnket static void set_packet_header(char *packet, uint16_t data_len, bool is_data_packet) { @@ -24,12 +29,7 @@ static void set_packet_header(char *packet, uint16_t data_len, bool is_data_pack set_data_length(packet, data_len); } -void set_bits_to_protocol_byte(char *byte, uint8_t from_position, uint8_t to_position, uint8_t value) { - char bit_mask = value; - uint8_t bits_to_shift_left = 7-to_position; - char bits_to_add = bit_mask << bits_to_shift_left; - *byte = *byte | bits_to_add; -} + //get bits fromleft to right uint8_t get_bits_from_protocol_byte(char byte, uint8_t from_position, uint8_t to_position){ uint8_t bits_to_shift_left = from_position; @@ -110,9 +110,10 @@ int copy_id_lv_to_packet(char *bytes, uint64_t id) { int copy_id_lv_from_packet(char *bytes, uint64_t *id){ uint8_t len = bytes[0]; + uint64_t error = -1; uint64_t id_recv = copy_id_from_packet(&bytes[1], len); - if (id_recv < 0) { + if (id_recv == error) { ssp_printf("failed to copy id from packet %d\n", id_recv); return -1; } @@ -161,24 +162,25 @@ int get_pdu_header_from_packet(char *packet, Pdu_header *pdu_header){ //ssp_printf("length of entities %d\n", pdu_header->length_of_entity_IDs); + uint64_t error = -1; int32_t source_id_location = PACKET_STATIC_HEADER_LEN; pdu_header->source_id = copy_id_from_packet(&packet[source_id_location], pdu_header->length_of_entity_IDs); - if (pdu_header->source_id < 0) { + if (pdu_header->source_id == error) { ssp_error("failed to get source_id"); return -1; } int32_t transaction_number_location = source_id_location + pdu_header->length_of_entity_IDs; pdu_header->transaction_sequence_number = copy_id_from_packet(&packet[transaction_number_location], pdu_header->transaction_seq_num_len); - if (pdu_header->transaction_sequence_number < 0) { + if (pdu_header->transaction_sequence_number == error) { ssp_error("failed to get transaction_sequence_number"); return -1; } int32_t dest_id_location = transaction_number_location + pdu_header->transaction_seq_num_len; pdu_header->destination_id = copy_id_from_packet(&packet[dest_id_location], pdu_header->length_of_entity_IDs); - if (pdu_header->destination_id < 0) { + if (pdu_header->destination_id == error) { ssp_error("failed to get destination_id"); return -1; } @@ -243,7 +245,7 @@ typedef struct pdu_finished { }Pdu_finished; */ -uint32_t get_finished_pdu(char *packet, Pdu_finished *pdu_finished) { +void get_finished_pdu(char *packet, Pdu_finished *pdu_finished) { pdu_finished->condition_code = get_bits_from_protocol_byte(packet[0], 0, 3); pdu_finished->end_system_status = get_bits_from_protocol_byte(packet[0], 4, 4); @@ -649,7 +651,7 @@ static void add_messages_callback(Node *node, void *element, void *args) { char *packet = params->packet; uint32_t packet_index = *(params->packet_index); Message *message = (Message *) element; - int error, bytes = 0; + int bytes = 0; //since this is a callback functions, we can't return -1, intead we just log char *error_msg = "there was an issue copying bytes for the message: %s\n"; @@ -737,7 +739,6 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { uint32_t message_type = start + 5; uint32_t message_start = start + 6; - int error = 0; int id_len = 0; switch (packet[message_type]) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 698db5f..2fb83f4 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -30,7 +30,7 @@ static void send_ack(Request *req, Response res, unsigned int type){ if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); build_ack(req->buff, start, type); ssp_sendto(res); } @@ -39,8 +39,9 @@ static void send_nak(Request *req, Response res, unsigned int type) { if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) return; - uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, 1, 0, &req->pdu_header); + uint8_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); build_nak_directive(req->buff, start, type); + ssp_sendto(res); } @@ -137,8 +138,6 @@ finds the correct request struct and replaces req with the new pointer. Returns where the data portion is, also sets incoming_pdu_header... returns -1 on fail*/ int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_header, Response res, Request **req, List *request_list, FTP *app) { - - uint8_t packet_index = PACKET_STATIC_HEADER_LEN; Pdu_header header; memset(&header, 0, sizeof(Pdu_header)); @@ -154,7 +153,9 @@ int process_pdu_header(char*packet, uint8_t is_server, Pdu_header *incoming_pdu_ return -1; } if (app->my_cfdp_id != header.destination_id){ + ssp_print_bits(packet, 12); ssp_printf("someone is sending packets here that are not for my id %u, dest_id: %u\n", app->my_cfdp_id, header.destination_id); + ssp_print_header(&header); return -1; } @@ -412,66 +413,34 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t //calculate checksum for data packet, this is used to calculate in transit checksums file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); - ssp_printf("sending packet data offset:size %d:%d\n", file->next_offset_to_send, file->next_offset_to_send + bytes); - + + //ssp_printf("sending packet data offset:size %d:%d\n", file->next_offset_to_send, file->next_offset_to_send + bytes); file->next_offset_to_send += bytes; - if (file->next_offset_to_send == file->total_size) + if (file->next_offset_to_send == file->total_size) { + ssp_printf("sending packet data offset_start:offset_end:total_size %d:%d:%d\n", file->next_offset_to_send - bytes, file->next_offset_to_send, file->total_size); return 1; - - return 0; -} - - -//returns -1 on error -//adds start and end if there is no start and end (end will likely have to be the file size and start should be 0) -//for remembering packets? -int process_nak_pdu(char *packet, File *file){ - - if (file->missing_offsets->count == 0){ - ssp_error("can't receive offset without knowing the file size, please add the first offset with start=0 and end=filesize"); - return -1; } - - Pdu_nak nak; - get_nak_packet(packet, &nak); - - uint32_t packet_index = 0; - uint32_t offset_start = 0; - uint32_t offset_end = 0; - int completed = 0; - int i = 0; - for (i = 0; i < nak.segment_requests; i++){ - packet_index = 0; - - memcpy(&offset_start, &nak.segments[packet_index], sizeof(uint32_t)); - offset_start = ssp_ntohl(offset_start); - packet_index += 4; + ssp_printf("sending packet data offset_start:offset_end:total_size %d:%d:%d\n", file->next_offset_to_send - bytes, file->next_offset_to_send, file->total_size); - memcpy(&offset_end, &nak.segments[packet_index], sizeof(uint32_t)); - offset_end = ssp_ntohl(offset_end); - packet_index += 4; - - completed = receive_offset(file, 0, offset_start, offset_end); - if (!completed) { - return -1; - } - } - return 1; + return 0; } static void acknowledged_start(Request *req, Response res) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); - + send_put_metadata(req, res); + if (req->file_size == 0 ){ req->procedure = none; return; } + while (!create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { - ssp_sendto(res); + //ssp_sendto(res); + } ssp_sendto(res); @@ -483,10 +452,11 @@ static void unacknowledged_start(Request *req, Response res){ uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); int i = 0; - + for (i = 0; i < RESEND_META_TIMES; i++) { send_put_metadata(req, res); } + if (req->file_size == 0 ){ req->procedure = none; return; @@ -516,6 +486,65 @@ static void start_sequence(Request *req, Response res) { } +static int segment_offset_into_data_packets(char *packet, uint32_t start, uint32_t offset_start, uint32_t offset_end, Request *req, Response res){ + + int i = 0; + int error = 0; + uint32_t segment_len = req->buff_len - start; + + for (i = offset_start; i < offset_end; i+= segment_len) { + + if (offset_end - i < segment_len){ + segment_len = offset_end - i; + } + + //ssp_printf("sending offset start %d to %d\n", i, i + segment_len); + //ssp_printf("segment len %d\n",segment_len); + + error = build_data_packet(packet, start, segment_len + start, i, req->file); + if (error < 0) { + ssp_printf("couldn't create data packet for offset %d\n", i); + continue; + } + + ssp_sendto(res); + } + return 0; +} + + +int process_nak_pdu(char *packet, Request *req, Response res, Client *client){ + Pdu_nak nak; + get_nak_packet(packet, &nak); + + uint32_t packet_index = 0; + uint32_t offset_start = 0; + uint32_t offset_end = 0; + //build new header for outgoing packets + uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, 0, &client->pdu_header); + int i = 0; + + ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); + + for (i = 0; i < nak.segment_requests; i++){ + + packet_index = 0; + + memcpy(&offset_start, (uint32_t*)&nak.segments[packet_index], sizeof(uint32_t)); + offset_start = ssp_ntohl(offset_start); + packet_index += 4; + + memcpy(&offset_end, (uint32_t*)&nak.segments[packet_index], sizeof(uint32_t)); + offset_end = ssp_ntohl(offset_end); + packet_index += 4; + + segment_offset_into_data_packets(req->buff, outgoing_packet_index, offset_start, offset_end, req, res); + } + + return 1; +} + + //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { @@ -523,9 +552,8 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ //if client is still sending the first data_burst, don't accepts packets if (req->procedure == sending_start) return; - - - ssp_printf("transaction: %llu ", req->transaction_sequence_number); + + //ssp_printf("NO %d\n", req->procedure); uint8_t directive = packet[packet_index]; packet_index += 1; @@ -538,7 +566,7 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ break; case NAK_PDU: transasction_log("received Nak pdu", req->transaction_sequence_number); - process_nak_pdu_response(&packet[packet_index], req, res, client); + process_nak_pdu(&packet[packet_index], req, res, client); break; case ACK_PDU: @@ -580,12 +608,6 @@ void parse_packet_client(char *packet, uint32_t packet_index, Response res, Requ break; } } -static void check_req_status(Request *req) { - - if (req->resent_finished >= RESEND_FINISHED_TIMES){ - req->procedure = none; - } -} //current user request, to send to server void user_request_handler(Response res, Request *req, Client* client) { @@ -593,8 +615,6 @@ void user_request_handler(Response res, Request *req, Client* client) { if (req == NULL || req->paused) return; - check_req_status(req); - switch (req->procedure) { case sending_nak_data: @@ -663,64 +683,6 @@ void process_pdu_eof(char *packet, Request *req, Response res) { -void segment_offset_into_data_packets(char *packet, uint32_t start, uint32_t offset_start, uint32_t offset_end, Request *req, Response res){ - - int i = 0; - int error = 0; - uint32_t segment_len = req->buff_len - start; - - for (i = offset_start; i < offset_end; i+= segment_len) { - - if (offset_end - i < segment_len){ - segment_len = offset_end - i; - } - - //ssp_printf("sending offset start %d to %d\n", i, i + segment_len); - //ssp_printf("segment len %d\n",segment_len); - - error = build_data_packet(packet, start, segment_len + start, i, req->file); - if (error < 0) { - return -1; - } - - ssp_sendto(res); - } -} - -int process_nak_pdu_response(char *packet, Request *req, Response res, Client *client){ - Pdu_nak nak; - get_nak_packet(packet, &nak); - - uint32_t packet_index = 0; - uint32_t offset_start = 0; - uint32_t offset_end = 0; - //build new header for outgoing packets - uint32_t outgoing_packet_index = build_pdu_header(req->buff, req->transaction_sequence_number, 0, 0, &client->pdu_header); - int error = 0; - int i = 0; - - - ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); - - for (i = 0; i < nak.segment_requests; i++){ - - packet_index = 0; - - memcpy(&offset_start, &nak.segments[packet_index], sizeof(uint32_t)); - offset_start = ssp_ntohl(offset_start); - packet_index += 4; - - memcpy(&offset_end, &nak.segments[packet_index], sizeof(uint32_t)); - offset_end = ssp_ntohl(offset_end); - packet_index += 4; - - segment_offset_into_data_packets(req->buff, outgoing_packet_index, offset_start, offset_end, req, res); - } - - return 1; - -} - int process_file_request_metadata(Request *req) { char temp[75]; @@ -819,6 +781,7 @@ void on_server_time_out(Response res, Request *req) { } else { //finished transaction, should have checksum complete, and received eof notification if (req->file->eof_checksum == req->file->partial_checksum && req->local_entity.EOF_recv_indication) { + ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); req->local_entity.transaction_finished_indication = true; resend_finished_pdu(req, res); return; diff --git a/Program/src/requests.c b/Program/src/requests.c index 58ff8d1..ccba50d 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -377,7 +377,7 @@ int put_request_no_client( int error = add_first_offset(req->file, req->file->total_size); if (error < 0) { ssp_free_file(req->file); - return NULL; + return -1; } req->file_size = file_size; From 6655a63b89effb6d71de3a3feaa00d4186d7d00a Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 14 Mar 2021 15:17:16 -0600 Subject: [PATCH 319/400] make an init_client function for ez of testing and readibility --- Program/include/file_delivery_app.h | 1 + Program/src/file_delivery_app.c | 32 +++++++++++++++++++-------- Program/test/mock.c | 4 ++++ Program/test/protocol_handler_tests.c | 8 +++++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 21f14a0..042420c 100755 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -13,5 +13,6 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app); void create_ssp_server(FTP *app); int create_ssp_server_drivers(FTP *app); void *create_ftp_task(uint32_t cfdp_id, FTP *app); +Client *init_client(uint32_t dest_cfdp_id, uint32_t my_cfdp_id); #endif diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index c5b3b1b..ac08f85 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -225,16 +225,16 @@ void *create_ftp_task(uint32_t cfdp_id, FTP *app){ return handler; } -Client *ssp_client(uint32_t cfdp_id, FTP *app) { + +Client *init_client(uint32_t dest_cfdp_id, uint32_t my_cfdp_id){ Remote_entity remote_entity; - int error = get_remote_entity_from_json(&remote_entity, cfdp_id); + int error = get_remote_entity_from_json(&remote_entity, dest_cfdp_id); if (error < 0) { ssp_error("couldn't get client remote_entity from mib\n"); return NULL; } - Client *client = ssp_alloc(sizeof(Client), 1); if (client == NULL) return NULL; @@ -255,16 +255,30 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { client->close = 0; client->remote_entity = remote_entity; - get_header_from_mib(&client->pdu_header, remote_entity, app->my_cfdp_id); + get_header_from_mib(&client->pdu_header, remote_entity, my_cfdp_id); client->current_request = NULL; - client->app = app; + return client; +} + +Client *ssp_client(uint32_t cfdp_id, FTP *app) { - error = create_ssp_client_drivers(client); + Client *client = init_client(cfdp_id, app->my_cfdp_id); + if (client == NULL) { + return NULL; + } + + int error = create_ssp_client_drivers(client); if (error < 0) { - ssp_free(client); - ssp_free(client->buff); - client->request_list->freeOnlyList(client->request_list); + ssp_cleanup_client(client); + return NULL; + } + + client->app = app; + error = app->active_clients->insert(app->active_clients, client, cfdp_id); + if (error < 0) { + ssp_cleanup_client(client); + ssp_printf("failed to add client to list of existing clients\n"); return NULL; } return client; diff --git a/Program/test/mock.c b/Program/test/mock.c index 9485911..698502c 100755 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -65,6 +65,10 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *fil return file; } +Client *mock_client() { + return init_client(2, 1); + +} Response *mock_response(char *buffer) { Response *res = calloc(1, sizeof(Response)); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index b0c15a5..befcc5a 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -190,6 +190,9 @@ int test_process_nak() { memset(packet, 0, 1500); Request *req = mock_request(); + Response *res = mock_response(); + Client *client = mock_client(); + ssp_free_file(req->file); req->file = create_file("test_files/nak_test.jpg", 0); @@ -199,7 +202,8 @@ int test_process_nak() { File *file = create_file(req->destination_file_name, 1); add_first_offset(file, req->file->total_size); - process_nak_pdu(&packet[start + SIZE_OF_DIRECTIVE_CODE], file); + + process_nak_pdu(&packet[start + SIZE_OF_DIRECTIVE_CODE], req, *res, client); int error = 0; error = ASSERT_EQUALS_INT("Nak list count should be of size 1", file->missing_offsets->count, 1); @@ -224,7 +228,7 @@ int protocol_handler_test() { error = test_process_pdu_eof(); //error = test_on_server_time_out(); error = test_process_data_packet(); - //error = test_process_nak(); + error = test_process_nak(); return error; } \ No newline at end of file From 10815deb00f1e806629d275b98d1d1a4b9d51ad0 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 14 Mar 2021 15:27:09 -0600 Subject: [PATCH 320/400] need to change linked list to -1 errors --- Program/src/file_delivery_app.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index ac08f85..17ea78f 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -276,7 +276,7 @@ Client *ssp_client(uint32_t cfdp_id, FTP *app) { client->app = app; error = app->active_clients->insert(app->active_clients, client, cfdp_id); - if (error < 0) { + if (error == 0) { ssp_cleanup_client(client); ssp_printf("failed to add client to list of existing clients\n"); return NULL; From 615797bcf2db735e8b7911d7adc6f618d84c0fc0 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 20 Mar 2021 14:17:12 -0600 Subject: [PATCH 321/400] add new revised receive_offset function --- Program/include/filesystem_funcs.h | 2 +- Program/src/filesystem_funcs.c | 69 ++++++++------ Program/src/main.c | 17 ++-- Program/src/packet.c | 3 +- Program/src/protocol_handler.c | 21 ++--- Program/test/filesystem_tests.c | 6 +- Program/test/mock.c | 11 ++- Program/test/packet_tests.c | 126 +++++++++++++++++++++++--- Program/test/protocol_handler_tests.c | 20 ++-- Program/test/unit_tests.h | 1 + 10 files changed, 200 insertions(+), 76 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index 5ff7d95..dcc0b80 100755 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -28,7 +28,7 @@ int get_offset(File *file, void *buff, uint32_t buf_size, int offset); int write_offset(File *file, void *buff, uint32_t size, uint32_t offset); uint32_t calc_check_sum(char *data, uint32_t length); uint32_t check_sum_file(File *file, uint16_t stack_buffer); -int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end); +int receive_offset(File *file, uint32_t offset_start, uint32_t offset_end); File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index b116a64..40ea7af 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -191,16 +191,18 @@ static int find_nak(void *element, void* args) { Offset *offset_in_list = (Offset *) element; Offset *offset_to_insert = (Offset *) args; - if (offset_to_insert->start >= offset_in_list->start && offset_to_insert->start <= offset_in_list->end - && offset_to_insert->end <= offset_in_list->end && offset_to_insert->end >= offset_in_list->start) { + + if (offset_to_insert->start >= offset_in_list->start \ + && offset_to_insert->start <= offset_in_list->end \ + && offset_to_insert->end <= offset_in_list->end \ + && offset_to_insert->end >= offset_in_list->start) { return 1; } - return 0; } -//ack is 1, nak is 0 -int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offset_end) { +//add_first_offset should be in create file +int receive_offset(File *file, uint32_t offset_start, uint32_t offset_end) { List * nak_list = file->missing_offsets; @@ -208,54 +210,61 @@ int receive_offset(File *file, uint8_t ack, uint32_t offset_start, uint32_t offs offset_to_insert.start = offset_start; offset_to_insert.end = offset_end; + //iterate through the list, and return the list node Node *node = nak_list->findNode(nak_list, -1, find_nak, &offset_to_insert); - if (node == NULL){ - ssp_printf("trying to receive offset start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end); - ssp_printf("no begining node for receive_offset, or offset we already received, can't add new offset\n"); + if (node == NULL){ + ssp_printf("offset already received, can't add new offset:%u end:%u\n", offset_start, offset_end); return 0; } Offset *offset_in_list = (Offset *) node->element; - //ssp_printf("received offset start:%u end:%u, found node: start:%u end:%u\n", offset_to_insert.start, offset_to_insert.end, offset_in_list->start, offset_in_list->end); - - //remove node if both start and end are equal - if (offset_to_insert.start == offset_in_list->start && offset_to_insert.end == offset_in_list->end) { - //ssp_printf("removing node\n"); + + //remove node if both start and end are equal (remove at function) + if (offset_start == offset_in_list->start && offset_end == offset_in_list->end) { node->next->prev = node->prev; node->prev->next = node->next; ssp_free(node->element); ssp_free(node); nak_list->count--; return 1; - } + + //if new offset is in the start, but the end of the offset is smaller than list's end, change the list's node's start + } else if (offset_start == offset_in_list->start && offset_start < offset_in_list->end) { + offset_in_list->start = offset_end; + return 1; - //if new offset is in the start, change the list's node's start - if (offset_to_insert.start == offset_in_list->start && offset_to_insert.start < offset_in_list->end) { - offset_in_list->start = offset_to_insert.end; + //if offset is at the list end, but the start of the offset is larger than list's start, move previous end down + } else if (offset_end == offset_in_list->end && offset_start > offset_in_list->start) { + offset_in_list->end = offset_start; return 1; } - + //if the offset is inbetween the 'start' and the 'end' offsets in the list, add new offset, and make the + //end of the lists first offset the start of the incoming offset, and the start of the second, the end of the incoming Offset *new_offset = ssp_alloc(1, sizeof(Offset)); + if (new_offset == NULL) { + return -1; + } - new_offset->start = offset_in_list->start; - offset_in_list->start = offset_end; - new_offset->end = offset_start; + new_offset->start = offset_end; + new_offset->end = offset_in_list->end; + offset_in_list->end = offset_start; + Node *cur = node; Node *new = createNode(new_offset, new_offset->start); + if (new == NULL) { + ssp_free(new_offset); + return -1; + } + + new->next = cur->next; + new->prev = cur; + cur->next = new; + new->next->prev = new; - new->next = cur; - new->prev = cur->prev; - new->prev->next = new; - cur->prev = new; nak_list->count++; - //remove end node - if (offset_in_list->start == offset_in_list->end){ - ssp_printf("removing last node\n"); - ssp_free(nak_list->pop(nak_list)); - } return 1; } diff --git a/Program/src/main.c b/Program/src/main.c index 9d69112..cc83528 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -48,6 +48,7 @@ typedef struct config uint8_t verbose_level; uint32_t baudrate; char *uart_device; + bool unackowledged_mode; } Config; @@ -65,10 +66,10 @@ static Config *configuration(int argc, char **argv) conf->my_cfdp_id = 0; conf->baudrate = 9600; conf->uart_device = NULL; - + conf->unackowledged_mode = 0; uint32_t tmp; - while ((ch = getopt(argc, argv, "t: i: c: v: k: h ")) != -1) + while ((ch = getopt(argc, argv, "t: i: c: v: k: hu ")) != -1) { switch (ch) { @@ -86,7 +87,9 @@ static Config *configuration(int argc, char **argv) tmp = strtol(optarg, NULL, 10); conf->verbose_level = (uint8_t) tmp; break; - + case 'u': + conf->unackowledged_mode = true; + break; case 'c': tmp = strtol(optarg, NULL, 10); conf->client_cfdp_id = tmp; @@ -105,6 +108,7 @@ static Config *configuration(int argc, char **argv) ssp_printf("\n-----------HELP MESSAGE------------\n"); ssp_printf("\nusage: %s [options] \n\n", basename(argv[0])); ssp_printf("Options: %s%s%s%s\n", + "-u un_ackowledged mode\n" "-t \n", "-i \n", "-c \n", @@ -196,7 +200,7 @@ int main(int argc, char** argv) { csp_route_print_table(); #endif - + FTP app; @@ -214,11 +218,10 @@ int main(int argc, char** argv) { if (client_id != -1) { sleep(5); - //csp_custom_ftp_ping(conf->client_cfdp_id); - //put_request(client_id, "test.txt", "test-received.txt", UN_ACKNOWLEDGED_MODE, &app); + put_request(client_id, "udp.jpeg", "test-received.jpg", conf->unackowledged_mode, &app); - put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); + //put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); //sleep(5); //put_request(client_id, "test.txt", "test-received.txt", UN_ACKNOWLEDGED_MODE, &app); /* diff --git a/Program/src/packet.c b/Program/src/packet.c index 4a151c1..4487fd4 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -537,7 +537,7 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { packet_index += 16; struct packet_nak_helper holder; - holder.max_number_of_nak_segments = (req->buff_len - packet_index) / sizeof(Offset); + holder.max_number_of_nak_segments = (req->res.packet_len - packet_index) / sizeof(Offset); holder.packet = &packet[packet_index]; holder.current_number_of_segments = 0; @@ -550,6 +550,7 @@ uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { uint32_t net_end_scope = ssp_htonl(end_scope); uint64_t net_segments_number = ssp_htonll(holder.current_number_of_segments); + ssp_printf("building nak packet offset start:end %d:%d\n", start_scope, end_scope); packet_index = start + 1; memcpy(&packet[packet_index], &net_start_scope, sizeof(uint32_t)); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2fb83f4..4b54c8a 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -222,12 +222,13 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { uint32_t offset_start = get_data_offset_from_packet(packet); uint32_t packet_index = 4; - //ssp_printf("received data packet offset:%d\n", offset_start); // size of 'offset' bytes in packet uint32_t offset_end = offset_start + data_len - packet_index; - - if (!receive_offset(file, 0, offset_start, offset_end)) { + + ssp_printf("received offset %d:%d\n", offset_start, offset_end); + + if (!receive_offset(file, offset_start, offset_end)) { ssp_printf("throwing out packet\n"); return; } @@ -238,11 +239,11 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { ssp_error("no new data was written\n"); return; } + file->partial_checksum += calc_check_sum(&packet[packet_index], bytes); - + if (file->missing_offsets->count == 0) return; - } @@ -498,7 +499,7 @@ static int segment_offset_into_data_packets(char *packet, uint32_t start, uint32 segment_len = offset_end - i; } - //ssp_printf("sending offset start %d to %d\n", i, i + segment_len); + ssp_printf("sending offset start %d to %d\n", i, i + segment_len); //ssp_printf("segment len %d\n",segment_len); error = build_data_packet(packet, start, segment_len + start, i, req->file); @@ -515,9 +516,8 @@ static int segment_offset_into_data_packets(char *packet, uint32_t start, uint32 int process_nak_pdu(char *packet, Request *req, Response res, Client *client){ Pdu_nak nak; - get_nak_packet(packet, &nak); - - uint32_t packet_index = 0; + + uint32_t packet_index = get_nak_packet(packet, &nak); uint32_t offset_start = 0; uint32_t offset_end = 0; //build new header for outgoing packets @@ -525,11 +525,10 @@ int process_nak_pdu(char *packet, Request *req, Response res, Client *client){ int i = 0; ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); + ssp_printf("number of segments requests %d\n", nak.segment_requests); for (i = 0; i < nak.segment_requests; i++){ - packet_index = 0; - memcpy(&offset_start, (uint32_t*)&nak.segments[packet_index], sizeof(uint32_t)); offset_start = ssp_ntohl(offset_start); packet_index += 4; diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 21f4d53..9ab8458 100755 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -16,13 +16,13 @@ static void nak_print(Node *node, void *element, void *args){ static int receive_offset_tests(){ File *file = create_temp_file("temp_test", 2000); - receive_offset(file, 0, 5, 50); + receive_offset(file, 5, 50); file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); - receive_offset(file, 0, 100, 1000); + receive_offset(file, 100, 1000); file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); - receive_offset(file, 0, 50, 100); + receive_offset(file, 50, 100); file->missing_offsets->iterate(file->missing_offsets, nak_print, 0); return 0; diff --git a/Program/test/mock.c b/Program/test/mock.c index 698502c..2f391ec 100755 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -13,7 +13,7 @@ #include #include -char buff[1500]; +//char buff[1500]; void mock_mock_remote_entity(Remote_entity *remote_entity, uint32_t cfdp_id) { @@ -66,7 +66,8 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *fil } Client *mock_client() { - return init_client(2, 1); + Client *c = init_client(2, 1); + return c; } @@ -84,7 +85,8 @@ Response *mock_response(char *buffer) { } Request *mock_empty_request() { - return init_request(buff, sizeof(buff)); + void *buff = calloc(1500, sizeof(char)); + return init_request(buff, 1500); } Request *mock_request() { @@ -114,8 +116,9 @@ Request *mock_request() { int addr = 16; req->res.addr = malloc(5); ssp_memcpy(req->res.addr, &addr, 4); + req->res.sfd = 1; - req->res.packet_len = sizeof(buff); + req->res.packet_len = 250; req->res.size_of_addr = 16; req->res.type_of_network = posix_connectionless; req->res.transmission_mode = UN_ACKNOWLEDGED_MODE; diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 4d3e891..67b7abe 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -76,7 +76,7 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ } -static void nak_print(void *element, void *args){ +static void nak_print(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; ssp_printf("start: %u end: %u\n", offset->start, offset->end); } @@ -120,10 +120,9 @@ static int test_build_nak_packet(char* packet, uint32_t start) { ASSERT_EQUALS_INT("start offset == 0 ", start_scope, 0); ASSERT_EQUALS_INT("end scope == 100000 ", end_scope, 100000); - - receive_offset(req->file, 0, 1250, 5000); - receive_offset(req->file, 0, 6000, 9000); - receive_offset(req->file, 0, 10000, 15000); + receive_offset(req->file, 1250, 5000); + receive_offset(req->file, 6000, 9000); + receive_offset(req->file, 10000, 15000); data_len = build_nak_packet(packet, start, req); set_data_length(packet, data_len); @@ -182,6 +181,106 @@ static int test_build_nak_packet(char* packet, uint32_t start) { } + +static int test_receive_end_offset(File *file){ + add_first_offset(file, file->total_size); + ASSERT_EQUALS_INT("file filesize", 150033, file->total_size); + ASSERT_EQUALS_INT("offset length should be 1", 1, file->missing_offsets->count); + + receive_offset(file, 100000, 150033); + + ASSERT_EQUALS_INT("offset length should be 1 after insert end", 1, file->missing_offsets->count); + Offset *of =(Offset *) file->missing_offsets->pop(file->missing_offsets); + ASSERT_EQUALS_INT("offset start should be 0 after insert end", 0, of->start); + ASSERT_EQUALS_INT("offset end should be 100000 after insert end", 100000, of->end); + ssp_free(of); +} + + +static int test_receive_start_offset(File *file){ + add_first_offset(file, file->total_size); + ASSERT_EQUALS_INT("file filesize", 150033, file->total_size); + ASSERT_EQUALS_INT("offset length should be 1", 1, file->missing_offsets->count); + + receive_offset(file, 0, 10000); + + ASSERT_EQUALS_INT("offset length should be 1 after insert end", 1, file->missing_offsets->count); + Offset *of =(Offset *) file->missing_offsets->pop(file->missing_offsets); + ASSERT_EQUALS_INT("offset start should be 10000 after insert start", 10000, of->start); + ASSERT_EQUALS_INT("offset end should be 150033 after insert start", file->total_size, of->end); + ssp_free(of); +} + + +static int test_receive_middle_offset(File *file){ + add_first_offset(file, file->total_size); + ASSERT_EQUALS_INT("file filesize", 150033, file->total_size); + ASSERT_EQUALS_INT("offset length should be 1", 1, file->missing_offsets->count); + + receive_offset(file, 5000, 10000); + + ASSERT_EQUALS_INT("offset length should be 1 after insert end", 2, file->missing_offsets->count); + Offset *of =(Offset *) file->missing_offsets->pop(file->missing_offsets); + + ASSERT_EQUALS_INT("offset start should be 10000 after insert mid", 10000, of->start); + ASSERT_EQUALS_INT("offset end should be 150033 after insert mid", file->total_size, of->end); + + ASSERT_EQUALS_INT("offset length should be 1 after insert end", 1, file->missing_offsets->count); + ssp_free(of); + of =(Offset *) file->missing_offsets->pop(file->missing_offsets); + + ASSERT_EQUALS_INT("offset start should be 0 after insert mid", 0, of->start); + ASSERT_EQUALS_INT("offset end should be 5000 after insert mid", 5000, of->end); + ssp_free(of); +} + + +static int test_receive_parts_offset(File *file){ + add_first_offset(file, file->total_size); + ASSERT_EQUALS_INT("file filesize", 150033, file->total_size); + ASSERT_EQUALS_INT("offset length should be 1", 1, file->missing_offsets->count); + + receive_offset(file, 500, 1000); + receive_offset(file, 1000, 10000); + receive_offset(file, 0, 500); + receive_offset(file, 10000, 10500); + receive_offset(file, 10500, 150033); + + + ASSERT_EQUALS_INT("offset length should be 0 after insert end", 0, file->missing_offsets->count); +} + +static int test_receive_final_offset(File *file){ + add_first_offset(file, file->total_size); + ASSERT_EQUALS_INT("file filesize", 150033, file->total_size); + ASSERT_EQUALS_INT("offset length should be 1", 1, file->missing_offsets->count); + + receive_offset(file, 0, 150033); + ASSERT_EQUALS_INT("offset length should be 0 after insert end", 0, file->missing_offsets->count); + + add_first_offset(file, file->total_size); + receive_offset(file, 0, 100000); + receive_offset(file, 100000, 150032); + receive_offset(file, 150032, 150033); + + ASSERT_EQUALS_INT("offset length should be 0 after insert end", 0, file->missing_offsets->count); +} + + + +static int test_receive_offset(){ + + + File *file = create_file("test_files/test_receive.jpg", 0); + test_receive_end_offset(file); + test_receive_start_offset(file); + test_receive_middle_offset(file); + test_receive_parts_offset(file); + test_receive_final_offset(file); + file->missing_offsets->iterate(file->missing_offsets, nak_print, NULL); + +} + static int test_build_very_large_nak_packet(char* packet, uint32_t start) { DECLARE_NEW_TEST("testing build very large nak packet"); @@ -195,7 +294,7 @@ static int test_build_very_large_nak_packet(char* packet, uint32_t start) { //fail receiving weird offsets for (int i = 0; i < 10000; i+=10) { - receive_offset(file, 0, i, i+10); + receive_offset(file, i, i+10); i++; } uint64_t count = file->missing_offsets->count; @@ -269,8 +368,8 @@ int test_build_pdu_header(char *packet, Pdu_header *header) { header->transaction_seq_num_len = 2; memset(&new_header, 0, 4); - - int length = build_pdu_header(packet, header->transaction_sequence_number, header->direction, header->PDU_data_field_len, header); + + int length = build_pdu_header(packet, header->transaction_sequence_number, header->transmission_mode, header->PDU_data_field_len, header); if (length < 0) { ssp_printf("failed to build pdu header\n"); } @@ -649,10 +748,10 @@ int packet_tests() { int error = get_remote_entity_from_json (&remote_entity, 1); get_header_from_mib(&pdu_header, remote_entity, 2); - + /* error = test_copying_lvs(); int data_start_index = test_build_pdu_header(packet, &pdu_header); - + test_build_metadata_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); test_add_cont_part_to_packet(packet, data_start_index); @@ -661,11 +760,14 @@ int packet_tests() { test_build_eof_packet(packet, data_start_index); test_build_data_packet(packet, data_start_index); - test_build_nak_packet(packet, data_start_index); + */ + //test_build_nak_packet(packet, data_start_index); + test_receive_offset(); + /* test_build_finished_pdu(packet, data_start_index); test_add_messages_to_packet(packet, data_start_index); test_get_message_from_packet(packet, data_start_index); - + */ //next up //Skip for now, will fix after connection server works diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index befcc5a..beb5ea5 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -183,6 +183,7 @@ int test_process_data_packet() { int test_process_nak() { + DECLARE_NEW_TEST("testing nak client response"); char packet[2000]; uint32_t start = 20; @@ -192,17 +193,16 @@ int test_process_nak() { Request *req = mock_request(); Response *res = mock_response(); Client *client = mock_client(); - + ssp_free_file(req->file); req->file = create_file("test_files/nak_test.jpg", 0); - add_first_offset(req->file, req->file->total_size); + build_nak_packet(packet, start, req); File *file = create_file(req->destination_file_name, 1); add_first_offset(file, req->file->total_size); - - + process_nak_pdu(&packet[start + SIZE_OF_DIRECTIVE_CODE], req, *res, client); int error = 0; @@ -213,8 +213,14 @@ int test_process_nak() { error = ASSERT_EQUALS_INT("offset start should be 0", offset->start, 0); error = ASSERT_EQUALS_INT("offset end should be file size", offset->end, 150033); + ssp_free(offset); + ssp_free_file(file); ssp_cleanup_req(req); + ssp_cleanup_client(client); + ssp_free(res); + return error; + } void test_send_data_from_nak_array(){ @@ -224,10 +230,10 @@ void test_send_data_from_nak_array(){ int protocol_handler_test() { int error = 0; - error = test_process_pdu_header(); - error = test_process_pdu_eof(); + //error = test_process_pdu_header(); + //error = test_process_pdu_eof(); //error = test_on_server_time_out(); - error = test_process_data_packet(); + //error = test_process_data_packet(); error = test_process_nak(); return error; diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index d63cb25..229a72d 100755 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -19,6 +19,7 @@ File *mock_eof_packet(char *packet, uint32_t dest_id, uint32_t src_id, char *fil Request *mock_request(); Request *mock_empty_request(); List *populate_request_list(); +Client *mock_client(); #define TEMP_FILESIZE 1000 From 5cfa445ce21c77099d9b67cab9c23a4d47127c82 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 20 Mar 2021 19:09:48 -0600 Subject: [PATCH 322/400] fix one off error for naks --- Program/src/filesystem_funcs.c | 7 +++---- Program/src/packet.c | 11 ++++++++++- Program/src/protocol_handler.c | 29 ++++++++++++++++++----------- Program/test/packet_tests.c | 25 +++++++++++++++++++------ 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 40ea7af..265bafc 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -219,7 +219,7 @@ int receive_offset(File *file, uint32_t offset_start, uint32_t offset_end) { } Offset *offset_in_list = (Offset *) node->element; - + //remove node if both start and end are equal (remove at function) if (offset_start == offset_in_list->start && offset_end == offset_in_list->end) { node->next->prev = node->prev; @@ -255,7 +255,7 @@ int receive_offset(File *file, uint32_t offset_start, uint32_t offset_end) { Node *new = createNode(new_offset, new_offset->start); if (new == NULL) { ssp_free(new_offset); - return -1; + return 0; } new->next = cur->next; @@ -294,14 +294,13 @@ File *create_temp_file(char *file_name, uint32_t size) { return file; } -/* + static int print_nak(void *element, void* args) { Offset *offset_in_list = (Offset *) element; ssp_printf("start: %u, end: %u\n", offset_in_list->start, offset_in_list->end); return 0; } -*/ int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file) { diff --git a/Program/src/packet.c b/Program/src/packet.c index 4487fd4..2b660af 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -370,7 +370,8 @@ int build_data_packet(char *packet, uint32_t start, uint32_t end, uint32_t offse packet_index += sizeof(uint32_t); - int bytes = get_offset(file, &packet[packet_index], data_size - 4, offset); + //the -4 is because wehave to include the 'bet_offset' bytes + int bytes = get_offset(file, &packet[packet_index], data_size-4, offset); if (bytes <= 0){ ssp_error("could not get offset, this could because the file is empty!\n"); return -1; @@ -477,6 +478,7 @@ void fill_nak_array_callback(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; Offset offset_to_copy; + ssp_printf("sending start:end %d:%d\n", offset->start, offset->end); offset_to_copy.start = ssp_htonl(offset->start); offset_to_copy.end = ssp_htonl(offset->end); @@ -527,6 +529,13 @@ int get_nak_packet(char *packet, Pdu_nak *nak) { return packet_index; } +static int print_nak(void *element, void* args) { + + Offset *offset_in_list = (Offset *) element; + ssp_printf("start: %d, end: %d\n", offset_in_list->start, offset_in_list->end); + return 0; +} + //this function is weird because it uses a callback into an iterator. We fill the array //with as many 'offsets' as we can. uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 4b54c8a..86863ea 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -226,7 +226,7 @@ void process_data_packet(char *packet, uint32_t data_len, File *file) { // size of 'offset' bytes in packet uint32_t offset_end = offset_start + data_len - packet_index; - ssp_printf("received offset %d:%d\n", offset_start, offset_end); + //ssp_printf("received offset %d:%d\n", offset_start, offset_end); if (!receive_offset(file, offset_start, offset_end)) { ssp_printf("throwing out packet\n"); @@ -489,9 +489,12 @@ static void start_sequence(Request *req, Response res) { static int segment_offset_into_data_packets(char *packet, uint32_t start, uint32_t offset_start, uint32_t offset_end, Request *req, Response res){ + int i = 0; - int error = 0; - uint32_t segment_len = req->buff_len - start; + int error = 0; + + //the segment length has to reduce the length of the segment by the 'offset' bytes in the data packet + uint32_t segment_len = req->buff_len - start - sizeof(uint32_t); for (i = offset_start; i < offset_end; i+= segment_len) { @@ -499,21 +502,22 @@ static int segment_offset_into_data_packets(char *packet, uint32_t start, uint32 segment_len = offset_end - i; } - ssp_printf("sending offset start %d to %d\n", i, i + segment_len); + //ssp_printf("sending offset start %d to %d\n", i, i + segment_len); //ssp_printf("segment len %d\n",segment_len); - error = build_data_packet(packet, start, segment_len + start, i, req->file); + error = build_data_packet(packet, start, req->buff_len, i, req->file); if (error < 0) { ssp_printf("couldn't create data packet for offset %d\n", i); continue; } - ssp_sendto(res); } return 0; } + + int process_nak_pdu(char *packet, Request *req, Response res, Client *client){ Pdu_nak nak; @@ -525,18 +529,21 @@ int process_nak_pdu(char *packet, Request *req, Response res, Client *client){ int i = 0; ssp_printf("sending offset packet start %d offset end %d\n", nak.start_scope, nak.end_scope); - ssp_printf("number of segments requests %d\n", nak.segment_requests); - + //ssp_printf("number of segments requests %d\n", nak.segment_requests); + for (i = 0; i < nak.segment_requests; i++){ - memcpy(&offset_start, (uint32_t*)&nak.segments[packet_index], sizeof(uint32_t)); + memcpy(&offset_start, &packet[packet_index], sizeof(uint32_t)); offset_start = ssp_ntohl(offset_start); packet_index += 4; - memcpy(&offset_end, (uint32_t*)&nak.segments[packet_index], sizeof(uint32_t)); + memcpy(&offset_end, &packet[packet_index], sizeof(uint32_t)); offset_end = ssp_ntohl(offset_end); packet_index += 4; + + //ssp_printf("offset_start %d offset_end %d \n", offset_start, offset_end); + segment_offset_into_data_packets(req->buff, outgoing_packet_index, offset_start, offset_end, req, res); } @@ -786,7 +793,7 @@ void on_server_time_out(Response res, Request *req) { return; } - ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); + ssp_printf("checksum have: %u checksum_need: %u\n", ssp_htonl(req->file->partial_checksum), req->file->eof_checksum); //uint32_t checksum = check_sum_file(req->file, 1000); //ssp_printf("checksum re-calculated: %u\n", checksum); diff --git a/Program/test/packet_tests.c b/Program/test/packet_tests.c index 67b7abe..cad8f39 100755 --- a/Program/test/packet_tests.c +++ b/Program/test/packet_tests.c @@ -65,7 +65,7 @@ static void test_build_data_packet(char *packet, uint32_t packet_index){ File *file = create_file("test_files/testfile", 0); - create_data_burst_packets(packet, packet_index, file, 1000); + create_data_burst_packets(packet, packet_index, file, 1500); uint32_t offset = get_data_offset_from_packet(&packet[packet_index]); @@ -266,10 +266,19 @@ static int test_receive_final_offset(File *file){ ASSERT_EQUALS_INT("offset length should be 0 after insert end", 0, file->missing_offsets->count); } +static int test_nak_print(File *file){ + add_first_offset(file, file->total_size); + ASSERT_EQUALS_INT("file filesize", 150033, file->total_size); + ASSERT_EQUALS_INT("offset length should be 1", 1, file->missing_offsets->count); -static int test_receive_offset(){ + receive_offset(file, 148900, 150033); + + file->missing_offsets->iterate(file->missing_offsets, nak_print, NULL); +} + +static int test_receive_offset(){ File *file = create_file("test_files/test_receive.jpg", 0); test_receive_end_offset(file); @@ -277,7 +286,9 @@ static int test_receive_offset(){ test_receive_middle_offset(file); test_receive_parts_offset(file); test_receive_final_offset(file); - file->missing_offsets->iterate(file->missing_offsets, nak_print, NULL); + test_nak_print(file); + + } @@ -748,19 +759,21 @@ int packet_tests() { int error = get_remote_entity_from_json (&remote_entity, 1); get_header_from_mib(&pdu_header, remote_entity, 2); + + int data_start_index = test_build_pdu_header(packet, &pdu_header); /* error = test_copying_lvs(); - int data_start_index = test_build_pdu_header(packet, &pdu_header); test_build_metadata_packet(packet, data_start_index); test_get_messages_from_packet(packet, data_start_index); test_add_cont_part_to_packet(packet, data_start_index); test_get_cont_partial_from_packet(packet, data_start_index); test_build_ack_eof_pdu(packet, data_start_index); - +*/ test_build_eof_packet(packet, data_start_index); + test_build_data_packet(packet, data_start_index); - */ + //test_build_nak_packet(packet, data_start_index); test_receive_offset(); /* From 8510506556accf8268b5d71ab8c3b7d75e15b6e9 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 20 Mar 2021 19:17:50 -0600 Subject: [PATCH 323/400] remove ssp_ntohl func --- Program/src/protocol_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 86863ea..2ee8a5e 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -793,7 +793,7 @@ void on_server_time_out(Response res, Request *req) { return; } - ssp_printf("checksum have: %u checksum_need: %u\n", ssp_htonl(req->file->partial_checksum), req->file->eof_checksum); + ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); //uint32_t checksum = check_sum_file(req->file, 1000); //ssp_printf("checksum re-calculated: %u\n", checksum); From 8ca311840b23960bbc8d6765437a06d013848816 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 20 Mar 2021 19:39:18 -0600 Subject: [PATCH 324/400] 46 bit transaction id --- Program/src/port.c | 5 +++-- Program/src/protocol_handler.c | 2 +- Program/src/utils.c | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 908cb52..8d9af1f 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -170,7 +170,8 @@ void ssp_sendto(Response res) { #ifdef TEST return; #endif - + // sleep(1); + if (res.type_of_network == generic) { #ifdef FREE_RTOS_PORT @@ -263,7 +264,7 @@ void *ssp_alloc(uint32_t n_memb, size_t size) { #ifdef FREE_RTOS_PORT void *mem = pvPortMalloc(n_memb * size); memset(mem, 0, n_memb * size); - return mem + return mem; #else void *mem = calloc(n_memb, size); #endif diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2ee8a5e..63234b5 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -13,7 +13,7 @@ Author: Evan Giese #include "types.h" #include "utils.h" -static void transasction_log(char *msg, uint32_t transaction_sequence_number){ +static void transasction_log(char *msg, uint64_t transaction_sequence_number){ ssp_printf("transaction: %llu ", transaction_sequence_number); ssp_printf(msg); ssp_printf("\n"); diff --git a/Program/src/utils.c b/Program/src/utils.c index 9ca4728..0eda7ed 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -22,7 +22,6 @@ void ssp_print_hex(char *stuff, int size){ void ssp_print_bits(char *stuff, int size){ - uint32_t current_packet_index = 0; ssp_printf("printing number of bytes: %u\n", size); int j, i, bit_set, byte = 0; unsigned char bit_mask = 0; From bf752e13e537f9d520c3a887b873b6c503cb9f58 Mon Sep 17 00:00:00 2001 From: evanGee Date: Mon, 22 Mar 2021 18:51:51 -0600 Subject: [PATCH 325/400] change network --- Program/src/app_control.c | 2 +- Program/src/csp_server_provider.c | 2 +- Program/src/file_delivery_app.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 1caef22..7deb560 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -221,7 +221,7 @@ int refresh_response_struct(Response old_res, Response new_res){ } ssp_printf("setting response struct\n"); - memcpy(new_res.addr, old_res.addr, old_res.size_of_addr); + memcpy(old_res.addr, new_res.addr, old_res.size_of_addr); return 1; } diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index ca88115..f8215ae 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -254,10 +254,10 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, csp_close(conn); - onExit(other); } + onExit(other); ssp_free(buff); } diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 17ea78f..edaa8a0 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -87,7 +87,7 @@ static void make_default_data(){ \"cfdp_id\": 0,\n\ \"UT_address\" : 0,\n\ \"UT_port\" : 20,\n\ - \"type_of_network\" : 3,\n\ + \"type_of_network\" : 2,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 250,\n\ \"one_way_light_time\" : 123,\n\ @@ -109,7 +109,7 @@ static void make_default_data(){ \"cfdp_id\": 10,\n\ \"UT_address\" : 10,\n\ \"UT_port\" : 1,\n\ - \"type_of_network\" : 3,\n\ + \"type_of_network\" : 2,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 250,\n\ \"one_way_light_time\" : 123,\n\ From d1bbcefcb31bb1e0382473ad284598da1c8b2c4d Mon Sep 17 00:00:00 2001 From: evanGee Date: Mon, 22 Mar 2021 19:33:09 -0600 Subject: [PATCH 326/400] change network --- Program/src/csp_server_provider.c | 46 ++++++++++++++++--------------- Program/src/file_delivery_app.c | 4 +-- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index f8215ae..02ef9d9 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -222,6 +222,8 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, } //Pointer to current connection and packet csp_conn_t *conn; + csp_conn_t *old_conn; + csp_packet_t *packet; char *buff = ssp_alloc(packet_len, sizeof(char)); @@ -238,11 +240,11 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, conn = csp_accept(sock, 1000); if (conn == NULL) { - onTimeOut(other); + csp_close(old_conn); continue; } - while ((packet = csp_read(conn, 1000)) != NULL) { + while ((packet = csp_read(conn, 10000)) != NULL) { memcpy(buff, (char *)packet->data, packet_len); @@ -251,12 +253,11 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, csp_buffer_free(packet); } - - - csp_close(conn); - + onTimeOut(other); + old_conn = conn; } + csp_close(conn); onExit(other); ssp_free(buff); } @@ -283,6 +284,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, while (1) { if (get_exit() || checkExit(params)){ + ssp_printf("exiting client thread\n"); break; } @@ -294,27 +296,27 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, return; } - for (;;) { - if (get_exit() || checkExit(params)){ - ssp_printf("exiting client thread\n"); - break; - } - onSend(-1, conn, sizeof(conn), params); - while ((packet = csp_read(conn, 10)) != NULL) { - - memcpy(buff, (char *)packet->data, packet_len); - if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), params) == -1) - ssp_printf("recv failed\n"); + onSend(-1, conn, sizeof(conn), params); + + while ((packet = csp_read(conn, 100)) != NULL) { + + memcpy(buff, (char *)packet->data, packet_len); + + if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), params) == -1) + ssp_printf("recv failed\n"); - csp_buffer_free(packet); + csp_buffer_free(packet); - } } - /* Close connection */ - csp_close(conn); - onExit(params); + + } + + /* Close connection */ + csp_close(conn); + onExit(params); + ssp_free(buff); } diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index edaa8a0..17ea78f 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -87,7 +87,7 @@ static void make_default_data(){ \"cfdp_id\": 0,\n\ \"UT_address\" : 0,\n\ \"UT_port\" : 20,\n\ - \"type_of_network\" : 2,\n\ + \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 250,\n\ \"one_way_light_time\" : 123,\n\ @@ -109,7 +109,7 @@ static void make_default_data(){ \"cfdp_id\": 10,\n\ \"UT_address\" : 10,\n\ \"UT_port\" : 1,\n\ - \"type_of_network\" : 2,\n\ + \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 250,\n\ \"one_way_light_time\" : 123,\n\ From b5accf8bf222ee40741eaded21f2dc6591748f17 Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 24 Mar 2021 20:41:45 -0600 Subject: [PATCH 327/400] update csp server --- Program/include/protocol_handler.h | 2 +- Program/src/csp_server_provider.c | 26 ++++++++++++-------------- Program/src/protocol_handler.c | 5 ++--- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 4e57240..ae11829 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -12,7 +12,7 @@ Author: Evan Giese #define RESEND_FINISHED_TIMES 1 #define RESEND_META_TIMES 1 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 60 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 1000000 #define TIMEOUT_BEFORE_SAVE_REQUEST 30 int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 02ef9d9..6c90ded 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -253,6 +253,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, csp_buffer_free(packet); } + onTimeOut(other); old_conn = conn; } @@ -281,25 +282,22 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, return; } + while (1) { if (get_exit() || checkExit(params)){ ssp_printf("exiting client thread\n"); break; } - - /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ - conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 1000, CSP_SO_NONE); - if (conn == NULL) { - /* Connect failed */ - ssp_printf("Connection failed\n"); - return; - } - + /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ + conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 10, CSP_SO_NONE); + if (conn == NULL) { + continue; + } onSend(-1, conn, sizeof(conn), params); - - while ((packet = csp_read(conn, 100)) != NULL) { + + while ((packet = csp_read(conn, 10000)) != NULL) { memcpy(buff, (char *)packet->data, packet_len); @@ -309,13 +307,13 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_buffer_free(packet); } - - + + csp_close(conn); } /* Close connection */ - csp_close(conn); + onExit(params); ssp_free(buff); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 63234b5..32b78ba 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -440,8 +440,7 @@ static void acknowledged_start(Request *req, Response res) { } while (!create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { - //ssp_sendto(res); - + ssp_sendto(res); } ssp_sendto(res); @@ -793,7 +792,7 @@ void on_server_time_out(Response res, Request *req) { return; } - ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); + //ssp_printf("checksum have: %u checksum_need: %u\n", req->file->partial_checksum, req->file->eof_checksum); //uint32_t checksum = check_sum_file(req->file, 1000); //ssp_printf("checksum re-calculated: %u\n", checksum); From 3f80c44ba716086bfcda2e2192f57601958444dc Mon Sep 17 00:00:00 2001 From: evanGee Date: Wed, 24 Mar 2021 20:46:48 -0600 Subject: [PATCH 328/400] update csp server --- Program/src/app_control.c | 8 ++++++-- Program/src/csp_server_provider.c | 34 +++++++++++++++---------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 7deb560..93bd2e2 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -130,6 +130,8 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u Request **request_container = &client->current_request; Pdu_header incoming_pdu_header; + + int packet_index = process_pdu_header(packet, false, &incoming_pdu_header, res, request_container, client->request_list, client->app); if (packet_index < 0) { @@ -183,7 +185,7 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi res.type_of_network = client->remote_entity.type_of_network; res.transmission_mode = client->remote_entity.default_transmission_mode; res.msg = client->buff; - + struct user_request_check_params params = { res, client @@ -273,12 +275,14 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, u app->current_request = current_request; //refresh response + /* int error = refresh_response_struct(current_request->res, res); if (error < 0) { ssp_printf("failed to connect to new client\n"); return -1; } - + */ + int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, incoming_pdu_header, app); reset_timeout(¤t_request->timeout_before_cancel); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 6c90ded..48faa84 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -189,7 +189,6 @@ int csp_custom_ftp_ping(uint32_t dest_id){ return -1; } - void csp_connection_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), @@ -201,7 +200,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, int error = 0; //csp_socket_t *socket = csp_socket(CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ); - //Create socket without any socket options + //Create socket without any socket options //CSP_SO_NONE csp_socket_t *sock = csp_socket(CSP_SO_NONE); if (sock == NULL) { ssp_error("csp socket failed to initialize"); @@ -221,9 +220,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, return; } //Pointer to current connection and packet - csp_conn_t *conn; - csp_conn_t *old_conn; - + csp_conn_t *conn = NULL; csp_packet_t *packet; char *buff = ssp_alloc(packet_len, sizeof(char)); @@ -238,27 +235,28 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, if (get_exit() || checkExit(other)) break; - conn = csp_accept(sock, 1000); + + conn = csp_accept(sock, 10); if (conn == NULL) { - csp_close(old_conn); + onTimeOut(other); continue; } - while ((packet = csp_read(conn, 10000)) != NULL) { + while(1) { + onTimeOut(other); - memcpy(buff, (char *)packet->data, packet_len); + while ((packet = csp_read(conn, 1000)) != NULL) { - if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), other) == -1) - ssp_printf("recv failed\n"); + memset(buff, 0, packet_len); + memcpy(buff, (char *)packet->data, packet->length); - csp_buffer_free(packet); - } - - onTimeOut(other); - old_conn = conn; - } + if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), other) == -1) + ssp_printf("recv failed\n"); - csp_close(conn); + csp_buffer_free(packet); + } + } + } onExit(other); ssp_free(buff); } From dfa1741958e49ee53ff3e6cdf2648811e5016f32 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 27 Mar 2021 13:26:05 -0600 Subject: [PATCH 329/400] make it so when a request times out, it goes back to 'accept'. One clien --- Program/src/app_control.c | 6 +++++- Program/src/csp_server_provider.c | 11 ++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 93bd2e2..0ea04de 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -235,6 +235,7 @@ static void timeout_check_callback_server(Node *node, void *request, void *args) remove_request_check(node, request, args); } +//return 1 if there are active requests, 0 if not static int on_time_out_callback_server(void *other) { FTP *app = (FTP*) other; @@ -244,9 +245,12 @@ static int on_time_out_callback_server(void *other) { } if (app->request_list->count) { app->request_list->iterate(app->request_list, timeout_check_callback_server, app->request_list); + + } else { + return 0; } - return 0; + return 1; } static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other) { diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 48faa84..1dc48ef 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -59,7 +59,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p ssp_error("couldn't get new packet for sending!\n"); set_exit(); } - char buff[packet_len]; + char *buff = ssp_alloc(sizeof(char), packet_len); memset(buff, 0, packet_len); for (;;) { @@ -238,12 +238,13 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, conn = csp_accept(sock, 10); if (conn == NULL) { - onTimeOut(other); continue; } while(1) { - onTimeOut(other); + //if the request has timedout, go back to waiting for accept + if (!onTimeOut(other)) + break; while ((packet = csp_read(conn, 1000)) != NULL) { @@ -251,7 +252,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, memcpy(buff, (char *)packet->data, packet->length); if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), other) == -1) - ssp_printf("recv failed\n"); + ssp_printf("recv failed\n"); csp_buffer_free(packet); } @@ -300,7 +301,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, memcpy(buff, (char *)packet->data, packet_len); if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), params) == -1) - ssp_printf("recv failed\n"); + ssp_printf("recv failed\n"); csp_buffer_free(packet); From 6574decc9e8794dbc8fab94781787960588db83e Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 27 Mar 2021 13:41:36 -0600 Subject: [PATCH 330/400] close connection if no packets received after data burst --- Program/src/csp_server_provider.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 1dc48ef..01efd28 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -242,10 +242,15 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, } while(1) { + + if (get_exit() || checkExit(other)) + break; + //if the request has timedout, go back to waiting for accept if (!onTimeOut(other)) break; + while ((packet = csp_read(conn, 1000)) != NULL) { memset(buff, 0, packet_len); @@ -289,7 +294,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, break; } /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ - conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 10, CSP_SO_NONE); + conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 100, CSP_SO_NONE); if (conn == NULL) { continue; } @@ -297,7 +302,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, onSend(-1, conn, sizeof(conn), params); while ((packet = csp_read(conn, 10000)) != NULL) { - + memcpy(buff, (char *)packet->data, packet_len); if (onRecv(-1, buff, packet_len, NULL, conn, sizeof(struct csp_conn_s), params) == -1) @@ -305,14 +310,12 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_buffer_free(packet); - } - - csp_close(conn); - + } + csp_close(conn); } /* Close connection */ - + csp_close(conn); onExit(params); ssp_free(buff); From 3d5501d359f1d24a00bb6961f914f634701e277b Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 28 Mar 2021 16:11:55 -0600 Subject: [PATCH 331/400] fix bug where extra client is started --- Program/src/app_control.c | 15 +++++++++++++-- Program/src/csp_server_provider.c | 9 +++++---- Program/src/requests.c | 3 +-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 0ea04de..756e235 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -323,7 +323,11 @@ static int check_exit_client_callback(void *params) { ------------------------------------------------------------------------------*/ static void on_exit_client_callback (void *params) { - + Client *client = (Client *) params; + if (client == NULL) + return; + + client->close = true; } static void on_exit_server_callback (void *params) { @@ -624,6 +628,9 @@ void *ssp_generic_server_task(void *params) { ------------------------------------------------------------------------------*/ void ssp_cleanup_client(Client *client) { + if (client == NULL) + return; + client->request_list->free(client->request_list, ssp_cleanup_req); ssp_free(client->buff); ssp_free(client); @@ -635,6 +642,9 @@ void ssp_client_join(Client *client) { } static void exit_client(Node *node, void *element, void *args) { + if (element == NULL) + return; + Client *client = (Client *) element; client->close = true; } @@ -643,6 +653,7 @@ void ssp_cleanup_ftp(FTP *app) { app->request_list->free(app->request_list, ssp_cleanup_req); app->active_clients->iterate(app->active_clients, exit_client, NULL); app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); - app->active_clients->freeOnlyList(app->active_clients); + app->active_clients->freeOnlyList(app->active_clients); ssp_free(app->buff); + } diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 01efd28..1a0c546 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -276,8 +276,8 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, void *params) { - csp_packet_t * packet; - csp_conn_t * conn; + csp_packet_t * packet = NULL; + csp_conn_t * conn = NULL; char *buff = ssp_alloc(packet_len, sizeof(char)); @@ -311,11 +311,12 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_buffer_free(packet); } - csp_close(conn); } /* Close connection */ - csp_close(conn); + if (conn != NULL) + csp_close(conn); + onExit(params); ssp_free(buff); diff --git a/Program/src/requests.c b/Program/src/requests.c index ccba50d..5105b57 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -310,8 +310,7 @@ Client *start_client(FTP *app, uint8_t dest_id) { client = ssp_client(dest_id, app); if (client == NULL) return NULL; - - app->active_clients->insert(app->active_clients, client, dest_id); + } else { ssp_printf("adding request to existing client thread\n"); } From 6e4f288a8f8ca0f5106be18998ed56067d066ad4 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 28 Mar 2021 16:56:24 -0600 Subject: [PATCH 332/400] fix bug where request was not started --- Program/src/csp_server_provider.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 1a0c546..91c39ff 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -246,10 +246,6 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, if (get_exit() || checkExit(other)) break; - //if the request has timedout, go back to waiting for accept - if (!onTimeOut(other)) - break; - while ((packet = csp_read(conn, 1000)) != NULL) { @@ -261,7 +257,12 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, csp_buffer_free(packet); } + //if the request has timedout, go back to waiting for accept + if (!onTimeOut(other)) + break; + } + } onExit(other); ssp_free(buff); @@ -298,7 +299,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, if (conn == NULL) { continue; } - + onSend(-1, conn, sizeof(conn), params); while ((packet = csp_read(conn, 10000)) != NULL) { @@ -311,6 +312,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_buffer_free(packet); } + csp_close(conn); } /* Close connection */ From f1dbebfccbd7ca63bb2c6cfa0d0f80f056423b9f Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 28 Mar 2021 17:29:45 -0600 Subject: [PATCH 333/400] add get_request, reset timeout after data_burst --- Program/include/app_control.h | 1 + Program/include/protocol_handler.h | 2 +- Program/include/requests.h | 15 ++++++++++++--- Program/src/app_control.c | 30 ++---------------------------- Program/src/protocol_handler.c | 4 ++++ Program/src/requests.c | 19 +++++++++++++++++++ 6 files changed, 39 insertions(+), 32 deletions(-) diff --git a/Program/include/app_control.h b/Program/include/app_control.h index 24ea558..95e0705 100755 --- a/Program/include/app_control.h +++ b/Program/include/app_control.h @@ -25,6 +25,7 @@ void ssp_client_join(Client *client); void *ssp_generic_client_task(void *params); void *ssp_generic_server_task(void *params); +void reset_timeout(int *prevtime); void remove_request_check(Node *node, void *request, void *args); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index ae11829..3041cb3 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -12,7 +12,7 @@ Author: Evan Giese #define RESEND_FINISHED_TIMES 1 #define RESEND_META_TIMES 1 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 1000000 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 3000 #define TIMEOUT_BEFORE_SAVE_REQUEST 30 int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app); diff --git a/Program/include/requests.h b/Program/include/requests.h index 1e64881..1839d3e 100755 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -9,9 +9,7 @@ Author: Evan Giese #include "types.h" -void ssp_cleanup_req(void *request); -Request *init_request(char *buff, uint32_t buff_len); -void start_request(Request *req); + Request *put_request( uint32_t dest_id, @@ -21,6 +19,17 @@ Request *put_request( FTP *app ); +Request *get_request( + uint32_t dest_id, + char *source_file_name, + char *destination_file_name, + uint8_t transmission_mode, + FTP *app); + + +void ssp_cleanup_req(void *request); +Request *init_request(char *buff, uint32_t buff_len); +void start_request(Request *req); int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); int add_cont_partial_message_to_request(uint32_t beneficial_cfid, uint32_t originator_id, diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 756e235..9b0e75d 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -38,7 +38,7 @@ static int is_negative(int number) { } */ -static void reset_timeout(int *prevtime) { +void reset_timeout(int *prevtime) { *prevtime = ssp_time_count(); } @@ -211,23 +211,6 @@ static void client_check_callback(Node *node, void *client, void *args) { } -int refresh_response_struct(Response old_res, Response new_res){ - - if (old_res.size_of_addr != new_res.size_of_addr){ - ssp_printf("res struct sizes are not the same\n"); - return -1; - } - - if (memcmp(old_res.addr, new_res.addr, old_res.size_of_addr) == 0 ) { - return 1; - } - - ssp_printf("setting response struct\n"); - memcpy(old_res.addr, new_res.addr, old_res.size_of_addr); - return 1; - -} - static void timeout_check_callback_server(Node *node, void *request, void *args) { Request *req = (Request *) request; on_server_time_out(req->res, req); @@ -277,16 +260,7 @@ static int on_recv_server_callback(int sfd, char *packet, uint32_t packet_len, u Request *current_request = (*request_container); app->current_request = current_request; - - //refresh response - /* - int error = refresh_response_struct(current_request->res, res); - if (error < 0) { - ssp_printf("failed to connect to new client\n"); - return -1; - } - */ - + int count = parse_packet_server(packet, packet_index, app->current_request->res, current_request, incoming_pdu_header, app); reset_timeout(¤t_request->timeout_before_cancel); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 32b78ba..fe4afe0 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -12,6 +12,7 @@ Author: Evan Giese #include "requests.h" #include "types.h" #include "utils.h" +#include "app_control.h" static void transasction_log(char *msg, uint64_t transaction_sequence_number){ ssp_printf("transaction: %llu ", transaction_sequence_number); @@ -483,6 +484,8 @@ static void start_sequence(Request *req, Response res) { return; } acknowledged_start(req, res); + //set timeout to 0, databurst can take a while, timeout should start after data burst + reset_timeout(req->timeout_before_cancel); } @@ -731,6 +734,7 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, printf("just receiving messages, closing request\n"); req->local_entity.EOF_recv_indication = true; req->procedure = none; + req->paused = true; } } diff --git a/Program/src/requests.c b/Program/src/requests.c index 5105b57..d804168 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -418,6 +418,25 @@ Request *put_request( return req; } +Request *get_request( + uint32_t dest_id, + char *source_file_name, + char *destination_file_name, + uint8_t transmission_mode, + FTP *app){ + + Request *req = init_request_no_client(); + put_request_no_client(req, NULL, NULL, transmission_mode, app); + add_proxy_message_to_request(app->my_cfdp_id, 1, source_file_name, destination_file_name, req); + + Client *client = start_client(app, dest_id); + if (client == NULL) { + ssp_printf("client failed to start\n"); + } else + add_request_to_client(req, client); + + return req; +} /*NULL for source and destination filenames shall indicate that only Meta data will be delivered. Side effect: add request to client request list returns the request*/ From d055d77779afc6ad00a80f481830b699aae0963d Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 28 Mar 2021 17:30:24 -0600 Subject: [PATCH 334/400] close connection if timeout (aka no active requests) --- Program/src/csp_server_provider.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 91c39ff..1eb5617 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -257,12 +257,14 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, csp_buffer_free(packet); } - //if the request has timedout, go back to waiting for accept + //if the request has timeout, go back to waiting for accept if (!onTimeOut(other)) break; } + csp_close(conn); + } onExit(other); ssp_free(buff); From 0bb9a65a21f34824a000ba4c64ad863c93179ad3 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 28 Mar 2021 17:34:34 -0600 Subject: [PATCH 335/400] whoops, need pointer --- Program/src/protocol_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index fe4afe0..423d310 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -485,7 +485,7 @@ static void start_sequence(Request *req, Response res) { } acknowledged_start(req, res); //set timeout to 0, databurst can take a while, timeout should start after data burst - reset_timeout(req->timeout_before_cancel); + reset_timeout(&req->timeout_before_cancel); } From bc12c072980b6664c86bc05d8e4db2feb9066803 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sun, 28 Mar 2021 18:07:52 -0600 Subject: [PATCH 336/400] change get request return to default --- Program/include/protocol_handler.h | 2 +- Program/src/protocol_handler.c | 2 +- Program/src/requests.c | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 3041cb3..7f2dcc8 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -12,7 +12,7 @@ Author: Evan Giese #define RESEND_FINISHED_TIMES 1 #define RESEND_META_TIMES 1 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 3000 +#define TIMEOUT_BEFORE_CANCEL_REQUEST 10 #define TIMEOUT_BEFORE_SAVE_REQUEST 30 int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 423d310..2911153 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -325,7 +325,7 @@ void process_messages(Request *req, FTP *app) { put_request(p_put->destination_id, (char *)p_put->source_file_name.value, - (char *)p_put->destination_file_name.value, UN_ACKNOWLEDGED_MODE, app); + (char *)p_put->destination_file_name.value, req->remote_entity.default_transmission_mode, app); break; diff --git a/Program/src/requests.c b/Program/src/requests.c index d804168..75fd9ce 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -569,6 +569,7 @@ static void print_messages_callback(Node *node, void *element, void *args) { Message *m = (Message*) element; + ssp_printf("----------------Printing Message---------------\n"); ssp_printf("Message type: %d\n", m->header.message_type); ssp_printf("id: %s\n", m->header.message_id_cfdp); Message_put_proxy *proxy; @@ -578,7 +579,7 @@ static void print_messages_callback(Node *node, void *element, void *args) { ssp_printf("Message type: PROXY_PUT_REQUST\n"); ssp_printf("dest filename: %s\n", proxy->destination_file_name.value); ssp_printf("source filename: %s\n", proxy->source_file_name.value); - ssp_printf("id: %d\n", *(uint8_t*) proxy->destination_id); + ssp_printf("id: %llu\n", proxy->destination_id); } From 23ddb9392fb5c7fbd07fb4039ed9adc57e8a6646 Mon Sep 17 00:00:00 2001 From: evanGee Date: Mon, 29 Mar 2021 21:11:22 -0600 Subject: [PATCH 337/400] todo, get rid of stdin --- Program/src/app_control.c | 33 ------------ Program/src/main.c | 102 ++++++++++---------------------------- 2 files changed, 27 insertions(+), 108 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 9b0e75d..ea161ac 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -315,39 +315,6 @@ static void on_exit_server_callback (void *params) { ------------------------------------------------------------------------------*/ static int on_stdin_callback(void *other) { - - /* - FTP *app = (FTP *) other; - Request *req = app->newClient->req; - - char input[MAX_PATH]; - fgets(input, MAX_PATH, stdin); - input[strlen(input)-1]='\0'; - - if (req->procedure == none){ - if (strnlen(req->source_file_name, MAX_PATH) == 0){ - if (get_file_size(input) == -1){ - ssp_printf("file: %s, we had trouble opening this file, please enter a new file\n", input); - return 0; - } - ssp_memcpy(app->newClient->req->source_file_name, input, MAX_PATH); - ssp_printf("Enter a destination file name:\n"); - } - else if (strnlen(req->destination_file_name, MAX_PATH) == 0){ - ssp_memcpy(app->newClient->req->destination_file_name, input, MAX_PATH); - ssp_printf("sending file: %s As file named: %s To cfid enditity %d\n", app->newClient->req->source_file_name, app->newClient->req->destination_file_name, app->newClient->cfdp_id); - ssp_printf("cancel connection mode (yes):\n"); - } - else if (strncmp(input, "yes", 3) == 0){ - ssp_printf("sending file connectionless\n"); - put_request(app->newClient->req->source_file_name, app->newClient->req->destination_file_name, 0, 0, 0, 1, NULL, NULL, app->newClient, app); - } - else { - ssp_printf("sending file connected\n"); - put_request(app->newClient->req->source_file_name, app->newClient->req->destination_file_name, 0, 0, 0, 0, NULL, NULL, app->newClient, app); - } - } - */ return 0; } diff --git a/Program/src/main.c b/Program/src/main.c index cc83528..6cee8be 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -142,8 +142,6 @@ int main(int argc, char** argv) { } - - #ifdef CSP_NETWORK csp_debug_level_t debug_level = CSP_INFO; @@ -200,97 +198,51 @@ int main(int argc, char** argv) { csp_route_print_table(); #endif - - - FTP app; - //init_ftp(conf->my_cfdp_id, &app); + uint32_t id = conf->my_cfdp_id; void *handler = create_ftp_task(id, &app); if (handler == NULL) { return 1; } - - - //sleep(5); - uint32_t client_id = conf->client_cfdp_id; - // - if (client_id != -1) { - sleep(5); - //csp_custom_ftp_ping(conf->client_cfdp_id); - put_request(client_id, "udp.jpeg", "test-received.jpg", conf->unackowledged_mode, &app); - - //put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); - //sleep(5); - //put_request(client_id, "test.txt", "test-received.txt", UN_ACKNOWLEDGED_MODE, &app); - /* - Request *req2 = init_request_no_client(); - put_request_no_client(req2, NULL, NULL, UN_ACKNOWLEDGED_MODE, &app); - add_proxy_message_to_request(app.my_cfdp_id, 1, "mib/peer_0.json","GET_REQUEST", req2); - - Client *client = start_client(&app,client_id); - if (client == NULL) { - ssp_printf("client failed to start\n"); - } else - add_request_to_client(req2, client); - */ - - } + int buff_len = 25000; + char input[buff_len]; + memset(input, 0, buff_len); + uint32_t client_id = conf->client_cfdp_id; + + for (;;) { + + fgets(input, buff_len, stdin); + input[strlen(input)-1]='\0'; + + printf("%s\n", input); -/* - if (conf->client_cfdp_id == 1) { - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled5.jpg", ACKNOWLEDGED_MODE, app); - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled6.jpg", ACKNOWLEDGED_MODE, app); - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled7.jpg", UN_ACKNOWLEDGED_MODE, app); - schedule_put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/scheduled8.jpg", UN_ACKNOWLEDGED_MODE, app); - start_scheduled_requests(conf->client_cfdp_id, app); - } - else if (conf->client_cfdp_id == 2) { - Request *req = init_request_no_client(); - put_request_no_client(req, "pictures/pic.jpeg", "pictures/scheduled.jpg", ACKNOWLEDGED_MODE, app); - - Client *client = start_client(app, conf->client_cfdp_id); - if (client == NULL) { - ssp_printf("client failed to start\n"); - } else - add_request_to_client(req, client); - } else if (conf->client_cfdp_id == 3) { - Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/udp.jpg", ACKNOWLEDGED_MODE, app); - start_request(req); - //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, ACKNOWLEDGED_MODE, app); - //add_cont_partial_message_to_request(4, 1, conf->client_cfdp_id, 1, 0, 1, req); - //start_request(req); + if (get_exit()) + break; + if (strncmp(input, "exit", 5) == 0) { + set_exit(); + break; + } } - -*/ - //Request *req = put_request(conf->my_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", ACKNOWLEDGED_MODE, app); - //start_request(req); /* - if (conf->my_cfdp_id == 1) { - Request *re - if (conf->client_cfdp_id == 3) { - }q = put_request(conf->client_cfdp_id, "pictures/videoplayback.mp4", "pictures/vid_tcp.jpg", ACKNOWLEDGED_MODE, app); - start_request(req); - } - if (conf->client_cfdp_id == 4) { - //Request *req = put_request(conf->client_cfdp_id, NULL, NULL, UN_ACKNOWLEDGED_MODE, app); - //add_cont_partial_message_to_request(conf->my_cfdp_id, 3, 1, 4, 1, 1, req); - //add_proxy_message_to_request(7, 1, "pictures/pic.jpeg","pictures/proxy_yo!.jpeg", req); - - Request *req = put_request(conf->client_cfdp_id, "pictures/pic.jpeg", "pictures/noProxy2.jpg", UN_ACKNOWLEDGED_MODE, app); - //add_proxy_message_to_request(7, 1, "pictures/pic.jpeg","pictures/proxy_yo!.jpeg", req); - start_request(req); + if (client_id != -1) { + + //sleep(5); + //put_request(client_id, "udp.jpeg", "test-received.jpg", conf->unackowledged_mode, &app); + //put_request(client_id, "udp.jpeg", "udp.jpeg", conf->unackowledged_mode, &app); + + //put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); + //get_request(client_id, "mib/peer_0.json", "GET_REQUEST.json", ACKNOWLEDGED_MODE, &app); + } */ free(conf); ssp_thread_join(handler); - - //ssp_thread_join(app2->server_handle); return 0; } From 73a91f8632138c8e6cce85a9a4c87b0dd77c4709 Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 30 Mar 2021 20:42:18 -0600 Subject: [PATCH 338/400] Update main with some daemonization --- Program/src/main.c | 131 ++++++++++++++++++++++++++++++++--------- Program/src/packet.c | 2 +- Program/src/requests.c | 2 +- Program/src/utils.c | 7 +++ 4 files changed, 112 insertions(+), 30 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index 6cee8be..ee66ca0 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -128,19 +128,7 @@ static Config *configuration(int argc, char **argv) return conf; } -int main(int argc, char** argv) { - - - //exit handler for the main thread; - prepareSignalHandler(); - - //get-opt configuration - Config *conf = configuration(argc, argv); - if (conf->my_cfdp_id == 0){ - printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); - return 1; - } - +static int init_csp_stuff(Config conf){ #ifdef CSP_NETWORK @@ -151,7 +139,7 @@ int main(int argc, char** argv) { } Remote_entity remote_entity; - int error = get_remote_entity_from_json(&remote_entity, conf->my_cfdp_id); + int error = get_remote_entity_from_json(&remote_entity, conf.my_cfdp_id); if (error < 0) { ssp_error("couldn't get client remote_entity from mib\n"); return 1; @@ -173,9 +161,9 @@ int main(int argc, char** argv) { // Add interface(s) csp_iface_t * default_iface = NULL; - if (conf->uart_device != NULL) { - csp_usart_conf_t uart_conf = {.device = conf->uart_device, - .baudrate = conf->baudrate, // supported on all platforms + if (conf.uart_device != NULL) { + csp_usart_conf_t uart_conf = {.device = conf.uart_device, + .baudrate = conf.baudrate, // supported on all platforms .databits = 8, .stopbits = 2, .paritysetting = 0, @@ -191,12 +179,57 @@ int main(int argc, char** argv) { //printf("Connection table\r\n"); //csp_conn_print_table(); - printf("Interfaces\r\n"); - csp_route_print_interfaces(); + //printf("Interfaces\r\n"); + //csp_route_print_interfaces(); - printf("Route table\r\n"); - csp_route_print_table(); + //printf("Route table\r\n"); + //csp_route_print_table(); #endif + return 0; +} +//sets file_name and returns the length of the file_name +static int get_file_name(char *buff, int len, char *file_name) { + int i = 0; + for (i = 0; i < len; i++) { + if (buff[i] == ' ' || buff[i] == '\0') { + file_name[i] = '\0'; + break; + } + file_name[i] = buff[i]; + } + + return i; +} + + +static int confirm(){ + char buff[100]; + memset(buff, 0, 100); + fgets(buff, 100, stdin); + if ((buff[0] == 'y' || buff[0] == 'Y') && buff[1] == '\0') { + return 1; + } + else if ((buff[0] == 'n' || buff[0] == 'N') && buff[1] == '\0') { + return 0; + + } else { + return -1; + } +} +int main(int argc, char** argv) { + + + //exit handler for the main thread; + prepareSignalHandler(); + + //get-opt configuration + Config *conf = configuration(argc, argv); + if (conf->my_cfdp_id == 0){ + printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); + return 1; + } + + init_csp_stuff(*conf); FTP app; @@ -211,23 +244,66 @@ int main(int argc, char** argv) { memset(input, 0, buff_len); uint32_t client_id = conf->client_cfdp_id; - + + char src_file[MAX_PATH]; + char dest_file[MAX_PATH]; for (;;) { + + printf("send a file? type 'PUT ' or 'GET '\n"); + memset(src_file, 0 , MAX_PATH); + memset(dest_file, 0 , MAX_PATH); fgets(input, buff_len, stdin); input[strlen(input)-1]='\0'; - printf("%s\n", input); - if (get_exit()) + if (get_exit()) { break; - - if (strncmp(input, "exit", 5) == 0) { + } + else if (strncmp(input, "exit", 5) == 0) { set_exit(); break; } + + if (strncmp(input, "PUT ", 4) == 0) { + + int len = get_file_name(&input[4], buff_len, src_file); + len = get_file_name(&input[len + 5], buff_len, dest_file); + + while(1) { + printf("put source_file:%s destination_file:%s?(y/n)\n", src_file, dest_file); + int confirming = confirm(); + if (confirming) { + put_request(client_id, src_file, dest_file, conf->unackowledged_mode, &app); + break; + } else if (confirming == 0) { + break; + } else { + printf("please type either 'Y' or 'N'"); + } + } + + break; + + } else if (strncmp(input, "GET ", 4) == 0) { + + int len = get_file_name(&input[4], buff_len, dest_file); + len = get_file_name(&input[len + 5], buff_len, src_file); + while(1) { + printf("get destination_file:%s source_file:%s?(y/n)\n", src_file, dest_file); + int confirming = confirm(); + if (confirming) { + get_request(client_id, src_file, dest_file, conf->unackowledged_mode, &app); + break; + } else if (confirming == 0) { + break; + } else { + printf("please type either 'Y' or 'N'"); + } + } + break; + } } - /* if (client_id != -1) { @@ -237,7 +313,6 @@ int main(int argc, char** argv) { //put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); //get_request(client_id, "mib/peer_0.json", "GET_REQUEST.json", ACKNOWLEDGED_MODE, &app); - } */ diff --git a/Program/src/packet.c b/Program/src/packet.c index 2b660af..3e86f0a 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -478,7 +478,7 @@ void fill_nak_array_callback(Node *node, void *element, void *args){ Offset *offset = (Offset *)element; Offset offset_to_copy; - ssp_printf("sending start:end %d:%d\n", offset->start, offset->end); + //ssp_printf("sending nak:end %d:%d\n", offset->start, offset->end); offset_to_copy.start = ssp_htonl(offset->start); offset_to_copy.end = ssp_htonl(offset->end); diff --git a/Program/src/requests.c b/Program/src/requests.c index 75fd9ce..a178460 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -618,7 +618,7 @@ void print_request_state(Request *req) { ssp_printf("request header PDU_data_field_len: %d\n", req->pdu_header.PDU_data_field_len); ssp_printf("request header pdu type: %d\n", req->pdu_header.PDU_type); ssp_printf("request header transaction_seq_num_len: %d\n", req->pdu_header.transaction_seq_num_len); - ssp_printf("request header transaction_sequence_number: %d\n", req->pdu_header.transaction_sequence_number); + ssp_printf("request header transaction_sequence_number: %llu\n", req->pdu_header.transaction_sequence_number); ssp_printf("request header transmission_mode: %d\n", req->pdu_header.transmission_mode); ssp_printf("request header version: %d\n", req->pdu_header.version); ssp_printf("---------------------------------------------\n"); diff --git a/Program/src/utils.c b/Program/src/utils.c index 0eda7ed..6506a00 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -42,4 +42,11 @@ void ssp_print_bits(char *stuff, int size){ ssp_printf(" "); } ssp_printf("\n"); +} + + +char *safe_strncpy(char *to, char*from, int len){ + void *ret = strncpy(to, from, len); + to[len] = '\0'; + return ret; } \ No newline at end of file From d581a7198776718ab514d7f51b21e0e19db6152c Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 6 Apr 2021 19:51:02 -0600 Subject: [PATCH 339/400] update request documentation --- Program/include/requests.h | 38 +++++++++++++++++-- Program/src/file_delivery_app.c | 4 +- Program/src/main.c | 67 +++++++++++++++++++-------------- Program/src/port.c | 5 ++- Program/src/requests.c | 2 +- README.md | 42 +++++++++++++-------- 6 files changed, 105 insertions(+), 53 deletions(-) diff --git a/Program/include/requests.h b/Program/include/requests.h index 1839d3e..a959253 100755 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -6,10 +6,18 @@ Author: Evan Giese ------------------------------------------------------------------------------*/ #ifndef REQUESTS_H #define REQUESTS_H - #include "types.h" +//--------------------------------------------User functions-------------------------------- +/* +params: + id of destination, + source file name, + name of the file as it will arrive at destination, + ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + app from create_ftp_task +*/ Request *put_request( uint32_t dest_id, @@ -19,6 +27,14 @@ Request *put_request( FTP *app ); +/* +params: + id of destination, + source file name, + name of the file as it will arrive at destination, + ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + app from create_ftp_task +*/ Request *get_request( uint32_t dest_id, char *source_file_name, @@ -26,16 +42,30 @@ Request *get_request( uint8_t transmission_mode, FTP *app); - -void ssp_cleanup_req(void *request); -Request *init_request(char *buff, uint32_t buff_len); +//to start sending packets void start_request(Request *req); + +/* +params: + id of destination, + source file name, + name of the file as it will arrive at destination, + ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + app from create_ftp_task +*/ int add_proxy_message_to_request(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name, Request *req); + +//doesn't really work yet (have to fix byte order for storate) int add_cont_partial_message_to_request(uint32_t beneficial_cfid, uint32_t originator_id, uint32_t transaction_id, Request *req); + +//----------------------------------------------------------------------------------------- + +void ssp_cleanup_req(void *request); +Request *init_request(char *buff, uint32_t buff_len); Message_put_proxy *create_message_put_proxy(uint32_t beneficial_cfid, uint8_t length_of_id, char *source_name, char *dest_name); Message_cont_part_request *create_message_cont_partial_request(uint32_t beneficial_cfid, uint32_t originator_id, diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 17ea78f..abdc9c2 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -89,7 +89,7 @@ static void make_default_data(){ \"UT_port\" : 20,\n\ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ - \"MTU\" : 250,\n\ + \"MTU\" : 1450,\n\ \"one_way_light_time\" : 123,\n\ \"total_round_trip_allowance\" : 123,\n\ \"async_NAK_interval\" : 123,\n\ @@ -111,7 +111,7 @@ static void make_default_data(){ \"UT_port\" : 1,\n\ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ - \"MTU\" : 250,\n\ + \"MTU\" : 1450,\n\ \"one_way_light_time\" : 123,\n\ \"total_round_trip_allowance\" : 123,\n\ \"async_NAK_interval\" : 123,\n\ diff --git a/Program/src/main.c b/Program/src/main.c index ee66ca0..c0e5726 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -149,6 +149,7 @@ static int init_csp_stuff(Config conf){ csp_conf_get_defaults(&csp_conf); csp_conf.buffers = 4096; csp_conf.address = remote_entity.UT_address; + csp_conf.buffer_data_size = 1500; error = csp_init(&csp_conf); if (error != CSP_ERR_NONE) { @@ -216,37 +217,17 @@ static int confirm(){ return -1; } } -int main(int argc, char** argv) { - - //exit handler for the main thread; - prepareSignalHandler(); - - //get-opt configuration - Config *conf = configuration(argc, argv); - if (conf->my_cfdp_id == 0){ - printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); - return 1; - } - - init_csp_stuff(*conf); - - FTP app; - - uint32_t id = conf->my_cfdp_id; - void *handler = create_ftp_task(id, &app); - if (handler == NULL) { - return 1; - } +void input_daemon(uint32_t client_id, FTP *app){ int buff_len = 25000; char input[buff_len]; memset(input, 0, buff_len); - uint32_t client_id = conf->client_cfdp_id; char src_file[MAX_PATH]; char dest_file[MAX_PATH]; + for (;;) { printf("send a file? type 'PUT ' or 'GET '\n"); @@ -274,7 +255,7 @@ int main(int argc, char** argv) { printf("put source_file:%s destination_file:%s?(y/n)\n", src_file, dest_file); int confirming = confirm(); if (confirming) { - put_request(client_id, src_file, dest_file, conf->unackowledged_mode, &app); + put_request(client_id, src_file, dest_file, ACKNOWLEDGED_MODE, app); break; } else if (confirming == 0) { break; @@ -293,7 +274,7 @@ int main(int argc, char** argv) { printf("get destination_file:%s source_file:%s?(y/n)\n", src_file, dest_file); int confirming = confirm(); if (confirming) { - get_request(client_id, src_file, dest_file, conf->unackowledged_mode, &app); + get_request(client_id, src_file, dest_file, ACKNOWLEDGED_MODE, app); break; } else if (confirming == 0) { break; @@ -304,17 +285,45 @@ int main(int argc, char** argv) { break; } } - /* +} +int main(int argc, char** argv) { + + + //exit handler for the main thread; + prepareSignalHandler(); + + //get-opt configuration + Config *conf = configuration(argc, argv); + if (conf->my_cfdp_id == 0){ + printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); + return 1; + } + + init_csp_stuff(*conf); + + FTP app; + + uint32_t id = conf->my_cfdp_id; + void *handler = create_ftp_task(id, &app); + if (handler == NULL) { + return 1; + } + + uint32_t client_id = conf->client_cfdp_id; + + //input_daemon(client_id, &app); + if (client_id != -1) { - //sleep(5); - //put_request(client_id, "udp.jpeg", "test-received.jpg", conf->unackowledged_mode, &app); - //put_request(client_id, "udp.jpeg", "udp.jpeg", conf->unackowledged_mode, &app); + sleep(5); + Request *req = put_request(client_id, "pictures/udp.jpg", "test-received.jpg", conf->unackowledged_mode, &app); + start_request(req); + //put_request(client_id, "udp.jpeg", "udp.jpeg", conf->unackowledged_mode, &app); //put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); //get_request(client_id, "mib/peer_0.json", "GET_REQUEST.json", ACKNOWLEDGED_MODE, &app); } - */ + free(conf); ssp_thread_join(handler); diff --git a/Program/src/port.c b/Program/src/port.c index 8d9af1f..9786dac 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -170,7 +170,7 @@ void ssp_sendto(Response res) { #ifdef TEST return; #endif - // sleep(1); + //sleep(1); if (res.type_of_network == generic) { @@ -302,11 +302,12 @@ void ssp_printf(char *stuff, ...) { fflush(stdout); } +static int shit_time = 1; //returns seconds elapsed, need FREE RTOS realtime clock lib to properly port int ssp_time_count() { #ifdef FREE_RTOS_PORT - return 1;//INSERT TIME FUNCTIONS get delta time since last call + return shit_time++;//INSERT TIME FUNCTIONS get delta time since last call #else struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); diff --git a/Program/src/requests.c b/Program/src/requests.c index a178460..0bd7dd1 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -327,7 +327,7 @@ void add_request_to_client(Request *req, Client *client) { req->buff = client->buff; req->buff_len = client->packet_len; client->request_list->insert(client->request_list, req, -1); - start_request(req); + } int put_request_no_client( diff --git a/README.md b/README.md index cfb3b0e..2de5f5c 100755 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ run make to compile! # Getting started: -init the app with: +init the app or task with: - FTP *app = init_ftp(my_cfdp_id); - if (app == NULL) { + void *handler = create_ftp_task(id, &app); + if (handler == NULL) { return 1; } @@ -72,7 +72,7 @@ if you want to join this thread, and it is a posix thread, you can run: ssp_thread_join(app->server_handle); if you want to exit this task for any reason set app->close = 1; -this will run the exiting subroutines and close the task if it is a FreeRTOS task. +this will run the exiting subroutines and close the task. if you wish to send a file to a peer: @@ -85,12 +85,26 @@ app example: - Request *req = put_request(, "pictures/src.jpg", "pictures/desination.jpg", ACKNOWLEDGED_MODE, app); + Request *req = put_request(, , , , &app); start_request(req); - -if you wish to get a file from a peer, we need to add a 'message' onto a put request, -we can specify that there is no associated put request if we set the filenames to NULL: + +if you wish to get a file from a peer, you can call get_request: + +params: +id of destination, +source file name, +name of the file as it will arrive at destination, +ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), +app + +example: + + Request *req = get_request(, , , , &app); + start_request(req); + +if you wish to send a file from a peer via a proxy node, we need to add a 'message' onto a put request, +if we jsut want to send messages, we can set the filenames to NULL: params: id of destination, @@ -101,13 +115,12 @@ app example: - Request *req = put_request(, NULL, NULL, ACKNOWLEDGED_MODE, app); + Request *req = put_request(, NULL, NULL, , &app); - add_proxy_message_to_request(, , "source_file_name" "destination_file_name", req); + add_proxy_message_to_request(, , , req); start_request(req); -hint, if you want to 'get' a file, set the to your id. # MIB (management information base) @@ -165,15 +178,14 @@ Below are the meanings of the fields for the MIB currently, the only acceptable values are 0 and 1. - 0: UDP - 1: TCP - - 2: csp + - 2: csp (connectionless) + - 3: csp (connection based) - default_transmission_mode: not implemented - MTU - This number represents the 'maximum transmissible unit' -- this will also - take the form of a buffer in the program. This value is the maximum size - packet that the application will receive. + This number represents the 'maximum transmissible unit' This value is the size of the packet the peer expects. Make sure your underlaying network layer is big enough! - one_way_light_time : not implemented - total_round_trip_allowance : not implemented From 5be57578ecea37b5305cacecd810eea99a6d2384 Mon Sep 17 00:00:00 2001 From: evanGee Date: Tue, 6 Apr 2021 19:57:43 -0600 Subject: [PATCH 340/400] remove stdin callback --- Program/include/csp_server_provider.h | 2 -- Program/include/posix_server_provider.h | 2 -- Program/src/app_control.c | 8 ++------ Program/src/csp_server_provider.c | 2 -- Program/src/posix_server_provider.c | 12 ------------ 5 files changed, 2 insertions(+), 24 deletions(-) diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index c7f784a..220ee25 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -18,7 +18,6 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other); @@ -26,7 +25,6 @@ void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, void csp_connection_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other); diff --git a/Program/include/posix_server_provider.h b/Program/include/posix_server_provider.h index 641ecae..8d315bb 100755 --- a/Program/include/posix_server_provider.h +++ b/Program/include/posix_server_provider.h @@ -44,7 +44,6 @@ int prepareSignalHandler(void); void connectionless_server(char *host_name, char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other); @@ -52,7 +51,6 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, void connection_server(char *host_name, char* port, int initial_buff_size, int connection_limit, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other); diff --git a/Program/src/app_control.c b/Program/src/app_control.c index ea161ac..f2a39cd 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -363,7 +363,6 @@ void *ssp_connectionless_server_task(void *params) { app->packet_len, on_recv_server_callback, on_time_out_callback_server, - on_stdin_callback, check_exit_server_callback, on_exit_server_callback, app); @@ -426,8 +425,7 @@ void *ssp_connection_server_task(void *params) { app->packet_len, 10, on_recv_server_callback, - on_time_out_callback_server, - on_stdin_callback, + on_time_out_callback_server, check_exit_server_callback, on_exit_server_callback, app); @@ -477,8 +475,7 @@ void *ssp_csp_connectionless_server_task(void *params) { app->remote_entity.UT_port, app->remote_entity.mtu, on_recv_server_callback, - on_time_out_callback_server, - on_stdin_callback, + on_time_out_callback_server, check_exit_server_callback, on_exit_server_callback, app); @@ -520,7 +517,6 @@ void *ssp_csp_connection_server_task(void *params) { app->remote_entity.mtu, on_recv_server_callback, on_time_out_callback_server, - on_stdin_callback, check_exit_server_callback, on_exit_server_callback, params); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 1eb5617..d205a7d 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -95,7 +95,6 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other) @@ -192,7 +191,6 @@ int csp_custom_ftp_ping(uint32_t dest_id){ void csp_connection_server(uint8_t my_port, uint32_t packet_len, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other) diff --git a/Program/src/posix_server_provider.c b/Program/src/posix_server_provider.c index 2893709..04e8198 100755 --- a/Program/src/posix_server_provider.c +++ b/Program/src/posix_server_provider.c @@ -188,7 +188,6 @@ static int resizeBuff(char **buffer, uint32_t *newBufferSize, uint32_t *prev_buf void connection_server(char *host_name, char* port, int initial_buff_size, int connection_limit, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other) @@ -256,11 +255,6 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c if (ssp_fd_is_set(i, read_socket_set)) { - if (i == STDIN_FILENO) { - onStdIn(other); - break; - } - if (i == sfd) { int new_socket = accept(i, (struct sockaddr*) addr, &size_of_addr); if (new_socket < 0) @@ -313,7 +307,6 @@ void connection_server(char *host_name, char* port, int initial_buff_size, int c void connectionless_server(char *host_name, char* port, int initial_buff_size, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), - int (*onStdIn)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other) @@ -370,11 +363,6 @@ void connectionless_server(char *host_name, char* port, int initial_buff_size, ssp_printf("timeout failed\n"); continue; } - - if (ssp_fd_is_set(STDIN_FILENO, read_socket_set)) { - onStdIn(other); - continue; - } if (ssp_fd_is_set(sfd, read_socket_set)) { int count = ssp_recvfrom(sfd, buff, *buff_size, 0, addr, &size_of_addr); From b87da32bf46c2606b726401862def0241cf82a46 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 8 Apr 2021 19:52:11 -0600 Subject: [PATCH 341/400] csp puse async_nak timout for timeout interval --- Program/src/app_control.c | 3 +++ Program/src/csp_server_provider.c | 8 ++++---- Program/src/file_delivery_app.c | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index f2a39cd..3e3be46 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -471,9 +471,11 @@ void *ssp_csp_connectionless_server_task(void *params) { ssp_printf("starting csp connectionless server\n"); FTP *app = (FTP *) params; + csp_connectionless_server( app->remote_entity.UT_port, app->remote_entity.mtu, + app->remote_entity.async_NAK_interval, on_recv_server_callback, on_time_out_callback_server, check_exit_server_callback, @@ -515,6 +517,7 @@ void *ssp_csp_connection_server_task(void *params) { csp_connection_server(app->remote_entity.UT_port, app->remote_entity.mtu, + app->remote_entity.async_NAK_interval, on_recv_server_callback, on_time_out_callback_server, check_exit_server_callback, diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index d205a7d..116fc01 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -92,7 +92,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p -void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, +void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, uint32_t time_out, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*checkExit)(void *other), @@ -117,7 +117,7 @@ void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, break; } - csp_packet_t *packet = csp_recvfrom(soc, 10); + csp_packet_t *packet = csp_recvfrom(soc, time_out); //timeout if (packet == NULL) { onTimeOut(other); @@ -188,7 +188,7 @@ int csp_custom_ftp_ping(uint32_t dest_id){ return -1; } -void csp_connection_server(uint8_t my_port, uint32_t packet_len, +void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_out, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*checkExit)(void *other), @@ -245,7 +245,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, break; - while ((packet = csp_read(conn, 1000)) != NULL) { + while ((packet = csp_read(conn, time_out)) != NULL) { memset(buff, 0, packet_len); memcpy(buff, (char *)packet->data, packet->length); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index abdc9c2..acc8e2b 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -92,7 +92,7 @@ static void make_default_data(){ \"MTU\" : 1450,\n\ \"one_way_light_time\" : 123,\n\ \"total_round_trip_allowance\" : 123,\n\ - \"async_NAK_interval\" : 123,\n\ + \"async_NAK_interval\" : 1000,\n\ \"async_keep_alive_interval\" : 123,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ @@ -114,7 +114,7 @@ static void make_default_data(){ \"MTU\" : 1450,\n\ \"one_way_light_time\" : 123,\n\ \"total_round_trip_allowance\" : 123,\n\ - \"async_NAK_interval\" : 123,\n\ + \"async_NAK_interval\" 1000,\n\ \"async_keep_alive_interval\" : 123,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ From 737f81065166a81e16d12485c45fc3e83a805c20 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 8 Apr 2021 20:04:23 -0600 Subject: [PATCH 342/400] change new keyword bug --- Program/src/file_delivery_app.c | 2 +- Program/src/filesystem_funcs.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index acc8e2b..02d4359 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -114,7 +114,7 @@ static void make_default_data(){ \"MTU\" : 1450,\n\ \"one_way_light_time\" : 123,\n\ \"total_round_trip_allowance\" : 123,\n\ - \"async_NAK_interval\" 1000,\n\ + \"async_NAK_interval\" : 30000,\n\ \"async_keep_alive_interval\" : 123,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 265bafc..f3c8668 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -252,16 +252,16 @@ int receive_offset(File *file, uint32_t offset_start, uint32_t offset_end) { Node *cur = node; - Node *new = createNode(new_offset, new_offset->start); - if (new == NULL) { + Node *ne = createNode(new_offset, new_offset->start); + if (ne == NULL) { ssp_free(new_offset); return 0; } - new->next = cur->next; - new->prev = cur; - cur->next = new; - new->next->prev = new; + ne->next = cur->next; + ne->prev = cur; + cur->next = ne; + ne->next->prev = ne; nak_list->count++; From c606ee0c7fb200e44bb02064eb56e2cdab7e97f8 Mon Sep 17 00:00:00 2001 From: evanGee Date: Thu, 8 Apr 2021 20:08:40 -0600 Subject: [PATCH 343/400] oops forgot to add header file --- Program/include/csp_server_provider.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index 220ee25..126b98d 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -15,14 +15,14 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p void (*onExit)(void *params), void *params); -void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, +void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, uint32_t time_out, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*checkExit)(void *other), void (*onExit)(void *other), void *other); -void csp_connection_server(uint8_t my_port, uint32_t packet_len, +void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_out, int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *other), int (*onTimeOut)(void *other), int (*checkExit)(void *other), From b038521dd52e2fef025141d1a77e5fe0e6abbb44 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 10 Apr 2021 11:44:49 -0600 Subject: [PATCH 344/400] update readme --- Program/src/file_delivery_app.c | 2 +- README.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 02d4359..15a00d8 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -92,7 +92,7 @@ static void make_default_data(){ \"MTU\" : 1450,\n\ \"one_way_light_time\" : 123,\n\ \"total_round_trip_allowance\" : 123,\n\ - \"async_NAK_interval\" : 1000,\n\ + \"async_NAK_interval\" : 30000,\n\ \"async_keep_alive_interval\" : 123,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ diff --git a/README.md b/README.md index 2de5f5c..9191f41 100755 --- a/README.md +++ b/README.md @@ -181,15 +181,15 @@ Below are the meanings of the fields for the MIB - 2: csp (connectionless) - 3: csp (connection based) -- default_transmission_mode: - not implemented - - MTU This number represents the 'maximum transmissible unit' This value is the size of the packet the peer expects. Make sure your underlaying network layer is big enough! +- async_NAK_interval + This number represents the time in miliseconds we wait to recv a packet. If it expires, we send NAKs + +- default_transmission_mode: not implemented - one_way_light_time : not implemented -- total_round_trip_allowance : not implemented -- async_NAK_interval : not implemented +- total_round_trip_allowance : not implemented - async_keep_alive_interval : not implemented - async_report_interval : not implemented - immediate_nak_mode_enabled : not implemented From d242e6628b5be9ff5a8a3e8b2600507b9e24c2cb Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 10 Apr 2021 12:15:11 -0600 Subject: [PATCH 345/400] add documents --- Documents/Design.pdf | Bin 0 -> 1278176 bytes Documents/ImplementorsGuide.pdf | Bin 0 -> 1893185 bytes Documents/MostRecentRatifications.pdf | Bin 0 -> 187758 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100755 Documents/Design.pdf create mode 100755 Documents/ImplementorsGuide.pdf create mode 100755 Documents/MostRecentRatifications.pdf diff --git a/Documents/Design.pdf b/Documents/Design.pdf new file mode 100755 index 0000000000000000000000000000000000000000..8bc85139cffb6925754a1300f211ac9e8b32c8ac GIT binary patch literal 1278176 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

J_6NreHf7^r5^ zu9GOnN(v3C3+j#Xm{@kyjmBzdm+|M&9$Y|B*7)8BexK=Cl&z*E23jKkg@!N|1-W|F zI&c-D6G9V%I)Q15EH-rMG>g1G4j9dp@*pu4Y9y>()0US+?o`T^-1IPF6+s+2&M zD4+jSU@wbLQlpH)%)y=K+(Ew49NHlbOEwb`@1UUEa}xIXDN_QMIfjN%T(jX_JvIf-859aN&65(`5SICpt4dsa{aN@jfn+HWa%R4j^N+n|3 z`uav@4QfsK2`vpyXpIuJ`peO+yX#CguvqTf`uq&-V0L zYb6TWcL@nJqZi$gidd_=6V4atU7y1+VcWqs1#2rr)$?|8lte_)d3-PtwUViAY%Wvy z)C~E8^Q6RwMRO^4h!XQ^EGYtwL(y<0>wa~&46nHGMDwWxMlQH#;qXlaV8>QKOIC9gb@d7`Z;L++d%Q%UJ2SnY(Rh&w7_ucAO zFAGP|xNRBszH!wibCouKoVEh}3wa9*8znM6FE=0%-S2~P?OQLdKI=i;-_;uF0LMdD zi2#hOz>#P}0=PsJ`Uhg!um&20A-nBOTZ#|`Nn&Ym1Ghe4K`ZP}=WP-0vz+S zyb!VKT3rXC>3L7muK2q^TfCOwyf;r9u$&980a!gq2oDHW_~-C}v%A2j>Cl`IvH8Tn zLMALWQYIX4&taZlrNs884aR9Fui~NHQ0egUSh5?%Wo`b|;&nhX3Q_f>*ux7Qb0`>XA*dZD z3+3UCqDkwDw=cxDAcXn_mmepYG(bLAc=PJZ9o{k)Yyj=c`iCzpn0(mqy;UYVs(X_U zz8}OIt~nn}Ah8Kjxvt_C>c-cUVjU#Mu>m0OAdQY56rnMLP`*X|hc`ijJA}Bid*umPC>IoLFr)a)| zGWgZ!p!ZB+Qon%~^;=HR8tiFg!UByzUTb{cih0T7<+ZK^x;Hg)ON2i3rY^(z#pK2y z4#YjgsJ|k_aWWBDDQ~@|&E;ZK!9)0X;A%21B~-+nk5Oy9MfA+mIhm2bX5)H*eWZvj zECrPy-*F`dJrzxRx5Y83?X*H|=!}YHrIfijsS~*tMN^iPDYMsc=winj*>jo%P2^;gmTq z6zAQG5#9|@@O3wB^@3gUS=pjt=94g=tt)u9zI_xnPYxrGK3zR`IXftw2Y<5%cSjsX zicd|;IQE;l@j!o03tOC*Goc^SQx)@K0i3@X2&`bvVNN)F z>&_AwCvwPP{=v0sJ)Aj_M62V3X|VJiR^C`yLW?o*V%AV(+-La!lIIWZt;TV2xY#?+9Z-ee~X~9kY)qzZnII16Qx>iH}LS>|= z-vZZk`zNUlFQb(I%C-w0A{hYm0t;bzhiM7qsy18UxY&xhKm0p)9;b*V}Jh>mG`8&5<}snh2&B#Cw;V3pP+0ucUsL3I%UilS*xyRBU=8;Uk#fRB zvm2(53U((65Qpt*L!I#3@v#JL~sFW3o>O&XROONEN}vj#_F<1d15Re)!XIGr4Yi z(3@S10EJN-8qTh(acZ^kY)JHL`-w~AwbRruVqfgN1MsjfSMy3S&X$V7Bjb=MM*04u zCHzMUnrWteoziy{p6^WYc1zIN2w3M$+u zO4C=_vJt(2f$4@KfDrpa(FD13h_T1Rk;S$ySL7-vdOU!~SZBl{nTI0U zOB!swcRZ}?kPoVxI$gQ0pWZHkw76!~AbHqD>D7BO6b$FSmocIYvP|}DUHzXI@{;+| zP|jP=1$EuW{BFStt6kxwh8gnv^AfNY8}20ScSOX-AO~aQ;zt(b+Z8U9-hi zuZ^FH{lDsO$F37UKMZUo$kLE+7D%2b zElZJO!=~&|4f%XMZ6n%o9@K%GR+e2Ca)h9uduwha#XYjsOZH%N`LXXg*4cg2cWpGi zuG}wX_+D=9ziUb7Pa(=jg{TBKmR4!RyeiJ+)9NQsCE5dz8gaH~U5Go34QAl5ImqI5 zDxk}W(T;Tj=66U>1Hf#7cwR^Nx?#puJsQ!Qg2oq)kpv@Q{ft2YeC*w657q;>V0naqu@FxGZI8DsKq7(b)t;PL(Rn1-Kj+fC zKCOvC_4Rz3V<&?{DFz*)mkaSQ#DO;a1n?P` zWt5-uCwWBHzK_YxKve8t1G8EPTzmP=DLyieoVG!-1wsC;AXd1RRMbu~hcqr%a$2K` z`z61a{bzw?1Th5X`GL!l#@KyOVkea5=CdR%)aHBaR)%HM4<{H?;NGNBl5?M5!(M_F zAiqqVRzibR4xI!A*F*b1Zd?TOSMQlKHxoDuwxfxoLweE>@2e00fq?%*>YVJ9spoqavOBP@&egpd_6xohLte8bOJ3zuIrL_F4=CEa&2q~zWyd%k3;f&Lda|HU!}&}XLY>6LKE<7Q<1S-;`h)e z0hgdSfCL6aqGzB=7y0=b(_NZnb@d#EIABE0%cp%=@aq*vyZIDK8`3YnTpZ0QF3sBL zyI5vR5jOhaul8c=xnz=d)VI!+4cyW4k<#mbWtb9m+6(JtiwQy}Z=h*F?cs;4oYhoC ziU8m_UjgvE(7#6~<=Mf7PiPB!D#1P8(0HBPy$)dng&&pAE((*YZFd{*Veh0GYJp8_ z6^G>o8>5yi^2*+w^(lxQ|FJAyWQY%P8?c&8{Av*$p84|_etJD`{GIb{V#gxRIUcBr zs%W=y20f%m02CU9*$1!K29nxt^5(DEYh1V8>7q0VTNWp!onUZQfCoqCRq_Sz-cQvo zgi7_X;Bjkv()A;Jtip?~P~}pb5dsvXqgJbSq?mU5=8Rn~4;&26th9f3gi0Fe9euIfweAq(^d_KD<4Wqg+0fZx`a>5d-cjMa?9;}#iAt?UG#|OL z!q7vmAmcmBESc;_zR)>69fLOwm_&5@vRyISF0VMlFZ^t{gcFZYD1Gk+ zTgP-kdxD}3atQul&#fS1ACzneot~l+0Nh||-Q`WRSNieXez8Ho!#pMq&20_I$(Ull z)+tKB7}w&>zK$an^# z>Pm|rx>ZT7SHTSdh()C6INvQuC~tCl2#bCGM(OBy98ND0bLHtB&Wx@;k{l2ANnnm} z=>-YX}M$^XwpRGcEK`Q^s>&z>D3@$}!}PnCL!f!fUtlaw&(#K4$WkP~kW zcF(ztYC8P6p!&y-Nd6aYQF2yP6^MGl(c&JzU88tFyNma41TxPw{VG@TH`)#RdMa0? z(g;yk@SBL{DVhF%(^q(oVu~j|wTq>uN-E)qE4?yPFJ#qJxlHtki^k=kw%pAY>Tlh) zGFMnAUQx!vu4m}%x)bn-dT^%~KDb4*%+Wo#!Ui;7_W-ecj|5(To**?)W*I&tHCz8$ zny&#~-ofSrl#LgARGxo^9Ou~v1~3WM$i|*+7^5c;pQH%=o6ngIazBcR z?N-1+$dxsp^)GaQr({hZFXvr8+ago?YA0r@nNkTrvhkd+T+dZczuL^KA8JvxSB^fX zVA+6-Ze-l~qwg5sD53q4-nYF?N&y;aRl<|EJS5QHhNLuw?IWKzZbDF3ZtTgkH_cb$ z_vu9zWr6h;tE?gXcA^Msd<+?Ju0~md_)KHvU4$XP8m|*B9h=F%GdaPRHqO5{&8u{i zUfTNfnxmt%^*fpz-b=e{ra5o43d)KDcrTyZ4sWtl-dFDz+&?h!DVC02>_{v8r4f-Y zKD^Jl!!^;$K_hs7MNUYY~*GPuK7g>Z}2r*d(FLQ3oI|QtLpecr|0|c-m z`mjUWHKGBb4xp;io*TZi5Iwv9x81p{?akY*c8D*8AQSL&K8DR)=W@vv>cWT7}nI|eJQKxt^F~hp# zWq^bpYjy4CW)#D{%GWdY;P&D1G^WX}tE)E1h0`&bGXDpvGJq9caVRqR)v7*jo-Se} zTC;n;+PpVu`yM$sd9G%%Ts{i2PF<9rz!D)GvApvsP!@Y>L#9TcmT5turN=YR89Bm zlOSd&ggr`kN2mBD%=PoU)}{4f4U=Khj27LB-ew3Q4o=jIOVBATD1rD_RC+J(@Z<1m zrp6KNlALs0XSQ4lIf%Tek!-?X)*n)g&x0vu5RV4$MH*WfqRrJVd(pn$)bY|6vqc~q zEBvkeVoDYMSS2LDdlX|S>z4)CzXoP_sW0u&-l)#pJbNSOU!-YSDXUX$RR4&tORezW zJBnWFYeR5t#1_o0Bb#dX5Ls9SCZC&BtZEkvI(#*PVSTi8r9kUblVGu2@ESdS&Uhcz>}k^`VC;y`-d-OPn?8j%8>qNC z=(lq{FXd(Nj5W9AKJ(6i$P@i&m~Tj?AdZrzHW8pz=ru3#PYFmZMdNk9u=X8V!co;= z$c*keIMPACxIQAfDdmsz9vQKZ+%*BDfu@}>4$ESrgY-~TQML+$af$N@#X%^@BXXcL zA?;Zh@YvWuv^(Uhpe1zF4=96Vb0u4wMFs%0@*FE3H1MVfc>UhOi${YCM93rcJ^1jQ~mRgs`2hQ4O1e{=XqKj@|XE3Hq{OXSDL zU{R4|J1p;!PvICdC49%(EEu>0pkymSy+II#gS`Re<{D=j%nGJdtv<|b6rHHKj{r8- z3kCW-!sDpjl51zy`9~gP8y26T#8o0&84<6JKJiC#W~*{hMtHzEZedk=Flda=W?N9( z3(36}pD>@U3v;kR0s92%OEZ(|+DWZeO3G?h+(%=1q#xI=BtLyt^#Z(Lr0d8gA5fO1 zYm2TSU4G;KUDUlY38w4 zmSc*QOz4#VloP_iy}#G%Wak0rc%unepm%XR*5Af7#o$kgJKYX;zhcc#)0bwDU`Z|U z*PtM9DX?Jg7~SU{;CodP7cKMk=x0{gTC!=Z6E|IwVn3SzPPClb-`fN!NYb3J z!+1-cWEdL{y`6ReAJ&k^CybAjx~70L^axIWD{*nctae*!_jBcTqx6bL;8>$inyhD- z8~J^b)A?(Z7$i0sNR9Q|(N9x`J#f$05^mvS2Jz1M%e%!x4UE?h(XxpT} z6PY&8JwL^3-z*7o$6U`;tMU)SPQLC|>lo(XrI~FQCeJH>L@q~hx(LG1FEI3Z1-;qE zmo%;D*f5=Si1bzpv+_3dPJod62{}9(f^Iz2juTyiJRXm}?J2IteAHj3e{GTLvI6q- zIS(e~htqz8s>1#KM3$v{@*z)Hz#7yQ|LmLpuZ;;+CXn;>$KWU6Ij=w~mCTZ*j}Ho)>L%z&Rhee~{M4;QBf$#IUe7JuFT9Y^yCzHFZLOe z8;e1(KI;j__R)OUE)b*Mh}~&L-d7;n-!TX)?I$Tg+*HcfLL3Vjbe~x60kIkge)~*m z!ma#!(Js?`%FLyyju`WOyG9&mm zG>1Ovc#ezhrA0G}HN44|D@H07=h%Q1)7s_BsMOKj>+I2*eBPOccQYg?z3dpDw~qs2 zcSrjb3#rFhR#isGf)^w>j1#7(Uly+;N*c0?m`@l(kT*ai$dxew7b}^Xq#kgrIWhh) zn-ilt|2n&?FoYW5-3K9OL17m9x@`5iRTf||2gHp;f4EpQ3Duz!RwCXN6fEmV8x>PG z=W#6E$f`KZ6jJ+o9aJB;&a<}vcHGT)*#I8$sJ!WnMKFd}LGGeL*a#nJHFV=T00mqq z7Qo54FUyE%uTk>kIwkGNB?(El&$1->=}LQx9M8IxbHE}h{<2M+W!F;ic3MQEJ9mEH zYmm|j13#lmL24DVhpt3JtWbSQO^li|?EHW2@Z+7gG`3;pfmf_<1fpjgs)3LT!1!rG(3Rh0$>{mA){AYVcrg4Tn+Qu}+>d+OdlLh>0gZZ%xgNr9Fy0UH~7e4W_S+keeh;um& z8qZ9z)R;+u|2MNv*ECZNsTF2ymL8I2n@o%SS;|RGQC@*OdVGt`W?7!<>Lspb1m(}0 zR5u^fqJ*~d;%F1R+To^t?{(;ytliMzawQn1NBGMe_5hcTrVJ~u?D6rfJu1V39Z;{8 z1Huek>J#U4fgtkAC`s3Mh<$7|jNaz{UORm~aEu0wvmHroEd2_+@^g|3${g5b-ZUOb z(#c3@vom!$Km1R~Gu|+#{h47LTAtE+qMb7gXG*otl_^xmmBydN8If*K21;x= z6eJ~7zXrk5h^bD295@ZQd#CYSgtM-|fYw$Q>@{58+e2!DXe-#9STEBKxE~K0*yM?& zO__swO0tNPb740Qzl@QP#`0>Yt0$Zb+VBCnCN|2+ZSq(l&v?aXQhk^~NYy-fb7r~Z zxYD7|!Y78$B7N@e+nr%K)^o4$dSynRn*7`7Eeazq3KoAF5Cwx}&Naps<1SzuDopy? z>P~O>pwD|GrIDgxFMMm&btZ1%14vkUn54mcZ9>PAgk9${$nNKWt#!1}mEuj=Ga+t} z5wP9~*VcGU4oN;mx|y9Z1$8AG&1@-}REqq;a*4VkSRsjg+L)zweYNu3xsfG=-diTa8*Y@%lgXG><2n1psZ{1S6myUV#blB=`_ z$v~3nibqYReylh2ANk}wQN?C=5>{uuJ%&VbL3&;0pi}MOn7t+;Rp8<$E>>_0s{Oy; zPlsAcms{Ai)S*j}r@YUiLGrO)Wo^?@cULpNTDA$WE!xD}YL*bEhTpI1*RHQmO!DWk zu$%TtGq<7rEJQ?(hGT<&H)6#~>MahBeh*m8s2sYQq&{tZF2&DY)TTv0jX(y;1*rrx zX6%nngVp=Y$rvqoCS`aitEop_Zlu0>&9W8Bop2%qF?IZ<=oc2A0BH}_a&J&*d2}*D zrB8Kpl1(U_EM~Fh!PLYOISn?;K+?+toyC0WOtpkv9D*hYqB^q9bNlqrLsXUs*4bx; z*w*B;VU^2pwQZ*;IAW4x zQNhiQXu{zTaPAuoS5%%3HZBK-fbo{e2z3J&zd((gA;GXQaqm&$gUxOSU*FvIwuxTa zdXigt6*3JkyI*#@oF^lW7SUatCsIzg*(JID3!)1Q$fYay1XMwd!}-A!%?%GG@mWbE zL}~E901ZfYL};1cF61$hu2`lgJ?rY$4>gkWys=4{DD9>wjQy#PsU-A|@Ok(80A0Xl z+1W5$QhWGZN*W=JF^bvx5x&SxZ-VPn03a)q*a_c5$Kvdd6PGsJ>^ni3>e-7-BfDdv zdc=#dh|7koC-~g)f)1Y3^g?NU;1c+)XN(n~+MJOuFJ^t5&D3Wjm}Mb6;M-F~L@byr zkfcApVU~6u?NHrGA6mZ>#9ewaWQ;WZ3tuEy-E4T3ZjKEKWo~41baG{3Z4G5^WN%_> z4KXt?GcX`9Aa7!74Lm$AMrmwxWpXb@Y+-a|L}g=dWMwZ*Wo~D5Xdp5-F)%bQOl59o zbZ9XkH8wLgG(J9abaG{3Z4C;YTE2?pE?Z4&p3M!%9#nVAFLc|xrKQi`2sFJ0xT5ZR zx(4@kIXo9ZX2D}4zCI#`aL8HF35gvfiPf2D#~(X*b$Ll2@X0*g78AMvGeFG08<^u} z>&^S%KV${)0S2qq#Wf}^GP#UWv5FKmg_D^(3!0&Msey{}9kajW#L(K0$jAFJ`yVMa z;G;Xf1(F6pAGC(dPJ&KR5cJ(kJey_?mQ_>h@@JTcb%8J+^Iu-(mCrf5zLJ>6_md>x zX2ha%w(j<|26d}dax_R`-am+VC`+?~5c0-9_R*bQd#=BCGw-HLeJ|xq`2uR2Iqsy# zj27IQR?kc&(T3KSHV%N@*NuqAB7{1Yuq^1Hf zRrW74z88Oyw3tk&cPICj;|HmqHU&Rh>}Upv*Lhgb00H&^I`-Y?;DHSh9Vxrm zvkw7Xx^uwDuUUSbFA6z0vr_z-y8~3=!8lswo@oCeTe%8->gxp@)kH56QEjZ_7x$ zlm<$2JGLNG?ZB#vxevXeM+Um21Vh7On&GxsMRO{+uOt~6k>h#J%?i?tZqfeG+<^H{y zg|BcT@ID=Yz?qQiX#f!949yg!v8!* z<#sRuioJ3_XWMn~3^<6L=Vl&&VXZvGEEVEr34G7tCS~f|EcyyV1aXI;1P<0-J6~~oKXLqbFW)wmORu;# zMFACtYp1iK~NXD6#W zhzgk1P?2x@qR<+}e2LMFX4->V`fTW&3`GlV{vD3bvuExylz?r&39)F53^i0B25W}Qe&L&v4i7K}`36LmSCDGpnMW?%Oee^%g9;2VE2S?GJ4 z`}&NOTc|*@MKPZd5tIM6ujy5_~oM7v1QAsb;J@cmaR1YMuyT`9GdC-Mw* zB4a`9wR};`7tX1oYKfRV-Wx!RvPn?#UHAHh)eC2N(Mgu;vZi#tljELq;1R8Q#8}cN z$KihteJz3VEUI+CIsvHm@;(Z!3p!OF2eGqkC6v7+QDoesEIxo`bjN&_9jwn;bFQ5^ zT=g(#q&8@#se&C6bP*ea=_Duo$wC}SBdr>ZlIG@TwDI2ngfqr0bDTJZ+^JF929sSu zqz+yfa&EB~pX7wuXIPwS7~OaS9+Pofg3G3FcM#Z_emo6lN;r?OJNvnoGS`vmC$XGB zl?7+$9*g6c@=~a4p-C?PSehTw2`BEt7fdTS;! zOwsK|y)Uz-M?rV+sC{cKqOKC8ixt53XJSE_#bWLcRtRyn`j4OM@E{M zIm2JFC$WXyzQgdaCcu3aTwohL?A0Qn>Bw_F9Vrp}py_dC!DhuQHTM+>jp!q`xTk5L z4$Dby(i_qWZzFe*#p7fw9N~^!IN&914awx)O6M<(CDct^9TBFQo;WFP(&sZ2!@2OMPy#bpJ{4c$)fJ_FctL&#@io#! z*vn#g69&I|2Zgp+FgcG(@7u)JK&ao`xbTrBq+kxbKz*V{OpL@?6-ea+@f$NsCa*uJ zUPLSh;^0(l@cwKMj1p?I)LTmLBbIv24#s@;%2W(&-<^4tdipTLz1&hp zjEB?dd4Sab5H6~dh$GtUUV9;+(|7<0oDrFTl~>18(PsF(_8ylbP(H2Rv0yd4)t9*~ z(+dh^4^{k=L;!DmCZssrpYM^4h;IAM)#5s!aK6^mB4qH3UWS2&1vsCyWSOQuHdxxA z)8c;DR6S53wQy%wi#(t-y3RG_VBOLN3U|fHCnn~_7cBg`txg#axB9qTGUw%H?_!Eo zXzPQ9N#--FUoMa2*6r?~gpcCyShH(gLd%M{yNC-N;1Sj#*%esN0~+TFL~KQ2Rth>! z!v~oi)+x}k@qTrQuhf$1h)kKPMJ)^3qa%!=sK+?ZKaD|Lz2jakXRDXC%osF!uV=$* zA+0%E7tUN4?@~1Fsu2e^+kzoD^&XNX*mbZgTG8W)7rr~8@tT~h_Pio2nQzvYXmsvD zgP=_V*#Npn^^@Qj9R{0i(g*vn4lbJk*+AxULh2EcnS(nrkk1sXMf((&UC30Ffx53OfR$J$$CVDW4&XwZFK~{AXWmX6+9Y4t-u*9BU8)eb41MPz$1_V;!X# zBQmSEd#Sx>@)1J0&=#1SpbR|6@&-NpCa4jz!`RiouUnjC<$@XXvv+raf?!IR1PK5H z2-&|0@d#4g`+ro1@%Wr?`R6dM9RQpoD+|kH&d3qn4#aYoHFtJJN_HtTc}D?Whe5Kq zv#|17h+#AdZuAl05vCzR6g!+B`-*5jrh56M!jHRe)+s7kW$G)7GJHvVn!CA9i?ZFr zMH-U_;n`koB}nbZ<+%+&OfJQ~3=i1Z8zkR-iedM-vb22t=UJ5fmbXspcu*Q7VOmb3 z(IZ^F?%3ZKUkQk3!u0Um{mx3A!bL`N5MiCLSI=c3V`2=)wYt_bEvh{QIu|(qgJc4O zj^^ZCnj6n9xJ3ohaPx*6=%|uc2bTaG(jsvP?5DDSqfo3->)5Sg$$2C(_0es(5vrE3 zis6v=>Kl0;N<@VWJ=M?_S@dLPcaplfN&ok3ruQOn{i9r_lU;g(@n6(o-Qf)w)o5?65QEi5v2X26}`-X3l zW+lD^{UqF8v3c=y?}|WOn|4}zF=j3stNiAL<66jU+lSQA2mDK!^SX#xUsrqdUz9}dR_TkGK}L*xxe@sXsR3=!Ei+S$rSG!e9ibcec{{It9s zp(zqP6CfYpCd0a6o(+nS8$}Bwazkf`gOA%avW|lY=loa=sb^IdxUv1zB>YGg!A{7a zb42s(y?TQk1F(u1(FZ{*&#+afZRk7v%9(=}l+G|LPUiCzFJNT1!(ffxF<5ftMx4u6 zlO=%@R+qaX_0|~@fB4EaxhBhS-wvhxTX2-O=oQK;f60kxTL&f;*0FtbTBy>V~7*Yrq6Ia8H!b8EdM^+0_3+uKd++JX>z*n+}P93A}~FgxdwQuEVBd)l!r{v za=2nPvqSmc$S+SLbfniVtRoA?CxH9Ns@2FQMK5O|ufC!CE17|WXXUEo^mQ;|EWWWg zW!7(UGVF^1Kpxu8N?Knu;%uBx$&?<;v5WBw7Qg>Y=r$&_Z+#iYTU-z|5@2aIWR_9f zVQdL%^43J$6tr3abS}lXN)Jw43Alb&K~0+bTpJQ0_FKw;5kF`nwD*8gn~{sPXFg`x zVt+_TTaq1fYlC1_+-?xKG$tSI;tmJ&$D=k zSz*Kt(J!lT?T~_UefUmaso+dlt0u_HZKg)fI; zLl*+8qqq2?O7xe<@%!PWUqV(NzyKIA=vgdZK2ATz#MFget&IQ>XgdXM zjOfv2GLm(UbL(%i?sY~jB)s;lM3caev_XC`${`k>}i>jc}j1s{9N!*BBmDz zdn*K;olfIwlKllUvps#e2k2y|=~?YdJ6GH7tV5dh!1r*Dgz>II#@^2U5=*a`iA4-Z zmMVHU5%IZx3FR6dW8oA*SnZ&oIGufXyeXq%lWh(9Tw-?sa#2^AVup0q2b z*GC_X&)Ocf=BkpD9Ogcm^~5;>6mv5@_9*`dixGIUa<9_U}!A{1nbN2A=)1-#&n?C*%wO6znwK%6)Us7my(AONdI_rm+i{oHokE zLi&)swh_N-+hLxF%dSL~&JO#`SiA|?N6R(p?t{8_th|R6`%R|`R!vn3h2*of-YH5u zy1{WbUih2XOe|vtst8LozeAT6Vl9LIr_uFDkHwSq$$JarJLoc6_oB6mtS`Qb0o}_} zc|(cqP1m!w!2yIv_i4Z}dw#L5CUY<6kPQvyg%5*4X-b@J2M?eT3IiRO;K9`I8A5*O zmB1sstf^DnUb0usTEeS(*w))Zf)J(Jiux|lVhqIB{+(*Uk5K@J;tFhaco{tSh~i2P z&*oN*;|EbUF{oF1Z?U(Lb9db#EP9uPy#p&sGxN+{2psEtK-GtKuOYXqJ~+!l-5C~w zzW-Q-GoKdaUu*|F6eA-OKlJY1fyU=eDgUm-Cuo292I6}Mg?R{sva^XEaCa}evE*(x zL)D;+E&w>gY=y)6mzOYuF>!g)lof>~tX|v`S+-@63at_bfvAnR!KxQrKgXtbpRX`a zhdp`P>7ndX$-#o`q+zX`-P;JUygV&uIsaUb^XS;tt_?Ly%p86740=t3`id=3^^Pzl zil45!NMV$oa>n6MFya`5s8>|iV5TE`fXk0kL?8(@l=t3{%~(>ge8uZ(>NctGPdqFd zh$YNk*z?CVc{oG0$y`q8%RFc?ZJzLQP1ZezZ4nVaqQB4BjBh35S2J`iIl@DLuH+zW z@(wTo(X`TH5nmO$P*eYHa`lJ$GKD04{KP{^$)4DP*Qu&{yXmg%o3A?BqOc zZ-zs(1Jm4X3bcbtteZaHL3s(V=Sr254csPOIe(^65HDsv9RAaiO;OdECHb4#{7kT0 z6I@SkrUHe^_?SoomCWU_1|O?J@=WWdKHDt|{IWu#uwuQAPb;PQ zC#nGmw9Jct%bOT`MZ%(PCYU*Svu-7t%-=C5rS{vqJ`TvOg&U+7Yf@k%W#>Y0TW2|C z51HVNH&NkT6K3^ZE4lF)AqcFXq)n$8bLwK>s)n7#pz$pzcHXV0Xpr{vj_5&S+u|C4rm+}m93-}R70`arnF=WPv!Wq6g& zLiaUlQ!F}K4M^PiDT??$t(jo#_RM5^wzhoK#CjJ-b+{%W?E&hKQDGWZ!Sd;alL3>C zR^ZT@m6K^Lo2-b_HL?>}WLgh#I?%+zju^ybUYC}rVNCujvG`l9OA%0b4{7Z6fw;c% zRQ9w4e8ezaklxd}b&>x+EwX8Ek!-)VF!uQ_LMM%5>&&OBoa{_x4;C4+gb<9Kq`T^T zQY;*9nMe|U;RV{KwnGNq!7(6H)!Cw?5H>4)irl8~T}R4(b9EMdy}(u^St%EZ#B$AA zZ}3090s?30a{xHu6ncZu3Qa)SsDHvZ0co;T#Zfm@V93nAMCu|YzH@3A$aYRQm6_`$ zHEP}cW45YtYG+er)CxOEa=m-|8?2ENKShqa1$^d@*6Ui0@{dQoaLdNWYeuUI-d46C zF6&My1n^S0!j&h3{Uzw7bo!>_%r2U|_cq}*?z-3AU(L1>2+qXNz+FM_x z$FshQnf4Za*aJ4u`W~~%4=g`7b?<_YY>5yqdyiVBZky8xCj@d-;Z2(Ax`)3Rj5l>p z4!wEp^C4yBq7t%8YWa)y!O{^^vMmEG-TI%Hx_GMGzUe8k$n-8;tsS$?oNr<@3n;cT zvFMASW<#&Qi0TyB*!1HkiYzJh*03F^F?^mB0VXH*_iWCvEe>pOhr}eWIAqu5Y9@yC z##DbeK%ztI0j0_2lFkd`e#hVOEE#{;MI-ET)y%Njm+1lp@9&j|8QQ zjoKAKn!nVRcy!8i?=}ws&%Wio`!<{2YRw&g*?Ji+f4Wwliv^Q6Nmqgc$;BSZ$a7m` zGR|^m(>Wp|;Oy-*N=7iTN`H;cqby>kOU=$kC-3l;B1_s8k$aI?PFP zDkfVo@_07S@(2H|g2zyP<@ujsu=x!AgJ0C$TmTidzVux~9S%COq&?LkSf)g>Pc=b& z8T1`38dd7BmiSL_6tGE1Q0L?o&kcAA^@mG^RP}d9VcG&`)mpLHd_utaf?Bwtct?2p zKCz`5C#|c?Wbt$uZUOppp*50$+ZAwm;cb$q57(>UI06#m#C!MIrtg?y;w1+r^9Ibc zU#jrdB~7yZ9w;1{A+jniGZ5vl;U3(YoxgXW0&D!Y*#)BI?UX-Nga|d1=Loe#R%0QlEH|wi9F1ma8{a!DS>|>C{oh)Mps}y z3g~tkk}r(Sv~W`q`{{OxB=p^}CO^7?VhxJ#8wCD zsrrdrg+5r#p6pdqqHpEbT@7%>=W476>URx0s3_1?LqId!cb2}}FOuJi4X4P|7GD7O zr%D6^hOGTm$N7>>b!kJL1M+*fWUrGr5w6K+iU_MbVtNk6oT=Wxhtn*i?^xV?so_^jHzx zm>^Mq_TI%-P|k2>MZfeWs>|n=R|V+8TMq*yBGLxh#IGt-+?0anVlnU}s?{qdTR8@` zSM9Z(&Wc)FL9s)m{%g-zW=BHm&r8dqS%ogYj5ZPB(>yn&ImlR{t1Q%3i}>yuhYeH4 zE;>30C3dXTQb=S$KjqBpk)FKQ0f!7b!f0rXE-|u6w%HT^E`OhyvpC#f5EoI}oIGsP z&bELtv?!1U+{vWm1rSW~u0Z_&;j^m6Vt_`SUi^BBtHTdx5JSG&y5)=R_O`$h@^u%d zyn+4=2Bj`-f8Av%)h_pO&Lff8`tDn&`^Cy~wcOYnU^?0j=cd)~p$$pZZ)4;x0c%o9 zgUQ+qe>arTR^X{9)~IM@GX?_AFEe9*@ElYBc^1*U+*BTvq!*V zOviKQB)2zk@%H;_V03$RrO}t1vbtI;*ZBgsx=t z;W(nxl~XDp%Fst(o1|})o`~gB8nTv9Tezi-L?0_9CeinMOV-2y_&VHxsWd7`f#l%^ z=U~@JUlX#&QpGet=7b8ZS}K`7c27&VY89{Z#g1_j0a4hXa-SNsLKl_gmTL$p67MBA zIQw8$V2_Lt>4rj;pfPLYC60%rQ3bOOyDuL0qK1M2#aT8C;$xUm-&e|7{u!NidG6n50*<8}Ss%qbdaRt;5 zlfqMBQAynbc6C|%NUjYyk2yLI95O76aUSD9C&h$(hjg7X=j$J=1&~Jqbm4COo?TDE}YgB$fA06d>yszYYfq9%l!%k z-AzIZMF~n}HKf-gw5x=rblbe*YpO$_8!eZs4rKd&2hK#1+k@n$R!`AcJz(lDQM(_T zU-(YpwH-c<-WDg$6ARCCLOGBb#%6zIgV-790zU0?4tWNQMbKQue`3IgoQ^IhzgQVR zbNd|={8R%W?b8GVAqGHaVWFc$>mDo5YBN9ScFJNxI3RLYEG=^Y`8h>FIGdDdPPXYV zds31>Ayhc9gTh}uy|1w3w=~iPA*WlQqxl0%DpxrzNuw3pZH|n&e_NtyPe|Fl*K1A+ zz(@Z{C7a6!acid*!z>L6q!?1r2T8dcoF&NU<|~0rC1lfn(|kx~k|W{MdOtsVX5fEh z3d@eGl5S-uSNnz~-Kg$=EKoUNEd6;-<6G^t`Y81BEo7G!ilh26@OeJ5?Vb#Z`<1|@ z`!JVMeOmcds`4g3O&TF;xyRfpQ<*G~2S$KTAeh3ZfLwb5M99OK7BgA~ng`WtBQT8K zK={0ebv;GNTxo?{Ob7e>vU}QUEN7jft2ABy(Yq@>GBT{wDo}k&@|!7##-?CN;>Si- z3)ygLdD6Ej=$xt7T{b=}91bitP6&Lc3VX1-Gad~KA~$LZjkP4Y1gqe)&G`j--~3tN zx6@0s5(V#nka{T`(T6Tp=v*Cpg#{RxU9)Xcn|^SifKV0HMC#SfzihKV%Ffdr8Rk(a z_H+8g0}8>>*!Zjj`1YF@X$yLf$>0HX$KPK@#w5Jh*d<|Q?UqRG2SvYe!BP3 z5ERR;$asliJDoe_%3>YkgGaqY!N1rS{2X2Fq3U+-s2ClP+@<9-8h}nb1cWG5{gx9$ z3z!j7A33L<1yEm%RM)SFM@Mg9`*1`8$;4Fg4|WLIJbp9^YtHxr8Ma-xsY45Y8{(52 zYK@xeHry8jyYuiCXJ%7g5d;hkYP&6Q!ZH9j2ob5rE7+aX@?~(3$`Pkzm?$^!ASR;K zTz(prYvW<5jS>;exJ6PqBs!!;i<|o~8~~k9e$uNuu|YA$r5);AoujVYm!0CLSZY`C z70qK^WB8(Ed%>JK(}b9OFf>sgAGwfaE0ilvI_8HG7_Q;RatGq0?lL2X@RWX0N=1I4 z*`HoU>Topbt1V0OZTzGL0nSTa!yzvrVOh*$gqGo8)-NMi52nRV$eUYg5vgO{!##19 zXS4dZfk#Y1nge$xU|*6h7_nk%)f^r#pZ@+PYyci32!1Ox^hF3HRwt3Tt&aIj5kXs0 zYkY5;k{s0qsM3&2A-F^FcAr$C3U&g52dvDD!>x{-nU$sLB?Y^BYv7~0gUd+Lci9oh z&MO2g|3dwn($Ha9rB4oOZAOSij^%^D?SkBAFp-6frS-rRO+%nEBsJ9t)h20XSNxDc zOVnUV7p7V=G*bQ$-0!QoKx3g*?aY1E{kNIG(paD^a49i_wGr)oo$|t5UUC!Vb(`wV z_HUF9<*EVGRK@;K-=j(`-Gj%!g9m7r!eK3bgpJPL$;$)j7U{;>!VB*;-vpYGihJgl z-cR|k1BMWFPG9A_BuXf#LXEdp?rO%agivoJ`-w8EwW8VH>k~F1m39O|L%udS3#(?j zl>x|F(Ld8C-cyhz7XBXn2S(w-89Zh~Chy$ofdK?~yiMJ8UsqDnveq!-L2T;qU156< zvKf-HoWw_CJ`UD?SL}{QHW27ic$Y>Y4}|;!`=!xey{Dn1BQ(v%G|~Wfws&j*Y&HBQ zQP*#_vp!h60(xi?;uIRRTm`D~+`nV#vPu4(%$|f-{a{XmSOIx&;3$+N-AZRDa|AN@ zR(+ckWt7z!i=necFZN^TOd3iX%c;}z@sUIvW=)N|?6hk$wM6!f%FDa1@*?~(YUS6h z*=0au5Qw!`l0-Qsq9r=xOF6D$So*t!d!r&=d?+%G>9yG9Jz0?y!*C1D>D)c6ziDI8 zzhhk!F6*WDB!ch)N;$lxV2j^M0H8aDbBT=ftI6E?ze3jqaMZH8nE$lk9CSQ`&8GK+Q zhNxCu7t9h2(;Ltc!_U}<4wjHt+@CYdXq#l?OAqFi2k=uVTZ)UimDf|;G>8F<_%73t zqV@Ux<{n@edSbs}VT(n@PPLi)J;CA}EsC>I=Ct0~Kjsm{L%{MITb@3Q9RUOIQKcwi z>1R5-e41Kt*M^iV6cmWBO=7S~q15~OE->av01_(S_PJvceG(s_7dLl!xV7AV4T|>_ z{t9JPs`gApBi+Dh?skp352DK<$k)nIqIKsd>ngygn@t2U65HwCWr@vZ&S_$w;QuT#Dmh`kwHhs)f&Mo3 zFl^`JcA4K>y^Sa*GV$C?P>7Y|%}0AftG^_U5zMIx;MztlZLd4S1Y`6wyD>>$@HT0a z`U6p~ARLP_0iL??FRXLZKYSq%8EY@QR4v(oW0X$Nb^5)KTRvo8^_5BqpCPT*P_$s(K&!zQ#C_po6`c#h z8xj;$F~rH!#Ix>(0sU#KW@CUx#FM3rl zs!OMeXSrGj99L6m6#7)Ao`gq6IjH&8+Gp~vI0>_-{|L~xHX!b2_J|&0>n@wrN+G@H zZw~wKF}j1n_)e$g;6~jwjntD&D=#6bIT^q;RTp>W0Aw#F18!J zqIgdl?%?$ap~aXFcl*QTz|%&;Oa6y>1~m~+fdes$zu=DhewlswX(Z$tCLH3I7Mn?6WQi z;pP#ufmLJCtcQ`Ip|Ia2bxB|Z!en)zlJO?yiRn0oEKmJjhax zIH=mQBFSZrP&b~)0;=M&K8zN9sm4N632Z&I1w?bauJ~QbD(O9SouVp|xwSI=^ay__ zDY^(@cYV9Ux#rZ-$AdHTO8f=1WPRJGcRz4j*P)YV%nD}hB6U77HYBqR=la+AX?ok= zm4@Q?yR%U;FZ6xXl=f3he});N^X##Jqpe7WlIQbCB7ByLd?b4|vp3CaAfq;WRLe0#>2>|wHW zb%9{wV9b`bv!MQPv$pGY43iFs@q}P_5P*a<^bG7)(0e%vBV=!u`Eyo}=Yc?MP*T{2 zZZ5ciJu)<;iQJ33^x|rm4Z=f??bj0=tU@?syH5|;cyC5i#LYb7<&rFCnypjJ=oe(T z)(0_(xp8(46rgjuk^jjWMMB(fSd-;}YA-0@k-*i-SCZ>7?K(l+BnR4bI$|VJdm|{c zo^oSEzb|XL zM(*o>ZVidTra+;VP4%nW-YqR~&<7%qyb&Lcsm~`lra=fQKgi+supI!Ihk&?oPs039 z6}8J^d;u(6!T@=YTk(`mNC#|gA7FgS2CqW)Jy@$(=CmQ!6FP?Ejch z8i?|}dqC@JO#ukn5z}dKDapx8SquaoR;zgGa5YfPX9=!BgSJrCmA{J`Udwz2O^8J3 zja&bOj8ix6=4N}u&IiVNp_wgpuqrG$%%73f;K161%Hhqf6OyqD;F1Ze+G~Ex4G*Ty zVBVd0e?HH z*cYf%v8yQNrtC8LDPGYjviS6nkb$1E+!X#*pz!V0 z3uN`7CFHI@R0D6Qy=@uE*kel;s|AP7-1ds>2`;ZU{g4$jwPq7b2>xzlE%{G(FIF!@ z`bs@UaM&Ads*LE}wXBL@w_LUHVP4xpW3p+m+Xp-=g(298R{;G0QQ~eZyv9>%T-u|K z#e8G6jz$6Il(b0*TEjj*87u5mR<6=C!$u~$m>Wr6xd$| z?Z9xrQxfTFQQD99Re@q2Q_$Ea^e2u54h9f`#~QMRuu)mcUWn(XtlkR^wQ73=JyX)gqUA#LlK+zaZgHLX#G@&Nfni@!C50AkBD7Wp;K28flway ze7mhGm=K^TCP>ZTAhh0l+zw=L<7&y_j-NDfCU3o!XxnBATnxOxu%n42*`LJwtB>W8 zlvyD9MoD9g#5Jy=GkhEEfkbgwcSNQMP0`F>z#KD_04Ap*c#ezy`cEwx=i5Tr!D9I% zXD3iKfzG+0+oc^b-~@QGalNRDD*SE3REZKA1UBLtvXv}hBQ6agXgA)Q$i>!4@6v{u z#SG4;WgF@PvIDRoL?OzF2LJa5E2fyb!~mRN?AQaLgeU$vjq&ox{5cuy{*$Jp^fUI& zU6){FmejSzZl64G^S!2AI9ApNnVsJp zyle3T6n8+~6z*I7%`%D~7L%HEHdoqGo5FRp@P?o4x^X_#J45{c@KbaEwdQyQP5KFX z=GM|yhG3yV=s=hQvkxM{z4jJ2$Dtju5>#(T0c@hL1Hik(i!G2jN;CdmjlLkK>ZEp+4nvq{1oYopz+(HYx z4#Os+F6)(9VD7^xi!vAIp61hK_;2Zc-Wx7pmdXb~mAD`^Hj>p49KavU!bWOO2e@*eU zyBcO9ce+u2;rMGN_A!dMB@dO}A^yKD2VI#0nRit85wIpi6T}2QOXkm$$?1f2H;#}3 z+cC0#)tC|4yu^o^pKYOiEdw{x-da1cE;N-U(FttX;bCsm1sOkPF1WvZQA5#_jYDIh zCeE5vrE3J3F%t-%(Qz&aQmYKA???6?F5)Q(F%>#6R)PD4o%BhH_z_zJlF?-@yYPT^ zD$KY&J4kwd?^?!d9-{xDCOlSk<0>JUV2%EM3Mq@}Yln$S3JQ9|va4h3UZkO}-WHtU zm4XYxB4Zf*hCN;#&EzfCO)^}68M}fwvXL|KTC)m}deh}7R@#K=Ttr`dMdszXBTCIB zy}I{(?LGCoV9_%rC~ppcW$4hQ+?A}s@Dzc~)!xDF5e3$og)#SdpVtOK`Hp^X6$7Mp zzbpRUsBuW(6nmyE8!C>ea}HZtc_ZU<{bX7q=$p`^(E^h!f&ZS*^PLH>G+T~m5CC_F zIwagAftm9YtyL?O<=h8Cly|5VS7|Z*oj7<-wPhZ`xk60eaLP~6nDz$tjysN6<(zIE zil)2sopO)U$+{cYY5uDp+vhodBjc{w)0uvTj+E>`Yccw*!JIHgf)(yK^A}jJ-{sXr zM{Nw>ciniWN3956naZP2D-jbrOHN1|_eCqpyeAC1l`dtYiRDhwcKK=Bfu0%RhebFg z&LjkfI>fVw0W0F@!a_J^L>cy&$mVLyNuMUu{WCK^bimh|$3qs~!3cn^qF7aG(@TBh zVOzN{*Festl>f)Ooe4J<4~1VKj#ZXKg0ms<_|;Tqb(l(E<={pH4ByOF;iThW5E#z#a@tfNDWpnqJTJ*Rb_e+;= zX}k_i4QWYsB42ahJR~K#T+Qzv*gISJ{Jfe-RB~fuDFEMC{3qsnp>Oh+OleKg9BDDK z1)d!>;+tRP9C34r!Kee;dYuk)r=U@Vs)3k#{B+?NtGCe69wgdt{H3*`F>cbV7-c_YH?)typkf=X?BE%P3{ zx*)@|Ai-|Sux2!2uyIPrJ&cZM+$z?YM`VDl8n(KX;mY2Gp?R05^J z0v!i38d~@GZNL0})$LIrM#}l0WTM5wmUFFQfiU`LIo;Lpn-RbWlGpGv-6{XZ%Fvso z<{YFy!2Bd;e!&C5WNbwe0oa&(<%x1+zuA)&+mh2&4o6@!3SIlpfok)3uZ=2o;@-W; z+ByAuEV)(XAJ>xtJUs#Ls?f`V+;jn|agm+^>S|Zv%D*t_(v)%yfC(dz#TDMDhPy^$ z1@HY0zCcHD0$M~*xm_hld;P7rGSZHJZIs1^e_uXY~`m)0-?tVwCO2tTvD(P|!&r_wRCgwiLDz2{)=!*4i61h|_6LjXUxij~N$BYhvxZisr+Np%7m=B6y2xPYM!+mh zE$OB7)p(_&AmUV@t@N|&_J3Sm+LCn17kfdU-x1ScuRqqeH(Q^1A>z}eOwghwX&)Uz z?HDp2WzZL-yfp8jK6_w#owP;2X@ixP5{{qUQD};@wYRwRi0w(DUS5VRzUkAd+Ey zObe*$gQKfY{)!r=DN>e7;O0vuZFkO5TB|UpCXb(Hf=dB)#46+j=eZtU_$V85W=nq>A#bjk|xc%_}s{5RBV5d zuG2W7kJPw=86`lUtWR<0Q&o#L9exd{XTk(^98Z91K(Bo!=Pu2_<7`Bj~e~ODp z+9-m?!`X&f&IDb63=&PA2WzJ_LCj(X+jNj97@Qb|Z8G&L`lg&80Kf^`zBG-*yNv>h z^>?+O#P2hGQdKaQ6(l;)_)FCf`$*riW<%Eg%?h#J%B95Q+_AcZVvr0fdy^}%4gU*9 zW=nAC89mPW6nXl9Rr{y`Be%!b2k=X+8YG8u{;MyqEVLBd)yI}Rr!F! z3)V)<&dFC#;}-WKxzBzm0`*<_a#|UWEZjVuZDXy&v0bqPz9i=zg!tHGjET2VRYg#2 z=Ml_h7{1LIg+xLjV;1~m1Nk7s!~SnyaQH4Qh2o7w#8ZUr%-}mj!-@c9lyOSwextGS zGE!ki=EZLFVo`e!jBA{$OHCwG*WQ%qz>zOkh8&^FpG&UK*-zN1=bG}m^!2=su+)U-(x;!+p&Mz18Eb7&V7?-f%l_?VbEbGWy1T*deeWwMd7%Tegko$<$p-T^c7cU50(|Qf?i^b# z6uc54pGy}lW1OWzjRS@&Ls0$eC)#lzRw`AG1u&nKp!RP*eEnA0yD#)y%2I|Q6=l|m z%^$B%!3e}Llw!1xSN5FQd8K&?(22-G!)$bN3nwuL)=btjSVcs^+IEPL&xG+}mx!#H z;+5$RuK(5}=RzIK#Eu;##fhDpstu3xs%< zBu+)0li${dr3d86T4j6@6h zhVe2oLf7U1r%YiBMjL@v6@HJX$(_I}Td~L!6RY_={z{*p_x{;`QBmz?^l6(i&^>eY zSZZa$BjOy4MQ1|@T%9MGfvY!3P#OyRIs(|AYJe7w1!k2VG1X=Z$jBykm^JZS)gH4+ zxcg)x1vn=;@c%jk;TJSwT2Dlr+JNUQq8-Y9ZJPe(m)03E%Uf%hYnjbo8R@n~Jk93b z6=Oy?li{|~m=6%R!q;G`r8m@BYORTvg_Uj`>diT^w?X#Tl|=lrNsi+NCRK)M=ziT0 zux2UrvIKt@a-Az)!7>8xKi>&YA4qQ}1nKlndduyec~uDa9}`D%^emBB`!Bg7?dFD-;5d6so1v zHHt}vu!OOU^+#< zuK$mLay`04@%`3pIZW`mzdlkrDagx{BJNL)szi4=HtJ!(>8QKoTfE2t!;%j8oB@`zG?Of;!T(5c@3Nf%SpFF;s%lmZ zfD~cU2VmMHaCQq_#}@m^ii`2CjV6pnQHq+wQK`@2O#cx4nT$_mP3*WF2)k-kBs`qi z|87XYU6ODNuhDq(+8N_@T*w_8fY>NwOj9KidQ6dm%gO09 zpaqL2Txa9gVaQgSz-t_s%)|?!Ag-Y@YX~+T2ZWRS2$>J2XCQct*Q11HbYaO3o)HU7^1>ay` z=M=GC+3w^VufRGMmUk+lynQ$HQgM;OEKeMJt2uVZs0)%_Fex!k0R8(Jmz9j*480FN z@uC4M%JU7~OXZ=tXjc2arU1PH+3C#vVqXdALP?f}S;jyU7(_a4kQ2p6YsNxhn3s>KX?mN}sKHqeA+Eb6G;wBh{{gi6qas|%D2<+> zfwopay->KRkdJQYe~g}!rmxW7i!uW%u-m8y@;V_JZo<@n_^f!@c8H^zxZmmwpwLTn z-NTY73Y2Zpv~AnAZQHhO+qQYqwr$(CZD-bPyohSNsGnG^z31ROj@ed_!qRZCHZxNJ zUq3)fm@M8+8cl&`BDAOzF(e0aET+&_w-P>2Y+2nXw2?nyA`>(4P*k>w1_aX9o0b!E_Q14eNsy}agyYS z(9A`A$egzNYwn_Le`))opb+0kmtFqvuM4H?lPa5Zy@&lI7@(xyG3bC~i3?0E@9MWgLr_DqPLVL%tbe9?`dT$3gA&rC!@+j9BH0 zmnJ3T$EYoD;VkIIc%L52y_m|5=#=^R9UU4~3JWzarn~5{@zXBzX`k|`Go_5d!iX=8IaKp5aV*QbYprSRf z$~7M&;vQRf&DIAhfnGS5KX3Juxy5*G{rFXy9^;0_UKmdA8^XCCb6M-ZYtaM}^rEcO z-kP}Q9H~`HXyl6{P|L8pg_Y{9YeFhsb+H_Brxqpp&KOV@#L#f%!)FWN!$Qr2jK>=M z3=Wj!$uiM3GQ|&-O$^c_s9{TjncT+PaTU;t=nlVZ*Ks%3-H}b%A<_3P%$G# zzIQe*Ie;SVYw&1u;cuv!bR>h#2v_2lJQ&9;B&yS{qkeK`$=Y{HwqVa3m@crsbBS*O zCZUCBdLgg-q(4!12__x3O7xKrib08MLi4oDEH-C??yN#dJWlg+@nUC#smXX4+dyO? zGU#$ECrCg7`iGu{w31?Z78IC1UP)QXC|LVb791gbd&;mn@T4R}=@^4|5 zgLR>QyJFcJ9Jz{mLGu#j0w`?3w~*e}bb5ZN75i~^Lx8aynw|LbG~2vDc^w`RV134L z*WX)LPQG039?yjMdrY{Y)*x-k0R_7 zxB7640bbnBHnr#X!{Y8!8vUl&4cw!{MSH~7KM(4U;@n=T%bPQ>NCXp4dlG`LU5vet3LBr3MOr7#)$`&M5I`KMVzpFGAx zoa?_7^5jaUla!C@sS`MR|e@q=)n2c?rMiM(d1fe+?^5*mz^p|D1Lf0Cy47>Gd$aN ze|mve9Z#o8cUD73k2zD4&Eyv-}7vjOlCHSK#a@Ugr7`rcNaq1%l7Y~B{Z znBYmVnkj1{SA=~BTU<;J2!frhRoQllnm+N;7^+B&GMT@5<*0o<`Rey6m|4yOzW07Z zS;;M3h@*@^a4^Xt8bsy-+6z!6yW_K3z+r3Vk~@SEJCu*HiH-A|TKN{$o?VQcBQ~Wg z-h;M)mI9`QG0c(6Z zKT`!>E=5m>zobvi2^{C-0Rl2e?2#QtTF8>q+FFkctwG~WOOvj)3y(=SC$eM|$HKB9G`1{&d z=G5jLE0A+D!As2}7}#eH4@PhWZSDxXW@~?_JCYC`+ZcizrG;Z4Jq!}jS<2XB>d?-H zZY1uXal{=RMfq(0xm7ctJWwV50N6qzi+$>yUx#NPvmu=#rzQ}$q0$Q1=@B)YpJba^97GFq=MtyOMmETI?odRPNB!M zN(c%21j#i%i&Ye25XUF&hh26ygJ({Oy13M-2AL1`XlJO}iQPaw3$#)tifrqElt6Oe zjue_eLJ*FAYmls{Iqz_MwqgS25owni*iP>TbSQk`X=>;S+zSL|$XBqT8c7pU@4FG} zbF8@zgr3@1C;MV}*N|Pc1rk^^(vG*CKpLwJ_7#~o%d;FnG6ObkRCX1>3+IXYApVMP z)mmt|>udm4?Wda-K94M(#Z@R=P_#U%&PE9Kqo#~x*ZxZvRa1;laO^c+8^PJh*c9RIAOG;=!tNre>^aBHC>j5ByQq6~=_ zlUdH_Dy>*Jb!Z5l*6l=6@Tna%YgJFp*@W!V{vu0eH-ma3E=ACODa0AOwVgz6zUX1| zUQQ&?MAQx)0T~?!%S~EyhKE|j@)#D37c@<3$sivh^gaVTT(MHCoRNJZR zr>2uBVk^R;swa}Rkqq8Eu@vm$7M)~z+l17~Ph3&FC5BG$)8y2}^}L~>nBn{2SBFY# z#t(*-u>}8SsHap#$J2^UFw&H=FsAl&MHR$UJ0l50(=YXgf0%9)U;!f-$N{n2nlg z!9Uo2wc&ixeZD%^sn!J#4tq-=v6g6PQc^C3-zX`jfHZnm7e^PN$7d^4 zOz(z|Ut=4LbVPS#`P;Yd&X3Y(EpOBq<{~BIWpa9P-x#?+aH5;fq;sT zPnqp>m>W=IRr|!2^ZLdFv%|sI?phRaMl4-+IFAVJANCw8*{NRjl|?G5`Y!4C86ZlERu(l-&1J#=}EV1p#Q& zL5O>T7=BVr$*bxN6gm3|s&tzGd|O{V4${m@H)siLL!kZJ=C_jjCe|s$=E*&v>ML%I zPK#brn)VM2fo|YxQvqk8#|L-=93xmHIpOWOwgRU_nn&xF84dv8#K!0s5O>OOXGP?G z%E7CJXEg(j^2wGt&Hxg{72avr4bVQbea|5s!75sPy%kB`?`4@aXutTcC~6axjU5wgY&kD``P`#C z>{T_M)0<^vsXL;LZiK%N>n$C3Xi2hMvO)x331Xd@%>_m;MW5eYWSCUoYj}eE2{S^q zWGKS{|LpD@b>(AYKJP`Xi@>XsVVqJ6xado9O3^OY8j2)N!)6q%Y@BO|rJhzUZCMtW z3@0_Itj$Qrl4z<55SYTSiz&73s+L6=Ud+XmGve!FwJLn}hUIe%f^vIAsIFErAAliU zk@L5Pc(wkr-ct2Yi_oh%LM<_pyFi4*XfeyTi&h7#21s9r+Km@p=N!8IzDN-0#%`H#QFU5WqkbRdHDuSwZA=N_(1VYxfn-5^Do(y2TH50HKnQaM>(A37xkd4(TcBy#R8zAG5OK(=Xzlq{qOXDQ;O#bihaxrKa1=Wxu}6K|0GIM$*YMa>+syoAwSCy$!#a+YQ#u+|Oocys zBIzB_Jr}t!-ak1>sb85oDN}B~q`fYnNi-SRbqA7t4&*4*Q3Q*!AZlV(6&3kWvDlgr za8wM3lq=epBtR7S8Ad6m8Tl1*ojjpfPYLjA2W9DcbxU~=arKVc1~o1uA3@Zc+jEZz zS8!oC+3|T!T^u$@m6SBdcbe*r4)Rw-*8-f&ns4AP^}jC7(Y{IJ6X7bJ9dw%0Ps9fz zrr1@$9Q-5_uhRsKsGzYL4Fwg#)9H40G|b5b2K1VufpXCnL7v20ehTx6pEr=*K377h zLKBEU`Y=E)@EbwW2Ty8_Id|RNWi_a~ro&F5lB^B@K~2o^gg{O z+4XjGrPM3XgwykTYRJB=fWUg!bOO>!lZ3O&NmOpmyMzOuymfPLlGT@s&f(Q7@xWF- z2r3ltO6bq)5?RVN4ew}nn~jkuC^@UY+C6G}dHeE0c@IOSm7W#s(J-WNVS3&gy$7S6 zFvP;xb?!TZ*#XzcjSc%C{kq@wD3eCLjtB0QXA&7`dV7ROstGJ#ijBm*qT9-n?yzKE zQ8ONiXN=bqtk?k=!zm9~5Uz^fc-gw$p^1))lIBh z1A+iGCPr%_ou4g2@iQX_%MuOz7}X?ybUJ(fjNL9;Y2qa>U99oyXj7rW7tL9wFG!y6 zj3=N&0aoOO25m8=WlBG!r==~TQgS+{EpcWMP;|lVu}d(F+~5XFN|q8AW~~xjAIFMY z+{A?uC}k7SR-?wQtzdI=H*F!mhuB(^%Igb%h}*7_fM$7I{az|7K3 zf@iph>ij2OX2Nu=hJN|OttRDL=b<0z;k)r@|9q$_|1sTH$O}qJBv_av1K}*=v@Cqs z$t6uEz;d&abdz55wCcP>SvDgFo~|g0MCkj51Cuul>fR!obbkg>y{Bd#P4Fa%i4^tw z`AepzO6(F&c%ps=amA8TdMzpSenYE=Xt= zx3rCrx%^VT{zbo$bg8Us2(#arEaEMBzD}JB70dl6%AD`5e4j(MrX%bLg)fP+!%O;& zHM=wr$S>Ypda#N*YqbNbzqgwe(FSZ#NG}qJ5W0~5P;%;%IHlewF?-jiIThRgYo;w* zllN4vxDB1LE(IDu=QFVl04Zj}K$|2UICxc9D;}`)_h&xn#A>XArXmm0JY#HkJibO( zhoIGTeqVlSIC0S+bV0f&U1Tq^P*pzkx2O^%9DTt;V+p7-3B+&h7`^p{qVDu~0vLd| zIJA)|@F{sT1n|wi|vj6zp2x;xmbl&bs8Jrg(D#U1@*Fa^vfgc8bzfr~;REe+~^4ZF- zY4p(m?22sm%s86T_Id(B>kU5=(&X~JrNc)Fisydw7h<=jK8C4n(r_lig_6 zRqtORjiM)h5s+V0mbNr+^g&v7)6>dwx3C_GrmhQ42Ybfu~i+2-fl=4AftIh6**n zGD1``L8dtM8!rzUiFfJh8gwZRY1tNQ*rmfR0uQ4Sr7ESG zw%B>i-Oj6a6NuG=L*?3&&~&l{U_ZhQi@J1OY~3V=$ad}eRSZ;B$zHENNz4cFn7f?u zt&Al)0rgqsMb6D>+G)KbOlk&meznpQodTHV5j{1p;izyM7&#y#! z*SqZTY?ajTd>b})QB~M{1YGJc5Rnj*H!WFpj0voBFJLL2srqwX3g*x9&%Gap3|liv zOnQ2Uz4W5C`_6LDA(hEdd};Ele8s-^5}ho|3WNz`eMK#I3pCsi>8CQo$EqV1K%K7D z*7zQje3WUo#Ll$f&)dx{zp=i4Fg|xU0H@Onh?RS#TN4tCc)fvSk{8kbk49bPsIJhF z{82Oc%KsH^psy2>RpQxE1}a{iWj9B0kAPq;GLQ_Gdx}Vy>J)$TpkfHHA_!cB~gDRqc$?~IRFX=)2^MW1-1(1Re%_-@I8bP z3NyK51&#K|$d+n{TqI`C= zCX}JG7_cA%;JMqrCN6xnV2#0(C@ej0qZSei;0sIWS|ID)%%a|#B6cd(?>Ps5_Ed?C zqzU+dFyGd@AmqJ@XbbOSfyqi)m}q8vUF&z81}_G!%OhafT<*~!Guy>=vD+3a8*Sio zhI%!(SsUPqKj4bn90=Y=(0fs1MuQ$9Wci<>%9&h|2G9KQt{i8#F*_L@$C=ebtW|2G zWwd_;F%tjaGyFp+nXNB9e&HwD$a?*y5bfEZ@Ye&3M%aWP_Hen*ae>}|ZfzTq5r+S- z?iK^+aTKt;|Lwg$Z6|SBOj@Bsy&0-+A377Vyf*B>azyM{p&%H0f>TXz?s!ol^Yf?U z`<{k35=w4!d&9hvV(KnWrZgZMB=?#UX5BBlgzCA^ynqf^ONWZJea+hq#$3WR@q)IC zEL91977STdG~^uKv0-h7NuzhO3l!AygTIJGqKw5YVH7!m-tcAUTiz1d=^5^oS-%AH zp0Oahu zoM#wX-S#lK@7hU9C^uDlOVu)vThnMT!rhfl9!1jps#6^*z(w|7xqH;0tN!X`Gk^YAiLg72BH>8dR)3evv>HoLaWxS- z_8R$1J>zOX@qbZw3HMar-Oao(T@{f#?`*IaL8o{0Pt@Bn!k32Bc*b)DJNbmSp6=(Q z*1$q%O^3YY(~%wgfSpq&s> z4jn8*@=HNx(Z8N$>QT()HBOIHTQcPZj#|GyESvRF2os0KAA!FCIx7q*05m z@6a(#5&QDZm~#Btt6bkHq%dqZpqn3H?;^YYd+GW&jfNsiP##xMX5Ky7S_v~$xDnx? zX#@01$DX(ek4ik2m)=t)xnu<7fqS_X_ZtQH6vx9lhl8w!nJqvd$K9DvT`n!1q&!Ev zDt6p5J)4(?SYd6pC*)fvOs9%TdXBR~aO%q~H^Uls*vG=Q@_AL$d4a?u3!Pb;p@gWg z?tELW^+`|&>hm1u7AFzD-6XjcgG;vt&qr`lragCubrr6q)gD{{sLdcDMvm)Tc6{CEjG^JU1FkexHLmG_}Q(!Dx zmJ%9|qYKqrW8m7A{vY&{Ip*oZZQg=5J6II-$dA3U4JVwta#_Sj7za=MHJ>6z>69c@ zJz2|J8tq!ZW*kbRYV-8?;u|h}+e^(F%)fn)w4vgr926ay$YwLG1;H}*6~x?V ze52On-&qQn$?!u<7#)o03>7qQ`mqA+U<7%?z4SG+3BFpBn?w`11vfwP^<7(v`<^(Y z>YlJzp)unU`R$n5__2csFg%O(?AJVpu=HF1i>{e!3l1;nGG*@eGJffVZpAlIsa*{R z<8bP06C{0KC40n&^OptpbnftgGXD;2A z!FYQ@CAb$Vlc6wFU@mhTYp@q`29?VvMIOjIInOotIPK)IJ_6F8u9v{GnjJCHm}_>% zp26?LImqLpb5$XgmUt6I!cyz>>uw~2W=QK8Sq4qYM&3$!)GfzLeb{Fq>>tz*Vu-A% z5fmu$#^HGbVltIJlT|@nK48Iw>Cw95V%@^W-PAy+QjVH^p6FLn;aC;%RYAI`LQ9* zI;Dk>!<8-2ZE|Y+RT4B8bddY(@2QG+cywW)emoO)&F|(9&ztopJ7_9V|9wQ}Z<7TaTibw2~eB)EQRi}F$z z@2$c-%e(LpU&O&(nA_Shb7v3big|flORdf(fyIf>qkJ7EK} zPN!=h%yiMP3>isTp8l%6PVPd-n9ASU zW`i3>thKK4#vZ*j*dW1dG}Xv#T9RPLdL+7ET5pIqC#XTsg^=3Elb5m%Zv+|2Mr0m>i$$-kXwxbU%nvV5z(PVe$NyLd&txSqO6J?@aBXgma|LT^UbKLPO zkDhWy2Hw}RW}(GKvD}A@m7~l~jrz5z3mmVms9hPqL!e-q17I+Y7qXLiU@GV@0{u~4 zjga5Uoq<5=t0X(4PA*=N6bI%6Zk0{JkRdmqyF;$ZqAZ8(vm<-KT~?dFGkS1EO&!& zhQW7ce;KJU`@O2P5P+}XGVWnS3S)oPg*+OHiH|DW$_sck%QV+Sx8sA9{J^w-&ZCXw zd}Oc_jhY;DBDB^endcg)y~h?gp~b)5T`3G835}FBUfwq(oEY0bgA~qkkyy%fh?6dj z*`^`gtwFLBR?{=j$FR(a*Gr0p_AYaP&T2=jdmsakRmgUEWG8@!9J3K$BdAPrLA0aFx7(a=jXz5TNbB##7($ZwEQX(JyfP$(;jtFm6> zC+QsPGChgg-)N*(Lz_keTWvln!@a`9F`&VkcAwS22fR%DWFgN4RQ^I8l+X_-^FkBd z7fri8;yV4Gz@hwayIArPSwx*1YZ!-?Or^SO7xK3oM^x_Jod~!8jb~-ZZpb?S)*w{- z&~^ENW2hMfbR7yCfWp+DSeBJNCY9k=+ISI=WqtbdQ%H@U%MlfXe%Q4dP0Jj^T998eJ?b(wO zH(y=yAd0R6j2Tm<0&YZj$pzC#(~Edz*&{i?Ct-9w4mg2H;(~)NY6Ns2h*Hb@+qX%# z|G@gdKrWN5sUmYH=(|yhjiBkzt~-u_W0k@r4r%xO>uCy~v0}(h^Y;gtzX$6bp5rS8Q=ys|{rxkz%*i0pi&BqsGR0jgz$W(vX?nD8k%mD%CnVJ2`#S}x%c zhYeJ=R%0?V5JmyM$Rq7h8lFtRTrH(!BrKV6S!DP%bjL*vaQs3$J6+^Fx|2%5I2p{y$7IFqS|RI) z`4UVs>%XFlIrX<=C9BXQAHhDB*^inaUPRNa?*3}CYJB|B@=0{3N>!p&*Nc~b7@SJ@ zplHL++RmH~ewE0H{$*@`r^v5``Xlu@;aBl|WSuHYdA_5$bYS*hv5HBDfM#9HDCdg+ zuw?vgauT#Z;=L$!RYA5C@jv3*AGF^y~$ zm=Xs8a#(qG*UG2VA-`HX--Pq7WAXCr>}O3wk!pciB2+31iwshgY&NCP>UNVWXVYrW z^Ff~rkpF3ubS?II4k~65OQ<48TLi&e#7{9;8J~Z{)FIkt1S%W+Xg_!7 zQkP2ZkSBh_fM{Kg<05VU$`(5z(-y!)vcZXQ zD{d*^8m7ivfYFrG9;|CXYS+nwCDR>8;|l0x4V3)Ok%2&O@P={IkYc8`H)Vy3H@hV> zwTtK+b)AxVFKE3i4007O{lTdn%>0$$$CJu)_WyvR82=ZJ`hQB)e?}C;|FTddFK1+W zD8f_9)5n@BcfA`S?*wBSr(T8YF6=*f+0BK{aCW(ko1vlkb1gDj-%A8lJbsUOk49zh z0Jk72w$9tGfca9B2Her$w4t(DIc=!4g!t5On6Jft!ab64#v-xZg`Umn+z@(59J2Gc zU0qc*EmN2K<|lL4C>}#ZCRB!!330+5>O)K%0r~6JZupNav290%e4zWcFvnLvE|Okl z&DBA_z6!2nu$TIg{9Fz4`M4d6Q4}f7pw1RJ{u$?7?*aE_B@eT>cGM3L+L}=7WDXZL z4DX6!Fy~HI{o?;6wS1e(#z~H>zn|-?D^Fu*k9h^KL zRgKe%(&bGVB||bb1oXw8<5*yyYg#@N2aB?^b|JCs*IPJp>mB3&o5eF&~19M4^ z-`dIX$*ADe=>eB>iWP&moF-183#0k`4to z1okD(`-Uz~gn<`RVIkM2#9}t=PoDCHS@sQ|(*NPt4*BzYkEg?!QSes6tx*)wEt#NX z>I-juC}6PjY4sn!hz1$Q5q@j1-XClgTtXJyLXf|#D!ah`?M_oX2p_{}mBH4=S^|Z# zTg<%aROC0BDj9&QV-IQKcS+?c&W6ikqoe?_92W80pLXrH=qQbtw}rHN=jaj8{W3Fxt>$KSl)13PMtR(8KumN%w^9X4e=^Qgp$ac= zD)6A_06P*Nga^%}Xly=Tz|fs)&XR*Y83gP6#`g$7-S^wN{A@bH55p|&8$4vi|3TIP zP5J{5WAxgxSFNvMuzqe`=uV7I{#N>c2wUIz!YrL8846a?EQ!ExXhSz;&s=(xx9FDMjEDf;4xlPmw;u&EX=cDEh5 zGH$;%y4<$m@&BY{q2kXSS2WRk!;sZH*WYoT_UmH9NqB8)EHRro?k@d9avueD@w}Gv*-Q>; z(TP<3k7cx%Z}JWN7Yzr>{Tui{*Z%9a9z%QocrL4C5mm1INt9?K`|(_>{40DsIMYkU zU=r=OVbAF=iUxm_gQKIc4?i*EHdSeQl~N(`z5T?u9_iaVa6l6n>ve>3E_!wc`Ar>h z9W-MECc4W?%!cUpu2&eh3o`&i$WJS`Z@bqwTrkEay`$<=C`8ar4PM2828F*d!Vd!V zgDH-I*uqAibO0U54y5*BDnAY`N-p&ijXIh)H>*_w~BHrX5vK z5#oF%ngcc3@xQGBcpF&Z++fSFZUqrSG)RjRotIN--N0Pbs)_D$1>sOp*a zUovT=r5$DRBCe=NfeRrR6pa5|!?5kH#Vs&)HY2q0GvcocJ!s(95eWBJEqM}xco0xG zDX3&g%}!q$wHF?+oBEf)pm-z$=KA`4&-(*xZF?n-f+2N?AlfS@xZ`d$re=bPf~7I} z9O-8fQ{MUF993y;x^lMlMW}^7ho&J3B%<7v6J@5Vq<5|~{0&yK2rzdGj??ketP9OR z3GRzgLAi#t*}HMVylYLk|7J^q9+Zp?{&NxN5++WTi=j5i*Dlt#hP6)I&nK=-hTIu* zb;|TmILaAl^EG9fo*g>uIF4{a`j{M*a3}CY8-io3vS^(VV8=qNi&lO=OMC|1Pr^4< z(U@o|_h`dDP&tD&t0zfB4eRRg#WLVcfuzJw z^hp%Iq{#r562VyF5EsFu^ZI%+Q}S956vsc8FXg)g9)=Q5Syk(UMjo~U)3+>+lc0#Oi!`|q(|7uy72 zv>BB_Sw_nIwPyc+`7eB@+m-&MQtTXi=6Osc)|}Uk)XlN6Xw(n7?DX-OmL{YxzPO2` zK3`J+J>y?!!wUk&FzIkq8wy-3b$*RB?e@`4bCRdh(}Q7TH3me?sPXMCYBexD8Ht9V zR>xDG5RR@{HfC~ejm4_%mug0B-TOlL_)D2YtJPJY)@qR>?@U=Y_Lj%u; z)2uG-VCg-n<*E=SiEN;Cp>$X?>I6x6zs+8bQ}27zk_k_V3c?k(Bbz=Tx6?q+6G$^s zozpH|^eq*iQ>V)h5gAO2yr1C!Q(mpK>r(-}?Nw>w9M~I>J|9H*wb#NOo$p(`W9Ye_ z?9_<+=5CzLa!AFwCT8z0EnYBA5pl@8i3@9l&(l4yfq1^4%)%Y@C~wmzlL{wJuTbC( z(eN(-LpRr)M-1&{_j|B1f1P!uF?ony^X(PCS>p*(nQ5zl<+(>Rh&T zwIR7TL}X!=PJRT%ndA=|8P}8dO^wrs4GnAmR?5xODl6%ce+*0t4rj@OsWrX}z zIEAGP$~Y>p3CGy4ms~D^A}Jc6^Ya4~>BF7P@J3CEM-0)E>yW@M;k2A)B%%8KY|0oS zoQoCe+lHjlV23C5{Zm2hve7w?p|-sahh zYcKlFuq`RGOe6Y_?@oq%G~$vO+iceq3bLDycd&BfKX<1* zV%(ckX$;WK@%7Ve%6pK8!%(C0t00IA(e>0#j93O?Dg|Q$`>wDuA(A{93K?lQz-_FU zd@N*00Wy-zS%pVg^;N;oi&9a?u&QsISl3DetK62qDeApvb@ej;t!$X&xzdt zXLlKj=E)*wyQY;PvVcqQGk@$YXC!>vKlTQ)f=}ng+#=D#qB-~I+vCWQfDbP%sKg3^`aEtU?J0il~4BTovMj2}_0QXlo5=7V~Gj7Soq zo%3?J#*yiVtGKeK5>OQG?+7gsOR?LaVCNDx04r# z&9cAQ7dFw_>N?k&q117i1%|h`4EQEgZ99c~pHoq-iZIv&+4F|~Tg3eS{wn=eQBK%%VNB2_b%Q<+~%kCf-avVG&fI&VKc246XnF9j-Bz8 zi4VupHX%+rS&h_}gojTuT4#(pQ7=v}yWOg<|Lig6&L9t|nr8plR>91N!YSB7D=qLu zno>L^H|&4fwLv}}I7BrU9OvBRWXI-yFaB*Q)23-G(~(WKbpNp45I zBAkf@%W4%BRG+;G%(r=nE-uHcPP_xf3%;3BP{O93wxBBn$xA&wl9#GGd1>`8ZQD`^ zUXDm(p$NBY(-&(_l(JiqWYq#dy{m)lQa#mh#pt7D<}o^Kcllb?Th6IF%CqEv$%-Lh zuzmB&X8r(DR9g_}p1F3S$4{m^*=EW8W3^f?>exJ_%tb-o2;O-#h{pV34DQ53uo4p- zJwoxBfQQ(JlY(FrJf8se?p^z8Yebr)CVm1>Uj=m4KbJ|8upN{ysB@eaDVXWWhFN>U0Ogs6J>HNq5YZ`DM;7sh?I%uB5?*Z zgKWvcy*2CouQ%rad?=o>qqNtEs>M~E$ojt(ai#v+?9;9rqLDzx?>sT9Du!q>vh7>N zc3fPt1>~F`ay&zr$>8_q;ewg0^IT*l_gnXXCSp8?&4QaaH7?!Q8ofzbp;IeoE91;9 z{j5tTrYb4!p0TiY`$~i?7SYoPoW8)a+o3FxsmcT4OYcT%vmnBaja?$t;LL|k1?i7> zC5Jx(?Vx6rj|u!@-g!3;qbcW3xBtw?82NZ3z9gED?x0PtX|#=JlFwwT23&BAm|m1Z zrb|}1Ga%+f07B=9uCNJQ^t;Z#lHXFvC^*UE?=8M{1yDguh@c1h-hNu?S#W!&?QhuX zy@hbV@wQ-u%zya9zcBrHT5bB$74viV*vS+^xD)6!DzDfEdDG6FND`FK9eQW&$}eU& zq+6?iOT;AvQe;l7-c5Zk*q#Q7^kSSl38ejZt7(%7`n+wSTS0eRA?p)kj;9rPq_vUI zYCE>nXJHImt;3S>wJW;nCrfpOaB{^VrI=F%e2tRD6FYecm{53LCiA)qn!DiYOkr6g z|Ax4nET{8Xa{rw=xm^i!tDC)q<}>0qp{YHhS^pc9{pS*3N-Hy4gZ$6bQ?g~xGYsnQ`P2g1F+iPVx;R1sq2WRX?=vol%{tIYw2XHh} z0${~e!TC)>eM!YyPynD6<-4j@>w1>TfX1Y7X39lbJP)+xU9vjrdtSR9i2=yZCVfw` z>Aml}wzqwoB&+66rC}F2u7IKX=6!)EF4zINMyG)reLQG)iZ=#b)*)i6MHXnDHKB?a zI9-wUtY9Hev*)yMOrxQ1JRpy|a7Li34pxa<8AdT<;p;Qx7;kvIJ-)ZnIvO2FdIIuf zjuUaNTtsF#KJ6z=ty)a&%B$ZU-Z_pZGFWi7B}zwh^cf^!+)W4( zsE1NNLz^A#MPtAncuNk2P(q@(gGwpae*tVZ6a`Vp!qFuZ5B1fV!CGk8v8XXE(cJ=e zdkJ(;;Outxx=_YxC$s3&^ViF>6ZVJ_mfztptpq~yb3lq)QrS$PL14wGM4|$N^u7u z*m7>&SD&%5gEi~||8wM@gLbz$IyI~Zd0u)&4LK{OB!PK}6aT))$&aQ0{97$P5Lr0f z=-+sY1cwa~-GOr+y4`<`N->k}o;CuG9QQ_(+@>LR>?0V+*B0&4Zp>Eitpo?3Ri|zI zOOnfsQFz;&?~}mDMC!a@!S}U~O|isY*qx?Lt(o|bQnrQIx7;MApRWBgM-GN5e&T8~ z8fu-R-+gjGAMG?fcQ964MBJSF0GxoAlbp*@G+Dgp#n@j(3gMlR3aZC0L0N))N<&baOW?LlmmI^eD0pK}zOpgst9k9?;S20jH zgS|YN`NXpBdQJYEHcm1IEH1(WNarR5*h_l5-it~PZ8GMJuA+7b^-yq7zsMOOd4f*1rnLidWdA)FcnJYjfea{Idgr4{8FQhs;g7vXJD8vv{Qq zJeHH^SR09lh2*buO&#MFn_~r#y>6<_X(q83evM~N63-$P?t!>}%hmrL4c(@*v-0pu zecvqd4rTjG^>NeTxo>379d1xx#+zU=nym>TR08a*-gbvJ0pr;2mtxo8=`#67(|^Ep zcOvRs!R4rxDaGh$DOG*uAWl-GV!vezl`}ZP@c1MD;w=e;Oc5ZHO{n6}>(^72+q7qw zr#!|~@05KpFa+BeB!+VVGz9PzYw~?}AG`!0&?-fPzkb{^CAT)dW#9GuAU}0K3Uj;s zI!CZ^7qh^QCEAo&>RQf~(~~o*ubEZwq8uOa3Z|v|Y#=uDg`AC6m1(wudd%NYJTZUz zm4iWPzR=?zB5%udT`QxK05z`t(IYqUOKQy8C_=6lx=S$`9zZ^GuZN6v<6dU@0~0nU zN$ZeM9C1^y(TwvoET_rGX)TWJxmtP5+unPSf@rve5Fnyt>lntRJsxM!9`E8WS-`iB zU+P@)J;X=GD7b@E{s>&>dr@=~Lp^FKe}A4al&E|G44>ez0kt|?S&J~6P zUT%ExA(jPmj7Bt6*W$SK&MJuk9m&FW!4#_Wj2jz$*KTeR+xxwC7S>41o|m z-SSvC4A>jjsy5*cYeF4oiYy3z9oH14$%fM-8Qp9AqaOx1EkD;NYWA^Exs&viI`JB< z9(=B0LqwW3`Fux(?OOh9Z9p@nT;m2PY*n;H1?kJFHwy$s=iVrb>K&$}`A~bO4Yw@7 zoPWTG8JCLSoS3DA3VLk}2!f@|(s6R>k9cNjj*BPGbJlhC#)__O0{AXsf1lu)X1WNxlT zet0)*OIaNE=aD68Bb9e{OsOj`O@w~xcZm(QWWnD}TF96O6p);OLiulE;c8+LGgSmY zxbNd1LNZA)B7#=q4TYH=Nvex;g$s7rBBO2Km33W(^AbB5ZR14mKr(3}&hY}k{P}_# zR9FyKyyKSghK$io_ll+-rkje)%pQb=Gu&I5ZqJp5;-MeR+j>mhd$=yyiK3U_X%rIg}zHU ziagJP5Wb}d;@Dvo!XW<_^-pl_u?k~haZA!uqMJlJq)h%b-DO7{-L=UhPg{q(=+B>zI)3K;>oGaxt_h}P2%vLz~ z!)`o;V;a885?WOXP!G4kK~?wAJm4sL0T#!!xsc7wP zp%0wXU#*(2MrsGxOj%(!Pyi5jLwscF+mJ~Ntx>!(5TjuTTxh8P+;!>`AuKcSyEikR zMdN6W_-P5xcubkXat2m4N|W|MCK6ifAM(}{vqYh3&s{o0aG%7v)ccMskH25``Xul?W z=QyFDK)T};h4eYJJg4_1&5uMojxR2sxN0)g61sGE9SjUMP6-IhI5|9Xk??VM^+j&GK7FvOezb=L-&3C6Sr4}4Gf*R}ubx=%c`oQIxQDh42`_zH#hRy;*xx|3B< z6{OmF&GKofKB`K<+8nrqlf5iPbu7|=Q^D?8N56>u6#CsNS*O*3y3gjm1wz)C);~eZ z3oy@;i*;Tj``!&LynO549;-#BhKAZ~p+4QiI{^c9h||Ib_H#Zo9M7~dV%-Zl=h`3EF+4di31omHrj7MlSL?t-brdWn{207dI-TD?i4|jX{ z>8bRs!Y$utRO2oUZL7zOuYV)wm^k&V8-8fk?6%ow|Mm`^->v^MV`@meOKAvvpyM@G zu@I^ERscv+&*hEnZ1M;MvugwKuSO;UDxPmeu;T$S~PzhK{5i#E)OgRd~MBQAL8MCj&-dK zo0ogUY_wCaYOd(>?5d#yi=^slm=4;lrKEEmL{GFNvazsdmSJ*8Gk74SIz+w{UyD$$ z*LCbjdB>6^d=3g1MAhYcu1xVyRW~kG2w+QlN)6!@?-x|nCQg*`{y8@$9|i^v@}e}$ zu^{bPKRX^X*N(xK1suxbRvnqeUywK>#6$7YG|NQIH-!$77KH9xdsPfC8^#88zkIz% z=ka~I4sPQ-IuTB5c_1YRX~tKN_73eviMFGNQ?7?qvOHpR-(?_Zf;t>o((54yIegoee+=w^O70! zbA1!S^dfBUQBzfftLYhVjQmpmNz{Fb zd`U#TDGPaapDJiz%tRR z6HVbH3?DyNG4BTD7R>oJ^=t7PPJ>@lYL-@mb%P2oY!Dbw-t1XAb0HlMw*UEaA!^OJ zHU`_ydoOmi(!XzaQZh@z+ce)VmFaiP^z?sROh0yCo-xWpmPLqiTkyv0P6q2+U&N2{%sxBjESU0zIP0|dc$dV{6v zFKD689w8gw*8tdE!LRwo-&RiznJ4=VAAtviWV6|e?tBq*aXE8S5khSQP7a zWwLK15}AIPEC5&Z^Zs9NKQM>$`@HvJk(q@1+25jHrj9*WxY};Kt~}IccWB<6^tqE+ z3FeB_89q}$Det)KZ}(_WAW!_vp7()brmk=+8-)GZ-p77I=&Jgqn5RLnDzX`%;ir4f znK59ykSe1hvN~8+f3G@J;yHh>!VpvdRURv)f~Gm!urh@pFPy~k3AgYc9cfg9E$3J` zR0Zutu5UK?o5R)Zg6);7dLb<4DLonbis}i zmEJ?>_Vz=YL{&JEHP(|a1A7mBOl(_d|1FfvPYi1F$Hvr@euRG_{6L^hIASt#ivxe@ zHx0UfXWcaRwO~BCj_%DRMvYZjdBrGS6hW3%B(q`hPw!_Ikj+KloB&Aatg<#duXlp2X+)b%fwES@{#5)nxGKVhi1@J5sK-ZkWo@Z1B=C)~wjI}cLyhMo5L1)qeK1C+l#j0_bc_8qg%|bXe zu#vT3_64MlGy&ocp~K61ChqGO70maxvmI@soWK5a?6K6?ptvpn{8Rm0I z)D9`wLNDbO!aY8fbg`z4^l|`PmP^<(eMP~75f3vzs&MP%YsubI)K9LDR*KKXu6nYE z)B$qn&HOR6ujm1>G0Rm8heL{L;R_idrRG;kc-~t@XG>eVS6pVsFFX7;Ggr-4uQdZs zakIUeHaB&j8Y(lI+`H)Z2As?<5~?2vpSeFiHS-Dihce6yZ~qqX zcpvG!w6xfoLZeKtSsIb2!n@{iSpOR%Wk-9}vht4xm)8gOg{xYz8+e-Vvwu4obaUlZ zCOLo8_^b6&N}M0=F^df96Of-xl-{H>@IYsY$V9>dDnR;SDY@+niOfelczv0gHtp!KkY)@NFyp;#|+zG zGxd8#d~_GD;)oD9e%n%V3M0$}`|ncB9&KLzWa#@1LU|(E6%cXH$-lf1*a!YlPogkj ze0t28^R6yk=T~RCsqk{C?nVBXgABPBFIC{DG_!PchEi0YL^4vXVwP~a=rW9|f2-Ul zBU0Uh<2*4$$!=Lnrj-n4jQY|6u#%4uxghJ(vhjQ5lOwW6A;k%p z|IGV{De6sqm?*)XHu<7t2sI(zByMzbn8DXf+;S6&J_Pg7T19JS5j@@v|4fB8UoXE& ze1?I`@TwMsGnm&?bGGtyEPk&|`GX=c)bKf4SO>{k<+4K01~LH-9_i0S&$ALWGlHNv2}e7^${Zds(T@HCj4Dy+;epp&A=Kk_p1#Z}w@g72`o zVuJsigRf}!PSus4T%aiH)8tkGJi{Wb7l#|Q`yg7@W}aqELpWx#j7VVB*wEC8I>26Rr$y8?J@v{ifuz$+CC~;?)y!B?m%S$B! zQ2RU_EB$iB2Y9K5oW%spr=9cELE&B<+ua6-xLF%YR}8nyk)&-}MuF@b93!Vf_dXQ~ zN^sfK{wlwv4>P>cY%JPIT~<>spib!CW>VA^go{*dzvCAdicV`4!R0ZE?xhgUsW_S< zOH;(d2*Ed=GrY=Y_P>|LM5;yep{zKPcMbXs?2UaX0i9TwmI}oV$N5q6E zJyv`i*7j}yKGZTM`xRD(ff*mOAxYC8>?6Jf()kA}BF|T1v{7|7me*On~ zc&Z^1AaZ$wBA|jPfr632hV<;c3*w?l1fAyvxO%B@An@1w0|mjUjHLir5+F7OE%Fp3vmE4rZ~n z(Pdt4kwIna$F%MKQOh%2vq13c5Z)n!rN3bpQ0CC)qWw7U2AA&{khiMfT8kG2;-8nO zb_cgYs@2B8(=Ej|rMf&l>D))Bwe-OQylM-z4IX_()1Hp3-E~5h965Dr1M?zv^iF0D z#*7U~b0BN%ha=44B=!t<9L``H-6VqZhTQ8cffKYVdN1Z&CJT~u1jeX>5@*fmQID&O zzd1b8DJNt_{CabTZ$03JLkybeq>#OOfiSOX#OKiDDK!w>!HuOV-T^y z>?esfNkvhiunIr_aOX0fN2Hb7-?xC@fe=#vq`7jT0sjtelJX74_mELU8SJ5>R1{Ej zw}P-ig)(o_udm1y+PxUKQZc|<5dA0rxfV>^lQIYSzokn70J-o-e52J8Qtj)Xj`Bh8 zE@WAQL?zU!QgfY;CDq{z&v~h?D^Ph>OIbS5yN@UORVFre7-l>f z7=*thWkxNm(wPL{Xrm@?dvBWvC)xh17y!P<|E%&n<%sIMt4t18{%-1B7nJ30bjCJ~ zCbEj}xU6KChpte?Q0_h$fcEl36;nxUm1U3$ew9Azln-c(LD~3c&o6sBuG%RvWjui5Bk?bSJTTuh z(_Kc~q)B%>V3wzOUL1%>F26^=-hU`iMq+EcWtnPmD#Z((UKZS7(2D7Wzda#dFC$To zhA5AdX~Eqi2a_3glqG?pP!p=-_8|_?H}T6ct1#b3WREDLbWdM!&PcoO6)EG9PO`kRLh=Eo!2lybT zOQ<)eZ$DqFiye%O}#u8y4}%(!8=-gsh>@B)&W}omGc9rc%4L zqXWU=k3146Z`1H!=K2qqB4e~CLtqK^K}(X+EeBNlzQ9bic}uvt@z2wWI1*#rhs9(5 z0c6m-FD}WhCutYb%y@N7odiHB@oIrs_A{PxKfb3o5yPiQ0>OMJ3pJ*d5^0MnC)gE&zk;~l(XxO_X)3yIiiJuH9bFX46liR^EtxrZAKXy+%``$e4dHojG z)wtCsoPHThwL(H+UVR5@5VR4&oaU+pj7ZF|3{IIhMKuTHly?Zh|APy${yt2;3k~is zV?^H}t;yr7p^Qo~I^jTy``u!Gbfv~LRESG(hXxN$>{lDxw1ux2au(NtRl?pPTo30R zIN{|nyA1FTz)2<`8gqp~EvHXJf&Q)YD#yv1WA|l)4xhv;xMs6U(JRA; zO|9|yDJ7ZAFzSCg1Pm8+-HIhn{(il7woMDO(9UVHTg1H-IrDC)4@FTpu3Ve2yVjY! zjNKZLG!m9Gu5PRyYdMEL@f_<(0NAnfT(kCY6q5351Q94{iqJLeUBHs3OnUF^0J&$% z6o>w|ir07G>MQFvyq4GvrouEobbd16NyN?`K8sTI8&gVa#_x+6BPF~DW$gbWdEsp_91b(5o#Scz@k+0r6;8yE5w^vNXTNPqtLr;MS)~@CNtTS!m@G=hAM0XXfc<#)4 zVRGrBf7e5zOW2;jSNI(aBxg7Y_0s_OdKgw3*Y-3P{>TD45hNE1JF+i@ z#(rGS-y#%SKxaNz)z2|DkFWZ11Y_8gJba-!y~h%j*J<3vq-k^mb4Y1V+K$arUd*g0 z;WK1(C>cx!Wg=ueI|ef5kjKn>UKK&gzxjKWE61&$7Jh<}TVI{P|jAg6Yl z%lP>4|I& z8d==ML+)~sv^r-~_BnSodl3z<^a>8fZX-D4rP^#NaIVJUYz8=35&P9S;}C0*vqOlO zyV0)x2s-M_XaR{`2DUM^oxr?RJ4t3?u6SZ#JdqH2JzD_;7x&ke8H=UcQREg2bOM`~ z3U#Kw`$t2^0S%N5K?UrO)SoRDqT0g2bUpnX`ck2tHOe~9mf2>DQriyB^y{R##B&p9R#S(3 zY+&ezJ-GuGjd(%uqj?02g*o*&fU+1OlEF_}VrXH2eEe=Gf(*VI8FOuHU;!9zQ^*kr zr6W<{jGgT~o>p&U8QdAr=#`BP>P<&GOvma`x1~^OUZ*3cut>;-KZG`C%@}B7G5E>_ z%Kd;#)LE=48zrFpnWsqKN_iAAv++)>iS3Q%$V^L4EttkL0m*>Ox3B7PqxQ10d@f*a zkNCY&_4>$P!PP~~@C5k3gSyK~w&V-3R5l+bxKf^s2o06ykM`0J*r_cb%C%xrXyjQx z!y)%EnYU{Nh8dS^EpS)D6o|IH@N|cQGjCsP>vP{_7NPDl0xIg5)-6RbxH8Z0siJsh zHk|ceZgClafZ&53P*x&XvqTXTmZDXCNRL*{F~3=lT_k^qG)GNZe`NPqTY`S(J7=?} zXI{etIZd-*9vkXps~pC>$b|>FDT=T517~;(E2Z)(n6y7Zr`c`!*~4#&Yfn`_TPcSG zKI0!hJZm_c3=aZzR}sl zmTJb66u)Dx*3^o?p_%27-)_M+f?iL;W9V<1r!R%wKmElGQ?lI$T1uk#erHU1%Yn6Q zSxlm!(1P@UEJmDjTd17j_`L>GniRmf&>Z=4Vmy+90(j%_afojhI~K|SftL~M{FDDd zaKsJ4PGKI*v4HeccmczdXd*jC#(`c`H5ooHVPeDfv4Qgs2t=$72<})}qnW&-`tNTXW=vm~xt?IOFT(_{%-L7#$~(l16->Y$Z)hNU`-cV-rP z@E3U8DqXT#3t|wy2&W#kzxgB*UYR6;P-tDlw`ix$H!J2qN)g5_=s#$6TD+!9=-Wj@ z@h6n#)fA1ve3jxv;TY%aqC!$#WdhL#rdV7q#T7J0h7eGKn@~?qmoyIzIe4dFS8OX z4S=;=cDIcOCn@R~AW4AI$T<8X-{Auk#4$*#cS>W`y|mgxulve^FH+JtdmEHPNS_Nu zx1ua@$KzYHKD8>!n)taDis3*?beJP%Cq{5KwNDCE!t|oR zlW$H*)X-M*egCpug8BG`@A&{}i1uWW6f2Z5qO&7y2}rVa&#Xj&KX#4ec?VVA`rP+f zkD5s;ZkQQ2+OI6gbG`aimCa;#spKRK1M5=R3z1@8Gnv+IZ4FH=c^Ma*$=o;MF%7b% z<`c|Y4li=dq{!=fdCr?z?xVzm|3{L=oSHI~i*UnqYuUaWZs&+R%Il$D<7{JwnOg^?74n}xc6H6G)HLn=|6sYEeO_c=_}ggwB{Dtetdq zJ0HpS1zmh1a<$MU(WY&XpE{m$R$mQzdkL=oLSe~RU3i?PO|OCd6oIZaXW|V2D1=HW zOWnM(yxF#pN;~g4>zBYSz!)n=+A^iiarN4LnyQx>E$&$clKHkkdF*^tX4#5V{%%zW zkLD@YP7$YMu|(Eu^*Wt@rDMbX0cahNd*SpKy-04m{sEAyvPs6NS2nb6)_@{i5fPl3 z(4+fuJWMehyFT0dwYJqXj=eEy`BWmHCrom+RkA;5L0KF}QVVtrqBPEv#`sU+{t4^6 zBk0}NLZw-GE}%r&1Pg)&7@66B>CooXPHso#+m`XACgqx2`AqAhhr1BO6 zdNLEnw~aiK!oXSU!(;QlF4{DO(98>CNUbsdw-Opbeu{+CpCHLALBqBMTGJuJLrJFL zfE6Mj+Mpj0TRK~MzOtk{Y%n%@s-CjuQl!;(yo7=;#TDzZm6=b<^+Ztd%*gzO@LW`) z`GG#W2y|5tx9I)}My2=H25ejA(RUd+aGz@Zw&L0WN+J`r;-cLdua*Y2>2$E@_dU3> z=+js^JMR4V(pG_aX8NFC-%mKTI~L;P#X1gR<$Ezp_|6+1{l)^v0USW`um(+sNFOVf z6I_Q80;pZ(-Y_A^nXBN*bceI!79pM(vnU^lNCoNF4aCwK}Cai8tS4eSIQ`S4F+jjZO9|(75a-iv4W47kCqHQN2V9! zE#y>aq0VAa>|a*_^~_4B(KawojZP5Jr2V>^&NOL?W&=8>JAE1LK5iN@bL5_E6p?3n zUe0A7?S)CkMc|jPRJ4c-2jGFnHBAXN4^ryn94Iw5P0#np1Wt)#*aJ3oDa<6=R~9#z z73sczO_VmgF}cVgg=LGNIqSqtJUnpX!6N@5otL%%VVjGX7Sd_RXP5@=zU6Fc|LBW{Lgm>C;KyL+TZXH z`rFN7+K`_#RZ)L%xr#EMd;_j8v)Ag=>l^e7To~h?t3n?~aI*1CM{;Z$$grv7hL*xL z&{tp9xG{{eDrbf7e|%=5)_!mlYk;cq!j7y&HYs!@u}N@tF3#A)tg&V|@c=^yyf2!E zZl=(jNDFEu=GoNWaAy}43$$YpD9@!rh*xBo$vhJ4srG{U7K=q-6T|_t-nB|$(sK!G z$zxtM7hskmEQh}}@rA%Z)JpU6k&Rm(7UW?oW5mnPhSQjj#=KCW`XAxvirQk^nbbFL z<6z>pA_6Nr#jN(Ok?}U~YF_+6Y1b-j)Dh5bAS3>A7nZ6$l?k9!I&3*0z5a^9je(pU zRATL6-d}TE{U&;E%Z;V7y{9-mt_NCU z=z(I76{IXJlS5qeQMeI%NS<2V#IJz&ZXOAiF6$Njgtj!I0l|!4?T~hUQ|Qbm?SLn# zVuOKDBi_ri(q%qgm8&J{`z*{@=RTvJGJ3oW#nVmq-)B;%bU!2CG(F3?w04x&1Inol z6_eOZ(VJT@+&NXSS?@{@%>lcc_;L@qwDx6}3^;yoQy$TVHhd6JGF4SNPJTSZ)4;~l zSmi}zJs`AL5FzGCkVSTbILv-Wlq#MPx%+aW3`VvP{9Eq%I;d{j$lz385U6AIZbCy7 z1O`H%C1Z89GV+;jrR$rUVlygU*y~gXJvJY~+}3koi7sS?^ZJ`btl&tDyCqQC5sQZ2 zFVdLUbp$Xe&5pRidLs%=u)-Bx%>AcbhgCe1;9tklyPMTl0tv5527%4?@${D>tGOPn z7T&?{#Z$D-W41Kh&s4TUem-bE^lG%3eI-|_W+BpKV$RZ|AJV~2j+^<*V2WSo?#V}c zG7p3niqIVlGhX-B*JwzXJW?lm*;e;>tPe|{Em<%%O&SMC3sgAL6Yd@QM|9*eY82yy z9by`u35v!H-CeoSer1V9&!q4;_Mnd~h5DSuqdDP%yXUdWCr{xFjCxUF=e=*mXwHChI)?@7W2| zGmT(eb0VuIJu|C-XqUBCrAjk#T?aeZF>=u#m(#gCTgh~;1t7Ak4L5mM*edkoEW2y>}({t-J0?*;b$ zI}i0nC2$I?Y2{8;rP5DV*hF$_4F@Ka0S{h8l4h}T?C*-Avy1I{PfGS7D6Z&%IM=+u zZ;2ngGqHd8?$2tN$w`~I%I65(7)5TxxhL4PyN$ABc1}7htouVVi17`%`EFE2nr5iWmtz zl>c>)vL|YswOxWVso$Ik(|yPbT?;`ey}X0j906t*+(iJW7U6<6a6X!Ehv#FE=gFIbYN5iwS-@PG^?`kuhDupP=z` zxkkmfB5u^O=ZG67gMgFiFf0Oi($i;Y4AD~;rJYT7!_68g^pgDmPdKj%SR8w4dCHc2 zl*hbi~|M9LJ+j>y7 z+30N;zP>6Csqx2wBlR-vRRGWjh>86b8sB|4T$CP9I=PclxrG=v?VBgL%Z@9&o4`C% zt4H03mp-8hR&PNf`fob1Gd2jmc9&HwDeB*-vt>_c_f7{_`Q9C3xTqg_L={mP&)K&gB zr!#K*F*v!@twQ4i;jFj7A+g_sfx_iKGtQydsER#KG567)EV(5tAI2~Wkt1;kwP|N2i7`Zck`LCdFIpjtrJewc7+6<7FAS0qw(LcVipjw8RuG*aMk)hsA(g9$(zAx z_jpirOv1ggavF$*XB}+IGRrO5_~WHOCJpDPRpV^B+|j_dotE*0C1|8%89(_RUyr^# zW2~DljprVCGJ~DNpGg6LTtGVWnX2qROliayjVVz+MPIe>9DBqI_@>vfeEHdF41j|> zU#IiCc4q4Eh~wU;vBVsOfnc4NMfMus^^ zJAZQ4`3PM#ocxI)XWGS%iHi#u{qP0BvKXXQ^6AO^;Kfp8cQFTvg764j4z~dI?GnUi z&H7BnMbW|q{7RfDThz8V{_&YZPr9eVT*#Cv!>RlLRYQ)CpF-LZ7eFDXo=v+Zaj_Ia zlLh_?6tg7Bzux$8woUY-)%$j{u_{i~*ZjW|H})5Cv*G?qH97TkB1&vZp~2p7MJB&^ z1Dv%)mb|ZlwUhlYd>gT`cmE~mT;H2frS8t+WWX-X<}~_N=5i!4Ct`gVgyo9QJ`2qa z|LI&{Fsd&*mbm-4<&buIqG|n4S=_(#Q(_MDD9)?4U@$7S?0C( zyp-b#(*Vd7$A0uA_D^safF?|d#_ZgHcxRdTxnTg1FMabkXIMg1XTq7Pt0}1iP|Nc~)D#rm^ruhjmMC8F>9T zZo6P$ib-NM zjX8lPK5dXE5g#hEWi&VZ$9Kw3JjOgL8}TiH7jPC;-O?r zYtQ2?Wqw+3KE=m9>&Lx=8t*IKVIOLnb5Srq-by*RkM*A_t1~4y*)}@gkGh39*ZBW$ z6m{O-8xlHpOV5xuJ$OmN=}H~nDg8t0v>^fbOQPSU5cg`Bfx1lypypJa8p!7|p1q&% zfG;Fh$nR_sd)fRkxPMWAS2K$I#=af71Rhei^3eHLl`SIx5J1Sqf(G}x+p*yMKbvV< zQKy-1;!#y5#{6fyz7h`=w`ExkQ8nE{4B`x$RhKbvCGe0vw}3gI;V6{3E9}g8*~_EX zIon0)eCHw&E+A_-y6Joj#5L<9wH=jy%|y z>GNyN_F6r%RggdKyB}>l?oPuH0X+9> z?z(ABTw8coRR%i`Wp9Ti=0C}F@{@myr}bgcFcwLIlUY~1n~rD8T*Dc69c5_Zs^|te z;Qe}v0;}aEe2C9x0sv$nsNVZY*dI109tk*5CZ1foih!Yk>4AOBp(4NSjEYs>agVdE zf#}KU4HSm-QAtm=IcmEAODlp$QSpqLw1iNWi^KB+sn63sT)U}&yaCbbNqM@_pYf^M zvw1hnkYnutTj<$4o#Ahnpa7E5!S;o&P^BqgsOOs|O8}vuZh2yQ zW&^1mUoWxEn1X0eveoX(fO>*(`z0K<8wB2bgnan*c=ycNZJg-cXV${0Rt0j<{1DwiambsV#zO~}!wz6kQAG^;KS^w6-L}ndIiA?+CfNLN{a9mP*xPxx%;uDq?Fz# zJZ{w;!j0#u-eShyT%g=%0p)d}F7!r_=Z5Pf`!kYgOzg1}2m^y%lbxLhkldXw(fE<& zA?Uh}J^@%rX6YusSEJ4HHhsm{{M`PKAu=s%Q6j769m>{(yg{jWLMF0w?G85Wq)a?C z)KmfE2mVsurh05tozlwg=vM+S-g<=3KkqY%+U>ml+zDY}P zF3rX3;BDh)>8zP{=>@2LR_TcPlHfR(kAf(RE6G{Qvl`x%Gp5k|WFT(i80yQr51|O< zQjk#|zY?aN_TF`wR;jeH-tE(ihG-=7&BwgZmhI0$?JdsOP-Ca>2QA3;=JOL1ise?h zY!^D`f)4daVr~fAQ9y7rK|XYh8b*gFy%BP`RI}v7llj_prKZk)mdO(w^jdZ z?j-n)eZdWII>?@|#*g?n6)7eQTzH|+6cmu1kp?yTRx|uCGNT^$3m0fuwAO&!H8SaqK zG-yUs6spiE^K4daKw@X7_#}ivereW2I*Zs|!-UMyp82a2z=nrS<*D=k@Ctz{_ifUp z(&?I}f2SAQqTMoRTp%lUx;+JpL|V2r01S5kLw=3P*m7DiVgMKX{fq?e_A@^6VW|BA z;#4jV_CP$2-BLCczh^DDX2kpZ3D@o)sqfS%|6U=aLRwK(jq?89iLy(@&Et$sM?aIm zeb?(o(<+Yc{+M7>U^moS%DVLIg@nb|D~y*hUYVX)rWppUKc_@$ zIYhtp^-hJ@$}#dxHj4F5clp-1e_>_kLKHeDhRt&}ymGrC9FrJ=NY4Ga>Vu{Ui!mmm ztBu_WCE1o&r5qEj&E9EpU2fc;MkKqQo&g3tWMS?9q+TqAfC07>00z@~h%zjK(}EH) zRNahlTQfnKP=b~vM+-21#=pHqnFsG>oNA6BO<_&>KWVos$^|c!6gLH*#tQIu%`mW8 zu(pp?YA-t(g`Rs24_baI@^9$I5KTdSPz?O%rJ&CXZ>|jeskBgm=^?6bxRJ1TLY7{> zbf($v=sT9c9lDq&)6nEjzyUB*VPgX-U=$qg78#AUQU-ARgBgn@f^P z)Smg>G9iXrd4UbwdX5-UP1aaI^{Z;2i)1a;Zc8ve@CwTFL8oG5UVPePFKEwgF?E@t zj$KBp;534$-w3d`N8rVSz-l7Z{0XHVW?aaCH9>Y(sA-imv#U8Hmc4Qj3HJq%soNX* z^y{wyg3y?P3ux5fErg8PzH6_5rC8o|eLb2w7{rs@kh3LRME7N|2V^gPIBocMUh&cw z>H>MPl}`)f*{4Al*S8K|#!OE1RSD%b`t3-y)cvMb89a97eu@eMyS@@{p2^V40CPZ$ zzw~NyQZ>0z-PT36+{}8J?cXw^^uHjE{PZ-*_sqW`?QLG{1YDt~&-9I4qiPfX3HIKc z?dtaw8AiZzsmYQ&K1rZG|02mKfCkUPiq>wEab|q~>UzH{rGGFainZN3k|JkkGVEp@ zm6|b7n7=8|ub9!@bec?7z)m-IW>)%*XHq(Q?&BU<@2%8axD*fvg;GVqAPbLpXbDE= z>SRHV`XSi3h*~k{^tX}@?<$+4KW#{arDd9TJ&aCZ;)3Gij2C7g>QtSj71A^PXn9X9 zt}wy#cAQ}@4IJ8IC!pP0Zpi|=qsP!8X(GfDnG0(}uumkaG?BOH-*8(eGU)KvGGdMj z8)-mrJ~gi~f3Vd5@mP{s6Alg-H-0?c8GhMEDP+%-0Md6NGXp_W-w!B1+?bMqOZYiS zR^QrLOcjODLyQ@h7C(8qg2$Z-r*gTN?h3LI<|W|Lt{}GzJDpv&L{OOE88+)JJITk- zNyQGtu`7x;#dY2-tIb~yq( z4i%gh;K*wo6w%-q$=vSmCeuO8eS5SKeQ0Lp2(kC2v4)(WE=bzwV}q|obR*rVahS`G z?1d{~vw6`BbUqV^P0Om#l-^oTG3&7T<48`Y0?lt;P}P@J{;vV}ywZNA&n%UCX2gpg z54Bzr2da6a)f@h9VNTq@o@wRj!U{R}jL2_87BqDG*(}eni%%g1*UXalTQwV@=<5uK zx}*g?5gB#AWgbIiLpw!CT1eSWGW(Y=^hlwRr}+5U%3qjQg;nkK&MU{S%2pJdBPguf zTNNEvLc1FY1ed6I-GD$PiTjENJL}`sZ?1S!`>sXg_9!WL5vk$ASXy?g zC3n%X3F*|C-fW@5yx()y@*#K|CIGO2iVHZ$E}ZmDckj<3Cuo_=(vb~ zZj3r>!&j}bd6$LE!N9z}i0aDdN{H}KWuFw5@sG(T<+n})4blf=%LYc<`@)>Ku0n7H zSk5d~50s4K?=a$k`re0+aSX-Y8C2$=|5;yR#@bAOa zP=2sz_bT`g@T0aVZ+~N$)j8&dG<@%p(%|5qP6MzN>5Ev8d7n|E249e`8#-u-L#ue` z)K2@+p%dMsfR?kCO|edSPucoHts-#riI0p2^hE1RnjSnU3B`iAOJ``I3;SFb$d6(I z=Y%cBNhEEI$+))_znv6T$Lq)tY9={0O6}u}j=5TcW|2*{l}|~&+KRz);J6(IPt2!R z5oCO*Ncr5W9B^HV9r$RtgWP68j~&G)c2BQmh6d92icuhM^tG?E%9ADmQiw-JH|9sS zQJ}i7Hmc|O@XQ=RYq%_Kt5?C1JG=4i_5SUf7^rbR%fU%-98V>RJXKluSlW5eNn1 z48>7(0t#5cI5Lz>GX9r~{8)SZQ0GAz!4};oqM+=&%yBg~=U_(#uHQY$uy|cy>a_m{ zQ|rkr?6KkyYm&`)UXFr08ZXgtpN$}!PDSOBkLB5sj5yd*Yo)$Bhmn zmk18#Hpr7s!gaa-@3@3|2RDyoea4~`LK3l9iSvAUi6X1r(<*IzDLNrn|C+n*jgL?+WIM0^ZIh-HIB|n ztq#(gKz0d{qi$-ef~oh=$ZTtf14*l7=+*Tm6HH0T`P4QLJ;NL5h{X~Bu<19Z~K(@v>&}wLa+r8A2+$4PSDw;sNueh)qvnXC4n^ZshEAb7F~Ji-?d6! zSu5(PEu-p>fP=?NMq{W>#>Tx?XnsigEXf}NJ;4?nb^jaJ%?Nv<>JH7sG1z(HNv?w= z;yUCY4lrbu4A;vGCdCA{li(J4%mg(`?ygux9{rfX0DQ4>y-H=l!Ao{=mL+IhEB=VfwWtR2d6AeV8ojQlb=Ij-tTuk`!b`5orbI&ZNz!J-iquDzcjNn>D#G6DW zup5;txuz8%{LfPPGjm>6vp9uR4g#2t_1h+#NGt4tVJrZyk@?LmAanB zAmNNVU%wc<_s1W*mq_siL+BU6qf(_VKK(nh(Hb$-nuHKfmYO44!+n+SxzVv>$de38 zaAFKhnQj^&oitnd8?vVw}uNgz@(1`Z^ow=q@J#g_-=V}PrL#No+7K?I;l?~3K)B(0e7b>lJD zu%1IAjW0SzI4IIA= z?cIKih zAv4?J*Rm?WDWaFcssi-c4JoPt!@TRe&ESYr^Sn{A16f{|P*E{{M`SekSczyzxS4Db z>xYrnq;D!R9=SbQK!jw`%24gCq53BvqW$jat5&}Q1V}(_^kok zkb|WbpNCM+V-sS6hi)&o=m;8l(puZ-CgtL~L3H~XsH9@x^mn?+79@Bia-JZB%Kd36P~EVMo7rd_>Cm@5kTub<7~8NcOCCNA5wnds}dV zAS~Y)#+L-!1lBlN20>FWl|0dM5M4`3F8?izjQRLXe6fn7JQu{@g}X)V=(JAPztAE*3>vbDvnQPtBbm}V8U&sXU*8(}BWp9>9=84`fD^#0HS zV?7=e?&ZVe+$@Z5gHoDf*V4*fd0CT#uh!A)S&7tE%6BhQ5&V&!?Y)e-PsaMN33bdv zh9Ny5?3V7&u9ap6$x`+<8mAKy9Yc5?Zl9dNRX|HjdP=bPmr7Y|_`sQrlBJbzA#rc= z#36`~6Op6VrG|bV6Rwsp53kbKt5Z?9igeVjK*5Q{iO$Dc_-H{|2~OA$*K779M#>Tp zVWXtPQolHsUaGWr(U40U`pZBhLV0%hO+@bB?a@M3qHP)=@Ej3v{E64OMo9h(pUyhg z30)ZHBt6FLKW!?Ut=xo0d-$-j(Y&= z5BEsIsN5I#>q`)aEod?=S)-G_D}o3dP!T->!otm%I-yUbbm-E?<-NW9f)j`Wdj-fR z+1e#P`IhoSN@%7#qprrMQy}xSi)IlUmt5+;4_xeS#3KVu1QT<6y(&OtClWLQ&Fs>V zUt_k%q2SR&=HQ@1-L_x~m-1Nat1RU2?bU9pFIEeCVj$_qHO412oRYW8OYcXa=}R1s zlWCFahuIx?yZAr~XXC{F29|2l|02Qo#Y(p-2Jd<(O}96mSYji)G3C)oRrLFnucdh+ z_`7~wcGitS{=Kv@gC6lYdM0aJ>}ci+u@Qo6$Yf2_D7h13s6cn#AEq7S)EW4bezB6$f)N)E;Q=sDb-#tnoRyKi8@b{C6+cV387Ow~4?00&_ zuOLyf&f2m>;Fd7>g#M}DgtO;AqZR&K4r}cV2cltDk5!14nv$|Zz5vpS!cJt;RE~jN z0KA@P3DI!88hIIHn9fluPNZVLRH~*uUV4aj{EP7n;2QNna(-!?lGkVO8i4-Bd~~tF zG{q<}b=|QN;VuJ(WlW8L?w04s!TtxR;vP7+(&8ktuJ_)OUX1>BL;3EYUM(1bsdg*T zUm420yxYSVuhk+bj0Qg!24L1+V9@^K;^D-0hByUA0T7ListDh*?<%>J@hn0;r^Osc z>_tmMCx|`{-B||D0_~!&J#_0szi_P0kJTIU9bTdsO zty=z)mzS^s2kwRT%1&XmiIS+Cphf0EF`>La*-}uR-9J%lcFq5ELmMoc6-*sO#QKe& ztarP#m9Gf*k-Ktk^+e_Zy4Y_LwlwBtWVAPVp zMsCk_ZRjBbOe+QFkL`NXit+nFUp~KKHOQN|nY5ahfSBAATV+}`{mW;&yvB(fS7R}E z!h;|-qtTc+ef*pwhI@B7+eodg$maY7#Hd8LM7z?COM4&x5pmS@7Jx+_Yk|8ClFY=c zxrg4c__xk)O zlMoV88ck0U`H=GP=Z{%pn4!Qf_ zR*E1hF|DR8C3F0H)Z6`Kp^GA$WT53kKp32K$}{axE)-@dE&rdC>ll84^gJ*pxs_?(n z4Tx%N62BO{+NN>EtYYBxFdCC*HNnJ-?K_^+4UoBhS;p-;_Ho5d$6{qe!BkS-=fJJ{ z_jslC4c?aFPpprSUXEGoVGO(2o1~bLk#auM4GLv$WOHU9b+G8iaqf1s4!BOc^$yNh5pDM_kB3hxtFxJt zG93p;?@FvOnj&}NAi?{^Kne;lExQoHxZ2im^GLFV#xtrjq;@AcS)7{f-@aC z2$XGL4B1$yl;^z*VWY6?M=E_+_gN^w4+;11>eMYIi&UJP+-WQQ%A?I;Zl4DS7Fma5UImT0W&F=Lfz+ z$-(WZa7$fz_-ek{qFg|mCu%A-IT6_6V7-u~X%pE*#xl9!i%ssosDcL|l`E2Pj-s2- z)66&{zQ*w)=^0?9yMQFr!{KG(5=P6+2x;b*2xJT{kj;1>ggiN3hx#BTkOr*6hB`W178U%zcLPO4YM9yp_+fRF$Hi&eZmF7=^aixfXS28FskDp_f+2;YK|IW zFcnhB?$>yZ$R2BWJE(~}GZ+__w@+Q`JFzPLd1sd_q6%H$ow;$NJJ7HeQrw*u?BE-o zOECd19FRBBFyl0xl=75Br?pVJWMx@(E7ZTOE<-p;nL% zvM1_mY#R7c8{17|w0-CMJRW={RJe726ABDOt0c_&J4ha54}JC48V8m`Mg>%hF`#3| z0iexKx&IyMG|W^B))ohvE`rJ4^nCt@IcR}i!ear|*kg_wwq^D@gDhOWQ6hv8zENKh zBSuoB)*QL_8BNL%)j(nJ^0H&egT4QPjE;4RuPE{8x2p>tRb`SLCeOUpUur;Lv6pq& zA(K5{9&U!u+!u3|Bv2^O6{mk`w6HZEYT=xf>HvT}#Vpip#=pAsKQrcQ#LcpD63M zKiSZj!Z=3~+CjjVYi{n}-9!C^@S#=w{7mnVC-`W-<2HLP^`gPG$Efa%fb zWz|(T`Zf6u??RpQ$mCibg#Drq0ufYF&Q;Ev-r9x*mRLgce(MZF4B?;pK7tYmzC1vX za5AU>UGJVU1>qVQMKB$*MeUQC%qRiAqDuPcfCCbdN#W+k$jeQsg}iBZFlV)e_`_Q= z&Hq^OWZ#5FYirdY3Yzr9{M`LO8bo+M7S}sIWiSxEKISB@3_!!kKe_4gbXJw`W*qBdTX$8!dk6OUc5W1$H8(PqeE&zH{OVx31q?Iu=MGG(bKMD0xi}enAi;CV+!=$x%Msj~m06HT@oDJ@awEzQoXpxB&>`4O15SnL{od$whge#L^4Zj0Du zVhT^(WSGsn4uKX(oV?gK5nVs}fb_f=>n_BAknLZSTunW$nhtI+;M_<|`cok^_ODHk zif$*inNn_)K0S)%>xuQEC`f`08Eu$4E(3G+lIf@lYRu2OF$kT&HqmCZ5t4@d6RFQ} zjC_3*BVCv&ePA9G*QA?9*serO-&uRt7ttQZM#rh%WW~opxbR^ovuti4YMiM=)R@6L zOabBY(vV zJ1(h&Et>!>gdfbWbEe{wv{>7_R7tOT978cKpTO{H!4B5tA-U0*bS47vzH{AW`Fm?EnAE;;bmcJTg zPQ@bG4JNpCZVExgI{8Y4-j%j+s`p)$9_=8&F4Y&h^NH}+mv5Fy+U)XqLnw+ zD-$M>!05(ncp@!NKyk#R(?OsXbAhr(&eOZMyKhpaN{NSoV1ghD|I5WGKVRa%%(IU6 zC%NzXc3otDoSPK?=J<94Q@-v9Gh1XEvkHKzpsE;MnNpY&JIYM@N}OotOC^rsef+m- zN;=rq))I%a9ls99+p~B6`1PI&XKyMj)^R}i$b$~UG@|)3JSwj4a&^ug2kc`=qBW3C z(nVYVC;OqMqv}yM5IDI3PamHpfh6hI3Q2|` zXp{3L;zrJBp*Gt_kC}TWoW*M2&absM7~$pyJA2GLF@wJ2+0Qc)asAL`0-MvLM^~Wg zV=xwJzpTOsbLb_3B z*2cX9*L+RU`&odjhX1mDDe=zn7Q{nq=WcQIq^>pZ!zuZBr6lbZCpm<&n~sPP9Y!e$ zCezECU>vGNiCt1tO>WYX!P6avWW+f)_v&TlS{Z}dm$N(v$6?N|03KL+SvOlN{YGfi|Xh$EGX7)j|P>srqQ4-GoChY8h=aAiyXeQERYOLgt#DyPuij@Ujt@ zYIv9W$J4h~Aek^`4}({$v^sYrn`?KGtZyk>4kqe75lUHFBADv`58Qm^LO!a`LnN{6 zf1+m%;D>%NQao%FIks(VT|Z!g+*_#&=2RZGr5n;ld$uLQcnhnjEdLG1-{a3S&fACT zvF`9s-aAWIF}-Q_YV1f|SNncb7(F;3m4Dk;pzMq{mQx;@3*OIMWq4G_6iP~k|7sxi zN#5fEc2eC+U3z`a9Yp#n*Q(o)zF3v58VPM)3`z#!obCj3Yo~0Gx{xee^H8c0lcB{5 za;YeG>RFtddQuoHy68`Kdvg3k$^QlZ1@M03j^HS9IpPdJ)syfH+j`lt z11c!&p{9%w-VGm-+q&l}B&=9(_DLYsG@@+?n zVRI>Q`%X8o2iZU~R$9SqINQD+{Huf5it7w__|sRLGkwL5O!kOha#n}dJ>z6Fzyjs$RJhHn?zBHEgkeHPeiWAp89r_ zlX;T)kn)@9CgB<^8ijUD5R(=9|6$MGz!mDNTreRW*!&hHgGTc7#KjsJRLioX@G6ie zSqrc9rW;T`;@Y-^aL()GOD4&O|QpYX>FDpQ}E@y)(@i*lk{ep49HX5ISk1;Kn zE3XVOw}rLDWf)fGOryuZK8=H+Kr-aQiM4aa&aK}h@;m$$0hx4;ApeTCf4;}z5Ht_A zB$_1c1=Z;OorQOD>cvYL>EGOcvN9~s~UhKuOokS}%Ha&na z!sOAo(J2~!_)`%>cN`Ov*$TF0t8QK-5@%xP1w&o@^XP=jbq&L@B!T8&QTzHGQ|iUq ztfk1Q%(RynUVGvkUB)sm9#B(dkClHFrfu=aq~LNs^|-hG{Y^`ex^jR!xRCuJ7buKf zx%X2qf$jI&vV_Y;po(iH5PvOg&;gqZcZkmDf6Lfe&ku|E?lOnl^L7M0@m=sa`V3lq0K9^e zKklCrH&hPf8r4tcr-nh#CXysnHtNlvS8x=l#zFlxq#5#_Ff-G*s4&T4D`zu zp+YcYh}GX#;ognh7EEUq(FGF`yR=MLW4x-&XXp+rgIUa_L1Ci6a~jy5(I4_cr0cWQ z%AY}0{*aEuWz$I7ppWEl4t<}w7(iL|+Gm4Jzn>|4K_k@()wEX^$&&kpW9m9i6DI!r zE5mDQL2)qm@)bbU@m6PsN|XUpE~o2zrdK~bhpI!gLnEy4Ls&8!V|mtJuiwiDm{)S& zU3gono3qjtSm`8scbI-EO{zjZh&q0n>00bRzet0bN7{*>Ogg6bQO&Cr<+6p8RC$9Cqs*LweqPQf6%&K%P@;g|t9FSga9>wMd&_`vr$`fv zAh95UwRiDoe*zO3#ibJ53R&Ph&~`f{XZ}51F&jHMJ2b{fhtLpO_J4>adekN~z9`=j z94RkkyB(K-tEgkuX2+n3NBB?kh-Z|G=YGnXgQVleL28ytX#L)b+m;8-8))ujAjSOo z&7kB=M4JhvG*L}NMTqnPA=gvXYL%cWjXQ&Q>LcQ~d4pZ_{s76OH(b9yixWkZt_2PM zmM{;I!}tryNL&j+*}aY>4j^Yq)6WwJxoW4b+Fu#e&UNPvnh4N_RL{t<)=J|il8_K2 z5EMd9PysJreFpTkS@#kTnN~z{1%~MdT*^+WG@MRu$UZqQV{KDd)iW&p;2?5O^& z@zPU?rGv^Zf+&05apugI1r1iN-_)pFGc*7b=y14Ud7uZzRmr`XIE%=956-8N0mU}q zN?*}-+5}PI8|>DA)5JK}K%|gAqs+)BDR&yfB{wW+qm2|WX3)~`PcdTsB3njmlN!OS zx^$eka8_vD2~RwrcjEWg)HS2?m|yJ|TgVD)LW-ZF13rsN9mdi&T$boIxNUZwecAd= zP|TEuoU8JO?O6RsvB3atyLfo!NRHG15(-lpe1SZzv;V|Z<#)4ruP2h`{M$TR#~JH% zyG7NY>YID3gI3J1#-O}^nHA~qW^qT6uKM4}Yalq|a%#4LqSgSl_FAD+cR~~v8!Gs+ z9|Ml{sLC$z$r>U6x-x8zK45agTlY*>J*EdgW^4C)l$O>OP% zd`=o$7`bS_kL{S-guQ^O$=$H2PDEunP2Y|V0ng8fOD6gz3Im}b&s+d}5v)$fAQM4& zbhk;23%M=QOK(2aJ8ThTNv)o2}4MJKxM2^i?W}13jds84Ij*|DO?5=12uciUU5Fk$!m^wkXgWt&r86T@x8kMgo3~KVX&=&#;n8K*v zvcowSOQu8*+QkCw12{b+$#h04e?RLfC`wN-T*!F;*2GVBs}L0pD9%iM@A!dQHDBZ- z8`6le(KiSv1YFu&(7r&2on20p#ydP%BIJCUF(GD`U%P#kufk!wAD>{8U)T(* zp>C|}7WBVno9Q)m=QE){c6~zH%KS63w%_d;Qr0c+Rmb16)k4^1r&O1}V59r^WhTej z3@FXY*}tFaalN`UWU54){L>`Wxn<)gwkKe?Ds<|ZFK$I!!bHupbMOa)m_B+7* zTJq^;)tPN>Hax}S4qdefjrVvQ&~0B7Y zy$r>fZ^Lfx@AoS7O`0uczvZ#hf_S$dM2C3hj_b`?CAyIYEy!il2_9X+>*Z)hF`B6`>j_=2)0*H7syvI^>N(IVCnS9G_Bl{d zOE5w_eWRvr#NeJ`f_$sMNX|9_FjMS_{Q^3cST`}_8xJhm^=CuS5?bCeGak9p)DsAS zF&w>$e+e|}7=is?mGMKp7{T!rJepO$GcdC7t!YxahC9KoRiQ}+M#QBz zj51qk7=6b>Y4>BeqJ28#)L-iYLQPhxE~t>YNPmlY5p1p6)sqkx>dJ2>Luc*E zRM&TtVPUQAsMSXFGVkT|=^J`>-!#@tq%~kwcqo>rpFo!`-m^~IH2WUlLqzMjj_KVn=_5T=D`2&P7f>bV}h+_T*U8pz4k5OF9gi-9LN+)R6*f+qGRo~hy< z`~bq}c~J$+s6!NP?;hL0v?2>?yE(?=y`?!Q^V)?gD729)+G@8y9W|BET6Qub#uhi& zQJE8;PbKfGD&6L&*_pa{nFCI!5aC(9`FjIJ1xA44n=2YZV*Lh~1e|gn)!57x2@mqL zG8!hryXO`Gr@rkPn;DZ>`PEt+4oe@g|Y$|3JikX@@ z5J|2!ZG(eUahECllCR7T5t=KPY$X&9{0Vxms$$B`JS0PHAYf;N3tEEEmnrw5n0yUO z{z*7rJUsozrWl)Ru$X8?*^xkQJ6XO;Q4{U( zp4^;OBb^{K3qG4ApN&D%@*uW2Xfy3Hi~myRVw9Y|DC$)jPSU>b%wXb)*+Xx9_Am$2-tx z4Nc@B09-(?n^{LH)2L3f3*znq*M#CWSTFFJ&Gs?yTAhvD$(L1?Urh?o3MOuf#tDB! z8*(>uM|m~Z@&t$vZdX;Cw}nN$sXmK$_H4QMN@yF{I;q@I3Jb!8ed-pVJVXtA_&38> z7HkCXh?yMklq7m^R&!#|JzI@IqCH^@T$h6~El2-_MJBmFkdsq9W;*O=D5n2eUG51v zh@Sd^-9+o%JB}-6H;0BIcYBp+6i&sOrIDAV6ClAUKib;`#db(jGAGk6ji=JBQOq1H zQPg_!4Xaly#4?3!PH3~NBYqo2y)>k6pS(l=?O-Jc4I+vR8|wIb*YlWUL~5Adhc;M@ z_yjagfXGrA7T~N48fSWCXU;L02sR*R9F|$WMmDYH#&8`@S2~Fx=~jFvY~*rXfeR74 z3ZyIFaO};>HUMR_UvyVG%V>*s!4wHsfXT?&P@yZwH(FLnOB!^N<$fXWNbwU3J`#!3 zc-|62L`JU-$~o7X$(BeKHP@;Ch{jpwGSQ{x(I?l?`uvYaMUt3L(1>zd=QCP^TZ0mg zCkjwOef1kINkDo$l8J?1N7#3JkmW-}&An9AKDn7{aHxernv5iA@D~7DG1~-?{`x4L zNxG80j~}0@#W0FAH1(;N_g~H-^TN;DKA2~C{R3zoAWg2Ih>IL_M^{q}ytU%aihS- zckWOjd5^QqFm`I?@RWcXlIZItFE#~&*aAhP_LrmeKbUkz*Qfp$(RkV$_W3FTR$aPF zOP^snJx~YN?s(JratNCmfrZ%~l%fT-I87DkdGu1t@T(KY2l>iq?25kwB&1JXB+u?etG}M9JW-%k*6*e@I@KdB$to`O-~x@4vGh2yVuU_f~Xpvt|BXJkZY-k~WJj(mLtSfefqY!tyN~voqQCpo@j@(}u*p90Z)hD}47-L=ICP zGx)p{cN-Q+Z|<_&I;_Tkq>{z{zf7_*>0<|Fu`Hq1M-Q$}e?lhHK{%<1F1@RC)!Vi> zZTi<`&5uCn&Dm(nQ_`vO8^f1dhKiraIl31iSv7d)4GbZe__UQcK)0n5b>`n5U48h% zi3-6@nVH2`lHUd(&#HDJ12Cipndd0uoR8G8#E)?k*p-WHy^ z#)If~qL#K>+?NI3(&XuQu=GyNi9C^PQrJ{+c6o`~#u%pWCmNGnMh@}iiMzPf{k6X0 zB={>vLPv*IbF#faD6%KQ=hH|o7+FjJsW)F2M>o}g3qHmjUWog0e>lzub}TYtC5@t{d&n_(#=YQPLu4$Pe{U#Km>ke6o8#p{|B z)t~X*Yb|h~_U0$oVFN2w)Wi7rSD1?Y)E+V}9}COgJECL)IfjUZWx*wo3Bvh^_uQs^ z!^&sGl;DvW{}((w@<}HQ|2PO4Z(t^^WDhWSXRPxCE>vC1luXRB(+r~uf@KZ8@gy%Q z8}qm*ExIh;b0BR!;m3M{WZ|wrrG%^Z5+5 zAw5cw60_6@LPnjTl}XFDTO+o-dN`Yn7gXUYdhJElVAxu5u{`+n>B)1 zJwd{AVW?v#^e$m&e{Y1Q!$%?1Cs@YcXStMjAN^hMEj8^bdtyyHd&q{F_P*nZB3?IN zmI-rl{U4d>TMaD2WIvKuQ&sBUlgBG?$G#vl+HSP|3+(^{c2mZR)Th~zxEg10+#1PO zFJfs)QMtzVk9juVD$C;hoB04B_5p|+JF{WDX^5K0Qjrg# znkd6{u*evk1E$U?H9T8X&cO6(qRlS&l-#%M_(wyLB@W8FS8B;jh1^}Dh%JeChxanQ zFlocC9=PKyhZtT(lf-LTsK7rEuGHv5rZRg$k`;R;cjdSRX(TgNRYK@MgZI6dp+xgS zB?efQ zGXcN(x$huBbjb!&i6n}02xWyK^K8RG&7DRPsT{SAMZL4} z#OuwtYz-U%z1-TWJ0xj0<*HRN0HsI4D^U=UVR*6%wR!!94jur6zBhvKUSoF#y;tl5 zdie6C9M!T|kGqb9!F|VX%1zZ)39nrLE7Cm`>%sWzui-&R`{s`w4o0BrR7?f&nA#E} zkir#t7(nN~P+jtnzf{dQCc&d-OJm*CR+n%7Si-lwAeKuy)v)w!lI6vNr$GA>ydHjc z2#~)?D)Ypnt0)hi+@=ROGfUVVtiO$(Gq-&1V|JuLSVgpg(VwdVn>vVhM*Qs(^n0P+ z2kT-Nd+pi1T6C5L4p?E!Erqt#5)0d%>U4s=lqX-qBBpDrqQN!Bx_{{)!)Gl9961L7 zal?ipdK=hB{vdULU_i!kW`piq+!NtqdgjQ<5h;&quogj}GhN*i#eSRZ;%*yX6{6JT z`}LT5kP8Z4919#4oo0L~+H#Xxm}39oZ3iueHE>3hPi zXBgSKog1zg*iWyMCent-J4sG=`5b@#+R1<}MN_)2KU^ByGmpgARw=yyYiZBxg~IT8 zztT$kAT-}vbZ_C-nI&4hD&MT>xr75`{hCqKZr(~JHMCA^vqMqH*yT%ygmd@cC`AXN zARAYR$RJ&@4IV?HA={1EwWj2_sZmDiNg8yb@|E~R(rayRIaQCS*V1)55QI{w_)aPz zs>v=t(|GqRLZJoNYsk4Ka~W_H6-u8pw~(0mSp&WVNb_MGF<-d`WMICMkw5|wnsKT{ zR!^~bSO*eYTxh3Ji*pzFS)RgfWTs+-$1F!`gof!x@s(mDjfp_@Ael`CWpD4=K}=}h zj|>nWJLIY}OvdsiiNz^t{0kCZ-L5GqwsAl5fveHaxk3dGj@sCyUBU$hEt%Y-al^^o z%Y4JiJ;5P=K(i>yS;@mc1+_KEv_^m%urChrk*PS?6-nFq)S3E%YqW^JF5+I$PkY6+@ajh{iguOqO?Jmk}kg!Vu9h|WyEBnq0d{yyhNeGavnbH4%IU6No zTf;h-$b&Z~5NvAn^#Q_~4{J2(Lki)@W@+JZlip{p@!fjJDZ#QtZ&p&zn8O!4dW|Zv zbPW>=l_#Ya9JtG=b6lJBYA-)3n*gInsB}BKcH6i-V=3grZrbzcOe`y^Z$>OI;iKhL zgj?HE5ZDWQ;RzXQRywgw!`MlK-Bi$dc`|&D-)645LjB|NIxSQ17~s+cuAFAOUv;B# zOuqz&B$<^d_^P63f+E#0s>K4JNvfXl*eOT&W$Uw9yZALzjNQ|cD9VBa(6(*cwr$(CZQHhO+qP}nHg@ZtADD>wgnFvT zippH>F*0NMbLA9qbG<8tnZPNByh6$Y32Z#(3r!gFyHVLWYxR7W^Ljt$TCwA}HB)f7 zgCfvcB&$)Nl*4Gog?CXA+iKAzu|Gy$yY`S?qkO8IYeqo?6u$HdU7w-)ANd1(!rYZK zsn(KtJAooTzUd|p$w$N z1eI&QC=&Og#dB+&lu(QZ99n(`?bWAo7f{^RbFI9cJJ>C9r=MFMjw{p>5UBXQT|!EB zHF!rav9QDo7ow?&bTq`K;;{pEgNQo2vQtDJTb+tD_9scka_++&o2jk#HonJbbN&3* z3&dqlIm0PiJ-&?RU6h(TAxSBfG_g&d-y^ob)r1R$3;Iu$eH>PZgS9jOsf1=IgEHmPv?0BdYo z-0tB;bMP)C+4aNUCheW{roL<=q?j2jFjBx#qJ3e|8@R`4ni-MW4>u^_j*q?ZHfxV{ zAUw<=UeSmFY9z7*11;k|SEkI?e$Pn;Jy-kk--M>)RCg(>A>u$h+i;j5j#Qb`mFFN= zUr{9ToHP{LrB*l`=>#G}%G6v`I(DbM*XiOh=nK3jBx}{3FJVI*hdq?}2=H18pQ5c9 znI;yliu$l%?w13sU)gC-S>d-6-V8*H9ML6Mb7q(uVNz1+eZKrdjC8Fa=J8%NWw(R(UTZ1bv!5 z$&&4cG$<){)*y(Vz20ZWs?fjVN|;coYiv4ebnBFas^(cnT>?)i-yKnRlQS4(asS}g zxj%rlE9*wb2sbB`AJoumUwxJ(jFGF6KUW?bt1L*QAo&a(S6_`|MGk^61`<}2bUeqI zC)_B?ek?E9Bji6GFf;Z;5l+`ke8KU^)ZtM`+(%|CxLD8jWftA(9^2>@z*=AbWq#-1 zY2>&riZn=~G8Oj5F=Xb=bES71B>?#o;t}#bW8^dkmj^9qhsN90{b4f<-qwQEQkS~Z z4Fj0vhn`^(;od8wV_CF>TD$Fmv&?!d93TPJ=6L)m4jV2`w}{J)ULrwvSJvnFY+UAn zOGxU_*gv4=b(@17qWmVQd%6+vi$XvM&U2IKU$Ie`p1{k9wM`;qL&mkP$(XNa9;pe! z{SX06py@gDF-)AQ2gr{lYMQ}a@w;(L_Z(m<+DCf2nEJ8p)NgGO7cKp7X}ukXs4Tm66LHo-V+K063_DcQ5a`oGR@*gFz~ItT5Nij}oh5ev z-Baj<&ZhCjgXE_eY-TW_ehO)QebC@Cx~Q7Fh90Nc@?_-Ysw-lHi}LX-V0e?S)WpF^ z$t{D^-JAaBpqdkV1(IvQSEDH|4gD>$;m@X3Wu|Ir{IEja4O}c!FCqU)55CXVmj$<+~}c~2@P@gqFihjw~22_^X*#23-I|V8K-#O%P)wuCd`E zfjp@M4KQ$9Y5_SbNYlX+%i{>Oqp}Ni?CAAm8C{zsD)1md%qD9kcObNiv&CluCt*XF%%)0?R;jav`U_vM&ZwY3G<{P{+;m)Yhp;jWlH*7rD18p z2*x19@NeqQ7(ekSoH}S?ftU5$?XUe5nQgQ)z-H=qauSUG^ zpfs>h21+)K4Tb^$ZqJ`uF2M>FaS&EhGu5W0=dIj5?2jG6oXZxo0M}ZU&EyWXATTxBD+gdxSUid_muoVHK*!Tn5O zCXcVqAlL`Va+~hsfuApLq5E-!M`g_uzeXDkDB|fqJyFI6AR^V7Eyd;RaoAYlJ_d@K z;8{%$v(wQcXZY&@iXQHtZNOb9e)+^Pb4a))C}s(EAB;3;1QQ!;#7^qpZcI8iwiFIp zT08AjJBxlNp?{zv0atlma?qI4ChOmIxub+QK0`4Dh?FQF;%9?zzu7ZEJ>2B_&gfT{ zu;U2c+G#Yd{m%eg>o1z}$f4bBnt;3%||h{!XCQ$s54_XTP}<;6hr^aZE6; z%UeAW+>LXhm1Z97FBb0*Bs@||P-l^$@Q~K3auD9GkDM1=uI%gn^10e73Ar+odj8^K zN`H)}U@WkgW_7P&K}mdpeyUw`aB9B)-2@r;*uR_>Pr;)|>;BAUg;9u8I z{OY^a^!az(4Zboo+gCF1B{R7cE+&b26l!AEmg-M2z4|O#7Qw&x>P=w}gI4J%cjGY) zR{}e|zHo^SlYa|2Cc*8Y^IZ~xxA8;>co4e1JbqZQrKl{RlMr(Gy;CWCHd7Y@1Vrqp zKl_lI0z@`gVP!7B!?bs?_w(777hX#U@SsV#k$0OMXk7#ei_HRvuX2?4)H=oKU`(g{ z1cn1P$Y-(RxQW?>EY+!4_RmaL)OPLw;Vv+=A|RVaY_+4?ZQD2xPW(|h;#QPDuqP*W znII}d!J?bY%eDY~k|+LxdRf-0E=F7l13?bT(kHs7(8!s9Q2vEKiqC}ibBvW3ybs5* z{_3-&>gltp*(JK%18=Fnb&-HT{`bxCdEszwa?UYXLK9xj;2F0yYr0>m&5J@(9eZ6W zTbZXzOxM@!YHBrB=;+ZV^vsBGJcndK&xRpmuS;$Tx-S?wJ?iK-6%^V8+cjwF& z43Tm2#781*vxr}?&~0oM^+FFR2D$51DonT!t_03f-u^ebkV8_8ttu7ylBqrv(=@73 zrG_u2DF?>`zBg#k-g7gmVpi6W#c6=P&Hq};y*8j&b!_~y9?vL*awa6PR8IjGAxAvK z1SeNkLHEt=i2oT(Re{58=RMhaFF$A!(V5r{2o0@IsI{5SQjT?7V5H(XSGMaTkGS13>wD)*Gu=_aK^HK03 z@=3j-rxKBfFJn%_-qN1Jw!YrnlvdHhysTzTPb@!#Xa-J1Qupi>hV^-ihm6Cb^R^9@ z_L*7PnH0?337e8`3dOj=Tt z9wm&}5$?=p5pIeCq2ONe7hjM&L4&3`_RgjE_4!;DmB(vRv0FbNN50^W$-sg_xdS)C z+Mpa;qq6#=z*biVAW8(l)z$d7Hs1;|mkTL${fG5cGmM5!$9m=Ibn1SCOp3TFx@gsn zp5uKk&#ny_xsgyLw})F9@*1>g^9>;W!dUZ4>p^vkbge(K|`}A3#Nc8Tl1<52b)(J~cIUb&R8N z;wmne8hvvN7aK`cx&|1QlOEsGv*kJa~zW5H(fIQg3&pq9!P z53B5m_%qKATwLpLC)F_^%^Lgj9JewJ2wqKaVw-jlP(QohA9_sdt@|H$&H~uo0kwc) z!OPsSETEbC9K-^#xMpg9eE4Ze7y!|JD~8mDrA!`Y9UsHTH=O}aXVW}}7#0(nX3MyZ z`PHB8yZbK`60@vZbVpJf{PN{AKoF4(4t6arr7`i-(abr(w25Nbl5u0@a#hzuAll_j zSn#U!>Eum)Q=_d|UMoDZLj!q`Hn}&Hmn~NoM_q`65|48C+$Z^?cj?T_l&?cNAOqYU zro~n*JQTCH(1(mGbLrrKTi;Unqt~jZ`~%w6k9&TEJ)}xze8)O2S23rO+C#*6rK860 zMKv^RKW&m?jfpK^-nwC1@s?W1X$+`%0N1#Z7H60N9SD71e11TR5t_RlEU1|8LE3%R zPb?MJ+;=6>*wrHP4U(+QdkKv1LmZq?N?C)H&~I%Q+`y?+JJE5GRm{q}j_mqoEhb-Z zsv&}*J(PxxQZI&$>76C1h~`555kQONTzd-?YAx4^_Py{DYgr*$R>z-*YBx@H$3yRs zmn}#g*nD^Xl<^zkS5#bZ^3uoRlh?O^3<#(Tn5CUz=pgBR0xUi^D%LC{izlD8o?&`< zseGQ!>`(KW1#>Vu81MHCIOnT?=#@;}M6CcJeW$E6U!W2AaHgV^gfd;v;k1k;a;OdN z>HII~Rw!$X*et_ZVOax2Q|HaJ34sXVD06*40P8NjPA=f3YbtewT?aTu(t|{+sZ&na z681Y9p+@OW-@-O{oBvw-wCDn3oF>MllpS_8$_6I0?%i(xkQVANG}ub zsh>Ev&ORx}5yp!j(A&?;zYXrNMxZOePC!wY1H~{KUMz*w?RHO!5GY25nlkfCG??lW z&>f@9%X~C7tcJdS5MyFbi(eP_Z3R(MM3YvvmiAcWMHj5*0;o%ilW=lwuuB;5N$v#0 z&_j^0Zaz*m*4wAABzRw_xr5v2&3M<*BgHy|Tzv-^VtU$Twji96+E22FD#>z|jeKJ3 zm_$K0W?H`1IkMzHnb~Sle#418KJ)HXg&jK}1~O4Hn#=MK8KFhyE?~r%>nw z@tMvqUv{uxUNhLO+{;ds%Jt*4plvc4W?u zxad$sTlCZ>2=138uZ!-ss|7lAUA06l;~CTjekL1cJ&eJVL*@gB{{iwe9E(a{bJ=4j zuvNw$Qv65#v{d5=JaUTbF$hb*BLke#dFW_hfaEsnCwk2dd?~PiYn={<8yfU?lgDF3DeUxkXDI4w%;> zPW-Y22$jxIjCwWNt!DRDpR_*|eCCY~13(GM|J^x%FJbH14Uw*RqSBj-#qR#9roZMe zs12`OtHA{G1XM`0gn*yy93a^AI!ZJw-KIzj+D9f1WbaBcTHD264fioczN{6<1Lhv$ z^7kVw0^#@g2WkgHxCHeR7+LxblE0)|=#dA<0F`2hEC;4N4*%gwVJu6O0$ zz|8Jf&4#JlL}!W5Swb>hBwNYV@W0mBu5XZM^{W_7^E+VmtOl^fq`#tHwbYl9Z{vWR zxZP;g;|kz~~Q-X;$? zSONoz4qlf{JNKtIfnZ^4I}mchfLUyFXAkQ(nvR*)TpeZd(z*j2n2F=QV|h!5<>*gK zR>B>xZI3lKOdBVT9-L0z7t^ z`Jb!&bLBsRkd;a-CKF{#pESI`;AOGZQV0i{P7|Lv8y%n6O8C+ASmgw8^-5Su^o$YW zPrwZPCH49&mwFV(-)vo<)q>*}Q`e=cz~AyW4~MfQzTp9jV7H52*_yDJ&B36p)1!kI zC%#QtP}B72ShMd7^2;WvkWGqgC5ZzB>^%iyJi7BV2UJs^YbUWH1WYR;dc|qzo<@Y( zo{oReBD`39b1ME>_7~gGdBP&W_lY2zkob?0PqNQ z*N}@O>_(Hb)MO7U99VPttbeO)D&Lo@{sm_E1#wA_;2b9tp16L6@A?wos;Z$&4PvfUX7M zjT=-;~fq>6Z8E;WxqbpdE>&C&$^CypI(-Zn_;oHkhQp^&W-idOl_R7o**-8@l}#U#Ls& zre5Fk>@^SHvKv8Vy2FBY-Y7b7N{`Pu)U|7Fa-Y$0D-T8n(hE$>uF9JG$}y>s&~@(3DBBO;Xu{gMHi;RJtli5_v|X%R3=v{CO7Q+gM6x zzN~a}?5qzZ#%cGe^Aq7fL{2t=rhK!h378>h6qrPgHu%@p(u&|4Ub48wleN9ME5wSC zWE9UW)}2MT0T0ujZ+mILU*D%tM?wze4lO6zWw#fe5hRI(q z#aEL)V=TcA!Tp43971z3FpC*(U~ZJ{K|gDKgvVu2H{&@}jH&hg*1HNHthm*+D)w%B z_1wG60&zIP&%}A}14477J-k;}k9RMeIWVC-%RR5K^)YZ=*wAZ`;#}%RWTLiEE4s~n zX|J;8A&X7@S!x_dc31iXD2v48U`Q4+QywWLROWR{xCK`rYaEDbl|)a;gfUfq*mIoL*J;VEDw}rNmZ|NisOXGIq=k@re@ofaq95eqK`#zq;dJ z@K%fdC*D-hxUsLS?I}mKmY8ycd6X?sd@Lb&iQPRT^-uXs(30+pLQ0IES>9*O6eqcW zXhdJ(vOT~+r)>kM>qp^M_{)o6RbzSb%Ih-jz1BE`-{o7l*${K%j>-?u-F+eB8S~Lb z$(@mY`;^ut?fgC(m=A`9DUfGHF)fd^9Ju*IjJl%2ieFopLZ}=+mM&_JPDpZv0|A*c z)~#lWBaTP6caEj#&YDxXeA<3CdtRxq3umu!R(H*)jHXoK-|sw+QQFbPGST*B(T#?j zM?R}0lr1oKZ(|^TBNg8`e0$bz;#)LppUX+gWY>IHo2LJnV;|f;(lw*3!&K$|$L@1W z-f&hXY;3EY%$F(GIJ?bD^W#LNiJxC*pPqD-Z}}&b^1M^4Y%Bz3RK< zI-!ATzGyWYIkyc~2f3A&bJHmEF?XrMa&uR{kh#R5$x~xKh2`ru){ta^B_~h`%9cZum65_3{3a3XF#owS zFqJL{>bQ-G#H9zqXroYl%L`KSv=uP~g2!Yfu$4PT8o%2(OxBZ-_?pujI?{m615j&w!W zgJ3b~yeX{J$99G#>Q$C{f^}oy?2tA!Ij)p%q^c?G*m;6P>*#J1%8|W-q26oG{2S~H zP)3Li@(RgfM;*ChHvrk1!bCT$%k<8P)1moE`c_g&IzJM!4}$9y@VlQc>TC$kE}BA* z1&7?!N_(coKqCQ)7@^t~Fw-x(pLRH8jAnIHpTx?X`e-`;qF+o@i08PeF|D}k78h?o zBVn|`Gn`oJbg$aE0m_gWEFFH!N*1%qaBcaOwGTw0iT{?jMBWCP<}LBBl{vKS#%c_g zH^_$GG_`XL8PDYlyDG9M@^&+C`(vkR6W4uWph)duh;-Sq|or2(2 zE!N0=*jslhWMZZnaCA6hx@ZcJmd}wSt?y_GuFQk9BNWS4*-S##CRtsmH7@t0H<*;$K)kL2TzM{v{p%T@PS# zqMJUxPpugk9vs{p_yV;!Ws%NPReNTI@2x_kdnD6%=rdO~)6rQOE{UIufQ03hKn-z1 z!xi;xkg9$ZzhZSd+?Gg5nljALK1dxX2^}oIftBBi%IB~_G42cHWCsR%eNBUa=0NOH zv3oKj53{cNYCJ=yqqs2wn!Pc7e0F)P4UvG38Sk~JC<&G>o#vvUS8 zY+uN@5Ot?spm6|BBJu(w@s78tKO=Aro-u}UUVt^_;&CE}eryv=qvRF7y>Ub2ocuks z4yu6=-06??{@80ml0;;-rN)Y{1RO>>1o6@MqiAo#(ow43O0t?1 z7{l<{ISk4`M*Xp7pmucIDkb(^zt%A3P6JswqdfbtIj6>l$r0)ns0d-(!sJRp%xCRqk?f8Hy|0^ww8)AV$_J4>4Y&=Y+Y#n2|;=ZMEAbV&e&h!oxpGovCRi-SC#e?dlEv)`E$QD&>JKF9w% zhQCNDa%~q=OKD^X#J(5qQ>w=n&<%=kX#i#N9StxQN8fA;hgf%swRkAXWWMGkyY^Z9 z?&+r~8-p~AR2ivhBvV(q^`$86*KVcavAB1n$LQ%U>!PH!-5>w9$GO5tx{F>>ld7Fl ziskJ{%}HKyJpAbp3d_mhoK;RYGwnZNc|#INxHz`dpA6i0gR8%FoULCN8&8pKgY6431g!VXZ7 zR?c5o2dNf@w#YeS^(*~%5ZaDY=X!mL@yeth4!a!{vM{W$X7zDG)m#M7{9};-9lWEl ziouGva7sf%&@eACY>8~u@T5O2+LXNJ0>!3i_)JFG&9wFw(ZYnSsEV~ik#IOJK0$cakaUA)-n8nkl+6neuPobhBqx(-`0hhhx5#V^%0 zMa^Bt$pz*8*)7>=gZZ4uoXd7@Rq>tN@yrXGy~Cf$`XH`X8%vnA(O~MfrN>ih2cV?9 zC(TGZ_vF?ppPRwAq$NL{B2Dj`28G}OVCM|ezwwvXKP`?QU~CbPhAN-@pyeV!Ng6gi z7li)B$tq-?o%_iq(HKC`X9Y;`t&_i5>DoQ&Woab_APuF00(_E(Qe$#_`g*KgQrQ*p zk(>7Xnak3Fm;()Qy^Rw|4|Z@>m`Ijfbh zTDGZpZRN|TRMzQmfh{up=?((ce)8W@gtzE1dCfXUSSVNNDIl2jxU=Sx(=qY}TT5>> zX%-X@44$TaK(28CE?6`ihWiH;){S|1h?~=+KgycA2sjx)0kMnb(BY?EE`bI{;`0HF zyKOvfFJ9{|$PqLQu^|(F>09Ut@P&(5{Z;7AzZ>P2EEgCD(M%d%%z0L}{&}GLn7uFc z&YqblJ^@3TT-Sfud6EShWZXPrtqBN*A)*}_-^Z@)WlukAri5;IHa4}4^(y>z>1R&O z$?it>aaN+z@79%1xuzbKeuob>g$-D^)?v3LG5QIxwA7Gd#z7_=@KuTEPSWkAo`Jqh zsZ{!OtjNKPL8dOXRfr%tGgVDB?jABTEYU$}S`*j`J?jaUh10~22Y)^YGr}t>Y4yJJm%4BC*vJ3gw>vPJADuoV zX|Diz(w+r30cS0lQ)89;23-~bKLX)#KF_(mjKLD^^48|3GsET4JBYmEix54^|DJ!eUQ?Ht4~K!){xoZ5 z|2n?TED5I89#ojzx<~tTc|qD(k2aG3j|L1(_B_P+w?LjsOLx~N{I&dHhL}|5!{!_! z0ATW{p-}6$2FFO3j6c1N{=ucg83ukgLGmC(?!xxpD@v%*y!6>wVJ~cw&_y;4db^N0 zh1-__IljqTIk~54M<=1|rP2xV1hAW+h$a5mt+)t-N3POmd1QT0L`y-~8Bn4|EbI@% zbV(av;rXr5RUn5h^rSLZ7xRmVJUE19+z`rdDoFL=F2e~GksA7EbQSZJaJ=2^(mkq~ ze-)hCFSLmiHw$b(rNwR(5Da;0EQ%avc+1Eg$K-amO=>{}6e`;tDe3VL7ts(7?zgmy zgmO(kR*AYzqW2Iw$7(K=np`rVy~12xdj)sC6vIms_&1i@C9m)O6a^aKKsCeuBH&S4X^M{ym7=GMmAXw={f@NQBx`O#WlG<;IW671^DemwRfIr)^DAV2; zSx=Pe+i9EE&LJed5lu=9Q9ek?J940qBs0DjXU?w02NfWdU*l z_c)q+QR@3nv;%{dkcu)fe=nHziBl}FD=Up}uyn+IbgBFO!DR~lKR9@+hQb?mt(8gR z%~9kukwz#+2+9q4dG1Mr719llEFt0u8)OVzX+t;#k$(q{?0*KM1=O{JnQh^X+nk>Ye zXmCx+!X9G&9po-Bp`FL1G-_+rj+dJ`89ILP`}HFmhPuHNiemG#x;HrN#~SKKu_OvZ zgS6p&Et+lQvnf^I@jao9@o6Kvd3cc6$*6Q4OT&f`!zGAA)B8ND&iX0;AE)DHKoOG{-tEOAJK--)HCZq?S>bVV}sb5XUFuv+v z*_Ywfj~KW4=qec^eUe(nlrQ5!%E$r2H{?^T5i(qpy9gHRGKf66c#CD*#IO>Rn$O^h zs(9e-@s*&7zF7Fo>T$#RZAxRlf`IJ#3M4oVoJv$&$fSdNz;IL^X7ws7Elal<=JU9=_5pm zpNHkn6#(3x_Nu19B(S~XT&!a`#Y&?wsyKgnxT%A^+NZt7v)C;{8>rHnALl?ha@1dM z&=;C%AW-ee9etU5lnVPTBu>2=hixTeZpK5;P~mnOk$!S1$@%|?U<9Sa>%Fs`bMi8I z87JE#4FL(4JNpSu%J%NCS`dAwQn33Z@Xt6Gk^*$vwS!Nu(Gh1}o9PJ^0~?_DlX|@j zKG&Jw-j1`&n$6INc4;K}Y|GXNaJeO3X3_!7W1#I0@?VF3sK@iN2RT?8sVPq#Bf^q5 zct2%ow)NXLj(GV#Ci&5hI&xaYi!sy(z(E6LYfP!+iIkqa~nSv~EdVm~^2!@7U zHfc0ggzF4VB|MIVwKcsXAEj&ZYDzMhRZZ8^|FUUGuOWrM@t_{+I$h*@pc`+Nxx0%> zSc1&ZY8s0;oG-Zi4@&#|16z{6W!h9I6$||XFvgkypoiNdEdiat-a39L_j+19qkA=~ zwf|AaSYq=5Q;+|#5ENHGG+E5^@N2k*0uAPV;#7YSR30D^xL~VJm2hmIZuQVt1e?3$ z@9OKsB-a~^jn?{qL%L6Vc)yy(Xu`x3UBcPXuEUZm1^0x~Iuh?(+dP!5u0=_u{y`f@ zc5hW;N(7Y++!;!_%OCTx0N1HLk$znN{#*Y>@Mkap9$66}fIX$N@29#|4J}m|jHjC)`r0`c^NS-N^Cmu6q#69!HS@3~8G|0% zRB@~hQ zqV8Sw{I(2!zZ?$WqywZ5sHX+Y0;SG?lA93=!uAY zPG91@@Um{Pez*<#6*#r`<0MyK9KL`@_@Qzpnig)8!Dyuwr5o<5WH5~7mq4?fw^VvX zceV!?!u;*O*(Q8@FQ;wdjkywhA7HJ<%k^hP>{YtGoFfA-qB3Ni#^4NV2JB%wMnU1W-=3iJ-jTCYxQ=hcw-i>Hav`2->Jy4LIfdlMk`ApeH^<_C@T_aivaQ z0nyFe%C;hA;D(1(5IuVg>l%sxQI}h=V5+!2;^Kc ziyv!(2o?3Mv~#K*?BQOPlTN;SlKN*wq9(3J^v`x+@>pbnSOGrLI?*6P8kKc4gOQh` zDBu*Wcy9YhhL^n-o@_CPi)JdB&o10e7|=uR_ggW0T*^RI${CFlj?T=KQkeJ=EExA7 zi9VBo=!TZf>aL~IAqAy_pNm)rVDo2p>c3g^0>3~l)Hd}Ssj|WQ?0nB!JlW`FsOl5? z|M*@?cmjVnSp#pTU-(pVq?!bhvyKCv>y;i;j1lrH|_h2-zaRIckfANeBBRLzLnpQyCG$rthd(z*%zbhH9fKXv2U z>H-h`21U)8j|(^si?b$%keX0ocAy$HFf)xWbm}3oH z$$!;0I^lKg%x1x8@=lC$kK&Hk^RWrmm_lP|JEQ{w8xzrWuSy{bAo8+1)`CJNws@Sn zfo)^kIC8Gl+{JB5W1VSu8846qt+WtrK!c=-dE2nT z8KAaH$S`%fggp<=_bisW3V&1G zW}0T=?7L?uYLT=QEMoE-l+&9I`ywXf<+zuz*nUSMAC+(f2=kSi(R6P+IX_DB&}m%r z;`uZy)xv#FM~J$!;StW|Mcz}P%WODhRf<)Ux;Np`ll;@(iN9J^r$(ciLlYeA)OBrS z3OGm#E7&yjr{h5ATS|-nD%Y*X%CTs*9WWI0q<1x50u^Jplyqm7eUZkyGkG;6pd(5YxbMV!^k1KhY@A`28_|7>8?J;=c3tgFP^hG ziYL)fJt>)rnaP2`>};WUM&$y1N<|{Zys7xbQqVIqzpgv(;k$9J)LE0pl@QR@zH%#4(uT12dgySCrW#6!)(`62^r>U4)c6(oFwgW&WB zrb$BMngiVS*W(*%`$#vFltnr5IYQ51*kp}+9J-;GQEBHbXANS=xHd79lH8$A&|2Bf%!-{@v(MJaS;e9>q&bqiwT{5(kfgY%{&+lPc*xBS zrr+QXs=KOz;vVC06Z0>{-s-p5+OpMD+SS~Fm_iS1<|wPd zM3m@<_0aV1$!5Md7l;3%?SsIK_|3v)_EV;3i;S&gV@Lhh28=s9ymuY>6W6znHi4BH zb)a5p(H@!o!feDqXzpGV~V^hACGpxE~PUYSHLgx zDHuldkBRZ(?;%8`=d8@CMDzC6bxgTrP!Kqntosp38i=KMf~wLe%`Pab2}kuu3rJh( zoT<}2gfEsvFLiP6@WM6o{g+u(*(*A{Jvt*27pi#*{($z*s(KqkTSDj)&A$$tozR|2 zG}(~XB5UysMs7VTglq6~dHxNYT#TS{4tAnOrS+W-;N;`cus`m`{;lKYDg)#@NaGM*um#DnZC7>gp4DIFfkXJoiWy#qB$hZ z?xMlfNJL~QsYjQYq=rL^|MbP7kr+)Mj2Lsw&r<|5T`Wy?JE!M0DU@?hn|ELI0lMu^ z#b)gIYB+HRZc)ScOCsX<*lCDNwO|z23dT{O5RQTDurMw+^nzN!2SnQ%!(COf0#B%- zqz5FytD+)tvLG22lxj34tI4E#pZR1|sUIxP$olZ+9OvKk)NX}=QyO0Gm`EUDcu>WS znl>aU$=R+%&Z1Ee;U8ZA;UD~R*a<3qjYJzA%|tAdFMA3090R`w-=r0?TnN1;&pdPY69-L}VGhB?fEo{VS$eg;yB;u1zwQMvx-D=ut_V)Cg79)$3f&qW z=68_$O{*nXxk2pCv`h#Mw~?Mj@G1r$p-(R+GRP4z7x~*`n#SA`5XS|{*JBsH3Hh6N!(~&6+GLdtXCit{UXVm5Bv(p>v6sC2IL&C0@>z$G% zLI>KlbCt&>3wP|45I@a$*bh}u7&ulvK28|Xb&4fo#QzLo`yh}wzX)3>2U5#Cj- z3>20-NRRNVlk>q}l!8qgYDa!d${+(BtFK|9HD7)B`v%oB0jE1SjblpCo)?it%KnJ7 zrr*e!4cV*=gz$`OC!6?FN-l$YK4<1AfS4(Sdf0!l@8fbtWQYT;t|X((MJD7Nu3F8z z_cQ}UzN6b*O`WaitX=SOip2-2!VaZYp!&6;V&rzx?!PGSdx^(}+wT1Gw}2RM(``0g>ny5zl3&F2gDtIcsWXx| zRvWV~7JsAGjBdQT33&`%>2C%%gRZ_)V z;q5)co2b4bG%D%DvRNoi5KG%3dV<-?=cqUGaJ)Snxq3l7E(|TK365^jr`AQ8jNbR%#y` zQ~n=PS^kJjuJZ&&&G?VI!1#xg>ZaR1VacfSCwaALr|We~vmDsUi@suC-Sy*2*w4{` z-p=I#ISvB2=_9cRMbku0W>CN|2X zRHzx*m29xsYaLcX9WIQNV>-seV-9~L+`=F){c1L7*&ZG4AhaIV5*Ig&uspYiGM$-b zZk~4^Fx#$7{)~=s2V+^Q^H$mO6L|5Oc)<{DOFgT72OxK%Hs!B2iBeC0c46*h%&(Cv zAGu^1Ml5mWGyPvD9Nl+FA7B<(^hd6fW$quBK+ju;c*})c1E$6<&G*-d;u!bZW!c@1 zVPhdZyxF?kGo(cjzLV|w0glVR%)ADTPyjz=TxWGi0mhN*;K(QHdQrXY{UG+svy^nU zu{J(Q)F}1=pw%jCGjD;&t4Vg7lqCP-?=rf46Z?!l{u?L7<(&Bz7??4aZk-vbkeZ)Z z0UOQfcDL22txLgmR>D$gj>flRUmAE?RD3XVk+W4waz1~7@etVtCoTm;3rDHa<>&|! z-+#VrkhUm=zMrR34cSWKWJg76aaX-R{#?eO$Du%Gu~$;tl!GkGFz{6G!0i+-46r%a z!TNy0N|dItRWbcL95DYzM7rh1D9c-JyqcKiM$56b035Cj_1rpny+ut-Bj7>KXMP=q zLhlQM&ry+xJ$m%i=Tr<=Hw=DgAiRAY$L#7tj+0B)1M}Y9IKv&J z<^%JxvvO{KD5Jvy`jWA3I35athvSn5Nw$sFGXIhgS6?(JeUu28YZAGvX1kqXwp8jD zt$rIfu{S_|m9#0SJ<39z*e&J!A7kgxrHK+{(KIVnX=kNv+qP}nwr$(CZQHi_rLBIm z9`#!N8)6V~Pn^B44jva`T-s+pC2(iESMC>PepP(y$AEE*GrG*bMG+&&MD`2y6G(eE zQCQK07GSb)lco;62&6x8MQui-0)7YHl$y49=nSzShL?`;Xa>&A#C+TEc_{S_V6a&l zp{0ZFO0tfGl9Yq=iDQ^|*yO_*J5Gh%OeaF#z!Q7CXBXzA@Fa_57~P;@e}!+2f53|= zGg*lZQQ|~jD#k{OqmT}XZBpc~r@QdA1(Vc^3z6m>BKK8aseIr58OeYa0!cxBP3wb7l zHjG+}^lPpeqLY+iLln|Py(gG>-mfippDkc!B7c(lmFH`fC#N4ihs}DqI$(}VqRC6x z>pga`PYeES^6GQ+XkI4MUgK%;qE$nfMaOE%_CPyejiw*c$2kAk=E{h6R7hp=`foWB z{SpKp;+&PdwuF|XaKa6G+V4O2@Kgl<4@j;n?iz@BQ+^`u%Mluo5iBW3T}6U?cKkmr zA5lPVWp3y7>|W?ouNKh0N5v!>GW5dgb#SFAxsr`xpsUrWs1ZbRM}|Qr>#!Da4At=zQP{% z6+Qd+6AijV9UDj4g`4i-)=(;!;EqYT+z&BfaNol1`hE1`Tf$Wzf#+i|O;UC?*+%j_ z0}+=Fd(z@lPpK}suV>}-t;`Utws7(-51Hy1Q$ro;o>z9!{tZ~dDh~J|QIWaO{U|m% zP&a~E4iG|;{cWBNVOMs4&5^w*DE;FJ?2@IdFuiQIvUt`Xm5@W9MfMF0QKQ34gLtk- z_sg?0-xLOYv3w*hHMasZZ#a#fHGC<^J?M?}CJ8W&f&+tv9We#v1oQZN;vi!3U(nMm zPo&_u*6qp%r<*`Ec_m6S5W@Vkmn1n0Tv)+zyX-&N))$MEkOK}w7?Mz$6P(dG;glV7 zrZ1UB;}>OZuD>H#azlh`^}aV!rGDTZDq&ppq|njKVN*LqY@aIKkg9;MLlS*5OCR{} zfoK%j+Oiv8(FalYFmseZJ?uC&gY6>hwxT9SvpH!vy%UFFa=FsXBCOb!lE|e))5F>=MGcnU0z)i zAUk{>g*`vlX@af^KekS$l>--wbzWM5gvDj{r-oh{%O(m-YYvhar@V+^J!Xb+*Uyx3 zESzlFtJy)2%N{J#{d|*$WaBNuym2ArD~WH##&F2MU8@8*gW(2XFo3KHP&zvYZ~57R zA3xtxTED<{2GIT2=G7Ng9AlAdNaEb8iPLL30@VY~Pt18wd7E)PJZ0nxwIC;IlLV(N zF4<0XoQIB>l_-dF1B}_EcA0bGN2U z6=^>H)uNXjnckw^^OH4%Fz#pB{Ge6GytdC_{B7PCM>G`*MKp@qrYM&LzHPr>K=EGo znXHE$qWkYQ*wi8BW=qGwouo_fRePf_=7w!%)3qo8K7h&GwngIB5o^K5tmBOx^`TG1 z&>9zDc7|RZiz*<3oH8}`JPO4SUzfp;?5F(&)+lplVz95(_^redf5|uKv+Nu?vB#6? zt55!$tI48S7pmgki@kzdoP-X@BSM}19)r6tAGA}raGiE&EKPfclLEi9n@7_0- zIQ==i3)PupWxMhG_dC- z6tQ2nB}i$pT<%3c117&!@YNGjX0-FEVfcCgY2BU)LbPM)nuf zcGrvOys2-}YF7CFP9qHNeR61)o2qpHq)0K9ix&nBa&bL22Ftkwx~TspGJm-( zcqSQF)T!0EdgfRz^gG@?zSse+SDR3uu=wj{h-&CemDbLIr_jS>jyDB!5v_Em=bQTn z9ha~lXj4b6S@Ja&*lNS@QofToflK)Q=B;fk$x>o+0-182hRYV>lYhdom-71fa29(G zj_~xc5t0i2hSfxSd|3?lq~qfmRHt&4H=q&R9$v0i*CU_ciFGE^>6Zz%{tc2Vb0 z4m}cGe!J{OxBV9IfabghjX{CP_?F}sJ&_ZZMyF8*=&(yMLy4fEQP-0?jV;hg z=%*nAp&*k5K;upu8l^GRBP%=cbsNo-@-y)TXK{y3dSv)9{@u{KmP^cr%j^lGV_cMs zGV#f7KX1$VTY#71>*A93wtgwX=+`{X$7sIjib}s4*EvrS%vIk7K{F=c5L58H7o}SH zz~u5L{(-uIRD=D*>}5EiYZIf2liHT-ZKA^X2}|xZtaYHAmcMoGBAg~?2Ra$j1o^rU zDv&wZl-&@+Or_q~2Tl#>Cqj!U@O?9C9+miJi9 zM8G~~v1|*};on(WbjC*VRY?qfqE&yw5_o2xROTFz8dOI5#7c#omJ{ zUX$kC&l!W-3kv5NxeWNA`TKxL=y6R3gZVgz=vUU8$9Pk9rJqXv+PtroOUnCxVP9Wm zXUitL&#WtHsx)f5uxBK}uTlerc$9?u3(rcwrjUhh&a^<#-{W6d@exJ%DM+7@FH8OL7U)#}!jzPWYhj_1*zQb9xkI}I>30@-{zj&TGsNM}#n z9oilJto-f%MZ}tMcSpr+^EnzTqo}J;f=!`pg|dUs+7TP_a0j{hl`A38HK+7xMfW|N zG|h1MI~!&R^*;z$)Nu!wT?(^jw8>sa#BcAd-8eVJ$^6XXDRX`uBe?b4O8W?MLGvG}5{n{0AM zdZbS_9aM#fvRF%pU1Gz^%u^i7QjEgi_0+Bdk0Qyme760Omby{H?Gh=vruFJ~ZZy7P zd6>v7sDC_%*bnt*D5`mm8g9ZJV(%5BFchQTkQql_w?^QhI<0r1oZBmVgsU>l!MuLg z!jagiG=F;Fi%aa7urgzfsCqnn_;5Qq291P$rE5BUwB%yvko9w!RsA&{sya@}|>`#-+OJ_k76gD##G}B#G(3jdkG8GExOWYepkK+)t2ID<&&lUBZV~o!@-cv4AV*03+WcQn6oHYTVd(&Ni0sRk+pO4z}Ki2 z7NwZ9hATMar@v}z?vu8`dE!j_cI79udh^rn7dnSp@PTBMP)%GL zCH2P^%KHyb^Kp}#+ZWZm@{chr%@XMtP>ikfZV*#|G}oFJ{P@4lHbSdT?KYeCeBk%2 zE1Xd@Jk7HnzU}RGz)djOP6?|2!w&9=_;_Z7|k6mlWMZ>y9^Q97PF4&zHN3N!Ho zCLm8J(Mb@{3cbP7M_PHxKD!+kBO3iX)OGVJBIL1O*OdH?mY75Qg1rfUEi=utHA)c4+%OyC4y~H3&6eaz68R!D z2fBcbrthyowRFQ){0Y|`w+H<1T>jJ0nL($J!6ME-|K2X-+M_@3*6gJhp+!?Z;2-$PtYa z1e5adD?%uJl^(dgCBgWr)2f?WBwgM(Tyr#54H;BxCg ze}xl_v`LiAf47MJ1G?(sxgLvN0lNb=siL?CJ#U(wi!2$mhFs?_w_dm3JLO{bYASs%r}zoOx_Iy$l`ib@u%> zOlV%)>$Plm!*NkxT@zdT35(YRg)OB>n4lH@UUjM0G%M18iJ@=c{s98NlTf%4=(q25 za0-R~0%@FJR>gBYj9$-jMZ8V(Z;>l^Sc$n4)*?DV^x^BRppZ)KEoG=}0NWjU3Rnyi zSA#!qfXP*s4@s{X;lRlZOT@9Nwh0c-)nXOP+@(mL6v-c6a7)Os z(xHj=d0&n+^uUu!A)_S_6A~x^ec%(Zj`l`j%$&G&M8*xF1lQhMYAY!B3>?p_j#w7% zZ{9+_1zQpU&+AZW;4SwEuN5uhmr3_|4SOa&j6Ve=z|=}zEo3fdJ&Pgx7U zk08?PWlJuhwL#ezHyMn0mSrd*!d+G}^jm3I9x z^5!3uBYIa{g+xAwLhg=9S0*Cfv$HZTOW7T^UoTp2&PMY57^JrB5#A(3s0ZVd(fIPy z?Q?UccMBz6vlkYIsuWj%nT4>fVn1?>1y^(Cq3s>E)c37d6;&0&d0*oThDpMLri?|N#Re(9D$9HbO zy%~#A_f#7U?N0|L2WvJ#s1;!rfh?Vg81XJh?f_yrwACocrc{KrNVcgbo7+=sQ2`<< z+4^DAwAy&+7V?I~XY__H8HevxM1j9lQUjy7YdnI-%I=#^6*JRqtDRC8AV3>=r}AGa zT?ABH3~Wsd_4y|xx%GEF)h%$eB3inVMHlzJ0cY|%qh9mT9PjSwpi+yh1ZTGH>Z;9< z&k^J1@_`*SD?&YxECXV2ZU45^wPaPVq@{iqzkJ8(g%V*4RLvG3ZeK3{8GEZyp(5_g zjVaOH@RH9^oSt~}unCtA4KU!SqpjlOL`0__QA61J zPs&@TB_)j+bUXA3zxZ6>&bD)~WTUfV)y=k3d^7)23U8>$FAwoZq(F{3E;1L{hN&M= zL{YxMt#FeZZsVwgkV`1A#wX4WXK_@9`2q2kqSDDhL|`68T*rW&?Ak@z)iDTk zBrb(w9B43l0v5|LX66rgMGT#N@#<`nNKdUJty{ZN=*QG^v>uLJ(MW*XH!%k*KcsnB zkqwP%WG<2L7fV~k_jEl((Yvr2%iMOGw?Iq-i;r7DK83Csu{z<$@Th?R(gD3RkXrPo zUQwE~mY1NZ&%WaTKlmahdQvvPF!9ws$YBU;teUJW+-*Bu$gD3rV>F|IjZ!^M;Pa|g z1-m%2n%{oH<3S;O{>kUr;TVbIHPehl&<7Tcvov)Ihp}y5{*%OJ4oIxPlLu6r249+4 zd6l5%A$S~IU&gCnqvHg7O_U=?#pL8fhmz=b8}l4~_qTa zratsqQ=yvr56e5gKeIEstwExJcE_jn%OJiB%&dVFOnLD(GFvG7OYHSz?q&xRTJZBe z5J`+LH=;vBNk2(cQ9ke7f_1WEY0Qohe-szYS_%f+@<9-_m1$CM5tokoqbtIN^*}m2 z@q?Gc{LuUbs6_tjU7MnVf2{TGWhkB=$T#jkHB-*PO!!V&3kunX^bgoijIIPjpCml` z+m~I9qF|;kzqto$>@*>Qo!cSkdXrv5wSn+2)7Om_E2iZ!4G%9t8WShyC{#eOh_jHd z56w)^zj-Cc^#?o+WeFkj*QC2{cEHLhKS0!4Rh(wMz9u(x=oOCjg|CFpaQ~n8ed_M= zY9gs5T7Ugljf|Ll2^$*?{ZEBISnb~M$h=$EgQS5>9jc2A_k`lA&Nh=($8o}UQqd9hqW4-;Yy)NNY4vFV(xOmoobm8> zqW;i8VES9%*h##6m2{hGU5O|Gco^cEZ#Fj#G2=Z=NNGX?j3lqXZVYZYNc6rU1fM1v zB2!<^8+ONtPodL`BnYbBG3-b%5)+;C8d}Qa&=M{OBMwcweqlK&pR&a;F*V+5>X9c@ zVEA?oj@X7bV@sMcn=DrOfq(M!P2e&KCeLUfbMrJW9ylJ9Is^%}_)kb#3y5kR)m<`* zw(6$_>%`ZcBN>UQ)#_JArTN$ml-KL;;YFSf6LIt0^*Wl8dhH~*=II}!$RtAAQV#Ezjn_};XiuQ$pH-QHlLL< z=-aR+epVCNyK-H{R_w2_-nqUuMRtsEh_NN!U2TbItXJq*@O{iZ3Rx)cIJkYBIYUBv zWu$Iyoj#PDN_0Ajng39pUZPI9^Mq`vK(hpJJT@lhM_b$C;?O_osp<0-dO)i?bppnT zSGNE{x6qo!`wV;YYnEdXSN~AKv%J~9L59L6zvi#k+xI9#oA-C`j-Tpe4Q5oa7>pdY z3wW(iGC)S1(%gLcXvZ?=NLMR$cakvQ7dV+ z5}qQeTt0NT0_4uQcg`wl^%#1ar$d>63y>QGTU6x z014G63YhG&dxnq&kTc(%z51QR^cVh!F?r)?e@fxho7YRcXG?%PC&7-0kWE) z9+?8;qcSauRw9@sw{-@~K-H>JycBH4ld~O0uytw62H>EsT+}{ zn_E#W+l}XF+8TVE3>94|ga8exrqTCN2L*uZw>@W2wl<@+HKc1Q?*{~gixs$;zEw-e zE|SvjzaEq#VE=17{s$MadZj7?t^O`H8*Thw-`whmlS2TmmH4evJG~_0O&s7L5^QTw z7Kg!$Jzw5oMBh9wCrP2%grNQpC9r&kGo6Q9bcmHE-_3`?jQ&HmV9woJj zGgcqCIHAS>iohLUy23dzjd-(J+T$&`XZG@F3TM%Hi?|{AG@^9E?%D}1iV-^ewm&6b zNjUGC+T`&$H3ws83PG#p2p#>sB;G>m8$>U!c!CmBHKgk8Kd3gQz(*ZJ&gaYZ&rg1< zr-@6w=8k4_4qkn`*#vMQf{ppm4XdD)vW#bqS`Ef$bWek&Qd*pMGC=faD5bsP=!Ypj zS_;&K;g*j~Z1KXxyiBGoSX7SngsI+?fs_c%U$oH7WZb5@Rr|735e9V|KQ&^d$z7j_ zKH+P0?1$wla~^8iqQhBiDaNT&H+5!4ew3{K8nL|DCB`RB7&6n}Wf}N|3wT)kh)-bX zNWn5P7}2T(fPBi2e=5k(0)NnKU~8c7fJu6A72lTVwGoqw>9^maR6wraJ)<<{7cF{9 z(+Z`LlEIGNy>=;U@uFc}-s}A1^ye`&fb_1%*apZk-EHh$=4N|M+K@1b_HQ4QP>lB} zu!Q?7Q#tclqJ=kH5>#+te7Z~vhlk0iRr(>Q*tI$rn3gXiJtLNPNUQJDeVe?RzS+ud z;?7ADnhfWExp420o)57cEUMxt0Mipu`l;~yM#sH>J$EOM!jc8AN>+s-o)~up2e*+q zFIW#_rxo$u6UoM3VN&XMo=@$$NBf)Y(0`NlGUm7%SbjLerwHRN9%X6u=|C}k^c;)p z(6(>k#CPG~KaccjtMA(O=yUGBA@Ltj-Vw>;2YbW-ALaoIlc=xv&mFTQ1OgLZbt2Sm zUOq}@N*rRDa|n)|9=yS|w!M!IjcKGH`^|5=l@UapAkrkE)NZ*vhZ;5S7IM?kfw!0_ zyTL81NVp!=o`-H-i2#BHZC>*?9{i;R5BQ5>;RX@$tTT!A=;q4LXZ2G}Bs-GYe@+19 zEjEOd647tS9A$H|G83_9*8y2zGM|?V!THd(UECEx#9EppqGGZLh%XylV^MC&C}Hov zN4l<;m0)x`5Q8>BJLy3A| zGy`?ZQMM7@!VP1|g0OK3{G@xv8btVPUJTCb|{9 ztXbJiNuqG27Mp_#XOrAGW83HZNd1`0+#*>csL+*58_Och((2@cdFwh*m9;NA@2o!b zFlT6oa9%@?@otvUkl&|Hh!(v9cr@CEVVZfgrZ=S+Qwt#=#@Vs(C-=@i>A0;}b~HGa zl??SI{)p)oa_hcIeII_>el^0em(ry^txpX~(<%`f`_Zxt@b3$^3N{^9ASEh~NVEV% zQQ-_5N559HX*dkhSalGR_?xbwG+Ba|13En&Mj}9dUYmorPp70_ zotR;JHly;uf<8{c-dpL~Q32BJ2oEDK4}+E%Dl)1?=V^RX4#){e7X+;-l`uQbDxlph zjueM@c=HFFQi-bWh^|%Xg;2%Vi+DBtWJX?ZGT<0wC20y3u@%Jk8*=g8JG(iX zGs@%`v5xU8RfGw=^k4m->o=Rh*vlp9|C)EgVhwZM;Ym0ww{?oM-X-W8Xfx|Ee;RO( zgIHa<#uecP^BN`k5!z<#J=6{_$AQ7J?LPKN1RG+OFMX-jSG%d-6U%2Y(^{`*bvX~) zOTTMNWaetf_M_^1OpG7SJY8p*`v9Sd2+}^4{@);?h1x>H7Eb*0Axsr-WgEfY3nm6z z8pR2!5;8htidC^SSj9Bo*FWK({2U19MG8UNF@e@q(w`DDHDJ)dpHCD1J*1o39LE%Sh1JKI<~mj7cAqPZxrBrxU3(=aMDT#qa|X^>(5|1zuK5#cLsp2 zq;rI$8na!-xgs!q*Z}YYQBxO7RCSK3tkl7Y=hJ#`I7H@>8X<6o*fcuNvj>qLmS-G> z=YFi@x}n}6wb`Y-D8a5u5sAOl)=zwANl_p~p3Sw=LgA95ljZnS4#RE4!PkTO4-9h+ zmok6B7mX5-V_N5$`W=m;^?+mFuZ-_G1QxP zzBRtP?(y4kTSJ=}G*s|gO}Enc%ZLSN#cWxToUK3ink78`5Otk>`+ZP)b66K+vbe9T z>7{YS&0kDnvc3HUwWd>x6Z&tvdI;FU-}jLa?gtg=!Rd9`gzv(nn`FwH?6lt00|H;- z0gnER>Lh3Q5ZN3n9|gO(XEBPMR4t|&uTdaxjvdC^9T-f&$ z>5EWALp}SeUe?#knSN~pax*Ox+vBFy0_9cAmJ4LL;&wgaJ;WjSbfM2fX%Kvbr7h$| zd*-Av0&1vsHB0z(jJ8rp-&}jo0WOKM1#!=#5ftld@n7O(l;qH_Md7b2_??@uhv*B= zC3M<~kh|R4j+f)P6E{ig<-y5@>Ss1xmxyYz{*D|OEAMFT3b{VCW;L$KRgt!`yQ2F} zH^_=>0}Ql2e@;Mfo~&;&N47msc720TlLGpwk&-6XSU!CFhj7>YcY0d3QVXWkea)6g zay3GWaDT*QB1lOQu%io7LCGg8I<-GM{=dybn{fji+hYYi@ltMZ^=K>N1nga}{zON} z)iU1{KbO#))aAbR{cfeOSrX8_1&5AMR7KK_D5BEqI>E6DPU`bs9RqO(yfkVz<~E-< zQV~?PGlkRYs9WXtheJ0vrRqB-dGwD6ZPPMQcPLRzhoIiz17tooQ8Hos2N_swxzVVE zIu{|@`&vCVEPE#d1hiX_>@MujPz+(SbLQL1_;k}E{cika! zlY}vi7N8O9Ql0M}bMdTXx}BgXuqGWD-KQ+_Is1EpH^&m~_P^;|y~KT$@`WQQdvMLQ zJn$L(R24`3g2fhZPKFJq)VDaK`DOA9b2~JtIy06K^WV?pW*0rPNY#fC;h6$9YC=$t z={^EZHLrrV-=8zyY!|DPpH~dm7c19=O>NNUtVb4T44LYZ1j84hIP{g;t8<2STBCLM zIbGw4_Fm1SGo^)&BuKsaWYx2Wk*i*WJ12~mV6q+FDfiH!ePc-;)6-Sv_pl1wi=gV@ z0rP7_v?{W&RX9~&jAEmN#c$pge!gi!)pU2jHng+S59|{e5ql%HsgeRufL20S&z4`( zR;U7Q7dVkvsyc47w7gWd*YW`O(*`*!PE0sR@tbPe!P-eLCph|C5PZy$I-P=S!T_He z3MykjqY5#3to#I61Nb!k#65z!PDcu&M)TnzORH<=%1;sVlm55xYYvTnVqV-(thEI_ zgOaGgh25J)LaN9b35diYAt5_0Z@|W7m@Jd*>uiZPY<-konhDO|@O;pU*5=!~nc*G~Lp4P$CG!5vBn&Y{*8tfpN zv(kLcX0l5nWGW0)cuu_20=M#|Yu$h!?Qz^-Y=ASug{(Aqvy)D4&&=?nOd=p3mRxLB zdLR);c>MJx%Y@wSX~5C6cyej^Jl~#n*jyBP1-}|J=JSsy>E3g-(XJ@f0AH*!^w2kP zZ8hgePj2vUE$I@MpslOzC+9*S7vh@vL!Z#~7DW?kGn9n4nQHL-;XY6KjUY#_(R+g( z3BMrqHF;NXzW%hruFf)f1_G@!I`|xyac-LWT$qa!%JRVa&OdtL_%BeLA6BMT__NA_ z#o)$n6=w=sNUR&o+W#}m6+q&D-B4Yh*r$sQpWR5kqFak{SvD|MMT!iV z40!j==&Lm>lg}ms=}Eb73dq|{i$zb=pz6|!7xDh!@VXj%+i{Ub?#DRe0e3veMVrq@}=K0 zn}3>V0@ha(1lmgOoLH&+z0nc8v2mlwyf2Z&QFd$3PKTg1YQOMGSpF00P-$J&fV^C~ zPg)ErAxay{qaf&JNjlt)rbp=doDorWN%S!iTA=vGS=oO1+X~j>kX39ti^@X#`lFVE z)J(hZeqV@xqsi&iJ)+#Ba0@VHFv%FuJY-GpdfNtqsUemg2hi8mi=Iw98RUX@79sGw z1+91|j@!pf+VutJoNdE|Rp?wp!EZGd!=&loMn(-fa9^-iW^RlxFuDjmO_-%Fe$*&A zUdcuDof8;)0fEA08CEpzkWiusyw9P}Ga*7z!mF%v|I(z+nborVmy~iB{M7n3w{zZ0 z=UB@03S?!ne@?%?!f>I&Uf}T0{&g=B{&6(JQ{DX-Sss7Bc9o40YDa8AH~LwIH15eF zVNYI{QbGU(lT+Xc-b3jXJZe|~?sa)@?E&Rc7mk1X^rEPZ) zn4;VUUtT7g3M~RbZs?0%T9&-|*OjIyXk_juAj5DsZ(oM{9OR2`xboQYuWU6A0Vx7O zJ~rxE16~fN`wF{CNR^~cSm%2AA|T! znhlO4)PC(9WOFU!oq{{0{7(CO_`}s+o~w4-X2%#k&aYjN$2291*ob{%MtUz}>+H15 ztjo1`NuxrnieWXbO7Q}7n$0QFyHl6c!ZBIC{?8B5>-lYdW6;;esoF;Sxt)3e7~swb zTR0mI5Y0o)EgfhXujNmsg7-&*<`7yyFr{KK)Aj^Cqtl!qVDk8;I(pGAbh+EPiHq@( z^0P(@D!JB#8;#<#Im0l_W1p9vOeQOoR~)Orp#tUbS+#J(W--T2&CEUWk5@TLI4GtL zZ&8+yJeBBldq#8E>AcS730PYf@D73yDLdVEpe?(so5<0Xp{@j8Y>>op1tw9+nHHaz zsF#RthlmU=Y0kWh@6tQh$xu-7o_V&ba(c(159QWZzvH*SuT=W(lT1h-9^>2P>vfp@ zR`}Q!; z%n8^ddLS98eiW~m)e9f0J}r_npUMNSy6YMOUCX>UApPbi$OHejGy@o`=P%AwAn3Uu zen(5*27)MY>~iR~sEtdPBq(1;JMVeq%#h&|Pp?j0-}0qOvPM*blr2|eJWbMYcNDe2 zzeveS7Uu%SXv%k~l#EH!b;3WUn*iSc?IQhzS>X;e#nbhou+f9}EisjddtncU3=X4_ ziSR7`4f&N6!T{r5;;l<*0njPzNT|JnP+rtpxhM{^*QW06F~y!Y38@b^ygb;6aI3yV=*LQKVn#-h^M9eBF{M__?^G*XG<5jyRcT9T}kP0nq^5Mlpjhi zN%fOigk2Pse5uR;t@C}Jy9@-`|0wT;tTr&YAHaJ~Z@eoE;?io?pjXWtmD4duZ8W+t z?h&Hne8&)c{+*?K?jK_D?+0ME!TZQnWKgux+B{K&Y`(;nyEk<|X9tzK(_A&4~zj=cO~5C z3YG=R%^7<~aIvIG^C0G~L&a}hSUn??;PF;?g?boKL}bLiO?@n)jl~p@avH`C>DO9N zGc@@X>C^b@|TkYNsrx5mks>nyexC5iVtncck8UH!deNoy^HZ6KC{kQ5~i!Dv| z2q{xKn%>L6Z2|E>L?Pv{%Ms=OvgXs1ZXO?#2+xZ~nYwdiocL;at;>4fNCQ?^4EynC zQ{qfrgCuS>2z8isvO!4k4D5TxP)3H+hNV__#I+btT??dDRhSCpom*i30XI#(W~MLswq}~=T=vE`I@vv!iXHE52Ywqvc0ntq%* zojTfs|92~UV6T(qB93*epcUA?2 z@g#>SU(=ASBNNGVGMHTOHC$c^b=zA>r*9-xN&BhMh^%M}(?B)t0lQpZ3u+2~nOC*} zVpMB|!+_h&Ee*nj@7KCuxkq86qkapOGAkBFx{%g6{ene3+cA}}3AlFZ95-a}99|7(aX#8(tXmQ)oL2V)9dnE4ReOnR_dZw8U4JV zz3V#jdb{HSsJ$p@Ag|d&dI{-ggQN7DU44)g z(jFx~<3lAp2aXiCxl7Dt^4Z@+i9^$)L;G197&}Ew5qBnpWhM`CCs(cGaAt;NkwW=} zL$`S_d|Gpi|1xGcT_+qTrmD!0)1?LhWrPcFoU2ctc>lw260O6x5e>pz`D zHCWv8PnEABiQl@KT!G4arO`|?=}x`6!8e4P7*>BvpkO$y&si|O57+?4Oh&$rY(;#E zM=DK{&xO!qnh-p>eqX8|eKU2O;WGQjW-It3 zv%g7M6~AYvqoou2OuvaAQXQ%O`NXV1jT`MxUlhIL;^h8ILT8%%u}mG>!W;ELnTI^p zT8ySr?yu;a`NqCFoojGk^DIC#rKInaots5>&BqOJ9FVJG+M2qilB?kL+tlwH*Vf#0 zE(o^zg-S%gU+xqA=Sm`O{`G{Csv!uJU&YEn zEwiV8bpKn${elKjULh17k>i>DwA}3k+mp_>)yBG+oo;H=3Xo-La$z;K6qm%LQKJd2 zlnSZW4TEE@j%x~*-&WYOgxfHGM*)X^+TWsK4D4H2?I(A(S1Xh@C~&Ifbmt++4ZZ>4 z8#tFV3MSXzNdiZWFe3ir(~_CayS~+X^qYJBhtD+V2%5)m(;fMt;3Z zkqCFS?OFS3K47BPNjLAf8+H&JNza7itmQyp;w%s9hDA${tLI{7~7SNQ=wMAKpVDda2 zdLg-|Ub*9S0)+!6k8o=GBvb=-HSA~pJ5A?j1WsYy=*ekrlC|uNIbo_U%DA9uOy1j; zU5BVJ*Ug_R2%mRlFD8`vydQ}DVRVunMpnK>>^G>zFxDAv$9K|X&O(&PDF}K7`EAnMGQomdr%80Y?+XBz3p`%|MUW|U=x>N$F5^H%L*5P^Xluqbb#8fOsE#i01h<8;K9kI^#oyD>1L^5edJ9bnyZ(MhD>BK8C1pnwa>5_WY@mPL zsNK-%3t#xMkaZh*huizA{+)|`Sb{-2QxW23ahjkMvAQ%TPrbh{`KGoL#zO61Yi-2@ zr;%ekS~42r20fvpRq(ZB;WT4T)oqcQ;dwkPVF~?bf>z@mZ^mqAkjwei3{ml4k^U8g zqg9?t0+Kd56-5?=#!O3E37xQp)0dHFpu-kgL%v!azEj0M^iIa}8+NC6w9`KVy&62- zQCI1GA??s#w6F07eG^X`CU{EU?kV?_(hW{Q?)b=THlC`_Yji#t9o(= zo4P8&ufYHPWXyjZW1Hj#r0xfg9bgEa0qLZAV{Aya57;m0=^+3%1L#UsSXYqeZh3vcJ|JJiB0_6tFHETm>8ykEE&cOpC^z;?ZY|UFv+Q1*o+LhXZTwwF%N=9E zF>5Rk_lln01S%9rs`Y9cJo`J?Zfx7OZQIF>&CUOPchByJednB+>F%k1 zPFKx`sXEj3R6P0gml#KaVYh1TkU>uzx>bT|!twFngggjoo=`O*$T?rEv#$9kI>Wo$ zM8vb=XAw>yNR8+tUq z9&u^UU-J&}qM(A-F*>$Bh+;^~)0iW_acAxBuyi`C0Ox2d=NK^8d`}i~_Ou5+?8t#l zFL7ed@8`;VwmdEKdfA7Q!@7fA6eB3)Ic@vG(1Z+X^{D6PPq)`1$A{PFK_I~%m>jiH za$;ueq%gotS3^|?_KYpS&I#EBhYRm=4w{*wQYaQ{()PsApE@)Wrioz5KD8jm5894d zb{FInF7|(bfQNXibZS~%|76FJ$wf#)$9U~5et;I(K|AM%xjx2>?Rl}xHlU>)ePHW4 zlW8NJVq+NCOg(Q;xyQg96YCApUML3XYVc|N66TA7X^)C4ecH+WrB7^4XSV=nqT_!G zu2zDuV~e-Jhv&_2$neO8%h$5kO6RA0PlVG2(pi(ALU&gPrtZGJYA%G!EckUkMz}<| z#ZgG&)9{*+Pn~YH@@!BcUk4+sX+KZ)CIv-PJWeUvKKxtK)$`>PqwgcrN^1`$cekQl zfv9;`#ZGyWnN7PYt|tMEKlcy0p%L$>YAq|in1Hy;Pnm^_aiH+3L-5ONg5G0sDovSH zZYI~Xz{a3qS8W^V^}n4cx_S;^_Qhklwdss1(FvSCUpaID-Q(qrJ7UXq31fPQO59LP z%|8L&ANDF$mSg)$zD3F0&(%L~^y@Zg)0=tv{1r8y&+-$jrKUtF{m#rPkw7$ae>i1R zXfdi<1&iM1XoHlAC0LiQDq<`^1|+1@Rn{CSk!p63wJZ6AG-a=S632AFrYYn0N9t!F zhuyUHf;;&;Jjl!)SVqg;QS0f@5e=8P1l0eSOABTA)pAc%1uJxEoM6u|8&xPqVKLyA>uH2!Cgeb;X-vHhSKTvsa^iBK8&LVizK8LM$ zYhUNx9dBmX_hQVyTrpjV`+UW}GQ64HlW80i5XTz4RhNk)kI%T38~f&aJ|n)3T*eYS z((0fqtGvtM-iFWvVu~p>e}9sVSb;{l?cy{cEE{2@(G$+{lw5NrN88;#7pOR+u$jTU zrjESR`LAsudY$zq#Y3-%U!%cOkXf66e9P+D<18VpO2oPvnT*5qPsm$Mh2EADtG+1U%ASOCCsV_5I#UcFGGGv}v7LcS z=g?Nh7k+CfzrItQDrbro-M*|ps;kEeTuF@-P!$L6Kw3b*tVzyQpYDqznBNfm|=)%?kL5yP<#id~7x2ESD)nh{^8%R{JK)aNrbY zJI*Cm!0|RbvRehbBYV81yFR%Yifa{2V!@WYW=oZZAqpy87fl)6!Gd-X^Iy#^m5xkNLIpRf4gjV>r z(_}G0$`jJvV~cTKoK#W$8C{Kj#z%7Gkxa@ocXDR`w;kj2&p+dm*jHvPdQo~)yxgc; zW2}mo?qDIKeow%OAbUuhJiU#uKByOi$zC=H1TL-TmrM91N zlNGILs5WvDE!(QYO4jwMe+t+NTPbceIM&b%Qx+KTi>0Q|%yhj2NfgSAP`QRG&pQ}; z9me6>{Lnx@4B^1*YFFrWiGZi3fzY6$Ch-1jx~2o-%dIqk7;KZu@%}3LKbh2=1lZcx zuNDj25I%Ah-qpmL7PKdpAJ1r!&&=Wy+mGR$n#ohks~rjm1(VLNdIJPxOH(i(|6a=- za*LD`vNq=e{EDk{Z*JE#|JRyruPMTWN2R*Ha7*BZA=pId97rt;p5Yc=o8Co?Rc4(m zuu7TIL3n72e$0b;xq8)K?TWWdo>{4HgUwrcKdZm(v+J!LP)*5}LRq= zlZ9Aq-Ulw+i3=L~AVL+cLM5VLy-e0p5|WNU7?!FzIOHR;L|E!6+OGJQu_wD?=5*AJ ze^I^dyXgnxo=ZmO5Hbxc4en0kKk8W~1Io(COOb3PJ=lxh0`i@-qD+LPluDbO^)x~u zy~L)jG~RNxF`WbZ#_53Nj<^5v_vg4F#mk>qle;^@2l@tX8&XTwETbd#))ikwR=XmN zCr|&4Bdy1PTSfw$p@LagI@5v1LPMbHGWmP)A^Li*KzsMH2ec9$gZ1=pH6+y`^(LAG z&Wzw4oI&3ka{Oh5iglgU2PQ79DHIyd!7-x=a@yy0xWInQ_;CD&^O;}fIEq*+R4;n6=;o5g=sQ;@VBy6pNXLaO_*m-05s{5k zsk<}vI7H^)b%N5L`F^P!_K4;dPIk{)+}GQ7WMk}Cp;ILT85sGnv(!Dmz`cZ71%u}X zXTgxwm*cB<(&P3moAa+&JwRC7zJD*X7I{QeGZ;Fr<3lv(+)8#f4F{RZtTyl4XRD4W z1sFP60c4n3^V6>kahc^Am|bU4FQ1qO?m36Q|8T5MX2Lug4Wo+#M&$QZ;i4XsdeO#7 zCi-|$n`J~0mu#8WqF~vqNtj7MQxBK_S`%U!?igb!fzkH6wS<)@%tZh;95crtu2}hg zOD$LmIQPQNP^0;X(4kA_G;T!7A5rCHD9VBrOHz3TP7(v&nV)e^@UGfc(cfZ_H^iYEtw3L|%3 z&^*NB+34B^AWLEE7ru#_yq{{f%puZPV0MdGqT`15w^L^sl5?S=Ea)L6R`2yHH-m{{ zUqp2E*sqnK*S~FtEebK+z9{d_{^$qfh#c3l^z!R~B$qj|+!n4d??43(WaqdK2D-5G zT|<)y?0C1nA8);`uiMkMD~{Zr6J)~|ES5w$hq=*0c?WAmNgF8rp$BtM^D1iqwMJqA zW|=(>-y}`3AHmZjn;Q#YM!O~c36~c*S3=%_LwWM6aC$W3N@wMk ze7otRjLiqU{Wm33&IRovrrh)*3m4JqW3S4ID03-Ls?``Y57KN&68L= z_yt?;!G}{tV-Eb{Ap*&X+IsDdLI%eMA-4U+IFPN@k|9{X)eK9pH(1_JhF^wJ z?glPy1BbG+R-!{lIG|5q`9$m7K=0}gl^huJ7LxzB7!(|MAG6{3Hjbj3%v0CuYRB}2zTYt@}4mkA(vt`pXV@o>NO z4aAje>~SDJycF!MJaTl+ji$de!peQc-+hoH4oZ58O zfd?vQ>G|&f9M5I%TV8KgTfBAQPGk%gysRE(AANV#6w}fj7{3`#kbO+~9@9*lX%Qgn zK-U90g*;fvPZ#|15bBZi>k}8F^hzu*7Jk7N_AMSo;krQ` zzZl!8TuLG>sr=_=GMp^>5A}o*)&YoRglw7jw1%>-{x+|H_-n-IBWWhvCS!@e9l3#@ zr=t64SO`!4wLvT~x6X))CiTAUkm(=Yyt{=4bY!VrJM6AIEIBnjHBPR`=0AJB^4K|) zG_ZP(>kmd{khon80Z%jdb=5sT++~|VEZFRPm^ZbO44?^Dr9%B`sPG83NrFC`w{G6R zsf4l<)qb&&W9X&BYz}Rcq?vXQFvW~R5ZJEGhmu+g_zlaB&Z3MhR~l2}f*Q#onO z1P@wc-9%mz{&iBp`;AR|aEebezCeGiN*X+RQoE*L_F7Z`8pLeyok(s!ZHqG zV9W7$*BgNCe$y@EOWsm!RKKC4QT_uh@J!aUmq*I$EG5CMnPpHvP|xV5-Y-$=RHHkk zAA?hG@csJ)8YpH35=-NlXUD7d+JezT0h&qR#Ng8APE~*1CXL zOskiOyhdl2?|d2G&6?%yo%GifMK~X4o$UxyOWKOU`G_XoCNju-MOL&J#4vh>^x41y zs^`R|UddIlQt8JI^O}W*rZPRD?(=6i zpzO%AtDc2utjTQzQJyv_pR?nyAOALVT?30Y?t&$71)`YKph);d*(t`pSy+uobt!9> zGE6F-D$D_t99eelT9z8lMB8a(hb^q(?v1DkyEr-(`j_eMW2yP0ZW&83602VP%~mAR zgH$-*b-S!^LSH-d*_X9{{4rUlBc1{QwM;*r?ruyUi-#LkE~uk0oHZuv;<5-!QpRQF*}#cS!d)SSmO@*Q&abuf+<4+{j;5`MlTzu7s7j zb)Gxvm~1bnn~nBF+P}AZnCeyx7$>+GB@dKMq(wc zQCb4Kq+hpD(x>Mx#{-u&3Mn3_T+7xcT=)Ml>bEELEwMJy7~QK37Qx;bA_~lmUBf%O~e`ROWHbkQrkaf)gxlsqi11Zgj4Js}8B{AUq=>gt>h#qAbsD`=Z9f6WBb2y+TrMQZYF23-z2qd?Wv^db zDOZS|mbN%aA7q7DM<(B1y~W<^4Vc*gL)gwp1#$J>>g;?p%xik8ev7c(^j*|4;CGRM2%QDFqRf|KGd zJc@}NA0bMk?c<$e*i@Q?VcJar|27&|_eT!Ofc0gbT-C&yln}!7?oOBeTSa%ZgO_h! zOQ6ydsGbyo+?>vfX&ve1JAeY_9&jH~mvm2q|49<{E9zQVX-wWx$5|r(ntOqgFE(%V zty>V)AT{b}gby7lun_i9+A!%ag#6M=OdCi!UxkcR$(9v#FlR&qM!zMO${I1Y95JK#@hoy%v^DBKHXBe2(oyx_VBIf! z0S3Q?c@=d-dLf-*4ghF4OujGR_T$2fo;m1ZCV_tK24Q5AQ3XZ;`O@d_LdFL>DeH

0aQRU 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 z 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

CAc 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

escjV;Ms zhED2ZcdQ0{r7AEm^|~RGOD{Evoj>+7oS##Q-zY2Bp09URYR-4?>M|!JCK2CH+@jY% zzG;^E43%3#>0L{gS={qS`LWz25Ru#)O80^9FJy(EaOJT9X2yA@il`P>CK-s3=$?a9 zzecJ0`22P;xhmeT)(lb=d_nJSgwZpYf9If@AYb~#kk?MsQU$>#Y@1%aAC5HzBbf<; z^Pi`bxc$RcRo^Q~aP%G*-tR|j4w{+L;33U~k$?0qjL15-VBodyt>*slC&qdSM=HFQ zJ*E%r(d?L$ycqy*t@T%LMQM+QF0X=y7 z6KAd})AKPBg0IMMD4h2dyn5}b{F0T0Qn>)3H?^b`;)E!PM4Ia#)f|yjRnDLkQu*{K z6gvh@{R}?xXh*J!X4=)d&?w|>QAN51q;)$7tMf6Og?jaH*%T-Q7YE9H+56cQZIp%>FKX7A*e`f)Nd$*N{;j1l^ zG7eex*kG(vx3|OHxV1h0tTSlX8OUokXR4w0UYs@S)IP{%YBd&X*kAuaTJNCLC-O<8 zQ-|s}6pi4;ts!k!n_N zkq=*l76;WFwcmN}8Drb}G1`mf>AIZ;8BOBZ?S!pf(*RT&n7 zOOnE8Wtns4HZEftABP7UlytjRR#F0coIbIvjI`OCpc|1&A|dDMEc*I2X2=`Yy8Yq6VMy=MlH8{$b7)bg;16WhK=1Tt zr4xD{3A%{kFA6-%xYla3_A)-m6)-2NgB;&R4}ToB-AJ!q_?g}!kLZ4Pu8w$hEuE<8?aU-@#hHN75lm_J14kal4Z{_4T zMY$gPb;nK3ZmsTakU~T+Zv(qFVS%oJis*gnm{moIbOhVXhBbqp;iWtq_6B5l^*^l` zL>x{(yT3Mm*(rMlLz|(!(tdVbjj}DyC}#th(M7qHU{37Z%&HJr-0QHm?5z2Y|ETAk z%AqMOPl&U#Ezdi)vY54h_RZ0`U~H||N@^DKh^gl8q|gUX!sZc(77w7{IT*+7%sx^E zlAPzYeTvi~+6QyJ8{~+XsLV`j1{{q((e1Z*(_G-Wq`ZBJZWmMr(TayZg;;8nZbd)# z$GiqrWO@MW{4i}RBZhtgS(cbmc7Pxsor))EBVQj9)bw4s{N*{F-d%BMH+HaZaHx3MesJ04et1I9S>;F9 zXcf>cwxENEsZsH3z3TicKTF4axPUlX8E~y%cGaVvtTp!VtBy$a_8Cmb`H!&?0~+tj z6J7>i>3%6xwV{H5XO$D3rl4-wDC_IU*muWd(}kqZP|TH_Zx%A5n%WbrnrQzPGU#QO^)q9{oLWV94seLcPqE{+=o_cX1bZWYP<{hvEz z)&~14i}DK>_Pe-p#$`aTkaSOH9irk8>JJ@bd;KooFZJi7udY0n+5Y)kD&mZW^pjUwMTo+Z=(8Yi*SXIYS z$}QI_kl&#NqYofwh+8t*;Xq>S6s)`GSKvVzDAnynRBk_ee{scwensTzPl@Ss=gz~A z$$YZM&U{QXJALrcncwQjk6RpbaSz=Pp9X7_O^Jr)vWWS?U*Zw2SPAG9@o9XFC*&Z<{S^`h-!3eS6j#0tM)mAjQ3VB zv6O|k9{O;@7LXo9kni9vK%)3; zblBUbUdZoQ4_ettgZHXL{2S;x@N6So4TW^O zOhP$6E82G+RA)p%WCC^n8ng4p85?A+?MiMdN){(@QXTxmX9P}t&(b0D&(0FYz;|9{ zwn`e$9AF}JQd>gVUT`aPt@kjP6nAVk$n66r4W@RD!~2p8J7=gdcN9+Cs|uTIkU!%_(F>ob%8-?9Xc>NhFRNzE{4o-lSBF~$8A@Xfs zk1;Z(L+2Wh)dpNeC>G-qS}6CBJYQOTbE)OMGT!-!XHo`xQ)w6|1}oYqb*DmHAn)%2^vC z0S{ZeSD00Ql1sr&8SXe+482=I_J#-Kuw8VM0YE{Qlhz$#L+(Q!!t3dH8^kfzu`Q^s zy0EhcSJw0~p~?kB5n`{yT?e1+sWlQJpl-Jf4$n0}AVm~@_{r51Vi*b<>Nrj^FQ6s+ z)h~BdAhUuG@r!3x_sdVtNfkj-cQSZ4G0K}^gq~Yg+L71}98t^M64#V7tdp6Ryso8B z^^R0>PrCj$Ies9KpBSLd1C+gDxT2-WSuO+-DAFZ|w2DHFHs`wfC9qI2O73W`!O^ijnZW8T}pH&*%fff^CZ3K(|DEa>VmePL`r2j69=-tP=-<_0~ zH#TAo-}n{jER`cEu99%pL`=poowM`I7!LF4r>pQ=B%=k^U5Btx^FN;EZ!F%w1n6Je zVgKRI{?*j{|BC?qzpdZ@?^#6uUUU90h_}D7e*bF|mWhGkZ~Z82^Qt8xfrN5@I*;jL z1u(?@qJYLjIa$aJ^%t&AT?w>tHzA(gXERlvbPsEm506#-PI~hjP0_bCqxW+*i#~?M zWzw6S`IXs?Yi7TTLgaO6T@=SmgZ*PnnsWt#U9y@qo~?(pmjI4tiy?|CN*uaR zYyNDZ*WOu0{=jJ0&?ed%)r3zd6mWXE^IHw|YX{^XD8>;&6!aBBO8T{k8jX)^e+iZm z%0Zwl1{OLMHI6xm}KL%$fKDM?1WWYBT$s0<034k=h7qwRRe;wg#TatsN}e zur~EDG0ZeX^c=zU-joyekTm97$2=2wo_+FOQP{R%BowQk7>GuS?F1KwlX7&MA_oX0 z2)(&7O1+^>fYv2}P7pIQDl6~gfivSC!ZW0}N(~eb6_WCMY>BsV;ikn5O~(xvJ3#V* zfJ$o^vy1dVhk}@kwhaI1h4`5t5bb;2MZIA1a@Hk9M2i@Z|Aua5Tx2Nfj$KBff=HfBeQGCtQhSh+)%rLQON zA(j|wW*#iK^A=;(4_-0f4QMWWBPXT?tx)-6Z|B{AeGPCXi?5*D#iS5KT&Od`WVzK) z)i-1^#+a}f2D(o}7iXDwm~j}9pM8Y}bQ8ao$G@g@kXV2yqv|&Q`YhyY2W)WQtNW%$={6|m13?I-4dPBKp!)^Ky|WNVKt$gS5(8DY zx^&HV&y9VsCjCJ=`uh%pDU|SGJ#2JZJ_B#vTqbdxA)luoKg3xci9!2*VPhWq7S&P; zCDnC~WaWxJCRH}3Dm)ZT($}kf1{vHWMLa3;>s$DKL5&~nfhSl8d)>iovO(WYl%&CB zSW5VM;EENrX_YV5DiH5a06FU;Q=}76t-8=xCCB%`cQ4ls;dSAF2_3V@Q*8CDT(#TR zv{tLSH7wFQr`zcvMh2cOF1I7ea4L7kKC$2n*X0b1e81?SA04;;R}jb9M7vipex^o~ zL>0NRmm^;?xTOuTK6M!+Y?q!)0FXN58)Ge4YJ(EpcO*JorE(|CiiKN$+w>a(0ES=$ z(MT!%;M3LngP8{wCp{ZUlu!n~re>zn3j>^vbyfQ{0NK9@=5b3cO0MQ^YV^%$pW_){ zVlXbIn891p=cRZuR=iBKXyzbAfE$@;0D+!+uiiq~u7r)(MF-HE>~eP+z;BlJCa@M> z+w#Q6JvB>5rh-4KJ+iO+Ux@SHUZEg2V2&ZIv)Hu??tVQOCb#jF?|6Z!~;lY!OE7a~Y!7+N6F;&j68FA;9fvB$fiX!53? ztSw#R9|i8r2zCg@6>GJ_NkSdRzXIn~d7(&J~6rm;fdsW_UwASGYjM%V38%{|e*p%yqJ8+8eK!a@o_(}pm$+jbEv-S^mD z04*qRnZ+0{$}|Pi(1UQgPHuACDQvuIXS@U*zMjcPYWs3OoK*3xHMaZ71&g{73A)RLytTd$o+`rlPzwL0p;HW7+O z-NDcthssYq=+7EE0Cbg!po}8vzeyh>oA!q^(@Tyk1uJ1D1L2(Wu75)j`-oW8-gIbJ zPYp9~qIh`b(1U{~h|jq-i!XrxmdsU|?KPVDNY73&*fx>8dNW;8J_9{|`>i)uMu?Af z<(x}CXg9e`a(#6g7ctUjFot9ngqx?{#zL2d_ZTxv=EEI8K+-|4(M~4m-z<6fX-Nu_ zq~Pc?wo8x80vw}N7#jhcPyU!VyO|xm-f*Q*7J}?XlZ{qo(0B}jHIwgeJvZng>2-D^ zNYk#y)SW`ZIA_>Q;6&@XGd1{u%5L}*qXJXeR}8+zoq@fjrFnApcriolDzwQ#yqpl7 zAM=a>f{w7v2t36|%yC{Sqyx-zt=4feshE|+$Oz-al-eg_;I)FSlfizeaI3Arj9u$? z^4UN~9VchHPn(LKIPIUNAdbH!p#Q^M@SkR~e`gZhCmnm(CA~porC+tT9r(YevBXR) zZk1VgR+w9t*?`e-5@dRSYPM4hy9=$J3R`;^a7EjvSyb67Q596irH3^AVe0Uo#rVUjdT;=gesA{~QbXKQHoM`vNTNO#k5vNd3gIvbdQ?9UfgdD7Um7v zb)zD;fw^=#_6a68907`9K6{@V293P&a_HQ19e~``re#ld0}goj%IZVucz@tnPVXV> zyOB%WsoT-~iKD3(PD&*ymGr>0Cc;#AsXU@YnUqJ9(xGbBZW30cVToh4mTzQxCT`kp zg{b<>jkqiY>ZnhXMZD>+UY-k0GowMO9&O}p9IvD3q1P5cKu+Ow+zaCayxp;KAwar@ z<}00xjJz1y6$Bwpa_+AUvrtZi$Uj4WFl*ZZk?!Kagw~Zbg4DDt@#wJkV`Cbi)0KRee#QGf*T0zbl;M_Zqu~qbrEj|*(QQ9D?R^PP!zd6#T=H=0Vd@)-0r5|Lyiv(oJ2n_c zc)sxYKH8Ve^gZU_vSiN8CU!KIR0vxZ%@nGDA?8ZA19jO?%)YND$hbBe&-Dfd8yBvr zWI&G15FbwnX`fL~jOWDG=V$`JR)U5q9XRLpa>A}sv9MWr zEVnSL^w^k=uC)86l;hdcV~Bu7JUAZg)n08~OOqh$83wfDM;dx{??4;vlO z0oHL4WuUPa*;COvu4rx7B+cLbynOC^czfmewni{x<61;F=gx(Kc~b{p;-J+A7<(gX z1`$fazi32xWl?IqwZd2$+J%x6=Nfruy)Yu62!J{Hv&R!E>APk|M|CWP>1IDOlCBR` zSB=G|=wST7&DSXs_?7#Y9)3Wj*lbmV6Y`V3(ED#kb5+Hm19;kLsqhK-w5U8(^E-E_uJ{P&^RrA?w44m;7?+7KMmgG4ERc-8#EJCw ztpF0#fLIO#uH-NV3TE)ya;+TFR=L>*WSd&4uEjS0y~&OR!oKv|#s2ElNB?}`L{k-( z{e)a&YDG}hRUS#}(Rzo^b3|n(F+w(D(eCr!o1AH!ZOix;+~z_4X?+aWts-1$Ta^wcT>G1 z(V5B%6fS9%T>*{30>!fy6rPh}+wyvbY@W>dr>~VzHtcfF4 z1X1M>-NxR@_vLP9$k+t)I)j>hbrOrJGyOpx|={xhN4kp_%*=@UV)UKgcGc@jUw zNADBGq?t5!?O9n_qHeh+owG$F`qRq^0So*9V@jrnHZ*T|*1?*Yj`yLb@ z&hR*~jz{4_49d#jRYic_49hLFrIkY|$bcmMG9&&x1nP$_XP(ofWV+Nx<4vz>I+X?6 z+5x{}$+A&E3{oPViU(r#7i^d2Z$Q0{;^J&T&ZaOBLVkRhwW@+D{=j@-Q$aO2k9QoK9Bw%+qo(#EQFL+RP(7~Fa3^_xeeL`rxBEOgyZj2|6+WNcU> z)L;F+``pof1dM{KguE@JFkS!9oR~_s+ZNqH`}3L_8w4coI=xq)$svm5Y!}FR%z#3J}IZ!fw?$9{4KQ^Aa zKDk^=5NA9|nIM9)0OseXkgz=PugOVtH4%<$NGN4V=*GK zXjseDXEw*HyAbm@LW<>vss6`(puWihowJ~v$O-F6Vrg<4$uy+Eq>h@Dl&dLPWl3<8 z%H2L1vtC;tHTU=L%vm`tCG^^G9dM`l9~`aEn{r)3p&+YZ3UT5(C7=n4OV}*qFE6F? zXx_K^`S6nvRC6eWY&2K^v4}8?KLLL%GfZiRf6jrWMhwTsR~R#H&$ne^R==uSC4AQf za4dZI&Xg?AJA#$AT6hC##Y_%{&m~2u!fx=_g0V`+;lh_euzgSD)&MqS(8I`;#RxPg zvD*D;&x@elJ4y!QlLfI)MCx}A*gcX^kI35jY^NUJO5-efpFCqWNi<`~)XS{zT#_KX zIpr6oTr-#epW_08qAh;34tnb7Wh4S1n7n;ZMD)83K?usjS25z4h{f*wldZCvcQT@Q zZJWT+E(dNVlyp6TDGJ*UtU7#*4VarWKaUy2uWgVLO349raLtI);zK-9=XSu9wp}(Jt#dCOoQ1zAnN?}0WNUvEyPVau_2%Xu6F|41 zk>XM1$T6SX+o;R@Dl~Y+Dnfphr69sY#6IyW+OEpuwf1)e({+?;>06mZJ&Klvsl{UQ zPG^we_)B=3V#*q!hE%?LIxYqO(vwtanI54T*(M<C2Iexh#95x4ik~y zP(0vL{sW~C#Lq*v)JZ7m2w8#BSL){-DDfe#b3%RIb&%XNw&^R4p0VQN<4(mbg@J%6 z<$!lS(}7-L;uo+B-f*dCi0)w5N33KUPKfL_VzzWX8J`c} zd$Ul|&vmb9)!!Ti%C^>ftW+CQU^^D0>syVuz&Ezg6|NkH<)=jmRYlOlvE)JCojaca zIxd7?N97F2<@#7n@-;)AF;k#Db~`;z+q?9Rl#IVvXm8)KSQ|1OJ!wlYhK+AGZ<%?@ zFSQ%&YE1IOGp7fu*c2%csv6`Fuj-Z2J**xbXWODxihgqMNh_R_Z^XYgy(liX#!2;u zz0V+tsUeote`EKuwI`51qC>`j1P&?Y{F2GWqEI){CV3&#TfKpJ=1u(UQ8#?Vs$ zgx}9^e8AV7ut9+EVvYFzQ1o$Y1OZD8P_9v(zr^dny+I=5S^H7pr~=A+Es;7_9j?wE zmlM`CsQ0WSqOZo=LJyQ~$3tYoM|8jlK2>1R`?kt5W>+(L2&F<-4zPP{W5QDHBh`j6 z3MsRqj6&|z-t~Y<(J&VD!IvRrpPp@jTWRip02J=J^o7X!uzxzXq2xAKuBt;w<3uDs z!N|{u%mV9CL=vXNK^>a{KGgqoGO303q97+UM;n~FVN~C_?4=Z(Mk9>e%$Wv}<}@rv zM4P{+u$ZP+NoGcOyK~^OIOhp>vr%+nA~t`lSVkd@Q`B_)q1QdHHzw|Vtzh#ij~re! z$RR0c-sq&)5K>X_`(oJUSec-^U9?=pK-x5#5$gKw;J9=CmGcuWI8ei)X=cY9rF@XC zK*w~Yv~tT&wbU6o$FUQa&QJbWI{#cQbUutf3HE^)WKedf69(9xpoz&KJs8Zu{a1+L zB;4TVLQW6W}kBE0gt`!{4{nNd_=soqrxB8(|&J!J(}|qRXT<7YJT5jp*8W zG~~KQK=+ou1$aLPB(H7pEu%&5{o#geiu$ZO`ba%h!m0&h?Mt=JAr3G_xY{{l-(T|j zIUu&@;c1!}n{rk(1@mq}@>ebTxr-Ex!Wfz(I{b|E+KMF=0n-`qyk5wqj<$C`%8qkfxpHoqMN~A7x>wcUvTx^Hl6GSM7_=oVi_y=j8NUYk88A5LoS(s5f4Wzf zBr9s78&wC0j(k_qmFM!Uyqc}<$R2E3E2*GWK^}6znvnl&tAdv3fZy5H@JE}o*(w9H zjJVU7_q8x0H>e{(gJH}90lK875rqre|8|JmNA{h=z?BjN)B7 z&K*M}#4zl;n3JzDgP0CC?8ztPb=CIfE`sD_TMi+{U?ph$jJ1+E{zY&r+8ew#i5_+ z;hI4?Orz1@!WCtQ$XtUHw^~ICCp4R^xD6|$wJ4IET4oMhnw`lzp2W=l_PUk*-5k^{ zEm5&55^8&$_`TE(itou|Lxvf60(z(n{gyu8v_}Ij|NVn{@||ZDacb@kQjon=+38s2s$p-ANj?k zMFN9WciRt<5visIV7M|=w8%y=?Kl2fTJdJ#_DibrwAiZxX0#qwo%OW1hB2g5uU9&) z-)*Z}J|IW;VsXUdwY#&vqtyfZ+A!3a;^9L{ilBJh(&5c@aWf_Psh90(HdU- z2{6?KGAn!8RxrFw2cofqT3U$eSkDVu3RVk*3JKdSd;~XM_^XJrFX|6F6?N_QEPAbi zz%t>WLY#kUiiEBM9@UcjWp8fBA_wZIDAy1kPK`B)Uu=4u?=@}9(KQoKsX22TE|Ccy z?cRIC5={=*1keeu{87!V5PH@|;tu6x$o?)#E?sPPB_U4LYcpKGH_B}n$&&yjw0O!K z^#60}Cxef)tP{N0iir;(u-Ibb^F&|*u^5>tA(<^O3X;%@Z#3>u=2f+BDD$WJ+ z-ZQUB!euTkSo$PUvQYiZfzW-i;U!bXtl*m*%>4rflZ-bJWSBl9Z7)Zxq#T)qn>QiYTo zeT&b4C9UPG=#$ZGOtc+m_0zb9vR&@6zKuvAJMyQVp z$QAm*rjMa>@RJh2W;99dnNm*{hiT}|vNvy1z}unnsGkK@*IuN||AV)83Kk{onl!g< z`)u2`ZQHhO+qP}nXWO=In{%SOWBQMYZxn;ex_c|CF5b+w^2za!aDwDOJ=wQm`pfJH z^&SwU=DyBN)Hvp(QM*Pt*ehcHE6_;7RKvvC`aSaySS13N(CKK;ETBBiCy$1s&}k)C z@wob2W{o8COwKSdgRFqgQ3ab`W-(%pvPZwW5kAw}?-&!`mfw1dQD}G~CsE!rw>IzI z?qYdPhWnPy>->cP8mT26^mGhu3RfVh=$H>0cI)*Bus>UJ@EE3pdnr_z`)$Q8NC1aoDFkvC@%MznhN~NeOy2x) zZZM}!X;)H#pbp<^ps&Yt`~!B?2?SDQZ->R5u~$=#<}@}-lBx`ZDFXq!ISG&1(Cx!>No}!P)V5lBhaUt6iIjdN$0U>n`+DH*VQ7>x~4Z=IFHz9$ngTY5DHf_8|oOGJ{KK!Xqel)`3xD1-G|-^5lH3;owmh6K7&_cO3l ztaebPzn9N|F=fwxu%^?sWnO%=NMP&lve}Ma*zXH%Wlds{vC@$>rqySb{CV6dV{*NS z;^+3E_Kf^V<5nJdMrZySbJgk1H!TU8S_3jwUJAmGE<(cO=oX_rPF zu#{BR#=<@bKLBB0L@dk%t@Zod0wf#NCQiPz8md`UzV(PwWTNZpIq-Rhp69qJ zDsy@ru?w!@gM@0c-`L0tt+)6ko)phIsHs4@7XNVNn%~I}l2rcFd%&us=6|=nFm;B- zqh35?;MssLy10mPZ(S@(xI@K1Y-$l0C=_;!Tc5|7LXntskTH+5O7>&rVweMC@45PP zPJwzTlT0+MdvF{PLQwb$@SKaSD8^k7-%Z7OgtnCV?PLMYx*_5z-4yihXh@oKg-=j% za*86bIUZQ+n_yN#%8jit4QqZh?lnAK9JiWKM#WKmYhzlyE>qW&>x>3O^uB`R!Y^i$ z;soZq>&5rtgVgy>l(T>?a!n{C$m<(PhjbZ|z&e7^=}NI*sgPlDylqyXd=QJ5ww|#% z-iv}RP$<=c?jF|1!q2Ep2!lN!uBdHRle9k*%`eSzwUqZtU{0cP3 zjH{_#5q^v4vm&zx0N;F>?}UbfR-V6GJtWoZI*uGCx-T zwKIa5+0<$eqOAgBc6_s1<(pPE$0us_Q#D{*H!JQl$-nDuqq?z0J82agZ{7O&y|v1Z zC9=*)f>S1m2>g-Xn(6(ArtJuuYh8w(ml0^9p7YQxPO=jx`VI5M7Ez`}?QdMC5aMKj zEedTmco;%F^y0*1c(L@2*|h+m@RjHwmY{E=+IH-?etLrnfVPYJkLaap4|d#fD%Tsc2!1uH@qzsvjGOCBk3<&z(Kb`Jlh&01#1 zBq>Nem1VPp{@PpP4Ywc(ZQCMri1D9(t&F9@i{FgO5Wr<4Ta*E}#eIZKq0LB@_s%V% z6FP(6ORc@ zY-ZLyoO40+*^Z;E>He#WiE2aNqUqbjj2m9@+Bm>aFA-vz?#8=uv5`du2&WpS%W15^E7ONc{~UvI@m*s=mv%5%Kw40>180T9KzbYVf%2<6@*q3a5SA&21@ znOe3r2irykj8JeX)YZ%iueyC1Zy&t^8TYorJ^s_Nwo7|Ba+h#yQyGxAP;ZSGzTXYU zkla4&I|Le<>8RPJ!H`XM+0oqVTm4Rx|EOC23myDF+~fZ@B8-Fee_w;ehqZZ6i3-B4 zT-~}-Qc=+N*|#_wlh`>foBZjF=jbWdnTX{*OH9!3gq~79Nl`TDCqrLRza$mQQ_j z>1hNR(C?SzsA5}N=GnXY`l8|BN-adlszy>ax{&zmwc)yyyXrgr0l+mwg>TtGw4Rv^ z>!WuhEwueeI%t$qYrmAEaZQo#!hn5H_CjktqTQ8Od>#_^GOa6)tb#3NvxUR(p*toj zU2$M%r4R&{Z$MKE#OtVbJIH>$cv`ws98c{cPJL`g%_25 zIQ=JeI{~PQsIx%fgRX zIiBKKiLGv??KjM@IM4P^0Z%#I(xm&hcWQG_ybv0LC{SUoRQs5J%j4=bE{p}mUEsD? zlOlXn6|8gj%S9aq9gy@T$(3+RY3Et(HW}%D1gVjC^i}o)uy57Qu@IjHqJ`chK?m822gMKR1 zw3%2&rk)69m;`i#Vjd5zv;{FK%VJ4?$m>SHwW(fbqi8_9G)`Ee!h`s28GxuwG&`;o zk2lL21WZDDH+$2Fjry&hu{1XfVW*mO=GlL|cg4#Wg_r#J#I2Jx$aICFwzybUQnJ<;!@Zlva`1t1>ge z2V*vvQe*j#C7Q6LVB84slDtTDSL5iaD)MEH_oqpyvT0yr^n_7@HJ3@A@0Ix5cN zX?NjP?yVA$^(#+0~=0`vvDd(vrHts%Y?fBu6WVIum;xT~TRemDj(2MNe<` z(8xa`t#1F3g2>L)Zw+*8XtPK7aIictZ6t zB;C{NTuWS0(=}Q2twN@xaGEwp1{TxDq=SaF?J<|{x- z1DCI7$k7Me1BvOj5_Apq7yaH!=)Oua0QP?2>d;INMz2-f8)f%cu&JN%`V7d0D3z=T z%_4eguWX_L{I0U^EYAiX-6W~Ohry$8!pUSD{P~_RERDrVYkLVG-nlRW=6eiW_0m$v`BvBKgFAwxBdWhHK(KT;ef+XcK{i!I&6*$ke zzVP`y4!02q!fW;TZ^x(WiBEI(JNJF+9~(#17F>J;n)z{ThjUqbH7}k;TP>x02x&Zb zSQPV3_S?HGGPXg2k)Y^C^0w}p#tW#v!<_|ZLJ!K7p+qCH)k1uQuyc2$>xu_mN?l@F znt!N6i7e1_xBdZ@h98qu*-kQ+g>B0F$w5hk8*dEhHq~DEF00fOY3MPE&mksvkLV3h zoey_wz>e=PG_-thSRuOPF!5Jn4D|N)6Hw>vC1fFe+Z(Z)thQ3cB{agBS2vr)mZE)oaY$tR7rMiTP!|y&6_8&6}fXeVP zjDFa!ABt*RA=8>$9)15R9HOP87Q*-Kic;yte8)C;QGF|7Kc{M}nQms@VeB4~-Q&PY zdx@|2J#>_I$wXg0w{_G7Mf)Cr2bVHAy~5l(qMm^@L`XiF_CSMHK@9M<2@#=_A4j&) zL)->}B2VFhyolyJ8GCO9B=dz?83k0D{`_lk*D6K=2pwm z3+u&WotXQ3PTwRIC^(eagbBSYUjoP-}0?4Q` znS>V7TFfv*fWDn}lNH~G+z~5Xt8g{$mp!S;6za>uXlv0n?N1;n3oaUM#xss|3(u;T zvWv{nFI0x9Pi7C=gsB6DWGYqNu6dx_U1k9E>Y?=`yhTgZ?vOJ+y$fp;b;dKr=yVX! zG~n4=nLtS`O#cSJ{ioEZZT&AcBH`nJFJY%ib<4aKRFp7|tDCCm+TH8s8Pc*rmEn3!D`OO6vr9;{G0ZB`ms^w_4sV#p;Ck&G9g*`8dA!H`RnsD(R!!;H~lqbwch&cI=ouqXOK_t0{3<;*J< z)W_qf(yACdY~1GIdsi><-+^>Hno!*BK^O;c*oKd<7tb9NL{-j(gyDzzZAH4!FH<0j z12FcyF99y!Kjv}TE~_RP)>5WE1nRp-0D9JY5`6}yg(8&Y9Md3RfFj%gE>z8!_0z)7q&FX6ePxK2>n2iN`Y|N^FarR z5+zW_#5QKRfZ--v9;`4y{L>13T-IXUhvae2`ZFi3eUm2TR8F`sIcwXvOt$C887J@- zShdTtbclWu%?Q_yoI>+}Tz!-Ivig3($z(o*-y*wrhJRcIl42XM%B_iEK|W~4SW4zP z@m38LI;MjbiI>Qx<5e8B70}ZJs3+lNpiqwn^vBb~H}PE&G_mc2J-!(HD2(wHyXRbB zR;^)<3{6A>tKa0k;`JT1!l$iv4_|#OI7`iXXC_F`*(a_T7!2PjAQZas!^3HLCg^YPDsS=&JoZQhG{SHGG z<{Z=L=A13InJ0H1a^{Jsn@1ZGmEwZ^; zZ^P#e5D9PsAEO^0Qhu2w8@v_$n9DKGQkw0tGqC#*9XNwIV3W^e4B%W!BnA>4+%n(s z`v#|uu3d>=z)jK#JILk<}KU)-5kcwAlwX(A3BOA-4M8`F`Q_3{`U}Oa#jx;L*D(T2w{@YYYQUH zZ0NM;3?~XP2-3Z^?S)X8FY%7bsO?R>xTBOW-&q|{%q3++B9&`a+Kto)t1^oJQ1pY# zb`sfC_>PZDyh|mePoHm*s;!hl-!qFvApMiY+HNyr{VE>jo~mBzB{gf?zD=PzLIZOM zo-FOhwRHp3`4q@q2O0SUI{fzEl;g2a9fDeAO!XuK8 z1DM)O`zKs!qT$twiZfid`sDt~*r0MlzWPtdsC)9G-CD9hfTz@InTw_6+DrE3RGsBa zAIjH_>-Ggvfd2l;-6!e-Z>qnv2&{`s*Vk0d$*YI%kg0LA3O8E{lC$OOQ>=nVnMc%d zyX*jBH8_x;Z1`VT4W%t@Pn2@sXO#Gcm-y6yZPdIQ#0<{1w9~snxR;Prh>9u)&g}hI z@0k|t^% z__&T$=euAf%)s)c&;3CTcj_Yy1k(uYB^7Iv!fzFvdQhZ+QO_NkK!rVI8F0F0OOZcm zX(sgnHX(ud>=op+P~&!A=w{Q#5^}vrp3)qr_IDkz)-h!5^>F4Utt1oqgzY|gYPK^GP3 zl@0%^tJf#;B#i`tU00_>!e`kStEPo~?I8A*qxylmpbA?w@j!xkOqhmLY0L~K@f@K@ z57?)?Ky#PAjoGkIn;{@bpJrB%4^P~Ef|O|uFTu%%rj)wsa5|G64UQoY@&u5wE$qP+ zkk9UMsLZFE$x))FEp~>I1`~3Ksn8(xERn1-19kp>Kx1(cf&1I;$h^Ysq*$vCuPuk8 z>NV}DS`}2Iy4!q0UW#`VVp7yK}<&{~JkspbL zds9{es@>@n8P?0(%!xL9&^wJlUYX+rk?k`5tfw{-dDr(%E4HcCS~J0&smw?#n9BQa?9|^@~%KJ+P07ICG6ST zmgJYy9WlS*hN8CdGGmv5kneX(J@I)bKu!N?Y7c;eYUrKV;%vw@rYiVn-%6VYZA&0F zRd$cgl>aQ~-9La%SssQ6B(D(#=;L^vSRe_=V&H3{mcw6xbI13Cwth)Fn-Pai&%B&1 zIiw*JoS_1?WXlKFHNSagPt%{1Yr|d03_XMr~?H zPmoxd;wEDt!B8+AJh><mKFD(BfZVB%)+vRTAdZGh z)8ClcJ@{!O5|&l{CNMXHQ+{pZI-FY7F1K|&lcGtpgFstgC?ua04tV)6_G6NP|fd$Tg`wuxFLm;i+ z{~`mIm7g&q<(i!e;IrG`g_ex2@#Th%5>nnHSB&nb3>DA`ib4)W<`(e_J$#Mqb2FiU zSB_@|6y@^7i`}n~{Jtk|lck$)sSw669`z`flKU=e>ge&nu>u(4A@G131?SOp5q8+!j2L`O4SaXHuxJlV3g;EUC4G^F zlvmcdB*#@qlg^sN{n5zi2KNwW&iTe=V+^03U?&>cUP;@Eix4rA7qMV`2rRtmufCKK zW%+ZKpP3l-@aWifr68=J>l6VsXXrb>KKdlP)L<41A0W>q!c7c0R9r_xUQxHPr~w4F zY9V{&?A~Ei^(HmP_~o?dhd6NpHF^3RZ4;gv_I2S|bgOq>&W9CK7%juvEJ`!d+DX^Y z1!Yku=Kdee-T#u!{h#J8$N!tf8~=}^$N$CjW&Xct`u=D5)qi`f|I?5Q3oFNep+VD< z*H z27{FyP0#<7#FmePuc`Y2;@BknfpX5?<#+5q&d8e~*NzUT!{WV>_px1BZ3H&1?g^4V zN`$B#W_uFgXM2u7S5TAywR=1#l$Zh~%`UxmN;|+%JR~7Ym19=L^>zHpPT^XDkJEoe@^oU(gkH3bg}D)&eQff#ej|MFW*%Xh1FKW>0~wP5Qs?9ub<~!x^-5NL4BGE#Ae3v#| zW`Se{f#y|SOY=0*o26!ZtyiT`1kV7~mT~0JbVc#eX<+Q=)IbjiSw+q}L$1$9Oc(T6pKCem0RP*FD+}T&FOx=eL1e^sw>ebOHbRE&JpP z1VV>e6uS@f3t@S0*Tok>OxXa4Z6Z)7L(NIp%fRSAhA7ncF(H1ld?AeTdr6PWOQ0EP z@8kg*X4YG8yGHo?p>1ZXm17wQ+KX?kj(@~ z!pO3a2*20Sg74W3p5+irMv86{1{)hk!z8;LJhI+37<#wzAd~`_6x=Cx;FbnuOSdnZ zfp&FRhF2bXJ3>sk+TEkotKXI@Ey-oIE>W<=7~@=}a2J6)N4sD33K?<3J}ESCrhYE+raBzYhFerv z@-F6zG3Em}YLE^@Hk$Q`9Q0ZqMx|e!TkeYUZLB&?Uh>&X@&t&M*y!-bSacQBaQ5el zbF-Gl8$o(F*$6YG&VD1M`ula=5TQGPoqVPFzMRs#FV?vNL1=Ep@Heq|8<<4wohDs2 zpPgZjjUrmehLt`c1Ff~CrFX@y+Io*-VYVpP2TkGl;2`O?Gb)lr8LThBT~3r=psU3k`-Oh8#7ahP?#|aVI4fw-ewPbf zy7Lj4nc#7YS1_9T*7GS#WR)^D_q3z=enD!jAz}^VYFrA2sMO^cp@rE_` zvp(`l+t~epag{&YDleuF)fmdQLyncfj>=d*GsW+pebF(~g9KT}5{o-popX|1q)&T&hewdHx3*oLrzmvS9)D?MFsz_Q{fp$Gpw~fOd`6Z8>7Fd^NQ6PW_ z1!G#y-*aQNqf95U(uS}~LS(RS@igr=y}r*8k-iYex9gHRg(zULW{|kz20RT?Ey7ES z9v0#Lh1W>C^-B;yRmE<<){h(j+CU0o!|$ld`Q?TlfwE4=Ip=NSQYJ zfJeZT$HyYFqt;-DcZa|`hF-~j=8u?3A)(=hpk8dCm6iHiMYNxn98})VKyULyQt{L~ zWgzM_U`#s9z1_e1y*2Mzrq;J`>Gn-vpK9FE;E%?2fpaq&DC9MwR!co373-=h;fJAp ztB8DOWEo|g5!_gHOYJ~^(aW%OJtV@GhW=Hy44S*Ko{=)mmiRQx*9e9N;%EEEJSsUfB5e4g*bfZ0$>)bnLO@I zo@y0pS|+eWUMgDWwAT2%#-QoD&s{B~)|sjUH!ulfw>TfxWt3ahxF?N?6m=^CD1|TP z*x}|`c4e`0c{}u-nPKCYx*H`39|C>O@kViYTY?;Aqm&}w`JKo;76C_ap; zuBiY)gUzZG4+BI(p*>L9gumsSmM>(vw~Fd(>88qbTKiN@h(5S-c*#C(l*0Vgdqy=< zIzS=B^`-wBQ;OmVt=;WL4{RHy#QKlF3ivywzFItf9g}#J%Ak)sHdLLR=9X{maXloR>f8xeT_3eqcl{_wvGB5p z7vxM0<B$*;IL?rFMHDLWDrT1n)UkVX9Qtd&_CbWID>LCUT$7C`r4N=HliBCJbg!8^>m~GcQEO+}>bm1#5A5!~W}pc5bf5TjAR||xe`#lN zGLmP8@=xIu{Z2xqDAZF9%IXAO%wmT`yKZL&3=DBqkgsdeeh~{O1xluSM(20Tj_9GR z6nqsSEzrn`a#z~?)%BhRc|_wg^pkwm9@rFs;aGTjpa|Uxo16U$Su&~hED6Zq!x4k{0g8HXFZ${3SQB!U|8>BC(EFq0`~R z?`r?YZm__v03Hz%JvJRQ+uXg0S)TKv#@?q9T^>q$d9963n?@a-dU73o2$pta9j;QW zooAQy4*xd}RT*vBen2|$_VUqJd+owso`zm4&6|0`%{Bgx{B z=Nq0xJVuET%aSl703uY#^%zX|=)G9#PXC6>B$M`ZW{Ygu!G$OC&$634Hn~wi!6ICF zlMF(Df-i6ZUw7nSp*XBrvQqp?>%B|yfSIQ&*m!?DQuDub$&cnzz9F_I7nBXEEZ=*k z)c4-y5#m(5DJgsiqUGd(UF7?QY>PJ~pWb&J0&SNKox7XkdiV1a+l8J!*F^Y~ERN3k z2{*F9FH59Ip3eHU#i#+4c8Jm~4S38?q3rpHT6M?0W zN!z)M?2%8F0Mv@jTeP_~1q$f7!zMFL!}I~66x8T=x}1V4Q!7}bAu~O6p`(0Th|<4x z*3kC5xe7K9kZ(;T@`PA8KVnF_^h^MEY*e{0YZ3RrAnfoS7HqMNxk6mR{$4o&1O`q6T_n!NRib$kGr25 z+k<$#tF=>Vj!Y3D7~$~DXBQP1fr(-F*Z4({f@~;NL9s&QVHmPeBy|$r4u67H4Zub& z9eBlJO(V>QEj>zkkQ9I%#RQ!dx8LlzNqQ@N7+b#Ci>;v>H@KK2NBGXhjhS6mSb>_z zpz(trLBP?WDPZ6f02^!^Rmek)4L!qlHASVCpBldKL99d=I+s19g{pQVwXX`gjgEs@ z(mUR|&08Aed-cei$92Gx%B*Vhj8Ri(bSWF}7eeh=ezRE_6Xb$^*vG2L!h%yk+K4{r!6^p8h1hAKZVzf@rjQ8ugyqKTktmAjVsLKm7^J=N88S6%j`&Zl(L!XzLPw^!oEu zXW-1*YS|J6gd;>Byo8Y=fm2e$#hJa``(iN%M4mk9=<%J^AI~G=BIOW4RFm8O=FN@3 zZ}$FT&Q(VvFwb_$S?2Wg#t=xtn4Nde6~!M?^x<46$EdKTZfM?#K*P-3kqF^NB5Y`; z#a|fVb?>qu4()p>kMug(Ky%IOt(_ZQh%j7k za!Dg3Adj##_!Z$|XjN>S-Y3LU7nzr+1X{gpqIgk0^&e-+1XTN9KEwr%ntA%VV z&0gI2DEND`*rO>t8TroICuAYfyi;ADZsAo^U(f{>wW4F)B|{;&euP;}4DJg8I1}`* zGx1V_D(Hp zc^$c$%dun5(>n@@HlA#dcu|4NFf}4)^I5H@^$MCstJu|a=x~(vdt!YqNL#Y44AXSB z-t%k$i)KWa*Q14&efKp?VqHtE1caV#G>M(-Jx!fm)W6B{S@w1cKFaHr(q7Y$V3e_Y zFJ`k1LJ^GdA16xHoSz-Zw@3(LmA&RAJ&v(RBOr;qQ0bblNMWNe)qt_Z&?f6?W8$Hv>8XhrHl`N;i60+6iD7j~5wksuLrWNw!Se9hr{UzG70RimU z=aSXrX@z86ww`N=u>i_i%0e0efUfy?*W81?2p2i0rQO|69t6y zImuniFk+ruUwM1{;L+kxtMrA{@pUMp$k@pqIN3lYgt7GTPPGL^paNlvTnn4XE^W2{ z+NU(7%EF0@7}MHtF2^{{*r_T1H5qG2Znp0`%CPaaK;u=fKl$oYw4BJbt9H4$EetKU z5(U3jYuZ)=2VT~6ghm#8?s3cQ4OM%6&Nuc)=WCZFIS?2rm1|5GIA0B9qFY-W@JyFA zhqd1IQ{yd3^d~~Z{E|k)4bhqWh|o4j5_@F~-Nvk4{mDarYn0dCGu3u4g?;=igFJ?Q z>kqY5iEhZ@rZu)nR(Pf#?{ z<6K$WZ26N8Q;_z9I8o*F#D6mj9>S)hua1^lU!7b1NgT6z(&XNz@k;zn?1&F9)vfyGvbM}h^y{DPc0nJd2V1hP>^9M!FgpO(t+m>? z1U>$FCIG<{pW{pLsbxS(sziEqew$Xm^y%mwGd%mBOm~j|fRwkNZ|5MkUiSfU>?vC_ftks6~PY1q*7nnT4d(Cir*M)aOz%q*! zI3!=xl?tK+4x9DIB|cqZC%{;c`x^1>SUc^woc@}dR!T4&tY10#weEskbdx)^i?Mvc z6Q=^fU4P6+WNL3(4E=v&X!c1fCq|=;SI*X2LMe1xwpYVo5BR$yE}@iuy2sZD^%l+rcsZ%kEBN#p=mbe1c%A9& z9ECEbD~*5c(*em~Mhzj(&(~JGBAJNmJd0FV!oZqPNFjdHMiN^;_3;6!eY`oj zBQuvvhxSx&Qz_if1iF0$ICixxlwTy*OWwoi4%WQe>ZKpsHdN zgEUi}KEf1sf6o)M-bk4DD+Rpy)H#O(Q$_>eU=$tiU@I+sM|94ho9nA?Ois!C4`lz% z@*!fP-Ii@Wqvx4s$Xh&qvF&2EN&o1ieuA`)Vb1y-Aln-!64?cW5LWl> zxuLO6x8qNbK&d%|c|>Wh_Z8fP`P&hkYwNSO7*VNo_(lsue;r*)$X=imj0!4wBE~1USO8Gv3cY{9+45|!clyiv@nFfwh?(DatSI{6i zdJ*9#CH(wC!82c&2&m^xoX>lVUS2XU0o6U-t@FTJLA_r!J!D3vv%18KeGA_WZM9qA@))l^aaeybTnFp zHb~H)#V*_{+~z0RBz4{fdATLIROdGVTcykn?KJe%<>Nbx?_rVTj=Q}erK&J7T4(IX z#!Uk}_RaIK?k7+l(wj_8hwXbdcGBUfK*xZ5g;Pl5^PCwCFD?8N=BV(2P|<(UtzUP5 z#*7mKa6#$|j|JMxvlKKtOkw#1^7vn(xvJ^^{c0GGC*<#}=1%~gG5bf3Hynru^$jGx z@Kuj`!jZ^{adt%}$?bbzjofUjB=FTvRu{Bfm!*NcaHv6ooc8#j;dCJCu`rF3HW1S# zK5Rg~*$})mc(+=4ptXRv)n3{3y&T@SsoG@7FOBzWAsE$Eh^zx~QvC2FM_AfWrtU%$ zD@lPr)HBFAEEppW!Q$raMFLCr*g$kCe56L{DJAzI-vqH@!Y`xpD3^D zVL&~%&9^`;wp88BXF>SCTC8P@cTUBwevGb$X`mb%7vA%s<9@6r@Yz(KTdOhd1DHwz zwd=v0VAc?cJxMjL1;9h*-sv7fRj)M>9$)GoL1GnaX%Gk82wV)fObbJ4$+}U9*vbN7 zZy1=ox0)Wt4&qozV-M|61?z0wRjoTPy`Lo|U(s}A^52{h(h@XnPVN@8{Az0p@srlF z69TFM)CH9ny)Lu(=s0-OIxG2P(5#kT694u^FI>{=CBUjs+It@`2u0ZHliYg`AGM}9 znV0mAyBC<`{nx$^l1bF`)Sh&gPqXu70l7p10aV)nU?gWZpbz6Ck`5~zZz z$=Wcqkd11_m&gwkTJHZL-!JjL00A>GWP}W1r}syqDaa9}Mb2f+2B({gDZqvc5D8BI z(qR!s?4MrI_R|i4v9B)+w@W*_Rj*y&r!t^0bnX#AK?!nCf#;eo1v~GDE46p@oD_l6 zz0W0fajiJInD^f+Z^JIHc4lb1iK92+xBBMYnRD1z(AtZP(|0lNn`M>>qczXb14htn zfIVA7Z5SFafcwMn+-EM{R>9=tld8DTvm&A`7ht>~KYs>`uQoKOJY|9UF64(XiUYB_ zCf2t^p0z(x^uj9Uw=_K4(p2kM1@b5yS|*NHSKkNmPzeq$blg5jp6HBIX`2WY&*}p5 z@%7rTKS9d%maQpYxJTWcHAOWlR1qcdIOzl=t-q9VABFnZC=^O zg@1x}oxNkAbB_TYxLxX=WbW#FNu*vL0!%9N?~l&v;^jLq(^;JW?7s3~;-+8#7MA3n z1Gq?^dd;Aeuh7P&qIwK}_-JGn>cCCGcX7j8tMB)?GjBU;@=N@Eijbyml5URa2A z{c?zP!@8ze0exqD6AK)7Iyi&(q-kkQ^$Dxm5Hz@=+UNwtwnoDi)O^xpPylsBlH0at zoZrCfZMVxA{FeHZ_yO}xLuz|(Mn}4L(mx4ag5Tq;D)x&Z=yix~8OiU%0OR&#NA5r7 zv#1!F@@s*9*g;=gf#xG)8uSp6PNWoDZQT{ODcDU-rMvm5Rqua&>l5ut#miA8Aw`~%*w_L=){~^h zw&P$Gxk<9{4=F!x&*PtZ|M4Kp4GBvdvz3f3r}xGx%68~%IW}h+b{imw$pkFsba%hB zvN_a1fzH<|oXRaXsckwSJgli?-+|8q=+PZe z2TP`W9owieDLATdyxLqZ9~LUsWr1i02zYmKy(zqnU7+a%)y+kMyKD|kNFfV!)FMub zG)`2$?p$VNyLVNqTKouGRYV;hSJq)l7}$C=WJWE zdH-T&EkIzkRxYYBP(}d*gb4^pXyAh6_`*+pKwfXxNL|UQN|j=v7|U@+B!}k`S@4Xn zX+7nQRPkgq;8TnB91&cJLzHpc+ZRaLU5CF3SR{E8#Y!-9lH?0sI;bp7p$U-1K~VlI zgBF?-H2?8%`=d$WSELjsPo)b(SdDeIh{v2?P?deVbs@6M3rdboalwg2#` zQ-!1d=_e;cC~%}9Mx9Vkh43dAqgKCVk{M-8+QvlGXBH;C%8`(x;}WC_P+jB9o{`)d z86S8~UVtW367fz0Yz2@H@usybjQN=9W|!J?$q~sqTN)5=<1XR02RSw$7nl{5X-JG! zhBLyU>pnux5_xM^B90O@1J-*Lq$OC|{T8jx2>9lq!G9At;rL-IY$MkgHslz|yBTri z@7+@7!qFb6GNP(~216UVGuLVuE<yIwC}FU~6LGS{1oEy&UylBGyuZ!fc4s1*s^HKd#Bzr=);EH`7R;V!_p_U! z0-^U1H{(&K)4j8viT~P@#L1-3RG|S-+ygr;5$o(#1+7n|TDagrfVdbaM>qF`8OP+y zB~(6E08!aE9tIx2@bn473~aKtHBOKSG#)oR=yv68OK@R{lNk-D4|X?akFQf5ocfry z9N+89^Q6_AlV8qsvYww8!lozNl#4L1vf@ApJWVYDzFrPs07^&y-C`(ujl=(=D*V5N zYWhD)3G>e*Hkru%FT9;&lW6OjWz)8~)3(i>wr$(CZQHhO+qSjScJ{ed)g8AxPE|!m z-{?QE;(cPp`Y_)0%rOmV@Nt6EBU5HY11KRWo4u=&sP0nZYNi(Sfbh=GLVkti<8*SD z?Ucq+)-kbE7az=tBn8^hAxdzZ>+}UCzs(b}$dnn%#%3_?-aII_x_t6MzcqykpczZu z{O#%g#>~X{56=DPPDPG?rJ3pf3)3?FeSG-e2Kn!qmVy4C%uMesG8!rZM6MlKqjj6p z2_T-H@}qqzFG|VQ09rRG79Pi19tYX#ffFqU>~DQeH#x8bcRP_(x=sd;mf*^Q$4?k; zzO*EN1$BZDT>%nL8>mPFf5}Fw5!B2}!HK1g6B#BypR?V z(DU1_J*Zm#U<(!x+NiOIt5o1M%$cDt78Er@Ko56yI6~ih&M>0<&_Wd0lj)|&_o#d3 zW2J=nijPkC$%4|3zM5b1Vs$%wY( zqIe-i!YmsdWJc>iY)xBwa&h2?uMyPf!;|`N9B7v4k4)m}X#51*U;4Gs8HgG^4SDRy)HF_r!xZ7YIwqUT!n`g878&_FMcY`w#xU#pjv=nrIHKopZRXJa-yYo0acZ%NnNo z&P~wMaXlJ&{cXxWmq)+t^BaG6|MRbF0qrhvUW8GFyYq_XYB+1;GBZcbL73y0l_)~5 z(qA>J6j))ID5*WIN!n=GPmW>vm0^|e`q{STG+VAApG{F8_DzN&*M&$n00Z2(^}{ES zLRZb{6O4)cB*6el7VU^Nf-nm&6>M*oy3mR0budQq{hu2*;-B-M{MM4KI0^9Ek0XX5 z=)g)882BrxswWN4$4lQTnZ=^Zvp*EH6*M_+i(?goP*qvB0;Tf!!XLQiy` z`sT4it37K|oWsAFb`e69!SnTbD@Mu?-1bTz9~70H>*P`2p1vEb(=AXeR%ZU-U%C<< zsq2TTU+7hDZ=CB%D!f1)xLeVPt(U%=57~noH&K2{<0jHF)5O?STjrR&0q!qNE9YLx8VM1gy~n1iJmB)H=T1+ zZ=+`iKMq$Ny9RLs^;o+%pHLyn@4Q2d|7Ea5P@E-0DHKjlPDL!`wNtNY$k~VuN>lz3 zx+uL9Xd{Svq#jbpPbW=pO`00=fqY%`J)1vgVR+1(k+arMi8YHP8eZ=9VcO~)s2kFY z4WSZz50R#2F)2)l0&)OK3lyHDJq$A(Kx!XhYRB7;>&)jdiQ-~T$8nn9i;UyKw~i$a zE>GU@6HBODrVBO^_G7~Zk+GxwAat$~SB8SV=2DYQAgA9NogZCKAttg1UM|V)?VzR>IX?Sb z^`eX#|J37J5w|x`qz;um{=eEFmA$fT!iP346=g-X+5zt6-Su9Zk2FOI`Xhl`h(M$} zT6w}2b7*C;r@95>eyPGvs=had7Z@-5;is`;T>r+^8C}V#{=%;FCBV- zvI<)a4a{__v0>oM0N-30;aK(QN|1XVOF&M}GFbUhtUNE&Mmbf>@yxypus4d^l6+IY%shf!#uDYsLb$T1&sY$9M^BS&G52EBDHRuE z848jsvpWj;vVSCV#w)wf)VM?!^`n1=QnFQs4PrIo-z6wG6JeC2P?zpg>?9~j?n>%++TV-J_1(A79g*!=vPV}Cw7G_cCkU`0b3`qD&r-^ppBAbEi_eDXo}KMRI9nD&u9{`M2P}*Qn zjR)bT<|yTG{j*RA!&x+yADmcF;ol3Wrrb{5n4mvPic=A+jQfxRexvrncCA3o{jF)HzYGu61z9a*h11g zUQ3LQChnzF%N@;(sf-rzLR{B$aPrWdi)XPaV1j?-o1KSS{((my_XtO$r28>82)i@5 zq^B3ojS~_-CEb>1jLXZ1>_rQX_JJ(JJ@KJUfJ{~aXq{or|J8yst6X;MTH*gdn)t_e zQPI#;MSy$Hl)mWp$hl>E6eSUtwm_*uqIql!#;ji!rL^2JCyYoAT+wahIItG~~%Gz4x)2 zQzF@tDs#c<%fjhsr20TY&Bo36M;5vpygK1H0LK0(>JAPAtz`yV&RDhJWrOMD9T>F&gh1^gKNU*huz*^zdn@ zkDHEYGb#s`?j@DPnnID0e=BFW%XRzDrF?y`s+pL9E!jA zwY&TVxNK3Eq)ZV{5A&`_Ng^h0*p4ulJLC2D<}lcv z_w*R=Gfc}buy7OPg1+Q;^jRS9p&dp~)z40#7XI*-^~T2ig43QlBASSVyIyjrQHUZu zFCHvfj7P6<9cV^nwl(KFGn6IFJ-OoiuZiR#rF7Gczy8_73A_cgZJN4$)pkQp z_6zyThmZG!88yp}^(mH6^7I@*dEiZ36La}0bMS%};FtuFFyXl|>0PQG;>?OBfTz2yrL z2BdH@NyJzMocjU}(02K}8Apa%wVr2mRe71zj`@?47LUU|>s>$CVeY+C zwl9@9_)9hB7%cvgdsPbbx6l|sg^OHZq!>K5g;rsxXYVz!3wz$J#Y!UWf+9ApaSM#? z)B5+fEOm?tS1J@CXQs^E5iQJkNcT~d^mdUUuuyqyGV8c~(5Go__nCDwkvWVMwEH2= zA5v6_d&Sy!;7Q$|*v{;jvX{aRMqrl@zQ;Y_EepQ#Wth-*r+OQc557Huh3c%AS0yZ7 zh*?HAg8o+!vwjyj9CEdIo~e%tiO5z@dVFsqR=f&h_uSpXORI#6azGXgDrI{4#}ra) z3*&o`LGjo*nW9TioG2t?6As}K343T&$_*$QfGC*HUJ`X=)yZAAs`J+Y|>7Ie9 zbOAg3Q~#BS=MhA9)n1J!E{R`eX~O1iw6KfA{4x7?O2076WlN3Q6jp{#A~BM9MG_qc z=JsLh2p&0iCq>b=Rrl}cr`s6#FUKDf)x@o>kgs~wJhTuEFrURG^0}m74-GkMNRH~) zc?!F`nu-T}-i0y4*wTR3Klej}A@k>j8XE**SfB%{-G4X`$0-3CxgA4eVT_WYNE)|i z*)18{&@I^H|05M*E}h_VS(B*B?(2ZOTRl@gAYxHrQ2q zQ)AcRkbu+%G(Z6BRL#R0XV@UfD50{O8VPVN)%WpoD*oq~aj8fiaLcv>EBI8N38-=Kx6QL}XXMPr^rwdM#CbnZu|j^ISmzCi$BU3zf`Xn#U)30DRTr zT=MXw_>EZqD0~G1{2OWUY4vl(ub#xfc#h?XN!fj}Y)%X}rS=5gANXG!X9?~+vMcxu zgTQUgM>1WLMpZelVwBVrOs*J)En*~RFvd{@Ja+yhs&4Z=d3v?H7||nd)KklGmZgAg zO|B~fkO-z31rb@qyeK4~J7C81@3hWczK)@NKHAt5lB9%S09qxuA`R7fd(W`?pd0kl z;H+<_S2Zgrh*NFfO=99#UG(dVxb}U!dy!X zu~A*ehJI~H?Ea(zLA7ag9?DV0gCJkndbuYnOhN`1s0m0&U*|pE!;4Pc1Y^#Vtj*Bd zZAP%7688=)fNNe)aYP+|Zv3PUlmz57hN<)YAb^K|2hjONS3#4&WLNXXm_(o(UaWlh ztEB4>3|ou=ilcJ+CXSX-uslzXHCGbdcKg60w|vhsu*$M(I$r7B2daw~n=O5>Yg@u| z_$W8w9u`}#hgA(b>znZjrEf|0vbVLGcD>LtRzQs?DCoK$Ie3x%-b8O>m*|BghKJDa zl{O8H?8nBemutM@T^bpUJ8xCG@JyeY)9-wQegXg{JlXhQW*DUYbNH0D?*sGHa}d=b zMtms(oVpSfKS+kj&K?SO1_L!Jn{RmehjyAnk>>hpojRjCq-Df(3OSObq+o{5MXj^0 zgdZY(G;*jgrgelQ!>II@+&<4`{siPgTUB6;Nr6|Bt-5aud_}^}ZC53i;c5{WU3F+u?T)7rq8kGTrzz#- z7@E8cFY|nXv`eJ$XUj#PB-KFVh<-=Zx3)G|ikE)V#UL>+@4Y2$TRGdC_<3ZkV z5XypkKuyc0)lP@?L?o6sPGWp~#ep|NA4b;J-y&=}v#dzZ<=z}?z*uK&@lI92R=1ui z5K#xDhg5$vJ55dx_0bE}Ow8Rf!~{EPMU$3APHVHxj(Ol;%fdgWL%o|V5w;0soKPG*BhM>)W!pP3!9EKtEq;ReV6z50 zfApRcUn;tH1zI+g){$G$4D1c%58WqNMs%Cx1MR@EiotQ)zC1*7U?cbIFKm+_ah4bV zTv+X$b6;=PRcW>ukp1x!3cLn*p=w|oKtOy9h~THeYc~x&L656CRUu|X45lIxpYa^_QZ4*2nh~N!;%t1(1kO*O zwbHBno?d1((SL2LQut_>TJ_3|2~jsM%Om1O$#^3pElBz9Jc=UsdHT+M%BtFBM#5<8 znxU7g!cYdse_k*0DH06XLw4*AV1x1QSDor`CCE8y_Bq-H_J`oE3KTBB!9UrD5btzw zygXqng364G#K-~qiNUUoOT{X?k^IGa@{sMqGgeNpIpte#r@G&Qh=}$(Ko!xqj_N`Y z`NKjCGg3w3;u5|QaXE}gsply*GdwC@$$72Q46GJE6im4%uKL0vAEULRCq}%}UQT)A z8`SBc1F!V1K4d|a|M*u`ppVJ=Bt};YdLxl8dMI6ny8g~HLRk(13e}M7PJCCdR=Ji9 zLyPrekIqNIy;~mexe&*&ztklL<#W!l-u3Eh%Cc~%;{4*ZkKyT2fClIRK6m_~c%dMy zLx|M$UHTIbmp!Wm9)5+^DqXrYWjL6-+&dR^Sd?+D2Ubzr$#VqH`j_d`m z<#EOC%Lq4|&6XFo&|{rWdlM_GtRdDY1s1vmKdDg%_{1;1zJ@yUQoA3L$U9meqxdJ% z55rpIOlpC-q#W%gyogEHD8U(3A8x(plQM9T#aKTC=GrZyy(A7+6+N)%eU)zBe0?3M z7L^~=zSAtj42j6pz>el5@x;Q9$OUr3{q6*A<+;8~o^~^f%Z8>(uz0IgC8Zh!ri+@5 z8jk_;(jzOS;;J<6Q!|+C#7mK^H)DgXFenT-fISOQL0;CmF%s7!;)4$&s#{AwbY=}7 z?lZ%x-muW=CT>`jtZX&I6cEC~SXOP7xym%^v?Wm_J3Zf;5ENuA9i?D7qCpPCF9xWXlSe5037kS9ohnKnSt=bY1VSCD&p-8}s{b6(C z-)k5o=U@(78_&{@wkZazbn0=A@WxqrXF$p+ zg=&__GJ5n2$c!0MNQ;%B*M_Tmk2Z}F%V9V#WjeD3cFPLm)IK>KENdEs>b|yosq$k- zo8u-}*0q;|a~Mxt9Yd@&JiKM}0NW-j<1Iz&ViyA*or*6GD?fr{yK`u2W_yUHZg z9$`vkcSP=N!iI@of=Y?)K3odEx=K!Z=tgTJ-m?wXB-H}6R(g?l<#>>5lF_y zoPQn)L_hhZI7xBbM3FYDtf;`JC(}^!Z&|MU^7%_)1UAM0UY!D8lrP1aCoj4hNzMmt zR$PY%)4(u&I6BlZg0pgZFx?v7f5!|Sh`Ohzr314xni#`~kQ3TO$H4xBr=u&nxm$>3 z72)8xqB7U#`xLVb3x6Dn& zsJB0SmgUOc-LF~_<Y^0~O?Y7$JFQr1AKiG(t_ruRhsS2Vw=nW&TMdOheB_Gc$^Ky1y>bGs(apMg(GZ zCfvy@(1>dBXWNc3J$APeP6Yk58YxBO8~H$e_^GA@dSwRM+5*4AyeD#8GtofLEtTQzp^JiW@^@XGcMVInd3L zu$o{E=v{9+lrL8SNJHYZk&8ocK-uUs4BA?FS#7hXj8UuOulTZP0I4Gbce#JHBaX%B zha02L=NHD6_pTJ<^D9@XA%?tQJ~XT7(3gYgA60}|ujXL-$}x`vI>FPOs#@2#`4UxG zxcXB>K>E?fjE~)r4@YB;EQ^%P_`XO4+8xVFcoFkZdki_!XXJgcfma_O-HQ_EsM)-n zP=Ikr=y?BnY#{j4jM#{s0_6#9xbJFhqv{CkULQb?oj{)y#>alVMBVmihg{2g3#?y{ zJ-nb+G)S^-q}v$!mD@phv$%ZXV8<)65=hs=tuNMT9YrlwUeYCU&_mr4-k9 za#5!H;mHVvpBc^AAp^p&XTLg&&0OX2^JYVU!9S&_pGf+Ld5f4!4$risV7cA3|1K;z zPGqllf|EDox|F&H@lI2T$E0Vqw_eWHL1$nB0B+vzo8@dbtPWoxYXu?`)aE?h{-+o+Q&mc@ zmk#8n6(6p|nOkjBPdzyL{#vg;1amLZG+*DgRK~+}1vsnf2d1W=A<<0W&}iVvDN2Ca z?3TvB!D+%wvr4iCl{(S(mso&lFV*LG-*RHvFu!LI8+IjYow`W4PgV(B&GEH>CxF1j z=`W$*K!1Y)VQR3;dLh4y7AknsL@l^S$Nk)sP`Z@x zt#(g=uq*VKZj(=WM2PDg)JpIL0ggp~*qUvixQYT^1S=zq9wbBZA)5N~Qv9dr8KvuE zw8(F(o#-m2;K(*%#J*cOiZS#Qv@JQ!KpAG^8HQxnExVm_Cc%6%TazLtYvhd!OHdF` zM!|Cm`Cl8BurB^b5Ojc6E1x4fdkmR>d+qp7PNV->62|x+X^Q_DuVAA8S1OMFRkx6I zN=nT59IXFXrBV1Vt@bR8e`mG-_o4pV8%ZVxrhgI~K`xE5C`Y4+C1m@_0_aqCWIgoD z+sU<>HPv+zec$DHZR#olil#+IFd=&P%1Oo&X>$>5%B?dgYvE|i8#K*kayjhNC1142 zIWkCddWQ?>l(swq!{Fhm&WNXYsDNZ9%?bj=3f6^SAbz7S%oS^-cMN0~?i;a<9!35p zejpMi?d_Tq@{Ev8%7ULoix7!rqb;bqYCPa)i#tjNLF!69&~^m~p`Zv|ueH#-?F>vM zXHDbTe$5ADeA;P?7G-!7aL;Ks6j3&_V2cz#p&f~PH<7U+2Qy8{(|*cnT!i)V0?S#Z zxfL)arKhieQzq$b5gmkF_)P1u7&s+fvD%Cr(pQAMO++Ifw74ZdN8jO#2)@eH3rcm1 z@(A-`gvluoQO=af>wvEI-;r9Sz^jdBIKu;ZVlelIk{f?Mn&xJ#fKdw8Trefri&p;) zo=-xGy^|i_lml#1n{sxua`8jeB91bV$VN?sS2`}?0+=SGQ77_cp07OQ#g|}A->($G zk0L=fpU4C<|8{?b847;z)mgF z3~UDsF&M4qO4CITRWyGV84UKv-d(Zb0@0Ej$P8L&uAZI#>K%II=FCvgDmc-|zX##X zCta*6T$C_h)WWi_fXbmnbkfvHQdxAU%G9&f=9V$ul-Ee&2;UBBguMPr`2LEH;9%6d z7Gl=zQ!wVBWPd~{(XW;Mtx;7|g(t+t&t&uxt_Z+528kq6gk|^XCYYZgEWCUke8j8@ zz8yv8yffAj=^6m0^7*2lWgt6_`(5{Gbb|!p{&7Wnn&8gaJ-Q*;fP8nSXAfh;%<`K4 zS}3b~qJUidomjd?`L!gvMqQ&#Hjeq-#~{A0w#vQ{M2MsC0fO9aYdS+O4Y>Vq&wxg1 z;+|DJM9b0Vk>`&s%d}CLrbM!iU4``1Fs!T;3CG@RHgpZ}k{-Av7*R*}ke-3VXfQF9rb%z~ukD-!RElU7lZhqH1u#lEG6<~>aCJrpNWMV8&O0PVLCqe03 z@0#^_bpTh5tv>u06+tBAXZ|_>{@Xn&LC97w@r5tcrs- zcQ8iYw{BkmoBN<&zMFCrIGRW72Nq1Hg{MT%W~!Ln~2^|h;qyXp4! zUu93nA#K5PgpV|9c^ic84XT%p1otX43JgQ{lqmiVxF9@;{qUtGALeFDC^+4*qdq)jVTUjo12#Q|@ z?r*yYI}LQ`!|7ioN29qt<-apbk&I`Xm)D~fRig^eEGsZm(W_Y5v=Dm9=j!NBAP7{@ zB|8-at9Lgn5$<82YCQI=-8iL}B=>kJk8{pDkj=8a6jU0c;W5k>e=0(JFKA3{r=Jq@q&|g0l2X~s& z^tvyWCcXq>?dZj}Ks|G@>P03YflM<;=K-zvq9$6!mf^&6ElW(aRlzYe*5y92%j!P0 z>O?3c)hN_yjH8?UD)Q63ezhl*!$QT&#F>yzISQlhna~Ehb!cPB(O8n$TSE?OzORJT z)(8OGi+G)U^}ok@n~YD0rN57u(toi~nZW;reM(q0$Y*^(4$T7A`%SJ4y zn0gID2EmNYwl;Y`-cx0B>d+b}8Bqxr)2-_r3!)o|4 zaPh!b=JX?kG!nwg$}@XNhI-R<#HIhi>|jbEAc&u zmDBmUxBU$jVDU)lZ?KDn{sY=u{Y3cj`&|!E3-buJpVrGMrCHGE4?8#R2PhR;&;57s z$_F2{>K;-VQ`PIvg#fgPFzVUadhr0ihkt=$JcLrousPh11tJ)e4<_dec0 zx}maWg7;+DE5TpOjFK~+5H(m@*!rcRLGFYjAqrp{PI%d{RihU|@ZPFYSI0S6kNLZnV;?HEz5~`IkHa8!*nQ+!LaAgEa*u zN2w8vP7IaY8hLcJB9%sQLX#W}eMwt8Md+0o zgW--=w)p0>o6f9j9CEkfu%W~Ja{O?KpSz($r0{6B)A~zvd-6^hsGn}g58zF}#}c0M zyZ^m?8d6{4Lnsa8VCIx`e(5zo5DP`y6-hAk8z*vWvX791+e7h~%Dep0d;M#?zM&?G zL(6yog~6-#Cr_hM&IX(rqq>!-(o269cDBwZ+t?q~cum=kkO?20 zv^q)iWJl-RN>vX+OCSzGOqBZEBBLMRCL7`yIU?B;o$0v1xTqFR?NFrFrDDDEF{eF` zxwBU9roA#9rigwB(ahPcT%d>*WMZusPz7(!PAPArv>~j&8lH{Q2h=MSJxYH?_ zf)&F~c6l+#as6PNT+I91dkjpnMj?hVGu@OJ8l_&+j>3xupIKa1ElB7X(4JXdL;zN* zQYA}M9n+X0Qrka0@xv&HQ)o*rH;Of-xoF6HoYLeVD?>0`hP0=!>*JV`e;z?fSHYn0HE z=>t?`q;I!Pt=r3y@hgmRLfZ7V2cs$J31wbNZAgNfZ^bu*{t`yR;OPEPqQqS$gi4AM zm6{S~$jOtHtBYjyS8tCK4x8B12WTrj&L7bpAL2iSL-Il>lFSu?g+rt=I6XVf{Kqsc zp~C!nkh6m?JGY0!H#I%a%HRx&odL7vXq-C); zQyZ_;wlofVMrSo&Z+h=~ot=x^%+=3DOhCQ0VwQjeGHvJ&FUL(8o!sv=tg4MbA~=j9 ztQPKT4U@=k(&}CeET@RY@RstKB-X9&SQcLt)nF3(sZ$n|lijx?$<2N1br#j?z1M}B zFo;RfNr_LTl(NJ1x?8)1{ky=BVG@Rn46uL~LFvYc>mCcJf!IM{DrqAV={#6uK%8}d zLtsqw{}gcln|7`LV{L_*{XZ`}>qd?iit4<^IM>)b1%qECHrGd07~{Rb2BK2~OSUS3Bh2V;F}Sf~F3J8zgreepAXhIKE51-&B5)}J4W4h?}T zpnT7~oVgSghW$ZFB%2lSS48WUutOCLfV3+1PirBykCGbEp3)1Zwm!GzrWLx29Gjlr zpzN;{*a~THX8LSQC`?GkSWQtU$_vg&R4OZ6^xw*lPpQQ!E!HfxkVmhE)=#Y9`P`o0 zyQJF!BQifR6E8woTdXquZF$}0Zhd~2fwO{I06imTLzy?QV0`v^sPy-Py{(lPGF6$q zO7+x^xY9BLxcSSVW(n=I^;r5w$|>Nk%-FhN;wG*H67)S=T)}RLs(ZamjxyxCF&WyS zR{l8T%1a7!@mubfvE>T^{mZ&dAjA_h1}2K}7hXQ7E{dNQYOYiJF@v0OP_GRIYJ9~G zbaHh2J31&Uw*%`o!9|#L!)U{Uj9ApVe~(}8}z&&TB8q+7YBT_r{U-_GAfZW41wuADcaHY?ZzK*Ww$KRMz8?iiy&vjP(SNGLi#-(_D7vaEGGN>;E4zalS9e)vU%E>OSZ4Dg zNe3%I6P5|R)$+jel?drkQJ|J?%*cSmT)Uf(Z)wC99r4D7;s)wcRoOTiri~Dpu?WAh zQD0)py}DE1NH`EAv`r#yWOEt2B{KEn#JXy+F{6aOzeoiX?hp^=5mFAhGLySi_wZdc zZ@S&d^5PdL;t6n9WwwdowXV%10V*ub^4?c$dHb*}xX>n*;8TMXwVETnkxTpMyo?sk z=(NY@Zz4@fp6Ik@uB$! zomhs)=@r}^BgLTOi|qso))~9O9|Vs~T9Ar}KfRt)&M11@U43A&FiEhj;%X`j@1$Af z3o#nC{d^dj z!X3KsS{P;s^rX^O-VRC(ANc80_^~XyK`}&G9yOL;j8%66=7_YRcTtw*{VhYVO?nJh z5dG#%OyDH_iI|P-(A~}7gl2e3Y@eM68^CaXPK)ME*c*83Cjezhv=7#Mb=7>CT#yeC z8or--hZbmUoWivRmM9e|AB4`!4*9E|_souHxhe1zQpMmK8TN`$amy0NGp($&zF}(K zbmOyrbMnC7{|p>j%}SVUu0Eh-*@ea#T^Xx62SMaQ+|g$Vk@u5{|{gEYJ;V$|*B}Xv}?a-e%F2J16U@ z3*y?(ym2H*ALaJ#p-83I=jL!kQ>4Je@N?~ORq2+JpyUb5yjyxqRJ}Mwy=EU?(X73y zb+@E1=r(-^gyYd*?7o=dUll@;r)+iQIYrz-#i$(*N(5QsF5C|NgkSn0&Dwdk83U^U zCO={u2E-Etp%NvBIW;|%8mr}B8V4ZNjJZk@Zkp>pg*(X0Wr@Lg{+WHoYYt$xZzXu* zcr~lT?6~#WXDN^%EByM_!)*c_)n!yWtSkPO*1ZPq_-;#2WB|khf{cm)*!5vX5Wh_|V1d$_LuRrK5L%~*77Lh`WQ%v8Esi{M>DvaYz z&7_OI2$m0~!UgZ+MTn!Xq9?UhaWYe;CZfOg$0b0P`8u~{SV7Dq)T#0$%yHKZjoX9pCk+%GLT&CPIWzm(!Wz* zP^Sa;1iZ>k^9FkY96>$d6s*Mu{K0Vmk5>6bY4+X-kI~mM2vbc(p@P^gwCEZZsL$=- zO!P>br3;|l!F`3(Gub#I&rX(rd8DEc%dg~xmKuA{`rPuR3~8A`mfy)Aba!B2>%kV* z^Zrt3f#HD)Dlo1JSHpIYtq=Q~l@aqrj9IOuXk(cAM5t?U359D2$c8_v)|Vm2pt(Er zi-LzjE7GpG7{k)m4>lAHa7v-`94A)C{F% zTOgxZA@ccr7&Cx~4RFEif~2Wa02d+$Ouo#Snq}^;=QtH8YKWd2!nLE+tVir|7uK() z_CuTo!QY*3kT%N6aYCo-V3BsHY?8iox2~5zG=x3a;Q1bG=Q=tEb{FX#rD!Cc^8$G6OsSvgYKN?eoIo82dbEIB8Y#jJ@YIh++y@Z3&`?0b#mUhBSYU^ z{$wA;=GO%h3KmL;RRkk_J&sZIUVZwB*S3DGyX9Q2)9DKH#-F+%Rv>GF)}l%DNT%GP zD>ZvqVE^ISw>-MKH7xaESiKwAf2qxW%&>2S7d7o064^aw{%s4wO(I$#2Zn<+yJ>WcxZkA#n55GBGl&rD4xya z@a!_l&DYaOkZb$RBj>XQw_q^*8xtm~MSTbeI0+v!Z%YPHIp8DGb?~+qi#$_5$S4gr zfRQumMkX`@Qicj@dJZoifYI??fX^4u)qR~BLe|9=`P9r9vLe#Oc*olG(=r@#`{vk5 zXVDi#ex>qWZYdhi!ABY@-m=hO`HcbNQ|V%ET0;Ea{%)0gNU>}PVsfS`0N%+u1K z%n7hEyogHr7@AXW;5^|X-i0eLt5q;}T!ydmljGl8#A{AKF6i5NNDVK`6VrON@uo^y zIsPW+w|^!^Do#7Bb+Y{xrRN2Wy)Ibs$uPfTVScqw)_NsIB2aO1V3aU5GLVg@4GL;f z>8^T=oht()rzD8RNyjdn(ZYwVAHv^F(Ch}d;-7F4t~(W;hP$UEJm}v~N6xrm4W?nm z@PeO$|HO?aJMU4oJ(rVHL3R(g5yn`nhhj{q0ORIj__D*GCVXw&5G;JLMXgW9Q_C^) z&{u?Xj%!5~ErrVk{hm?R*H;;3qfuvEHRcVKQk1#wV;z8{TQvWo`UvtfEI@v&eqvdp z3Au>`!y*f~WMBt|N?(`}vK3~no6_!8WdVv^roA6MnphO>@3NzJNa^1T%S*w5tTVz| zg~tMT<>A~p&pmS>5)_=BJo)s(YEYFe-B=r?G-vs60oGcj7CYB+n=$zzrXl1@9+McM zDYl&2iy-I??~5~Kno@Zw8}R&9Imwo_oS(;q-bUh zJz6e>_qlxDlbqaYksg;yUkO5|;cl+1}qlFq9L9%7PsYyaBNm zYMB%hO1z2xMoKUUkLRsoA^!_ieIbab5Xg*|*GmS>5m1z1%+C^?iEqR^RXN$VRsHn( zhHRiFBbn=(G)keWfU&RP^NyHmqrQlVuVCX1nE!7v`=1N||Ag89%EC%$tOnnifOM+!YZv)&A+<@{wtm6&dlK#P5tEkbUtpM#@oHUp+-p)^-9DS+M}4EHQ%4#m!At9y zva>O(?ZibMhU-!PcrQ0-byf$NCdnDaG(r{g#!D_b8IyoExZON%p9At%7Qth$uN z9wbz4&VRTdAuX_MSMRK=+ZB!@GjVQr=E`F z3zW%Cd|%fti1TIQ+B2UqFU5j$#yCiK@sfGS10;!XSjnE}ieFZYa3M||VF$K>mp~ws zt|jf4No^L;$o-Y)Cy+*BNiSP&yqBRbQIux}=A?abwha}(J>&A&tt6WiL!^Q<)@|HQ ze*6b2I2Wwu zsfV8D0DWqJUo+Ta5&7?YbmVvg&$r#AebrrAl}BerU|jT59ww%1EDi>Na^ckvPL7Z3 z!kcswCCz9P-^W5AkPB=gm)YIN1FK$WUXWW<)4c<7dOF-X*OVDm5^qppo$?fjPSb$k zoH9~^N{J;}@Lpso)iB#~M6XYA3@T=%$_yb+Fz4{i3$O=Rnn`LPIKLq{oxU;KD4@<8}7Sew8mil;qqKuviQI_ke z;)kNYTy zBNH!bqYm$#XEBp)&CBEa6Ec6x7kKDqtH?BTsIv)xsPUSEoK@CN!-wD~_*L_T=2{z* z{zW|uG}1f)-lL~NSe(ph^;R8%=7+9N24y#59j7j`Qj`R*GORIGZIZLK@Y^1|pS(6z zJ8FyWQT>1Lc1~S_MO&5*+qP{-WZ1Uthz#4dZQHhOXV|uFc2@NrRkwTG>VD`N{R_@H zV?UfZ_nhlnZ-vFOYJ9uIh;tw6y(NwG8iN*om3dVlLdASS(A2sx%9c;61HWNnqw{vq zvm5kA)XRX+sGr$KAgIn#3-qFMU5CzgKWn|hHIXOYBcs(892jw|bJtWJ0`wcKawUB= z15cLKzC=lh`mAXMZvZ+zn5ZKsa zY*~(NwD8`83&=<27+HWD5&&dyYZTJ^fB#4>FD0FaG&lsIZ%MEyxs2I70LbQW{VrkN z$y5qhrQ{S(FHX3q3)_cNcDU8&RQ!B@nz5kEL$*YLcjLow7m)vZ7ID`leFEWceKdMyc_$xTGQIw^{B#l4)cRZ?eup~e zqy4p2ateqCi#NwSI0iX)h0npc32~n&P6Sa}FQ)OHfoeAefgxgAIxQ|XbAZJsI&!J` zW~S1m6P<1f@@T)nl|h4QcBT1Bk1&P~%07@Ki5HIWJh|WeauM0v50!1Jcp$%%4FMP; zCXi)3yvy}K=@t3}zG>l3YaW|3dD=-vv#pEM9+Q5v?5OQ6i&g)st0sZvp)!kwhE4S( z?bE!QsFOnk@sKVHiCPEhG|_WuCa=~3~4J?11^=v^&EIaHZsnvOV#GJ!&Ig-K-ATvsf`w5hbwVR z=RVm8!_p*NX-qBdzSzXKZ;g_IZwh0Ti_?uTnD<5+?llk z0_u|&AcdFHD}RK4kIW0KkDY81AxTGcD$S4SbCAiyPCzEEUjPmBl0uf>tPt@bMYUq&ErlUzCHV{} zIE^7RRi;=XKgb95CIV63qKirkO(?#dkI& zztt5dIZ8jkV9F&&c&G47{qioBz*7N!D0}W1;`)A7r^Y{>I_#>UQDV$UjA#EqH+m~V z*J{PL48M)2AsXgo5qiS<|frX3JVVsuI{VsOKJl{Rw#%1bEo)x zg<{)h1#;o1Rq1d{h!kFzb7sFf0war|6XVOKg(FQe_av$w}=1VWh@8dKUDh6M9WMjEUp^#8d*wr;(FVd_nN8Ey$32;O1T!CKsl{s#fKK-z_cA858$pwG$Qt zfSVKf*ifMRHAZi0T%^<0Yg58}@o32({FbckWVL;0cKhl^`3V*PgTAI{F@Lg) ztw?0P^rjUIPV?x&`dzba9p@kJdh!_7)e^{#@r{pfa`_h z=C%;2k~8R$DYR!jwNU?w3GPmb4!gJ&OhZu_qg0)u1Y~v7uz*`Vao4Q%PUsMV2h@dC zgN_$h_hE#z%&9a6gdap|_({c8AEQU_fP3D!9T=PzEOI>8w+S@GieGs}* zv@_TOmP;Y<_pZFn8@ac=5}dZs!*GQR=j)QVwm4#IOlGF_R>$}t8ja*O5K$SOH|zy< zG18a0Jvqgvrq^V$3$so5WC?RK`P!-v>ERoj3RDGgBS!u#+S_v<&j{=Bb%TV((v-IdcLPEoQ8p$5&$^2P zex@j%A$DFEv6w05H(swIXjv?8rWkA{U(|df!DP_K3Po7o93Z-r+;2ATUC%ls*}4LZNM#KWP8%upNH41(0kk4r!W!3D=*x~#BDXz(cV{|_*Ghq}qP06Yh zZiEZGxuDPBZ*B>{NoHcR0jlG$oziaA*ZY;stAnaTc{yaqlT2xJiRSKXf~~9SH!=Kz zo+oel7ZGr8{UP4~S1ihr|6VAy3P@7(Q-et8fb1;y-fAH4X6+qmA|&?DXlF0Jr#6sBE3g5b7Rd|Lz@! z*veHGO*>NNR5)IwP1N^GkTroMoX(w0*dD6 zPxV5-aond2Hx@lX)m29vi1QWkY z0*bDd_C+X91Fa8x5(dTXf5SnUTIxmbJQ2^sw`xzrydu})`l0d!?(f@=I(K5c!3O-5 z%HP_rBwjmDWfx3S_dP;mO3K8iY35mAe1Y;U{Zqm$4-T_ZM5F~}5~O2`sIs)0Cka1{ z>upEk%m69;6|D`AjaioYsSp?p_J+;E;1kXC;IsnqTf7?xF8K1P3s^3?Ym75M%Dh~! z598UhbU6q8r)E|b?Bm4!5!YxPUiPUxzH(Meq8>`S?LeKD7TWw?CLh+nQzTtz)Wm<) zNr(ZD0HkIs1zSb)u>jUHkKv7<@PiMiBo9r%KQGyL9pv0J90+p{m2>Z|P%)x$ATiOy zgz>xjeXFz*CQW+9D#E(WgT0lih}$Dz?4yfeL?a$W_=7XW%By$1GFt>Q=1d`UW(IiX z>u9>^V^42feiwqu+vyhTpV65f&sl!bm~Qd5 zt~qW>VRw_p{klh` zd%b9?5U<3DK-s=@4z^cu$zBSqQy{|`X2v$#sjy?_0njKc2q%b%)o*gy(Htu|(LH_6 zZGX+;yz6THDS+8xLR2ilK8Mz?daT+l9>3U^55#JAu#Yysw{1j;q zqjEpuNlr;}IO#GSKELi`7gaPj#S{ISHSI1wc@4spR-chW43B-!V2%0#@Nm+utqM@N zRvvZzK3b!=I28~SrWDtdv@X!;Q?ht=l&ThuR2%BP97B<3&sOc{zz(ifKaVjmdAXY> zINbGyWG(5A1oTR8uB75Q4T{8|1%643R8MQ&T79cT`qrc}&4KH3dQw7}+7|)yYISKu zu*H*mUI?aocsW}mek|}msr?Qi1T}9@V&GYu; zCdc5E%|EZr;OW9~Tf?2kS*5Ew&4`1jyR)O1f;4^84lUwI>}hpQ2K)G}()hu%;a%T0 zKQHlU{D6Fy%<$?v5S~xhs&0hu=kV}RiS5;Hy zfT)qw+P39FgZw)@5-oaidNYPu->pME=~|*Iv1S52RwjCt8$w-iW~ers7@tNgV4U0P z3aK;5d)YOMvz~CRB_s7(VGhbg<&zDWh=2l<7O<~Dm?vbNtPn;e6gk&L*QmK6zvO4@ zIy@kXDKEA_wzBw!)g0lG?N!Xkbi9@vtHc2kBE5FE{M$wK0c@k*>=D}9vwgHrS5!6> zq~KrLgny$L{X<9p$B@xKDrNsUWb|*7NdH|Ov;RM?f&E{*hJPBV`WJ=1f1r-o7}@{H zH8>j=@@t&WAT4TVM{Th~#`D8B4APZzu zh=Et8;l$8?4UThzg`S-B?Ecj&*+!QijByqv0&ni?Fx^{P#sgCTc_NQCc;Vu2wf!=O z=?T?Jm#2a=b-eiCW(z9Xv;TyU&Gn0L2N5ka6J(Hl-NaVAUl9|;9!t_w3N>he0!`Z_ zbb8SlzP49)75|LM7wtUGr@_d&7u&Hfy^mjb?NrvQwnH3h!@yL1yGiC9GgoJmW<14w z8j;8-i}WU;oJ4CO6ty^}?krB=sY4RF=ln%>lpy@?LgFZRQf5;hkhy!ab-d9@n<8^j8yH0FVLxUJ-hND+~D-x(Fx}yVtkJMLN z%vBKiIY$>>cbSKZ!xRhkhrt4aeo>>-XVKcBRm%MRPcXnwb`L(_}@%K|NPG9&WA@Uu; zN5eGTG6dvz95ten)X6}ce@ESam3)^KY(j>c$K4nm|3;WuX5XF-XcgGYB|KpKny8zk3%kk67%S$!}F!Xix-li{Un$dlv`gS zSp_ePwN8tpFI<26E#NaA?b9)ls{(AhRugY9W37)FgCa-bGr7dV0E?e`@TFQ|;jS%M zO?ea+h%{2v$rg_npZ?|BE*_Qa)CfV&)x!fCLwve`OVN8VbuX!Ng|lrkJ2kTrK~^+< zf|p6Sjb$k9b6lKj2SVyDriz{o^L6yle5}G$x63~kS1JEG^%VrtL*f^+=YdrPg#IdF zqh5*{wNZUXwZkZaC^!Auu7n9YBH#aO)zQwg*#+W`0b=t@t4js$)gerFfCBsZ?ca zTdKB8yLme$vQm?6HpfiJgq?QKH7)!nsqMsI<+w<`I|b@nN-O(>?lTQ$*cKH9ds*B2 zME!*%h#TWlsYQ->+~}E~go*phNHMYrMQ@(~{)_y&I-?%3-kl%ElFDR6&do*Yz`q~@ zro;&SCxc6y9u)^|L>j)4n}kIkBjj_T?5q3S&6x%WCR$=Jss#eNg7NWbR_3f$6OiR0 zQAZZiME4c+<*)%&H~%s3>$?HpggkuDVh=S@bVk}~1)!!&_osIMskmGpexRC+7&Du* z)}UpG{CalCexP-pyB)L7Mprb}rwTpV^{RT>odr=*E1VA)%$=$!ikk(jMcZAzn6{0t z_cVl>uu?u|or^nGD~OR8krKR|Vhf6>8cq0Jq!-R@xGg1rjHg#3|Lp86obIiG>94ax z#;yNEBYDGP6SA0X$oV)X!>ypPzRFr~yE=oAuB1WAW!@4U za1A;r|M((QEBYJ;78&}w-urP6sRqkw=s9c_fb_jKa6`Fk4>n`RHK(d{Y(7NULe4T& z`hUhUrQ@fY+v+J2Ai`~P%dR+!co;Nnx76o6I9m_aQ&+#?K~@#AH?eyCvTE+Lo3N_< zHNv+ZN;LxMZ_-Uf9DbKlzj)y12-K&_Y5Eln9hYFTI&$hx5{I?BE_JB~$}*&EfWzCG z3s0SD4aZF(ub{&&7)u1bxRm|<0>`1KITikEw#3So*#*1qeLjlvgS5`FyY5b65Wni? zjs)|{DT+B}rgAXa*w^)#ut6St<@y)gKpcye7(1~NfsCTskEep%<=9hO1JIhmz_Gyt*|M3?mDxLWOht+B*?};X zADP~J^E9n?rlLg++}xrt4a=W*2_!z=-?$0__e`KzOROxsIAi-XwFxODiY1&5A>8ZDSZA`ZrRu9mnA%r z_^wst%2_a$n(g}DH7_5Bhg0h*|GMK*4+_O6Tx5^T61fh#9yR#F@v)7$xahbu{T7!v z$tm}sVV|V5WCg2eB&y8CuU9^)NL+52l~QA9~xPzR46S4zVxn6fwq0fm)9HSzC_kN zl0deE3r5rr33XZHufP4{Pz%!W3wvMJBk5txOT*X8t#s2itoqiNO%m^w`T}%2ZAJ zByDKJ_ZbZpsVBiq5;RXA#aE`DSfSem-mngQLfceMb5AO!qI#_Lk;6H(qtq z@E`jD2KKiz_dE@e*B@^_HopE$S%-KUVRw;#eoq7IlPh0@13`A^qkPCU&NFE?ef|MI z=gf_2Ky))>!D5n*fk7P&8i~$r_*AiU*8^=DlR`{oF)~DdRypzOPYM@yRHla_VR~liX>gI=6r!>1 z=xe*FgIdPkq4Yz#q#8lf$Afo;KlVsQhBYm+sLU}lt8X`68r7B6Z|7$)zhF_9FR%*W zc3Q?`iXvNun<_RPKvFY+6&`7b;^`5{LfEwyWrAasJ_jY}N}5?2AbpXO6+|5u+D%nd61vEM=$WX!@?!wsOiF?GA^V zN70){*)6>b1BBHB>VzEY4dGq#-93$Y8(n!>1lamlXunaE{kd#_`L9jx1Zvp&m-hJ| zQ7ZLX1)nmL0ta^VtMVXhD5qhlVK=^Ll=@DVgRM*g$j>OVO%d~}VPb)zxsS4(lPxE7e6xY7j;wj z*~lFBG3Z#K8r7-UeRDuq#aO@RZ*npQL_GvzWKseH#!=!}?he}pt%g~1$y^Yko^v=Q zgqA23(B7@nremUR@dH6PT^o1M_sKv{K-j{LcB?CEFVd1U@y2d9M#K$sxMUjQm-F8-_UDYbJw^96#~kK?5M3#_@fT4aX-%}$xME2s>%cBjMjFh>&Y-Iw7Y-b zW2X$MF>Xy2dY;$ZLqZ}7>^jTa3sq#!?6jR_*5!-i1bSfah; z`*B|tli>1u_Ce{-+#G(P=pwGrQ(L9^(RFJAt}Z$VvOzQc$%CxOtwnZiadH4tO$k5n9pt1hlL z5C&F6iRC+V#qY-x;M%?(5c6ckS+#Te`f;vH&J}MlH@_RGd=Qs$el}2zT*E*SR3c)Z z`s5Dn6^BgQrGXv9Yc z&G=aI8#v**)isbPm=*gNKL zUb2{GNMp!Nh8#Xxls&78sF64aM)Ff6tn81noW=vwC@87~7RxgTv$xvF*rX?ZWxTYR z_FWDGidEa(amIvd&JpwG5Z%fLH4Re@ARban84m6G00TgP%1|}!H#%&EyaWEdMJ*gA zJwH6`BglujWPPrS*qH0*1*6VPFe7HV;KnbY*28u6sIZs@v(H|T*ZmVQslpyRtZ-2Q z*2-F0S6@=QlqBe!PB$_?I(!3|6G5IR9eIwrrpQy@QchVb)P1RT8rs6F(M^fA){NnW z7TOKT54o3A%t7(CM3XRlQtOIf#ipNRwQ6%Yz&66I3g1bshUM8|ryMV#ax z4T992v~p|pa?^(A+5tqEvIrr4%lzQ3yRPyR0vtZqK)OP!M+Sz;jBt9mCzv)(69a4_ zzIO%VJl^wW0Bg=P&n&?~z{o9!KyTI-TZRMHk{0jU9vI`UWCljPG9IHXcfK_k1EVG> z<_RI?KNL^D?6d}4ZbNVKt4H7Z$k!Xb7yu2FS|Z?OvpfTHosIc4l;3WYA0FnwCr5U5 z2k=ul2xc2hAuv0qSF%#XnpI=Oc}gFqNh15CQ3*DS+gFBsWNlc4RKHC;^}B9iEjl*8 zx5_#y6K!spXfyw(6Kp3-Cy|j-8}+Q%-FJg%-a^G$|qvSe8?q*fP4cXtWpB`Vr`MbYkjt?daz0wM>UGh zd7g*z#cl{d7MnaG)>*n$e?0s;qmNz&t&KBZJ4f{h(C$KlBK7Yi zf0i96L`?XKk`yn++9;;2Wsc@TQeNvjVP$bLk%<*Ii78m}SIVBst&tIhu6->d15N6#NYYod^6xvbz^^kY9l?l(>1L^1{r-jP}EE(WIJg1|9uW|_Hgqbd)PU&2zZ z>;PKaXW3G{0L#ufmG=`GX^ynvS!`u6E`J56JK|ZzKHeAPv!ydn*I4H4`1!k6WeF7} zjBi~f&ie_PW!Bfwhf>%@zB`rbe$ktVo3a~n@Y770)kpN)VI1^8QNpxCGPssp1z99y zg#d^Xu*ZC2|8MAqq5=HV>$GF*Dw-4)7Wd?HD{!3Gx^*v7WI`K=wu^HEN-HD_V9FCn zyJs-=R@L77NnM_pMzJIJ7196fucbVSPAWcVUNe4nF-z9Av5;d%tUfjP1o0I0a zD`YfXN(U@aZ>c#)Z_Ohn=Sk>Z{Tp02M*IT0L@#UpZ7s4&`B?0cd%6NP8KWN~jHPpN zWwOaOo_S$pZS2=*zR$@epkRcWfO{;i#pB)vhb@Rj2;Yto>*1r?mo9nOPE#s%D0g(hkZdMh*F|5mai=Fl4$7;}y`gA89UF#BreNx}I z!!`U%B;w(=G5*Z%YWMU$h4bU)a;PXg1hP($sj2fJIxkH;YD@ysNCXxuq0vRHV6GkH z=+Y$?yqI~t25f%L5tNzHNhe?OR~-z%a7X`{dH^+F(#4~8nQy<@b*LAKi3n3g5GhrVRvRd*h%Ix44_M6s-vfLN&j%M z53p*CBnTFtNY$r-@EN>v#D zjmq|4x0C)iaKQg*2jYxIBW{$5$(1G3_Ub#iU&N|fFWBJ-(ha_|JfvC{0E8dzlA&S|0NURVEC7r(7%7ke|=W}$b>ll zm-QDUr;_cWI#1nSfLk6>0CEFuWm(1j|Xj92xAsFElf>T;#9(= zd7J~;kD@85+I~_*=n`UEz9%s;yU0}|ZQLOq z5)(}ncl>&5C?8@p(xw!a3)|89?;vBX&fvL}*elvGHl}z%(*mBvLa=$k?9B&5AWESL zO?9uIIKbq}j+f(MjN1%oeXC}fYFbX7=4D_s*-}7`z$yn>6z%>%pQ?bDZAbyq?l`LV z)5*xD?W{@hVT~vyX1*l~6_69dQgY@kD>k&N*n2wAG|bJp8COz?sRhvB0rP&=-G4s} z4x{`Y$N~gaWac99vRG5={-c4;3gy;hXUHwCHJk$I`kYw(2!<~8m)z*7D3#e) zN9d++*)9;A-!i<#H5%rs#&qLbqb3Fk==QhijawhCwkTKu4W@6e4z~bQ8=_USro|8OIN#$L)!`AkiB&I=flW6dSj00=TtDSHcoG8X6Mc}KQUP1MgwwU0@tx9 zUr$S&5=4kXt=(<9A09#6A4EPr;zDi&^gG*c4{?hsmphw+ikHcNza-6+GmF8(QDe(& zyY|G;dacx0v2xcAYZsfg5ZTj$0E{3}h6T8=n;DCA>fwGZar#|($H0)@Ad9_S z(5&T8ju*v)r7TR1>}Kj{l8AFJJ#a>$(?hXyCCacH^+%?~m3o3tre+;Di%3yJ4HI}} zX_7i3DQA968_h0!9FDxny}QS4ZL0jzkQ$)!1pt&#rKT$Vc7A%vcG@Euhex!43#T@_ zCT#NS-kmR-?Q%$Ri90WwBQ8Jv1y%au;AhnAXfr15-U%g9f|8ZP2rTy^QNjcmVExWV zmv%OCI7oVB;UjI&F`%iwBO7OmQKDTEVv59Yp9fgrR zo#(~yzEdMKg%Wa;S=v;VhQmTtesFIYvqVMP_YV;VeYgJiInQCbbXiq*AJKsCuXIJMkG&;vD;!yffzK0Nmlcg~{>O+gpnmk~O+;t!^;kq-^4izqMf9!Rg->-GVo^Lt) zpR!0eG1l>Su-21p*hBa~L2`I4^QR-ajdKZ*Vgrv{!0oY&bnZVqR5kI_rDz+|4HMu6 zCWM`>0NSmX0k>LAfR|L(WImN1mJ_*m_&j4TZu=xK1mff{+GDpR5r5yvbp-vf z3h0l5h}U}~DT`^m2=q%Eieq9jgi{z$if3y znzuSrRI~H3oUg_$K#Z*@3o33WHX_?3wx?7L<1HHmhVSf^#jAwE$7y6!Au zh&t-21SVCn0a;l6bt#E(odUgAm$nh8%sy4->K5XdVq5n%POCZZ1|8}VPzX6WO;#P- zl^?%PzbTbr2^5TYn}oo zHarEhTPikV_w_2<8}ClM<%}Vk!|aJ!(7o}9FJ+o0m{U!}ciRZvn((ko>XRBNtC~~c z8oJa73F}@KU_Dyl4Kh2g4;V9ABZnAxOs295&xz0#9A9nbOGvgz8x=g96*9)Cd$N3` z7a|D7)D>?4Nm$AdsEm^D3nhSum2!m{XsTsw3~w1J&zUF=Z0l2%YIGJW48q+gbs-tm zX^h6G&UfhF>S_tMG55zFwEBolsL*@7mFGa?FD!dd{TkLsTroks0%b^yj@PXJn+2ku zdRzwYvmWU4tkwi-)Xr|Fvmg51F@xqkH+J#cW(jaFsqiBNkHdqH>iqNyf@x~b;)Qrs zuWeC#NQSbg_8s-S`dT05Qn(8A=jlh~LdkeJ9Ig@oLrfKQd12njWFdcOLDh0UgA<)7 zjTY$>{02;nPMj<~8sXBGTV9_O77sX3inmZk>U+l$9?t_t^0E>MSR;471TE;R4SU%v z{b__zMM>rY5%!`Kbys2l95#zzV1aumH;9$0)S0qWuVId8r~wv`BjQ}XWTBvDpVUUP z6eZajSC)}lzf9x)<;|a}@CX%~01IBy0}sA0Ekr& zh^LbJ_;KTR!o7w{ACao(k1em+QDk44XOzw$DEC5}_X|i_>*PiY^WN((g5nE!$xI$? z#zjvvc~J(I@4j7KA%FnKW^d}qDJsy?EGPYjS`ip#mj>s9H0im{Kfg2PEgjv!+*>N< zOw*PmBi4crGiMapfC>D50*qC9JBI6B zEMRxA4hbcg9nQg>jc&!U5;hQ6Z$}PzgMC^4Ks39`-xqNg{c6nF{5gW6aQWSSLgC&K z1AH_;b*q-GC z`F_L|%$C&IWuX1dY{8C=ez2DSHZmf)Ip*k~%n)Q@$GHEIuT~IJhqI=lXD)AdAJ6Rt zfJ-Mnv|KDjFF(dZA+pP8`i!hHHtF}h&M*Qu6bgVVU}kPIUZX* zT36I>d_8GY?Isc+yO+&A^*1VK*$joGcVC1BWMIKs)Ou-jakr?NEfa1k=zuD=3s7sWKM95G}1(lR<6X zUrfqi(m@uM2AX3g8t53qx_FTWT~7g;Q2@+ zMmB_#UaJ(BO=a z_a_Bz|FQf@cD-Z=v$&nmk>UEROK1UmNm1WDOE2q*#P@Wb>*>ZL+@Gn@v}yU!c??=m zE#M6T2xe-nj( zU@m;{yBmVK>L~zINz!-41|c1(GmvGaq!F(D-^f9(AGn#oHf#QvUV+Xw?Pja<5bMke zV)RRfNb2fg`vQg3wU(aI(VI!aoEvv~QZX>!486dSjDj8;3lKm>B+Wn7>ZJnR?%w2d z8<8GIrN4MOq(7wn{WkD0J{Z%-ut-8Ql${>7;iwe{NI+Bc?+>T^ZKAyxGXeWJPkI$T zCD|ZwPR<`!W^tVq997JS*YegFIOswI5j1%MvxdJbN|f?ZP8!h7=tue5XU9S>td6hZ z!G%yxr#TfW8>t-9YcQN$S$ zue{YMXtbNXeIeqy=;4NGgjl>zXor3TuYOpxl=``=dQcd`{0<=WhW%N%234N>dqwjD zJcda8;KzAlCdouHMY~@a6OyEBz%K)|jSDM{bM666N&R*lb<{}Pn9-P>zK7pc>!u=k z&yS}qNh+|}VK&ayJ3fu3?*`-jZYM3J>Jkk0i@U>5=dZa>-;yNo9QstQ*%5#qNp|Z( zpNpjZW3rxFrhY)nGmC)=V#Q-zD+CZNj8{Ko14PRE0Q}BMRR^?lH141^s}GS9rU zMT%8ppYJJHRNXCsKFT7RS3pJtx(UkLFQFbPK^t*U2X9Z53TQ|S;UN+&KISq1?gcjV z@d#E5^=fMRgXTE_78Xvx&#(lCWbMcEe3ULopzC*@KT;X#8Py^@5sxn~buiCzRn zA3OT7HxdlUVBq|!dGX2L8 ztRDK$k&#?2L$=oBNwQ0un=uEX%(G04(%!LW1qllbED5i;d8X#%Y-PKVPpz1C_}gWW z?2}DMiW{u+U*q}lQ;Na-q z0>xs_8GRAizV@hV=#`s8(BX;9i_uOAy0j*&rq*(YjWpvfW0E?+8ll@#cqt>iF8J`t zMj`ty3s`I^rAN`vs1z?X2`{g|(wv@}PMPbc#xn97p@UpK%VqV^z6fz#sB@Pt2bEn} zaytu6$;~a{30k?(P-uAwE;||Y^`S-Vwaqi1AWmAm^~>dXDkNSj2M6TI*n#Ft)ga}G z6aUwcsrDHCtHMtRFryj^A85S&kHC;P=A#l#Wg!sNPs1OMN!GT1hRj zTO3W9c@%Ah=NN>pM@jnQRab?vj=;4$sMYY5oCEmJdTCrW*}_G;rcRjR`Z(Xoq%$5W z-thkB?2Nw>*?o3wWTw}1$%jEB*IY)~VJ?Ee-43Gjkzy^j#vc{kEWZmY>X#C?Q{Yqo zO8^BD=SK7%sx4WUyRL~o?DAHHg>R6@HVPiSnexUWBZ%oz26Rb;N?%-ui{d@Q4gQ$4 z56Mn1yV5aQCm$KA73O<%dYxySEmaGwSeKFgtL{y${S?}S^#^z0;2g-N*oJZhqdlH3 zr+!Jmu9$P9cCz_QM~CX^_?b%a!y^QA;iGo4vKOsW!D7T9|HV$_N^FXh!t(U3R*7uCGFO;P9ho#W zisOm1^v9Ij$A7o^ubJYKQKoWKbDJi=zzyx)YgkIm6j$G{Os`;{9EUs^S;1Ahi;vXbr95jXOJma@lbmrx^CsX`#@jYRr$z=C7?8_Bb9qBphL37_^U3C^c>s z&;02wx72Na+u(r`JG$@ykuT3Z-USm7vUT)ovnK&X~{)%P* zfCV=c)?(t79-VZL8YuZRLgmQIubMKl2lY&fh0We$Q>0ybd+p-UiRp7+X=4hqwEGxn zfBn{CpNV-@3YPb*h1YRo4{6Hgy1M3^$`CcO2Z7!d)jUhw^ruv_QdcBbC5~n?p^7j7 z=ujT5m|Ag?Aro>8^elwvk>{2AAk=%Ze7faXfg5tzk2dDGIDAfs0jo)rUaTeGeYt#1 zP_DJ=YI?G8)UhVRv%S380~Wpu1*`U-ksn7 zaj8aO(&v`m%>hNBXVSD1uZ|yx<$RBbO01a~w%Lxm0hB(C%@Di?@;!`A@~V$gM?SM0 z7E3flO}H8ntToO&RG@~^xZdqhej;ZkVbNd=e9uw6UjosD9sA=mzDW7k0_CNa*J!zq+7V_=g&c7~jJZSyP@Q;Vlc!CHi*M?hMQ=5=;on z9eIH9oEv9IYd6|B^UV#U47TRp0%KzdE8X6aE;D;QQXHb zAU`JAP0q`i&@P{hsof~FHRK2;4L^kRY?J>@&+fkxz^N0g77W!)ARhm&xYX--0FEJB zTOMIS{}Mr3C0yLWFm%6cA@=xQ_QvQ&++225xY0gu#EN*Vi|2GG$q%use_q`;bURmf zahsU7JKkk>!Onxa?Fi>GWxtw7g$M=>b!taxSwq#dx1^h3n8AdK_SLGn0JrP^tOu^} z&hsMrd=}a$A}x=xsS{UP#q$Wuk=9o3-sLq4Y+K5DP9kZP@pBu!MOUa>M&QK6{3ZAH z+%M7|T9+%VwN(h}LV_m}bccVbiU0yXm+w^1{2qv2|551F{EG?m{DToe)^u-)KX!B0 z%akE8M^lU_&I@a)i~%XcF&MdUZfzk3YfaGiOUG~In)95I{x?nS8=F4jXy3WeE-FPk zMPRLx-z)v@eBiJ+ey#XsqIM?}U&scf&Oowca%E)Q^oG7-sH!rg;;2-m$Vu$m@x@ia z%NO1}qVW{~e(+S5Rr6#0&kspU?yMV~CIrjyO$#%^4Ux(@s2#tt=_mEa#V_aeE|3*M zt70^B#vKPfHwQ4UdR@{yP86T-exg{Y?JJEux$KQQKlPxrR*BXL1pWLygzfeTKZos3 zbj&ynZ_-pIfS-2kT6Vet5oSekG89!pd7=hSjq4>ECVl~sD&nr0ZNH%BdM39e(M&h0 z_!T_?cZ4TTMw2V;>$|p7Ei?6$ryO;Fm_~w{EiM_1-l#%D1G>vC&_lVuvY%aAS{MHH zo^ahfB#=EZ$zn3_=woXqG<&N39zADpLYL{Z%l{cb18mwR)z`Q;Vroef=150p~y z3_Kirgv@FMHe?5^5!(R6zoIrqa}HkO08TK_ce#S)>9k*u7qCXFy?&JW=dI8;2mZnA z-W6;|L_^O;ut-vBI6IS(oa(Llri#aCnmb+PM2tHXq!|C)YH{A{%A##FM^_i$`QSk@G?-za znfffTjsjk~RigUirnENJ0cbanOBJ#$KI zhH!v^cf%TF_ozC?H`1_;~Upn3~(ZEuzexn3(A<6vS3JBevZ1i%WDgwvYIiB0i_RH+E?4GI^ z)hkGH>lIH`Bp!Sk)3*52ZFERgo@gu#%N%ml4EIjkQ3neE z!Y{w%6$i86BV5emGkI+xJVdYx+lt8!($|Dj@n^5mB*+b#>wd_ci5U)K+E4mzEw8chJU?me$WZNKotrYhy@z3j&I3OvhgN%^$COMZv&uFM~zP->ZO>G#dZXVW(B9Jg88UuRJs4X>4%=-==7PIWZTR_*1-0h&Z|OJf})=`?TOY1|6<0W#{w9Og+d?8 z0@Id}_zH28-)SX3I7Aq#`UYMKv^htTTA{bZQOkH}E+u(n1RS~MB|fsx?_>TpE_rd? z`?pnoIo*!fY69$Kdu%uflWIb_dQps%DYw{~-y#7i1EO}-&R&~r3 zlOds{cnE02q5YAlM{c>swHS#Rj-&!W%RfISm}g^CpUtuZbf(!fW1$V1$(U(ou{WR3 zk(3&l%ON?vX$nQ|#h6~}C!j?$yI->ie9mk{rIZt4xn7utoT(^*_uS&uH=Qqh5g-OTyaHYzknI0n5aX6QM^Duk=!Nw7Zj}TJe z(vsv@mTNr$`7>P<9JibwJD)@<%feO$$8%4zmx?3+m+NR%EEr9U*WtQ3t&Y4SX^XQ# zuc+^XROkodQ~(`19qJSYHNH!@>>6aUpG)7d!%p@NH6z2=mlFXVVwcDnZS>7SzX%Iq z-S`lo`wa<0S{4p@8OX*{OXCqUV`DVmfPUis;*|Z2S1Y{QN6wHl-kE-uR!G+T4J+`Y z*PG5kaQaTUb3d2>@W%PllYF9yGW9Zu*grh8n%OpxqwzVasw;{_->&XN%W#oGTc*8} zdK@}Sq_%@vFb*`3WR9C;!&KDby!av+{yfLngcZu%qUB})t7p?JtjK6`-&%11l7Z~0iYjx&Jfi>%b8#g`$+J{Lc{7^0! z^GCcg&ff3QH2CilZ3Fz?J!oWBC(F%X<+~f7Dyu>Ql9hn;M@>c>Sqrcb|EA;@7*W1& zU-n0-N&erDJdlWMDIpjp4^@jGkR=hzz$j~i<|8AZ(O*o0m! zbP6FUWE6{?iJz^YQd1k7dxazIe}pcQ!RvTMw;B`v;A8j-O`dn+v_z=hC*!pgo(IOm zb2qD!EVZoi&rZkiS_D!kPh~t2zu}sFuKdeC+P?Nzovu+PPDn z9R37`Qy{LTWxq9aJ|QsG6KmO(N%uKpiqO^jTw5_qU-LS`X@rb%g%g`@m(z_kBphM3 zk@A`f1}2jGw;#|Gbkjmxw14R31!{Vjbt9#xeDAB&qM78AZM$U9j8W`O`EICyA8OB` z(&56sk=Ky-{YOgZzgFV^Yi{O$Vw@Nmnf}*x6mvm1HGjc%tV6(DK+(?eT-Z6tGW2h% zwGZn;P@Z5DPJqmS64x#ZOAqGK8aJunq4mkCH*BbeDScO$rK-rCTbE?e7J9rZ9%emt z-DsM?c``J1dn62IQlq5!AWcY%LZ4@_Z%%y}UTXWYKl*CE|55wO_+Nn2|2%~MKc%n# zeF)F^|1S&df756E@76Y18JYhx0QJ9Rgym%9_#ce02NUAw>+OSRC|gqIl*Y5cK>b*N z-0`Sx8GeM3bh(9>4CZiLDDkn%X+n1hP)|LfR+xe$^`(8l`uQ>uJd6eg@s1+10!2)$ zPp-?9U#L?FJXUnm#HlAmjopV-efOn}dp7ve&14u{#Ny1(Ys|{MsQU?0OyXDf!YbO5 zm?Ccj3L4#@7Obyrxz$#HMUW`FB<^OzC`{!9a=Xiidd7lEm0ICyM z<+n{;sp>>|<2uCbH1w^{$W~c91trV?XWr$fJ^)skv3KuyG5OSTLjkf;8mdz1oU4h9ZSul2)sC(`%%N zg7qL+T;HG64KkFUzVqFKr>-N7>=Hf z+vAIZS6xRK)@O1=0|Tq_b^bWk{wGiD%aewLf@JNE1IQ1O;W6Xo-hIQHV4>0X+`3_X zV(qz#%o?juSyE!brW@)|*9LAO^vtzJM)T;s=p#s}|DqSv>`^Xt-aNP5cIVn}+{blf z5EHPjn9YOBNPXWemF5^*PU;@e*7IPDL1%bF84G?^-G%uQsU$pUgPf@~G<^q%r#SFc z^50Da&|gaO2yB8zOrEh{sXET>skyML8OZ+?G$-6$Mat}DMX?kYxlK>Ew#ypYreD7>bDt@ zngj6jw-Cx@hxIoBONGRK*#2@s#&<{%lxOAuNx)-0b_ans(jOd-?YV(CBfMiTbrC#? zZ@IQjiV2}ijeGHr6>@t8FJpj!>eP6*VAtq657KqT>n&7hktxj2Q{!^hjAy)6*8sXB zcT*m*Qea;28BHwmt>J8qGHQFL{@FxcF?$15PMh3Y?f^kkM`~2BBn~(_jQ0yaLKjlJ zJtJSux8IRalvB>^N&PK^!{?M7p~U0#xlFwcC^j?RS?o6gCm)}`&DOFl`S;leq{?0{ z$%zo1dxXYx27*w>OsVS%ZT^7#InYakbt&a0xy9PLp-MrQKU{doXe_}R_1Jv?j*84N2xCW7yKpJkEBvf1lexh^pr#NJtx3bhAXZf`t5n356 zyL5!Pq(amvyxgTOjzFK@*wj}Aja7woG8Ps_?8`+z2zk?LN)qZ>ASK?ITV@Bz%j}NN zh`p#h4OySYYcZvq1o9YQbX|OPH|1oW<~v`~95o-?L|GTF0w<#p=5>+XTq<8xI7uR- z1Ip9@-70+?YyB3U$gbAc?X{wUIg{#E51?CmvzqRzw|WOd%GrMq>EA2IX7Ij|H3Zqq zBGVPh{_we<^?0jaH6~bnymoNBjrI;U>NOoFt)tHZt|v`Hu1~ zCxs_Do)-yc?_t()kSQ(WrHdR)-`Q6?aN%MwI~V}dXF*vOJ|(89OLxN}w{dyLSFTRU z?a^UEqxZ4{^$maC63f8&Bf{LmhcE)sTN(CELOww)>m_PCV(u>3y}}Cbrc5&v2F4j! zTk#h+UfGp{lnG5b40422gc4c_p(Hf*hS-JRuR}1hrHv@4!6EWf6BFA*V=oE8EqxB0 zGz=qWA18Ay#CosKh=Q$3a{B3=-_;ZTW&)|Hfjp8`0$m!odgyB34THOvuVD)`Zc_uQ zv_&u-`np^bXP|s4Ma!8HDkV$<<3}-n(r8u_0KD$7_JJI*>6sMk18jXNA~8x%Cd0-m z@So&+ZH$T*q&-(5MK)$NF1=pf5{WlV=P<)z$TXyW{okqv029O=WfO<8$1{Cvvnhxl zq6$CA8-15?yG(NHq@57`*jrE0szRb~NT_6Wn;)~?O>LohST&VMnHVsj-WT4A5i;TT zeJ&*;ECucDjkr|Z(-B=A5KGpYeq#U>D8O)_gT9?1qj6P5c!%mG=$VxBC0%^ma&agx zKHNhg2j6aPS2>VZ{)U^6TTix#J9S-_p%9oR-csnaY-psu6kT%~P)8a$n$m7K_kwfv zV{WXve?wa9)`JLh1Vlgd?6p2U9!pLCfY$0)^|tTFB;EZZ4ip70NHofC&M-5n_uG*OWtx zM&W>rW7hf{*w*2+UdRdvf;1GOfi(_+`5NoM?bz+Jf6}aL zH=g!c4d<3G^vOnxj_$)eQJzCtjEc!Nwx}tDS(hVA5sEN-b@yJlEHOI%N z=WVrJ%lc3!wqz`g`0*)c9R~c|{UtfcL{CzjIPCNk?6YznD5(RI*mBk{v#wsTrePIe zeH+zJ-lb3?^!9<1OzC5z2yFA%KPDvsw4o5|i7`la_yN=m`034Umea9ZwneM3D$Ul} ziF+dFMY`Spbdx$5%d7Eh>%a65=jFPia2BM?_?`%b`+Kh*nYU&rfOewgD=_z&o~?Hn zv(u&c7qZ$AuG<0}u2c#7Dq6j)cN7)1@P_Gqg`T(C*cdz-ieA{Hoo|Gs>AdjRBt%s> zR^Q)DKI|IwT(VGFi^Fhc-_w;aYWX+Y&*3P;(}|}pEm-F53?U!9G`6sm^`fSmPyq-6 z8}PHP^shesab!@gBJk`c+ak+gx`Dz}2;&btI)lRz#R-mBwuy$ELi`@Nw0kK-16jBu)^WH40ZyD0Nxdy~<&`fRJ_h77 zRk{n8uV+CR9=Q;Z%>Be`Ktu~-IAW;2L&aooMX#($vghn<>-f!*DJA$rdM>i~VZle-<(>m?lak`gqKT(yrpQM_O|Hyn1qg7O}K zrKTF-j@0`wLQ}xx3IDICTSrIvUZ%vm1=Gskde%q#835|tRd3xEqFf+3RO~9b_y(HZ zZ@1ZaK{L&m=uNb*OCnD(s;H9db5gTeBzsAD3`U3v=FH#C#87;M0qI2ZyK?)GG8C?un}w(h9rQ0PVXWci?S=oYbXe- zr6utj&&MBUA0p=op)#HS!0HXWV9zR;Bp0dJE($CV)2y15M@fJw$UM)@6{ zEBouhd1$F}n}eY#5jtj?B9y~dAGQ%#L`FN#B4tV|i^qH^8OXWD;iGfee!Ra&nUt9Re2<2@xvA{8_R6hkbB3Vf&nmnT#m&#Yn?PyxVyKH#oBQd)bG zG`f+MIvWD!y-W=Gk_v%0{x$N6xV}*pLB%L8XTukDn_o)LK%uufpU4^=bfH>Scg=xn zl{U#P{1Ll*#kLjg8-CIzx~V8g1K`qmX+~luW^<+yLi9(tuqazh>AIH z_g3%@XZ>|07$-21roZf>wX3H>gODU&_d|E>;fm^cn*{N|uuQu^9Nb1=S<{9P1(JgoY;b1l-EVM4pJMwF;GZ{%H7Chwn_ZIwh{pj`m=i zkm@dAq$>8+Y;d*PwEueC(+9g-?8Q0IpNU464tors8P8`uWUQ>cx#`E(M8@a3n(Q@2%P=&GMn>XmyeomewUWSH(uzx$VtxoR zy{eiCA3=2J!SM~vys($MEiOPI($C#S>7&`!Wc;UJ<2et}1U05==f30AYa|Vy18=?ku+tU} zTiU6zW8zcLgwXkk9UU_5laUQyq=OaFM0b7WMnynP`qMr@EagDTGHLkPN`gDU8x!U3 z)yJ*xy|aQI*mDVnlaTcQTHg;!hC*cxp-jq{HjmEeZ!v`$wKG@2$&jY=5QIh|Jjlfj z07XCqF{r4km{@%L9Sw@Su9F z|4$2&vEJe6sfU&HcJ+Wr$DB{&ry5OJG&-(WrbCb!+#avT`%)pAD~BDP_dDmNC5cn6 z<@s@i05vr1e=)qL9!8&RT133cE#M*KHx_@W>qzmE6I-W*qP;M9@+AIU9wvW{A+95W zgG@Yb1v;^5Lx)J>0ezAtIeGvoTXj3%#v%P}^mh$WLKAt9=2cEg0AmcqFqHJc6EJ~N zmP=Rk>4>{-(~wffxr|ijO~NJP03M~tMK3od0`o=f#Ne&vId`xmIE1$c;z6R+er0J| zw(VoR-BYondo9-rjUa$LgLoFNK`I^5K3DUTR|OV*=?-ejty9(1(vfO{o`STT0qzn@ z&tO=bLip3*yajw9*@_=DqMP)$dd&sfQ6{>N$8tN-}=7aGNZ#C$B5`S=kz`h2DPJvrZO&9~kkgE_-wvk^Xct;QXD7MEv4LA{5a0(AJ2%;tkFT8cEMf@i!-mw9M|1_VEI32Yva9yXwX3bB>Dt@Rhp-z`&3xW^kthpo)8;y^Z^ z;_Fj2&U2;h1`;!3ooOV$jvRgS+F~b(nM%FXW<4YSp7u@c==adUDkrFhDEg=CCV9Z*| zs|S8RTO`A^PyfL>%`yT6Y&ic&{Z*KgklmXbJHG)`>mff%jnJL`4Ue=YUGm~opSL}F zilHM6E3xD1V^gdy}{Fbj|b?Yo)_F5@ZTpR@c~7>B2$Q3`N4e|fe! zhv_f!(*inmxlfWmTSfOkFK2*VoK(q*J^b3uBvN?Oi$*M8SHdxPS6rqU8%kD^Ne$?N zwq+$e@z@eaJx7-00BD?{&E3{ZM}31hNRPy3K3^w;8EelUZn9nobq*V zqx?Ga?0xR1#=Ywf-9Q43yE8gbm$9o%B#w`7lu~y1;-wOqZo{hL;nVs&(Ikf3&^+5q z5wzl8MAwvkcY)t^)q#5ZdEGG!Tm?{6VVUV08|O9;K6ep{R8YC&+>mCE_lBGSg0*p6 z)O;wN|DiKP2M^9l$BL-{4%;KXz*Kp%sPKZ9#JhHClB@~B9XU=`%ogBAF)Z4K-t?>W3O_+*CB2uE zJhpdOLltCfULMC>K71U=E%M38o%a{qYVDXuZsIyBx_L=f~grr zUy(~e zA14ePh)omCV1<274o{}Dt8f`9X&j@~Wkt@jr;*gWgG-le$7YN{*Q0ex?%s+r#nt{{ zTl*n@q@8z*=HpRgwZL)3t{E#ePCtD%JYZM1e~ZJzB|{gFU!}Q9h(ACP zb>D|XXbp)OeHhWk{M35H4}Mv z`6h=QKt!{X{PZil3A0{LC?F?5m{M_O3WIM(H{vYGjnJkqArAl&VV)3(ISj*%mpT-8 z2@a_@6EllylVx4aY^fsWzHUNb%wkE|Ld_0{k?Wk+B!6&i^cj$Q9?Bsl9WUiWpk^@Z z-tt8Q$(Tz+YNjv(o{!_JmW&fHdUNuoLC54?C{26cdqC;&jB)x@Eg2{(DbyUEI3EKn zulMlF(u8IvUxl+JOXdr`;=ajX+*GJ;@(8WB$}Vekmz|U17l|7!nz_)Svi@EH6>7tk zx^=A}_DFO59vX=}GJy3$q$wpwnC8P9fy){7dS=Q3db}!(R7p5bCr6}(Q|mk@=MPK& z3C*3%5YunGhLrth7&ze)ZBBJnl+RueDZ?qK_j-oll3q@4bd#~|NO&L8VK{(2vdbtYEbdl2U_+~yM9p}%-b*fWSKPvZ! z30XF0(4ho+3_+_P%OAf!qL?IvVkGGuIZ<)S9qq|hTfI!2jm=@j^XCsTs@xzlQD?+@ zPW`x?$o70@HQG}nJSeRt9>zj@UJ#m^e@q!^mKXZ+lvERNMb?sLDPW9WUIc(#Z-&|q zYT1(YRF+`MPMZE7)B#Exmv#f*etv2*4b%c^8YpFHWn?UEMkKMm z#~N9H@Byc*P`JASj`R_qpTLG>sk`*+q6$IM)H3zA0nV=mdrlokRhj4xbe)^Vj^BeX zL1(Yl(5)8#MTwMSV8>ajodyND26U`1OpDN4B0B4_j{*5T`uU^;@?q>dB;5VlJf z|H&5Gi8d9$g@UD8{c<)&l*K3pzh1$&8_+zf*Z3u4=Qk@GihjBSv`HE=uM#_u5_IBF z&LkpTb)TIOkLmae7S}yzF`Yvnx%ujLiXd`V7IHK(uhQ>V0KuQ29)|9Pm)vgb)$P@$ z>zw*ij!$zg4eo+r!*m{bcPYL{XPEPK_H~fZ;WYsP@`gre3s{?m*>}!&d~CLaJY*GC z|3$FfU=%_`kXsh+V~>SzA6oEhTy!Og-ASM=5?Sy8gpNA+(oyDri6b&CwBQm97lhf0 zlbg0JePO3@7H14nM37ZqcACc$(7F#Gz@5==h_`eEmcj`4lyOzX!DG|8j&;V1R>RcT z)H->{*K;e6BZE@aCGg9V2Y=m=TC1hR@13XsQ+9HAr7LFNb*1>)Duk+mQDx-vU~su! zazpX1?h9WQN94f7Yzf)?iyMnl2-i(|^qu#zMz3u!l9jgDDfZz98+e#}itmcmOfkP& z%XrCp_dvV^0$D2aeueL5b(@p)*otDL=$3VFU=-j=+~MR%judEQ6^)86w54@+&p7;S zSKEvbS^HQSpjD&@tTaISeRjA|7SB&VnpL^$=MYDcR)|R>9VF*)mW|y#y#u8Fm$6w7 zg2iBC@NuO5Nd;0~dQ^2GN`*vbg>0YIcfZq>=8Fa~*x2(tB_S}z&0IFAsMkTBP|~*e zwkWLjV=K&Da%P^tDy-6E7J>~7U$#LYqg4Z%YPYk)UY@eZ#aT*Eg=4tnCLgp*Nkc{_ zgfC7TbmuCywBhcIUev0y=P7zF)oM9aHu+YAZmdU8&Y;*<1x}6I2pt9%k?}v5V>k~@*&6H z&IGK}7$Pdqwg!b5qqr#IogctDglqYkpu#=lDWo7{CBnwqf&aGwQ9cY#x2rNJ?q2`6 zR}^#tnzeeei6#4F9yqIH+Lb2n=uJDlFQQU^QZEZLYn_n7wdO+&f1{d&l68`2!tXQ@R;BjkqT?`%Jx)A*$gmGpxlXWE?hlr$_zD z1JrP}+)HDWM~-d%cS2jN^oNb%j{jaXd7cuZ&FlR^8uzfy#5W4akE>Mxc_qgC>KZ0(NRFKZvwirB?-N+P7{WU4}NKN2%t$$mtc1XA}Lfv zAEFsI1mMRy7t{LM!ElEI%9gc7W`>$k9bhNsoOFST)Ujk$!&@frYGgJDg%skL;i$ijp z^qWf+qUCNXbtqMW4rZ>6kT6N$<(txLg4OjYQJH-euBTMz*F!E1EKbyc4~}C{j_8h> znT;&p!R=uHNRQsCEA50t_+6?QQt?1{B zDf3N92K4B_?!s}p@SsQc(_bxPX2B_!)lEURZ@(BD{r|F z{M$Cdrlr)j^b@Z=M>Jn2{66~krLr(Dn=4?`B{ccjD6>sD(pxy{J+V7|3CK=Sy`F> zGxYU8bYK3%W&U5*D;5?GK0YUBM-u}ZSg7hf7mhNj@$?P(yfK7rv|(@sgpFaz_()p+ zZ=I4r+@U3>lQN`YHJ!Ju+=v?hNWgLZN9$pKkHFPZO!(b$vPFJdYF~G+95>>Hz3&Z} zp7qrenMJ4zbC!YFLeEa}w+w|+4d){Rcq2h43Mm!`2`TD_%y&!pnVH&a%wd{8@ub%- z%^~Jr;&E5K6-isMSQQ(~lLb_gzV4%dXfS=6$4m>}prU{sMhpf!?`#M;pMO(;I?M-x zi**wsC1UW=|dYi3O$7s=q76|K6i^|1V9Tkt55pX-WBwaR0Fy@fe7Fjz4@RMxu+cL>L z;k<+X^6OMH+k%wXaWLqnqb+z$xF8e7e4P#H0tEQp4JW`0JcWTVH!&5#^R&ZBo3xiq z*V(#p9)MFzm`dNV?_+MVSBgB0{4toH@f}queb#4Y<2uW23GS#({q% zj7Ptx_bck;b=Hr^Ak!g}?t*(UnQG-B=QpFm4<8Ql_cE(7$iGA2ewY@mft6w4Irby3 z-Kchcm~+`m{Ugn$KrtraH_9oSpwgKiR5}mkaYsRFu0vTXC!w3fT1I(cY=D4URg%~n zk(-oeFAit0F6-gen6&e-Lea`4Rkn_W)c&E@y$dO08gyAQL!->uo80Qhhf9LgYVyDh4q!zWrkzU{TfKx=3*nrnJxv{_yqNkl?@J@O z9nBK;T4jk#Po(icpHIKukeN7Ibs)Y_G$qusr488WS{U6Uw3vD#_WhwDw|EPXH7M<# zm7^ZB>8agT_@&QQ*O%2(@77lO3>z)xoj|z%HH|DNSjY@t>9=>3caMqY;oS# zB_}1nA1OXBw^k+~PMIm06vH=$mA58Yc(9kBDG7y6`y$NDlU+^hJ{w>zK!wj-&@>c! z-Gx{{PezvBb;psz#gNSeJNDwWpc8`bkl>i!r%Xv}_leP@^vk)qxlIl%m0FfbYUwU` zXV4#t0;{&YldvpqxVD|-6q#38yFvMi>IO2IQmAW4`mt0M7AYC;8gsDA>clB@>xL>4 zsKUSrYN=y4Z)u4o(&tjGRaf8Ifu~&%v5G2BTHw$kqoLbWGl9kfB;F0-TNR~E`-(S+ zYWSt|n#;VhIN-CnF( zXx`_5(5}Wqj3fNV-zU9FN8QxvdSnk8+oXJSi{t`BXAbk^&4sCk?Fo_**tmmC$N+zX zt2pZPry&3cdjn};ODm8f&6GhN+*4=Hw(B|$D}45Eofu5~)L62a{>%dbL1xHeM<1C z1;^4-tO~n&M38Wzi)`_;WC^mzr~*&V$8ppe{CT4WSt%p3=x$0^#hAe5TG7*KCTGZ+ ze=Aix>+E-eTBXy$GBx=rnX#lfw`^o*3W)~q1lUIV?NuH~qpLnYk;7fizW!*ErWghV z2DFL*j?3}f5f_=YjP_>&|9MIFO^LZ!+D}!!2w{*JZ0xx376b91gioW1>UtE=u24N= zIYNlx*|i7nSwkdUIxG`D^=bkhVe?xgXbqujEi@m)UyyR0`F)g^kV@ z-u&~Aa+l}V#L!GyVz(;UslXS;?BF!eC{b|k8u!YW(LSaAD+*~*<2 z&1DZNN72CA;7S6%;}oT6^F`SCVC+5v)(rS5^?GI~CZ2NvHU7{*w&!kngY&W!&wcZP zm<- zAk32{lW||Aal<5y%>%8}D)#sr>#TVlz=gYyFDE_6gw;tq@jZ{tfMZVSDzX1xJ>S1Ie< ztMx5pVITD!n@fBo^aBM(5blF%!8b8BzkU~Ghj=?lRs!7frDy@+-Hz-BB@4P9mzViL zS5mV@8)2|j{}ZOAxu`d)dy_YQJ@suM2HGuGD~8UmVI;HYTB4br;XVj1y9`BDuV5Z| zA{$;}RU5{)j8wM);gAD>#GMJ)^G8W8+5~z?gjzR4&Q^C1^RR7IA8%+JRUGQ(rr`FO z7sIU;rfKYUzwRv6fgNC*i zVeZ~1Z?fp$NEbcsLatp{B1vEoFG74vg;y>wt{jdkM%y4w<~bp^omU|K(gcL5r0TEK z%;+xpRJfmtAg@7B*uI#`@J;3oE+^GjpTuO)KTG|Y->LZCk@oc;NAPII!+tm9PCZ{< z5fjGM>Imgn7?%0TN9#_c9O)cDHV^zK#cdRzY>}RwXUJvFMvZc0qJq2&$3b506i_V%R{hr-24X=SO$j13Fdi8D(B{rKy*Xw6T zJ&@&D=VU?C$eN=g)V33)8mTK=sv2}GF-ob(962Z6Id027OSNa>E{Y<++=V~u9ZG^K zM~Z5@vL?Xc&2dQTE78+EZTyMw{g>*N_N)-sA(U z7|~$iKuj$z?ESI8vCx6_@1#MzXX5*k^;BwAB=A*}ry9J6mqAt%V`|Xm5gbCrk;H<6 z%Jd~>Ac`lRGODuc{Qx3zw!elsyS6ZzS5r zK}JtN`v{VRlOtOQ2{;M$qC8?!L>rL9VyOyv1dW)cWc&v+3GcY}0_U+vLBQoDH#fTh z`Isf0^|%OLY`{N!$l?0MVGBw+<{vDUlkfDi(s>cj-%iNOs6m*7_+zZB2esza9ReFf z;vh#R9hl@>S`z*m8R?>UMk#C~mw`3IB!3O>m=%Xrc|kpfb6nAP?EtlY_GTJi7TPCX zusL+OH9jx}JSB>1Iou2diq6lRPcga4NHZ78l(yAt4WqKY=P2&r{$t&sjX*L}4ft0A z8mku%ig_1QOz$>auxJ*)ahtWr&L}wUp(WoX70mIM$-r*BUlEmIgX$TTZy_xBVf%AT zz+pd(Zyc9;OEWMh#e-ngSG1d)Aj$ZC@2Mi4OurRpi%D3-NZqY5G7UE*k5Nwg(~_Vw zH&-31;CMvsM9M!yu1o1@#lJlww4+sr;Awtw_K0=8ur^oGb|r$a;mf8{k{JyQCI3=C z&~f`zCZ-F#^6oU74bMd^afebvC{P>B#WATjl~r2@84aglNtk?u%WbQna1iRt;bpP4 zq`2n=dIuutxTDasQS9!!y?w)rSW%xOfx}0?y%jw;bSaxmvk@^)_ap=8<-+?^)f-FP zsx5S)Moup+Pp-Eki#P;00wpdWN?p_zHvEn|`jl0FCqZ zn{$-=8mxu34=0-&n~#8!(YzzP>-a2RvqsKNCwtq4wIsDC(gc+JDW!Q_SXS+PTgRSl zpL`+M9NP#e=BdsxlL1-2128C8%37PLd^{%3r3kGu6L;Q1NR8DZ@i4j0Gu@k{<&DfkiJSSOG47N)(rF_n@zklzSO{uO$qflZzk^Ef1_xm|!6K~bM{Xdv{ z#~#tba80x9s$I5i+pb-y1L2vUd=lRaWclfZEZ)-H63>fD+NM+&-TP-!7P2&Ve9L3YIhsJw z!U-JHE@|ag%%_w%(L4tKlea3Le@f-((IX)aYOHA}B4e8XmcE0mBx+QY5)Q zUBr>@y}$Z?F)fXsJIZ{Wk;M-L`^>@bV@uoLi=X@9K*`V~dr2)zNG zrpb4U?W}jc^pO{E3ewh{!`%AdsJ)TAkuqXLrT2BFVG)^?&V8CYB8fiSEp#jg>f30gTwkS}a!~mRo|!hE8=8TC&huzR5K+Ef0#2EgEajO`W(A3fpUh;t4Md0`WLT~m!`yKO7Iv#K{3u%{Jm*KL?@V|;qBiPxnH@*PGH0_mc zSjQl_WwnG!dM~c7aN&=-*=TdiFlV_cSf0!CaeYS@i}AM9He0U4x0eEQRa@YJA)Dz) za_){%YE-n(kl9LZ-k~?4;58>Y0_pFl%EaT)~jx(}~kY^fH+woE)cx$)hMaFVwuozLa$Wd!cBPFk`$ zc1+P@?y9%=4>`D;0n;e7@P?i@_jxWbx`fuH2L=}mo z&bfbUQqq%xaUjKvhSUz{voqk8Uq%mf5siOSxCzC1Qe?|2!sO3+7BrY`+kQ=`x~+SZ z@!>`**IJGhX-@(S#|_n?yMQr*B75CRC?8>o?K<5$@33dQ?lgpy3NhkpBZGf9K3n_}*TS&=# zAxPY(|9Rp7qfP4lg0_3f%)8*I5h%%!#~KRx2KQtTOYfkC_h$>)l! zyEgfux_5=@Nps5N!oyMav@~jJJ-^%6)2^tsctzMVSSaJ(AymGjqisL;j<%^}U2J>S zJ2-$Q*4Fz}N&c`5FfdG88Jh672Rf~C(4!eAEWFfo?#zOu^MEz*x{~yc2#Vm6Om&nZ zcwHQgzBxWfyYT6d1?KXP7Bgq6YbLc7^k4g0d801VovXHo1GJ; zo(}b9soM2MxLxkwd;w76eO_o)1qZ}8F~L@zrWaoi!~5P(OsIIUsS%^Dyg#n}o21Tj zikr)P!9HAoKGM4t(j*2fLPyhiiIhqokYb7x-w6VzP%H7!`|-Q*)EYcdD!G8%SzO*= z5+?8Pc|v7E2**^zS>(*%!a`|&xdoA)Z&{uwuGR70#vPKIMZUa^0`oEiz*uYfvPqqW zJI*wx@{?O$qay!hdiX-8DuD_}85*s4{wH^k2Nr@;oE9DQs~C*QjX z=4u1JVfyfg?w30O^JHWe8!KRd&{Ydk-!@u$ z75Z^J|w3NX(nx2 zsZTey2|+Vp-SAKY2DnY&9HNZ9v&v*94lex@-={MQ4tawF=jdDL_PH@IcT8 z%v!;VqE$OFWSMi4WlO|B434|+FN-<8avM3eQH>BFG*n}kK1VCZ?*&Xytz2>1B~`wY z_Fr6BVQ{MODf|xFZb4hZJVJE(;ocE9fqJt$ga>21S*#RjUggqd7uy)ZSNBP9m%&n+ z5lY~gfB6xv?GCq;{n0SfV(HqiP4}i8|MsmCvExCNkuf^V>MK@Ajx@dk5tmVC8jyf2 zv=<@GyjE;Dv-3CF+@-FT#(ztpEQ5h>sg4KrS=?*d&OUtO7Mc9T%*zIAOjCowS0jUm z-PI|H@U$9m@+=tuA~*j!8j$v(*|RYD`o7DjtcXbEFN$w9QGNNZvA&D&+D*l&A+7`^^6V$2>9xKxrtzBp;|+g_=l4OD zruk#M14#PPBj+{ePP9tZ*K`QRaly=d-iV>A)3TC4Z3i@`r~?YVJ&7Id(+Ds4P}$a4 zxB##DLu}L@01V-d+-g}|gbYq7mAVI})E;I@`)p18Hop{zkH&kjTWspkSC_la=l%q* z#H12#dMqcYOjVO);uCAi%GG0`1YIp@VdFIbDIAs$BL!xm{O#s_vhSR8MW}c&#^Of_ zxjUzz*JuhaP4>|?&ED)-VlF343RW=hhRl^8Xg#>+akgGWYX8T2P)HnSPyEE)C_yc& z-B?>bC&vSsWEHbwzG?tnrKsqgf4EI~%MDZJA_mvd8|gWdGaR?5ZACB3@Dw-uB!? zsIw_qPz1V=4qu(n`layF+EKESI=ET( z2W$M`ehaCuGO*+BVSuV??x)`xHbEQrap#KQWE=$ECk%M2^!Y49mx!hUk4P2C_8&f%|)5b>|m#v#xx`#Tdrgr;Cx1$ju2L- zCjybrw3TcmEoLJk2-N)%Y*2r#ohuN;r2Ba_AOFc@1wCfB=$&?f&p!QYl3JxXWns4- zQ|_LEC*Lr%>zC)0%(V@|@Dz^9))se-Z>!*E?2VM~aLhHF(v#^fOdVlf5&5i%#j$S6 z8cg(umR~(<_o=yRf>PvR8Xf6+RQ#crd>(FWn&qsSsb*uK2%2Zo_?4rmDV+A#UyF4{$ZrFz>TyEabzp{Fh_5#|~Ki z)(v`P17zr`ftw9!aXx;gp!T=r-&eMOsOf%OwQ3B{pT2A?0h&v>l0xeU2&;&Bp0#P5 zdhExvd2&p0l+*E!SJLt)0RK$V{uehC{z)2PFIV*?&DlSv7D5=17c^EcOP$(Eexxgm zCsERhh3yq!r?r88$0cSC9R4T@amut+_N)P4l9eoUmQQH;yW_89ae8cFFh8!3km{np zwzMAZC|$tyrV6PuTux%loP_~?GjAh&y`Y-%cdIs`wwrunA}ybId`d-tZGYZYIj4?< zw<{+)+1r9;J*~hf^1_M$F4=1;hXPk2cp%Ld%ep{D#)>~TZp5@5HA9p+b5wF?8a&Sw zU=|sq4uXEX&8lpu`7`8SWRz2}6uF>ik(%HjP)aM}Nz4`{2mv^_?xQaB5Cf9M+ zdG_~GC%N}56u_L2vOPdFCVdF4LsS4C2miQJj(=Xs*@b@j!tgO*?gK2so&G83YHSQ7 z6pc5@o-h?=@Z~vHWtRa|OK?oA%=tQ1fD4)_`3P6ynds=5rqvK+@MDV%^`HN=Sz;G7 zW>Sw0@gnlgIGDBKf=hE!SyoU@5UH8w(a`M!*kQUJ#&K}>%xZM*Fhc`sh$fL5=Gmr~ zRL4qWU?QOkkMoXkFfZCTpbbpgB8;rxAIf#n#uZmW_4=;cgN>6bDmGK{Hek#?!* zzg91XNUs0iwnqM=#PR{{jU-XGD;=i>@R3uKRH^8+Np7B>T zdvi-JA$x^4KhTDP*JH5szyZzlP$WDOK5-s~LjZfKld|IwIk()*N{P4VnGx&qw^jQL zHqDhl?96U>mMovzHO;Ql{8@ixuP_Lglc+{y_cwsz+W1bNWf51_#~T#{Fp&v|tCdB_hSs7yEtf#0 z#Y;$&dRJwY^j3VQG{xF_{0ye;tgP9WIwLk<-Wfh;-HgQROtHxsQ8w6sm5JWA1G`^& zSi?+a&u=#(5{zr=?;+npnmh<`Ml2h23lx=*4VG(2CnG&Vplz}fbb;&t6gi`-*S{SZ!XePah%W%yGy5vISUmlp-xL-KBlMa|A`T8VNc~Xz6SUP zab)@e%s=mg_0D3;Dkhhd^wma^FHA*B)lDY;UFBdjYa}3mXzbXpFwXEqM3!mYG})}l zp-Ao!c0QM84DKvDfCIGa#b$mS3F>B|bc-0BKUgL!A0_&yWjI$xKF{c7*bX zwNihsGSpR%l9~xx0!s38P%>@U-vO}@5OqAjm3%sP1u2AOTJ;xFko9|s!2MnR&9Ci- zgr3hj06w<_KHXVj$3=NWqZD>*?E{ZR%m;Oj0{&KAa2lGeE)bqN&AYeZnvh4X|4eea z{eI*7S+AJYW!`=%L=80o>HEU1;-=NPvj9CUH|1bxHn+3c zAB$#%Y6`=-JNIs8V`y^BHWY#ohNDefJK3AUmRPO~7x?l%Wa2SnX&aLh~3VWS=BKmINDES&x36~L% zfhig?*RI5K6sW+Vvc|TO&4Ooi)CdsPl(PALPiMy`uiYSo?%l)Fx#$)`T`S>xZ`~$F z`n(Zr){)XV_71HZy8h*#6+kC8`c%^WE?v1P&3%{MTJwT(CC3MmoBWC^&lHwpRxCWT z{ClD*T%s{KELeon_tRR)`fRqkX1heo)I6yn7Cm*M+3`ypYIH?`f~wL&OmC}KVg;qn zK(dK`HF}3I3oUAq-SqB2b7opUeF55E%gsX-yFbJ${d2eiM);21hRylz%CKDj$np2B z1oM?6MF~Nt99GYZ+-MDxPTmj%7e~YxOM3_gTqe0_0I}q(gIB>&unQAnM5X#fWx8ek zrV5GMvf}1Eh!nH?%Hdh@W<$NrkR!^JB)iGdmfKXpTHcTVHW*^v=2X(~JbdF*3r=F& zp-W#yq9+V1Thi4~IRHxBKsTWtIxEhm&@ndMU|m2frlH~UaRVg6z?C&|mtq$_aG_-{ z=j7*40_&Lhk@>IY(=Z6^&im<2tY3vw^6?YzPO}w1u?sF1T~#~%EI;xX7F6F^c3 z?#Tm1Gy5S^u497mJL$+lS4edAoPbn&01_fA6rdj%+&-^OFZpLqeS|JErbqDHi8TuA zT|GjzJp+$DY@2A_xZy4N-Ry_-c@PGCPXG()>7|=0%uP>zt_;fP+ir{;5;Tm8GF8Q6 zgpQ=PY1sEpYH=h9aTisj0Kpj(ro2-HJ5l*l_H@D7rzbmuPf{5DJ;@w_(T^1iWwTt?0zR+n;P!NwxI8cNSrQ**#d*nugl2 ztRHm>>JdENuLOxuO{Lh8JOdAv9LT1EVfp_MH-n;GfQ;O_4k2P@LAu%cC6~pvz_Xnx zB<5b<&yQwXPAXdaMr{meyyMU?ETHsaD~8G_8PIYs&wdus0=hYjb^lbM6K|oK=C&Rp zG}?r&5Eq+q&=ms9rr|jz8Y-Ve7n*_SCcu?BWvQ$o^v6T_VIev1`a0zzU>M~k>Jo8` zhg#^JdZrPEDiY><;WPf2bIt}5;SW1m!sL2RK-YViJ|NctF@iS=*oz*mndjYJZytb4 zN6@8>^D4>Sm$c}|%fWTFqmBhJs4;K=*V#;*5?@=|7exfaNO}9K;$j9iDlbe1pFJ+{ zRGISN=~j#pZsTZ(QP7R;080TxYuDXy<)1U~xZ0NTbY-(08zPoasuf90kM%P%f}%=V zGp5W1=bU*D9*5(jV8HduoRg)BpzG(iJ9e4IWUGMAgeic!eSLPr>ieIP0u>ci)5!jr z24tCR3$u;lTo%8-K)Oz+k@Zee$m_g+70+)`HD{0ZfXxlyTe0He9aFlOu=G{aqgwfI zZDTJVVSrrpD$a|fyNtoXhnp1|vVx6PTjbT|APS!5$O@qqW$f9#(ao4RDHKYxdv$_y z)jGR+B(LszTR1(dV}{m47-G!v6eR zCp*ekH*>H_GqL0N-&0gocl|@LHOkDxt9Z;M>aMDqbW2Yp~H)BDnIjID>PYS!$r+xX4!A%Fqzc9zd;)?d`A^%uYoqILz+K)r-krhM;=0&Tb$OeI7P)BM~LWiwpn0U-d`4Tf{vjBevE_Q8mdPw4eVU(7%ijVc&&+w1c0^1Ly1Xhf$`Wdv*Y0I)*Ae2q18+2dES*7)LeqF zSgABB^>E)51!n1OPbZ*X&KMnVO$uHs2poBVUbg9_upE11?wOc@`}*7gw*`smT6Z_+ zonzKn<0%Q(6q`L-AD?|Mynw;NpdlGY={UoN<@EHv;y^50@hX6Bg^7pZV1) z-g{hzIx!yCI%-6FCf_0v7t!;^yjde~La{|IrF7pS9-xf{1UM~k9E%m9cGXZm+J`#< zipwaR5u{$oUS_9v537r|>kJ&}xHi^jTT+sMyn3J`C3 z?U(=>3m<;7muy9a;7tbOxtuf=g5K+HsX|Tk;TcaT&@C?9H+l@WyPcD~RG?U12yAk- zC8?3bjW5j@p@0dN#uBytRY0Pr%#vJ$N6i zOGd79@U!6%BHc_@pJJGZ=JrHdy!LS~?*Y#FUYnMDrMetw9k|Imz}LFvqIKz@odQXK zF)GfNlmIln7-D1l@o<(x=JjqYo-^!%tH`8j>3=2iB*FVjH%9~V3_9~Y)T>4`Mpe}j zjuaYW(QRqKy)#vn&{n|9I4^0izRc0<*b_RQ8tHflbv zjsd_Bg+g0NzEFvZ8*A4OtpWF6xi_|~J4!zp(WD*mnph)3w4gXz7RAj7-jqJ)Ndmt!09|-u2vTUxGiBc0lUy*xk;c^Dir2O@-bQbs$NaUS@;bZ4U$dsFsHHq77SwjXhs*wiWtu~bk<|*! zkvXf;u}wmNHU(1Q-#59Ta*BkSeThrQu6bP{e(?{B5?_e7tg%+;S-QH>p+Yy743Xu= zxBPW6J3}E7B|_1nY$msas^+B3g{I#+e463PVVWAqU7sBwV~%2UC9BUy4J5Q%SKu=s zsh9o}c!@&XKpFRrOVPm@K`=iQ&!4Eo^uQ4jhQCQQ?e}v^+KcNcq4vd>+RL=+?s2

zc4$8e=5tG% z$qolhD>M_s*IB6<#E92hA*#zOsS*y^8n;2~f%$U~=JUj$9SbY6LDe zmE3KWpB$3UoTExeYgly{%$IYnNqV5HI-ixiUd4@VgrW}L?|N2yFUYUltKR#e=XC}M z{qtB}G*lm?c(|8YhW_`Qd(WlUkp~7O1EjLWHrK3R-XBlE!j;t8fm1wt>g3xq*^k~T1#1l1}t`*m_$Yb~ue z6s{PUloyj`SItTmOP~RZJPS;^h3G3ERk*D9p*E`t-AkAo?UMM-=6eJyMQ$lX{7a3V zTS9o!xiR*bQv+pMIdVjHyL}?HN@QO4Z0@6&&ZRz;3`_Tw$L0xeB`>^gCg1a_g<3;R&uhu8(7^7NVCiG} zhIdipG`)E*l##^UiB2QLv6h~RGF#rWTlqs^B@aMPWnkt7aP>LtA`Eb#oF2uF+f>Gf z0_E{$iYiQ{t=)d9wWm!0VdOYTm;?mw{tu=LFV73BD1F!MVZ-Ki9ve?%*kW>I)wp3< za2iqBdGZ|TGfDe+1T)I{u9&lU31AS=O5rbk9)Xf6ftehswJQqWaV@jnTtDAOzRGuS z#n6)9lhGUf(_eg|A}2l-r=H(0OKv#6$^t<%KEk_)wv&X_pNBw?3=6nl;Id}_j8T{b zi&07;$pd94;52=0RBVOu=iYbbZUjW1`ga^d{o=!-h3yR+*>Rk4nC)G=r9YdBM)BS@ z{=G#YkccoLpGSZlAnvDzPDbL9XO=JKG zy1No>%}~t##q63pT?QGm==-kJ9*o{ljxf-0-JL{n(I0|`?VVd>^@L`DKpvTcbM*(U zdnt#81#J>MHYMK0vRO~9BZm} zj8{W};|C$LK;dZYTSilQB-Ki#NV{_%gb$Va#qWlM9pB*#`HSX88kbj*rJ}-*H`c!M z#r-tbd@@Yghtx*DfB9XKBg@J~b|_@}?)z1Y#zaO(l9!arcS)*M*fpk8?MoQQcwuS{ zH0yk5MqCyLg(CZ&tzIMdJ1y;3cjWhX-DLt_Y$CgR+(itXz|V!Y$?)~gtLPqxZ6E@D zmRcPMEY6WDH>t4Nd8MeEx|zMETqXg4EM#ocJ@|GEz6q)GgL<1-`G7T@sSWb_%cH8Q zc^7Gd&cjlUrQWb+^_drF{W5@xV*86EC^R0;`Ac=Rb&NnS1+M~s*%cy&TtPC*)Ru#= zbE~3k2m5bFv${c4eyO!isfbDeOeg8&gdmzZA_!m~$_LAWA>nVBTI{rRKBWxnW~oN5 zT&}IpYCJ!tW)1zfLzZ?%sw;hT$&`+2D6`vwSfEw-&l=YkUj)yq_3@UxA<_D@EIiwh z`V2^Agx(hESzmX@TEy!Ka!zL54!CP~E9#RxD&n@s=l$mqMRf&gV;SPgHDZc|YJ2$j zQr0CO!!vqS7>P80fREh#&)ae^#Y11Ni=Yf)4f>Nz1~VVhN!}P6y^{WjjSVS&t}AVJ z);z{E5Z`$B@VbNTxr`a*l7Ql6&{_D=p~|E&tv}_QqJ^MN7zq~I+Q;jMo`mRnInJ(+2{SIMgmCA*yVybZQV;X-v zI;y$*6Dxe=eyv>o@v076F5kfwM!J2MaV+mfxV#V&EjH8mfGUSrv=NfQ-5PaJ5Kzx} zkn|{VjPH!@P}6{#OBsU3h~QT)`MKhU6{mssc&tfs0FO*X{ken*3-`Ugys zm92mY7<3v@Y#3;47XJM)&d^%1W-x}lNasQzE>GmmJnrbo{Azc{lk?2(yqX!*VUg>kySs zhM|qjXWgK8#764Xvb_Rp-{rU?87VSVTPbx_Xz}cJyN(spTWDKjU#&0r1S*SPJq?P& zv|&@+Mf{U_RNaA7ghSJ0T_y?fC~oi=EfP>-w~xl&i>$fe;r)F`YEi6#)zlce$hc97iNCZU~nEw-$q4 zJvYilLDpu~ju>N8XOE_5LZy$mr z)h0(w*5a$fF<5^Z2v(~^J5Jjg_yUlRhOob4UJrUv>gpC|)Sza-mcvFWIBz4TSIv9ek_22+ ztmaf^E`y^c3C;ZOLF%HfbGwWCf^saLOVZ2UX{;qgcvkHSa~7~FCW<4?48DSy#2M=% z4&?*`f#g(%aSrMg9bB7^+Uo<=Sw4X!GHpzP1R8Pgsty#Fdy~no&%`n6%Nhk7h&!QXohiJ&qS?!bxct^UHx>R&J1AE@s zmng4HcvDJ8pHO=GKuJQ}m6J~lu@HPhcV)^4l-E|;0k!TGMA7J)S^WUrrpgSOe(^W zNZ}DD)w(r_YNTkYt7O?1%e;dnPlZelKBsLGGeQsx!!k!^O{wR|ts?grl8Ae=X|svm zY9VXAo$D0X%GJxRokDiX(PiX#^+yau!w!fAvgo!MRf&l|9}|x8Yi?oLsjw?)0hYNB6k68;eN1M=sLANg33IDo^A-YFj ztR<)mhpDdgsjB5C;I1P}9a?(V_VncJwgd`wUy}SjbgCJw$#w&hN@E`QiYd_a)@05R z5Ry#UL;|b~{`;17WxKYyqR718ONzIvoubuK$+PKibXd?DBr@sWQjec&__ICS5J-KB zfYae%#aSxEj@i&}CUwow9B}baB4P<`RzoZuLtLu=X-3jsR$xtfkEEV2Il}(cmfCUj zH8;UP8yYlvq#g8@5az;Ej6*2^_i{3`zKVLxL3NBc(18s|t|G+PAA9==OoTeSW(Y~oP{q3J{Y@O z4p&7BBRnPR#0qVkuqf9LB+!WnOSvwgGtTB+o!42C@}=w4=ToAdQ41f;6h(lX9Fw{O`b)@C?^)jltkibAb-` zXb2Xn1(@CGuxN(&gZRPha}v+yf17YK{(lMVIavSq5R0wetSCxH-8KiGcmWm!<9kem zTOS2LXVsSm#-Tv~FZUB)VSYH0e2V<#GKY@tPhk=5poFzPzU}0ShVuXR?f;8(=|A)N|H-8IPe=vhf2fT9Ps`_d z|2=dHwodv^#`yGficSvBhE8(&4#qZ4j`*zf4F4^p;(rYC|Cq@$v$C-MFGvM$ob=*; z&5Gi{DtC4$gx7(6%3?%WWU`6SF)w7_VT+TUu`UCytUYXUjs_`&OfwB0SyL@7c>_pi zjfZ4@R)yt+En+H((rhyhX%61v4jVFX%#WoIdulf&Z?Ae958jG2Fn6Ck*uT|xFT|8a zBk#~p7xcR?2Ewz5nD7L=s}LmnvncQ?#sNw*eix2YjXsD%ery!X>9gKc@f=32X-SJ> zMb&!M<8}CqBO>7{p6v20RT*0!TVf!;Nwa%sJs(L58t6KU_eGO8CjL=sWBzFph##V6 zE=3oiy*PW-O|#m)adsj3O!46@5Q2Y#88R(~dQat)OaRTNb|vp9?*SqI$u18kJCeEf zo9$YsUB#z$GTP;98Y==OV!Vrk^}=noJiFP(KLCH{;R_8L1yAS;9C0n&C?P!DV;MNq z?!HV;or+(@7Y0hO$Lrbp0CmLYN^fp2oq2V4a-u}>rb;M!5{9fg`m&7O7JQ81DLZR3 zc12AfQKvOc1})@V1AGp)0Vh-@J_!fcikkXN1{ zaNz^s{o7;%;@=~ML|f>o^5W)d!U#T>td-k2L=!`Ecq8$)KPg?gYu8$hHSvb*EMv`M zrAZr9zRAA6Pq34yMCTX4yu#ReWmtfNJ3&SiF&((#4POmqoNG44#qnGeui%|2_~>Yr zjz)m|qlop#OCQ`Mdwd(|Hmnr+2c<~oVn*8|FzxP za(3#F0Dv%SeE)t>s6%io85m!468%sygDyB*K<~EY1Mi6AWtZ*RS2fd@JFZ*T zJcEDfKef^lYN+@{?Bquijf}Gw(lx1zb**uwv|3rwkLbIa9Wp#OoR075J4!NltCC~? z-p;%5z!A>zyk{8A*w1b-z(Ks(VqY{VjcSwijw-;M-CGNQtf5`j*JL}P=T3B<6#-IX z2W=&rF)PetF1lh5lvG+Ofoqd}^>pi^F3K^I#rVdOGtulvxN45tUvMZ?9EL-`Vjx-2 z=GZCT-%{T-g*V&b{yokxe%YC^{KkNDxwCb}LvWf=2`Ys8#K$4gK?_ap1yv>`Q3MxM zp)O)ritgP%(n^qUBeP4ZG%MBv58(KF=}mtZ_mhzBa7p zgAmIIB&fb=ps~QWT0LW8?TK4cPlrQL(n%(VYoeGInwZ=3G%63y>lhJkJl6jxCo5 zWM9YBR4=8yp{xk=jdUN=4zDyrmGuO@JEc2~u3q-)DVcu4P7iTeioU5O{{v}|*G#FU z2OGmMJ5*=8OFD4KPyUkzif8;*r^KSDzar1u>I6Dw|FSSfJq?oFB|O`=QOD8X)+7R{ zKdKmcYv7d=@{8o=j$c`F*bv%K5tIMq^~15@A#B*sXM^qKld@j;v2ZsgFwP!^Dp0l6 zJH>n-e~lA}8X?8ptTMsNt}JF?y^r;0woTSytyfrT_@JL`9r4065fm<>^SpixWzAI7 z0MK1l>1c8mTgbIV*m-a3&xPs7RLO)CWAmXL_2v)TR56)?Hc#TQ@yGtO;%iMH6bXkm zRLgA^@LjyF&F*Di-*#EtJU?Z@OXvP_Sw62*&jV>BXTj$VSKa$7L*43}_eoLbEZ-=C z_qOxeOk#~0;!L(0S3meI=ClRFJ*__`2QrDN&K%E9G~;DKjF)S)Vh^V`D<|U=xI5>k zAPY9TUuV80cCKRwinO`u>T(4=Dn-N-?%{jf_YNkKDELh296M{+vN|zh&vpU81?7}l zCITJ4njw=XmuV{$GKHISI#h~4+Qam);efi50o{VSk{jWAnmjnBZGH2-?eur+3Pe8O zW-bt|3SKoW;(-9xWEzhe=7&HtjbgNRN%y8z>BK?AL;eUore(ajpM+Id2+$FR&|A?} zWkIfyrT-14EFERm($kv$Y_lg`nd*r>wa|ijGgWPaOrpzI^p^o!L50!L1_}$bpeJ56 z;zB`;V7)c=DB#KpVo7*cxjE$92(N61P>H0jYC>9j8=?F}VdZK0ZRI`Is(=61J+6@7Z!#Me9pzm)|``I%@k#;$bH;zm;30U^3Kg`Dx6FBNz z@NzN{nYXOq-l6Agxw)Y{D@_~=3lzKmT&1vQ@WNcJ0I9jpje(Ib%Sad?MpXC9z`9yv zZHVmdc%vXB@^v{r$2ZKoI2F=aV~`eCvumMc+HLr(idUzA0qARCLhn_r3xpsye#s>{ zSEt9%$e-kzn<>9wgvV1Z7{i!SkE1L zg_2NuH@QVYwU#_Da*1BHrdWORgEEP~r>3RXkzFFqB!#L=1=`Z(i}GHE1xfW=UW7Dx z78H8V=;(pv82v2?{cIvk@3jDHN_8ZP`~iQ@rUWmnZG<{U5y4>K;*7{8$U-vFGpWH0=!5Lo&l|t6<28tR>wt1l6NY@#PFyq_!lgnl>DP1X zYMGYxzr8BJ*1*eSX+SZL20I^*mzy%WDPZQJJC1zio5iQMd9?3@2xesBd9T^St`IA9 zgoBqBZZiTS(I_r-PBz8`EYgL$9nhI)Q!XoR5l z(6_8BJ14ZU4@_wyWW{ySdj3uZDLVZVdE;O@QD*K@SY0t?I z#G}li_Y??L8biU`9rw9b&;*HN;D`umbogpSAm{$t8i;bKYQ zAr_wpum{f`hYu)bP-v6Gu#)m;mmz3(XS(|M0;xWOAq}%7P#$KeJrCWv^e_NrPlAT% zcP$c0^{(kq9PM@aYND{uKkk~)Q-{hvX0o---p7Qsq>i!)oM;s$X&j;}C_u#^=&#Oq z6)_WSYyjj?z^CYG=?@)t^aQb_;Jsgwqnj!GyU8Fla&k{NOeG(tm7e~}%2O`VZJP@q zQot(*(W|GPe@;ZaX8l%k%)FDXk!K8ycB|Ja*kD2|w7IR}nBv4?b--a-`1g%|eVqZt z+g(8*Odw5ed)0UmEBUx?43f-5gk#8I4JPUjxsXFVn8qJ@0f#m@Oc#SKI7{aOCpREG{r*PycU>V$HCI$t76o}pAN&_5oV0iV` z&st;`o_&>B#SIRcb^BSQ8gwdH4-pB6y-WMf>x~6Zzct^_jQmmh+bh&2TPX|wU?n}X z%!tWQ6c?Qr!w1+RG)b%987i)Ns z{G*m1Orc>yhPlXQjlgsQWU3R5`#*xR?BLUG^LkHx4o8vSIR^}M!^N|Y)YY!9PxxVBXovBPFLh!tH;$rHKfTE>?5OIXjZ4cM3)9c5VVb{;l)91 zBXsYo8|b`*6kr*3#$PN#&6vX}1ind9xFc6#;0qpX5?^1;A27x4W(FuZ|4^>guWp9Q zRpT9l`4-~+Y9#kH9|E3~a6LA35B6e7idyW9>Eety zqhxy47dyu6^ETe$W0}N>ao2w9p$Yo;XR;4oy0$N8hofT02wc;HX+6(UHm*4RC32%; zfoB+#3^jZScx_*-=or+DQ*V-&yk9^@)s$n3tXY;T6&j&(TqK2B+aUGF``H#uGG@w{K}FJF#h&oT$!gT13ZaX_ss zLJb-gEaVERt!4lyAKstvIaCz<1Fhp%>b1U2YWyS`D@?5r{-V5It%66@|l67}C!kT&~ZuBB)9Ugn{L)Wt5REywk&x?vUoK znUs9M^m7-g1zElPIwCD8E7Pom!!s!UHsvr})fv~(s6$B69$()8x@2%Z%F50dn!%Ab z!&8_QZlj#`jQs4MNK4$pz#RaM@^2#3@Kl+_!1hENP5sMe5#Vss2j8gYPXav}M}PK6 zc?BN%@Gv>b{`wr?=SlD$JjR_dZ(a@^g1$*c&Xc~xzv&&M{qNibTZ6jPs2k9LNKwV1M)?~<=R3ZQU%?NMlvBT)_8VEPDlh8m#Q`?D4drta+1fxso9`=%!oYgd|z+lV_k_bfI754 zzTYf*N;G!)KZjlnRg>azkAO;p&rlYl%kH*^eGD!3cd^KMcT;gncp=aoJ|2?ful0Nw z)4TOW!4X4Lh#Q@*%b1wZzQ$IIXn!2|JWa0t(=OZp*@*qWlWzY{YIB*9{9pQFW|cxJ z{Ag;N=&iv>%z97qrZ{Fj9s!dRc|i*nnj?w1qRhYyl{uX$n*@~go?P&|{P!?)!4$>7 zmwS^2=)z!<*InL^M)&H8ucFE-lGoP10kPJ*l?_`8NLAIpf(tAwS5G2D)ar;Jm4*Ll zIsXCN`@foo{~bR2A3{Cwq>AaX8jL7^Sf%NlSeQkPN4(o)JY&9S@xij zpg%fr)O&*5uCLDH!_5bU^XvX>d^7L30+p7UG(8TxPF-WiV0WL6;2eNtF~+n(3!!$U z??rdaW}n{apsZwuO@5+QM#QPQw%>nSm++z-Xls7+2U8GnAcV6FkOB$Rb2SBW@aLz? zh8PBM%)3>3rok{3tz?@NW>{~)Gvg6?(PD5k2jMaaFtoG-K!k|PP=SCrlw4@ehZ@z~ zkWBeHz!3OiB-h*b{Vm&f5+6%I#2#V_V60|A8;PFsR{*e$C~k2?@Gqkby2SGPtJ`Pr zcPj~sqB~gC=i4EkD}SedGEX|1KXuD4a&ru@>bXW;gP{fwGqGSJR!by!RrkA>hZmoD z(whLyG)zyRhc$*Uanm);?Y$ubuH9B`8uaDOVdZ7LTT1s?qA!&r3OLg2%Txw6944D( zR8G9APkgUOfkj!oBrMx&LEu7(f*vOoSUPfFe|<5%F>Y)7U0kH~^_O{_2b?rH8QNEf z8C+=I&#)%aXR9AM)l&P2Y^4EHP0TH(Hiqr%o+!MB+&R}BgzgA07GU7jzWmTd;R$y4 zAQV3`3$c4AP5S=HmiUPxG*2)pi>NU=BD12!tGS}{9P?XzokM$7G;#-7bx|GJ%z-~) zq}a#Aa^Hg4$_mfFx4b#n9#^x?o8HkCT;dDqC7zOH&?v8E6otY>F=h)ogw4{eN#5&> zKNZ)AV>*p{%Jo=UW zjY=tg_`He{O2l|u2;qHS9an|Xm*60|QI-|G3sPpu+D}EAzCyBBAA9=!Qq_H~LxzO_ z`+Kp328}Wg*1}2nUp%O<9Zq6|(s{k6r@J#bM3KLreB?IrBJO>ZH?CO3$%>0Zx+k6{L^ONqD);aQV6R^aV#@o=!YeT|3rZKFOsS4 z2Ke-q1p3E;NJE+yORS2&WlOB;U=^eT-h#wAgiVUwZ$2fukLJorj)_s$;&YEA_Z|R+b z`FHrpyAq7l?=7&0?0{~KKsMnu8wA#4k0?F1nSD_s_wIwP$RgiDdQ%PDptgofx>BEm82v3>s z*QIVJJL;o;zlWXMazhT9-P$jOpPBn>9zQG+LzkY)`5OKpE6(z{*YQU<@U4{E$xs1M{mHiVDy%R>3n&O#nB#rsIg~M&UOR>`*iX7c93gJE}Gr zyY`}NyciIwYBX2v`d?Wg4QcVu27iTJAdSBFeL*u{r9mGL`>}!Vh-yf7uB;~3+G>0O zO0>|-sQgqa(wVTa*AYl`=Gzh2Lt;Xj8z5iu^>AX8!RVXTDr-r0RDRMK$?wDdFjIu{ zfw@)TJ`b@Jq7ow-@xS{cFwp)_thDqZR z0vQxq(c~Kqdf%g(Hha`D#d$$x53^s$LCSF_ITkB%^ypxKh)G?g(<}XmE)XnM?ZQi% zsKTJAsr1*yK#bue3Z$lP-u9!>ypsp3pUU*CD80;?8fVx= z+&Q|o$-VHSOKLx{d{a}&Gf#-pe|oQo^JZ8i%%fqY9bMQ>j`9zu<3=@$u>y#a`WB@^ zA%*AMz%Nt3$iu9i1phQ^T;Em@a*IxNo0f13EF={@wCW&Q+Lw2lBz%_5#;ViDcDKQ% zN6iroB^-Mf|74N%I4Y|}KAWv46T-UT)7t;amCWZxcnSI09>}%1Jvsz~S2m1^MAq%n zlSwW+A;@VlFA&F{)8ba64RvcDtBAvvd2Lcry0sIRXI}3f3JEmNpr#$RZ_t=q^eYjs z2QXzNi~Qw;8Ai8(@aqfuw6lO|wR37JdX% zwX-kZuLjW>0(-RZki6e~jTuIXHP`CccF2LWQ-z`6l@)H46MB~2B8=<+1md9@s5tQ& zaXphk`}`E0WaXxc5L`(W2e$73Z8Zxf#pN4j>%=gBVmXDk;=H!`KDfWh5uR3~g` zRKB0wfMsK9T~UgF&2mLfwiv9hEK|v4$No08f@%EB8wSnP4(#Z3R6p-2}zY=8Rpxr{Z%osHqS%jb5%ZSOb{0uHU(xo|;9W=>*yu+r*N zFclj8Vc9i3=Oi>p_dv0S+4lz1+hvDe!0Ybu%g)!-aT^tQO|g1)hl z7&}~O0yCRXk(A?4j@T|trW6|h$`SI8I<<~~@PKqa=Jpkk!UZ4cyJBpn>i3jG#{DG| zjL)FZG*!HzZb_g*3xh?+$rcTUD{GHi3DSSO>DgmV4dFtJ&*6ws_aD}T#z$<87;r~^n!F!BC zB54LDO@o8NueW%0Rg3U$cDtZxBgQLp;U2In8s*1SLIh`!0DCKF`&uf`eIwain7H z^WaPpM0`?VPgN`R1hGp;dX~!$nLBI|C<@(tc5XLqFAPVDd{F`@9Vl^g^pB~XM$opm z`9>G<#aLVJ!vo6F8B!{wX>bBDWqf$2kBUI$8udYgL$sO%)##>s_aNno|?)bZn1xh1`X z?r!Pp4O1nrUwnAv9){GX#3Gc@=VCa>ovxhyOwIU)A_#nWuI&Lymu*MroB7Y8JE^ur zFOE!}-u%r?94&k!z*u3AmLa7n)FEy!z{~iAX3f6l_S!UCD|7(lk|wkcb@-?B>j~DgUMhDD zmt1_0znNX7S5%WcAe&$Ru=tcDc3{+-aLEnsjD3BM*#OJxjv>dGl0FN1(f~jpZK3ZX z7X}Xgy=ekx+H(q5E(9q4s)ikx8ZaVdU8^y+Bb@-L|gh^ zOG|&ZUrfV|^7fq;qVB+No9a~TNqgxW^Em*e2VOa!yD)Y-!QQQRejDzq$%&WD=*uHC z&~XKe#Su^Kkj)yMfaCNhK0*A!8GXp+%EG#Czq!I#ubPob(BnMgD`8dwLKuIfG^ORE zfM-l1FU51i5P?G4Bj^*;G8ywOZ5J^%V&c-uVQPAd*}D}T{zSp!=_QK%GmI2)i&LBcZ(#F&~@AqDs*TOy!Sc^x!a- zV}2{UWlc&Y)sh%qY4M!K9BZdqg_1tX#6mH&7@{@wrT(lCx%{+TXo%a*dt%Tz< zj;`2oEDmXh7}O`xW=~I;F}oNUGWRMJ8k~XBb4cmgy6t>^#+wZ#qw)W=4X(JE;PIfr z$YM96a@kF@D=R#(zNF2J!i&5DgGr>aEH4Kwa!wj<{v2Bh+O-W!uBo1@40P>@dlg)q zdL^2=-hBXs6=y0o`v81|mf8)_y2W)ydENKh&ofJhXGtjwV#RL)?}a6Cgn$Tcuv&G1 zppinadN%K)A69rjdSC^QOyb8z5BJ%C83oH6bO4{p)B!`P2Ij!sdzaWk+|b?Bh$)CV zM!bx`W0}Xsr5Yq!>y8FaF`6~`4ppQ!Kqb*3-qYg?jD;WDY{z2Ch0sp2owaLrvrnon z5D@)7{P|Wr(z!f@YQ$_Gz53b)prJ~lMywmyOWA%g1n-Cz%dWAwz^wZdTdRN|@6>wV zKJ%1s^y+%SX#rTFV%-z~$yQIo(Z6 zlMzIjqKhwf?W?<9arB85hoQPxESJv3S2psi)zcIZp)JqcIlPEB2@0xCsFM-po*+v^ z6X>`xJE_!LH%g?2N;GqdD%_6%5!}PYexs-XKAZk*Q@5bQ4S`&L;eH!;ko~YCsts0_l1~HI<6;Rp%5q=2$^V(ma z;=sHHy-n;3RWcA3Xx@{Tkc~K04s3X`E)tqE0C`DhBiZ;Vm6Aw$zCYbH!=m zKFg!-0Q#4loD1w!WDbJIO0Q0Zl5P?y8RR_LD8c+L zbH%5=d#Yrb&mK>LwIM!c!=qhNR>Vm)bd<#}MY%;1Jtl#Te&d2@1=O{RI*}Td-G`G7 z+t)cL`)k27JaljVGfmX`^zNSxou~7A+SCj@<(1;_9KL;>tu}Gpz)Dq)24`%f^vTKc&nM*>MA_9B}(ZtK!D(U@id2m1NkCWV9>mOhT=@( zmo7#LhM-g}b%XRWi>3nj@4t$xj#>jewJ~OsH^PP9A+Bs-i>Ww4fo%d_3D;M~1CZW( zS1!$hmhl*QCJH3xw4A@pEC=6qyM6QL^z12B2Lqs-5Uow$cyW}LXKKG{&HD)p4_*El z0;}5@IBFmAx$u#2{Gu7ZP12RoiXr%S$pn$@M2nvQRJMRoHJs#AM7N{JJIk%(W%_ZU zAwI|Ozi^U77Zk0a25-B=3t;VoiwpA!wLxBu^}2QNF&#Ryv}4lz_Ue6$jEGJ?-7wPi zEUNcFIOjWCL?Uq47xuKfU@vM%rElP@nLT^lQRl$03alZ~0R)I}yC31qRAIM^;tm{1 zE{w}X-9)O=H&=mElu^-G9?_<@AY06w{|>@#3XUveZqtDcp+PK*2JAagx4=?BP3E)<5A`eYLs z+vIaO4Z6??d1+ais5eq*g7^@F7Y$PGu2CPV$49Uu9*gVy1c{;HwWL| zF{d!FkJ1ZorEn|iJAd@FZx8g)7d^ zBihSz7l3S1*K$d*;?eUIv*fS%kmj`l>xLi7m~17X1SecR%Q$R0@i62*1b+jRlkcX_B+M2&FPeP5h> z9=y?@yVI}*V6eTkW6~kqBS+*5@Z0<^`{&jl%Sj$sgK4K&wT_*4hhGP6zgcuz{fihxMBOv)!oKVA8 zDLfNeMCjG!trcd6R2LB)0jjPL3nqPX+Z=!Tqgff628R#cMN=#~t}zT9i!W@y0DUG# zwa>6`r;1{t{YwwYsh}_@LU#fCf#i=jAt}|*VgL4!erIFJA^A<>um40u9=#Cr8iULs zv{G&eQ5AN_ZSWoRc@!N@Pi9_K`XG{W7Q=j-e~j-H}Pw6d3uP_310s<%Gjf$G}z zPjTg1=~BiRcaezr?XX7ZA9V_jyq1|-;v)XTLijGP7mE6W-%p~Ac0otJ0$tt=nn$SF zHOo=IKw#DYZ=s*NsYKn|crv4N{N-Au*LC;6*YJ0@=ZxrRzT%tL#+AzxWJSD*sGgrl zg5C%y&y69$0(`w_ZyKB!Q_#MA=;7dg2sARY&*NZ$1L&?RQF|(Fv^4MBP4X@Gj2mU7 zRWt7RQhdG{01TewhKhF6na&-;StterHMI1=baIFQhMrutMD!UIvQtN+{F%Hr$4=nTFq3HgKe_3zlOCov|qF3GB z+G+}1q?^Q7UczB^#G zyDH#R@#v*TD+D{SR|`L5ISy&;PH;--%|V~iuY}d!oQA~03%kX3R?B}OM!6|>EAX(a z@@Cy`YA(c4j~4@|E5S99U+I|jm7#=a<6IKGF3N*J1bRnOO<@Vq(66Ti#OSm}NL}%m zD;!Fdle33-_6xw5;Z+U>CjqBCeK)C4e_J~SEzLoR=B4D=jL+^!rY#Mjl!lR*6tCSi zq>&0gf8@QM%Kg>dBtOXyXGvq`Ee}kcR<|v`V3zP;>PD{&tP|k3nic4 zkvf9}OocgbNv!5ql4_rs)RtI({#K)P5PN}s2g#0pYJ&-bRLEOBlv^fgiY!9?V-D8b zu62M34Yd;`+pDVXnW$DmVJHk-3RLhQVrQ4kjo5+UuqeWgGSf4TbF8QJg3u6Gvw#cs z@uA*)*yb5_&d4SPcs@9dh|g|2JSEho;0bMercewn!{8>&1$KR49a+F#pC$#FEM+3X z{|cWza@?U^-6OcNwJSds7l>9@i^!O^w5k?GS2yj0o~J03sSA9g?2w7KVd{JClODA~ z4)BKdO?3IR-m*h$8ymEeSRGZtif=^eIsWptR=C6~KB-i;oQb8lgH!b1)f#Lu0=(`~ zxm0ZbleCllnY|qtN#TeYbi2Nj9sq=OaBB?q20bj2B^KDCn;qG5GYWYZ$RHlgYezkZ zngY@4sGa{Pe}K=-Y7=sx^wCv~(bh%W3l!4+I;CyT5f4)+Gk|a5r=SnY^s_c$G_yNu z9h=pxaVaXXPBj`~TEg+hj;3griFh_~IQE)l4R@jQ_B8MRzAvfe+rT{Cg{F(> z-9%?~`O6cD2rC6xtStEO2LR&+X3e^@)CioQIZYH@@<}<)hpE#+KnM30TLLfwk02=-NKUh$2bZ!O*!0ehTb@&y2hQXc} z94nRj4+CSYiNE6q7dH!T@%$Uy?PZEf#?oS5((4pB%$xCyy3UdtFzw>Wp(Xu$#9;tV ze-?R@B`ePU>G>M+w-W+S=O;)i-lrU!=3A8si(tp$P!Fq>ARN^ss)bicE(<8C7LXgS zMwij7uYejMDfM&@&g+li_;epxT*oK>7`MN1ERfVrg zdwMMQ{tyB8S2I)0j?xdlpNE~CfJPfCQnHY*>1a+LoqxgU;1eb}i;4{vL?=WD zPrQeREDUH2KAgQKLmZ?|0`iyZeknhM#%GA`vrMD&HnuqIhPNBNo;mpdy0qGe7Q?^c zRC9kvmD(I212zBR=P2hry~2mR9$$rPryR{@$X}c!=X<<^3hNWNkr%GWV(q2eYinpn z`*fYG=d04uDMx-2!eb$#jQJ9iaEYuYzOd{jzc0<6-#_bOHjIhob+A2^Xn^=2Dh$TZ zvsHD~9DA_i5H3pWrNcZteYt%VOc9<)=|rvftleAqV=ZIs=!7!x`XFZrNJmn2ipdXD2Z&apBoYiUkx5-D~(;NC#r26n6Z zyH;_lKynQZG`=_qROOaEf1W(T753I>ysh@xLmvmoibrw>NZwLdna&n^>PKEe(WVd$ z>?p$nTM$`Qjk`{md!_WpE)?xR)|>M7q3X2Hk0;+Xo8B+*FkAz;n(JURGGr(Wu90QV z23WfUEn$w*WiwtWM02iPzq-W$ykwYr;)|=e^SK5g_wVefL2%>;nU;KhwxiGTmfp;t z)R%$5*tL*#%a1w7QZC@WSsFP~iJyZChC|pWmye=(h?M|QQ-YIFJ7RkW`^|wo&ag~Z+{w~kNEiGlHLpPDy z&0}5RIWJ=5md&Xenh0~EE-dXUQ(&VlIxib=J;sL@ut-*))gP@(%0gc;axW^rm=Fwo zH|J!-2c!+;qqzgOAxN+DvVISNO!T1W590GPkc&#Q}hkLAJC<0#S zR|lVQ@&e-)6`{GE+@~G+o&Wx3plh_16_Du#_a6{mKaPot^YfR=jj?X+l$~(}VoJcfuV##Ns=bvcA&QK@`5^6-XV9zY>FL~Cs z+;bfcpy6dxF(39-N5Ns~@qP2d!W7CdX>8uz1&b}yj%0LMvkR+$i*?<>9?G&H;PF+j zc;tGg2~05B^}sMAO22tutj#A%Ox*@qLAmXsuO6CK|Fi|9C~9v^J$a5Z7HkJ`qfkVH zibCORt&S|oY3FsW%302g%4?s*yib6BoYxE(yPgmKspwMf&t+qE_o#Y`3ofJmhe?8{ zy4F>K_rmj>{krbBY)l}a{f5TC%aXDv1mO+tbN~{2LF~=2t$#( z&TecBy)2)zHJtNjQ~sMgAg({Llk!Q;{~jrQc|28||+~0gl5U11a+b~5%SEZwRFn|IZS~6gwS~RyqWs;GiNXkKUa5sZ2PL5Ks}0ex zOz84p?{#Rcc!uQ&GuSewfxnRCudqk4)~~r7Cn%Bqw55A7^K%JlO%O5W#!96XsF1A^ z9b!b!fS|lpX0>V_JuaMuS4)m^(6mk=C{3U}j4dn8yA+{E?YSEPea;jI!!wwYQ#RE! zpV9vYbSw5I36L<{1mY`=$V5}lhEC6iNRmDag62a+kB@pNp9+=Jl(LmsTo!g^6(y78 z+^p9bqZ#V13anYh@9q3&>adTxtcI)~mut1?C$)smRo0U9NN;>TzE&I7%GN!G5dEa| z045ZOljRF&Biz8tCa}e*2lpXRU1rG*Y%N1}HJjut#D-^^vGfjWtlG*RgkV z)T)&gRlfwn+gVv(Eb3lVCCH!P`sS79@`^T-y6zHB!bnXbM%cEzDT{R57j~|htGXbM z?W$+G=xk;lZKNJxR^-i@X~TEkrSICm9VR;LM;!LNKV>H1oMS`kFm_ zBN*&twa%H2IwD%m(2q=a!m`D(l6OCOCHp;B;hLQg`qCq#&J?$Bhs6TJIgY9YyKJtk z?5Xj0_NHjrY~T`IZKfYbTmx8^Bv+lL>Xm4oNK9+cgbgt&a~o&N1^1veO*noiOj-P= zUCK+m-F80fnjxUZr=Y&7e^T;=GmM+@_wWSn0xC@%AI658*x2q<(HoX1ifvpt97cxY zOwir@0van7D#+!+|5$Ug>}R%F_mUw))w`cbN!EJaN!aJlprZk zB+yyLr^E^}|EzOETH#?y@f#l&u47fcr*e01#;pX znux|tZe-@ShaP9)68SzIKeI1jx$2g2xCt2bC-{L#sa)f(ip(*=!$~j4hL~Lj)-B+? zJtP-xfBvOEW4tz(LnB1(DGI8Sz$Xg>i%4fk#mOR^XIKCWQ$hSO8Ag;75544RLqGy1 z#43V1bhJk6TS_QkNUxg8<#z4{Nyn6FhMVvV5&)FUYf_Q*pE|!R=*5PWRCtd4X6{(e z6b*9pu_d_qnjwbXt7JH6!Dr<3weTFQHzB8bf(`xXYzZK>T6`M{DN?Z(v*he`W5b@x z5W5C?MPV2Scgi4LvV7$zj#A$QRYny&e<_&+q# zYHcaQ_PeY%ZxK)7BJtDm$!uc~&qZPm+@w>z7PSI;4jk8DDsfPm-`ZPyl0Z7a=Z(%E zg)FI|Bcs(heYBt!?reI{7nyZxs&{#qngd}=0V9R<@D!TY@scRi@Z>_pRQ28{$7n5v z|LI!jf6I;k*Xip2ean@R{lAXF-|`JY%BO==PTCX%W>1(&N2I59Q9I9sS@A3V9t#-@ zmAFR1=D}L#ucgMsbs`s(AYQYs)75mt61mF%lv!q!Qpoc!v@ep*3A5a87AB-LJGWbM zk1+c&wd9N-Z3H(OqXo{HNvp2QvTv z+jmH(eF{(rUg`u`SX&&u|n$L9a5RKM&v;4D|8Y&3t6V5duFiL)ph(BK6G4UZD=*j8*tU{*HuKIE=vKWr zU)IPRNRNs(udfiu1F{WC?uQ7-b4uz>00uY=XtMouF(5P*iMrnX`;ONJI5|-h)*`gu zxx+xp<*b81Y5UgRpsPwMS3>L@kSc5Sa`=N*OnZoyg&wS z=Zf*CtrjVi#}5GHUKR(kIIM{WEy1U#evBP}?S)ZqJ|WpK3)Xamv93S7)TH>_*U^7)xs2p9Xz!McYx6O`^sM)Yh&Fdqj;ztR$VWt<` z#bh;_*PerOZR^rFt@8SKZQD@la4Dxv?^#1roraiHb0nCuE6-8%80;J}U*~)BHjJI3D6myK;|>BO&OvXl`Sf2lKqgG@RNiJp|7-Vq zP3Q@eE9>FO(nO$83udtQABBI)C>teY5snbr%pTz)8f!N`JH{$tLeIi3=NgS#5z!$< zfIek>6!;+kXub+rKQB=yjOh&%+;Xuzn8e;S5I{8`n4Tgr;>OBjPqW}WeS zsDAzV+GA}kx0_Fhfq4P&bww(ks@^tvF219--lmLAKilq9vQvMthHp%Ggd_K<57QjH z*B}WqCi!lS^R!>;?AQIH`R4+xf|_p`SSLf{!$Qb7*#Q zce^ZpiVd2qj8Dw@QTeP)8FSR#Oxy8hq|OGhtg8}DC9cDdYp(XUEcXlw)~4erA~}lj zpEv2cv#h0k8tT`!FX&8NSi1>9{FQ#4hEKEfSNMQvusGa#aeH-|S4YuWaWz*EnoZx< zT4_o0ln}X!n*4}jtsg{MeAlq;?*!CU)`XV`M?I$@n|!-KF>p!wd%igTft;1XZ>9?0 zeo=F%!P0B1Cfk9vU98OH^==$ZMc%X+unWWU4j=4rk(!z*qE76JL=^D%gH1r5uX4pSogpC7m^uSH(@0#-~n(<~bqhphsXO=&Ss+wF71A zzl$J|){(EE6>;Ki6mB{+KUnH-02|5F<$S;>whYn*I1cWh$P=wv{t4L6XK?PX;HIg! zmzKL4;q+{8R5!Wt4+M)pcNpq!AyjqP)gda#?W?N`WH4R`;q@W|IIYLf9!X@44`IlY ze>@1qzCb=4+X@i^tMi=Ie(*7r%wP}e4>>M64Nhb9z_jU{JD9+Zz7=C7x}I!3jHVU< z(exX*Bp1~7vDMCCHro=bNAqs}jN@AUrSOE^^uEmwlUn(uw>B<)75xZcvPj@gEL?0X z&nhj{W7(;z;eaiJ&?8yN{y2H774U^|P{I z(JIZP^@llHj)-lmFhJpEG;}%%O8aRmF?`@d$PyDGWiwTJ&Bm6CkZ1^eg81bhUwz5@ zqomiS3na460}_0#B)!hzK0SWjAkr|4)te3}>8H5GR4)CJ%-ifca+mA5@MK?Xe8@s` zCwR86s`{sMT{TY|imHgFU2Y-7f4;&|d)n-5j6+Y=P@s7L#}uOo^`Vq?eElZ7fChc# z@Fc;2#>qp*3*(qQ(CaenQt^}7{K&63LJ$EOZ z&TVi(Nk!S^zggW?^fG<6aa1ni5GArd1+^-p7|1h7RtS?ne*utT>ON(a zZ%AY5t+8l~s%(_=!Lf28ev{Mrc^*m01xdmhENV1ioOl0N0WpZ0k#P0?M(@ogNw>?7 zxZ@+wjf#M6U^RxxGEIvzd9`qE>*RK&j%!r4wobtqIF(=-kb*;jZi@MnB$Oe$!DHP~ z`DKTN^xl3lL`iC`b_xXYoHjbob7fD`7~WC_gXdfd!kRsLnl-iKCC>8=4(&)?sPqd# zPNdote9No{OFxn~--EjJ63a2<;ve()qqrQ8zohlMDO7g8@ zqL51_2`Dvs9CYUOg5O8)FS~wsniuseLs--LmUi}fSr8p(llZiyIu23)p8G>I9h#ip zWQJ<*NN#aQgFl7wj3k`Lqv6bax|4r$vMc;0q;t&@%Jl_jP#B|mTg}ZUf@_y2moA}4 zGUlh0Tg-T6ov=$7a}WDsIHG)mj95qe@Pn;*2yRd17%|J5M$oP{pheR(JOjueJ%-Dx zlGm*^CM19s-=tU-X?1utWoZ;91{p0r7ct?bU?So&Vna@3sK)3aD0Mj(F&t5#iL5cB ztOkAnI6liKyuzM*5Ix+Own+SMsm12*7T*IQiDgkE*8LB9esONPU1zsv7RVkGL&qCUfYA;1lrs&p@NS)YA zef-?F2VpaY93er9863U~v4kf+VIAPy24@1p5lt@9qNcuitmt|-kkAHn(kOSS>uUHIxTDTYhN6g14`EwE(d8CK!KZ&F@hN@rRmrvawiz(uK>U<(GS!ZhQ0$hDyBSlr zp(d-2irlE;mj{AVL8=|g|jYWMf zX%WD6D8wq#BSPQ7pxHipK*{bBXFu~U-_gZ5a zcNSLYh7-%bnl*Hdhu4SG`DbnY<|~)$vz{#rEB@vgd`7Oy$=-)QqC2pUS6{VcuilI= zX77Uc^5)qGmKEUAs(xw?rUsH*apa;uAlq>{i+w|TF}=9NYDRlYzaMnQ@iB{Estkp; zXB+~GgAvF~WUj^GhwCmLle%{sk!?xG=c?)N>Lk{^ZvgiYbB>o#6+%TfPT<52F13JQ zLXDiJ;3WCrH^5%S&^%Hfaa=bVE_+bejX{cPitFF9zsw8$(^J|EaF(A2;p1)-+j^laY1)to!l zQLEJj`tpFF= zzdNFTuDt$9c7H{O|LHSDxhOX(R=+jn?i4>4;Z{?46XpEI3;`5=vqn&x8GBsBL+J|c zX{|MUdR8Aqt^YPmSVK}s^x#OB_ZoSWaaP7)^|r-#3QsBD%lo1ouub9_7G_i%@4VlZ6iT)w=fvQet zX#V+o0&_TpJ-{g$?!d>{_+iLv)f2EyR+8%sKp26X62W;|pekmOhcfwZfVvU~4|C&_ zT1-?;iOA3!jjlYvWtmjI^&tQAvN0}hlhO!|l|2KAGiH#US?FgX3I4j#{x2zkO%UDh z9I#U+vUpwGcTv7@;y|6M-uc&mXgD%jrg9q&q08MzO=&L|+lS0P1b3vbY9nKLY!Ta_ z+61ovFBva3qWXv56MFXz9l(unZt@5$y_VKA2tTI56)B5~3V>aHKe(x#J0`3Tl><;` z1!U-?y~o2(QL!BrDVE{7wjW^LpfOL7a095Ke_VPrRp7!ZYrp;dQInK5(XL)XR_2y= zH$^%gmF7y(gW^UcFGk5XiyvE66xfVnSC;FR2>B&5^$+EBE73b?K- z;yZUA2qSpQImrOZAJBepJp!bbM9hVu0W{o5D>WBb`mx1iN-Cm>LWr% zJIM~_7ypuFcBK)#U?(Hp-{iCIb-YMDr-T=G=AJk@o=^*=nF{}{qfnj7vaN6l=84Ny zrr)k$oLnIIufrh-ly!qkQazUKHw6FMQ<4Ocil_R`mH&py!ubUK_R9{tQoz)Zcx~uD zKsnW#ttpT*lI`D(V?B4&^x!P5h*V5)od>#n4<2(CeniYX8uXrX$X16&+lUl6?w>FY91=DQe#hdNkQ2E< zwgdQlXN{1fwg{RLy5bith)&E2k^t!$YyzH7wIz%1SdkxKZ3wE_yUmCFDl8m(7cyt+ zVAQ%_Z20-6Ok>!+KsAz+vag}P`~Ih0y?GbW%-{9Q@MW*H;JLh8_0>2>h2u&hMvK3U z69;zVXhuctoJ$-YFw@8EL!{c?*CVtRpFf@nkUyy&#N_Fy4AO5*Y$aVWfuI_x29c8n zlJ>{#^}*vNNe}!Qzx{Ide6F{YJ8)G@^w}x}ks)yJmpDV%n;{X~JsF__Y4J{?#Wh^U zfT~I$$q7%-kr!*3Mnl9TMe(wVz3efs+weP)sP;h$Q^M|h`N?1&G=wS*M*$_KMbyg! zjT0sq%`8yWmchq&%){@l5R@Dujb?KK;zcQTNGxejFnEjSBc7%rs<3olTfN~`# zj?Lc9wQ&$9)f$yYa5&$(JlC@*tn;qwW2?aY`gXzCj_d9YPxG8`eXdB5AM~(JEmunA z)0*IwhBVC^9ZfGL>vzQG1%KtB`+cGy?q&m1L02VR>7GP>v1CWeaja>SH;;cdtPD;J z4&W*Cb${s`&)r-C+wUFNJ~hUW4icTUjveDq)ih z>za74wpFLUgfgZr9|pi`oIeoJ0%5p_xMSa;}Mmv ziUz0{jttwhUiXBv3-=9&Ou=Z;W7UKVWNB1wyjVo3UN)lM2|%MS*8aQ>yPRF?EU_7o z-1N0oOZ*aTi|11n*_+c=|xY(M6>|KfWVOkY-u7}I# zs9g)Mo?SC5Y=Ae;Z^!o`Jh5JlG^<}=M*-?o|307hg98VC2ztmc=`@z>?65pC=r^9J ztLFc?6T}17;2yc5ef+cfA*n1LX<*gIn;wZ$q11Y2mv?IyGFekb(Q$4tu|$i&`fq%OQN^D~$Qr4y z;q)j!45sbSwMOP#_n06`!_>| zl~6lIDhvJZ++UMpwQ zDROv8)Rh*G0#1%%=#6V&8St6KLiLXJBS1qi^be`=bKbdQcke4twq?j~Ux{E!+AC+* z{j+*~H&2hMESL0eWc7X34+MD?+l^>X1I{hdtn`k!D?#Ce%CN+!gwuj(j-218!Qsv= zLlBD$$|9A{qQEDnt>5W9ZBeH{rWL7q-R26Fn~=z!?5`rw%ic1*sEzf;i3{1~fy|8H zlK4!CVV%!)DVxIf#TO}%{e4)OS169s-!zcO^5N&!XR7}P|SWQ$4E_m1d(rty1 zh-`pBBj|mxy{_6;{U3gh16|ugBfbMp$7GPy&9w80kJQB`X0jsPu6eCF@v3-rnPWwq^VNl!VT7B&0Vp>!!ugN zsIn`i)9+W8<`i>WVt(QARDE#ulXu5C$*`LsK`E$w zyt8qftyCHhzV>MjqY|AV9%CcGYQn-=R38~-ACoDVUijvOXexPx*##9$Q5rRZvez^Z zMG&oZ>({xeq<5VU913~OWnoFpoTHvqUEEQHYkdzrrc?_gm%=?NPG2;bYI?~nCP$d) zeBgtism`c*Oo8AH{LpH!qAwzd$*|)gnFBc~?V$y-KFgk5mAB2d zBkFMS=qd#qB@EYic$+DBWzjp0J*4%GTIEH%ER)LkdHXtbCYE6_%PY>7u6O{S5&rg7 zMy(?S%s=?`UD2=`JJD#AnV}%~8H`CovPEY!uP8h;YFcid>(k*b8sC`xr62@uC0+JA0^C*A0(cCNKZjG6;}Q}M6H~-h zfh#_luA_L+G&d{nUDjqNkni_=tbS-l3CiMLFbXJ{RYp^zARWg)vl}IoHcsm;+>&$L z>(s&rk=sP`EIvp)P|AQ00;&C9?R&i6W^OeMgnR)}pbPIbK0eaEWnuU}cs&y;K|Odpj?cYl<{Fx&tq9xUw^)FF zV|niKvNax>T3Km!neV??TI35O!m!9m%{|AQfxJrr@*VM66}iU=ZZ=|c+p#|Y$z~L+ zVfG^V?V2(?zwHmr^-LspHS6?3B)$SGK~tJ^q7hj_6p=v@vF0 z&}4=BkNf`3P_|!77yt+gqBj}ekdV#yJXUQP!xxCj`o@G^?&dCUX0^b6HXBud14Qc_ zuTiW4kw8Wc(>vB~4EpQ6H|FO-1TsVHs~nt9N`qLIpW~>LT7{15mDuyy|DB`9{2#s3 z|9fBS|6y4EpU~ZVfz{TTHGKwOo0DSzli??nblDDD;fTg|F9+I@xZTr=Spf4#4T@<% z-FZU?u*!)@QhvzcOf*mqsKpY!8i;`SCXTzDp4ShF_?ilmty%%p-8=)Pck`qt>8=`> z2|eWh?e6~zc>I6*k^gs-_W$xD|AX)S{}H;I@juN@B~vFm7e`}LCmtSpv40Ewd#I@V z1N*T3=h`YNj09|~{|W3-QDGwBWc*KhxQYt%zjyv)&r1JCbT=o%e~a#B{x6{N|2>6= zg^iu*e|eCCpMBdRXI^gn5bo|VT#&OasjYUUnnLhAYj1#9U@w#d-RA=R9Bwm)g1%XU zBX|TCX1pHp_iwws@Ek@u_WS@*GEz|`?aS!*XbM=nx3vC^qC1GzGyb>(IL$5L2e!-A z3MxaBJyXf4gu+L9<=gOvE{3Wpb@%l+-+AM=OJ!qW1+*CxpLfJ0hE-E&j{_Cwsp1>% zw!lv-dkP6GEFMX-nrx#>qaZKfa=s@pP{7dBli@>2{2#={O)BtU3zR4uCBBCI)N9o= zfEu%ISATQ4*q-zpi?fVTwF6w%l_WJ@8>rA#-r59OB&V)sAaI6 zDP{6zaS(5xzk*~y;YKZr*NzXo!W?7BlAr|hZ5NG`z1XL_5Z5e?=D?-TBx7zCiii5Z zQ?M*7w6S|SyDl@Hf_$~K89Sz0_*kOMW2Jr5`eOr2(2N2I5FYGoy{KKeV`af#>(`OZ zNA&|rTOXXygn*6L_ZQ7!um+h=7U}n(t+XgpXu-aaRUPceu9BBQ28aZa^__PxO_f|Y zu?G(+VT#DT5*0on3{E*Ra=~e*`|>m?1(lEo@DC1%huXN7d)G0Ld+P3Dj8=_s5rwg+0BD zyq7u4Ek{9JL;nMhy*WBGW{2mT-S}x-n0ER0Gi#PUIDkLA)&jgW*))OrPUur>{$}f2_39tUw2l5r*7~+ADV-sH zm7QJ};``~=RJ!niL7n2*{yi}(o^o+q>hH{F{*t*3Q4F~(4|ZvJvkX>VSaTR z*p-XD-QH^s{j3*4Su+O!r1aw1v|L5d z^jkAnuX1lom;LMv|H?_pn87Cl{DOKL!jZKeVcwP$1=m=!PwgHWY$tLCy*$p85MN_n z(~wkgtf_pidVa1seFHGnjoZI?F`uhltpz|?2JW6kpti%j<79<%OdaDi-Sc@KDJ97y ztny9m_IIUmkoR~BiJdz>TR*ARc1KJnWJs@K=oabhL%~ckuZdE<{OgVPK_AQFFDHlQ zNtqBvXRgiCgg;WQ1lVw`_=Kgf?H(vsh#XlJDfi`cp%vD;mC}|MHva zfY;dR1_w#z9QYh%*R$ z^UNwH{&VvPvQ^6z`goaN-{ z+lKO>f2cnBc?lwZk9}zS3W*Q_=x&2##PWAqL683=^KH>I=+s1(!np<)LK!(I?kSO4d0u(2j;AJid8_pTiZAUByZ)fKGe5)ODUI)Sv~l-&)Shr% zagPd)*y-lIUmgFqJq?`bXEF}b?NS>4+uN3(Kk8c1yeRr4Ou4mseLDAap8RKjsY)y7 z{%8PfUEM!cwg#&&L{GTc*J*EX?d~Gjbebv-U5$4wSVe_YFqcNb68Uu|RfDH1$ zu@6Som6_+~YY1ydkkUrB?Ug&t^llUVmu=;%c68Zn+)j;;DNqhbO83cwfIX7T&GyS> z;tVvKVb?*PwN}zF-v~iw&UX2VObO<%Tebk?t#3t07%cZd-n7~yDAdl?h_aiR1(#38 z|0u+bURVSPz1QxJJHX^gdpa{hlb&f<2W3`#uPLSb4eF+ys;N3DYBZPqb#wBFvZXhN zpM({h>t>M7HVhzg+{hEv(l1ruY{6N-AP>maMcBL6mz&c@dTiEnMa~v5vzj1{RzY&f zpof2naoMb4#VRTuKsF*EWQ>_hG`=_*?r;V@XPt*0#`S<1U*r&&@r)y94?aZIrOw)R zC)e5?uzXT+#j!~$-(3K&OV5VEVIM#bsisAv%=!$L?cUbxGY~x>!$YvXK*+{bURfKZ z0gr7dlsQDrI7D_|1CoYapUzoJQu_E@aE6ak;DA@+-R&#il2B6=z^9!F(2X1sfvN~j z!_f4J+iNSYTomuEHPUiGOBr@d$L>h-sMRMdoOK+nhe`-YbDj0P{;FpgsT;28$&f&XF6oJ$W9Hk_WIrzJH4yUjkHh`v}S zT#S@ByMf9}@tLdr_)PYBkLRt3Sbwr%NrvwRp%BV7Wr=@0jTbhRxj>D@{sjDjrmXS= zj#)#+SQIWK?9l+VDb1L)hytajUOAS!Ow(9-|X(u zua1!DW?hR=K~55+nJz) zwz^PQaLB%oqGmj>i38JxHz)6Ic;Gzs?Q!J-@uYbG4$|oFI8N$r4Z3(jRMykIxJ>ZC z7X(3{J-LL(HKX0^JF5(bnu8`797-W5NV=eLkSUH{;M_4dQYr9#CX3hd)x>WuX02V% z3~VbgrHO?NFtQ^I=8N*kW_=j473=ew>3lw*AB`_o#cRq#gha!{sIiuohk77l<$YIw z(<;Oa;oH8#qs1$E<_T~sXQn8u_e9lcDORH5Dj4pLOf( zR_3FS=$3{L$m{Y9-JPK$96@*%%o_eqy7aeRx|?|XnJ`XOq^5BswG(v6Wi1Em zi-HZiw0sVEWnoB0afIY zT` z#4#f+Rjpc@)q$Aa3l$J{XzK6z9bu+mqj=AQnaFINS3c*_xTh0ZO{2=MiAjqKyFr_J z6`~Y#*jHkpuCh>9g&F+qv^*~f)VR%iCa4#0PK{?28J7;PWn`vG|Mnd{jUr}ApabVo z)lX7q`Jw1!BC|4uXHJ&FfWPU(2~5hvc&=;UgUqQdnf@J&SHP3ejh%N@HY~{Z|eu8+MKbk0v@pNxda)krQWtNz4BpZ<6<*qxHrVJ^;eQh zJLfIt86O1M(mT*}48WOUY5QG%+`X-rij+vBo^T$jRO$F_%VamOb9@K5z$AAycj4*%gp!|x(c|{PpN9i92mX(|)K;^rxg2Qe^uIB6I+*64B0LOF?!a$kO#AI`UqTgahla#EnvCNc1Af}=dMjx?xC6709JS+b)NhiA3w-#JiOq82-e`)f*QA(q5mK`A}ujXy6pcbvgy8F1GzecB1;|UYqTmnIf zg>z@i`zke5Da>IiqDcq@y81Sl4bt8uKczR@Zm-6=H;tSsf=jDvPK$203j#Ak3jV8L=k?o zznBXBr>{@QW;cl|i8b^fd^q{bGp#6J(#q8|45oV?vMFVw@_xAjFR3@_O%88b;BAG4 zuAjJns91%*_9mMO+v1%J39jDC_eA)B?AhZ6$k!vrCti1(oyOImT|U(}BR_WX0%^Ez z+Y(k~p&gj4TaN2Qt{N(pyM2B>`i9{)7ExMi#=b%P^o{&fZ{P}(;%{I^HxF%|ppQ10 za?8HqM*`Pp1mkdlfFc|Yn|ON|`WCK*Oz=~3j^0i;=6AgLRa~%=+B@9y zDU|+O)$KpjtpC@VA>;oEaSOP>U0R3x zDIq%u!@kMJv>unrx?;)mmNIGnC=2foYVzM6=f9B2|EGxfe~EPeb*SM#c;Ekj5)s*% znErba@xOq}|MwyyBLf4+f0<;cNH1d5_%yzb?O>kFcrK0_M-JMhBl;4NWPCh>Ll)k5 zHG~Vn+Llsd)hSJfx@GSo7VH0)3Zkq#R{$atYYQ)is+`uGJ382i42JBK3G{tAt;)VI zicQP?%HEz@5dB&(Zh&Zh+3p~@5tvHmjUg5AFI~VJl)v+#93CI<&6DTi-wT&L$S<61L7Uvq@G!lMx^*(aJddHd!I707Pr?^=+UrBU-fIhEmXxS?Z z5koQ>o%XB%VnD#%B#wdO8$jS;WH)xyuTkSwBt9UMv8p^pt^b%3SFhY9+7In# zk~UmPXG)f8tS8u54(I7+fM4e~0nH9!mA4z(=!If7?yJ*P8k5Oi9IDjG^5?B*b`b8m zZ-ZBsy6eR6KkK5azenC(uVcqxk4ppob!?noP3Z;c84&}boo}}g;YcA!MsJeMy*7mY z*J*EMh^K@mzj=lpyJ4gs1y|w?e_GT7F~YQZG$m^QJur$#cD6mSZ^@azSV|J8!az7op!~D1ctD0iQAI$r- zKX;f(&VO-K-hJuB1*9&d5|p6vZ;R!sRJH7|)g~kWobvh?x2z?<3?mvIt(htW=4aQb z#M$%5Bwt!ombfk=@$G}+!@J^i(O;1oI!=lLSVvT(MR#;VTo(baSZ$Ma90qNUp)3vN z$+#B*H7!_0KwA-OsbzT16d#)eyMNulh_^aI5?TmNr2uvsb%Fj8vrLoW^hG4Ct=_#$ z0Cwb#Qm+DO)zN#6`+uEJk$FPZ@v(zXgOz1MywGr+Kfv-$VrLHU2EF(DHM5b0 z*lm0~mH=u;-K5zyd0F$*y9r%1MCq(PoQZcVua-#+Itz>(+M-*Mow$etg$Z2{PGwAH zF;u!xqm8xx=FcqldwlByPf?BfI&xF$2sedTRYFqKOt#B)oUwhjQA3_Ep&f55-DPX1 zvm%lJH`#L@2y~*zuqB$+Rbt{Cck~8q@WE6(=Hg{VmcuZO$Sogr8S`Z^r$%Gxl2zsE zw(Ur0Vl2RtR!wE;=2DfT{+aL1d{6S$V0&Wqfg`Fo7?fHlYiWIw@APV#j? zm^7JfNQAvrvo9QSIV@%xYG~`S_f~zwEHYJueBKv;2fD`kz};yf-Vw$qsJLyBIAjaB zW+y&D>?zRK@AsIvK(QT!tc{*5gp zu-t)2O6ZXv+5Tt8h=s1;Vc+_gxp?af5O9%LqxpVzE3=tI7S}8g3NatnZn!_PlWsP( zY4MIBI}3B8F9Tz)|L1vWaM6k9^9u1Cv?_yVg=rhV;hG=Sl6^3+K3!@72^iDI^N+%& znQIm(I~p!`8cX>_rXHeM+IZ^~3X@l;o_cFvQ@Ao#Jd@Jq};kF$7G<%eQy54mUg9-QZIt>epuFg$C9Pplc~F(}ubELI$!!4rRh1-L)t$pEwnf8- zJa%NymC>Nt)Sw0W1Ka4dUB4vWlcxIzS1CPU>o7u}x#YI!32@u-hvh|Lv~e0js}8f! zDJwcZILtl5mGyzKJc4SclJ%xSD7)Yn3$|WYMO5Od0+buMlVfsFp%;mG78?u`*i1an zQ6?E~`?t;{@!ilmWWyfRBg*2(7Q}8N&hjUY}jiPmn88~ST^E~$=i zKyWF2lX!^HACo+^5|Ui&OH);p8XF`L!=E(CFk>OgY~+uD)~7oKiT-VZd@Wu>2w|(h zuE0>79l4Bqf`2H%Ud(GMq@Ctpt!PS4Nj`eEFR$YY-_g)s*yc^*NQ40i ztMirl<0)wrY1u`^aeMvi9Ov6!W}0=zQ4^^}_YK9>(C8sB+!#C>6`#*hH{t+4f-?AW zyT34KxA%}H>5~e)&_MB2JWFncm_6-vhN0WEq~i32f*SI~Q)k&V+nHC6_jeSkv0O=G zqhC%(nS2}Ii4gYeq$?2R$!jQ(vIKhFNaDyiPjM>W(`rq~#=T49o$V~OG-E%(QgH{q zV25+yF9m4qkmp&dow^r-*}I)M#VTMt#NnBHT}4Kv%@t2q;z0U6kA3ypb$ZPeW*USscvpw!qM zF}L*v-B5WTR!zCUO-oKjg;_E+zvvd~!&S&(x6MF*t6F&o!ifv%dyFyuiZ*j?#3G$W zTFmdD~`sh$YK6$G{Q0d!j3vL0?N4vZ2dlF!cxtfD^{%kV5+>G-Nq zeqWLUXJw>!(IFm|;v}4X5!6YG9{rJY);*8d0Fu2}ZjVBNs*JyK1Tu(KJdAQVxx1vT z22JfW+b+}bmY3Tr+&p&3&{>8$7p4WtZ5bj)E;vRyM;bOnlPXRAI`m;d1HOrfVKo5C zal%$5>xw7|*T^#!U@xht_xl`ZN`N(@fB)<57GnWI7=1vK{~!V~aicI$JY$`HafIz))OTaqm2XKlHtTW~9O< zj1>62j4a?d`1_m+?0m3YSRAj3Dhpzxu+iWlwxT=T6G^?7Qad28Nv{b*-#Ab-rT1V+ zT?EmEhv^a+0-q{YcA#CReKr-@>pLIlwa8IWn+b^DSb zzK&h-Q6Y6oohN zgG>%jU||bTe#hUgv`4uN=x2GL{u#}e?zPw@TyXv$O4oY_9plo9r1lgaqX`s-oE4y_ z)$6$jPS;Oh+1$g4MOQ%(WgTrWXZo^*d{`dTN>2Q*M`0j?{dB*L?7~pQTJM#?-I6t_ zLAk0DxC`=KXgAI6@{GK|2)~OX?H=^HJaMD&_ON+tC{D7V> zYg%P(jz+Y>`YOxLDH8vChBbJMDMpwedcraTT`O^<)nJ3jd=+)B#CUL9!K@8%6u~j8 zNb_*KSgIwS_a6C7kM33uRonDIRyKkO3EJqUJ5af@(Nk|yK41!-A~bY=E4Vc$K;t%z zz0c+Bh2a8di9U|S*#|?pJWvoC7!B#rjpq2Ni=+6ft}*#*3au3!vdOg)x~ZuH2? z3H@s>a~}P7=`m+>alSeC2w@r8To0~bHV8ABa@W~PRfe_)JvoAb+R}&!yL`|P`o_~1 z*EE7-VvLe!_h%X%bNr;uxU(4FotY8Or9SpX0HID^F(Q~q`=kOu>6~LrUF2M%x!g3M z^t}0gb5HAVSl33?E#^-=WXHQjXBD*pOOIpv7mOrvqbLdJ6-Ov0tMD0^whKzq&$KBg zArn!aH;Y9SbLQ@RhpgypZ;F|7ZYH+hI|RLI>AJ^n*JFA!lq+}sgc=EdsNV>;&l+r5 z7Im9fmsABHzK;H!%CEHO{koWOTp(!o+M+IYOQ_KR1xhgq@s--|gXF}Ybg%KJBYcI2 zEi7bAadCxq&-=;>L<%Uw5G)7=@y(bea5Dw<6Xt7!7yYPnzv4)9e(s?2Jc1cv?Juz2 zA-nk5HW(&u5}D!#xMMDB&m8nDny*Su$Tvf3UduY*-xt5wL~YvSqqS5vwwKTIakCfK z4`Ggn1RQr@-nwm&`jlEp4SuCqTQL1~bpi#2Tv8iI3B)fia%p!lSc_e?|lOYJ;vxFXZPEBhIGj_d;feMt4J03_)YJau) z+@UnHnkTyFx2X0jJkG80?N015on(=*QA#~Mn~8%NDTF0pwnP9!ouBOb^Zio7sI#7~ zbHD4b6LJIDrX*{L(n}4_HrW6-c(bFiXyD%S`BW1jYERZfk_(%b*L#Rt>wO=?u^Pgk z=FZ>)(C6D-e|wvTDDjWl3GGO8QWu&sm?bV`x0RVnUeWIKQnLLFE2#PI$+8t{$%NEO z|ssd+gy8&O(O-acy!P+v~Vn>0WF@p+CMaK9hn z+!Sa`3P*X=hOm->MYd(npg2j2oZS>~&P~9LNS&c4>2C*AchJxs4ZRzrzfBZPv|oD0 z&^o7&wlHK(sZ#uxL^EHv@1sqpRXdQAUhEOLIUF2kyOL@wBu$exzr3f^&aW)Srp=!7 zKN9fTp1Fbmm1#(7aiqRP9HvAA+&Xv?`8d8H=cAC}sQxh1yv1V`U3n_%TMyF>^$MNv z(ae)%{61jJ+>q6+U@bN<(UGhebeMdm*C#Vdrqbk#^CTiZz~^d7GyNwxjt$u#5pzoe zkhnv*Kb~B$DNMn?ac$LtDz&w|uxvF54Y7y_Wm0_!)6zKXR=b%!G01`6pxBRujM2I4 zjGRTi^VVhX7)&noY~5_Tb)DW!OMr3pur=jb-i#EOTW}(JquJwdsNnz~d2orA_1orU zB7lXT5v>nP7ODX;wvivfcx5p*d8JBS2jj&nC<#aHnCsWjIQ8pp#NEs8d9diJe;i)V z-vi`q`hQ~1iNv(fXU}lYBDDC|zAx+T;Z0(vd98hH0`_%IY(No0XfE%9tCx%6H-Wk# zek#;@7>QQY=pJ+qr`@4`aHMW4ZtO>tb*R% zQh^#{kDOyE!XH1srKpyeb0jps6uVU-;G~+22AYNnV~5QFLi0<;04*QTRW4|3x*NP zsah3clb|h$)BR7e2`Hf`s$j8VB#USGmCj+NH&TbJu zZpfVSfz#jOYl35QMxX}lLYdk`uMEp!0#A*yzGwNVl%X(8&#Coqy|ro^K8SV@cR%IN z|CZCWI1T~kwYPx5ogJkimf2liMrKtB1Pjzcv>80>iP<0OhX4m^MM{w$TAKrXe!bJY z*i?>Oq1!ZQr15B_xNGcznGsHXsix3_s@OzbHPQ$@OGC$dbXt#_eYrT`x+kUF z{0Rd_*W>}t$0RKQ=Bsf#2f*f0Uck=e@)>Q_GgMaTE|W!p#-EZ%<`P4n5Z;4BrQ)i~?)sdwDOGG;vDCwsA-t&$gn2UQ^@+VwrdO;$2G*hM z_eJ0SuSGjAIw)oD!JeD7*yr!lMPx)$gZ4z?`O;teJpiB-Xx}OTmBWj^6g87(jOXn& z9hbN>iX6f%{iYBX_OOeVl;VvT@(wXX*la8#x6ydE2EK&!`21VxO4ehr-Ey|Ao1oO< z*LDJUaovoo(bn7wK40y}rt~mZr`L>~>6wf6qKG1&()8J{fXYssTvTNZu3yLf5(aCY zu4Tw{G7!^;;X~J=AJb;5jR{t<^?4!=-@3roo9JL`RL;goT3X48JP&1*Pi-{ z_s01!mKibOUh3Bi!q>37YJfv}(x*A0Dn8zoDvDDDS2D(%MbomoQMh6lWC1&Rwl?Sa z8yN>Wa>n(v+HXI&{Uw;qxUvV9x^z2;czZ;q9OSS(VBGZR#QnK;KC=60n~g_cpFcDZRLvKiVaE#e4wOl2@F2ma-R;;Y(moms3#1f%lEa;1bD!-A;V2Ht`9I~N916zAY?Wd+>FaU!-YnH(FkFJ@E;w% zqrn}BpUfJ_Lv?X&KuvQ5fEXh+&KMWu5oBXyq?7_*I7DO6Oa?CU!?ApD&u7^6W>CXA zbZk{dBmdr!M|QR5KwQjw_Q{3f+VQllMVvJdp=&6dUJ=jXjk@|05_3fPzTYU(1y`Q; z`bj7k`l@kMv)_AAYZ#S>3)DM)0teW3OmaMZwe%bwlJt0F;O{O@L;9JPeh+&Yb7)>z zW*Y`?yakzj2vsK&4+CeB?-@~ALQ^6SyU6X)Nl_{KajlZLH!BkHUVj6`|BYfqy#n8uJB(N*j}RAYIS)ku8PGR;`J<$G1=KIQ#6}dbTIIv+sLUb|a-~vC4h8hW z3b&ow)yiu#9mzjwg_nU@?t{a^2i}`?Ot#zRfq>h{)G2~C@YlR`0=DMeW)}U+pKUV3 z{i+r`jV86T3>3{;g*KrPlZ{G|YJI(z&s>D4;T)j(7}yvsWfT2i?v=c1LtjiTzgIUO z3y(%#Kst+OK|SE=&;pdU!W;$a@L;;yUGk6r_JEhi?8lvAu1|*avn`eos321I%IwbY zWg`G3$oXYbFB7m3zFde~w?YF$&!2|NT~2Q9v?E!AopjRf>=mz4zMrkD{ej0JF)JJ0 z?|+SZ=R^S!g6FkyOZdaqx&t}hh8Q#;Y0kS}v*>&seC~VC634wBC)iO-D2J>{^rZUg{?q=wMP@Rl9$t}zcvsmi1 z@h~T9CY3^9xLD##fGo|IdCR$Q8+eVFr&UcIX2h{ zxui?8O9_NXjz+^LGUmcGgFjgEmBFx&{lj zei^_Q;@if6w+ffabTB(PA2%0u6` zDW>YwMpA_ZPRFNrLZlb(Sbj>;DbA-ZE99EtRjE@x2v%HM8h_4845luE{N^}BSLis4 zQh8D9q*Lv(Vn{&U?JSc3_v1~7f5Y72A^mcqqZ}>vy!da zxhqvYy<*g%+lpSQqi!whM2qPbMFk`@c-}x?g|n2`)gpdndwwlLszMZrY)D4=PPdUL zhUhn3Aig<>&l*dhID~4aInK4{`K6;l+Gwgx- zJ0+xe_>nQ$Hm#C0Mwy_Bco$v+|Es?lNIjAxxtFHPtoeT{hK!2sb+;Sb!|Z ztEhAM-mdDZ@(%GR{KJuqo&0|9?YEO;^?Nz6qas_m6-Y#h4N6! zV{VaYZkNC}Kt3NuGS~I8I26)=#v!KjezT4(>mT{9)=%XnPY`iCMrPj<}5{?HeL*`m3w^Q4(Ed`bF`rmoE1?o7?H;-R(L@Kuu&ndv@JG_;y5||~p8@5?a z7NyY*S1K%f(bVC%p;`gaXkgzg*jq`;V#nxE=e`I0KKEWtTkxEpaigyo(;dd%Cq%Oi z>jG5f1#YVSf&)BLa6i~}im=vUt)~IP*X3v}F1A>%kqwn(%kWN7`KzgP4kGT-pw8ie z(cM@Jac?Q90K;EGN0uFGE1hmz6sAJ7jO*GARjNWL`h;qIrqOiJi2<=YIjoA%sP0HI zV7wCs!)U((ZL^_qsj;^l++Ra@;@ZJ;b&(E=f(1!Yojjye@GAW<@FBF2@s)sM5;GTM zlydsnYcQwLP$bF&D=r2-v>K||IJCqhbjvSR;203QcJ4qgU+vrSs_ExkJFm>dei%~ zb5joD498%mXAL=9(-GbDeEWd#@Tu%ReQ|HB>&BTTrgR)n^L&33%U)?#6Q=-LMsf^R zM7fxe@{fXjcwY%_*S)pCQaoFEppyHKLwrOMbVB!4WS^oh zw#`&=AaO8_g1O#ke2}hWhLz5{b4EWE-lauijod*wD5%teK!?eg*X$zQ+T1a8oEK4G zkP`oX5$w||ctOuk)kbE*6(Ny}NiB-;oSu01;nek&DYwb3{2k`i_8FbX6TZ>>q{rpj zW=KitS7XiASt|j>IQMNwHU>Qr3>!z`rqc>2jG!dNm_8m$8B1ApmHDC!+4_+#ht@Fi zqouV!JS*S>eRi)ZEAW+i4*jn9DRi&m!^Xhr{c_m$lx(+Ds>I7zBs)Gqqw*T3tSaqX zf{R*H$c5cu*pxX6utYNGrh*qYj4~LgYx6fsUY^}q5%|JhG68vW{MMX1BbJ9)$vQ+C z0X9JlYrPQWY5)CXua5n)4qzn0Q>+F@xJ4ZjL>1o5}ldPlOJ(`zF6n|asQ zYxRs;-exs_8a=6+CoOlL9%@EzRT2)I2J9eK7Sfy|`O#E!Mq8G0m`$?qmd33o3c8Mf ztWKN`v)jD{kwDGgCG1u_#a%B%$q4gNnrBjJ$O>5QYGYxoT(!^Zx>!MBG~!6BPzYfl z$U8s%R&|mj(h}yXfyYd%MNd=WMT*h^m$1peC#!^>+=xle)TU_=D)c-im4CnmH(YIA z!HnWcfzc6B^!>aUbL0qla#w zY6R^YOj*mE7=oLG;EPQ{aSsajj&i>lZb0SVVGLx15?KV2xqnjHooSdLnZ^*kx?IG! z9bMi9_tEiBlM%_8;c>GKL6KcG4)Zk4TMe$9_V|X0yMSqyNjLzD#*@-rjd&p|ohu}3CfSCt zzG2eSa(NKcy)cp%yvMvcM;4DRMsUOU6SjDKQ<~i{Ax3GeB!MX>4Dc=CdQ)^#12~VC zwa>mUS()b%BWl8-d&;54Ggr)!rC?%3my+Mc`N;6v#wyviY?}0Xm9kdlQ~^}&P0u69 zmO)L-LA76sH*U;t6sK6#3rOhI?2}#^*wqvJ@_pJ@<6-!RQj(w4Ua~3huEFq+f6IOQ z04d3U*j_Pfy+h>4a>okQwG@r>PkXBdjC1IGEbkMSz%#_(EU*1#FD%Z0N~9&;KNMp! zOH=RiunMH12W{f}rerZctJW1>OO;@Ai*)rzxe}n$#52@Mk{plPyBC#qgB2T>MPIn$ z!N^e{BKj6BYXR&z)3y14y=e~q-pY%L0{ykd$i%0w>SG3VCe^DU`rW2E%WZoOR0tTL zo*=U5H$a5z4~R#&w8iAKe#4GRYoa{{7_WLt@lL`KGoxJ%n2hpeo+UKw$T`s8t1FIP zvmz0Cq-5B&vchuwu;a_e<*W};Y!-*WFyG7sq1>#A71o3pEteD>S$-5sa9oM^8OW-* z1s!T}X9$*1HKT16aNaO&JTUM9h+7>=hWb@FY7ugG=>{emV=8Ug2b+-`F10h(ER9~k z%FUV()&%`v(P&aF6!0T?(#=?gFwoQeRpTjkyXd2$)&ft(^AUm9lRnU;YSG%r1KANCeQ)%WiUcB&|ymm z!$J2tln*@@tG*#t0rtYli)CUjk^t(Ag@VIYHl#vp;TYWmvX5Z*;+VJ;BMRc!WM z+C44r3C|@XIL(U=&x$90ad9bq)5?_4q04l%HCjCk_-!pQ!$G>F(Hoy6%p>yLY7L`c z6?6&s&k)3tnLj34cQUWPuCAV?&K{bzOpRQVoGr;3YZRL)W0%hgw170ScMyMPZ_{8r z_A&F@K5V{{uDdcT#4(D&6pI_9aOzq{s$Wrs8KhmANBw}fM7X(XdG_6(Ck5{fe%=5H zMFIMnX9xJge%=aY#VC}{-de`jVH#)QpqXt~g6femA*5DK zh6*;Gf>KJFoJZm}di#q1+qlLsAb{;05k;*xxgxllXBRu#7&-lykPelVVHI7EbEC4Y z-;o2SLcWEfxjEnJ zzykucH|+abr|ThVn_quKIc_}`80#a9s^=iX9%iqE`5mccb0Kqv3tEXcWv>sTTxl$R zEt*snuv3Il##`u*NHl#^!aF2mUsuvUVu@`3W0a-7w*byA_ZnGZ%daglRgSIXjVD#5 zi4>55Jgsq+YkaNOc5S4_$G#OVra0Ov;$~?(5G3<`%VF9?C#z^KoiGf{K^4c|oE9R- zOh6-php_REhMyzRTG0~pSB-@`!oYdfyU*&Ih}BXoA;^ahtv&I79Oqxm*#Ajc{zo$V zzoOdzo|zW&Y10Hb3-8ig4YUv2>5bIm~wPzn`_{r)R_aHQ@78uJ^0+ zZT>)MeRA1NO+0FC_$2}3lBeEDa_i~sfx}s+= zO~%(NmbL5D3;^Vhqes)XaQl09)|nSL9HoI8d{_uSVu=@Q(-j zUuzy`0(o{V4f}qX!x#bIn9&MMl)PLKqvAB8U4 zGrkdm?R6n_RoVx?2hb=aX3$hV_hNhigVSxK_|3oiB_<14y8NzIzM^_6KoV58vhoB7 zg>fEAhjyM3R~@9HS9WJt+Bz*b@?-X5hP9ckecv&Q+JTP_bzp@*Gj9Bx7v0%{42_Rf zxvV7aZP+bHS9W6V$(QdGxr3kHfy86oxkgPl#XK{ofsUiwx}J}_>p z!KhJ+p+=0Z3=-EfeZM^HIkW<4C18c_Bo@>B;QWJ)l>&YM7&mPmVHdq1;Ln{UNF14V zDfop~o{+WMoFUpry%&)B1J#Vx2ak2Yz#CkIPO_U<`)u8-a!0G7sg97YzA(J~=smy+ zo%`U+meAqmfr{Dtbo~bnZ+%}T85w$;T}rx06maTKGMu*e8CI_Xa>4bvaUBKYggG#! zC(L*amL`s@&1nX(K>#>zfpl?$^i`kWIUD|DwNVe@%^#Zat3vTDz1yghg=2CYE{MY- zlJW-|w%qEeKgFt<^O{0yyRpaj@3vqjiM{3LdSd%}fV@2onHUXiXmZ|>bDpAw!11%W zi*XQpycOu1mEVkHK}W#7eeR^8*|BQK*b-|7!=1$p@=$WiU3`1?XWYO=S{)og7ZGJQ z8QX(^n-AVYOeHSLpQgzykd>;`h866J+jRSrm%M(!4O1gDo2=wAWL<~F16EFs^rNO~ zI`it9dr|RZ#l%t)v{*Lt{n1U}S`UFH9)A+$n7@6#zS`z?4PapKEtsF|WC=e%A?~cK ze&FWf>ohP;@`bT(U+pk~|BduZb}Z9&gT!K< zCH}3q3MdKKx+{Cohoz0gNSvPP9GzGS4RgZ2yETCyz);RA7q=g#h`=t1E7?HqbrQ=C z#z>AWHKR}Yv9f%2p4>pGK~JmhXhs>cP+#LCK(+aiu1j|v#HjOpx~KT2mXu6yA^~w; z+9RHaTmx|}Hw?C{wAL^)d&W;88lMq;Ko+rkXoidKvNv$XBbW zHUMdcij1ug(%3jV;FM^9N~ZrP3C$u=_Zr%nU2D(es&RwduB|YSlZJ{R< zbaQKK@L{{BPWKP9=vV+`*l&FfHE@3T6T1t}PwviF)hsg~!X4&d&PYkr^sOt4a@W+P zEA@Ob5f$@&5;TWcV}@Ih+-q9REE*NqHE=**y404Gso4Oy*5+&eWQc(&xwiaSDLhHUk9CBnfFf)w901r9q$G0N6YKbHp0-*q+>8{$GLJ<|CSPey;>O31QeLccW1>OMC&$I)v)uT@IEXXrC> zE~=-NMg#ej$op!JBhzKW9Lr|Lj`4Qt)q&{Kq8>fiWObdz=1#yz#tE)3FZVsAmdJ2` zO*}%mR%M)jGCS9@L|xY6wtWp6nBxv7%OvzI`z@5@fz<0xiv`qf3FjcLaQo#IDVWS?b$jF_w67|l zeL$+OOpT9IIrBsWuI2&uh)A1kai*Hg-%qH8%*U{R$LWR067PdJ#GEP+{IRJ)!d+kX z5%&n#0d?;}(4zx?l{K{q8)pm7QJeH;J=*oKE;nsBx}1hzAK02QJ)+~+U;M%iZ< z+aD-VG8l!4n7HxxuoNE;UBANE0HTlmT-n%!1rzm>>%u_igqPNTQ@Na?1aIU((Mfv6 zl{$C}FyogEz9Pl)twh@jWcq9lSdhRymGuw}pO6jj6Zqm42=!6D8&5gKW@RK^g0&$y z>qUBnBhs*&cSEbN{m^mObG2SG!Hy2ziQG7FM-gJ!$yF_a*5jYOq&#_q;n5vUUg8a(qEhS~$I zd^d2ze3sDzi-*5WiVsHjrdAdZL1=BAe|51CuS&jn<(C{WH#w&zMd1}A5mC}$Mij=yQN=lidUw@S? zR%?s~(@ltITz%ESiFysI3@-}Xk#>~O*fvR>Q!=L_7EngYc)mlnD3j}neTdm3AmPDM z6g?tO_=7@Sqep~W0q+BhJqVR%zTw&1dcmS30n!b@jQRm=F!v0WiU`0^$6*w<3e8U+ zLzl|*HJSlIR|UiVn$^%M`U93x9aN)0b?+_D1ts-rQ-^v1rr*fjL=s6*^=P7k#@2uY z>_3h&82E=!rGWsxk*X+(yO9{A$ikw&N!0)j1{hJ0)hR=( zi!>?){hHUdUBQ-_mfx$JJmUsE-3_@Bq>ssS^z(`Ix7oQCm#lYmAdUFxcW&3155Q6$ zFflq)EmIYmQujXKZjfJKK%wA;Ptfp);*J!w5dQ-vEJ<5kmOkM~ zt*^6urEGPr4yzlJ!(3ux0NWP8!&JUxIhJtvEb9wv8x}^gz2_=z5Ose;ab!8(H(CkqOY9+rIjiT$spO4im)!I%J5ixSehmqimAd>Nv!y{<|VRku;bCrmMJ zDBtMHCtSyUn3ySc&PTIE3~55uJAz?k)zP&?p#raV1e$uE^!gPNTs19~QOrx*Cqk2& zOd%kkCYbyYYVO)k&%E0Kpsc9Dzox%KlT3?alc(V+N-vZLx%_{h)tj>gBOZ#ia9z_s=y@gT{m)HR zQoTh1WK79`ET6K6Ce7_8Ii&Fv^is+8HLmu7jM>veoNqyK%3a{0qmYOS1Qb$CiL!cz z7Ryy_w^Hvb)F!dS@Q0bK$fv{Z+d2v;u$H)PD8AUR^qTcil|m0>YrK;*yf7m}TAdd6 zO(ce)rwTH_OUj$TNA3;p9@X)P0keO{w$kR7_REbF0caEV=n{n0c*m<|N5fhJm;H>UxKI{fb|{ zPy&nDXndzP+C;cOj$YmgDL@*i91FGaf@cwPvC$MwtxjLlpoqJ<<<}^FZz)$7Jars^ z@UPl7T}@WBlS`ho1JM7)8%vdSTM%5@T zWE7u(NAO!RpE*&e#@|pW$a$`TYM6OX;OaxrXI&wYrN>&4*-!^NlD34#q{hlwLh$)D ze0c0_+s$M*xhn<$_{P=m?Q3h4eQ(xY3tDDFE;(9P8@;K`<@Oy8Cx+Vo2a?YH5qHkp z*c1s)2t@viv4Wz`|dS>Dtohv8ugY>6Ilx&N_M&@E+pT!k_1pWv} zeC6xPPG;8ls{Ro49EA2-_N!=V6ggm28(9tCtY~a5CC&r50hJQ_t%oGsCZ?^i^9%mbc@}_n zN5_Ux{8fv*6weSV2qDKSbDk89x1A&aYsla?Pf1h!x8~l3rav?eQ|vc-p-%{oFgg+V zddtZgZL7>poR20ze9A!u14bJ1C^DHMr69P_R_}goeP=-bXX(=HUIt47_hG}P$j4a` zhJf+#IFvdEdVjdp&DNxJQ`!#4{QVh2hNX6ZFUPHETRg4N32m2!1Wg88nd+4z#s{RS zGJA*<*C;(sAmea$%Qi1P3&6alN@lCsda%_dk;OCL{Mj|yR0o}pa4nOGi}fNh!80tH z@(~C3*GW^5W@*Q&~cRV*n`a@c|{2oa@4fGCRLTI+6!dReVpi3T3}p`W)y0#a~@gY(A?< zYeI!>uK=&$BHx^QNd(`_LyJOr4W292T9PpX{!!N<_>i6Dy0S9ja`6=ERC4MLYl^u= zs4wSv_G08p<*H@h-g4G{se9IJV%u0n&K1 z@Zj;TWjTVzSv9I#&FDy)c0bK%{%n*nP=cGCJU;z(($UyoG^MIOKJ0PvD!3WX{VAXFZ_UX0VN@QCDfo&JP=uM`U5EzDg>rx0xtx6WMxfAD=C}w&(RStX zPbMd&*H%`fk@dOGeH;^%^(romnfw7B^i?>`Y>;mmCjKLbe!)<8pP^&^Ypgt?l@3q3 z8y8UcxCK+r!r$8~IIQ%Ad`xn7y--PSmrtz^2+VsMFz*sS(wq9=&@Aw%C?vb1|AIL< z4@*1f^MI|mD1EsTTJUV-M+fl~E+)_S;)9*Q`P+IQx0PD7xE&j$*f5J5Z5vPKAzHroDZ~=${ukxTql3u4c_N zC9$8qH8%qo9ZrV{gswV6yRv5XS!lJ!03f0U3GuE{TWlmKm({yuu~*5+^QbC34BiTU zv&Eg)!F5{YrDSg?LuG{4kwhBd%>d8<%w{S_ZDh5q57NSyH1$f;3H_C~6;X~(V|san z^NL7D=y|-h;&DMQ*q3q<)JzNVJBq?g2~RV);)u5AMi2uNd5kb`F+fZ)#2Hb;O{(90 ztcWPRQ9mJQY@|t{MNYQkt~6&eQ)I%xQRBR}<(Zah^HvSgk@yk-gLFqWHirTrL*4aH z3H}GQ;n#_v-Ax^TQw6?SzhtSE@6&}dS8UHc3aGYzu3enRy`;@9*@7~U#Q9KG0yw_p z9k1>IMyJT`uj9qr@tsCMY-_E%Y<*Mr5yHN*zA{cB&g{I?;v)I_dzLp)t*5QPyr-1G z7RaarELE(KGQ}`2OzhW>PJ|K1)kBmQt{*{|qy`n;XGEp=LN=%KsCp~z&1yIBXH2yc z@{LmZAxoX28$z1sz_!t)mi=ZF6p4AhX>=-1UUa~8ppvAmm;38e#qqGBRMd)qDb=qY z!UrVgEmFmu|y{SXB zC3AM{G}6$L)5#!DqxK>{Whde5#QQfWKj4XwKsVZRf1`}h0&2h?lTyc~y8(5)9Lv}@ zk(5Hxb1_IfoJ_uu06g-c!ReM$a+H4j6p%4%(QR{z~;4|64I5K)$GjUyuA;g=Cz*UEyiO ziC?-l-eK=v{@L)x?}LDWuyvj3G$h1&qB$mwND?QpW<wky$NGVNqL;w-^h#3vkpuxNAQl#f|v) zE@a;A;r5_|%}@u$Sx@Qv)*}hc(`cNhG3~A552Q$Jk!(`(<=eG*ABkzG)&!JNs65xk zNaVvU!hVlyqj`T@CF zsM=6TcpV^>a$P@lp=)+2I%%cYRPlxAWO;`IriJ;6S?&uS?E=U}L8n@~*X{L|TZz-+ zEMMKQa*w#qKTrX(w=61B$x*KF`){i+ttU~vm&J`awqT+mAQxzR3{Z~Z6CF+0pRdiz z!V4P%3qn%#ZA_||<)ko4mNY?Vp{JBLmi5tG0QHK@oyIBaN=755t!XbaDz|Dm@LPAf z?`5>Eb2!GCuD>f@2ha*sTn?3uG(Y8-(sO0|DjW&bg5+G+PJgta1EsnyZi-qtMpRzyf_Mof|TKwQ?s#|f6Fbl=sCR!_idGE>Pih;dHwI+2o^S*!C#k*Prh;nQ6 zhO@Otyg-h1M1m@1a5K7X^|>0W4GTB4c1~&+kC)5ZT>M!E0;0>^YGY5=N5%u;lSGT_ zK-G6n$K|!MUpOw`@5jOCVfb3(C=<$;;U#mg13MoOwKeLO8sBT~6{FNaa!HYD1%X2LjM9x>&Tc(8 zNSv`{47`VnT^#I%%6Arleq#EJo7sg6Cd1qV3T@_%!@njkRtB7lQw*-(Gc;T{a;qA| zkKvd>yq#k_oh}`#gmzk{?%oIBKiYE|nij^eI50{~*60mLc@Fy3KZXY-N$0hrC z`>LRAP__{|9xOPi1rESn?V$e18YgKw)Y4sxYNV0Nioyh!mcZB-)g9t9nj zl|tf88^ex{Fl^gFyaXI&j5W+&qWZTYS6KHj`_eJ0y#jmiU3}CG^H1RIhJy!O_uH0d zw=Dz(6;{*Ql&GXPrp9|(D6J!1q)%;+sWkfdT+%|y zUU7$^uTyB!+`X~MYikad^q2xlKvg>j1!>HbHCTS!vI7`&ZL!K9E*~KzBreLf@iI&- zzno8#nh&b~u z)l2%21vUfe9CzCv{RuW{fjRjNBEM(ohp|ppXI2wjTD3p%*K89l_Xq+v z(TprA@ieLawpRAATQFZZWD6Zc9P#<;EqkPDNQl|CD=}U=)!-@cCYzqWZH4v$6jn`} z(n_CjvomyI&9He72IgFw_25*30@j_u9}0vq&7M0vAYb#YkerX#3=~HHBxm!y8nWuF zPpTSSX)~X|SjD@SjjD{VQziUH9-UMNbrXt~>L(Wwj!6xlT{8<2Y8Q3D%BX_(H;!ge z(yt&7@6kM|bb3bVsC=m(NrtN@xbm;Uo6GqUQEf+#Ej`NWm7@`q7=5@EXo?5|Ku0|) z@hTdKt{xWZP~dU;DyzU6)%so1b7`_;WBCn#By!LC+_>)FLq=iyr;=eD4pgY`+OA+> zo?v7V&?AL7TQnHUr(lr=#cW~hAJuB<8? zLIL3~+Su|Qhj8Z^`z8L12r%%DccdgLj0K(c-9D>OMDeuHc^O#EY4Rz;hT%B6p4PkhUY%!4Vcee&?PSevcUmdk)kWg?TSU zZSv-ICP&n{b!A$z(v>qM*mO)1z`2Lz?SYB`ugxF(B77%=XwNwNkAY&Qi|^V$HW6ux zQuE^%B27FQwx8|F$rGn^`phzOTW{`R-PSJfUk7s+c$ zm8Z+=w?!^6KSh~mAe4n!{2r?)##O;CvI#&6zC^)-?_%IA`?U2SJtK5HFi>0M$U<*u zPE^>0=cpq}w$1RMyJFaqQUzWu@t-8|?-JjJW`F;9v@+Q8)7+T103*6T6NL3DAt(yJyvVHt zN|bw&0v{YwNr`;N(O{C}(f~At+E6llXg)aGP%HcsLBRZP?)CqEkN*EcRj)4H56J~p zC*GRrsTDGgt%TPG9`AvJ#sGaTm6##HH~3zWC2)~70pv--9F>!PO*A$4aakW(DmGfH ztlyMUGXL|=V~pspTEF@Uiz4C#&A(-bOg3_$b1wMpO`=7haPg0){}<8zfASCiu7&@v z>TKr!&`$k-ihuausp{F-|5;W4zXtj5-_`%gJg{;6i>iL<2TkC(17LxA5l2e`Mi*XH zFb3;cXKixMGH?(W{AfNwEkI^BJY0vGX}$qH#^#C=l* z0Ptmf&%W^WrJjq2J9>`1wjaW#rTh=GjZ9V*#TZCbL~b&qwe=VzU-*R`NFXM8P|2@u{(4S2_6$-dxLc^O5ZuS?q#FDEvgF56_ty*y}24$YZxm zOci`QDR4YcbSE=@>f>J-pk%?{Z%2no2jlmOmFMa_f{1QP#aL)BTpolfR6Rt9{GVqu zmOo$R)w3cv0E=6tJm8$-4f(Vh-nfMvL_5w{xYgc<>v7JX?qtX0+|^>oP}N4C>CK2H z{`7&eD_=lB4tAoLNsKPKpD_b~(Ac2299wdm&E zvFc()S~_sp&BXTbIBRV;-cXIk6BlO)w2b|%Bos}6Z5`2AHNhQKorW|p=~0A-f=NY` zi7F7T^x}{Nc^0H%i*wvj(sC+(@~_Ne0v1CobE?;I)#xVDaDs>_$fRQq7!C?Nk~(GY z2c6p!B%(&TE_YXl*XHF@CxSO>?gr?YX7qTLM1EJFTR;T;O?TWmB-zd$0QB`jo)RFP zc?Esw9xUmPFhP*!$*cxvbCX4~T&|n9%_*o&7g55k>)T*Qal0A!gEfx32vx+qM@Z&b zvM!Gu6^}e(W|Z4q^+SG+O5(}C+a{y4R{A%w6JXl1Wx{7`kkOd3%G({;UXp+XA_N%c zp}II55vRE6s->^dOnQOYTht7>(ty$LmVlaJ`dbO^Z%A_Q(VZj}#*9d3*Qyj5qBn#Ls9%k0(O+<*~JrGX2r%9jtPN*q6Lk3{}L zS>2^P1Rc^WXt4=A7P72e3LUNUKgEwy+Zx6n7UbE@H7zgZCS8a?a>XsO=eWhMI$xwT!4FBaz^I7f>MGbF+O;WZ9vhOIR*1}SPcVuW zQgZVN0qTZTT~&2gQuATxZ>jJ}WsenRU8}ktx){TyU4EdIBP4U8x$OPQlHoZeCX|#` zr_`A%v6hMjx13BS7R~}?={t0W1(no+ZLlE`b_)x-F2s_GFiaf}?DB&Xuhp3RJw0+( z`!tIS3hR==PY%3V=NVOcBQ>GP5R1QhvTBUiqWBD-6z@4;XRh9Ca}xvZJI`V5OY7YZ zqtbY$@EHj@UyZWTNl0V3v|AHVeXY&8eA+xQip*@cS12J`!W5+U zZNc-p$lc|R(k(*Kj76uHz$jiu@Ib3bMTO$O{RQ<2(#l3TY4)?IjEh1CcEB4~pGeW+ zA&=pmBAwu3@}kXoW+3isehrPFMxHL)H8bnMMK?GiAB%Bo|MeQ@OAuN9PP|2e3Jjtw zp`MrQPiXlK9x}x+*0y0br4<@xn(Bl53D}&_J)7@{L=4lgTjySlAL^#tG1rY zP8?Rbk)i?u);{t>Fw#tj&7Lv3HW~gj8Au9+JIj}=o6h6q+cKkW;$+m0hfB_*>6w`A z4MXcqSYLLF(lpexLe0|ZR|BWp-^2ICgC7L91fRn~Q16(0vOTDF0F#u!fn#A6r*XPR zc7?vRU>EqX4k+hZ-V5HXzqwv0%EBKLaKM^>SIxg`@pH5Nd^tSQNL1hE>SW0aAePQt z4)F}JBs6ZiK=hLez~0_UE@EW$C~U)>O5*_iCRby(dNKnq@I3}ynE4n-lc@;Ol}Op5 zniE&7RMuHf{Y{LM26v`>>MbU?w}iEc^-|I5pmaDv zAxL*Ona0bb{ADGWz@SMu%L9zb>_Qh zc9=pNt(x565}nuXcDV@a-n9b`eYz+6VdPSscOlbEwpbQxhbvrbSUen)nrcEH{Yb6x z>BS82cP$lw4nZRNF3bxfs1a+th)Xm-y0taSeFulE3E5?TngAjO3kd$B!*r4u^8GKa zZtLHpgK7EgBbkx@PJDv+>F{`>D~Y3AOUA)=0fx>#Wx0x?GtasZ(CvVNLHUD53A*Rp z{87B2BnxMfkat3Bq{i?*=6Vou*RhE8gD-|=wDxkV)_xc6uF~B0kT!hG?nlTs z`6?nLESuTtIM__@hB6hqajC-EQ2&nUNO@ejgq3^9N8zxBm;gkAig{lE$Jp!xPEeI` zEzJ;UHJ4hHBbQ2?s>@A_tnOYc9u7d4P?J)%Vc$8FECS#Q%9q?@Ot)fP-aUg=%d^MD zX;e%U*#@QyffeF{$v{+5{n!XCAL|+^YMf_KlzsB*o~$ZA51zLeT`xvlur9liXU=`~^SxII)J{PJ<|H#tQ$ zIM}~S?u7+rw>2!#@1lABi^>R=J;&#x?)1cCFyHx|P}FOeIM(JlCyoX={wPsTp~aR4 zOPA82fvgcWL4A`_7#&_uUjs>`hh^For_RWmW6Pn6>Y(^pcD35kd1U?$H>Ty%{=%dz z-uahrO_mFcVzcl2=I$Y#pgi0C>ypSeTxs+`mRd%}If76<30j@NxvXHCxr^`Io7$ju z<&aS4vW<$u?#3t5vCnw!DIH6KAY;b?ID0-F71TfZ%J_;&{D*9Rxu$`~PTsDzn+ALUahlRCP;9zKg@$MsaQ znUlqdY{4+Ic{_`#AUj1gUc=?hkQkN`jhHyHY(=7&U7RzRJHkVSgUcu~+Ga}wZ~&0&`{HCTs(=HKAe@h*@tqTv&yZUOFmMep z#1@d_sG{6FNX}k*3X1*aMqr}?`H6MJ&`+9PGR)c75hZW)ndC%ZjoTEmi~eR|#K|VO zN<>T7M)?X9*x1?{9@n|F3G=n+a+vut)J0d37qQV~d17}DtePLtLp6I7Fpj_(u0=N= znKfiGj1Zd*!`J0-P()~;T~Bq@qO^L~+g5C#c?&wqiW-%W+jWTYjJmteQ)FK7N4oH5 zkZl5D1XkaW_UguSlo8L&th?JfT*q@(zHedKXUt z*i|vs&FO|GaH>|m-S&A8vpMNp=SU#cO_=>cO0=CRIEZ3mH)Y7QLcYM|X=^MI` zlcS3ACIy@(w6|;v1gH^Me;sA`UhBa^DD9p@ozV3s768W2`i)1soaNtbTcSsm+NZSO zYwNRj3SVNv1ifTEx#DdGq1mrG!O|#@^yIdDI4i5Re5w92#%N_Urp8!-j%Qt|sdlt2;Gfd?-CDq_ zKj_E)j0M^^>Qs#m2CS~N3Gd3XpV$6@u+@Mn9pAeHB-Z-pXs*{g5fNOxSt;?LaTpik zme9;kDogQVBHcfyb8w` zVO@_bU8)?^5ni5pIi70qO>Jo{D7L$F@C&hhW-^h_+Z1ogYt#-<2^;u}cc4`6`Elu| zBhVT@+6b8(fDIqwc80Gg@Ta4Sgd;WMn0u$Cn|TQ)w?|bpcm>5Dt8K@w?}=vslr>vA z=Yk=RfCvR|>grV?dmV0(1VA^fPL*|4Sc}n9maP9I@YXqrRs;60xPQnn#~)-O)R$tk zYulRxZP8DMLGb2~c=5V!+~{h)0{VQE0sS}GEze1VH;M-wQYTo!anl{)gX9{qYJLJk zZuGQQIuy1z*YvcO9v33Dwe668LBxkZo*`ug3YriOKdP8+I;Rpmcy=OY+fsWN{W^lA zZB62FzkKNm*j2KD!$>p22=kEq?A77Qw>V`KATmD*sg@i-G(2dvG<|JJjaszpLh|Ld z{G5^V2bcny%83~EqCF+DDehfXpJC25jF#PU(!d2Q|E##9ZL3{F&+7d|*jy_Qu!^d? zER(p>px-IDq_IW;F1jw{gOG(j|s%nZ3l1kyVzc3@N+N#71s4 zX&H|05k8h0hBqSgtSgwlj^*WUyq(`S8gmuA;O|337zxW7`bODBADZ$(vEJ2s(cHMe z+Y>h|FV5^xMX10V9*nNq1YE;DJv3Pg>8V^Zs*T_in->6}gA@d)Ke4l#j^$Gzr!lIF z30)aAldRKSSR3Cte8esK)CqLZn})(3aG&HOw#E_5)ZVi=Gpeh1z!w&DZ!H&<-!V6| zh3XD|8d0YiXLOyH9;HW65 z&N82MRE~B)IMOTQsp@T_p2<1QbF(~uHapQ0(GgD8HJ$bAnWGYLBZEu7nFAQ{&B$@x z`fMqzJ=Ajc%6179LD|%?42ibhU0h-Rk%Ta(!QRyNVP&U-jkG2!nhz``gNc| zX@@tTRR^i+s)jc|+=Yxrhmwu3D764RRo|xmp$AE=W{KqkJ8@RtJ}GiRB2GETr>S8K z00m5P?d2K!uB+f{yhMrkaG1yuS&a4VyR%;F*PFbWY2|Zk4a^&Byp(O&3F_4p=}b?vsQx0qEB4dVm<&}+)4OL2MwSayto;aq ztIRj&)n%*V}} z9rsjmic!MC8+4NSOJ-urVc$6<#z?>cj@Y>6tv%yL)k-rqK@YWXpbaV<6kaPsfWAC& z#NQ{HMELMH4-LoIUN9etvztp{nWf2BVGX!k)2ZXsM9^Q$PPzU;#4h%OMpHc^B#?d( zx^<2HbkOekgzea1uu1l3f5utImJN2NIRQw_fZB=H0#N>4>No{pW8$WYo>>eqp6HUL4s}H=RulNky0y_pgVSi|}YAFz}1zq!20%ihIT+Gk$F@ zU#@UEuFilT-9||P-HoGNiBiKUzPJ(T!?NUSUIIT9=_X|}W{n;LfKgfe<&Jzv^EI&d=F^Ny^`irwz~i96jMSb<{qw zd?Bu<9E%9CXF};RrL?QC-q9Uj-g~{R?tr@%o1I-OP7ttOYI61yE7w3zy7`}b>GV|J z=@Ld{W5zxTl1{cJF2^T2vALW1MV#-!191y{2`Ga(E!aFh1~=ZJAW-do6HmMz*d_!1 z=rVf-tn@V_!SsAfia$eyN#M(lh zFH?<|Ma$C4iMjL<*ONgUmLz^(5-rX8D6E21cji)X})gFmyN71?q!ZyW4h#YSsyfsiLtL?6x} z90s~XnC7uoHH*Vu9>u-3byDzwI{raY7jSEGyoe8~yRq&$U`C^0V(y&^{&SEZU&mzw zro^lR(MDCUjWpaud?uSU6otL=P|aE9cf+JnT38-_ASeX2Ew+O`JedK*Y9a{E{(JS8 z1n5%oQ-t55%ByZpW&hVo%gU3)T^wW{66&rjOOw-G5~<6KxT4C^BDEdOH-7v`k4h!&gdl@erSIC)uB*Ntj@)d(>g=&Z z+TS%Cpm(Q7VcGm4Si6a=Zde388sRzmY~Cy62?fhl=iYL8$V_5o6g-n8iY` zO$4hZ;?!r1y2mJ`O};YO&n^6$StiXf@j+}#K`mS1KjbAl(#Z`z4(mk6kixjS!}E=T zjE(oN!P$10!iK8WH(`uwR?ER#%iWwfY&9Nt%2V=x{fx$|Db#p_+~=WLhcWQSAUi56 z?_on@)bt3-PVCX<=9ggJlfJ+>>E%Mq2Bs<3C5c$?=h?EwYe$Sk`bn^~sW@&vmr|R! z4JG7G8jMqi=sG?K!n+p4qn5W*x`Y$R-()`olx(t zIdoxXu~Qm0^WF<~=@bkD&3EiFm9LJQf1Z9FKY<@YwBB`}Sa}x+xka85#Mafw5X9E* zJ?$hHs%YpLp}R%$^8bjt8poRNzCcmqe*yTiuG;_EF`nbK2iUi-dPlYJ#ERtMEgEBZ z%DB6+H=}w7D`PfUwHU%5(`a0(R*XP{rm%h#^=x`LZL-UTyJWvRmfUw951ZN^VMz{E8cQqk29ik zP4kS>x2+`)-zQz4t9JuEb4cufQI0oiNTR8%mgQaC@!TR1ful4`O+}eMA-yYbtF~Y1 z&UMbo*r(lr0Sj1y!J*C4G=6!|T)D$wI5+d{GW%k8mydBRqwQAVGGER|T zlS6?XkeY`NEG*}=E@P!n^B~B*o|+Lh-%{wDWCFRIte#yZI-~+4$`UU^UWqVGA)zU@ zx&bY!!^Z(ti|nE^bzMSnc{QCD-kK?_%+F zybI-*!*Z8C7#TRldYieF!7_SV#|-Gg*#KePgnzn3_}eCIWN5H}sohP6KSjzp9A6a+ z701iKb=os%>Q^(rqOz`Xs@PstpM@7B@NNAboiF5Cz z8#*^Z%8}o@N>O8g^@ua4m7wj^9-nDII}k@X;7mPlzh4vFSBS~r)|rf(gL#CEUy3qI z&cUXD!oYV<$zJaEVOCa+5U7D~xi4Tk8%*;0kF(hvT?p0Z8*&el<2hG+$u9+#k1%EY zTuJ52f*nd3x(qf5lIVhk!Mg?oeps*a?<@<+Z9hQzwY#dB0SyA z;~9br@hUUj1(Qxpp4Dh8;z?--G9v%DS_CftdraK?!lF2gPQ!b>chgYx7bK;CcrY#sg_*dt~J@CpGX;M>16R4 z{yp_CXK1P9Z1Z0ce(gSvehrS>$Rc_XM2RRoV+wjwoaii}zB55=9YE&q8fJ-A=}|qJ z7K{Mr#BZF?S!eBsC!!iku`I1qOO@YVdBlDgDC7#e9ML$rsENGX$Lgd|+nooOa9O}6 zYtfF++j&M0UtwtP6~)`XZo*2j{z`|Uqr>GgjmK~b37Db6rT%fee`)UePYB`P>aYGb zTm7emf%!i!{Qm|*U}s?YNAbe{8sz^LLSSY1R|tWG6HMjRX=PB3n)vMu?z3vec}eHz z#np9M=sC6!kPAZd=LpJiWloMmzGx-2sUmoHdcQt|ct3L?&zM%rR`BO2NO}Z7Xp{}~ zhs0Y{Xk!}JI15cDTIAZWjIEa>nQ&yQhgv%!W#rEJ|6uMNgKP`eJkPXk+s>1=dD6CR z+nFbA+qP}nwrxA-+^Xv8I~})bW+FN|=F^T?J66QA*8Z}8&mZrtiQT$3q+VbVqbNsM zn`5d5powxbR&-PpLic@QZ_y|2^3&G^3oP>A zt+s{ITnQRfk|Twv2o`~FN493*Es4y4Ra302a^DVrn)6_M9;KO4aZ%?C_Fuz4>Zz&7whNVzTcRH-yfpeDIS_h3r4N5SB%9V^um9&MqpW@*zs_o+h zAB1jhCK26@9GLDL!c`o}a4#4qa>3&HF`Q1-n!YgD)Hah#Ww?PFNRS)s6m4H(k4)vd z#RvQ9{jQ$+13{MshrvywD5ps%ML@8|&yw(DLo-Allx6wST8+15;heHXp3TC@sRRes zk?W^w51Eh(zP@78r=3>(C2R-pd$&+~4Wl1kaHI&L9P6L$T$N|C8gk8Q+4{3`9WNlU@ z4I*Cf{-PE=0vN>2`28%qa@iqVu*NZAVl;Qa3YEXMe7H-K4k7aMb%u1|`E!<BRMi+M_|~hm{{EXSkE?J2 zw0_yzMenR?U!ib70IuxK$!npe-w5@6ssi~6702`EMwQAU1B8ZZp>}f71+M?2>jNZk zbAKcrwoSxr$;d#5ppb=|+w^%1f6lPBI_BT9ypBwr>A9NSDNM^$FP-?iYsvdLRDZ!> zL>h6Mc1a8tWh$n8euOH^Nm`k!>gqiptCHLJS_Bz~f0-cu&ec$)omYoySTo(p3N}J= zoU+-3i!qTW=zMwcfN}JvGTo~Aq)Wn9O%B_FhHXj@0b`#3OwYQL8JQmo^PCs_Pogf_ zD8PBqUFV$HR4>DdI{bOmsT!UI(~QMF@~*?x@(YIM`{%TrBOyqs^pt98XqsZKz89~{ zK@US2s4GXorv4VT;*tAa;j0=xe2X)T7_6#k%E?~oxYL3W?@ArMruuGd*|}< zxI=ZS^a8XkT&jhizW73{Yivnr8~NG9FGBW+c|B%YDqLw?II+MkC}W~1fhr|5xb1!# z2HjYfT^C|52cX=1OzQa}QYl%nZ}B{PRm+7TMT|2X?(Qv1!W%oiLs;?(j$J2qp?abt zFDYEO{9*TBfX&?OQ|(3%I z?E3cmYTvXD43M6iQ0f@;gsr3*vjg?;ExjGo&?{0-cqOZLmI$Dc5r_HLLGnaZF@lnp z=9xhNF!^b#Yn}`#q4LRg!xzsF2oO!p1ogXxZ&3vIZDK;Bh`I^XK#` zmtDO5?!(b}mhj(*P>BVE#&yve(u*2w$GZR&F&GXG4kCIk$x-!?9T}OT7Bl3Z6rjH+ z?D?N67X`;|?KpWyyHO)Td)|6M7(@3d*>R!9Jo*g{58|8J%x!^cr>QdxcdknK8E53- z?O>p2Gu;yNwF(EonvTMD7}4KGj4sODNT9M#gtzBx=p?-S?XQMOWK$EAz?`4B_vxi= zrhd27O<6X%>&t0`iP1;~d#)n4NWCY|$-%`f_~tGF_8pV1uF~+&=^g2_pRW(jd?mRZ ze$ZIp>dnhEd*zMPB27F~t}b?7)8Bg=9nJtn(Pux`#7EEhm=Z2CL=!+JLiLCPg-l1d zlBu^oj0p$lxKvtljY_9dk{Z_q;}7lIA-PA6wd+PH&oew#Fx!yrJJfJCjip$By;4-u6^t1}y*RxBua#kve|f+iV` zH7w>q?pp@$wC227(mlGqx`l;X#TaLxYJFL$rSof$qiC!n1>eJfRj?VxR#d$c$U}{G zw42>8BCJX3+wrRrKPUBoz2W7unSE6XC7h$qo+D20*8pg^XGtS(+qF�NGO#cq)(F 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

+Dl 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%0DnE zds(8s@hYI#v!^Y(U=+ect5|lW6QcLT5)T@X3NOL=AwJz_f`0Ly@w2$~ZKcM-JsI9i zUu!+AB3enTBEJhP$%Ap0yUEp%mJR>t-jd2h3c)}vI$ypZ~SrM`vHyQQ;&uv zlSfJ57$$I@bL@19f#K$ooO4W@)ORgdp*j)5^e^dWS-y+jm5OzzR{Uo2K1XzA-JxTF{&lFZdYcAq2L z9pM^e4IxQPO;iA_%SHX8r%@2~BbV)!>9t?zsmH;}6_Yc_$bacxJTo*7{h3kGT=6O& z2TOfoz220-Lrlhwe(w=2JAZZ2TwZ|NKoRc|*Wh1`vL5ry+D_8vE!8RR(v7MAj)=jX z0c3N?=(Lp-CpWaid+qqxr_NV~n9&MqFil=CTH&<_Tm;ojmr^xZB91h1NJme$dep8+ z0twNVS26upd=5TBFAh5JqOV4C_9la_Biu^lT3Gx(Y`iVvxlK2@Q@qySq300XCI0Ge zTh=l8i)%|qX2yQ;G56v5&240IgZ{kqpfFjmw(a}mwV0$RV7W=pYkN05Sh&6|3?QKE zr_PUW+6o0ki)qYqXrBRYa}kMR-ErJ}G4vr6-!u((!!|INNXG>i|1~K&gkwJ`X{!p*!rY-Ic za;Ox%RU4|hhw}Fv53t_)_ED#)T!Yun{DSG@jWA_MvwR2dVzbwBN#H@#YB{JrZ|m!0 z)g1CG*$o%QD#GHzo^r_)+$7UA6ht2%0NICv)ZvmWN~QAKQ*aRb`<5z=@*;X8(eQzv zcQHx*mt8W%FTE(HXy+nS0hi%s4IRywWid8~JWp*x(aAlg_Q@$HL?c!$N@rw0lc6U( z9ipCMR*Ux}XWOWQ^#XKV-%h(RH_c`@KWHVA#or=(b34$!W(rHs+aArI9B@xn1Y0Qy z2Z|o7VLoyLN6swwE<6n$w7%W*+lXrjTC(-0E9%rg4!^(PgZmIKD6H5Mn)^zm8K(ID?9BtI;)V$iOw5O&FXQXkZ+!F zsaHU4$EQ6EH=cK7K;K@T3l<$g^c!&YL=pvllxt1B9%T}3ipp1fIVK>l!Njm!dvOEL zTY(hRBdkN$T-q$8O5+-y5O4Eopye^fCEkwY4`5C*PxKUeL-H1Gxx*lT=kGau`^qvs z5RR-nx%`nwEI%*cfZ?uQ$%K8|7sdlB9m;^@9j1tKG7DCRIg*aU$bN#v>v5dJakJ?8 zY`ciyk?Y1c15W7|l0gFOn0s5UCm#6*L+WE98G<~<&E+hx=W0d$JZ~+Ml!0z;AV!GF zU)Ic6s5FqB4n*46di4*445FI)1Y@q4^Lvh&C{ zgIdumsG_ebM6js1Se6iZROH5XFDqRmf(0sU2HEtoHoN+s%c*HBKZQSxoT)0zqpIIK z_#Tz1LUK@Tc-knxvYdHat!Ze3Lb>kOG$h^5J8f52)azPi&X7R7g&4T2+<#=e5+jZ> z;Vj9w;1)Jt+#zr_u|2ydJIE8qU!T)5Tt-_ZZXyEX1+2c`RXIwm(nZ7}n9xdUu5tie z&0y@WFO+K8;gDeF*s7&fX|FPpqob?lFWXOn-3c~ujuJ3Oj2o>GcXIC{F4k^uN$wKe2arlBeX)z z<#+~A2G&%k_2WzM_M5fB8U1g|78Uk!9e4@W?*XakHErm|mx;tZ$gs&pGUj}jrZDC$5}iF>PAQ;FcQ(~39+h3QvsCh=dO(G&KvqPv>We%1dqQ6)S< z(1aQzOm6+csPz-Z6gU`9_CN^JAwwP(K6MlV6A+xKc|dY(D)5(q#L)m1l>#}MbC?Eq z`{RR*EOSMhugs38$-2ht`y+?{;C5f2$|Qsw?1qwnu1$OxK&dWmePXxqho1t_#f5P@ z^graVKK|9OW-P8pvv5e4?%UT|>^jT=Fay%1-}|Z;D5>1Sf-NM3AY#1j@6yam;&TLX z-~zUA9CVKG%FKmftlbVWZt{xTM01wqwF;_XC5f_IO_$!7Ixv4lx%} z;uz9^sa>yzK3^wlaD&7Z4ciNW|nuv1*D_h$Vm z8MuX)mV#4DUMe4{8oCHyB@b9^3*}sLUIpP#!%-qc%$$xw=z51 z99w^Rf}1@nOLqTRxZ{C5-$o4nESkbgmDA}@mQeiY=D$1d-@`#Gx(dYc)JZxJ24}aM1QAaV-hXO@G_|TDL z2_Ue!mKsdWogEncviCfQ(9?gDMD~%E_DNGR-m*JprTj4X!V2nL-{1Q(vXv>_rKSM|j#_;}aP4tCc`vZr%ZRSGlf-O`;u7dT zgSmZ5+)x(D4$slwfftP^s`M*7X!O*REN(x)^q>gssp%eDk~K0uj}%>klVxH ze-?W+A;6KmUF&?<1i9iCR0`->Blfyp@+&o@olhv_Hr;^MG^wa2$sg8~5~Xc&dgbPc zlUzUQmb0WwpY5+EPb<&dgND&T)?EmvXq%P@m=)VxtaK7xx_pF2&tUZ9YolPd4AN#T zW9&7X|BAumE=lQuELtjb%?;06A<-b#JoZBs38;eEYRUd7n#t6Z50=N#F#w28Yv!J| z^=*-%C1+Q%=O}q{X%W_vqz_SxT#l09u#9dEAMb(=Nr1(LhDvAV(!6mF=~d-_I|2*( zyAgPD58CJ?3B@StjtAV4X0jEhl~x-_M5sSo*1cojUxVMLM)dhy>A^bG@f;G)U$NI) zNq4QBZ>G+~L4}h%PZrAAG%*^;-G2b!MdvPh@+MPy4A5Bg+Z9oH`y_O_VM zDu^bcz;N6I*}>hu^6VP5YSh<4gP7=rr5N)r^NE5Rhdf%&s6TLoUawoY>c)uf}j;+Nff6mPX4b2+GT!})#O4lu+3`*p7(g|_2^QxDNEtr{Dsji)I1+Oh;#v zd<|n@H%EO|Hphu60Uj}9D8<7k{05w72zMtw?e)ba-_n>|J**^7K71O(al&m# z<6R2uMpF@#YjrR0pZUgNj3CiZ6G=qnJIJJY%dZ;p-PkF262l8ua|8zt6gxT(*TX9; z(srmZW%!N0o^*IN{!;8qaFXvPRjuoK^yv4AjF)roYp+3rh?Kw=yjn={io1E$~5#ds;geE*`Z#m6d>V{OWJtGydbD~$>KKz@1nu7 zw;2-O&p;HbbwgjZ_p>919w1r0O zAl0^<(yokeS7|~+y#s~IqtwYD5y|5G`UqLpePdTMnF>=Z9YE7FaEHJag*KrL-;gB=iwL| zk6&$;T^JaFwilwZp3Jh&FOU8ti zl?y`UN+FP#2Q6AP0Jiw9iO|-%B&}M`DWQ|KfTsrwiV_&9|8Oc37LNsebD3lmkwKVX zUcYG;weXtQ*(3hXnM|R6#!+PjKCE+CaBQLFaV|3_)GgkW5sA0rG#L0+qOWgR+yzm6 zJ2Dq6GMX4yyjoV#lHU4|n#~gEh@jRi1J)9)6fEFc%h4)Z ziG1+;7ikp|1%vi-LiCJEqSVJHMcu6euQEL&YbOTB)&j9f%4sBfsGr;F`%gBjF8M08 zvh{;lvtsS}1~MZmBD@YDbdnGZ@Nl`a%)N_1lq*oo`HjBStzPzr2g?lqctGiKX7{OS z!ADv|MCs4fxe59NxwN};Wxq@SnwYqC!mMwrYiTVI!k!;6VI}u#N=F?CP{UPcVba(k zj^v?EI|9FDr8UpgFOu@X|C&CV&unTupo3k0b)ymT@G3!Gc$iJ|PL!a8-Fvs;>Sl!r zg&BUENf)PdX?f8QpMMt!kpqwDsgu`@WzLc7r2BaWyMntLw5^A4{IWG=K6o!Sv9dj+Ieab6*P;BTGUR4h+ipgB<=uAWkL{5%7Y!YtF5w+s!1!Di)v&~>mY zI--9B6FDk%%)EHs&g7dYZ}M=0S$+~!pdfFca6QkFBUhrkMf*inBE8XEn5jG%M$D!G zr)T_J5`Ln z;*Hb=EIBmuy#YCT<(oqBTox)%XSRR(DvEAA(NWe&Fu`N>!RH=@de51BcO2 zNLLcq`Dhc0Sg67)th#V-NIx-dOu>6jM?+6=k9X@4f!RLR74&tYQ}r3p+$%=G%Q z+hUbFu75}ds2tA_I!XZ7V%cq(8?`0DYfTOtW`L4ny%hkPVHcLRiXS>_kd8I;DyrWe zP$uiddNGIII{#l^hJ~M!yu+U274c?uXvnFC!s*|uK3pw5SW@j#bnt2}I~kH(ExIn= zo`OlIjJ-54VN)PG!zsHaOq&u4*ro_{qcTPwF{zJ<==qf@>RxX}q{1=5GqW8W)dV(X{*@5#||fvb4$3@qD{ zG^HLT^anuF!fYBt+)!_*Ck=* zacl60fe9=vWYe=j0I&ozLCuuext66LswxDv`}c1%Auz1_!F!;p0LOzYnwIB+L;~yIb;ngoKWOsJa>;)--XllB(xZo4sXsnA=&!+Vu z*M^=m;t;(yd!sQD?dG}|KKFUxOPx~Wvx?*X+XB6K1;Bj_NUQKdtemLxN~IfH{bBCfe7868e8{apMhPsp_8KfH2TwA`XlHeUx>v zwssixM-yZVZP8HRRWUZXN&nIQoLB?}gzF;4_#y?S6uyA*0rNr~y1dI1`%bi4%>IZk zOIs-lugt}Ns+=@9G}<>!a-b2K0L{Yd6s7@RaqPr2ompdR$kp=tyR45a})mQ>LI%^g>z>DKk5{ zMOIwQ*o0UR2!&uIEwgkILAyOj>#y1z^!`L2f&V{zbS$o?HJ#gkQG+|1A^luRFxA7* z#}>oFx5w?+qP|^ z(qG!PZQHhOyVAC8JNu5hd+-MDKkPxAI6Kzbk6E*G5HEhv27r;x*mSJ|Rolih3pass0`zOo2ea`5O=c{a~aoojS#Y;D6MVa4|&wItW*rh9NzYVAoTG;JGR5)(vmtJ zW}>56J~7ltE@hnt$!&-2Zk&H@;Y`olTUycVHk0go)mc#E>@igDBZxg38e(4Lu9Bp? z>mSWS61=&&4RkNe^|%jWi67+I&WblCw=~&d+Ig!8j;<)K0_p?IE-s-14nI6jwwb;Q z*-+Sl)&Q5mS81}?`*F%~TuE8W|8_f02G5)FKwU)7Ir^g0Bp3CK=c z#`U;NaNN4%_~o7}Fm(}K64fdGn&0unj#^8Rt%wmWH2Y)z+!Y=|Y>@*E^_h6SVcdF4B8S6=ciIxe6){JE|(LOto zOX)+m6QraONtNwP$Pf5&b*ID~wNGY#oXaoCww^#|S?fbQqgex0hwj!#|+Vt}@z}*jjae@>kb+MSP?fMov~5;;j>OGZ~1y>6#8V{dL~Y639|P z)5=B}Y*x2)x^89S71qlhXKZ)T{1q}7kO!08klG)Fygd-Z z>HQCryPD3Gp8VlE@@NL^`opZQlds^6!Dk5KMfNdq=5eIP!XWg+Zk2T_z+ox`iu|2q zQz*?clIBL;{k8e02cOC4f!Qo0?hy}=ik?JJxA6C>bzkaN>it2KT4o7!wStz8Gs=`R z^RGjB+U+QO3BHA`!(H?q7*?}(6G4aXkU}^R2zXhnSJ?K*Y-44Hu&vV(KG5A!%i#H) z9YRX^!lcd?4)qd?AI(-%*+z#7Re(^C44f}l1^R_avef9M$yz&AfRa7L1dAWQo&w&) zU8q|sVLs!|D#0e@_1eLufQHkx*SgKjcQ=Vn4w3P2)qDO4&&ASdRjZ!+04Ho(gz5%* zSCq9@))o`Y=(vd=;?$(01`a*FFO1*2AppO5|aV$hu@Bk0)!HC?m zKwRWy%9ZLVmuGWNP_W3{RnF_=aRXG&Q6i`5 zxmE-vynYe1+y2PkLzrCAf$$)?s5WgMotMTuXUL2>1aeGGOPYPm9m14VjPE_RR>&*F z>~IeAn_Tg(6g&Ibfhcg=*9M(*I9oFs#Js^waS2C)DigCGa%0gHjC^>%U$zVTYL*BWXERB~u|Sl$zd;y0{?Lsp z3R+#4Kol&RNsL#?p@di&Eo{4B>uNSdLoS}w&UNg8Z#HVOA!D3-nFB}u5D2IMX59+rD#w$iy9 zV#?DhVcD6Q#u#D6|(IDF9DDu{$;>inNEGQ0?fKH4su61|mq&%hfaWX(j>lbU>6 zLzDW}YY`}KM2(nXyIa$8*{z@6NMI0r4c*Q8UkH#{g!j8>It3NDgULE z17zuB6e=?;vV)LaP0}&hg8&;6P>=C#_kO9(ForaV(DTWKR(eY(=%Ty0+G{cSXXBW# z@o6=9yEd4SDZ;xboE?YE5Uz+G+>4fX5TC|?n*Pn&>qBQRaJEtvn^vI7 z!Y4q6+(*V6CC1CEmq5Ati+6dGAYg)T;--X$Lr`xaA>|Tf;ZynYa@LQs=I;OwSTAQg zcCOHkw6a_6^f1xqQY$T`kygN$8a;~1fqZ$D;)yMsX?k&JIE68gclQdc3ud8waTANR zAk#r&v@wR7Qq{WpzC=+sDjM3nkdg)(#$wwMH;)1xX&NFxu`PqBS5_>&QbE&RGI}gK zaE2+Jm>$G7vL{iCmy|M~ag!T*c0V~9je>S#l!V#-$fs<{y{W+?c0a`k|HSd|uqOPc zXZ^t;;`r<%$DO@ft`)|H4Rx{PvEh#fv;ICPp0Y=d7R1ahCN4M_1ahkQv@lPBVSIu% z+|Tx;Goty$GMirl9qkp~t2OaRM@)H%?ymy)HIPe#L6fy_9%?`mjY@yFNy|xl2A6(U zU=*zbb-+PhTWZXU?)}$yeKDn4#Wv$C=HTJbi=(I=>cd;=@bo<$(DLF?oN83A@&_8> zWLQwn2jOD$QaS}XJxu+1YtxUZde>aq5j!h`55vLiU(e*X@(|OZzuVu&ql)z8M4gj* z4Y=RWXHww>l3o#Q=QmX}h1;rXxi_VPy55`W;U1-ro~S1wiOT`~Fi-^&n{PBLnh@?Z z+}euqNnUW>-g!nhYkXm_6!}-T=E4XuH&`S#gJ6)LT#NRvpoX>WE)k}6Odh1ODz==0v8^&I?H1r01*pM<<9g^Va39qP})a7u6qX$AQ#g= zaA`+~FZLNSW!jK;_eC=Q-kLAxDX!6hV7vw%hF@Uut{0*ui=D7T6jg^7A&FK}LxTsh zga+$C@HXv3mCA%@+k%hammf9^jVTNer@#{l!AReH(~g@ZHxiL?uE4YTTQbb>!~;o0 z!t++ZbUgOV8aZWRb){6SW60RoUh`m(~$`^ zU1W#T$Qms9S3TmmVTklJ9@5xGkrYoA1VLs67WvLRC=3LQmc?ZCkKwi9Mg(>Q*NyoWRuw{HyJyGGh zg)*2sMyI394k7yTU(r{*L*wv0j9)9uODG#^C~a9e({0qlZtFQ8*JK|2cqy8oO)dRN zP{Jw`)*eA-f>;Vp)ddj&&oI)0n=795JZ&w9z<|kdz>Lsfg4)>MO(cd*_t{NnR)_nt z`9rwpvNcY=!tq{jTSFxoC$xf!6JW+2IiumIHnj4a%p0ddabtB&mYdod;lv^>EduQR z__VI_SEDLac;}JrD$`aBnRes~$a;PA+!bDi>GLFA89Mk^!Kj)~C2q}RkPwbL+m<>M zl^I3^&*K+z_o4RgB$N{XVU3K?c`$lPaets|R4Fr7^_Nb{dONb5!HCKnQdjIMS*$LY zVklYeyqUR}!9sAx5z+_8dsp$BlT_h7Q7U3>KHKw5o-0b2!zSYC9v*}mSGphAm~(UE zd?LNr8fHgm)UC5tBhoI|PgOW|_F?-g|G3S#5qqSJ%)&`RDmawDgd?DO!(?$ZhF@>; zb(@UIFk@q?8O-WNKx0IV?-?5Odo@pJyBpz3SUop?R=+?Z1E1Aq;KCE`CgRRJT|{aiuApVESXvAD2wE+ z7}{3i#|(g!!`wH0=lU`4m*fCmfXQTWA+M2r>^+Q%Aqc(SuW|7})w0ap@kjw6tYJRk z7b-iv|7IkYXZv^KJr-AY0kSa&mf94B2e0xNz0sdMjN}xj_uMVr_dGx=1$=h=L0C|5 z)gO0kgMv}n!anB?ocAGR9a&<|=MoKJOw&rkF&y`Hl7z^qxD;aMl zw+ndp?!~^EL9kMgGJ;cfL!X0&022YSvFkRoiW8EO9WZHe=TV4sN3q<)_iG8V)=m&K zk*pt;r;#Dw(pt8{&!u26JoeC7MNgHrRU7>LkYQ#;G|5gIP!V%ck0e4U?vQ-xp=dL) zQb3c!dpIl^(+!`lL)6R9fq$&3X;SXa8{ODRhk%T3b~gyL0kcKM9_2zYd4^)+*4pOS z0c;sOz7b`H2+pM!Q%W;xnE|g^DHOe zF9e%FU5|JX1z=k??4qyR?;|zv6!R&^3CvnF#fFIqt9)LDvd9#htXu|7^K7P)6qh0e z?dXqa5}0-2BL7Lq>_R^T z{B=!2GXeNi+Uf)E8i^;5m75A|t^sW@y?;y&P4wP|AN;!5q4lXB*oMW2{mA+sOgu?L z=zPl2>iTuW@iu3p2bg@>lAiukL|+2m{03FemhXV0Q>|^SBXG(e3-hH9Ls%DO8>fC4 znMv;7eS(8qKM%)+H!C6Dwk}pJIyLu>q1-4NuARCt?9WQ2fo=4_KFhIc@Z{*L$X8#P zxaJ)V;vbxEw7gW*x#ONAeL>}#=`gDpjpVQgEEx|6KpJ&q?; zyb?C%;1Eo_|kz?ws&!%Td%N27&&c zi+A3DnEP+#8_!&zr(hWthbmmzZTvhS>wzxvf@&Tjx5<%!8sd?UJ3d~gIKuNO%8e=_ zuI9fJSIAbU>vG7^vn?tn+esWQ^4^$Gx)&U<;4nEq2RrWJpBybjvFbw$eF+6$83V}g zBSC~MV5?fvNdqbut4U#+VOQ5-$a&uJC0d4c&_(kl;IZoLx<9eaA6H{ z)^mR8qsFhwoXGh-OVU*+hd0uDaUXJ2-QatO=o%~9#*wv=b)RLw`h*LCbt<~kC>C4W zQws$a=x<1>rv89qZpP^v2{4`rut}Je39rD{Ep6xFx!wR+8NvNtLhEhyR+LIXr&X7k zL65}n`;W6bxTc^!IEJ<$ ztP{!$IYhp^{kAdy&%(sZb9-|cfcky~iYp-B_HPjc@Ltjyx6crGS_jN+?~7aI5x>GP zGkH_GqVw_v{A33a8!oF6aH?MT)*$%WN23zJl*2hZmE3oR5&Y5cIRK0G=MaTM!teE8 zL?b6pofNd))OU{@P({H@6jw2JK`T_6Z*H_l6vcn98D7Eu{0vd`)05|U|6-vI;andA z0t2)w7?|=8hBLp}mIW-zlFl5l;<&LmiJletKfgzP^7rjgY!dn-T$ThEO?In) z+rn9La7ss?jZ5o_M2(TYUpqiy+%ZEEzhS}~#zHejbu%m;6HUCV&V`%_-}b?LGSkvj zJURRq*uxjIU>CQowd}f1Qpy4$BfS{L=DiUPkcOaG7-F&2@4M8}{+Q2ikIyYI0ZNNQ zD)g2~Zh^yEtDOnKJ3fEo;q07(4~CLjzQ2jNN`|be9Sy7eMf2)$Fl1Oy)-1dS)7V_P zEbQL2{Q&FJh_uu8Ka6i-8?#=F?^<+Zl4Xe3gCC*nG>CyEanPz5^_Uchb7L?6q6%2L zG(9F#DwonCru#@;eFv16GRRZ%J4vbjqGVm@rls`BJ9-Bjh8TOrX)tT}4#1NR+RDx7AK@2Z~b5ki1 z@5qoRnf>CqgF%UGF~4)lE@Jn|4lp-P=t{m-&H1mNAeUs16=Cdm7mmq$0`EXg#Q3v$#(Exl!1 zK4X&Jzfe=Fh*xYcK8f?YXX2l8MW>Ey|NG@t@M3~^l@}v7cX~;a3(H-f@-1IY>;_j6 zTq5Rw71|+nT;};%QjK=oyO{kWF|$6O*k6tRU`n zevS{k6gXWB@pY+B;pr|X)px#I#;Tlfcw!^iSxbfs) za$F3?A;twvQ&P;FdYAJlgqQ4p6GPIhB7Vt+2jNa)SH;db%YuTld$TVORjj5eMCGq_q;-o?-*7dU^lA%(#CIoUlAdt$PR!eIZm^@gezQT9!8)fyR5*`L?EZGsmtbdbTf@ zLeS@^#wv(!0vZ~_S(j`Xbwj^ z3IA?SGGW{DY-;PM;G0gX2VN^b@{R;rPUr0oMgHa!3Us0)ivQNSZm@+p>I9{_&KiAu zHD%->KmFPmrZAP4Hjr;(%i_d#8J!`OXR2{gs>y&^yUu4#f_*XJz5Rov5 z1q0=OHBHv_67ow6ifv47Y?la9Fy%9mQ0#Urh3^n_Wy#6}L3*8EPsTxqByDXWe5y$` z`AmHwHayg#$0K7YtQos|zoaP=h}~6rs@$^p#3R&{L{*Sh2cJV>=7 zFS_~C8YrTnDuOXtErft-yZm*_x@B>>QQ?@P%fSZtLKUMcwUnz}U`cgL1@GS!TIZzF zi4z;~*>)HdV&h(uH7!<1ekLu9BmVLPjC29Up}ZuV3)4sIcP#R)6WiwdVrj#H!{t3Y zXV)=5cob6zv#N8>59>*NH0cF8Y0cWkE_*m7wT2FrpG%r5J8>-mavg0xw@jo-P{l9@ zi)aKd?cj#AWq$KYZ2^F{r9d7t4>uSnKfCS%w@Bf{+KpU#f}~rH3Ezu%rxgCjc+%1< zjg9rB!A^g6W>$aIi!nM>xf3J3a0T@yhk>MTw$)Ia*t)k( z0q0kgV?K<~+=-XSkX?T%H=UfbJZS2?1b%#c?(3~+D-@$bAybg?%lUY}27%9;6K0Hu zskg&VUtbi_)a>Gek&Ah@3A5Y0v5l}px!vzvW!sk~>#&p7JiKag6Nt8@ z_tip9SZr`sM|$!hA)$eJ^L`Oz2g4S&v&WPZ-%8JJMScEMhEEC)Fm3ZOyRjv zCmfhn2SwIZ?FiML^?~%kBcNEOS`6X5(LoR3$1g22do@Wc7BWnTHn?I&C0#Ev0a@6r z8O^Ym$21GH_RaFp(uP!l4+B**0itCC9^Jy514D%`N~D`^TK|HawN*Y~7ti8$YLVC^ z7mvUt2JTW>wgep(CuL~8O0Dc+cC$MBy4X?QQc=IB8iTuN7Bp;WZO-)E4EU;;W0gFG zbIwWd;dH4o&-36>SrHyQ-!}rrBa^sm0=~MT+SLza|Au-O*f*z9ur- zhicHoU@V5{O#2^~JU^9seamQsjz(^z&F4G18OM;kH<;aU4SNp|OH;b`ig2@iXp%#? z=ZyIBLA!{Q8zqiC8$9?`;z6aW8B!X1mh_)74iw8Xb2%>u<*BLgSpk6p_NOEAQm9vK=pxiL>q3~=1Rvm=X|=I%j! zod<+0h#Z0D;FnQQRvV32%{$v_V%kLY7pPv{zbuA#f>yV^9@G67pqw1^m#%zJog;8e zr}wU?G=O^}$qx_$jafT|C%70>x9QMGgyMo5+)V@jUmiBa16zvEz|@;+<$DG^1x)&}0?Lr9)+-Qii9a@knri4WI!JhCjrdkOI={k_2WZ+T zz8q|*=nrq4={n_g8@h*WfGAVb1RHb!NwJn~beLUjI3{9j+C}3pQx!rJX;bbHoK$8*XzO4A!K; z+D3D^g-ym0lmX>jxQTF}E?57$n>&N{gO3()9PBOef)r>qC~Pw{BLm^}IQNJAZq@7f zqh2D)oI_BuQ)eGm$2QU=LeOUD2#v_AypEZH=;h~t%p`?B-9VPfGJuNj#Cna(2uLa# z9FjHdHDV?olFW{f0uqIV{L-P4hnBwzT2v-C6rYR;l6EaCl!k5UE*ZD;%e+ZQ_7`MS zkB-!BhhbvlilyGzXp@>0O`PvHD7ZH^H09I}6AjBFl->ilid`ZQYOb1a zO2b~$*TwchsDEtC9gXUj{Bj7gO8?N-7BwAdIb1D^CLA-4sO$4%1C`wR;?aIS{c8hf zlP2(@d`#6$%j)bJM@tgsw`;no$0-uNfGLrK?xr}$ZP|Sx%xu_nn{m&KmoICqO=2X- zhfG6)+$rEugwr_#3I{7prlol&>bYJT|#i@0!}m*PEa;I*v40;MkH~I-b>}8QHecP;~NEd(|uz z=rOAE*OfD(7L4-`q@Y34&4?Q-Qd;b8+RS8cd!luvjw-MU3SGG$hVcteQv7f`nob1z zwct{TPNtrYm_iiYA}TP=aI&T^rbB5;^~&!twYnTlrhKpy4Ps8D>Rypi8etMu^Wa_F z+%14RpNi2DcdAb;{~`VOws6%G0bY6!ex=IXP7_r4`V~iR_oZ!?y3TJlmtK0WDanBn zK4!*mOKqS)%ShRHYkJE=e*RoV7`MUZQ6>J`C3x~2mrf0GhB{)qSzh%*5tPRcK@6RO z!bt8&(?Ai5eQ%#RnxjSaugA_#{W^6RcGoYSO%x!#p|7mN)H^;U=VFfGO>J0lrXfId z+A2J@)b16-kf-U_qkLgB8^`XmOjHCSNz>Lh(-CdLw-EIDyerPE!4kSy3!#CiFL?lr zAU#*$QYI6ntr*5k__3skCO$(V4oBEke%HiRmM)A(< zm{8IovZ?$^VX={_B@-14D99-5o8fpgS?!95fHD6C(kXa1?$YY}KRb>A(67O161U(G zzq~E*mkk4(W@k#KQ9HuR&U$8J^nkqK`aL6IXh9ub?FWUankBcju%6xsPiP06eQ|<= zg;kNE)2INh5#=+-q3#dDLL(Z>^u4X(*I05wmG$>n)58J#4t4kumODDQdO1pBM(!oW zVN+8UQ0&dome&JhBv#0?+u}eI!7}-^J@bFf|80dC!StKZ@`{U{&%IY$5Vq8H2W|~A z2(^|rr2sqmrG{vjz$<8@o98kl`|O&o8MvwipKEKLs=V>!yA9MwYvhP$FHLo`w3E35c*_nRhE_Ax zxW~i&OtB#-;mI$z27q_1r$uNgx;FCGiKpHQYWOa(?|D=w@co|Iy)aQ9`YG`vqfGi${BU``!9}MT+*SskS(5en;AlTT`e3sn>=d9%J#a@*x(CXjIa} zon|n_>!cBZ7#GxfA28Ea&W_ivsbq$KW3BXYzG7tv{qGY3{2uRDG?7g7-mNZYr?XWE zXR82>^>hN1W}<8HAOS93Q@l;Q7sM;jlbLak`)jUlM$Bdr%^ zNB^@E?;RHt%fD?HbT_abTcCAb*yVbj5S07l@ekB)s3F7-#DL)BJ`on(k_ko zsxTT~_d&F)XIg%79LyZg91hk(FmGZ0#bXwg2iCfiMr;Y9skWfxb^DoMbv-{dB zj|9N_d!5^>dlZx|k8s>*^+5y()&GF)aAy+ z9Lv>y?U#eUIXkFAwJtTRfHQ(#QsbFkzaE!(VH_I_sb{!Gb%3gK(+aO1B-0>ITbt^c zrQ`Q>s|~@RvA;;-5R1`b2`38bUPtJ6-}E&RvlE;6H$eH7^%OR$dc`@T^XZGLU zbVff;?Q|naCfWG&`|jC8sny6iFxw#>a@cfs$M&JfVzO5j%gek+Xy_*N>(wE9G$hM8{cBA3qaD8de1}PAn<#8I1v1{D6#(;$9IE+gmBo=kNr%Mc-wHi=!W7*sM z=pEL#7H;EDK}A^7!jFgk@g~;GHbr4mzl+R<2Yy+ zc6IUX($>y9&iZE@?|(Oa{!wA070?^a@NRlyqJwxIiWLSk*g}aaW46C4k7VT~CD1_g3|1GA22#{N23G3LS2fiL zHW5e(sk>Y*Mbz8q)gH@`%KLZ38e|+!LMWc=Y{MS5&)5aXADjC8AHm025%W5g+NQgj z{bf~zM)VBIgqbR>HR~iOiVghMM@y@{Ex5HH7Wq$#5yoObH+U?)dhvlH>K!8dDnnf2 zk;*%Lwy%gE+!2l3IkuIEfHVp$-+{MsrCP<=Afo(_E!>C(3Ki+fK)D6fN|9YUdK8E* zsH(2dtwj@#&ZM}#KLpr7R?Clp2y1{hn z&!isRA96e8IQu%BY8@lW3@?>%C=3W1YJ9pfh2QTf#i_r@{3ic2XRM^wjhCmOIYIE{ z#81!_N^uHu5Ci?2Wo8W}x|>j^Uq~#Wr2a%OrFFozlqIzW zo*Weu%EnX=tki_n&+B=S&BZ9~WB|H(7HF5Jc!BqWa5-2bWPdh3YzV+pO&*Z(3$gjM z%4sumfupuIc7N`!YHd?3OsD>KHj(p-FO$cXua|;D7+6Kw1Cz`c!Y774De}Zy{(Fal z+N&Ux+V?=?Uwccy2P3*w9-HEhZA=;x_qh13o7*oo5o8;%Po6y_V+>hm!c5Bg=-<}v znw2Ppv;9=W#BeeNn3~I9Ma4p|0jumV*6;LY{MP;l&-lpEY0y(i7NI&y?hbZ`t>Pq2 zTK;(UCACD^Nq&fKAs*NI9CEMlp<0p$bstdbST(WvYr6N>c5uH z27jV;TvVhd=1%{PF3{PqlqFf!J)JK7T(V9Y)G6Zl7dZlCgc2Gm9Qrj41<0Nt5!YSi zdV>YtH-JhkS@oBJeVFrlYu1UpIV()oZAWW-K9sT#4M|s4XL;o@z9T0EhgGco4ySjA zDP_kSI#kPrY_UTD#V%90`DU49!f6HDkgVxU3q>&ZpTt>S&3+|TRH$7itDZ{$`G1N;Uvhc$*GOAfgv`IoB8snw+Z4Dv+!{nZr+OL80N1Ie<^Di06pVv`q{`8wE+2w#p3W^*!n~Mb)6^_- zUOT|wlNYF;=mrA_(DD+k5bJezzk%J30w^78WMGe(X+LD>)B*JSJl@YwzkP*GCu+ zPrS$XFc>Eh=Z?zBCLc*UD#Q&qR`yVyA?Ef2=IU76U|I^|MB?+iac^c6R-6X9a z{Zljb4%Ji5mc@`$dQ9l<%ped#$Sc5xHU>>X9}f(}t8w{P-2!X$zjsNn)5Dj|6*k`4uv2 z*S-W9Q%PwexhZ;{ydGpo8bnR65%>$X8Uu!;3{WY6>-LgJ^YG@KQBUVM#7X&pNwr2H zG42p$NGSI*48CgP&eG(!bOqDfbB?JpdB8c3TiPqFM?Yj24jzHA;#HzDJoGu5*l~G% zyAgnk&yB`(EVms+IXQY+E+7>99C=m|@bVTsK}X$(o9Dw)NO{CErUuYE%&K$tO^oQV zEIpH10@hoYYD7zMX0{m-5YMxmB(7y_v)0oiDku83$iPE*-PqBYdK|BzCY0X#xbtR3pdqzsLL zlgi&ij9EH^IhEMr8Bk-FBl_d5#@d!S9y{<4UmYiG*=?SIG-IA9;O@&4s^yLV7+9j^ zjfjsfI~`EPi~}8pBvsa_+d#7wZvW6vRgK|RuQ=ufJ}E}fp7WFb8cclI5G8$sz|Xf; z#5&2G6KIdrxyXSi&sCIrBWk`pKHp7A#_9D_WB_FbL!>}dF{o|b|Biv01cT@bFF6{j zHw62ei{O=wUD}kEi-J^~l5!Q--LGJNXR_t~kFn$U-^7lEgOio<|Js>37&)2#zZfF# zuVibbAQ#uC(RmGX@vE`yY0TY}B{j$viTM{|m4{SjfTkvnCq!h&i`=2nX%2snCF2*D=K2~Y79 zz|isT`v3d|aVoYtQP3mIH>vslic85NDQ;)NH@p!4Q$u-1s;?G1vM0bH9k>S*PBWpT zR_~vBEv43Tm;K_BS_JFB(vntuDfxB$EHntSgnb;pxqL!~R!{l-Ab35Uy*d^W$JkHyK34LO`IUcX?_Sa83IKJo!!C!G-4Cm|;xa#(fTBy*d-*{(?)=;9 z(EFh(GpW%jqyt5)s-jUmpR+OHznMeEi_0*Yt$=Be8Cb~X{%{Gpu?IW)H}@qb3j-W+1bmurjm<3;V#`b{_TGWNnG|x9`bO@ z@2+s-n{a7~;ii(6JCZ@b120Z#?z1ER7*QJb>a?;k-vWU;o)92|6Um@+P?c_IrLOEe zw9Rg?i%R?UkEhwO7bfQOv^c931~MF89yoh9rxJ-|F?ibM#;riSwt%{KVBbBT55}!j z^F#2L9E-T(fh0K_qvDBSas7;OqX@A@g#$DmA;sFWE})jPVT1RB!Y`A0E?^UTJ^Dz-DQ?HKcS8Dtv z5V8%!(b_^a9B}xyEBc3^v!SgfTl?W_CdL!>?Vml}A7S>7xG#(}9ZbE@kQHX7S&Jys zcX`8w>3{bRn@$?N^5*^9ta_)!L{rsII;^@s@k5zYiccFe&KfA*b!1~Hcri~TdM@q+ zIanqX^7WOAvRi_n8hJwDxVD;^US8wLAw0_`#(5{SqjUYRj_=E3D?v47DG!b+JG z*(>KodH?mC{2}7JMS=sE8tOrC`^MS-<9_pVpDtOu5wJ)R){$_ZrnveOtT*GQKt7U2 zgJf3M5|6K2_cGL!sGga(lImB-Dcub6TraW~PDnUK&|N3NjPkBHB|FgNgzy)llb6AU zF->3>(l5%0dQdxB`7kkrl-&pTQSM~&W^aECqnY3>!7C|9GGw5Z%gH7B4&Cse>;uU} z-|s9)5NcSAE99c3i6vNgY*aUnsnbiTG@dPyuJowW12l!kQ>F%rHlmNRpV)MA{l|xS zPEUx?ws@6HZGpCQT^Z96r*a`Mpc&{nyL0IFM{k~111s_XkU2jJy3jX*- z$KK20-ixd5T!+d#{Tp72;>ks;+b0d}YVmVom5KQ9LwOpNEG>n5Jih6@Fvpbpu=M)Y|3 zS`Z!=DDE$uZ|Km9JIbWVZ4*WM2D_&yo~_|B_6;fNSWPUSX?B)u5=00V)UgUpc;>yR zafjDG%7s68ujqcK0|;J~t7*pz#oqFj#a$MQndaA(Zhh7%uil3imO;qv;!wU(*HVKi zMM%twpOkk|rIpKc>8=0C{u~3KgD=v;QKuGYFe7Ma^(?W$l!DMx4c)QPYfp$az>?on zfg_hS_)Tp-frE*qb1Yl_bLA#OU>P?R%OlM^-LHLBB9lXIoDKv zcNu`=qu;XYUPltdaw<*~3Z^AK!$}yx&X9$PEZ7gIyaf&{J+9PW$82Y3P;p8q#I|81 zA6gVSiLAgE_kb40_OU0GS*-tz=BV&I$}kF9b|`Of{soO7mFUwGVoK?BXy2i zE5Q=+kHH4oPnq|??!ec+dkP_NN|v4%%T6h$19AHXVSIpuW%vke`dN?gK{(Q z1cfs*5{7p7_)u2SeLjY`vtauV-ce+m6%(5hNGm+Zngic5AfwtNI{1*=`wZAfIPx`U zoW)X;YhIzvk-6xGOe&uv~@)zbdgVnitd27r&6-xj&D=A zS~Q=W3nXY}lhb&eFXl?2SKeC4#L<;Gd4X_FV`ZGt$`am7Y@^N5Fh2sujP4I#Z+k{` z5SH};S5|$+tabi%>(z7Mnl-FGlm(4brkXPn!l5i1)M|%$N$V{K#m60#vETONg`a#j zq(vSYMdgj|aC?`2pi(ALA6MA16F?3ee{kID5tdNjpwKd>mQTdt`m(^FBZ(vR>_lsv z8&egjsdc8sr?L=)QsG4re$tS|xT^3rfLZ1GMEgTLPw+3(zU7f>S3!hYg@5|XpPq7? zTs!k2NAOnKn&KsvpYvU24{hmbm5Ua$O=0Q859GK<6mEC#V<%Ktm}#BzB*-Bg5=Y_w z;Xw@dBCQH?oqb(<_Mh;MjINnHbi^)b(Tue^+%Us>U=OMvqW#0P9n?3=$fBlglu zXj}058}c?R$tK0C0Yc5_tu|tML`%@D%FfuM*NXrfB(ORAfiQ>FPD<5yDq&|4yW!jJ zf&v{yXIx|<-Lrr1uLlv69El7sctmOaE@i`7*ysqZ2=;gVEbP5ml?h1gYL#|KR*F3( zAkQM#7&+C}w%ndp5JjMnVdL8SosWM`UfFBTC>&3Xwq0qw)Q%ro@@=La42psEn zg3eh&#g_jYS#;)$T~p5vKW1=9bYAN(+N#2r^6Fx;nhQDt-s{Gq=eAa&O{!X^^9ok^ zgtPttEcr!JWux1CEBmr?3ZUoTyng988RhQ5}^C4k@gd*idJu>Aqv6C1Rpl1Rh zDVy&YAN~TLF$uxx{-I(?fqq2`WWmeFz}`a~^dNEAz<_<#bF%_gzb$6k2d%Sj|gm1^q)IbR0e zv~Ip1LR>ne@+K>3JIF2@)Wx!QQO%$XHBPr+&z^u$KN+W?gE8IIqbS*F0ez4lX{?X% zuhxgN#kke{+spFG6B0zYbn)-NZCT{={9s=N$|-BC|9au}$e=h<||qQj%( z6A(8oxU`;9x5M{;08>D$znK4|wf2$o`N<=t<)2zNC9BS|BF&{AK0gOq>8kZ`?m>EItbDLPaUV+%NiZ z%LP{LhFQ=VsJ$|W3TFT@)`ruM>;wc)>3sOnSlvNu$EsUQeHa!Zn9lMQm=)L+jLzk~ zPp2?qU~5-><0{7~p7;#7r^^V-ch6j?(^`d7JoXw6K%cbiP-V#z-U;C9lDjW}RtXft zHofAA6QcxUuD36wM630n26-2daY!8QqU97&@Dj0Q2Xr(DS*?xKoS9J4=lw8z8@a=W zfcV=K))EX#+tQ>wWLiZ!M+=K;6>Q!$Rh#vT-P13$Ksh!8{E4&cMuW+ltD`5-L^8N( z*CV09OWM)bf(iQ@^=3H*&~MJ$jhEAi<#il9wb8b_eaJyQRP=AVpDyn4R)S>O=713t zVNx#-=p-q~C+Vw%pvzk1xcZ&OB$A<2Hl#)F2Tp(^=l~@gGU7%la1{m7O0fui$)GLmDp(WSlzC z%?6#rK7g!_AbOePSLe_{OBldF36ZYL> zO$2QtP|usz?z49Xl)RGe9n2#g+8kVqTnKZO@`A9LkZ9mj2Yc&x5a4uoj{!AI2z#^r z(>q7Y@`-QSZ&gN)P9ToX_;4zf!23$9P)AiFUG_UdCw8z{tg&@GD2KeKXuaNWwHEjF zuL0wU>Hkgt&+f@wJe3NYCK-HaoUty258#uBj#Xk=-#>{TUJ$gCo*kVoXpo7y80RfM zBYk+dS>y#x@eM|T03=n#3-{#|izQoSiUvk5OT&FVw0j_TOxg<1rK#A&E0Ax@kNq@w zeJf<-FeqmCZTo2X1RJkR5z@NCmAm+*NS~|2Vq6`}l7X6&G5*8~uYkQ1fY%4Ba(eaL z;JML*=A5)okt3>~r{Xe1WE)IH{;>bBb4!}Ofc-HB%wmRNfW2J zGk_=cAxMP#YxnNk6JCzDngccWxR3-gRZML6BgS~@saAp&eMhdSmos62rgC7;wUN%A+n1m?uf z>do*FIV?0w+Da#ODv9z1hH=Zk%`*z8)^4(^qj`QrcVABA(}E*V+8u8iLddr`I2VzU z%=OCi;kRbBzAy7OynoxZ*T;Ax;)=EHaq1)reQmy?2MUL;`g#Yc;}QCAvLk|PfrL!L zHzhj^yD_PW{oDCYi{7&AQ%P*is@UAD@&S7PH|(u*DN0K}n|9sd*t2=x<3t(*RW8RW zAzbK3gLJcB>6=e0FLL>u9vfEng+%bZzP&RR^`Nb{JfTRP@fH`mSbJvxAuapQ@oKHY zmV$cRJCl3rp|tLHcZEkEIWoayQ<0NckdN9ZCY1HY!Jvp}K8fcPOz?ycQZCg{%zVL8 zDr)-7W{)!U7UJ6z3MA2FI*^~}TWS~&MpDhK8lgz-qCQHAwX+>g8c3)8rJR7Cr#bFm z%<1y)(hQKCmw^zsaoS2(v;zA{{Giffp$eo$VXokaDF9mwQnjD0lkaip=E)cIm-0ZN z1~QkGOf$bSIoQC^_q&4SpISsZPXp*BX4#)G!68AzI%h<=I$EpN361E4J?$Zh^FSL~ zbgA>HeS4doCzmx6Z*zGCn63^gdlhR{ro|vVhFtOV!3$_N5ZBhdcl%veQtUQcnM<6j zK;3= zo|Q#ioFykwQ7MHFJTlK%mG#S;AH}o?L2!li6$qF#hpi~+d@T?`xoz6 zOc-tvDuyYq1Xz!u%QKhFTs~7+v`M?>6IpSo@jrCv;S&6$iYknjH_@aJY9d`6-h5{l;nH(7ruNTC#PllBc@9&1o{U- zwHnhRZ0$mj*A~V@cn1oYm*Hhmy;Vyh4j=rPUgTT)kgy>1w-49g#a8R|zMQ@%6-g2C z6*FX zo^66h(J2+$#_8haZLT)7)E_TjjoX@N6>f<4r20prJ3)*!3>v}lO!L!U2T)&9gf!=8 zEdQ zOL|g*{MSx`LzGb z!BQwsCdN`QHqZe({*u|_NT|B;W&>wFL_-y^(;;V8ErtNabNM1VL1`^bOjk3St<3MDpN%5wl~qZ2Oc3zajiDZYQ=(AhOSl&Lm$_(5yjfs1qK9@kMzKa@2-pJ>2LXTTp zVJH-cGr|%|T!NNZXZ zog0cChb^102EYi8;v~;+`X3?`05Q4SacfEr_C^G4&lMXj%j~<_4uSa_gVeC~9}6tB zl8$yM?B;|4{EiKI@2zS$Ic~zwl6~DZN1ChqZdM<&r(~+E6bap%8zX(8#{6DSk3_Vn zVpRLWjl~fp+B{5r>WPWB!oIv@Y)TQUmkH=J$M$0nYH6w=x}`>u1NvzWn9fx;;D5J? zmQ$K=b5iJ^{M~Z&A44aMPqteeJ;KAh&kV~%EY`0&@z$W z>cP46Ab2??lY78S{TlrYarn7K>^R8A{?rBVa-ia{sOW5JLO5^UvYuMCoZyf`Qms>H zRs!d{+lHIoy%1?6$y+?-%%2~^PvJO9QXg&nOx6x*L+-m)@2TH4=XujyhklDrh%3a_ z&`%HcBJgd%2PA*);y(z>lryiAv;d5on{o0VnIeZMVbR`YlFn5YB1~?wS$8j zTe>Vnnp)?Jnme|Yeh!|<&}1|qbjXgbn2Tn(69Uj%n)L4Y*Sj{yrijJ3H?h-8hYYTf zvy15kZ3L^PPg3dw@slcXuK*Wb`MH-me z8_fV(7cEyOBRMIWY3%xviy4eDN|!06_gkYti;Y7tm~KYH0Z6>yEXrBg{n!c*Egvqi zjZe^q7pY9wV%L*Boh73}%^uX8M#9n+tp+U9rQBzzJ;X!)J{ z_V_GcIL9PmE{wj~j^Ftd{eSnyxK>66ks6AtMiO)6}APRY$v- zr|bU(IBn;mCP?}PN7VdtL`^Wa!Dmvy1UE#2%e#@ZtXLuDdQJFp@sM30EgzRNO%<9k zV{^B&!&*S@bYoNSjN($L?1Or9Ml`?x1$dtomqWg%cz`Py*K}>q4ry|D9q#~2nhovM zQ&Uo=_|sFkS*Ma>&GVX#vCmnzbX(phbuiK0XnvnI__m1wnO68h3`NHc6HzEqIQ1lRiDu7Eq=ZLcGwcn%D1-IIb;_uHlvFT)h!W1 zQ5RramaC|qT4c6M1W_{$KcvNpH(9U8w|GZ^gq0zwxd27rDvr1J8IhM#kZY-umox}N zPU5A%>3T+*hrX}lnbbq+7445>8%mdGzP;2c0@YQ;k?rgZqZWUg z@WuMw%%-s*Qub{Tpx{lKvY08L{| zb32|R3)5pB?QB7-fnaU;bFr+B%A$GphQf2ala=#cVVEsIfnj2W#QRMZqPa01$!tjR zRK*~bUmvMJ@DL)jAT8fmamuIrglS`kMSQQN%faN11rM_4dy$RXv7DYz>Mu*X$y(i| zBD>1@IeRmy%WTI^1wa{gCh{bWUC4~nl-1BgK1JDDP+iYUjsVaP(M2`kqU@BiN9n?*HcEjiZS-ja>YLdD#hq!jc4nc-r1xx%_L2KsuZ?vytR=>LaS6 z>hVbMY*X=4L+T8)7;EO%l$8v|E8B@4*Z2K~fh?6}$FJdMmIBtJI?qAv-QtJ*4n@l$ z?h+nh!(Dme1e$&OI$9?g(+M?n#zfneDS-H0t}~NQgGZYD^uLn6BrohC@u@*sF$FT< z!BLXjXIxu!GK@2k!Ho>6V=a|83BZ@DBGfgBglo`mp$Iy9ay#d+8*M3W-_4ZTYwi5O zeqhpO%?$(0kep^ahmOp3PSj+K#Ww2WU6D^28e|>oe-?uYx0t&Iq-HH3X&YtGQsD$glpU=C8R8-UK`)xhB7#=Q` z?xw~p-k7De6_o&3l14CFxyTQfUUE+z1LL}0hkr0BNwInNUdg$y^YL~7AQ>i>wCgoI zY(8K$rcn%^XW$TNV}}R>yO%}r(PiODbS$P}q)?U&LQE1v?w;sku!*BA`50>r1TXiG zKLd^jW;Rz4l zTL~p8L7=6wQf9W4`Qyx*zq8wE-255Mpj>lQH#)7&8*l3XpUsWbn$sgq56JtWvjgoh z&6bMWLYE>RKv^fb#EkUQe3RCi$enQEfleuQ$n@~EuIFs}%2Wuyfsy6uJnFmf>8u(I z#lwNAHRb7zv8N07xYKZTkVZb_cZVT_DvNCRT^-rdx3vw6srqL9mrIyX8kk>y9El^> zGqNq#s5-k=qe?PhMABxku^tyfq66&9iwT7M=vUEHNC)hO(_s!gBeBVx;K`H7WbF_MOvSqF4MbqBq|Q+PMT6X2F*Yj0KxqwzY+ zG7rRD^&L7?=?rrE^I9X5B99esug=@%=`6OVSa5Jzw2uSR4w)xNtH7Vq{|Zv#_(jjk z?OV2XGXiBLIBoOCPF)4K@5^*M4x`IMcTTH+SVnwn z!98lq0HZATL)t1$HO8nzsSbKGZY{`+ShMlF>2jf`_LgPTt{UkhQ4`f-a>enKk;&djXO(n%$v4k$e z^uV$aW|k4t0qYa`p$3unb69vf+*U8(g(QFw+owLbV;oq;hf)J`DjaT%~Q*;xLoo_)bE~ z>TxhtA*?9~yt^;(YSJBoS*AkXCX@KUk)eE4AkrmJ@+Dy($T^szwETa8{+{(QCYBjQFAvSa z_o)1VMm(ML3qdjI6v_R4U83y$T_9}4P$LBhw=-hJB}G{H18-%7;Q!wM+kWmdusy#5 z8uFgAJ`h-#HxR5o6(ZED6plLINjhf+HUXsI;P=?^K=ScU_IEOuNxj)Dw13HEcersk zy#`ePW;4X(_65GHx~rOULs+vatS-bNE)>k(^+wCASASLia`^y7EyEs0M-^iAvn~2KtEovfkc!=Ve z?dNog6KT1zYqb49TBvI%O?dAvACMIPAD%MMvADQ(~#C5E|b^ zEf`Qo+>W2A4D&c{{Ig`6Q2fg(`F+YeV7}uSE)~KXs^BU^3rBs=H{dsbTMC@WaQDAZj?F8-BrWx zsIwYzDd%J#`#$k6w})$xr4l|A{!Qi=;K`&KdU4AV1z2V^e&d+8KaNj=$TD5rt#daC zCbhbp^w>I+8Ntyb^huMC7D{UC#8iI&Yd7rt~qDLN1R(_+Ny68myePOlV5bqR( zAHi>&kpt_h=-8}3GajWe5ex^wwyTGt%eCoZKDrGU)owk8@+s<&U2PSy6)cuzkAz9f zcI!enVIUPYV`kAj@wh+7Z0@Ttyd}fBfVYL z=X6{rsDr|TKcZSh5H5C<+)*=EmH@9?|Aie~InfUHkiQfh0=nc!S7y2nutOTxI|x3! z((I=l0Lxf&i53*k-W40U-#1*7oxc;>`61bOh~VtxUjqu)j>j)A@TsL=_mFM_i_1wY z9bmwrF@5N1NB$;ATNL0(k&ooPlJivGGgTysd)0%b2b=<`?tgN;3W3P^ww6zl-dVvB z=V8i}pIWStKaHDf%g^=LO+N%Co0~3v)zV57vfqd|nT_7zShWgpDs_3>0|E(1NhPv$ zksNK`F`s@Ox6a8PFE|tid`!B;nq18@F53jq|M}9_ieM`;Zx9=ZT%~aW9yGl>Rtc46 zaK6>PRW40w=S4ScM%MMPAe;lyHGw$T=0?@pJIVpz60 zFrU(g-H?ziNQRFCf;tmihBMSNAsGD7i1U%q5d*i2&o8KbYEHikY3i&%QK@k1^v zo(+Iv$9nHs0aq%b16qHaeb36_OXHyx&)HLCEd>I(P1;8Cg!nr1|F~n~-?GZ(P+z~F z$@WS567U%w&$woi(s9f_DxNhn_Q*SO_OQ}ro%QRxFu255g53(gQ_rk>tlQht&S1(b z|80squ^!LsA6hSTFc7^uiG1CDCyoMeBeo#;jay;&t2Dr;YO5}y%ihHg_h3s1FlSwx zsdLT~U?W1$Un1dSx*uDXk%sD*Ck7rcU(jT)93$Rrus@V@0ml~J-jX-h6eC*cgqs5_ zGa=^ZB=4G@p%~~BkU31b2SaFx{tit-Z>;Jta;xJdraUwUgMR8W!o2UMEA{}|>djxA z{^Wl}Nauc#GhKz8HNZUFb++TFTq||->N1A4%tP9|L1zeR(-gvD%>c%-Q=1hru%=z} zA|O479I6rdgmtkucIo4&?cft4V2gNlL{KhOPGuwz(6p+gej1lkts!KF5_?V)7oV4c z&I&0TWDez%_u1KRveCo<0AbbLXHkUuyYDgf6x3ctcpQv$s}*N*y6=CZ#w(qL1D*_Q zCrq36H4qM;BzJR4sA~U=79Gwf^eH*g$iHJU?KvsYQH+I?Q62WB<}%(V##{L%!Gd+a@PO%`$`*j7Q80xb}_@1 zOJp@!%Cd1?=U6ivXvyW__|4Mv=987m<}jQVJTA-$^>_R7Pf_Nw*15GE9{tJkMFbuS zgW(W?PmI-0whIrB8^KdKn`&EaVp;5sGv4z!9iU0DDK{te9?59>l;cXM8uE0J!{?!u z%M-8P-~x2cwBGI{WPOo%57f`i+gy5JDFiU^bW_b|)F z1Gno&E>Dl8E7nXvp~k`6`!m8~pQP(E9v8rL8AieH3sz*<3Y93d9xnj~(G>wsEUZ1; z=>AzI^FpveY&)V?IJOWnb|&Fm_#331H=Op4v>(5mCQk~P$2CkigS^s*=3XA=z-m6J zHmcI3&7M@zr*|g*VCa~^e}sS%JRV(R zKMiC03pVf|;Ji(i_tTy!=WmE7;EO3Y;CtKi?%8_QK%t-nfBfk%u3T)kgL$GPB2k8f z>v}kF*?AASW`t6l(k3*i_|xj08)TB!q#b0e3-Tt%6}@#cJ0WbK4e7N)Xl5fBr;@}U zV+5Io&zsTZ_R5a?P%@vIGKIu@HD0=`{`H!~nI{b-b7|4v%yS$=2YzVqFnXonDc(2m zylF7y)O3TeiLHnb0h6G%Lk1)$$gFHS4=M= zw4^_70YQ_x$e31jkAVj$8Dv9f)(OXs9DG+{Ok_!yd3`ngt{MnGWO+oIBU5iG2#WUVYK;jqyAaT3pxMl|N;U&6< z@Ys30^L6#6d0QmYi~uh6nUjM|YR)^mLjhr!${5MPV~M=OP|{OGb|9;App| zgef+-OSgH2ZU14qY%c!RDOxyoM{c$qZ>Pp7uoh}PO3M+WqWLmxl? zE;y>wOrza0W~AmcK7UFL;Xo|fop5f52z0@hih#q6?L4|Q1M|%(+snnyUDG$+pmC)! zwAc;v;Dpyx^*xjxq1&h5k0%kozQO|#xU|MF!0CDmMEC>nt!L|Lpi`yRY>t?y^NtnB zYL@6EH<74dAr6l}6myH~PD5NO!8k`7}?9j+lw8r0pw@CH~Vm3MsiTaB_J%PuTD1a038;SoiA0_bJO)5%-)WbOAc4RHRut z`fc3$yn!9%yV8`veKo)C5u1L&tT{AYu|Jn0D_k=2_Eg6Pu=u2 ze%v^I+4?kN4_ELB1nz1nS>j@r)yO|7mse;yV;<>vg#A+oH(=>rYP;1{wZ`y%j{u(8z%BY3qg&<{3p*ExieD^FA`Tzwt6tHSk!{) zn&90BA{#)Q$M_=Xmd-uOOWgXNA&Twd}%xbWsT<}+(Wns#!gP_l@y*L={ z*-8ja{U`jn4heJnAIP1lm%8*LV5r}QrFN8UpphV2GKv+hL6NLkd8PbQsp`bW>Xu8C zt-wX;It|6JlJD2iP)2N!5&mb_lD@fIC|20Kj@yuTnhM$_bh3h!`}b?5gZBN^1H6My z(dWWa>&0ndP4%ayG0DYXxT9;P6~KJcis_{D)!ch@q%_FnoP^d?W{d?5LAi>eXZl6o zO~BRuS&X}Cl*ezmUJZw28>kI}iEo9!uHYk`734^dNWbc>jf;fjBiucZGy0AJ-`#K-sr;^X3>|vq8dm+!1g%qa3&b-%OTciRa-Zd{ z>T?^`37x~iQ8jMSg4yV4N8#i`e)Od~N@wpNdV*ujpZO{X^5i;jleezM+;{E}r26fr z;26F}+5Vx-{f>8eulS~j2|7{gwn3iO!6qQ)5}~(ZnrObGJ2v;r8~FeQLM~THag>Px z0I%ZGTiu@uj=wHoB`?*TODUs&-V$K48$PtA-OT)3pYO0@i+TQ}Xdja}ekro{)dUP3 zw0kF7q~%_=V29WjyZFhPOTh)LJl>h1DEX}r9W;7|680hyQS%bF@rtF@w_|vBni9e} z#FyarP%G6ix(OM4{oYb1*dmcKADod^%l>7OHCfPR=j^A1t4 zRjML(B+q>4|-@6?qFqc~2do zGk_s=S6r)r-TLg)6CbBfgqb(IIeO(ay;e>mDkEWtR4cOymI0oOP+n0X;i~q97od8G zeqY(09IaibsaeyZlQ8Uot(MMvQ`XqkRVBWdAf%*)=Bq)843r`7YYBO82?5#dssTeL zybB$Instyleu3(~9@dU})t)j$;wiLpaB!V|1q(Qd3KptP)d-6 z8c?vv(5@qeO-A|N#Myv2{;3DccpJZ(c$B(cK7UHj5M8;(;o97x6X_R$^htc{BtfuM zzLI-9f0E0$}uEyc{^CEgjFe(*2beNVb?|=g>G9z zNf6-<=Xnko1fj*6$)GT3Cw?)g)*-CdoDmczzZoz3Y8+;@CDynLK($?h(@YqbR$B?vFG7!WYvMQU0k zQ(e+gq z>oNfyHVyY}Ghp=;&E*z3MQV#G`B68@DbzBx%c!D2sQPeJ4rgAW%YF;| z)IdtA6`ZaNCW>=k2!D3_-a1QB8=j7|2@ka_gb!{91JNR7BeOTOvdGZ%)?c4L)Ds<4 zhdzFjW<3lbtaK(;-w!`q9MV3o6V`$RpD@15Gb?sGAOw(W{8C^^Qhtp#bGXTev+)MM zY#WCSDybkbBg=Gl?f}7JkPhUF`9bU8sQ3`#Z4tzuRN9XWlM43QLy5^PSfLB$IEo2- zzH`tMxp`Z-ifPPy?dQqEqSmE;u@TQ!2G|9jXo>_EJ+U?Rt#!OM5MAr_1ju>*#O78lJ zv3yF{JPR@yq>5>?t1lQy62FC~zb67-}=Pe5iD3#PrL>;vFv%wOeucG4xrqUQp5Fyj3(uH|) za*zh=gO}Y|5Y3%>`87LA3=2YcJd;G%44jB&j@vC z2m2fDRqNm?U8*`FZ+8{1?MF&gxwh}Y#B#G{bPrAsVYanjQrj@Jj;Wi~(zKXv)Go&d z%XF=&*-wo5wfCKJqW9Ep}wFLC&+*!srXMmPwd?^QT z+-jB^z`SW;$;B9vBTl~kYvvII; z_1Acx!}1fS-xff2SWDlmx*O{gl5SHg(UN{gL#LX42v3$_Bz_a{bI(j#%3qsi8dS8F zhLo+mG?8km91vErPR-I}O66?64!e33Un=+Rrl2$o+AW|dQCDexAzdJ_tu+(#%g_gH zpW-S~kmnwNh6s9AoY(Sz?f!BZNn)qGh+*-0ITU5a(YN0nNLa8-8}(>L-{k^~LnpGS zLmgV(tREIYbcrTJ-`__;mz_Ej?NrKXLk9)GVdo0Wr%9mens=V*x0bO7GIzwfAjV%i zcG>e!sQ-~+Y7us*(ffuqi9bh*=04By!M#NV2ZX=jGNquno2#H5>z{EP@1Enhim}Hr zO0(W^khvF8_joHeEGbVy@A@Cwa>zc34jN*4>o_WV9&Q}51dzPQJ!>ykrL@j(6##{$ zYCp<x=;TJ*W`rIJvI3EG~F~zVn~8bKVz?=1(Uf^@}N5;!}X-6`_&Ga zsg|ZbO8U&}c9aKsH5fjg%ae6rPE*nOA=P`KA~ao{ypr zL0H^rt@bKvTh?cG(Od#)s?xh}#*P_eT_>$*PN)&xTAwK^tWHq~&_^_o0 z&C8oGj~%idMEd+!%4Y{w5{4xyG~F_dotfbCk`^F$S+6bga`zAR@e}91@j8eS2tjxi zbQd5Dz@cZ^RRZ3xYViLVD4-ggl)eCzcR*$XInF@l4-P}xj$v46RQ1=FAW0d(sby;E z59ea~a;D;Fq$$GsnUd0u7He06Sw8v_6h2a^v@f!!ojuA@1$mnaEHETdkN9pVt9kGI zr!J@zg0fx>aVX?Qc_52^Lf=OBGZ2J8MMqn%?*&qx$)^DQG_AQ*pM0LHeOKJcX-#f< zjsRI$zJA3+(|fo&sNf(f@Q^a4TpDChJ=G-|MmPLzu#ws(8OAMW^kmP3Eq!L&iX>#_zG2DJaLcZc!^}gz zHh0p_S!?|OPJ17uR!5aF7S<@BTx!)v_BE<5i;MVF&iJ-bOt!!$2~+Bs-k%QqDCf#J zXO+@Mn>f%7z0k@2+0ulxbgE`$G}-j#Rdlu8PQaECtA8 zEdAA=Wf_njq6b*dXk_gLv5!a9(@9`#WnWEvQ}EieaSZ-&kT-{d?BzG*8gn5$4AmYE z2;Xwxs8OkK=qdDLVYg;YJP4gG#1n8t33oRC$h0@d_w#;HEKl5(Rx^`To33kK8g3Paq-d`}g=wTV)0 zwnd-uqz8diU-PPyecjH9E>dJSbl}zB?D)o0DXuI;lX0$>B z)mth0G@Ojfbc^i(nKoo$u{$hqD9w>bUuYfIpBTpD8D&cVahitvLsD7%Wyh7btX}|9 zPd67?k52dcn*j(I`48Bm*~y1LMJh=PM}5B`4z?Ls(YQdmmqCwSB@2nwc+Ur0l)wV0 z!Ar%>L2KL^Mfmo-JeL9tdLlkn-&sa24xz)IN&OWYi4H1S`BAdVvbVkka|OrkYzjUp z)`0p?iXBE5S(|0u+f1cHq~_;ztSeFZOp%>JU!wZYh`| zrP~+Nr?g*{R+DArk(?Md(u=}`bcN7ND5y{XMp(Xww~ZozNJc_O){8CY>q&(DPQ5H8 zJ&4kia=~!aDX7PC2_rCKpA0JMsTlxp*gF-5k+&Mj>P02i6YU@q8DTlkg1$(6JQ7Vc zcj(sp>$W$0-2Qd#X<9<8NG^w({AvoVD)h2_#l{eb{G{YuabG^lC1Zm6;L5|>N-;j- zF#Bs^5MO_Ra{V;JtLE;qlrHZ#r+W^OHk?L9QR(+)LuO$bmPJY`LTX56h3wsb5$INR zS)wG~*d(jSt!qb(qL@Jq*Mr)AT~biWsG0x13z|*_rDsI?DIbRDF^_>m!c`vm$zF%C{db zEVkC8VvY+%=`&UKaTCj0j+r&WTusNb^6^b;wQ-Z(7={YllsaXLqBL~gj=Rxx4dc|; z?mt8n(trywt`%^Ihw;?gzr`{j1O!XQ$iOH;GFdh=qW;6Brwh8q@^D&uNh74UHpOKU zNJK`YS%{V8)%O(8OeUk(i(sC<+Yh%bJ@(a7Dm9U|oOJN)l+=6W*)L6Gxx&>V>)?^q z8glAMYcPEk$syOhM^3&q0C$gkd5%SwV=F>!y zFKssKJJN?e9fE1l8p96GCIr`lzyYA7C@Vv7U#s#aBKw$uPZM&ShQDkNgj)8J?!Gf5 zsH3O!P(E^j$e6#9K9G2N+FRYNhw}NpfHU(rv5;SkWhi_|bogOLO}FRo#D+Dg+L(>m z5Af_rrO>34pYtpbdL+RT8#sk3Ii7wsYV5|Uye9h5IfK)Dh-QJC@pDhG7jcIsB5g5U zBFsZ{_*=guFAm-t6rv{o#W`S#VLS!4OBgs#8Dz@AMQ|R@#;((se8$J=UJ;nib*6{9# zgW--8401;Hjn8bTNv{GmeOe+QQwc(7h<|?N^d3;OYuD*8C4d6g-cVr0P+IDQ>T;`p z&N=JrJv2oh6MQ`Ey~;3x7oQ>9u0z!^e0-+hUN00B4qyUnh98?~1cNpp6rpN3Qbs&! zjBNL~p~zMy@v2J7k|>fbs)+wqZADL}3W8ujg7Pu&z? zsZm7S=2!_uB$MktCL9>AFIKH-ykzf*@pNy&*ebc8n!0N|sCNuyY$jGW$1zeb$qh3q z^o~m=zN+nlp+4_Lx8z79pyYaQjnhe%#kDjeD;Wn97E1HZ2PPD+)$dogYe={+OV$QI z1h&??l?=R2N?&iBgb!38;u zV#OMC=pX~WGgONnS9ttM$6rl>H68Oq{uzgj?=C#s3~d;fy>~y5o{Tz2A2~I$eQ~fW zqn8&(tfJOQo#Ni4D9)@5g9~>HMK4^X(yhj$f9bG2nDDlQ%KrKO)|QCgPyehs+=o)5 z2Fl=Njj-F_l%&j;g09f(B`h0*YM4^IO~h^k>KR-5wXJF_(@$YbpS~SgFA#+v!wB9> znmn|M54t_UoqO>XokKB;bL+LX0IrjVTHk199sF0UOoIg?)3)_)JM1^hbPMJ69gUHYpImIt811?2{E&7l1N4s@&BcxV_+ zEriM&JN_KbhHimzF{O2HtOn@mKgAtal&%xTSV0U;7kN`g_`NpD5JGWJcld~!T6XNa zgdstiFqYvtz)_TaN|)i^H8a~ld!zU)@HK4IRva$tQ?1E!9;@@5fq@uc8e|1b9PIc; zg}NXpQGurve5%*i{3wM~gidvs#w;+X?uT?i3GpF_)It&lmaVzlqYBh;xnRn`sDl7l zBN2}t6ZaJ4$1b<4Nhucj5cyV<=(0hCmL8?R2Q^D<5yv*(k8nx=eR6~`h=A3APo^l- zwsgABrHi7ADfdp-VOa-0r*F_=MR z#79K2_Ps5VxM|;NaMPqO4iD^lRWNOzrHuF+xB;I7FI;Ngwqfk)I~UjQT))-ElB*kM z$xKZ&eIj^PZ?RmEJRIq_grm9cjR9#FiOgf{JdQ7 zCl*L>?OsGXvSlZ72BBQ}?c2EpyoGbVT{09osAEB*t1FVg>9{tm5a&+G z7~wQG!B8p)4jj}#Sv|G-k1`v)!pA5m%Ykwm(x)uB1<<(ZX+2Lo>Zc<8IGs0pk)*F) zWd0m+Nq%O=j9k~8tBQU;H^ppgHI))zJY!T%Pa$i^NG;O-2`vGREqv?O8m zqgbu8Kn&ZVRIcQ`s;|sW&UG=KOcdO&81h840ybWZFm_n;yyH}GuustQM};#FR7gSJ zZ+>>3AC>5yvz9i(auhYUNZz+F64b!z(w*?I*+_h%;aqAx5@)VHpUx9x)0<+DQ%F$x z*i;GbVD-!M!k!!V#!OkRCgg>#7Gc-Y@FcM&di`i&)E|qq8%c(>TcDKLMj` zz;RjvW{Ki&3NdX_FGc5_)=}fLuTG*Bib+NRPQL6%gO_S|%B{ynJ8Lc*+dP&A2(XHE z{qw5pw(CKqn&GdanDQLAx@513&9MnY0?(O9Gv8Qq%6vN1+nZFv%0^i*DtA+n9F3RI zH(7X^{%a-X-aR~@-iN7N>B6oGTS)CFu@!XaeOhF~!M|N8B(`ZF5l^Gb?2=24o?ICnqpskT?J4;1p z94S*c0HVT)H@AUt&zmiK%t!`y8lkQb&TgR}aT!clW63(iH^UDKK9w zqu!HYZya?|X=*Pccs>s_DH`aShzSliT~C1ce}LLP33lKid;Vju>dGSE7)41b_T|uD z8=zqwAca^0N{5E&D1L5HMkTobfBs-)`-KduO%)Iul&cU^geU2Ry-A5sH;8UhZF4cB zP21n^Sb+5oK22GTdNck1co573$t=M?U*pM3oU~OgW}V8j@V@uvu(->F9wDmL)QSZ_x%m^<6FynfA#@UyWJfq`guU8Q(t_$cVL}{)Ky7t@LvffC|~bM1;7M zp_C5uyRoOY45FI97b<}CgGNxb_`+gm4oy3l48h-dSL$l%HbT=w4j2V#d$uin;JH;b zd!nc&J=JIfMM>B=6b)1b;{|j7W0q9YoruUJMW?hP-%gU6o3GhGeu+kuP$0t8-Q_^(`2E4wvHg3Z?&I5PDkw22&Ka%8HA zl@^CQEHXh~rM0S0rHagg9U~9^kRa=+)orUsg-dn@Wq}Zo`s@j8OcyCv>+5+KE?t;J z04YG$zXWVJcRk>u7gC(B5Itc&XtvK9l&Bp2A;=xFTYQB1l zNmd->RA?mdhU`imutO5oP$LjK94DBTUjXB<#k|+JTeZ$J$nTs1Qf|K)1FGXOoCX}e zWcgPlz7d6h#|&0oEH}hP|HDky;!83BA=TFj5*^`4qOXaMl@4A0#C{2acC^Rr$glBP zi4*S**z@Q=nyUdUfcRp{=!poBmpf=UW|+=wd2<4@(RMJxN+gFdBZ` z_w!9jVoZhUWaZVvj^x@Cr_kOLRi`8S3bJUom{|1$Pj=AsgO`~10CK80YHZVVOsC?K zt*9y#jTndMh0P$Bv5?_y$=R)b_Ya z!bHZ^;fkm9+X-B+lQRE$b&(&5opR{X`7JGkgz1#pCH>qUTXOiuQ z_se9#&;6_id60n&@hpOj1viU}`q@e>;&G2t2++qj4M#)4rF^=_Gp~8V@kbPEeHnnv zgQWSi7F9VO|Gh00GsoI^ETbf^#1?Ds0#%AW{ePlY?oJ~-$cqz|u<(N|y*G=hiTKCC z0*n}ao54w{9AIV(UsQ%&U>jzd>}$!KidN`=(J)wbcH6#XL%qwaRz{1dcdSDoI!4mo zJd%`og-W8z(k8-;Vu&V9{8lK~0`xgN_-;~1&v-+$Afeini%|?C1OzX&pg@#tK3nV7 z(IF6#w_z~=Z~$lEa2o!xN-e>-Ghc@{BSH&l%Tqz98;+0(AB8XrVuo>qhmo0MeA8Ut zS*9LlAyjxk(EaoOj}$WzD1Eg&ar?ro2=u#d-?iXSY4JYO$^{*sW*Tizl)voIPu)QU zBBb67diJ80uL*=+HNkrxd=Q#_tKtvh5=35HDTlTd`#29DtE{|9dWOlKcYj@z+alrTaprq{&lM_ z*!?PI@cieb1qiZfy}YDc=~x=SOfWQzr?b^zmXy!Y_*gz^eM9VS38~DB{=c%;abvWW zcs|>a0iFZJ!TC)7B3vT|h58n0izYKuzTk*l;Yw#) z2KmGpZcv+~Jx!Cqa6-_($mU_Kx4IgS{e@xI5Tq zq3vvq5yvh=3JTLf4GYEWa$T|io>_Z(v)QH-(HXmRI7;wtrM-*&D?a_~$Z`d*F4X=y zhkv#J!P(}VNw=Fl>v)kY=CtxDlp?&cpkU|^Ct~;(FT2GT;XLPFZEV3GXzM`Iob+W%|4r++EVOW(u`sx}u&euH~@hO)EK4(ZeuBp$Mejn`EZKDf*6?4`3x7%aa>fFK0=qjh`}Aqib~yY2$VZ zHSNTLI58S^peoyy2fTnF-wB8;k}^1@bRT!LGGb#)|I_)Eug^NAQ4#;C}v zHDmG8TN1&A$h|dVNrZ8FnF2}TNqzLccov$2%D|#cLwMHX+S+-LRbNf@JyA9g(d0S= ztZ`+B-D9uB$1KTOp@C`#mCKvVSR4qgC5beH6UjdY>P5NyViCK6- zuO!VK+IjF@YORjn18L&$j+Q+OfL~=jxHg2NP{{a6|G~5xP@Q@Q-OT;|O&XEN7<5sG zr5uwrTLLbyOUA$zaDevB#mb`oXLxus`OWCWfv8O6(}`5F=jgcj$NS87@GJ((_og{d z-J!w&0TC`Y=dPLzV4qZ1-^97x@!d};ZJ$-US_rNO!S=xKb^7Ta$~ei{Xl(|rMk<_S zQVqw=w}mFrY&k zM=+R&L&)i)1l#14henqRgAXqw_+Y2~+(F8YT}mAuPN)oMov7ozrspN|k7rHne2rd# zH;75nX}#;Y`N|IRnX;2$)}H8PY?04l>U)E#2!%T<1FrFf;n1=sJ_aTeixzTrj!dg= z;}T#DNtt9Eot6DV#@9?I^Y<*6Y6IWaqYI?7AWpZ1YjcnktrS$L2G59^!8)2CGi?9W zb=BM;(cb}IXD}!uXv1F?7DN)nYu=`V(5v|J-<}{IiOhEPodxKis;JcLKu90Vxl7&_ zC?7xkq);TK(t_NBQ!vkXvH}M znD%?T|EAX{<;DBWYEGg@U}ad-@f@l>eXlmWz zm>m+)9xf(4#^XxI3_Tt~2P@3WcG?DpZBQFb5sm$$HGfnOTH_~@0q5;yf?H{*ym}@o z^l3q&7r_8b4YW^{npWb}QYI%EsbN>dj}(VS_?8gu4Ob8s)vFMO+%j3M2}97nm6Kr; zRzg~QUtuzkkZyuZ>Yd478pL~{NR>ms&{IAFzDbVe=A1*6 zgv?ZW-XA}?_m)s@#ycP-C<%>>JkS;nKXdUsq`g` zhHQp{V3?RQSyvw(AWV()d-QY|c4mDh#ncVh(A3sUZ?3*U{w-5niWv|@lp{N18;PHt z7N}6Joi`VSdk5!5;LPsUstu$k+LL9CqQk#z z<>Gqx2J^cJZX$_&UkF|E7OpG)g0PGM4`TTdh+g7?-!-FWBC)OwMdaJt=6N`Sp^&da zcrsL`cyDhlXD5~h-^x70RiR+lFB3o^T>nuZjVmBGRW$ly7htvxJZ!UqIY$u^QXFsN zPnv6C;Vg4AKpOx`E`SxJ0Xn-LKiNuz%^8Wifqry;%fvf@n8}TP4v>F01RzG5m7Kcl zb7dqiRCR=on#ItCi3|pv9zaViqK@>2lO{tBE=`xBAx7-Z)(q#b^zDwH0@+WZPTuwX z){`Fl-qOS4W+FVr=^6rth9TC=QI7vxQ%eMgTzy6`^0p5hswaC(Cy$2f8*h3KZE2JA z%2$$9cdf>10z5z`;a%=;IVSD!(2LnejXLMUpm;Gl241ZC-s>X3{|F zvfZ9?lg0vlls3z~O3Um;YbP@SV-H;hJh!AEjHt>IJ=~?vv{rIEA8rO@I86d5v#++` z3}0xZqfHz1KRA(A@eO-*;e5v_O?<0ew|UB}%bJj|A^8a;si(&96N;_evk+;dVCWJb zce{BF(;Jb=hGwd=f%&W`PGKUFy^N2AYNJLPpZ2(F_7zlsJ>N|VmR z3iJ#vTwj6Y>S?~-DeFO~<6~#qT@I;%i!A{KlB{rg^=!+4HiO5(b{i~PrUZG7F;2-L zSXWEu^HG*#M!7zE2C+kir_rWCb`vo|OOE=>q7((rK8z=S!o|wr7sUyzInEZ{8n6X^ zA-rWTV+ox)1TqM+jO^)}!V42Z&>|aD=&C#pyat}z?P17qQf6mixUv()Wd?a$5lBRy z^z{}^-2g+&t|Eb*T96alEKtDm{z|sXd03|J_rCF}(BdSU*<%Z^ zXT0VuPf)Nj5~rd`uuaTOrcmU)Vt&4dta_afiaKE|p_duxs%ks)&{oqtPjz*_H`ezv zMXn{ps6tD*KpSD$@P#1CV3MC>U`CwuZS&|7FD$u6E+F#rq(M`sRnA${=s(C2Ao?{X zOdhZkCd7!b%X5G2R)RpFL-SB&tH$mIRhL3mMVlXB_RWgj;WI-Xk+W&iGCW2MxDSSn zSo#GfMt?F=uZWF9wWNwSD8ZS$v%4P3`(U~0;m}+d8LemN=6pf&=ZqV~aWv>$)Bl4aL zHc0(1h`SLDzJx(+g(O!%qTq~W??Ft(lB*B+fH-3DvBZp7)yv9fKiEFDt036YEX1&Ly^^JF1!=l+30sshw$gw1E7W;H1 z_gGupID~pUGB4!y&BKjqgyukGAyb#OQUCdYB*C`F94MSAzv3J-fVf+0Fu0j&eJXTw``dQoJOnT$T<5)91B*d6O8!O`*Erp zESFTI#ZTZ5;FPvYIQ_`FqDK=f?UaBm&PB$)h&<|pz@#&wq`?fK&nr=yUy{U?f3N}lxQ2$rJiFz4YZ>(?$^ND@@rcm2)%$4&U5W^wG^o`a%ZAIcF6Rp zd(vIvw-c#U-O|!b}wO9_sJJ!GT(iE0qu(a#i?X%wC1+*VJwul5WS(i~%FZ`<}1TN1dIXZJ= zE!>B^oz0D`l%98+l_K*(7)h~&wd%U$tG7&kiB0ucw6H*GGJ2b0w5 z`$+-m-_FwkXMxUV-3boj3Og^p*S?qyMGxj<1riUhFe>3J1=H!Zfzw5la;Yls40A9v z)Pad;&Rc}>ZVA=c3k;kFe~3n2;?nxcg2l6Rn)8U!kt7c5ry9wDqX*?$Je2uso1ZlJ zrfccG2UxJ?bcTQFAG`xVOUnNyXrR?dDGI4T_#TWMN!0y|5&;nHW%gYNCg`hR)F_bV z!s0>R9oSle&ZE{^;9r)V#95i-xvRv+vy^AxSznV0Nw-tr)gbZK6nm204xH^2DZF4( zOO_!`8Nr{gJg=g9hn+s(+wWFLfk}T@Z5D&##C>OyjfvKrZY&mDk+Mw5H#;kd#O$_n zUL=P1f?S!VFrGVuD~%r(#&i0m`EP|8q0T95C%F_)sPp0dPZn8tm`;%fXx;YE>t+f` zs%!Xs7Fk-|3MfVClPzO)mSbgs(bJ;t@cE+8^$bp3G(TO)+hinuie`0F`tW0gSm`pG zPSRBmh?+jY;a|Z;#MC`K$R^m7UInM;7InQw2AIWZ%$htwz-qbMXQ zc!LddXMqB$Gck zOLHejvF`f4jL7MO;B8YUpeD ze`H@q)MNd@g2?!9GRG381FPJT#GlbO+WZl(YV5e}W5iI-j7~g~FM@p@X(c=SB@6wQ z%2~U&jzkm^{;vb6dsre%;@T4;uiQl_Wu{rLwPX8y&_S5GlvPIZK+oxu(uHY?M z1nFl0+A``naXgA^mlMo%7Smg=3-GI~61^~-`3BjqUnR@n@{z>&xH{C1ZgT7p3ME>ey*(M$A4XC1fYK#&7tItGT_^*XmC#(Z_KEK z{uG&YKh@3k2}f6XoeP~sPG;~JJeLFLitdfiUhaU;7(L|v{yHrx41jpOz&`^e$g&CR zr$tHy)8!iep9iAJk?Qz@7Ze8C{)merw%tcNoK3-{AcR*|XMHrDi2mw!Qqz?3Ra5)` z3r{Rg|L$kaA#Xt!jebM400&X>^FrTdZA#qIjWs2QR0&gzfuV$qA<+HAoD+cW^2fHn z%@ZMfE0TvPX}ZRBZvkC6^Ub$K5DyXbkHgpjz>|oCyZ^EnGHv|i8an_KiQ3YNZ9Pab zMH*)%S4jt=!bhdFv;#2&@!Ts*o?NCNFJ^VE0&U4^NSrSyA8-M?5>|B4$~N|QoCfReQjHYNRP316VTyDOrZ?6Ev@+3|Jg>$%E*5O~8x_fpMVRoEh13 zV@HHL`f9|`79x3JD!8<({NuVhpEXG8*J!g#9*?ac7n{?$9>yb%HO}@}teWlLT)W33 zy9bkG8$>Oj6P%Ramk3+SD#3mHbJQBXa@0PW~a7;-ZLk)K?RV%r0=n3zOAsjrY3^D~EacM1A@+t~ z*{l$!{-+%FJEO=IX@#{hll)t(XEPikb37-glFFLB#7LHEGb z=~7}hCU*M~IuR{Hnq7j`%R!|umos7DR9@l*;;<1UqCWs}8F1IqZ@8d^}Ta5tM*2J2W1{2F&=}P`#tUp%geCd6YcuMLI z{NJ4=`cjT5ei79bnoS91`?^fpTJ zVJ?%_G}+uIsz)-t8m#(&_#}VTo7$XCm#vmI(7C?C4dqClU^VPF2k*DMX3V02P5Lj+ z??v3Pkq1n}Q2L>HMe2(vL*2JNX~TOWQ_XdI!w}MsvOKD?O*TQu!m6@k%V7vO{PZ$Te#CCm zwj&Yo$sVH zWXPM7t6(1`l_K|U@y~Ya=I2EwWDVbnL2s!(W5|uihl>BDWdx-is>}QwpZlIW&wB`L zqzONHciuyOBpHpY12`~7h?KA;3IU5ES?)qZ#0DrSF1mkgG=d&uXCQk(d(EPgVOiZi zDJ>)4;ueL;=_y3}4GNjxEY|P;FLHi+o|O7;>AbWzQ^u8GtW7dUMxiGG)$1XzBq7s} z_hw3xkP5ra!|-CC8Vy{cV#88=5n?l}2tG|aYj?+Dw+s)wppT!_c9#0M4GH?P0}g0# zGEP5+J6<$d@R_yeAyNn%BnwJh6_?KVOx^87s@4zXN5+@eEGBwI+3qo)y%gGaE*|*g zQw)a5V#m!A5+zJcNoI|y;f?@9pFbM4=RQ*W<%pqjp?20w<~xO6^yv2=)|^KI>NK3f ziNsKY`^{YDsQ=F@t9N8J{MLdaQU>l)3s$!B;cDN-2md&8?iH>MYw4p&FDWamhW|@M z>xsa|lvshIXyn?UKMJeqC03I@5QB%lBH_#+^pHsm5Xwo!yvE8I$I53aMhvYW`MslB z-;)6|fcf88upxXuZm+lm2rB}TmdwnkQW@_CF0%KiSP1eYP<%2y`cqlh$;(6kT2Cwg zi4D^*4cuT;D%4Uz)SuLyG<}W8Mn}~a=G!cR0UzNW2FmcXm&7t##smx64|?1U?>^># zM0L|O?t_JFG)Nw-EC}?jxPT6+mm>=u=5M?S$Z{_5wqtLQ91lnZ6RA#x99}Z(Nz_g5pYhF_{`CMFu326Ni@d^PZAJ7|P);U-0{?Nk zw!dGu&KqM!>x$4HwOfoIioGCp3BJYri(OAP;cVI)ZN_$HhMS12 zSSL7LK1iuE!x|S@){_BQ)+XD5%!+^WqHeYnvDFVNrAoRXUNHBv!UkXhz1Slcew=F}=-}Bou(PHe{aqCv}zaV5|@3OI+ISJ|Ycfjl~ zk4CxWbdbh0Cfrw1fS*qenDE^}t`+6r^-1;*qk1)zRp~|d4y9!~m)r;-U0RhWb-<#I z9`+>lPWTR_W96sKUOy(unC4WEn~MHr0L+zywo4+Y*UZtyzhkA)hZnMj7M9 zjJ&=(*9DASFxkeJhZ-NB-m~wO1zp{KQU<8YBvKETh~gYnb(w z0*7Le)>(eO!m_720N-^YsWn%wqX-WXdD6Um4-3pV-LuC!yPR8nA>!t)+`Zqczpo}* zeOVRnB`3<6h3$7ykvKijR@{m}peK`Ext+<@1>)_rNLOSNNMs&&B0iw6Tp;kO$!|<8 zU!EPW1o7t3+8|4Fi%a|NQ#qy+$Ey)q)G`k3N6{Q`D2e4n7o|M9#pBTpB0>!2&7ZK^ zukBM?wXa1_6dKJqeOtA#<#`gYjnlsum0%S>)qp!x2xh{-Q`G>PF>E?AJXM{#aKJwF_b6)Z!`U= zUO4;SecoU2nN&J!?=N`Pu^=R$<;>99K$z{Kc*}|(qL45gIAIt+dHP7P3P8!9BHskjj70|G zGb>KSHU?zy?8-V%$$E739J2Bv!~R`MyI*skXbnx$p-H3s@KZpcI-l8y5VGGTp#`G! z(Qno4A-Ar0ITV!G26=OpI_%=|ShIwE484pcmvp;*E$KWw5s`K-?u03rb8v8l8CB_I zG%isZcwGZ@>(KE4-4zX~skEJnVGBnAQ!9H=mZI*I^qU9C{~fAfua~x8hnOZF)0D5; zVKId&)AnDs{MHxFbNr_68xEOS^TebbWdv{^RX_TvDi1GyJP9r2TlxAxzlZV(i{en~ z^3c7j2xh(Q>PHjY>J5kIVlY%U3`K&w`kH&6p8;M`i#U;X$-dC@ZL^H^T`SItL`)VN zRUV(|IVGL>g7JhudqE(fx1GC3f$)spR}j3yiU5B!W$7`F6Ve7yaMwF}Jw#2qOiHH@ zi^4RhyT&A-uh7CXbm$E!*WTk?c=&v+#%8{i>qV6|O$y0)f)!-{ zA^t8HH%ffRLCzSgy(hbJ5coyi_U6LJSktDD$zUwXOAz5*%3Lx;g-%wm!+>8a;H>RGpLn_24i*GdPBbqVQt2+ zReJSxZ1*dCb}ltCCt|;hlGkZTEB!f`)pW3I6t2emQL2T=ky??0C7k2KqDs)DNqAip zAm*WNRvN=BN5g!34Zh&b!Jv`u)7Y5FT>}E1DW?P{iwW0R=KW_MfkXmdc5+SgnWYv7 zT}`+O0Lw2;>VjBAE#DY@q|mb&+!H)4D%R!~_`wMX<~R+LdUA3zn`^GH0srL_QOEAH zX`#pYbfn4-sM}Vh39n^Up1Sls2srU<H2ajmM&E#b{Y@cpZ0p@WM%YZh;hffva;3zYvFdO49l z@i0&7wEJ=`TE)^cFJxhDsRVz7?|bMRcqcfbo-KiB#8|}QeQmbf6Qsld~zs6c%NOlryF}bVtDGJ zsl)EC#;z+ywGoqnLNNU!cYYHSm(;cxN>TKwl2v8$OM*2i>OdstV%3!;OPwa>FtG|? z6N7RSW^Z#_%%OCf+4PuR6G4=9+RvQ5-D zUe#Y0;agTAHE?}5-3OuT{n7_UMVkrE7K!sCoun3Qwy8)28D~&yQ|P@7fbhU)`E8x0#Ijjvf;N$juT|?g zavU>bxsT9#Helo7&ohoe+Q1+5V_djGF}6#DokE+-|9`7S_xs-%?l>@oceo6C&MMrD z|7SqcL2e<%Q^b2pF;Q}BybFK;IjzOf3oAl!peugi3S{2Q8wVCp`V6jPuP1MhZKg*a zROYZs4q)t%g%CLS<}S7BV$~{uWi|~O=ksAHa=(o;Oo zTS>bQ0M^6R#pmcP8!~<$VsA=$%J?=X7z!zoSnH!KEm}ItYL$*uHXv}{lv{;4Z05Xs z<~EA9G05=5>a6iA-_bbM%+K_h?envRbbTJ6Yx1@z#f^xY+mq2u!L#O{47~O_c4*vM zv^W6Ijc#)~%^nxP=-AJ{ipxn0z_We~C0a5|z_~s9Xp;5&^{tcqFGP0`XZrVtpl)2 zm`zW3vq`V9;#5B(a=mjDVv08;wA|DM0$ZSvc_E&P(Qm8EO@p9}UEopOdin>+Lo$0r z06M^*$uG5BVEZVlOCZgFUdTP&OCZ1JaPXcjWB-eNcc;QI~^+b)gcL>Ud zR1#d5RDV0WP1)%5Ymm4ndx#_S&tKm0|KN7gw}xhyYiU)%0QBj%?T)%cr6j}DP^5X8 zNZSrEoRy=6FF0dpc8yGGvoS`RpN6aGs>F?=P_paXE4Cf&=5Xlt&l|0>!QHo)0W)uE z)12x3FBT6y^E#g*yLjz`V?6SOJ*Bnj-aN{Qf$RGR%)4Bi@vn3o6tbxj@;}g=p(T@kP-Q3HJ4Q5ERY+@h zAT_Ah!Oj~RJMCw$(Bt<~ONAJt#m%Zp$oY!8(K@bT9HC0i1_b0AIqB;TyN|o2dh*#)%Ff6tC??$rN#PENLr;9Q zwGJv3Vo7#>1UB>Jk6l`^$y+!+s6c&dg^)eL&i=41iI*fnGB0m7a+pl|D)rlA4uL8E zD$LNSV&ohu*_72LXR{7{$l(~y;%_9*X~H$P7U2&TJDvHIVa^&7$%xcTtoc`X7k^&Y zysRH)D%wZp_bB13gh+8@xhx%^O47*LkJp35Eh z3ts;(?siY1<>Wu`Hsu?EUQ0Om{<%nTR}C5I8BHZWVkF8BFJKuS$h` zG;w!>VQ8rGKjTN-at%S|rgNDt2^O|Gx>9El@b(_zFT`$G?EGk;FHmPw9E)`739eSI zh8a`69yi2W&|_k_;1J2DbZGLHhCO2GIW!Zhij^?&-~DJ7zZ-MeXqL_%1;ygWB4!@k z71sa!ElRG1MZ?Dm`o-+|;1Dm;^%yJ&m0|xoH$SQcF~sReSfEoY5H)ED+C9|lmXLpq zx=!bn%P2;2>i#*>7AcO?6E^)#awd`P- z3!v7^a25FaBfn!qgLWaDn7VFDFX);e(qasUHNLyVobkXq5wR=*dp^lu{O#7_VonDq z37>#OQG`DZM9KWb>~ZQ@);?(F=#dKq<)I&F6CvK6xG@(Ewn(WTWZukYyw6Wsj}g7;Q}jXT(ph9l%)4+= z*5|2KSEh+p!OO@TD=9~67sC&jH_T+vK?QxpP4&(xjUi&%K%4rmB-OQclmLQHhysug zjyOKY)cAdcMsE7y$S2gb6`&XppGvwgL<2-{l-w|FX^`kS=IwWc)*eM0k)^m_@G2+3 zkUNG#?<)*HX@!OfqF2EuGY^lfMepJ0I5uL#Q*db`bSyX%-Z-RPQcMi7T?HDU#wgwO zk_%~;xf64pjjVOI59Q#jZ`CDdt;P-eJX{9YjEQ)R0Y$ajSR5hS)Vm=qlWN&S`#k*w zTYnkXic@cQwV4mJvptHV`v@>T>Ke5o)TXSFov+qmyYNU*cu3*NpR6qM5QE6jLvf!K z&iEk&sY|X@gkr2jyN|RhPnTPT*$j>e<7pf;-I0k2m4%1R8RUD>&7ilb!U4Y-zl0h* zuiV6cIR;S8?QJ&7K;8yPPqAtZW{ZBZ;a+(oL}0kaull_h!&ZswFP<1!g9?NQ<3Ko= zaT&YQq6!q>oY_x^PZ1Gr2gTAKJ??9j@k4sL9|bdjHp~5RsBv&?JS&VUnUrcosw2qy z$9Ts_KK|)FSNTJ3%n+wyg7h=JFuPok-%ne36)B!@I(a4W@XAmqKFwB`r!rV6!W9Hu z_Qqc3OS52okwaqa$&N@|RNf~ovUeY9H4+O921d{dDY*djX}+8*>{!ph>+}+gmBlJg zLk00nvC^z*pv4QS)@4ukdDE7upo!L*19WowqVZk3xe`sn)l{zWO!J)9cNQp{uR(>y zZy;v={mmJ@bheP38^41XChfu<;p<^0mV+OME-KtJHQMx(QnFDqs5C>8wH$ zQEU6c5be2AM&lT8mA+`gsOy(Qi?W#P=ZXohR!_#rgHRy7l-K!dX-dU;iWz&P7fOwq zX)u0-+y}|K%;bE6%^p!IIIMni)A9vG@zg8b_d__@2R$#y8j85yJQz`6JL(n zS~Mae{;)TB?eN6qr~QJpn6c04@dAF9QZ(tePRXLVrx?Yk<6b>cRteLO`$YS~ex!9% z8mY%^rtx%!bo58H22HeT@5p2@Xr59tc z`cfwkr>yrs{Ykq&kpKhu_A;OwvGv90^=dZ zae0mV&{;|p#X972T$&r;&aJ!^JauCCTlElcWKQS%yCvodG3a<`=s9WBzn-SS$rl)w|ce#skwJ0o7xXD=z01 z>snL>N@b{@BBu_zGx%HgUZ^!3z%AQ}tiW}z1V6&rsw^%>e zl3e7YJ|^ja9-*7r22-^Xw5Yxzdv>UmHxsBl2-pM(1C1e=vIDf@Twd6E=wquvvX@cu zd_fOC1Icu`N~T|sos}u*6G)*Q0X@0T;qA|RkbL^s&<>0%xg76Latn#B;pTa#h;%2g z*2Q+Bee;|5QK)`{&2AM75Zlo7@-q7w>g2NJom+UbMy06{k!BWogg{dmyqNyw7!5q& zBr7Zoz}s`t(DQjafw>3%<%P|?)-&w)4_kiP41Q_x%c>dy{jVx%N#>7rXo(8{L}=Y) zrrjKvHTNXS?Xk>kC}rgCuZkQR@x0}lyWp#(x0bsPcOwz{f+s0tTGYsp6oQm6+d2v! z4LRo$ko!>0LO^lU5kwloi8!m!90(GOI$;Y-+Daik<*juL08%hC^A9u~GOL7E{X`POdZ+mq#w51*PGdIv5>pUkK-0R7zt zzyEx2cF}a_?-f%X#y$w*fYZLQIrYQO${I$WAM9trK;I(=8=F#v_lRLF9|2=10P3+1 z!bA7*sC%j_T!AdSrt54STFJkN=?1fKY;fIIXNK)58NYGP#-V4}hbl(t?k9raCi`KT z2l5}Isy2vDr?gQl7#{B&{u*>j+dhjX=k{NJEr|w~ z=5BuPX?@2aF^=Qtb-dl)-|>x0if@ajOxbkla?+Eps@$M=6t%5Le1y`LTP9!M-w{s! z-iH<*BaJjE7?CO+hyH^E=S$7t#})I&y!M)=6Qv)m@#wFNrfO$Yh#RIVEReF0i|KG- z2~HX>U+qq4OeIJ5XtAip7)zEef{u+F-Gi-^DiPDv^?ftYyJK1BO_zNpbpZt7q`Y_ za_DYgaX3#QbIeAy{n?ft2csudi)kjCXb+3TFFIU&+1>HIf*;bGE`!FZ^tt9yV2ki# z6z$54-84N7%|EKHH2^8p#?e4NRV>S@(8bu8-_@_urKm0l}n^GO@yF0VNA|mhHH1brPD*A zz9Zb9r{+oD@Lz_l)rH&D_@lWPSpL^?!m|VQ3oTrjrMgc#De9ezj<1^jCTGxg?R^iUKC-DSCce=hPwI)SjwZ)Z6R^F z{lU#f^~hI!2OJ=W zUs@hg0B{PbLkFg{CVrcdrg*!ePq`dr(pR@#XaL6VA6b18DsA&T z!;YL8Rar;wc?Zw(YQkBy48PkQX&%*@l2;<$Y4B2 z88#DRLI5NoR{^t|lcfX1cWXTyCL5$QJ+6 zpeP}7Z|g3_kP3n###}$gaq<>nGj+Pxz<_zGdE@*NChA4dO@-nR3DwuJ)qJ{47i*?%fv z&RXVKIVW_GnJ!w#YAib-Se-Y>BmtzZiTLN{(rUxSZGZodg5;Ts?9{(clUN;a>p!Ai z>BIH-qtlq+tr;8nqa-zlmF4X{Kf03vzRASbeE(N>%{%?gRsmZ>JBmL(szJPpRREp% zwOpCJgJ{@6R;Nq(4p#yWdwQdDy|rfgpy>d)d`jR=PWBCMRoL_>b%3|VZ|+b;jO7fa zzW@5U58YK*1Yr8g>GoZ6K|q79|IxITpoI}t^?qPW$B5;`Cx`Y%*TzuQg&@3>I}6%b zSt8AI?P#oL4-N|obDZKUCG2GE@6(&3-^%m)1vW32|?FJ8maFvzXk?bg`hAs#kpL^`b!IeXn*mU znUy_A{CIsI5WhRHEt}Pf5JYXd?fJL+Hu62Ao*8NjrkM)S@**GVsbq7CW+Z@hSXdia zn!J)u#{DFce381F35My61scOR%ADzW+BXoc0TdvWsRc=R0BQ6dq_pJH7}uzD!LRNM zjAEB0WgegG%ZoL=l+O|fHW3uX&hy7n{W zyy$^oqLzR;8r$UJvZH|;;Zw(wm$M38H*u(SKKj6)s7mdX9T2Z(wYDhj)K;#U=% zDnc|Z07c3MOK1vV`H!b9TnW}gEN+tN^6n!DN_pA)_=AknCI$KzCHyS}1U&NYIPAI) z;SzxzmpunQg(NHx2b9YS5;mXe3s9u)6de0c8=HP1Ygti&FmWduI$)1wg3<-P3tH_* zUlNhCF<2Z~AaqWZtrT@_`@u9NZU-Bj6YF}aFVxN&9JS1gK_RexUeW|fmH1AYaw7F% zpTI5|YunDV%tyj3N&4f${RfFc}0ri-hRAT6Q)_TGF#$Y zCv)PAEjQ#S2WxTGltSjXK6T>8cLaokS=0z_9*SLWV2aTGb(%yBT4VbUKpJ~{`m?tz z3v8(_t86gRpuJQWBdHqPXuDbdKG2sT+f<|>`M_}gQ_b;$_eDxb+}^EDoB0b+#yBvO z&)kGurP#&>iZgXra?7%;fjb?Id$ z;8B_Ruu`D1rpp|S58KyljlmPp&OPiH&&uB^&?42Ve6mS?-nW-(+^thqKgRUzptw%N zSYOfEpB&va4JzZB2boJpcIh%a6A#;ef2dp}fo^|(#2?m1=uM+?N>mFu*`BQA>Z0X< zjS?L^5E?lR=TJAbo&g!9(6xnNw5vds^s|$x?D%4b+ep=QSx%;`%emiWX53;paDfjM zXEI9&KH0Lsu!PkE9DUzperD#AlnD#*pP@;%)fK}*#=FORm#KJ`FyVfJFl2LCU7w7d zLy#cQl10n5ZQHhO+qP}nwr#tr%jmLg+n%0?iI~k_{9SI|?q){3#61LGy6ER6n-_YA zk&Gs4R|MQTbGNADMd3a{!$4f#tC|q;JZs|iV{Hy;EWp-B`6p1j8QXu!LH6rbC(+l0 zCVG)aysZ=i0%?8Ij?wMnc^CQJY1^yVy-I5Y1=qJGKc2nCqlVe+i}7t`SXxzA=RX}R z&5xY!HI&3EUwLoW0Mji0O_Qzp&Kc2Sw;j#wN*S0=eNEkXSpG~!nFBBxtQv1`fgS4# zmc;AJ%0;<>*?;MKe6=+sW-q-_IzNU*jzh(Tn{ijr~Ru)S3-3lYvs|1QRni z$4I(~gA84=SYIqs4oQH5B|B-K(2wqT3jut1AmjGIQ}62nV0#9{3-5Ex0q2aS*?$1N@NUhp^vCq5IOLNC`J%0yyX-;CJ5I5E)cLhOkFB}lN<5qn()5r#1%5QLDBhm1R&Ak5VaI~1Jn!#*Mi++1z4Qe0OXGji@vGp zAgsUQpoajlHR_X1H^J-)N>{eQNWedPakk&Q0|XAG|3#nURBKKT_F6=o(&Q<#jXcZe z;Pf37;*sw}4bBc1b_aiF(R9+|#+g0YK3q)GqZ)>vlzYLl6Uafv$hOOyjJXV8(!e4F zh_ZRLlsFGgJj;N6(858#e@n2eSLld74%}JE`nu6A1|igMG!Z{GpC?lK{;=`!`^?u! zFlU%%?H_``9dX=-OotPy?gq$Ro?qI>ABK0%zVY@SDz*7B5m)svo8vS=TUZ~1cN-rM zyP2P6EtTm(zDj zs?>Do7s8-db1?9Dy0{1pU(g=u`A3JStUNYK{rM*&fyrE;N@p(IRq`PTr%qGqrT;3dx zDTbXqvd8&{CIev(d`S7hVeqC;#h<{C+4?kVnqqh;aVso{HDDCqD3(S6ev3v0PYzbd z?m5drl1ARO?wyQ`Bw?qSK`S5n&N+Q+iqb@XoMe$s8P0Ded}mC6SdC0g@y#J>m2vSE~5kPVb^8R--!`)iyu? zav8}Kq0ls4y1074L5zWrx~SYsi0D^Pys7=nC%_a7v*hZdTCs)lx2Qs3+zkTHC{i5h z#Yhe$|LfnXx}EI@6S+&oiB+N-zq+f6(zKF;h#fh1OfOw_?A0H&9d_m~w}6%gkWC_l z;NKp6S}La`;Iio@DoKlM7=6UUc?Hsyhm#eg3!>g-R{+OTsB@nTn7y z>WSX6b?tG997yuUIVWikHoCyUzC4~Z>JibYnzob!xuf)80M7wB^j_BUG92Ht3=HN4kvCf@ z+gJ1D#R7DWnAFIpB*AWRXE&yDG(@S^srIre?fL9Po?)K^g8(j|O7a-Fz^e8Z*q^Y3 zJ58dZQp>gOIwZ#t6FU1@!Ti=nA~(^mFj57rMuc{dPPgCn@Vl;g$L20}0BoDOAD%SI zefXpYv2lczyO3xap3GbOyAuU!GB#5$%+_va@99dBzI+ag7;aa7+QuIamLiAEUY1!b zC+Yf&Yj}J*{Bb@=elaYmF@gS@`1EqZIo0j{hvf0k?*Z<~kd4HV?HfKYmBd#)kJ)%* zC7L8R44KH{0APf)Hjq7>(3Z))CLTO{#Lps`%H)+d8Ap5O1x0+H$`B?jl&PJGvx}3d zp)Ksc$lk~bmW6?XfPvtDBOV@lF-sd4Qzv>c8$%aU5mRG(6H|H_Q#*4P3j#I<4nDsB zdkIx{x0o5VJ2{64F?Z*f2nx%xlBOvC>OGW{F(dcV7dvH*(AG!Qs<~luR&O$YTQ zD$_WdZ4FIGi1slR0!^V~Z(Maj@iA{7k!b;qqV^ZSU)5`E?4yI)x|?T;qBaLcd5W`%vpn7;X_|IQkRhWr)2)}kb%?j^kzI7i5@x`o2h2@20QXg|c* zVay$n#JGWbVr$V0+RjTDL1^SbH>D*Jrlbo>mz&Gm$zKz~M5Lbz{|ZLPtjO9-L2s>s zmUw)TKo8@iu6`~&nR>YGE)gV$$~BLscwi(UzZ`-*fsqI)PeNQzo?FUrc$R*fz#8I3HtsQt0FOjaF@ys3!W| z+KkK-CD+QZem5u}fx1<$DTXgF+n85Qjc10H|rx-9%A)u`Lb#Oq>7 zaRZ>2+m79einqe|ms&0jupRCe#)jLb?m`;C2A=|Vvx&zxqdax2vo#-g?3HhdWzWIZ z0Rz1xEC1_W^3M+c4($Z+D#6k=CWcxja!}2F!($zg))k9!oYwZ>;z8TkG1d5*h!Hr{ z_tP?0N)0mOTuZ3J6<*}<(gziQ=E!`MY&g~;?cQWjFGzl!*SQ-f!DO2Z4B#KL6&5AX zbuq<)wFPI>Dw~+_(lbzHyV5(9Jam6sX3I^$YiZ@vykD=x)>$JCV6MHJzfy$h7-c1W z%LY0&hI7epP=%H~z>bT6I)LUCB=kYl>D2PRTRI;L*U8T)>idqv#p!}`{bx49`{V#v zV+U;1xUlbnN!%scjF~5qayOdTCu~+4r`6))L`dXjUY2(Igu&%w{cCG(pW8Zy9Ci14 zS6i(UqgB#B6_540k_b6DB9O^tcpM!d9r`Pse-AgV*8=lG`qhY+bT4fC*FN%VY1g35iyn89oqa!XH%T|#Lpema8!g#)Wi=ZEDycnO+xLIR50@o%MX`pDJ=xqrX@Z!qwLsbm* zIm!t(m?KnK^)vGm6DQjYwPX|q?=^ApZnawU_?TeC7q66@Ex2wq!t;c?t}&|8p;^D! z(1M#i;JK|%{1UjC<}N)<)tF~1;Q&A}W-fhvIsXd}?j#ir8X0xieyE%qd!dM);8%U= z0eAd!719497i5~bKZ3lI+iu{xxFRyFBk4^AMC}gJLsbZh9`Vq4TBTL%q_rKLe0)!(Y6Oh!9dIrW0-F=QXnmVqjxPwaDC?23^e4i5gd zB1iiYCfm!E{9*i*;Y)v9#Tf#mrPuuO7t<4Ms$$D)E8Dl1W9I&hXU;!;&|KwWzMxD82sV&2Rnyc9_&;@qj~qI{ zXMioZBtdt*DA;KJ99iLF#+Rl5=VIVU@IbisO|$^K3M^~XVOtP`qHnvj87c8nGeHyq zR`I8k_P3T}GX+zSh^%e-3wOqq%u`i_Gj$$-+9ik|b@(1AeDl7>jw4lq!L52+U;mq6Nd|ah;VJ5+?U!`YgCJren z6<&|C5~&+efNb(+$$VTp#OcQYq4`@k11sRmUqc-n_v})`xJv4*V*0O}ZfN&j_&dFb z2qLE76k)(4XvA+U^?p^s*srEtE#kw~yYRAwRD|*xUPPMhLe!!iGfzr*Vwh5%R-DWhKtRv(hRx$~?X}S9_jxzJ=nebeu|?MO$uXWtpSnG7Y*YA9M9OPc^YEanvDUUc z^`Rsk63-g<~*c`Sr@Z2}`n zIPUAgdj}8jC{?^sU>0mtb&&9$kr8BLLp?q~$#^A=+_t^DrOrlX9Y7RTZ8=w2kb z7M+M*{G=Zl_K2|^uio0RG{iS=G@jrA?=q{*Y&C39W()?rnhU^ven&SP`LK1f>2AEZ(fvf07xtUqH9f2r$xV_Y)3j~dJfYykRicQ zm0NHoSC81##!bmmvbKn$sen{75Nc+oEQq8A{m4_x%>j-Xh*k{3d~x z7aQlA?L2BFL30!pl-Ia$FhwARRE7~_8T~`j#x#K_;ZTtil|%Hf>FtJrV_>`TM%gKl#^gkg&BJ& z=i>It0U`h_Ac4_i{`U|UpTcbPwVVL`IQC3X7pEe3W!tocNbKLo5TF=3bLFJl0Iu7C zl$rYu2q|qttNY=rQ1(t+y_vs=-1S>uOYk}4R_O4%y9et8yFHkdo+P7e;2#H6C2Yc@ zmwI;nW{5lqV{22ROgo0wL#7;8VgZMAo<4`KIdC1(uiZ{v-|j-aK6dPyG; zo~NzldDD6pN*1YbE@P&Hnx{|PT|1(O&^-JsR#O6KjWLjSoXPsp=A+&oRN}N{)UaPO zw1!556U8Q(qY7i8R<4*7owCLcmv@Z*u9_oa!LXyJdP?&)*KyXYZq9O~=? z$dNnr6yhsTNx+aJY$}|Fw?y1(hF9DqW3sj@;5}+>qzVB+8-0#m7m^N=KRdpgRn&VA z8S|ro?@RY0FDzq3VXlHeFGU3=LEp!>^@$lpTVY-E9y@9p9i5i}HMxlY8ZKIhfqlmLvp8bFDi{!js zS1`}h)tUomzj^!X6Cb~(%yr%n^+zN(5Mk$fW-2gl*_+o*2&hXL*z2L#_~8=XI{56xUn8&RxEFpak2cLhX&6MkO0jmK6(L)n5xNS<#EHXi z8pcj45bXMg#QyXYR_~2&`mKfM#j9#Z~v`p|4*|L(^qfd5b8HQK7sW!pl)!J@2adr$FW9mJfLbUEp67Xj{hb%FO5zhJL6eY6g`IfzIxnG zLk%}@#~m<>+oC($#5No+5`(ln_X0RaMJr(16M>MkkGeNIrxTmJ_E?R_4wpdLjqw;Y zwHc#7mk>eiX&>gnl9I+2<+zIR;5G0WohLt#!=yr98FY$*Q=~wN;RRA=1@PRY-#sM5 z{nK4$Uf?s_Phs~)TjkdZe4*KaWD?5hXw0GO`$NcrLL)8(%}0+H&#lp78I9v6@ppb^ zX6|t~=R;J`h_es@Xk`m2HL_0i9K66J>T2GMdw2rV*(F|1^|Xt659}YzG0yh3P#kWR z09J?)ITsJb*XvX;%vWuZxp%`O)e{;;AzR>pQKyEznkSBCEQ5r!zY zo^SmH3Q>XCkshcGKz)W*;MbeD)yD!A-h{cOmOGDFnJ&}7Hxb!Lj&cAF%am&U8LIDB zk;HkfP<8Lv14#myQl!6x$VtS>#C>@7ntYV2K2?a(D1_*Zn(;KJfN=uwIot9=I=NiK zUmhoYOD>+5Vv0|`9Ui=qxv|zXRy)}GX(-e~x(E6ohD_0VgJbc>9QJ%5&kl4DMeDhj zuRU&**2LOg0?BD6KdjYK2iWzrS1Kr;_u3EY{P~rkf0#!#>rf%RjlKtxe*)S^+(jo2 z7uF!`pa#au{>G+&`&3D+f5}JArVk7&rF4G3?y~p%8Z%rzZv`h_+Ojio{lc7cIm;<@|cEQ1Y9 zg?$8%=7b#s$Rm((ty>8n+uo$hE{zF^#!r${$z~t_VE(jkm}I;%i&%0vH(ihmx<2$) zrHW^EG!k+4WkHWXk+JEupDb<93vqQ8c<>8(Zn&?#o>Wi|2n=mm_?Te? zvF!N;0bi>?5UO@`vRplt9r(MBhNl{t8!h@Q6R#?3H`|TjOe11)-IgYA|DdoTo8a6$ z9fW1v!o^nb?U2HQ2AeA0ChftB&SPk7bukJ?ch?_Qec~iE);qJU764S%Hx6> z8GAoW%j@>slR@!g@KD1@(Ey-W3{M`Jrng#2dG^PeoW*n^wN9QWOoEf{*d51We$|1G zuAjLvz1Z*G5z{*I>QtLBVGTvE5@|7-Z&+PXT{9|+Ul+BNh*%*y436o(oj85I3 z$@=@#wTMcfI*#B`L6~J@R)*;EEXjM-XkQo=KWH_8!D^ zu`R5URsWMOEKNp}>4B6?Ps*wU1d~I~QpMePdEm@}VjQ4o?)*j*WuyF;_?4~ME?^+9 zjU_p#k{LSt{?F4DF%^MA*W}Vs(fUQq!br2&1h&sP3^=YjTc|J*-Bh^?G{%JPHlhS}WB?J7CdqSyw%9R!Gg@f}qb}Qe`7>F)T%pj@qHYK2NG5%_T2W>+e zd?3X*h;e~^sx<~Ug?w=_K~x^^)A2HFyfeK@UW{TY`NcnH#0YO;PU?oMu$!_nTXmr& zUZy?)T#c{ev}E2JLI?d){Wm#`q64{N_qIBEKKbjq<;u;6yp`+#wCI-8c{4=d5vRlp zHg(+O1no+EZqJ>|Oj~dpLgT+x<0v&9#c&?SGV@V_H2fgv$N;7?46SfV{}-6^wgOQj24z2IcEh7ad?9dBR1bB8y62TgStIQJ}iCes#M^m$yJYg2dS zfDYeaXt0A~E0-pk@3$)i?9X&L4$DLDZV)>bVa$>;fPduaoZOkYR1kYd+p2?7JBpAC zku}GE@deK#@K4^rDO+5tlN;=2qrq%`2l@V3KI#G_poKAm1&+OD>Z_286@An$$`^ao z6){UoyOBiS<*4A+LD#=z{e+Zbs$MlxUX|Osvxo6#uZf}p9Pl%4@^pt2 zv841Ti+qQkHFm@T50l+r32=HZSPc4SC4m3fG#R}!9kTW(*HgUGfOI+01s3N8XQ{(q zBD+Bz-($=dUXrOa3B~b{Z+U6#*PawB zdF)G(zf)UWUUD}nMa#2@inx4hk}MF^le*>uNY%47Nq@)R z;(dP#uSAkg0a4&5QsfCV;1iz?Qh5e@wKN+m{cn!w!`Gg`Vw}Y|W92$;h$vgLA5AZi z^4)ii#^awKa_C?FcbxRFRcIXuiv-vwVt=joUb-J|VclG+Gne_bie%tf33{?SW+jA+`!Ib-M z0Qq=I!#!1KhmXWiQW%{OY8I%m$tkUk4<_tHN?JJrXzt#=pO;&51~E42KQP>+LOEL< zU0WgvQ=|bY78K@)cqz$t_3~byIRg09iw| ziF;!$g`Jx`9u`Ih(9=R3%o}5?(UP6zWBY~|vcOb@UM$YxOPEf99j^Zrka@DAhz}+^ zl9y|75!Ucw;*wwRVJuW&>frfPkxsg;yt4Pm&&}2;py>gk5zY@uf)1^7or<;^IwHK8 zUt^F79oDEJT>G=HA5K`M%WG&uEWH&v)h@0VV1 zVb+D64Vgb@xS$?vz4Nz}eW6X7AwnfV=o|qc%I;^Tswbbl;);H>U+utbAj56$yT^&W zMeSc>7`M3*sH?8>sj)~ZaqAu)0ocF`E}GTIw5Z>K*f4=>lZZYgfRoKR%$z%9eHsSV ze2>JWWVf0+BlPqhgr2q`QB`lR5(&N^x$F41rmx8f>b;@0!iIH0)%rmaVFl~MeKH$= zxtT7&#h^R)2)Q|icz8@uL?=Ks0Qa4yg|nXMnvfOBG1U|}p?baMn#7qrTy71$y`29z z2>udg37rq=Yy7Kn{x|5*7k$;Claw$(jlx+Vw$sGh=!z7IJcsI4_x)I02to(AQse$A z{IGuMf<+SDRyT3yIyOPr)T7kdkxT?Z%xH?B1}^Y`gwr7MHQ2W_BFB?x~s4;Cvpw`R*79Q+2kWz^W)Z6G61>kn~_h4C2)1ct)l1)#t^s|zJq1TXP4`s|xbeI&ReuWy(ShN))b&sJRD=pdFWsvn2f1kD|yBz6Ipk~1R zveot{MRjq8+XoHX=2Tok@0JtVh2ue3F73?u4a9V8nV#TJ@;mY^t22iwhk97-D(|{n zYIRN9+~PKWUS*mew21iq0J@5%N#I^c=&BMvDD^hL;;HfB1*EhL|IQc+2qYA0Z_vwg z&t$6yJ!cuwQ$F@$j^>~UNkfajnBK$U9CRtK-pA&qGSBOsPvA_m#kPd# zqEpK^6_Q`lP}H?i%P=xGD5-W1PG$ez^5OKwno+42pKU5Ww)1%Ly43_(ay*NBD{xF& za{`-ju-x*WVCaIUT`IqR(adbny`T$V`mnIwy?wMnBv_Mz<-@17&sUDgPDUb*2l4Ac zdRdQUmCs%T^vGWXOQIJTdfIp90q)kVGk1VR>nJR=UPj_r48CI#qR@ZeqmcZK}91nVYx7j6&2CGHGZVrxqStF4OF)QVqRY!yo$a@>oMS7O zfjvW?&1@>>l@w)-wFa1R*j3vN8mBv93O^A^j zK-7}7r5{MNu#LpOeTH7;K85J{=92Bw>s?!Dc>&i2jT zcA8?i8OnAG^}JsdnrUZ}bgz_J?@?z0y;SS_^Rn1h2v=%c4s8dxj?PcX5}0a%gSvuq zDrZ*X-VId3yAKm7kHZ+e1(PE*@}Zl?4tqbAFWmmfBlnUiVW68_aS5R>+La#q8z=^B z{be6IsS)}>~=O?o;XJ@ zj2-AqP&BqXUrGu%+omuEaMwpqjs0AZ=Q+zj4^$R6_WFVF6=wtC-|Z)B%1VR zpgRO>otAKSd)se<7{?AGl>v zL%?ozFWfzwDyRP72IsM8$O6yeu?#bZ+w^o^}ciK|JgDwbX zS~#pJs^y1>j1X;T+RPW!mSdu9qMuizxyJxG=3)mL?C{*(im4(wT~v^woB3tvB~Cu| zLqO-m1fECg<)K4%U*@%4a#%hH95O7ftK6DKm1nvg$TRK=;uG9UPT884Z%D7l8a3pHN5-e5<;Uw)9UthGPqiKV z#NU+i1>e?pQ+1zRqCvVE6civv?zq4<-Cp1BPB7+4BPSF! zPVOFv;OywN=>6n(4$s9hx-K?{VH%9&=)w%e4Mbs1NhpD}h23^vpD)!`05csA9vg>6 zT4abcoeKL~IT{qnbh$tH)doq(ND3`PW1dnp-%~QW3?MZMV-T6K~#e$&tBXs8u+l%hgen%(_nLb+};w57bD-oN8qfKWPWBW+_ z6@R)bR|$Q{N?FaXEG&unEzWS-9lyV~?`#Hu(5Ck)a`K8QdGT}hsb~2+Rq>J6xzeid zgA&#rX?L+T3;&WYW|bRyeBas0U?}jQkTs!C9mF^g7t-OxK)Mz+f}!g&AC}Qf_qWy4t(fU^blXGd~(RP z=Pc2E7D^(yrp|p9{gqm3nw9I3HSia`4)!ZbB7bLahTnHcT3YmP67Dcp0m%}xkmulJ zOy%QNf+X6K^W{M5nrhI%ZLb<1xaZvxm4DCrrOKRBSwOSv=0>OD`T?{l4f$4WDWXGp znHMWV5V`r5VdlVm`-t3L4L;gv71P6tn4*@oAm|-5 zgxvNv%#r)c@ARX9&(w08S|+vblfp_9l4Pb)sQ@heo}0`d)PHC!{(BlJ{tPKREfquI zW!|Nz83yyUDoz{HQY?#x8Iy)x5%2BK%Kazp*3~-!`c)bd#?-Dh-Kol9WslOM$eNW_ z1BRh3Q&U=(B~hOGUYN@bJGW`BzL%QK@E_BK#0i9|OQrp>Rr6;Y%9>LC}Js?~(1O&iEmn&M*vd1(qOp;$C=}VAMicxW5EaZL)jMl#hF= z5{r6u?2BR)IAC=Ilgd0N4}O%cQx@N*v1&`nXGPYy*8ZFagFR$)UYG zr-LuDH3_H&2S{@5KhOccTt@gnkT859vr=>b>Ze=tzYnpM<_g`vgT-V!+ybo;j6d_u zPUv&3N>o0{r)rV+Y-Ws#xC0Pk38r@da1knr6XTsGd(!2d9=D{XN{4wgcb=4tqliLX z5WT!>uI5BomzYbDFCyudXTpLMO%QEyev9FdNztDaJJeOS4NH$-yNRTX`TsLE{`}P=bJrbQRm#mNe`A`r>sVO$IxZ_+Pf0&>so10C%{eKSc zB6K-foUKa!nXBJ;Vl;EYRhOJ8n2^gYU`ny)JrvmBkp3fR-nu!kkl3IKMy%*yTsf22 zq22VctKsR8#g~Jv&^s$)62NLd-`o*6W6ewk9;X4wFN9nRG8D`;iKr51T~%{oJ1hR0 z@=KW4_aljSUeDv1u*LD>G3Jn)@`noPwLU@B(8RTJc3y$XM6f>FT12x zv~4QE?630B8d)Qpa~gFbFXB%86|m}z#V6DYhSotJDbmNAe|$Zp;%WC)yLi){iQCc* zKBa-iMhsHXb#YqSR93~6nc9Ycz$Fpp;pAk`pyYmI&nvvKggoQihdQ4qNZPD4s3sac)oMRqK!bI|0r}*>T#K#8s<4yh9e#q zk2n!g?&(-4-yp_7s_-o{dcv?=U-15fd1G%zP?zROTD3UkqaI(h2Fc4pAAN0^2wQOy zAXRM3G2Ywsby>okq~KaC5o{1rBPC|8q=~Xtq+9$YECy%^Rsyuzkac_^a(L^W00!qD zd4(S}r0_3&fTLb~AKCbRU1>&Bp&6JDxWQQ?3p-|2y4j^kJuQ(lucp*x{ic@B@Ad2B zUs8@~I4)M5aeaC>bkdl5%*Cm?Nqrw~g+VW9KXoOb9n1ai+!_w^!}?BSA)CS=TL{rY z?s;9C9Le^zcowK@q#7S)W}A66IB@2@XZ0WnIX0%V?O=gk(2(iM_`wh`y1wQz)Me@~ zLdpr#In(PeSDYPVo;JOz%J~QJbD9+d?*ff->7mOOm$!6|(u6sc5tbTuLu zI@`c-rl)KI+|YqJ{;&cY-dQ}|E1LI-j#ZXkr^5Y%(6d%qcO>=8f1 z!$eB`2_$b;a687nujNp8io^v%q`~-pmJ~`(C9DCwe<^c*`*fDUNV#53PW;+;af8ng zK+nntjZ76qVnY7*QbQ>Jmkdbe)7bHwrrw_r4Kkp8rO)ijaUh`QLyy|RM6 z8LduS2!Dn0YfkmD0Qm1@8`8*VkFVZXE~&s-$_*)@^iDY7%JF+#?K#7AEWfm20%75cq%@biOJg}(fz6-!`=}lLbtL#pCZ77nj1jQ zl650*ZkA19+@&K=6DGxD2u~+OTgn!CHf1ROm|5X})#!qJi#5KDzbi}NoB_LnTg(ls zkH@OBf8w>tU#WaJR7Ka8Dx=dXsBi$1fm&$$3ho-ht@^H8A21Mw}-iLjJwlE>L5qvR}d@0dc>Px zKw3J^H~*r2SfRVgot+PqbW!3uq2Xg!Memupebn&|<+#*>wttN(OHzXE?h+J@2-_Jr z-g<|_gUetw`p-0O%!6in8WrD3$-(z1+(^!vW-n~B$4fH1J-9bt<$>gZcgLf98T%c$ zPjn#|6m%`Pg4lW69KIfM22#-cBmD_a`)-Do03sXHQL+gSXGhh)8`o1aWy}c2DtWYR z8UY`Wuc&IyD#CB#q1A0>-|0fA;aaL`!GNni-URurWC3zxyqzN|?g16LuIkex~mzuoYMH1Z^dFrxc z_MFmP9(%YQO{D-)CY1nDB9owq9Gu5_dMdEj;=yq#S*k{4mXZvpg%r#&VH%`~``!(h z-d68<2%JqS7T=W>dg{?NPIR=PSZO9>^R&8D^{kkHuR2=zo&vePSr~cAX>f-6c<`Yu z-1{m!Tp^JgQ94A=rEIets2x1YWEtKEp;)LT@Ca=gn4U6N{)+|1xtD-jW9D#Uho>`k zvBKw?#yplnNk|Z7s4pkl8kU>hBs6ZsEC?s4spA4H_TWmZDUf6lpxZ6!yk8jGhqMhd z;d?VfZV-w2vEcsMM@zB?#?6-QZX;C-bZ0@)=%LwLF=O}KBNv|SPXp%qTf6gM_WH*! zjqqxe7}Wp3$I5JPvLMJ|dfwR4Wp&zCGhSh2JSEWURC~V7q}n$e;@77a2O=$`MJ+K*NlmgPi185PGAaVxvrm+*QUs%XH z<2&D=_HHvX*iWplljPFv*e7co+N}T0wHh3Li#18a&fM(53s`ubL&Pioh{c69uq3vI zF80IMgVX|YTx?E>B)`}FbJ@rH<=z`uJ<6yZS=#a+Nw+g@%2P>#laVWnZ@k)~iM9z= zS3&n_V9@jz_!Ff^ORoOWeS{gt-Y928#RE54uIAA|0tY?gHsy-N2!yS|4Knog*L+-} z6PwkMi?rZ3oqMbM9xGk^t5CU1;xp+1;t5qn?B`!aYL(fm~9eu@Q7`0=Ei=dk1jJ?SFY=H9-DU&W; z&h#1l@c3bn4zKB|u8S#$s7MuC0)|0Z-H7FZbxB)RIyVs6AvkT1a_d9Xhm9CzS0mHo zgShP|^xazJ{^vXhm!<1V2kvZWW2+BK*eOLJWjv+4sHoWT`mJR>sjm9RQesRo8vYmO z`O2Tkobj#|$2`2Bq>)h)sUWsn>UFFp_-)ok4E;3g+vbdlxi4H68ouXBpSJCU*hxob zL{l&YC20w-ZV7@6X!u<`x?E$+mV3xg{kP(*BCy~uh`GaW6DYs~uV`kXS{5st7|Dc()A>TX9=Z=WMo<0oG7zB9pX~vAL-#DG`K3mkf2kYfk1bhnyidUs;c0m+M;oJ5z9MbyN6^9|J*q zOo7zus&gkHR?N#Gsqhpp=)`u+WqQ{+(#w?8qGh>{T*&jK&BUBn@_=>OUn9(1LZ6?L zSTcFwlfIXGneucpEQPkVkUjN7k-H=p8N9thO^)+r3`i}5!N1QLe$!Cq49lrQTdf;`Ixc53kV)50nZk z+$;D)X=e=W!(s&~8(h=-FSr6!eff3w?n;Y`TK*vo?k!fF$W(N4q9llRIQG zjx5r~n4O$%UGnxN1b=CSGTU?qRwM2`CNsQg*}6UqSbU5m9lyvR7nb#`TER4y`qu+Jmj%L%Jl7AY9kzWY6TGj0Nm&kogjLn z+9&S8YEu}hk>p&wctS+ToG-e0FV4lLB;TVvSe8cFHR1VO15Kf9B}oU84=nU<8Z3i) zasqonLI1JG+w@2F2i>(R?LMBS^F?K0VrU*I3&*-(bGO$6vYdmhSgz`AWBdBW*#Pe% zZFs{H_xA?A9|m&3+vR6(@+RRwF!?w%<6I&#rYmVThu+0B-W=>`ro%YBelE;3$rUir z<55G6$51_D3>T+_bHhKZXA=$8LQEKVQhJ)Co`T3zS`shK%|PXgDsbD$rY}x(zCUHZ zug&WY!nqBa8y9^^$@szeH8Ad@2*h{^!WA-K{^Z_xf8xNf|K7MHS4)fV*SNwJzLwdD z@67$O!Mc!i;|3A5jOqo;nMsZL@LD23)@)a){4n(HWSf=T!>wY5CCtuq8?a0~PuyhJ z_{=ghyIaG+mm7R^^8;(jCx`u{4VPe5hj6qCK~GzRTFwx4Ic&O$$+a6^*cm}(*-Uou z3_((^cqw7RIFzNd?E%EDra@(2DWmhYGLogYr9eGbPkw80(sY%3I8gs{xFzo1bog_L zH?=xOPYxi?ef5VC?GefNMG#Al%gQJ{Q&5KR*j_7dpDRfV(VrB{VdNzR(gA1YX9- zWhGS5dBGsHx1H@d`AbhQtOnUTE$LDjyEd6rv&%%szSB5Wb@9h>HuNvkLY%o20=D-mpoEj=%)1j%~*!x05nk@t%ly510hu%rV%ykJgt-Zs+EGGbl|s^asQ-@!IC? z->U~YeEfAT$35~KH9tDhl0$z23`0TyLYcL&Fn$HRRZ>kS@HRb-<>}R*(eQnvfkA^) zC(#dA<0-~Fmv&l;up@Nm4E?)WGLT}{^*?9P&kS&Dn0gnB1#fFiT1R1i8N0CSEjZLB zlU08yLqd8n#`Q#L)dBMs-hZXEM0f&Hz{^-p^uRa_?ah4xd4a0N4x}s$uo&+nQp>jP z*Yk#yrcuKtS>iB{GWSJlR@>6GbGDow%$SV27P>$cj8&y?bGOa?4Q=Tu%@nSN7WpT& zKg8}FsxhhTOCXT~`sytS|KH%&3!?lrTzGoV{6ek4xOWk48h zi=~l~uV4C=)Ff7O<2=>yY>rA(?snv*e{j=V=3 z7OTo6!TGA1X;R%!MFQz|z7WCGBjlQQfxcol{=4cTx7NR(MkA!)9kZZY?bXSpoiN;2 zB7-_OmfDN*7Q`5T{k7dM24?|<%EPCA@UL%hMitR*&>U)JEqs-;T2~ax$-~nGF)a26 z=4}kr!VJh;Y&i}e7>A?xvMXFc9u3UL^DEfuf19zY(`hr z4Ofp#O#uHUx}lqdX!*_mN@?&!z1)4}K?v?EiOvDOT_V@Hm7|aAIfC|tLDXM$3tOxf z+y1D+(_mJ5^MqVikr%%}KG8!dX;u4pk88E{Nqb_|Qcsy2w|NYSf&^^k6zH1qVpHFi ziEpgky^kK8@V`Laq&HRA+Ttb-aRc>7@wHu5zK%aLBHppPhCW-E_E8M1Jd8O9K8ACL zael&Zr*DioBfuov2 zi16hAuOYmXLc2;RF@2%sIvZzD&2dDzeV~OIdcQO_#C~ppoCxsG?`0d=R4DmR9@kaX zvR~tD!_qfh41049G;7nQFVnUmf83>JvS}@oo|G4*V+^!af$+1IHt79?b{t zMhqv~#`&OfsR*shrTdUZq99GSw9+ge_g*eUvV~>t?uPcL{EPD`1|&}}6Gz7i^k^P< zXeJ@{laCiDvwuywWro`FI;j;CiBQe9iBRnS6Nc9buy`@Nr-vOTx zQKdKa4_k;5A&_~)SfCRI`7hz12va&dF?)C z1t6ssorJ43jbKki-1c4dor-4_pIr7X+v_MFf0acx_(eXZj*%qwQ3||4eUZYOI?2_w zgb1|IUZIR-NUAdB=Wwz|&&aivHW?_wW(*um+3zHCkq;ig?oRz2p2*&he{-Z!v8AFL z{xpew zNM~pwm8}1uPR^3%G3!*{Jk*JBcRV92rPrqOnTYzQzS57xq&r;En-%V`!JoZ12edV! z-$@I`GZNqI%8xtudRshP?gJ~}R9Qi8857M(96AZ`F$Au*;ZtrbFvgCHDn6(+yXaBm zJ)~ETGLoA!nA@?uZMvf2xXm#pA2~~^Fc+KhSqwy0m-)owK@z2vW(oC})4>CvIU@EB z0=Tc%UEd6;cbiE(pGWWEGXRPV%%BM%G1V<07k-jhqqurOtoX?*gPpJjT6!ML zOAqKC;TdNSy;+hzG4sJ_CQ80<5k|&QxQE+OJWFvzk?R`3Q&$QhfC-J-V{EjLTlr>5 zUpgH&=F`l;6>E{rd`|2p+&1qIt`q76XRS#{l~ps%QT60*)>ij-g7$>ct1a^8Nw=v^ zCd7a-w%zhY_!E%T5zZ%pU#LBl;+An8*p;qS0MO)WCk|fpes7$ zP4m%(ISDiJx8!J(jsH@K+Wd>xTnoYkDjK?84Z(uElQ5aG1b*Y zMw2?_d=vYlNB;XSD#t;Z7*Q0}v)!nyW!-A^>i?g{k}BICs3=k3by^#I1>NxHV@PR2 zA~DM`-u4mJ>B<)mYn)&Do7&l$+Mi~EpZ<~b|8XF3?$NRjP6-m?--*Uw80uDgrO)`- zh4^aizUDjg&U5P$HXnpr|2o><4U*j zvwAsV^w(V^vgN-SK2EVO<0o7;*rNYlBsK9;MuE>9hh>kZHLYua)fr=d7S&G;(2~K3 z)mzGHfVQ8w(zv5m&lGfY_lEfZD{9Yif0VqJPS7)w(zlRanVs2P*=3cHhEzHjV}*;J zJ(H_mud#N*YwNe~X=MV2CfL8AX72{6kXS&YZhG@T)`d|1-WPTpHXitys!`m;dpFPV|32ivQkdr7^>P!}+dA3gn%+aZ;`3f>bnuGBQ{z*JJ zaMhU7%|0Sxo|ajgcI!$I*8_vsLIOOMRimbh!Pgo6qHk|glu#nE&O7>WOrtHBRQl=k ze;{vw%#uzTbT|A!b>9Eir9#5@)y5G|`CAo$Ve{x5IhG-r4MCrpzz5sY*}xK@AvZnS zF2+Bf&uO;^I;rj)=E~{rMHRj9p6@77+)}d(AjXD9;OPn(lS2d)7%1Kcp3t`J-j7d) zX?YCnaLm-0clm=?b!s`c>9`f}3uc=N=#**1!Er}1FSwr9nsK@?*>PiG5f3u`yYe>4 zZy4BujIW@^?%Lk2bZ=YT`-g-r!2d5iWW??f<__z`l0ez;DcSh5VfY(gF4 z>wDHnI{oTGKKqq0a~}GO!L{a31J%ln9x{-Ig}_rEflmd-dH7yUTH!tF2liSfsJU6C z8A~ahd`56rPJ%FCeu2NbEKGtFz+LEwjku==))ppjowJP|4?NT7J~pr|HI<7a|$Mu~9Q7J_@U|<*?$R}GUiF_KwIOej~;WR^N$vg2XAyD##B6Qj{L_M z?LclmYUD+Fho_vYJ8b>>U;6Q{COT#8Lw30?y9aQr9 zE)AHRS)oLdKKJY7?f`h=}I9?g3Qn;x{e3H+UCubnLCHvSPGH zj50~hq?x8rE_GoeZSs9Lc%W7;vs-3levcQLo$(f6)sB;pWX|x^Wrdk=q=fpS>Ng|f z1E*b3VE=}U&qJpuz1iWB^OejH2wVGoiA-J%2l|E$=zS-+XK(w$ok~xZ!cSLT( zO|(?MgB@XHLE1HkSw2;BoVEqRn)bsx>gRM+SduGA{ZqdGM9{dBbe51EP9bv7~iFh1U)30<=YAR;WN>#EqSv^N$}Nvs-29zF9`LvtWrci}1@~CT5R@P|oxc_=W2t z6vnf9T_~i{E{iq~fM?nxTHdQ)+OP)#7*`?BX6n%(58Q>X#iJXz+rLxbITojhtV!K# zF0KTnu7jH$j-O3;G$TX(a-%?s4=FaSK+xHb~uz>4-FaW9#hnai{n?##@J7$y?M=>vt^Hwg4afh()nDwNe zm;=j-F0WH(SnZEP+gs{J*#*9#Ux>Wm>4B^TVwyOB!tJ>`G8f6pWw+4Z@A+ES*|WY~ zP7i7UTj_3h6uHKIIQCc+$m7j%Y9wqH-mdKhf%RSgZ9HEV4cRMItq;s*) z-`>B6N;$xiVaLYRo@-3G{oHtD9oC!gb^BowV-Z;eQs%Ciwdpy+i7LjfVmX5AQCeb= zz~*?=iF)sY;K^WUd+N8_E=^#1a37BX8@0UrHJn1jZ@2mdRcz4XBHFl*rcLB{0YJjs zRXL~HvXi+_?NF+*Ou_O~A{(*#q&dQ5ld9=OY(yX4hmd)+B038Z#cJ1PdWYyB|Jr9^ zmLgy<(NBz&n{nlzj)FlrOoS$I;^kAeFSwWk;}Zn$o~k|=i=*rNq-g%%@@HaERhlNm zQQMZB?zA%rsdSuE0O*yE1PyY=ASVV3`P^TNPMgp3sFaTnU7G39kpsy=PD1;ws=iC!?96nuyr|K(yPgtF2ILKNqL-tq%xikM#Y4|Oh_&`ar=B>>y^v<*Zn9Du3|Da|8r zpY{f=p?jYqIRtul0t<6x!w2`7r*fl{ELJa|kwa-+*gL;;pxc=O;1qwVYED{}GE^CU ztlsQc4@tSr?wl=W!mn*b<6!fHTTsQH?Ul`oJUFNduYmv6?J}tiBM&W|2WWasyQcPZ z;MyDvS}I|@Zhd2!y2Q^i-g9|oMQ2>X;U6ckK=YiK;UzLzjkwcA8l=tzB#zj!6?IKk zr3RM-M=4q_Bo!B`$Z)$!R<4(47QZYsf^mLNz{uU1J;JrXrzif7!<$FCq{foY-I($B zjYb&+=e!qtgkmtyh`@7sXBVy}%)oF$46ndU4QqNoB@E?%dcVj2JAL#_cd4oMTP7dgq{SP@@Ty0AxG1TqM_rS>iS&X;%# zJk;l_xud?)RD#AMJHZxjFQ$uHvsOx)xHgl&Lb#@*e??gC}P5n3UJi zCx`aMzmNn&F3;hZMuCKB<;E(bfvnPWcAmnvw>j33T7 z&a`v_O(LHroaRNA7_)rL27gN@%f5sn@oRcWSV$}okys*vRMAaSxO$weeLlo>ddpQ4XD-gXai%N4Q9V)&NS1(qJPzI6Zmu;KOIeyREI0iw7+C9iF<>%b(j@ zfBOWn;pJQOM`ZX);6p+KqW#szY7p=_1O)BqXoQcKK+=4oOr;doQAr8mx+){jTU9kQ z2>m>DOK*SZQ}%r^;K!Fs24=1h1%-M!QeMh7=%HLCh0ee^hnNig-9S%d%`%HhR2nLC=eZIR3~ZiiVO0g`NC^JCSbe zB0Nie2*8=ow4k=|uDB{KJahil0QZrll|_Pq1X=6IX{oRr@8TTruR1T&u?lf9;vKxb zz6{AeSj{X?;#pE6JYnhBBri5=FUQdTj#tj1EKNUaD;TygmW@xU7xBwDFzMo{fr9H- zz^qZlqC?$o@#H={>2-#Pu1Wq)5IjZ~o=3rt7ws|Qx=bx;vIrO_8D^OZP}8bYwu)@3 z7fsV1@g>|1M4r9{MBn+Tu2b%48Xg<>`|k6YDPWGsSC-hqcp2uo9vM7j$?dYT!hdaU z%0KJ&PfH8!kf~~eD8rVX$T?J7WXYay(-Qp7K1hprAVu)Fp1N021qNheQB-&){VPLg z-mhp=XpjA23!a;`88F}G+ifcUw7utw28xQ05c`R20A}!6hyamaLdkSNs=TXs)}Rvo zjBO93m=<(HW1cRy$5jQ_VAD@Cvm1ez0-Q84Rj2KNWc=XRNTXX%=AD-G}&+t-^y-YVK|HBSga~*vvZ~Mu#JC0j=3>Zk@AZhl+ zWgmhDHhc`}FSwf`!G-t@+{)GcIy>c6nwAU-UkwN<(gyv?ePr^u68dBnjg zD=Qi%jthC`-F^>^v>V8;x5A55@CaLq9uS9&e_U-Y65xSH*Vc%alIdAlKb5@Lc%EBw zQZ;h$d4QX5D5IZJ>%)*XJXGz~v1_sRBK?dc1H(7>zG{PXynTc0lU~IZe_rXD#hMl_ zNR#-VG;H$?HU7pw$5gVLbf4_DQ3Q`h)OtlXz19!ZsA+kS1^g-YdHp3@G315CTU##( z2zs=%Y8iv(+J1Z-s>hRkWn^Dz@?Q&H{Me#_pSX59)Fcf|^%#6m)iwjjc2F&!-m%aG z=N-Rh=E%6Io!->MQ}4@lNRjbtYwui}3~Dk)Xu?!ZADhf8p1ph|Y#?mXdx1$z#H=-) z!t4D6N#g!6yb}&zK)2$wVV<#`$ErrCSF_BqdRaa3qunzKn`qGI(X=Bo=qtiistH)WmZ?ll@V7Jn&B8f#*GvCjRy6J$Hq!(g?T4GP=e{ z6i*=?a(EOj0DCn+ZmLs}&k#`V105pD_A0txkcf4dNbMtH+#CbG37tKaig^1wlyebv ztVWIF`SvR?bR`;)lWfODCNP(-BEX?_GeU}QYN^Q{= zSDM-ZoBNNpvz^fr!#AxZUB-RSn^+zYK!)g+^e8T-*leNL z_8s!y@NK*>^^ICQz<*GA$6$1FGKdq%1?hhU)N?;f4R-t~r& zG-A$l`L1$btbL|Ima_-*vTmipX}y`+ITXMF+r)$5knm*YWWjo!8{-hp zA%`xjZiwf(pJ!$+sv_xi4a?IYUj>nYCG!dATw=0kReL6l6ur zW<4Sx06zH!Yc?rKgV+Ft7Ent-Fz(F9JJ>MI?%G3=z_v`v^hW%*cMX0-brk<0HlXkM z!)+}kK7CDM9^N1Zv7upb6|_<7lh1sfcxTiF1%cY-woo4e?!-o!CMKa64%J#okr@LvV6%T|W)*Nu(u%1%ZjYw!@o z@bThWp3UTavPoz}+cLAO$DGD4Gw`|hUB`zlxcLeYt`TTFsD8aKf%2Oieik~ROv%v{x>eTTv}nh*u<$5Tu-yG?$a#sTQq_l>lh z+7T}xO9}gVuXyGI6NXVUS+n*aTDFtLJ4C~*2AJ&l(Hog+nk~NqZJ2dl=Qb3_l6iIi zW($O`V@pOuFZ2wR2uIh0*dGH;E^Q&nZ`gkLk@F|ChY-hb`RudzVTx2kTPk19j~eRZ z;gHsi?3l{#zyP+Zb>`!2F%<(2N?l8*YyOWl1 z!s8+nzB55oE?#5@BSog-$TY1ZV&Jt5=PGA$=qHq>AG*ZM)wMaLjcNdXi7EQDSRJ1! zRKyO2C(a-|?v!iIu>>y{Fp$YG0*~fu4tw3E4d=s5PMgUc01LSHj^GGOhxPS78Ld0^ zSVhnY1{L*{rDUZA%(F+QoahhNN`6*M=V%$LLOxLknD6aowbdx>3_b;WCGBDR_EUm) zGxLwnkkG?v=w8cBN1Lf4ID%cMOJ2l0R+qQ+}@l5tlnLW(d%Lpdzp9CiZG_AUo}mIhKABr_;uT095- zG3|PczsMPA5KO`F4eEyxWi-FZo=7CVvNk`5PQiy2wpBBy>tiyHugCON8v4!-;O-Ff z{CdDB3Eqh?#OsKwEGSK)p(WSGehelV2-X&5>By5hZYKD3CljjAm$+%mKn1YfS_nog ziy=Le54>J$Uu@ARASR)HFS`VnKzw{IxD;|*S*pc9 zrejvEzGgb230H$v_5SNh)WFI4Gr^b5x<&N(sq{G>#&A)48SZ+Z16DU9YB&v@1SJcj%r^MBAFN7KXp>1En{ii>RM)hxyGd z$%Yq5Puf4ETyCpm@W;&cDk2On9wt52R(Oc@{p(sao5_8kvhftjxUyXrs}S!9r3Vr~ z#cr;Z^{;@8Csv8y$=gLHuwH&UtRx_TWEhE+B`jz6ZZ^F~w2~Gzm9cIq{7_Sh$ zA=|WAyk!PUL<8sOT>67H!()hs-8!!ZepR(3^{PXV*fTLby4`+hmPFd1p^bcr^F_br zq)!2OZFw(1a|FlszblU#gVZ3O8_w{c8-b}-_-nZfg4SOT?3!1pwQvi5JyZA z_Gl-Y-dObIIhl?P;!Xfke}3JXb|FNz`=8gi^3O(WVq=_NOPs$RNL>nuvr@H|3b zH(FJ|qbF045y zo(7--RJU<2r-@SjxJ22zWVPD3sC+lx2arYR=~Xm!S<9VFPb&t&D1`UnGr}9lE**B| z=GS>7heY@2F$@|zj|IMl`>pM~X0Ot9dq^+~xu%5P3tj3`nghTV@Qx~X>(O)Cwfb1; zh+HK?=7m{5p-Vf1unBTveTSoFb0#54x*jjCvxH02@Sv{l9@11pQ8cwz&`q#2@H4}NGFh;B%HSzu$zb&2JT0{7L;v^9M{?j^PIYf;|>tC zOL~gvy`p3D{@y@bw~@M#X4eiM>tc6(7E#UwcV@XI9C-|4$$R13>vso4 zqyJ4=X&%(JgIzu5cm6D=PwDgMIM+?-y}!isNr(+s%m!36`+uj zhbAe4y`l%P5@HYbkSTe3lROobx~W9I~6h6UFHdcJYq+4 zxe=_?)h;V*eW=!MM=$`-x&1S(Vj=qI;4FltlDKw89CPCos=?w|2YQesg+HPYD+)J- zx;5)v2#)OUOr z2^{iB%+{dSV&LxNjYufYg@Ns$kkQ3li>8BGQT?;mhE>}1ZVHz)Q{X&<-^8UyUKUYI zBP_1Ox4(p4i(s0Rt>Bt?OxV)FTglP{nr(BJvQ?(J$ji*Lzk&v)mp~)_l`ZFC($RLg zmABWjWNoLJK(vVju%C@J0ECC21*2d@VGES@8y6c)l+4ZzF3hL zOi@S{Q+_kF7JP=mavRO|Cc=l+i#Zxs8HLWAajDmINL`o z`00fFXFLiskU(^gTwI~?zu9T5=x3prDNAUR9Ev@t*=Ze&{*-)eCA7Z|g{IS4`!pr6zABs5$q_*GzN0YiJev($ZdzNbmX(bVOe( zHw(8)d4MtdV5J1 zEQrIUESt_AK4w(BUq&M2|9M;+_|I)>DR;8onJ5W@ zsgI?D5%?L=?=g=LVH~u80^B?=fctj9Zn+=tn?Q&mCI-Pw7D9&ryXO%_&A?fkF`lZpn&61rF9 z@5Tx>8D+dS7;#VoALcJ0r{p${GcYb>B&Cb=Q4yaK#C`&dFo~Zz==D5L4<%jAmS5T< zF}}V4^FI7;(SIuwR2*T-O4ZV%)$QCo^<=E#WoH-TC`NDd-OO@zG_)WH@T|I$ z470j{Qi0HBlT4UqN~grPOVa>ncmwh1sk0d1Ys@7};vH)on}Z&@AGf^)sTVl^&cC5X znh+2*ut@f6z@C^w2OS=eoXxi|ssc$9BskttBQJIz4a$y~e#Z+wQpw?HE{(|eXtYh! z@U+T&Np!mYtDqo`q@b^4hxTw03dEBPfP0K9ZR1bZpTeqnDqh^)e}9*B7`vYXA`!!Nt530>BrdED*v1|L z2(Nr<=3@D@8m??1Es zQ-MU7d)JMFGS#^*<%1z+uhs?=EGfbd79_yn)xW*pL6LkRXxlEbSlt75dPMwhq!@~s zrP5yW_mGfD=2*Y|$Edt~mmk9yo>bmWu-Juq)~oCMZw7LZPs;9V)EX{aOm|ixSe?0t_&kbY*T+Fr6Yy zPzN_q7=y3=+V3}33)wM@!xUfZSrSxiNu(HVSEXF0R}NMT`sIIWDdOyP!oj|nhv3iT z)-=X%1!!QjN`^95E+XSvlij*2Q8(Xi&hQs#m&p_Db&Ix^TZ4>P) z8l!RZZGH`}9Q+Z9rtn%1LIPs*)~&|=Dy~h<7O0c) z_C^*T!y=U#gBU!fqB<*&+Kyu;+YO#k1JbVAj+UVZ{^sIf64U#@PW*NJof=|O)s@|- zS|NpUJSv#Lw0Ziri$UyaS%QZ9qh*fHM>|KhG@QBys+Bd^mu{tD%qb4renYW6lW2Oc z_H?)frA4yr?)Q`BY%H<+bsDQ{G4~j=pNb$NM#J~>*GYkfB_eRIjN~)~U|?yluj*hkN1~AaNwvs9VZet_mQoKZK5#136;`?ND8;K96i}22}9kO8CpxDk98lJ$RkE zCWKC$5%_)b3Zdu;7Ys6%Wj^pLTReYF)wwS{|)<=E+;@z{%39YKQ+(^Lg zGO+5f6$6v&)%ss)S2IbSWoD3&=~qPLA+w;YQKX*AW@L?kTK5fOd5se@pGO3hDg`|0 zx$yVtHCP=LfQFj9%qMtvQ(rUUFmth8ETnqeDSoN0y^SZhgI}-mfgCRoM8M^OKl8yK*RLg7 ztLxOaw@=njUYRpb5CVvrLDp!Xqv{miWNee3isw2sk}fK@#cUogQAo;%+dcBmT!UwiuiPGRZmsEb^=f=AmlpH4{#;-I0as!>eAlF`DPq;zUH;KHN zobs3_5uz$J?i!1L6#bB9@Rmf@D;;|5-Ba|Y2vONtNatYypAaRIxhIVsj#%OE5lC)T zS@|zlld*)`M&VfFsgMuiZPy9^)x+ ziC_N$`7~8EKS0}v(JBYy89$F}*FTUP@*O15=3xO#L?c=KjRc0d@%B7;Hk!|_Oc;#f z5|(~Zq4T8?mh!{iMXI~NS_y5#Ak!4+Ufarsh^T{*wuJr{2+t)RRWpVl_kT4M?wt(W zr_|~iTb6?ZjaH^9$a9PKb8BeaQlS<7W#}8VI?hZ8`Qw_{Aaw0A=?E2%0uJErMz zjh$gW?nrtGm~Vg%=buLp;4;Yp>@I+IbWi9aanwIXFbSIAyMpf*ND@ts*rn#n{VHZ& zxaRJS85o`8|Jc&v6P_MhlAwuUF@zc_eb+28Y)mPag+p*r0|h-DGBmHhy2DO1wTPM9 z^{B$bN2nH+VDYQ%`eu?1^Ek$THJOfGl@#XmC(fr*F?J0G@|PIIVUJ8GQpvPR?&Lm0 zeL01Rz=J?0uuPpV*P}&ENU!idtOqF6DG)>dkB`DO z2dhdbzs`<`7V~x8u`I8Ij*mffzpa%`=#QZW!Vo4Vha7Y7$C%+Ktcp0ICS91bn0*v~ z#&I+DHl>~f$+Q{;v~5Ib9X@rGcxQ0#6rI(`ds!BNz4*_qVEt9L z%56SW^h*Y&AnziaI7hP`YRk5qF{ zk3$1r3;4a&gZY`oEt~NVy4@mD9;3>JAavy>2GtVfcOtClk)d%$ECsZPMKrh}xPCaQ zEWF#{)w#z+kdS*0Qmj&CRWygy0R?|b&(r60cH!=?%13$Kv>~cg_iVLr;NvV;EFfx9 zcz%AXH+N|+XLCyEezWYYE6ZOktn4!)UJUBZk0$p+0}jlv@EA6Vy2*-aq=qHDP2S_m zu)jH~x1F}MgTl)s5VIMgh!=iWmpxf0KzcQSZ1#r~G+ixcDVzG42sEYlArI^NNK$!# z2J);9_SvSf>btN0Cq&DmiX0Q^%n!an#{e*ejFC0cz|oX$i7b-&_#vx=LLQ*amxg5* zF60|HKl~FosR)hLZFS6Gpd1GL^8EgEQxThuP+f&gvFrW-r?qC)ww?e9%WGbp{`1S4 zNSCgt*xIBhg+wMWG74OYtsfzTLH zTv%Te>TR)C-MLD%&=Hq-3RygHRJvD5{TfH@#@zA2BqsNoVMD!3E6hDsK@Tg8e>R{T zIf`YP@u*QDphXzBtR()}FgyvQj!i7Nf@bl^>T8r%b1dG(XV|zAf4<@CCNGg1z|$8v zDS1}cTcPlaT~+SOSdRO~`Y`aaIM=eh+=r|Ki2YITZN*Ybz$W#up_->*sO8Q z^Y_IHugleQ?d5>bbj|eyF$dbUx;`4P9qP`gj~JwrmfYN7=EQNu+MpgsroEk3%?o?sTT?a@?r9tOB*h-OUC>)| zt{~vt9Db!~4#(PHJ!*-_Pb$+{+%IK_xl#r%R=0L$O7aT4)(sW8 zv=is+P;zgJUipo}qah}Jx7fZ=M(Vg;>tX#_$PrB*~z8z&I1|j zybcCzetuHjjR(eM+&S&xu-j(MtBO?mQx$7?TU2?65F4nx|^0 zT$N$C*@W1&EsM!(VrTT^JMC0X);%sH9w^TNCn^5Gr`uTvLzJ_Y} z6CCR&uYmI~Zzl16MHQs@bxk>{!@X$V#XM+Ov8Vi_1Tg2h;(GhwA+v^8PS1RN-9+94 z8P=PbA2F<&(~4sRFxwsteo~Ig2<2%o7E!JYO=FTSNK4<9c7Pv?)6~*5mDcE8o=*Pw zUdM@`^H8Ip^&(XsvO`%l56D=d`_l6#`>tiXg4?KfsLYXw2y9%p zP+$zEof5<>619Wv#sMr39WRGcP5ehhgp;9z(a2~a)@W0Tn(aAPmtN~-lt|qp5;E)^IhkH>F-Sn*9b)DPLZE}|)9E>I zGkC1plqq^m0#ct+Z!YnXAG~GyS%;jDPvZ#4IcZEoTOcnJ(dI$TpGitCK)I4bK^3K! z=~ygq6R+c61EeTvV-+$!ct)!>`kj?X%=P3?Cnp>31P&>u!Rt$6ZPgvt)OX7UM~*T*gn|g}819Iryw9#a3-b zgj-g;!a3R9o-4Ta4G+oG7y6pn`{NnhX}JDT8=f9z((P>~ktgC&9VFefMrU{^xA zdDHl8)&=F(rb-Klb{SYTBpn>bz?>52iH046L;?wQwA5dw8_g^wHW!Jbh1UR6!r3?> z*YVluY5^W@g)NX=Vqw{oYLi!sl2!oN^eUtES8a1$xd+0M5jt3RannQ2Hgv{yuVqiu zELF(}ENStZqq(H0ieH<$__jRnqp9TBuDv?%*)lCu==DO=AB+$ZFz=iRI}tY-BWA{8 zNw<(^UD9o_)&X^U!5~xDp3zb*X1To#)Ody~M(&pR#10MQ(rN$|3SYN%bPlE#X!4X^ z2!(dFK1ovBRC$NBO(Qna;|tte$y#GzmxZPWqjB&HyIB_a&)xk=`L@|*zKUoGbE3e{ zE=70t`f3Rsj0A^1eH0OF(XxLl0J_G&%Kzvp8Vi6YiO`Zci7qsNQVAZt%6sSkqYwn2 zj+^Zpp{PZ5*e&U;K^BDA$@VYA%yj=bCP@x=g_fUZfJ2W$Tk5dO@R<(TQ?q{XJ>A%} zVe3cn(Q-FXr-faWdc-_oaDp1gh7NJC6M2nQR7j$mbvLC1GZo?fLQSF5UJ&xfk|i4I ziKqk8>@h9Lp*&+a6OUaeZ-_@7>9YTEHlJ_~AvqX&5`lZcy9zb*=ccwGR;ew;4Orxg z2D!00QuSQ~vIAp`T|=-Sz>=J2+qP}nwr$(CZQHhO+qUP~-r0za*vmisTV486UER@@ zot2rhvm6}eZ|;{|8WZEcMf^ALedr@=B-w|R-OyjEf=K2MTx?UdLk`sjaEb^%I7CzF zfV&~go>?-$N;jop@|DRSH?;hDvin&?qSQ5G+RUN@Obc=RTXk^P?-#E$Qr5Lx z9^}S|Uaup(GbsmDI<-URo&RM23sY2Ez1g!4%xx~1aiXa$SQ%K#M+bGZ_3@-JVu9AQ_FWqXoz}?M%a+>#2a9k}*S%}GUxLH#ujw_#UO!o9vvaCRaC$_vWutjzmBYpkLp2HJ?n8mv8#yA4rlqLvYQ%Gyw2p zpTLT4<;Qu(!o^mU$9;+yRe^jnMOC41vqY$N7ufRDjxIKZqj2kN_lX`@0tyadXu2t7 z3@~SBkb!5H!t5HcKLw76nS}Olj6Qy9d2xfFwzj(Jk$2AbG$|WL#R-hMPR3#oDFane$^-y>jBk-_?WWfUYV9cYjxh z{M^KwA6$&?7hIfux7Hu(if=Xt=OA#q#h&{2-V9a#k=-;+8FBe(4d^-#)n{jSC@CKM zKz~Rd+99jermV{J$KROeOp>eY2o*K)r8WNLR&Fc2{aam~a8rpbUxf;TRK;SrhUska zC1s4_LX+yRCRz9ea)_R-1srMB<}%YAoszELIeKQ?V1A*lbgn&%WWA7?iW&VmY4bif zLae+?=1*94!8PUo5AjOQ6yAJ)X(>hKysc|3I4wwUo6qlXPHG2|smS#Il2tp>jM zd0G}el7qxlH0-J|_U-@l{Aa|tOn)$^qw?*6&qOzY#RDM;cLrld04=&WZb0yG2{0LG zxbO#J6yg^%9Bu85zBJ(vL|9>unskQfGZbZSy^eoo;e$ziHOJa+63(%-K@Dx3$c~$i zVflq@qnNjZr#WA$BCF-FD&(6!Z&z`@y(QU1+%O(51gPOE=fox}U;$<~RFj0H6$E>Z{yRMNHg2 zmh|sb)(rhJQ6{E>P7Dq1$i+Vrt&6Y2Hoa|h&#dlYGXUu zr&Vc_gdt_M+_^A2+9zOOW-FAS)}o1oW?9_PEi|=(Rz2}aeNHo2aBs${OLYd6didHE z8#gR5g$=faO$@cnp+ikhuKFi)T_#Sj^YYdQhRQ{nc&HRO2ni@t60#rkn&c*2uyBQ& zA2kc@B-UJ1kN=zSC_>+wP}(#6odbjp^C=<{`J>k7CKnwJAR1H+eYH~y*uq41F0IY235$ZB` zm}27XUr)LQ`#gR41uOFR){D4YWBco80}hdK;NGMUC@*0&2-`x4D{M^02ynXE{*>66I zuFEkN(%sleF5sEqm(6(m(|((s7Mr`hn)La0!8Yv*NY`X=u2T9N8%qAS-Tf5;x6~ zbY27C%t#S2p7OXBj(_&Oe*F6Ei)b?69{-qOb! ztgTC8bI8vH1CtsIfyi6l_BjzcV9>VOPQ56tPRZ^lk=B!%aIelu)D)&xWYo;SPTx4p zkABa7b(7P+7;pw4))=m46<8O_Vco?pk~Fu<*f>Uabm|&}HS{hMOqb`!$HelvdSPKj zB2#SdpigpkwjOy z#;`dFotb(*cTlCmyN?qB5WRFQx4=LUF#Fa`&_WAO_$F!CdRPph1E#Xb z9*8R=%PK;x6NAd|9B24&2^%e`e?r$BnFbiQLsm_LC1j9qZteJ$q0ilkevF?}r-%1i zmy%ImW%pBi)MqkIeg8B4{4}G{<*F_T0J+$2;CzX6W=UzLvOPo2i|Hmj zbM*rX`@tHwWV}X!{)DP7z3HgzYB4|8NB^yS{mBf+Ci;RGo6EP49mtZNcwZ7c^PWTS ze6qWckOWj7I^ze4$tk8J#AK!Gf~KV%`Tkw;`%NQ9N+=vDuw-3L5ykfEN(F6Eucs`$Ym0Tn{nMkt-i>h%J1X zNe(c!S-p?=EC0LB~PcYC?9o(odOkvYC4FL!HJyJSjfcqWCZ z)g9=tfaY=__RDcim!0MQybtyD$pvO>n&20{Q}G?fhLfe+{9?TI)NaEUBUb+WwmYyx z`sT_Nm5)Krn1m1!lKrhT)B43WJNV0oA7BqWgXt17b!NKDYAw2x*C)xplL~dD@2KKN zc+UgbR~WM`UH7QbuItk)FrJ_lR8zSP#aVqn@%Ouz0IL=(Di+rXOb`&7`&g zHs~kj%c#A$c&oa`tO(h+gysT|LcYvgVN3H6lipI{c%r_jWlX4KpkShBw`yGe!NJ@K z7ajn=Eli5a6lfZ+?#0kp$~PV{?~okt?{)}8di3M-S)6JHL_$C`*NxQ~ei!a6EY;27 znw{8M^`<`fQuu7w10P384BmD zKo_yZBY?N2+#8?W2Ui{|6#L>nDAmBG`@^d;?8D2i{3vnPbUJWc9!L5sy!LQs+LK+xStg_ocVMVqT$xGpb)GtEBc|HUns*{lXj`v=PN;AoEdtmm{;UV+@ zuB>ZRfb`kU-=hMB*f#YDJOh|pndxd~3j`e|dN$0bVg$+~hnc4nlT0@GW8`vur_ zIGk+NqrUfO+Ow$vQd@E&*Soq@e|2NvPB|?-i>GF3x!onFT{J!jiC#Ss_R<%L5Zm%i zh@6AKfq{6F0TgrrHbo~A>oS||DlkLp7A_!x*3eUpD-&%e*7hZHhVkk!?J-B|Szbn) zAb`FADXhFJ{LTM&$6q~tvrt~lR{RmlMV50$!xm>`SU*&zMXiRCceK2>MVkwgvQp?2 z8WfIzNVS6|wbfTw&V>4Wz&9v|C4GSqfzvLOAbz%~a$TD~zMcvh)a<8`e?KpZi1a!N?$cpV`V2iScVABCm}aVicp4QnDItb@jx%eUEQjlg zKJtcMhO4?qgce=HnD^uPdW!cLDJ+}tK&b0FSD{$fBg$29(VpLs_67NeZl0(XYhPz4 zrU~nDa;z>Cm`4j6K#?2Bx@mxLtt?@@SKOP$oH;El$*NZ}s>Llt~* zk;vmum%d+FG!V#aQMnT&VDQ%OEbN;o(%x9+eWCvID=37_$)DiCzKbNg)Q~l{@y5Pl zP9SOqTt1uQ_Jw&w zx@H0VgQo|dOY53K(8f(;bi(x$&suk-#X(Y;t9BR+Iaz}z#Yw=D92fwEqZQ^97=t-l z*MeblJ?dGHbdUmqeF5@Ya#1EuCn6KdR?0v0Q=huh=mFTM1OJb683!)moz!0Kpc|-N z{KQ+oz_)ygea0cl!L2xzvl+_7-$j;-Fwkk$@GXwBq>SPnlJ@V*+6mQ zMdyPc$iwf=B1_?C^0n9e#vJ%pASW<+_OnMm87@AwxBaZwxmA+Uiqy!BPswZhBJr zzl~@YaE)i0??+se49*bsZ|}zK-dkHNm{N$Wb}0`@aeMtM+N&WcFx$WU>1DzLP`9fp z=-S#2M+)^NPY1I37qGuNDU^4l;%A~5TCQ^?1H36EPA%?XR}6diM4#U_tFJVfvk+(_ z$jA+JmYU!(b7LU>7QuLy<6<=E+N+I&5|4rb*ABmC(Lj?YP_%yUjimC`6n6%(#qufh zuRmV*bZB%7NjyJ8@Cr=#O#_H;f-SpRbVQSaz-fK6`G&VKbaIs+pdr92iA8=q+jIhj zi)PNfG)@_p_sL^80;N) zFj(L8s|1bwX%8Xq*E-2$@d%>G*aSKtiX}W^wNK?Y$ z(R<pL*jiSz7>{llZ*#)vIH*@ zXyreYZkxpp{K!=B13ZH;=zyCKH2D`B7-_=0 z(1L*bqOc&`a0!Y26%Kr1nX%^=`g{%Ep zrg^8pow0Qz8&i5ku0?PiuUO#gXEU()#~fy~LR?%JzQ=tD<7O1dmc;8*h?MM|%o;hv zt%5=fUoUbO4e6d=+G7=x#4jS@ILwIp9#4;^CpcLb+7*=FN~b}3a&TT%6zGdR=zey< z!de8s3T|rr9!FHF86mNsP;H4Jw6BgG*$}!okeym{hGeOCM zaE z)WX`?#F0+a+Q8XF*u==r*o02n#MaE&9G{t;o|pIkRzmvtVUmb%{_CfpNsKl*!*Tnw zjKkvQ72;1sV0_jjSX-8ul?X#IV&c)W`mJeYa!ys=<%)C0V=3w6K~7+a5oZ2SPp88| zUv}}NQk6gv?N#g3=wG+o5=53&#SYI$^UcMYUTA4ioh8@z^kl+#G74eWy!g@3))b^j z)f7H(sxpNxpfLg4OD@e3ac?A;39_bxJR9J;YUj@s-i?h~YJHWqk4aQJjA+|Gq{#Ljv$wXZt${j zYreckHG$|{>+|-Cf%!1N`kL74Uq9u{rV$S4b>1r!&FxnEA?=ys4H|``*P@7?ke> z3Cf4R=!KI_h99!4a5U`Bu#GldNKLEMm+5`mmAGlR3Pt8hi0?EOVwe?%+s{Jxg3}Xr z%BG2?E%>_n2AOR6W~?|83L-dcmI>p3 zQzncotp8soTuQ17bxN>NR?=mOh(J(0>6c@d8Ic<}pY`!2{mKd8!6otm5nf2|tR0i~ zCTg;k!9ic3xMm6>+aj1{O^?9PT5GpRv8my0*$8{N{`x+S$We*p8!l9(L0>2qj3etg zMh(x!g?dEKQ7QmKOP3HDSAu7X+FY zYI2r=m9R2h7ERnLDfkMx9g=h&XoIetM~(ISin$xXpPh4hWoiv}?~u%jhso5!~{cNcPj z_uh#`|Hm{k{Woc3U}RvW|G%ThfX_tF!ou+XY32EfCJ-q8%R}e-YHtsH1shZp=-2Uv zU}JD`Co)qvQWAKnVo%xyy%DbTEFyF>^&Osj_!sAh!s7wI__ z%l`^eLBYc0D(w5HYg%Y_n_B5>*K5D;bXWF^n8M(~%|up=y27_NRAxSD8}zs8fum!Z zKyLmq*_Hy3{6KQ&yb-JB8AND-V|(jkU??k9oO(@T|E*X~ka(RP*^{LusMDuDPNj<= z*v+e=7?&k_7%V5F(m-%=z%#>sQL`ivawLCf|4+LO!f&ZPv)splMrD)IjZ*gvF8^{7 z%h~`?qE%e7iq~9n$Z#nhYa#|({WiG6^T9JT$Uvsron4c!2gh)=a98`M zZ)*3T4zPa~z=M{;cK)12Lhi4A^J#y>LuB>tBY@x7QrK12zCW_h$IhGnCOOlW z8H$9-pthD&e;Q7uTAu`XvYKG_yT2)4iA&gCEVGBSi#}eYB(~3(zAZh7?hxTr$i!w==eyc1V;k@6{sMWSog!D5{ zR2phUdX9On%l(rM6$76BIbdk%lAi<{_epdZ8+&F`pW`6|iK!JH8+#dFsmD}lX&zcR z{}!aEa+$ZipUftXq>$R5pY)4O^bi(DTij#L4ARGgzGk|24lcWo|&YdcIe#~EAUe5(u%V{{o8G#8bM3EqDEn($EjP_kWCstHB zV>*b;lCh=}ST@Q8@q5Z-LM6ZqM)nqNM&0)zDQS}UN6O@RpAH3r^5Lz09fD2}lyqFw zjFtc_*F$B3d0}mR)O8ZW+spYmzkRs22aIK zPv6XocR6Q<=n}xdg|PUEBeK)eqVqcFA=$w&9}|Wl4ZUMpvDGmqdx~=q9NGTN(>|`+ z0w3zM>rLAzT=Pd6wX&KVWGDTg59opW7Z&UaLArPm($CAy%i6uc73t#(mM|fy7rizs zbNf<>w2(ew?ka?Y3|~_AH(KY5+Hf6Kjk_bp1Qhs}cz3|9?~s#7$`w?N52r&b;4jW| zcGfV|`;4q-gFDDEoVJmXZ-P9TPr710X9a%X07<{jJJajN@#CF29M!)J%G`e@KV9fi zfDe*Gsws#Vm)QS+d=i6pBPg(*Ml?HvSdJjV!_EN_e!t`sKUb1CTq z@*iPjk)!K@RinEs7WJ>iLDh6j>C_C9H$1xwu3{6%<}1k3bD=KB zc@%GEFVmmbXv}BRUPUNXl@{T9#jt~xy?1P>Muyx7>Q+_y#u51iS!|pnPIvi(62O^ItCVFQ>_#)-y(Lj9?kJv~-lTUXuu z)urS*keptjohn}ds?Uj{KxMIg43Mq!k`qsrhyaZV^^slcU_)SKWP~fJV>@}8l^7sQ zgW9i`oxonDm(@3cU7%ACSaWasyh~5t9;O{1o3V7PXdMhvvPE#OS)#9$3h~TW(t7ia zd=*9Hb&k#3I-~|h$P(ick#j}rbCklgF@%1II`Rd6zGko4FA!sr3MchX+IoSLE%mkq zygKw*eOo1kT)v+(zvP_<`Kor4Z?k}sB%lu|yRIv5f$V!p3xLnf%bi4Mp4xsIufN{2 z3PN$~+174roZu{QK&1M&D!c13S6@+J{;ZVtGZ$u(_guDiN>%mouq=vUJAqV)9}!(X z%|jsrDw2%SH$A9??q%6Wu-&o47O5Nu5-+gY4Fw|CbZiqjI}nqcs%@fkDMpirwj5V} z#nKdg}N@$q9`DFQy2YUT?Xi z4e&mHl^EEPhden#5hYzy>B=d3!bBNrWB*TlbFB()@I&7=`zALc#TrCh!^(}uM|%8+ z=JlP^i7kSe(s~D!>B5pQ!If8G#zo_F;W5))O2gv&?JTQCjEGgVVvP@ znd)&z+gKoBHCo(Mb7cA$BIM8gwNC#Ik-qVM%~bUr34D9BgxXw~X45**w4DqIb@hM# z@hUH)$yBM!Vg9|H6k`sOq2j@lqU2Ti?lnVmjNr}b(~jx-?~FOYyc7;7Mbwx@Z@nx0G2FRq@U*IHbmZuJdD_|0$i;X*_Qy7v@#$ zKjM(tgMBKf+0d*07NkVQOPj)Gt=Y!xd(4>i#4=SOL=SEkZmOnT$^9+yFyNiPM>t1M zjQuA$-Uj2uCwQSPGLTi(oft|T|CjQQzqV*Qx|<~TSX&rBOF?+p2I5qWNEI3E0G61S zyCa+wgoRuY)KIcig(9V7mn_f$$Rr>%?Q5~%$?RxnlT-7Mq|Pa%@aP|N3IsZNVINt+ zvqb42_s5EfLK+|E-hx2_AI(WO2V4*MLa$!a1n+)?8bsXF-fl5ar487WaldTL_z$ldsPe3{pMNCxxLrGp>j}^^z z(VEWDj&M*EhM9$ir~`_r%ZHohOOfMyAv_5V834uIi@rX6AB;;FM^Xk;#!@l`6@Rmf zI<1{OTxPH!Pnjy=_w#&XZ>xAWm0a0`1z=bN9!@eDy;B_;yYVinHp?5XsEpbiXcg}5 z#0r}iY@eJ=UT-*}JLUdporDM1h*JD!d(Bj{7?6UgvVWR6UQtBD)@T_+>pPrWE;-T+ zU!hPfRIYn{lCjDq3oc9gf#rxD>XqW147s!Jl1Vwfs8Pg^u*n}dc4+A1M>U;{pk|4TJH@B&tYFv1TXO^av)`NYe20jusWY= z!)#gm@p)CI5^z{U#0!c+%#Xtea`_v8o2(3$INW!Iidi1hjGBNFfh2m%Ix+ z8rZW|8XTa?KNrYa96aD-6AcpTRL|PGs(RL$xZ#kbj)tj?0IlB*l@P6J)O-0^zB0 zt91+mqs|XzprjBaIQ>Ayyl~b&J|1XKi97${KTpP z#Evp{-;eMh!&^K zT)QK?{&ZD=|FnkIzL!5aiu5rdOsIJ7hb$d)IN$Jk5=Eewy1P=3fLGz(WDsrok=W7N z6Pp)DMI8>VEr5@ur|+}L#qc(cI`!aHHX+`%p30ZFUeP-nYwdMovRshMC#Nlf)`F7P zk1OEU`873Ja#&Q0_Hy#_IX$uLz#JdNpv;5wZP0xZ7`WzNgMK8FyZt~DAlWPI z+?dE9)PsH<3UBhwtyFUxdU@G=0@=9Q<`C|M26CYuVcKrM!v~LmSw)MpB4gBE_DvTq ztmw)Avgv$NQtVT**-?2WWumL$wfJfGiVYyJHk3Aa{{8FPz5jqqoT-P)V8zG4Gr^K) zPm~{tHr0aqYycN}&Yzl9?pyGZGCwdHLD1q~c}D{Q%KCADt&p{k$8ls2l3GX4k=3RQ~R+0l#4;`a%;EMTHj&uPrl!Lo^&J*ewTrp9IV zXI~e=qj2FRHAi95og$2Qo_C+)J#0I3gmHAV<^&{N>_a`BocyVkgeOeLkTtOk@!4fz z;K*B~GQTJiq)S1+O!?tRf)!>Fk|(+TE}eV_$2Pl{p$FOrJjGm5z>Ozkf+~)#L)gKm z!!Im~76rdKWjbSN@f5^CD5yCYPcW(YSJ=9?RtotIw?8!hHAaRN^xzyoyRj$leOn{$ zd8y_hy5vg=3>bqnM^_z_@USXBCugahlEM7A)z^{p~5bbwsqZI~I1+&TgOwL&};`_angH+tJK&z;)U z!AH!u{KU!p^OIjn#StR;)-nBl*HVPAsdPr)8|XP(Cz6wuK1K zxBX;bVITIM*jd={MniEv5aCy&>T!6LR<|uu6}E32+4N4NG6QOnnQ0G)oRnD$pHJOq z-PWmmt!Zitxi=@v0R|@c47ib}I^kgFs4}X_-}Er_vXhyDRa8ETX9L>MLzM(zxPkq# zj%8ZASIP$;r#$ua*H?1-L~ZuJ%7nLY>#U_CEXVBj&sVMybu|>S?4>eN!Wpm?Qa!^3 z4K=ZYGV}}1HcmjR_=o1@yHIMCMhh!GHuHBA`)VwD-1;W2G!HF{$os|K#e>C{aHruQ zFV;Z@%_Hc@SG*XJs1WeLKTIcb;b@<`K&B2gfbd6`JKk-q6j6+V6x7d##-QNNL0K}ex()lU}fpzBRU$z9oSEQ;o#gt zhWe?BKu|K3i5au)kLOf{;x$g$%J;yU1~p2bfGbgS$ilT55paeXu>iTn>?wAS-kgViIx4!(c9M8Lwlw~6&?YdAN82?SFwl;iS^28WGu`o>~fwO>anu!IL)J!8j2w!)sLVjn!JTd()8? zc)vOd_7eYU6Oi)SrJ=j7l|2Xq*sz^+d_>aLYhaNgKtg@O^y~7gId5Bo_46k%RQjo( z*{}paLh|+^IY7i!dM6>jP`+IMv!cD7`m8Z8d;wcnPG>dqwY`4_YF9j_0D6*;K)9@3 z7gn)IZI|13BetC*tft4HTHtfjac%4JHV1ln1!M$2w3R7I*MnZo7E>04?IFRMipU9f*x?rmYo1&!jG>xb|6q2NtRG7@cjfbrOci2IZ&u2}y!!fa|8RD_OMxLh*<>xSc$C6Eh-p5Sg# z;cf`MO-1=^gr4K!MJRJV9FzYEB9hu76bX)P{eh}wb@?fF*(wr%MkUnsLgVgUif$1~ z(;Q>Rtw26@`l=`aDiwgOvOt^J6_BB__CL3Q?{sPn0y5ntvhzV}^tmhjdJ< z9DP8nPhej7o-EO=$f`J^B|!J>QQ+4zw5q=G`&kE^X*;CS(m$_p-KGLz$sn8V{)#} zp=_>gzs7G%`3Jjsn&~#Qo%+kFk?vzkvj;cz@EVdX5fl0-_I=osY_vWV8~ z`q^#t+pGZM-AV30fBv!Rf-@WW1548YSQH%H%aKxSS6cYS$^2Aso_q9R;gp@#bp5SaZvJ&lQ>Gn6=yeQ zd|R^n)&pr9-H5=*haP7ZgDS+;N+HVWqU<9ja}k@BG4e|`T0 zgQ5K*g*l<-lABRA8M+2cEG3_WgR7sQ4sWHou7%CjKAAEYw$xM17{}c?Z6tDzsbw2u zg-3Uif}uYZdO)Nt1x=tqwy`wc!4uP@^GFtp<9=mGk7q;1ZhFLa?4ae=Bou2J9uMCN zu~LujBy@be%lC-l*Vfv25=`pf5`)BuZT>0xyo#;=F3=}6X#)+@`JN;x57g7TUVV$M zrQsAgDZxP$56!5y>l-$`8s^?`4=0$<1q_3GC+~uQeXeON!?SJ$sNMBR?a&q zO!yd8Eh7{TyX4IHCO>th=0)F{BLTx%<1{q(;&?Zi(kV(SUgjWS6`bSLw>d$|cL~ui zU%F>l+4X98NLs6^q<@TwK6K;h1R|F&FmdXLuP+d#q!Pf`bY)Pv$OSKV?)#O|b7eIF z8Y%j5ODWD|4ogVl1wU4I487-Y0;OZ+C4_1jZP?ml*GVVne3sN=)NNKrQIZD^^5PXN zWazooJe;@nQ~oZGFx1z#R!TOIoDm#A4BL`a=)$$+$nD{S0%o!3JtwTg ztHF67c2I`LM7lN2tr{r>Z2228z&=^YyKJ|SJ4oHXRRWMlU zG3@EDl}8nbx}vPb4#RQr!4RymF+)1c^Xj=GHw@vs7yB+^4=GL%)bm>ceM+D)IW05O z0D$=O+7aP5L|v_^G4i~8V0~Sb?WS>(8$=-nS}^=pM^hUpRDlVVVqDq~9XUqe;R!^*MH=K7N2n)fMG<5U)Xaq^IC;d`s3Zd9}7*{Spnd@uaZjC4G5~ zS*FoT)dse95YrB!~nIY`~o@Ovn50~Tt1tLj++WwXxw>9Y*PQIm)ZAY58 z(ihsQq-JUb`_v}*hf-k)C@tRw_CdfpSZ190jO~E2hb#(mu!<-Eslf-&E#V<7iQDvU zs2oU$;9m}{j;uwL(#4~qfx1Ue(EklnAkH9st)*YbL0lu^GC%}@%qL#5kECOEM0LZ? z*9qn2&CWPYoUCil-FoxudQse+?I+^0`mR6^eKk&ATKqy&^=3V8Lu0h%h?~{aW__## z4_=Yg10+^9N>fYb09}F&8$P@VqkbH<0^U*X$E30>5D>t#t#7@^x8jZJT^(m%Zr*=k zNM#e_A&P!Uef&^5jt%mW3>G`XY08j{3xB067i zb13k%JasmnirgH`gkV{?F&#4f&U9FnSzeUvp6YJ>_s=&jM$m!{z(R6c~X!&I4>j}I)Yoxiy_T8dfDO< z1)dT)BKDGnQWR0TX$O1jX{O9OtC4U}v4kPpD@E6V1xK?uz^+PsEs7g1gO~A^@Pq@4 zh|L}m@b|52s6i&*u9P@cw^`<$-iEpQ`Oio0S>oXT-i zIlz3JVHFMEr9Zeg#nSeIE@_} z+_j`#SrN6C;Z1~zzF8LkV3eRen!5=F%G?>?SvJ>ThtO!4VNHKy1G$t%)WuLQl!x2H zvMTJ&MndHVcTr&s>)S<@sK@O@XYK9d3zsfOy3r1FkDG0Fr>D}E!fbyXU}5li_v(X; zvkrr~?AVh(Tc1_5!LzB1o4efk-a~p$kzdJQ^E0ApIu+)6hTDOV-VfZoQ|H4E-zv0w z4zdDq@AwXVe55wd^^|vNOaTI=mGnW`as1u>L*RBvPfdvqy z>P&|4&q_}gek?W< zOkIRuS8Mre#1_v;DyQ19dv7z-m8-t>JonPH7;>~4AdiOer#Yp=auQLVwfBYvU91d=A}_z>a67!?a3Y*E&gQjsq)-8adMc>4Msj_QrO_nne**-kF3a z{G8=GD}GCi+hy{_Ds7}R4XZB5My8RqksO)AN#{GNZ0_i^w^*BI{>sb-k@jXOc^z;o zm2$z-ni6JjTQRa&xLA7AJ;X(8ECQw6jW zBor=cK}!jek9*65$ihNJpjnLTaoZN*25TYa=5jPkM4Wd8rj8m|-^|8f@lU#XWN!lR z7gl?n^d`uld_(OB%Hceyv5d106C3f#&A93P4&rk$>_|YFVWtTjY!J$}3Y;Y{@t(HnOiWypkCtbYb{+?^a zSpcfS9b(*-|7@i4BWGMbRi#!nYAtCE)>HLhO@W}-2eMT`c@gKD|CU(P-+r%f*`^5h zr_N#pR_#MFCYb>oa^5y*tW-RxDhj+i=lGX8FIP?oK7r$2|B|`g zLwwj&Mx#2809vJBJYB!G_5F2XlT%Oguo08jGhNsYrE=HXa)u8Gw28GOP?lARU4&4V z5%dk3bgy905PtoF^d%woSbqHc6?qg=T-o+3#bg00+=#nPeOg~?aIc~8S0+Jc+|@8B zSd)u@2AIM2qQg5e`*tDlDhae>pC`xy*q)TXJj+*a*_DOefali%!d+^+6)2}$7-nP} zmjI$w?|&FOhiy@`C`%sOwr$(CZQHhO+qUkpZQHhOC-Wwnezu<-*#>^>NPFJAVNgrtCf9~M)Kf$clOK&3^lVxZMA z3{}$k#~shzy^_ABoVvwti4!n=;{E5>Fa2>(jMCIw$}%$6>O(|hLoRZfx@l73SC z6+R~M#q@Hs?dU>xdjvK(lUR*LNviXypNv1$9e^?K}j$z}F<^PB9;X4`YU^7g5v0oLMso>6l; zUtaDGS(E0Xd30%|)k3p>fx1@NWsQxCHs_iuP|Bd5$g z{w>VGiM5++$`|VF|8xt3!+ww=uA>A{JcSr{oN5VGP8$@NUcoNm_#!xaDM;#h$m6aF zcl;$a(Alex30n$rH;WY6K4#0R$)E>?GyAr~Es7^jB8r9O1JQ7a7u5LD(Z|$o)X$l@!Q*B3eRM(^wsZzL@ZW!wc|4Wc-?i`^nr9Kv_cMxy*5sAF ze@PX?oS#J5oLEkfdMs5>PB6o-xc>X$YS4^uBd|C;47!|GEcKy4M3B6L; z<`7e){`(X~Fuo^WXP)efrxepq0+@VBjoM zDscnthKcvQ6!6a2>U167Dz*oLIG`Yt9^ zcGv<|!La(YyogXfET3djIS2d&uVMTzDLKg>XDZ;+a)oL_`i)fh#T_%^qA2IxsxO#e zUGDxJLk^x6Mbra6VV-lqLa&x(u5mW`ZMfSzseo#D!7Qus?(*;)E#ZAtVWOGuQ{XRC zXugr~Qlj095q7>Ur)ysQBu+6OYmhp?|J^3}^w6JRH$?W&zh<=+bsk_z; zr>aNqD1)RQtG+`W91n#s!My)PY^4SQF2vnKnN@wAZ*}X2%B6j+4}L4;gdM}}?zua> za;$$CG1-9UiTo78hBW^RoBL!-&G3j#1Fl*4EXxOy)Oq{6+binZ_$FW;2_G{>YFrVq zoxRM+jQp)pXXQ{VGn)=a9cIlR6LAv$X9lGi)?fx)R)yDs@z@-$2*@|ycCm(hYYh13 zVZWQZ9#qHDN5b?EnoXxc0FP)#_>N;rkhdT>X3Lfrrao!~m&InNP%U!MvHd&yE}><< zx41Z$IvW*Y)faff>{KyE?*|HfPp&2|8>u80050qcOrT-_+}XcJqv$GlOwM(Gb8E6A zXh_IWB>U8#kU5b6mw@&37vZ*Wf4HD0`V4kmH#Yf@Hs zs}I>BrKv&1*IjomA(Imfq}P4Ee%rIoDK2XsE=pRnM zp2j_UtImh*<(=Wg9BWUOxDn1Ioek!Rkdkt~0f!;RXaO;UM+4_@vG} zzGtJZ?*c8n@LC|uiLNIT|Rv5FucNfa* z6Yz$;5#yfB*ftKP?SNTp-hAGGYRd7&R&LnwsJ{Oo22K&x64W_(Ise~ZB9`yl5S59( zcSoCU+x%qffwvfYJ{Cow)951SEPrE1+nmWf-~%d<%dHGnt9K3SN3&M#rviM7Lg3XL z=wi`F==F#Q(!60Qd0rQ&1gp@%Nw2L&uyN1GQGjQ!w?;nblxnW9vNoCNCfu7wkM);S z^(Me_Y(>ln?HN+H?F6mm&@YM7A#J}|gH6OnWq54yaNAG98hS6&`!3mV8FUU(Nfqst z!j3X^BY#v4;fW`cn#hJ$LG^^g3ErsS-50M9r~_~`^Lchwf3>6V8_CZ#)aGS_WqjbB z@O8UzR>mt?j0jmbRrSRSU*%57-RJ0ll^$w1;iFY_&)Q;mIYSYvO8WZG&!Sbg>)S6n zFLwCs5h4^l)^1&?V8r2SZnta^l5knEoi;C=7h-oe3dbtmoa!JPiCjqrKq?L29RwxG zAPcld3Wz{J03aBjo{7v4dI)aRP0X>$1s?h_B{e8UP;7xc;p(Cu6^?WSh+TI&nhvV< zPD-oaqM9%{6QE8Y*G>2X9?U1vE;7Z(>sf0wb9;QO)$|^eO;VoA2OBPYsy5%MHjtTL zyGp8pL^7(oAMuhN>mg-Pk#PTnf5)+mx#lNRkc&9d3LU_7c3v}g@Ly`;*645_R$y7^ z0LDnS5_wg)8^YW#Rmg$G*r_Qgw=-Vy1;e9}|Hl5oj=?E>z9FKmb@DpcKNFxD@_OPr zp8W_S=H)7?UHKiy?tY12Qg9rm2?6Y`*_F=xS}(y)*ig2Yvl9~I4+jg1ej+@i>_*A~ zjF8$&a?{beq3c8C0H$J(uXS8`P}#?4B1hl}f^yDsIZ<-}{RFgBhAGN5vG+((vlu`b z@(W9j?PZn2Xn_M_XE)v*1r`R~mQfdm73Z_l9mATtRMQKtI#D_`h_?@y z%;=yt>>Vc>q3lRMP?7W_)0QfcIo~s)V&5jKv$A7M%7%PFbHBGn*O=an7ho`F=|YH- z^4$!46nmXaCnm-Be zxb|cnik*KfX-{-Yv43`&>|hbz zU#@y@n;h{riTq0b0m(d<2K0CMz%}j@uNB-FCcX*}y>^X&As}NgDK?udmIVey)C1t| zQZm0(HO4YVBX6n6uLCw!%^3FP(?X?AjhN*x)9yCe;!dms;c>&~K%qkH zybXx!cpNdBn3^#?156KYrw3ddQq-t(ag|Uk6*vFh-Xfm4KMsfUcLh1Sb?GXIUp8RTFvbc zrkR|2uUs;ncVKd!8kMredq8TN5FlE@^a=>=LleC4LTz^_xGc_vZSJ3W^*$uncT++* zytb&`k?3wGZXcBMwKO|ZF5ts6n-uv6my3NB?s?=*0H0Ou7i$s)}MHzR_XuJs^TAxz6*i7mzuI<-;iNGRaQ@% zPN9&}rP3zilFQua^MADt0a-E3H@oQtPqQ{UE(i{PvuE>)>-97#-%^^ewy~%agsu(C z>JhB6%F)IePg!UoYj;$<8zXS_ljclQ1;gh7zFmQA|G8bd>@R8$>* z^tTui*uK8BGr4hcQ-%Ww$RQ-vn2}xKt40TaQUPyDpYz33i}av8Nt*C>|d>sKL@J8KpKkwC4@QLbhI zv_(z|G7Q>GH7eS=mNpDQz=&0}dV0Fqe;-=eok$)0;IXvryI287t*egx1y-Esd0Hzb zr6`*=K%Y+|PhrvA7dDG85Xx8bYX*z<*-6y64STU*k+0SL;K{m1>}pIpq$H)xG+&9! z+aVV#E779J(cdOC(?N??uGsQgukbnOOdkLO=@Vm+GhC7fwEpQ^tBM6;ln+6bB%|uZ z%hk#$?(J2StPU~$TSf*Eh65#?EHui1oW^sywUtBIL_N#RTZy!UOlRt2qtgX=M=R9@ zdu?(8ImJ>IqX9yQBm37?0gXxUb@2=<#V*ai8A88f!;fIzH5Rv1nKID*$YRm>P<5g@ zDH`3ulrbX=SCreh9X#T5Mthw!z$xs_+#0~&KP7QuO69)+vrp8JmJT40PA_=^tN?kR zw~t9lGh^@<+YB7;O_DUZ?A>H@kKyfB8Q(9Xy~6#lii0bwT(Bj*%i9|pXWgI@a2Lb^Wo%U!^UsncNh*FIZBP`(CuSyS zmMZt zZH)L^sP#PP=Rj{xO5Cw2@pd=&kW6@vxZP)N;^(_AZ5Zl zCrTVF5ao?cr^t7B={6yKwV>e2?nMMpXtqR0MINd9Z+(d2%TSh2OK1DJd)yadyegYM3jy zSp$G}av5idjo^lqzP+&MCiSS7v_3ie2yOY9<&tM_AKxf1fr6Qspc#1)fnzo69`Nc| zXzAsRWI-r6#(#v#m&gF!ljPd$Ku1+fNq;oVet+=ItgCfW#S)5rKwrTBqVm*e^~l+A zN)Ls+gawI~njBKzmJOLAc;b5+PkQyta1;*KkQuBRd%RWyVWK;)UuK3}H|Bgf+gU2w zYvvS%#a2dJYyP+az#Bv$$lht$pPS#LNs}}M2SYC~0bYhY)-|(lbjqH}=W0~$+-|V> zH3%`UQrOhq-waRUh?)HbYG8EcZdC$AH1iE{Y)3EKvu(m%SGAl@)ify+?`juywi8dd znR?5${N2J0ciyM;tq?z*s-SrSOP4#?lJa*{$_*rNjy@4N;q#ohHlL` zH1*Y`Sn!Uoq+$J-sQ?(745l`KSB3Sro^D5BPOv#CzodBQY#qhbPUEEG8AA6zA2*Uh z!DThxgx`y>Q059$LD9d}rUR<6AqwGN&BtPctDVR%H0g`PTiUvi$4)HQ8mRiXS4JD; z+_4n>xek9NhER^FW?eG%k^fzb~48T0Ta8 z6atNnG|R*^hE5*6*GG1b0#Xw-lZn~n-35Pl+alOlnA2wM(%jyZ>8%&$>~sS8{qIWL z2=*#Lb!Y+#_hnvIN_9}NqneXas*&5OX$fYHg@CMjD@0uX6KLuf<{OAQ=J7tz*_xR2 zE&tTMiunPjx42H(Q006~Wq@VdtFc%ghR2cufk1)Z_Ga+QYh1|JbM#Dp?0H{`sp<~ZYvukbuhJZp*FHAU|G zlyah}=8X;vn=W@{5C-x>=VoBILk+iF^gd$qedP?Z`3l(gK|@h6dOS(k$QFQP3EvTO zpFMy2viU4O)*I(jn4sDyFG;HQ!E2ZfN;2up?JKp?7H;_wk0y;(qv(KaXO7$3d6M*}69g?qI-i&EO z_i**%&3asb9D!9fG@{=#(Zd=$5AchU3?O~-=6U=jV^eszV71IN*8m!d$^R08QyD8y z^)Gbf(doa70N+3N2?CyAB$jWRAD*szmS`N+W!QSnNC*KHK+%9wx6qIHGr7lYsB?hG7Q*}Lkasn|YOF)Ijwtotfb zqY)Ol=-G(?tRuxeX=mVd6ms}-!`IF~K|h|F#sv1VJ!tBuFH)(Lu&w0g^>|8jsn1O& zh9On|d5eQs9|eA@z`X7FSoVAV(@QLzV_SG4i@$9O*?T0zxe@-_8Gr913?Z}B+Ofbd zf_!pm@C-ueH!k}LhahMu7$w+jGIOw#62wZei_dlQhlG)^yrt7R>Yy1-%DMnuV z*~Hc5(AqNrp9O?eqqMtY`2m^E$V@H02w;Q~{iDS~Yg%xmt{!3UQb|dKzY(4a`1+i# zqD@bw5zKutE|F@D+5#sc?NXmde@N*dMi8yW9mj+-OMap%oEHg4B;WnQbf29@aCT`# zDxBd&^ZHyz6wf>#)AVV+MH|M%N8?^Mie=vwz)Olpz3w1|p`jAt96h25qtLB0YqS?L zsw7Yd0}EwfAn9zHPOFeXb#mGb`SwbMxaYqWYM5>rqJFGg?r|m)Ki*+MqgLn8yaIRL zKIY4ww?9-#5!O=H{!N+Qt3tTK^n~k8X@{J6v{lSH*UX84ZzA4D=NMr4?8^2-XCz9; z#QFmLHlEJNV$kfGgT%8osH;In9&^az6ANLwYM()V_#0+{Kh^H z*8o%VYpA89JnPNNg2@3EZ=Y~c@3DH4U6W+)o!%=;$9D*2SD+%UKDTkMTn9)@9z_B+ zC3Eft;sfkqieIkLJR6#sdSYxyVD|^YIxBD-b-9t_to-D)_2Y5t^)TT8yJ`qf9>*gR zR}|-_61>2fmc2&JqZ%WEZiRSPChZ*UUOF|t8A-WEH(gJXaDknBf9)E|tfikADrJC* zOGsX)32vonnMYbmACpM{J~(fILYxQFs;u`Uu@|yVJTvKB`XHV9aDwh0t2}M{^~w3D zxNe(^n5S$8#^1;tfW_zGn|-bisFM(G{>8pbjxCl`Ft@2BOm2uH7Pmg3dDVkfObQswe_O(z{>7 zXr%8%u73M=g@p*Y)wy{H;zg_-EX!dm6wA$rVZ+M5{atXYG8jWD>)IB!O_=VnF>7#E~i598Sc zqpuQJi5Cald;{iqwP}q*+k*4)!DsiuCqv9wdYVPWnbbB011#|l6`IsrWOHrt3^M0w zPm{T8T7Q#{FwPcZ-5&0VlG3;1G#O%6yUb2ffiba=QWkx~*^NTPkr3ZzsR z?l$PLO{{=BB;wZ`G=fOp6~|`vqBfuhX~-bl?iLrMfS$u`JTvXvBr{(4y~vom3cE!O z&NgP3B1xLkr6P?ReU)E`T&#y-*W-i%u6!KNl)-OEzSREE&O70XsSL_O$#!fUXD+Gq zgZU~vgpbEZyZkX5h#eq(G zEFWvIkk3nQz0=q0^RpJ=dct7*+G*xg{MSIO5Yc{u>_}z$st&LXx6> zGPX@`6xpLLRMUFx3~#YFqameNJb(KYq{!^Y^Q(0WT`$#s|6gsJ{%hGclRoR4)8H|_ z`Ll9?PyKS^19 z2E=ay>t0r8QK7bmsf#X2K79HifKjZtmw_rhpz(hwjExKJDhOb3@xHZukRdAO2C8>L z|Fs5kx+Lue60~Fd5h`WLt`$jLwu=q*8D$wpY)TRo@7NHQ79-14Y*J;zFFkob88ppB ztCN|iL89EKj2kMX)cxN{fa@BFs9Wh=v%q-eBXwi2kLtk;eM<@FBNOz@R{!(G83?&ReV34WCNjx}N z>v)C$79Iu~FyOk5&Df8jw=1KR-KMYWbAyChz(DR=g=HxDAKn+I+gf;vqfx%WJ$nBk zvU64ME^7ye^D}&<*%lW1U%+6$m;yCQS7R}E7BizIku__6Mf&Fw0{KW7^JBEUgIsru z)uP<3ODe=>r~j;N-?r%OE+uP%uWv^)v=rMl1P+^>m|;Eyxm1CgSs$lxi&+UX7xME0^=61{8G+Goe(k8b%3T0s8QQJ>av^=JpO zftUW+jX97zh~TJ-?$R|*D1rg}%PUVhWwbiuq8#uweS_~EpC@Ah1cW9Oil+GRYCI2Y zbk~`P{(y>w0@ms(GU%BW{>{xoMHDXJiUUvltb#IV@>g4Dix|vqfX2}-GRh*tG(adr zY&0?S!lIYW7N6~7q#je9^Y9zCqL_)~i@GHIUbzHlMdVm^IrLaCxhKIBkiCYD`WOAd z;IT^1wX+uKb34+&mlLEC%i2rvrYG`BF+kq;MFahSuuhmKsM~AmjEFTZ=uFTGMHH)e zW2olBRFp81b--R)^foG_2~MDyR}WgwC|r?){=+tm$|yYySFro^9a33Ca%Ph+DG`4Z z-JuF1OB}5M$zVUySzkOx`tjn7uo=T=lO5IXMPr-yb_>}8s%QZyEJ;ls52rfyGX_7? z$P+d+w3YTUJkFH4GH5l=71+*|*iZ<9OE$NxFeMVb5GeRbI^ zRp>x3^*+62UijTlbCRbWbvJbvc4hvMiv0hK z&-4H!e-f3h_g_Gp`&K+75d;o45x~X;<3pEsx+uW1udawjnjy2oi|caRJ$$#edKvfx zh%ww|XkpJ2XT&RnI}cBME$b(IBb7(f3fMt^d_XF1)XQLc+I z)OA*m&Ot@~YUc^*zkRzlMyp(Sf3UJWIT9;zmcgBzxHoWJcmIq^r#9!MG#QjjsU8%1 zvd=sdx_4obVSWa&*sYwnR_I(3hxB4>!ctj&BKoE>2~VBNk>^hGv>*a2A-;Ra*_lFh z#Mf>&JjQu#sSI6n{b{egEgs!q!v;*80D;7Uz8}3`Dku_%=lDbon9A`|PG7RzLEdyw z7S(QWn`puO33*`P6VDr{$69^jxAfe9p^QsgdZ3N<1`SKPbGC5Yk`Hhba9Bj?7|jd+ zjWC66iO_@a$&5LjqQlzv+8CmEJk#QjRDLc;HQY`i0oAHqLDA|w} zJH$LfO;1vymUMeZ?7BixR@=9A;8HW?Eetp3EbRxF;%v<=z832jQRGJk zgm%rKKLc4F6GyO^mGMz6I8;_KDgYKU0DPp*SoclgEv>%3u{v~;fjP`Ggh~ktwM}N= zXTvu5=v1#86;1m8ph2MSndKIrCK+gl24R)n{WIT(QXj1o-S;oKLrPO1r6IQOk`Ze2^Rqw`k|sN5v8?qWCX0ueqZT zk8)<*nC?X{=w{^&)p)N+U1>b0|&5z>a_=oti&Qz!{tZ!Fwi5-m#+QXfqb*L3*RbXR#Zt zQi#}WXlKU*te}+Z4#C_P>1o%Z{v!l4N^1C+^vFOf1EZ}=-Uk@v`JVy_h@J1CjojeK zRZl$5A5Q|^?uxHpXF=ir^)oah)xx$?OMDYfocS+SplHrxi6G+PmmQe+@0Ey3=?g-_ z!~8;u3B!AeGp~<44Qig>!BPxv4Tz*|Gr*lGfJ+JVgw)gPDvtG}_|V*fza)#pyBDQB z2I zMc#Gf&PO#bw@`@{#Z=R4y`IUG$&Q(N|3IBQ8)^rfC4sX3>ntFqr%D*JXUROc@qpl` z4U;iA!w)6aao%GlV=;JVbhf^E)7N|P>6oH4ls#V1(t9KmoErwJ2Ah@$DJ`j^q$%dp zJgy(L%8^k`9|0Cn=vQ<55yNeT*>oFWuZSKXn96+?w!tuB_?rYZ4xjI9@c2tN0TJ}t0^2~rUhC3JlDrx5IvU< zDD=Rl53RUYfiz5HcsX@NPMx(+IUq&GK>n*@*bHl)J+McqjBg!#;`ppOm7g)J#B_OI zKr}I+t(^gH4JX9CM&8|-bq$m&hw}XVuT#=5hR>Ls;5pac9TKMFdd!|k?bVGwXL;EC z8?NTtW5>&5Z~m@y0vSNSU*-$Tq{rjBggD`2P#;A;0KX&R+Z!2s(g+g z0t8HA+nS>F@jMQ5_v)9;_AI&*R(EmrdCL9r{&pqCmjm-Hs;AAmT)L7X!i<)irl~=v zlMKBboWD%`dKJFZ+y?^Y363Gb>wT%L|Xa3W1s&OGKFgSO#(9hIA6Y%7;oC@y$*azzhF+8 zI!qX~&mYJzSoPuNO5_|qp0_E0dnZ%O1C3=lPOEQwWdF+8oCgpu{Cw&beVGwsQ|9y5 zqsaN3lV>zr4lMaEr(877>kh?8x@Wd$TZH2-d_?S7$rad<#3@@T)g(6Ck}=}XNfw(| z{V+ha>-J0?MBAQcI&fcK-s}2V4ALS#&<=Io&4K2ZF+WHgD^qNmH+fBhCQTtj;dvK) zax!Umg+x~sg11*^i*fXP4@SqPj5aC#C96;JyNQrrE$<9Ll~PkgTs~K9#;}`6I*-lM zgz|4tPXUP>WU<28w@)*y#7Qna$XC+I0Ob_*rP?yv&1o6N#aicA3se-U6UV z@I0d|8wXCMsqEDHn3QeRv}OM9`|v;EYP>2l50Ubcl=Sf2n={3y)O=eZPwkJ}LbjE1 zybWaa{h`+r_d3R=*Sx6snC}C76eCp{uXB8Rw`dMUJ=ZF?jG7(MpFe49531Ba?VDC8 za>3_I7Z_d?Roe9!0u)dvD8)J#X_T443yZCp5Z1C$zU#;p9B{F5rguN5ngQ21lVvohFb%v`!b_+xpnq6TwI@aIhH3F-|GZ+rVsI0VcJ$ z8+*YLptCT0(=}iC3Dznkmz7yVhaDW2bkVftg+Ryco&_E(^?dDf&N#nGVG!i0B;{=h z)OOLu?#n7aDZIC!zb8jRKW}>NtL5wv#H?QaS)ih2KnrA7LxL(b8b6As0w=PXwbgid zBBczc;j8~Ku4A3nrh=QBr>RUlq0j3kC`oBN2qGe-Vx5 z8T|wP7?+zIj30X!FC5@+bZV0=HkMf3&Z;yzbk0JR1?V^nY*afFjHd^H}L0T`%Z~ z{nlU}S?h@;kL=%9tg}^ee{mIOT9CS9%qVrG+Mo1Fh1y~rpkvk30^1lVkc)@&SKJ6A z{S({j`4Q#Hom8zM8|!m;=9(=LK&sM$xJ#hJtt;Otr_ zfkJdj^C~ATGN$pN_hJDw@_ikq2^cXh$cc&{`{g%7KU7J)h$Co2yWA~EH&1%?IBKkC zhlU%1T=(?P$%Z6@JS|%qqeaJ=Qe~Hj8`q7!jHCx?eWm|JS#onb&g2TyfGRm`vC95( zS4+ouZQ_}_j|CAf<)k_sXQaEK3f_5SOAmXn1DMq26I{gh{6D`<0dOxd@8P_iq|`y2 zDSfrSgS9D#YBMT8C{Ung`o=t%Peb4H#2WUD;Lo39hEyQ%`MLtL>oj>DKtZxA20)28 z@^xiHzlXrVil3>7g&_$Yb%%G0+D6GX%Yp33hnFVT{TtHc;9LN(ZNU;jn|`4H9fKhv zBp2}AuR*YVLYK?iKvhF~xVVGW+R9J%nE(k#TA#YZ4iO)V&urI5*A3HNVcpRX}pIDN}@gou??NiEAh z3Z=?#vXy5A+w^v{8Xw-)-~5t7seOLbGLQ{|1OlSVN2A$WX!s ztvsXJ}+4ly1_{&w2jM1qSmCR@BoA()3w9tB?!~i6Aen4 zMz=@KH^}>TQ?)M@8yF%#7<<8sLLZ9lJpU`;4er7=kq%Z1l<(icafz|*H0N78_$a|Y zj0rVo2yQ2u%-fpJ$}hj4uKd4qf`V{0*oH9V%R3v^p}!>ZT+3fNrDH4g5vG7IA|&a( zmK}Y@vmDRjpVoEFR^9I4`|~|L#|o#s)(=M$-|>KD4VpWcinoQlfC2By zU)*nU$qQSaQ}i>bahpvHd4c-dg)E~I+*e142o>@4S>G(lsHx291B6EO=d_HPAQ8_Y zL_f#Fvzx;aa`=_25j`!nAt1eGP756fWFZkaiVQYNi)xm03TGd#3$m_O#KY#@>Ji*N zLg9*cmReMoU;|M!6sdsg!GES+Vsj1)94I2NL1Hu(n8?o5l8Cs|oQWqlcY#XFZ!9O! zl`pHPzzm(h$kf+et${GQyBu|AJC|kp{V5s(ua=_1O>#4;xMG`(rks&?6_7JV3+{pg zLb561!=tX}uDTXqI;52KJ)kNfJr@HX(>F-$vGhexuPV|$`e!H-<2iu$COtu)BOg$5 zgr@U2auj?J*o{rQC<3=>8}WeF7(;~yGIU|)qF1Zo;}9Tk?x_(k@IIVZ{F#0PzgJFq zNaK5NP0cihjBw%f*jx4Z79MwRyAjMP(5iBszjsj&Ez>O-4oq`m?rC#(^^blRF)vSo zDszdCtJdDXO&VBVF4)2~Gg831R9aW|+R&tI-HfS7qI(jgp-5Xv@@gE$m&#o>;m5w) za9`xdkis~>yp8g4vFC(K#76aF1 znRt?0q>BPaAYH!VpcKP${uTHagf%XmPx{%tCK5l5-^oE;qEbJY zvF-e0cQFU&PdcH{edWxFB2#&6)ZN>#MG$X0{%yn5N`X@UE@!b&ELj^j3AhhpVdz$g zMic%8N|I5E+FS;)1m|^U2xh{C;4suig%x}lVyMMCDl$qnP5R*(Pm@Es>NAN=41j`V z44$dgAS#nC6#1;ea|iK;4R>-}R*6wVSnmqwrP+8>c_FHFFYP4W5zK>x*|#YfpaIAV z_AZ9`7?DnIK*jNijIy2i2;t{)6pVR;vQlhk>6!D^7rG-Iu%@OARkj zwfq(2%Z0q_D8Ww9+wsyr3Di(e97ei%rDA!AFkOrZUO*|7T!yzRQ$Tp2Lwa*MhL8wi zb1;q1)$x)DuiCp1oZcsMOODiJU3k%$AlY%)zn*FMERfgNEH;h}xb9j}FaBDBiHhp_ z_7L*#tvLw(C&GjZ$VKTW=Y_$KVZTdVl8W;`D2}rqC=K zjS^B-u#Q5?Kk~^@&!Crb0Rj_r4#?F&FUT{n%5x{>qab{VuV9DRjSC*xkgIg9Zta~a zTIi7W601L+(6_(Ic9ep9&$fm4%KX=Y7GY=fCX!9PDuJXm9zRanDKcq?2m4j=sj{1# z&Y)cd6G$xdsHD0gf&+9BuSg{7Jm`$lg9+eCh2uwye@buK z0B*R)QsUUR5;ad0I{P^B?0RWXNwox9C4~8HQ!eRG;iLe2KA_En`?19eh`S#fALOw? zgz+pXOyg|v70@ud8&6!}P6wj|#2>9Mb31p9Ho$*0tZ*cxe+EzREZj&rOB z$6n1l3!}{OtJn4C5eeD#`F`dx-b5J&Q4GTJ-2Co=eZou2j4nI)t>+eE z0_<`G?9|nqmEDIdhDM@J>jMkiLH`JIr&kU?`1aSQQi)37gDzcSNWuG)+5#vEZ*CmQ zpLelnB!SBR(#xJ(C=c{2B!LxFrm5_jW*z4#{TCq%!vf``84+7M zN@aQig#U=-x1|Al901p{N6^a;HAd2efEmoDYjL)G9}tu`_AOyvjzT>(c58#EaNICu zucgFS0V}WF1Lz6O?X$>`w#p+96<829KmNm;O=(WxtO>h!KmfAYP$MR@Y&$V6kK_Pb z$Wuw;*Kr066W)LsbSzz_kHcnJUQ(z#@20~+D%wha!v3uUBFr$+F*@2bBx$!2$d;qw9DL+v z!aowS&#C06dmGb?bh9p@)PW3a(VI~g)(ly}iTcown>@f=@ zd!CVfz`h<~*zv&cm_G2tVcd)r0jlIzkWzzB=6zTSV2L^I*bI(oo1=8qE)xAX;SoAN zI@>(+_wq5KYoq!kw}#;rR_vX)+hL|Bn+iLReM`n2H_CYh(ru7#mXM|3n(4U2h`b#u zqqG{r_DrvisNJP3SttFS-nQ=JsfPxRZ3^Bv22OWqe#o3Vi0D~9R}UOb9t$x&rgo{^ zx?}_7nI>heavq;6M5ZekDbnkN*=iRdvzot%e*~n^XbjRW@>FquH5+NQSQldj`0;=3C1|2U~XYz$4C@c*IbE_1!w#B)G;@W(q- z@N=H<%99SC{PIU94AKNgOWepU1Uc9e$HyYH=Z_lL6X$Fi1e_DrHXid1A!61Rcb#JhNbR*nsI3%C>`6Fsj{&ARqS>yUvb<>h%*tFT9DiDym+9R? z$V3FD^9e@t28}aD@qPwfZJ*5~qPKoEdg8SwFCok27!=ZfI`Rib$&Bkz>76W8=g}>YPcy%?#TP9;MnSL- zYw>nN`ZkVtW*MO2DvM|^_IXy z(ZtknBX6HfSu?ikRfVEM4w!K)h|H`%sG0KC;G6gQm)ClgKEkl6B@N6G{<*WXpM%)% zEA+z|33Piu`Gb?5XTWXRyrrSMfeVyjTrnhUANgPH-7mAW>DpSBPRA~P>Ui$MTOuk* z^kK#if$qlc=OsR$INBikYtfWFdp3YC=t9t#`d}FCbwvI+8z$M|H+MMjj(!W?6RBlD zCPue_`9wCmo65ur4xR{!c?pDq-J+s5CCz3vKvC12&Of<7jB!~Mcfx$;;N+7Q^y~n_ z{UHYgOq}dXorfl-=U97|ScGI_{+xo>)Z%>WPnqU`yM)|`t`ACuQV`fEDu+i!vy`49 z^U~qU#?RaDW))1-hWf@(25c3(>~#K9QzCLOIO7eg=*SQho4y2JPiWRzL_Z7~_&$_I z*LXx##pUOR7)>zW&s(WQoS27{3$s<>`diDHdGma`Gh%>!of?gMLL#uc4Dm(sxZuue zt8FBzY=4GX!&#PkI-+W@jjeQ#XDPsiljxqmtQjuK{<_-KC|7^s?)JM`DdejTPPvOTxzB;RqQ6j z!L!SgE0QymG{{0O`b8V1)&K_4LP_bH(yPgw4}cl=|FbDsRW3 zSHi^rV_umf)cEUv7(0h$QM4f2ZriqP+s4_pZQHhO+qP}nwr#!Jdex~$eM3g96_Io1 z7zVxkAy?*sW(O2!eWNMb71{+BAHixL{b1$POz@vN@!&<8{`a*`OU+g{F1^{Mi)MDi zfoGYKw(RYF@evu2u*dCgw)E^7mAj7RoAn2J`l)7wEQ1z%tlv`3sjs=oLrT`G5=8qZ zdYur*102@AmjiPpqdt_Vl$D+Wo8&yYl2WVH2s+%Yf6TC^IC^ zd5qey*GYs*<0M94ot#MJqVx|{laYxz!np2U6%{aV*g@=*?tLE^-q_0}J9{cr>7p(e z;bdD;tZIlN`{d*5;FNncRh(%AQ|K`y%1ZES7zHkY(?@syY z0LoLPiXy8vZY|mI_oOyJOhGm2Ry}598-1+|g`OU-P~_Og`$qjvBnRG^lNlt3K+y^e zk5wF1TT+;_HsPGI=9{&j;^eG($5)d<8-fId7{z&>Z}i}9o16Ri1_N6X1v8yWA}O3y z-db0f$J2=h1vk-#I7ZVGI7)viA9es#+FDb_iQ*2sxw&gqYV%hPsR^OppR%UQ1phu@ zc%l&Ja*{*qsUAK(-WjhgVI#)XCa3FwXR9j}<9}WpZRAsCYA||Njah$-c=wX&chGY- z_n7yJE0}2ckgkR)!Q%+HE-4IV83&b6a9oWk?@dRyG*?q4NHPmW++5K?PJ$=X+1;eZ zR%o&hJa3VLHz09!{nE!o#P+dnoh1}`S;zPkMKTD!Qr^Vi-J<axJF8 z1#EH%%36mI&^eyvxqKoq0kHE$yJoX9ThRlM*jvjr(HJu&5P9B5R@N!l>#i={= z%>XXY3IJIedNwg?0vRg<9~(E9s-}K(*kjKi0`Vl6mw6=H2Y**NIg$?ntK zC>&1gB()-jZoCRs_i;P%XjFiVT)pg_z~9#7+%C+lYo@gJNW_Kr=yoo}_x5{BD2YDs zc2k{*{~AXs70Ls^nXKB9J1%Epke%7IS%M;=CT~Hv`C}wPDoWs9yHV@tbDoTsJ<&XA zUMqam8c#o$N^8Q@K|SM!+n!3-$Yy5aJJc){mg{)-3|d#%b)_07SqDBh&MEYH4n(Ze z(PIyuBs^q=A-*U?;UH=+vVB8R1akr0%hg1P`-V|Q*pA_tky^ELR6Gg;l8!L|JXsB1 zz#u;Z?oJ@f{S(Q7Q~22FP$DyQw>3Tt-3X4r%L%`-P1@OcnNwH5Gs$NmGGn63NBGBk zYwTPGs@*4^$;H=aIHrbbWdgg-n$gRxuYsoV3LhCPC3^vt*D_GYGF^f@!{AkUj@3^r z5*ITp@Ed~6N<&Ml0_wg^&28PsMp`LIiTO>+e|J%XxOVT%t z-=nrDe?}&ePg~!lFftXx-)=R`L94HPzVJ}up*Ok1JIP|~!#4y|cf`2KJH~WBZAY=` zLr@kM9rI@A$w12C9P`m%4||Kl_&Xq_y@<{gsv=#S3TfhupfstJ5QKFQ!#Ej4^!xWD z8@DD(0~6Y`=eF9P0!ZO3M%EFH1vIHq?cSi5^k69fZ`AhN0&UVo zPOQyg(2LOtANUA}mGTr@pnY*;Dc^RK3u+so!3>lx#Y4Y2oqKVy?3!`}H59J9D_@o8 z%S~Dp$n7D=0;ogeulc4Ga_e7U!)&0DQOl~(5igm>RXZuNpfXx`Eh05If5w=`HQIX4 zRZVW)Wc7=7BL4iHV-#vd+|R}vXDydb70pm?V*ZdY&sNfof7ce!<}z7|-$_Yd&1YV? z{CwU4innufPyM__PG5p2nZt@cu9EVvW|;?!B=x;wgWHIYBI#hA@b=HAXu#?EH|!SH zh0T*EtQlK06=MKINa+*-{OvO zopQ=R<~fEY{{-q;iBHjQ4>K*hl<*Ftv%N7|ClBaC(FL2a(r8IUQIpo-JGYofg|=x{ za~?F|@{{FAwZt>zQ!^~Lq~4zndA&TYIT+Vwo(9{Z$Xj-#(7S^J#e?fPD?H}?%vi!6 z!iN*AU<$r(=c~3ZUohW{uE%N6$5*%aEU+&zS4#5SE$9eMqpi&YM(hh}FlTnr{kg#H z2azkxovBKcU^PzuWPOIjb?2J?+c2K%|AOkY?r4p5MWiR1Y>Y|y!w7^W3aO%;YAy6& zX{Jd3@v^#yi;yU8@~pf~J+k}D5FCya^lp+(T)D%6NCWCP&K*aTyCND5y@Qj9)21W; zqJx^BIjtC(EK5@eu2P%bQ+n^kwF~=6K?V-SdTA~%^;Sd2Tg}iEP(af>?`<|WzZuRg#PMzb z011FCQT3jWzF~MOiB=NLO+}*#@(x6?m$M!c_wz7FN0H>}cAu|=q=--Gm+^+XDU=Xo z9CqN+d9JY>`f=Ed9DRb!!zhY0IlGuPq1_#?J0yi5k^ql@80=bd<^7ee#KzT*tir2? z2XhDi{`Wbp*8XIW+K?WTK-+T856;Uxpn%t*@r!;J0x zBWe)W6cRQiUV7tVI@2 z&lOE3ld>#n01qGy>V?AUFm{SXc!DK9L4W8NwZ3xQ7P;4@s#;!HLfap$z6ksY- za4)pPWR}CQtRLY#_0g8Jt^{xZSI0TUZBTdq@J>@H@6M29(n7q*NzI1&>4Y^mscBM| z=%{ybb#@Z=&oA{;(R0$CgoFqeDh@5qG~5bL%;AEV-nX9sYN9xmP{ZKuz6zBM*D!jV zzna}Y<}AO##f*Pe5w0m7!02D!A-`rE57|mH;7hr2-IooJO+^!jgB7@${aog#`ze{% ziFIU3l5yVW>#i6(Fv%FdMQu}q6$jBeeQSZR>9p-nVY40tw`LZiGis_d9am-5Do3Vn z4&X9Z|Ed@fWSo~Y^4I%bQn}u*!CwF5e$U0@$vUd=EKXQAbPSB|qm>gqEO`O7Mxv+O5K1DnHE!I_N%@Tk55;W7(0 z!|&bb$0jn#4F#;@v{n&E(aDYa#p+4=!XRBLI^5r{*4O!_fRZd5`0?n<{UvwG0i8i& z*QOF=vXw`sv3gK_3I_kMsz)8p%_uM|!{q@V`k@`Z1T)KEtCEBP#=$@t#Q9zYmW5+4 zFeDqg%Qn)^Fs_-gWG{Qw_nf8Ykz;olPqi8j!2Tnpg9+9Yc&|9+yt)s0_YNT>bxSO zQ(K=YF8yBS#1swcG+QC(f3xrM{ME-pCDs3A-+KJ?K^N+OeitEoN0^f(A@+x|n*|JJ zchIQ3dwm9)z#*g`{*GY(B6`+(KHqk8e-zMJ>?}%uW5GvK2`(d;-&1rqZZ!H;y8UmX zWDj?=R(j;aT&0?WtUtQXZ--~~dw7`?imNaTWX2UP2CbL(7MLs#r>=Z>)ezO(`%C66 z8@ByHQe=9(bzT-y_a1BcpTGRwyzgn8trYpxSdbl;TiI6lMu?6fXFXV^>fZ!T$Q1*Q z&ll=yXg6<)7je>|0K}m4v?r;*Jn~nTM7(j%(0w4(P#Y9K)?VTu{IHwT%0;W-l6ymK7B6`~69?9SRC%vBN&5w#FCrx;$O~G9G1YHlyhd^ft^p8`1n`xw) zs4N2TW?>{l6_{PjOE1$QvqiLw;f07Wgfo(bn3m^1qjSL8jKSv8R@Mqb{1)r%12(0S zxq?g#G29Dhp7q`U6y*V^Ih}cR>Wy(eK>Yp?eM`+)6uJLsbHibwn?5-Z7F2r#{x|}G zOaODg3kb-=D8QCQo`dC0$8%a5D1{{`ikXIINS+58Dv0qA);a+5dbylyW8dzaBT^eY;7YDQTQt2M@A;PQY7K;0KffXd4iIxFAUR3O>Y#h+5z}SSN1+ znz4OgXmh=&v`EQk)~r(tuy_S^bEe_bIKBLNfDaVCdhD=m*|D7Pk? zqIFG09hroOSB?nf+vICy)oGQs}o5V)aKq$O;1 zQ4BFbWvpO4Q?UHaXwK7n-!zIu3(mdu%J~Om0q-bv5q#XB71An2Wg+S!kO`b|57kits9pZXap5SK5k@*n%7`a}y3AQ{>t*T!Q4GE+0vE{FT@2h)Kw!$#| z4R|8L4%MEOLbs<%zthVA+wFM>5-o|F~OnI z@0VS5K;W0*upFIlJEVcKcC}^WphAUF_!VyxwH5uRu6tsZI;;u5^Lq(qOq>wigs-H1 zGkiyR(kYSd&%@2=E^1F0w0*(64nRl;=SXhtHds=$xm^9oB9&zo6orT2PKOh{WjeR% z^}PW#6=qO+V&XcOivn~zawUqkjQe_qSP@pFDdtBe^;t!_PH0VxUzYKb??_LzTu;4~ z8dQX0^0mBT?PB*I12-7)yK6hM;oy>73HRs1h}X2oc7@ge4PH=LmG2fl zO?Fv7U-0sju&Q-YI%m|-_~;5YJ~B6cQ?`zd02&iZ9cyj~etCmp15CrCnUiZq9xrlw z??=LAv(n47PCZ$UWy5*fU=-0wNQtuvmwVX~Fo0LK8u9C09wJC~TzqVgeBEQWI*cjN*fs zEmIyq>P6u(Q`jM0G09`ZO#7o%A73kSX||EMoJ?5Sw@TPCGK{-P#G&Ey1A3v#HhdLa zpl@z~_BaP@6Ia$F%$}Xe8XB+YEbPW))5b+Koxe+_sszWPN{PK{cYe~%P7-+pRP z(+p;hGH#@w5HM$nCY1Ayg5CvN%K$)2zYfVjsb&5cqP}G?>EhL|RTrXarUYvaHM!KV z;f9n0U^Go1I*AQBtvj@^Z^>i}^bNP8pDKBn6zU5Cta#~X>(9C*3_p7l>Q8e~SkcrR zx44C17wJ!f zUJ^}Y$kf=is8*k6MUyuOc$g#ps`C9n)kv&Fd_1qqxchK`+g!MrJ`fAhUmd9}?F!|& zU{*m@uRm|NtDLYq+#~5y=V&!3pI(Ggi%R#+0=hBrX8DnJ++`&@;)uuy@ve_uUo*aG z0kWD^O9p&pNvFtct(@k(7oC-^^t+qTvmFRWMSb=2Qx-9BamfB zY}p#|8CW#&`Jd2hVPbRJfcwYC8f(#X)4`RiTsD(e_t$Hw^RLjSHgOReYBzZF@|OML z>px~V4*lRm2-63;u6Ua>#~XZU=pXLp>gSZ20V}aRN}A*(nN+eu`kAc=O>=Mrg9QK1 zePK0rT7w?Wr{0i>a8m5_FAP;Pz^!!>e}1;cwICq2$MP>DC&a=>O?a#(vubnWxQ1BC zMuqp$_%*P)Y}>U^`Nu6@z_NR~nlW!g`x)6_$h~l^c#l-=SYYFhOJGO{j3Q1QG#9M* z`D4vBbQ1nXa?MOB>E_c&fn&1qE9Ht*N$N09dR>{BC79@iKVoM%GEcD&H{uUU1p04I zEDN0BRD?AggXyhfekeThFhcm%_5DGJvbm(44PuJ9-Xb^XXYoE6>&@ToHbG8N?uSK? zoB((=s8B%ih|joN-S^Xunk*0dL@Eex{WkBJ3f!^N6G(m!4g(PO#mnP1w|7?5JkTiy zc1kL5jVAub)X_f*4GZzI&c8m$*v1gAs-PYbV$hv`u)6y%-;g~(6x;OZf z=1*OFO=jHS?U6srMrXQ=;pCkq44ZtJ^2Z6Hu8ZChhH~eEKV`g!m_Hq?Cw%cNyk1vJ zEU>1*Gn~I`xX6lDL>5oPE!PF_Q1wp#mf1D!AaVP!Z_}aP*q{v7ZbG~4usarbfpd{F zR0Z~|tn2U1v#OcVCw)vvICIOoV&*|X?({C(zgvdcooo@SCK!vRTc2#`6|CFrCY~;8 zl%#o6V4^%I%KD(w55}>yaw_`ob_vt;o1iI5?Obh@?@!BTNIyGhTM9E>H?#}Wwy5j7 zsC^kqTv!Lq#4z(MVxOK&%)aKfB~s9cP7|lk0vCBjgtE{jMoskJtyHj9nMn6mkJdB} zDnA`{gg=io%{(wEk_Ypr!6@%d6o6rIJ;(c-k?N&AdtM3Pe2_Q{;4@PNb^0=|Ud(Us z5MlnOo#D#LJ_m~+LJFnXgzg<@FsVmd8;FEK#)A<9`~S3nis7^Y`nGlihyua*MPt|D zIP8wJq$aB5QQm(=6I$eUsH0QU0A9~;S1GWD2+4=Nyj1GT#fugz{CrdHHVtqE?TnXNCqI$>s!}9TPYA=3%&~|ZamYl`vL|I`!zgdfU@c# zvq$z{%m}L{Kw|VYa#_A$k-Mm}6n@{FVpxgZ!gbLMa?gd)+mdrcfYP~qHAnX*6UYGm zMHZ{73!YM`lf#7D9o)(XQ$V4lhl4@&Sp>nY%7lH(g%NA)cSkX>K!SQC{(;-Hl9QC& z(d56A%DHfja)dwsfy;Ud{+I%JrBoQ>;&iTVD^c9YVY!#=cRIiClHSaJ~*fnKi%K18gO>)Po>1fje+_@|~n{{JeaB&!~*>jI4E86YiaWGL~j0g+rLc8Eg3R=~k1zSz^^? zOBHk?KUmYDj7~jPYq==+iT*mm$z4t9+p|^AU~qwwk9z!9n?&oiU(w%_5}WGo(PXV& z(|*;<4T#bNeH~{Lzd@xtVVQ5WX7!@9wZIRRqs-ba-Qy^>qm6#92)HwLuZr-?P0 zj<+r`G>TiNMj^cLkK;Cia$!8@_K@%2FJ2`4jd=u3n<{nY^7a8kOo4(LVqCNF1J9a? zeh`hAZxI^qQ75*RK*2!PjKn$QKCs{_>DU)MxSQNaU<+y!WUGdXI-#P8N(b`}lP9?i z<#&pQ$yPXf0+tgTl!>BwK9@Evkx+ZOjBTQ6ezURDW#rNI72_tG+Y-L@$%q)3>AgK&UycZ?l{~y=Bi` z9dUV*mx)g7XH@h11040x`=A;O4cnz3Sm`!)e7rB9d~#R8k0F5eJk$2-!21uTN~cEW z9-|~BHsr#cy}m?T72}`e{pJmOHEzEZ)O9OIUfF9eCrcsA88wCgItKypav0UKoz5nR zKJkUfJwci6LEMbKZ4@n%(f5(FVRGww?kkks#a?^&*xL3C-rrWougHO|qIAHz zNElm|YcvSTOu38pWV1!VK2fPoh(3q14a<6|ZW&lD==T~wg2O_)g{Of%vLhdIR(Hr6 zLwA@oNO3JHeKRC6P~+ZTX822C9{gyDz~#~6Q&8}N#eMiJd4vz={9)EXdhmk-WWp^CHfsarY!*Wc0#0l(&_ zVq^ZRgU;96q>{(9u5`3{Le?&pHP7kmpj%E?k!Po^6vQOlms}8;8WYY0VzcX!T_I%x zLQ=g63;wrJTTrki8J^DD+b3gL$7z5O)-U?$eS4(tHR35#fC*J2I-^xG>#1fcBQ_Cc za^|nv*?!olXYQ(C*Lg;#ursiDFu^{!+ge73ENH$@oMy$^fb>@Z*mzETDHjW7E43b3 zCT&BfyOS+peDU&i6E}_S)X1o&k41H~Js2mqdnz=DKmOR@I4ohL(A)oTjX|tS^um3J z*}V^=X(guHASji>-Y8)Ok?zm5qJ>>72o-`pND|SJ#_~(XsA|)S!~f5?s)2;9$>T1uTiu4t-nD-7MMd-Pp$_z|4d2UTC6rY2iKel>c z15yZViN~tJ*FnU$KrluBe02v_CJNrTa$fZ)O~)5`&1>kIK=OcjZ+GZtbF5jvbm6;| z834yt^0*V9>KaZB4*=2a)r%C>#yDm^e(88mFm7sYp6fDnUED|m4rGRLmQpqdWpwRZ)Z=ZEByd4FE z#2;Y?90kz8xZl~R9`$8rgH*zkcEV@71t2X7tybLe%yqF-Tee*yQ^S98 z4-Za}G0zwkm)ebInDe_if82f^=YZ#ZOarpGd(@J|&>@2V0+f3ANJEceh;ekK9^Il8 zEhElJMq*Q5pu`!+A0;&5>&nd0C>soyLlgb9_)1ax>eu7=Smn)hlCxmTFttHC2Fqex z_@C|thh2Z8r_XHZ-wWmYNw9!dX2oR+!ArQNzjHRzoi*LcoBAf|z&`>B)pjtBVU2II z9mdgInWZcxZUQ?{evJx|0Ynl5rxophgM6NCpN803pQclJuZIym7X?Ag4-zh!KA!pqu!ho>8- z>1sq1aqNLH?sb`=gn{JOq-ATT=1cO4wC-d1Gx_G$O$w2SbDXjOir%7 z7GoQMyk&`C5d5d_0^8xYYQBG;RqHColgu8#?j?wn8o1G5kY;0ds&<;4g9U^LpUl6UwEAhO^4GdKCuxYR^lGi2R_d6>O(a>;aN=#PL{ zxJKwSB_M|J#iz%iK*}FcB$!3JY)qe)tIwTE^&#Q2^i_8kNh1ks_hh^%fPq8rb&SEz z#Nbw1g)eUpsJc=nN{v<`v(Yz#dJj~p*v&sX76_p&=nXR=INX=`QxNRkH#$xXBxb}u zQ2^x_a*p{HGT`M>ueE(Ey`9x3RI9ErDsG>?Lq{x!c$?AY8SnkA%H9kF_^h!0<|Za~ zgIK=2z%sbFFC>#9ae7{e6KA|yGzMl|JoJ?=_GYskLalLz33SQZJL`wA=Y|Pt&TaeE=BCFcs>#O{lgfJ{vnzLk1(e|#>y z;*e#Po}<(D*`q-l>;y~|8SiiYmDs4!B6htiV9B=g4{nPBW1MJXlVR!C4e1G2#}FIe zO;zWQ;yX?2IIdN{jRiSvAJji)KLvm=MKlE(nDy^njN=U`#9JkuLiYcuO?$b8;O((FvNR=@z0t}@zPnEiUnl18o1K9Ql{w@(^M6+lvc0`mV?_QugW_Y=ou!ryon zO01Gg{ULLMgKxThg`miEB&*g`E-KB{C4!ai%~jzLVasH1U=BvZd-(=Dz-GsZ)46js zQ&zvN{5YGarxCyp)E7VuKQ(iv!EX7pQmmWsq_gPv?`jQ!kHRlZG=1>NVJo*<`p}xa zA^-#7Dsk6xL+ej5X6Z^@StR$ymLOEq7Gbg?CgM11o=Zziv6S(?BeP}@o|C!ZX;J_maArUxZm#V*z(2pEVKo>NQ8DWFi_tImX1 z$ZxHelB=P;h(LESL@giMPHc|8&Y^)Rf9)%%YaL;kwCoNL$-gaf9du7I-UEu<$$iXSCNd8xH_#b9dL5oB+CM(aglt2qt&T?uV|2l`K5!?64FS)5%{R zscsQ}z&iJzn4r2nO!~0nP6HA7M>TaTu_@Qs%kPhFS0(L%WyEy_ly@4os6(mHJMRmX ziNGYEH^%IL7-dA{ZpT|{DR6e|#l-(u?^{gpeoFBp1n9#L!btJ%MyPd=*DR#;l8NSp zjWT4Lq8MB24Bf2&DPlG+wjaf#r87KWCn=6cRQd)_Yr}`7P#YC|<>SIs=IUWF^IqCE zWNMIrdd=fFzO%bTb75IVL1yDjQ28Jgbpp14j7OoZ_CH#R?x_j-rge=UF|vG#0dVg=R|18~VnddK8zBrlhT zHdmJ!ZTj8#`#K4iZ1;8~#}RigzOv+X4{A6*F{Nqsoa*)Q7z8!B%#N&mv+tG{TXUSUHWk7sZ z56jhv9U8@UMq)4aawx?0!$Gbs;dO7gqW`t)>D%&575QI?ENrf|+S7_G#UyYLqOg<_ z@4+%xXQhqBJzR?E;a{R11BqkISrO^zlby8NBs_uz_E>a2!5z$bxv7(b>Hnh2flBjL z1xI0pv9e9-bFTOuOEI0#qvV^di76#Gb`;ClvI7d z5=C4rRxo9+*-Hao9;WqSw;HV+^DX`;^AW7&v+&;!`_fV51-QG%7VOQ=Ji>>{2TliDb-(-n%TjyNb2oNc^w;gFwJv8!7OE`?_#9br;2ZTW^~~6I#m* zchEFcGBO_KGXp)FFv64BSXc>of4W2_dY;gux@YY?c|jzLg-E9G+-@AUc(oMCmnjM9 zgxB~)N(pvuX|$eDG;RD`5C>^a9M-pfWoy3H%I~U4B}$LDF>&Sjl8vmAFKYi8GzE@} z*p@TNt*pkO^I#qk=eRf1z-3dBC3T0j*0pkVL3&WetaU-H&Kf-YAd{fI+V8vkiW(My zv!+SfN&j-n^N+`DliC5Ue=a!p6S(L2zyelZ@%3&XZq~L!q>5||*U-f$>qSAC(Uv|^ z3EdXga9KSSc*!;G@n=Vz7~9-OR&}CqxRVgrOLvK;>44*e6;#O(A*?i1ucorWQQpVc zp&siF=FCu})a%5%6akNBs#-7&wCT^$=bOjWW?gP>+fj&^;bu?s)Ir|>D7IzPtLsjy z{d`zOg0hvylry&NH4PjK%YzUUBk!tRo?>I`*=M4a@|>)?AtKVn;1J!C1n0L6mTaCAcqKb{2BfNZ%cKGtja(Czwh?G^_DvMxFVh@F0IslB-^ghD6X;sb5KJuteyIs`?@tr)L@p5g=cfU!mFWExi3@fkNX3w zbP0=#ul-#W0o@5?FfMeaN=xEPRB>ra8_1H47) z?R?fD#`0&5+#$Iq$3`34udRPL1`bk~8XG;&8PK7RO@NcgA&fnbP0ZBRy6xO&Rch)5 zi@5DyOzY8=$9XoG3_|ohT9ycNz5N>`1J+(@1k@0}w9KesaJ0%8gBc!x)mkrAMoiQo z0VFLSGNlhok%+xy82=o|e(`|TrQ?D|RwPFS)Sfc!2x;e0&P;y})n3efEB(t$3)5XBMb4Yfhk zNlMV%FCblX(+}~&X17kMMWi^lF7AXzJ=c}vLPCDt!}YO^@^sErV>xMJCyaSL_QFa* zM-w(6ddS*pGr~(oJ+<HJ$Ol^BOnr z4(+zs2N{(HD4{_dj90ryh;wanO462D|A1qO<5Zz!%B zxYRd%%>i)(=AhNm?W<#*scKx-v(yv|EIRwvjc+{nadDmn@J6j_g2-&WrB(OV2X@oW z_wmrUZL{Iu)k`;UNuS|HacZ(y;4gYvL}O}T+i@~Cuf;=WpaFZcf_2hI;Cu;C*PYe^ z;hGDDE&DAK5uUIm(wcwc04a*9Tw>gsXnr!ti4uo~ySh9XFdUDf+4QM?$bs)+Q=O|6T3xHGJu;#=|S0r+|7%=7`JA43jzYIzIa49q!pp zWOf@fH4e7Qr!;=c$1o9jmC~2Z9f)B$y|_X%rb1O!!${GpHeB5ViPC74}X)OOn6WT!X>wiSK(?q7;`w@fYGda%zC~EgP&E z=DbRefscoCjU3Y4iEey3>_R`u^O=uvT}5Frvxw@-v2a1Ps>GPc$9ED75s5-B09i-1 zNdV;l6AnU$d2J{%-6{dMI}0xsTp%D#&SPcZFG8TT|J8xE@)5Bp_8{tO>hd8~)Jk0u zBKcSS_EYhx^HrZhC~B%vdUdZbjV)3H75w9t_yCl!%?|BpC)7XNCbPiyb6e-6LkeJMD;NZ^+nW71eKNHL$n zAGTb`66~cfAN<@gli`}fmd|Q7AB@aJFHww3R4(mD@vYO zeG#n^u&h=+K-~1}figA)bzIEA(~i^m;xK*I_(kOi@NQpNdBnN% zPol#X2^Mzlzk6TqBPNVt>s`^t$G7O!o$|U-tGV0Xseu9YH#~I@qzkz4YfLepsI{&e zaoWgQ%qd(+Lkz+dtz2reH!o3|HD$lN)&fC&nze}03<;d@3Syp@uZ%Qa?|wg*I_ zn;zauuFn7zg<@^0UZFFdXQTWK>>h1-O-z_b>l`dmLBStQRjiy$Fi*?W=F6L%sN}hn z+C$2>oN9fFCT)yt0Nl2ALBDD-w?EUrx_7bSAgzIUWrzm|z@p7L$Vx5RM!>Q5G<0NB zS0GDxWw8>Bg6o9Q28yeridPtb1@sA@)$N-PYZcV${#u-;^<*QPcei(%Dt1@=k!QkVRe^wMj3RO|3Ib zCYv_j0kKEJEQ0UcY4Qt1DR4@=Q?8uc?gn#D_!B&^pep~qk9eNnR0sAUV|Lpe9kr`N z0hoMZ$|zO}Sr_WRtM%Q-3)6MPdD zkBR7GaIHWy8u%L8M@{U&ZwhN~bFY}fF%Bd=t#=Rdc+A9T-?T^b2$ppPk!;JwyBjPK zNvew2Y|;HPm|rGA9PBcQKE0oAQ$uR6Dg1=XUl~=+8k=mm7G^r58A*2D7n7jhZ4ipi zi?PrVB|Q-lNDp=&QMsG*XApO|SWZ068D*`9lZXP~H2q~)+etsKy(~(8aTFKnb>9i* zKL+=HDdr$E{p2@=h1Tv#?NbR|OCHqxsM6q>?;TgXz@)_)*0g=GHPSf|uyd9>;1Rx? z4`^Xf&^*0lQuWwQ z>9A7{^-=e{td8_M^zIZzgtjRvf*KZE)dW2P%M!&_aKJuJ4BbA?PdhHv#Whm4qwSEr? z?t?>XmdiHUCnrw{SS#|hYRmbcc}()bpJ9QDbYcc=ZFyCHw=XCJ+q>KA1j@Z+Zjs*e zw5HOm)EHy81!4s&y$4l4aQ*-67XUOBW_fH0iMCzbA>ZV7d)0gn5`cOLQwHhGG4npZ z3H5gZ<8nnR7JiS2E^JAhCti+}{|LdbTg_GQk{_%&-DA*(w`>D}WAN%kIUSrJe#$tP z{8_|>(qa<;+K1RA(U;@&!r$Q&g(cu{22gHoep8A`yLhC7W>FIld7Wv@hORR`)fU zW27(=KOMmN+Uaq(jL@jcz;i3g{GOWgl-df`%-l<0Boq1X+mXUJ(5Nh1@<#`B^pJu1 z7nGCe66x?>KnLjAxu&(|=$ukl{`bGf?7mYA=MrtWBl-zPB<020|LbMjRI=?wJz zEeYAjZjuCn#+FQ#{zs}fHyL)t!4^w5ocJz?q;IX6x3!Eza>4Ox|N2iw?UZr8`CHeM zqo%n|+8PKlv!heO+NN6xaxm0c_dU%ZM_&CYEo53z{g1(8j<9R9MV>=&=;a?DNboJ_ z*>AB&-7kWkHMG18!|*kbG-u+;-dTy>zS@R|GB1?`074-&}11!(GIIHN#LFqt~NBe~i9%2P|@FA2boZD?Zjnx^k1L z2exvC26l2r`ZXLmk=ZBu>D$$3!i69?*FYsPA{C~TV?nc<4Nn7xUQSJDW-DTM9==Xp5vEElUVXwHkoa$yA>LRA>-PCT| zfq2w9ljW2XV&3osj~Sfi9VWp2$ue8_k|wMJ<~9KqcrC7Soz5dY3m;{sn}_ zCOuc_g_k@}j7T$M)ih`J2m;Z;YZh`y9R*Sp4P%LABR898We9^SM1@x zYI^73r+)UQDIDCM_LnKKbnv-gRth+9o|`=d#?w7KvoD@n!;@k55Ne$M%hP-KTb{91YUJLQK$m){Xtkzsj} z7p!l?fKkQfTLsBXdaFBr`guIp9Kf)I_%sk_3$By!9Ic|V2L;Na#{VjE!cpPn<{icN znL7UWv@Z>2m?gVAU44>yqz(<*Dlml&YTu4DHw)&hC$f_CLDgUY9sk}`>^sidkO@le zQl(4kke0ii*o2N?q4vcA$f0+sBo?M*$0#_Q0eNIOM>2r+Oq4_Ps3N#qXA4K{kPB9m zk~HLxU!p|D87u)!F~gk^pi;G-h_jSieD`)Qcei|zA*y&h<{DUReh*pWdzMFJM1_sT z1>`<}Z0xLYk>iT_8^-@b+E%SlT+N6x^XC0df5E>jxQG8EB6TZrMKpDOyP1sm6PzP< zBM|DdIVEa4bb={z$|7b*>%+`(&g_1 zTLA`$a;ruPiRn_NDq26};P2`7SeE1qpA&Cc_w{UgE-val@R8#W~|mub+Q z2PH1FNSj>Wl_y>=;6AI1#k~RSWYai$687|Q-apOrj4^8iTAOa-DWKle*{53Cw9+4ged|Ch=KQwDaTY5hc2v6zkNb#0~N7^$7>>FEb z+}Njl_T|bYT`XOY8GQ@J+jICal4R9gxaQ=1ZaN0NEE5nAxVip^XiT;hra9@O5nQC) z=lNoPP-KmFKFaz=Mz0gL$phdXvlr$ccqeRXIr(ufd!xLl({YPmXjBGPN;T(hDBpb6 z_~*ONgX(S#Pyc#kGu^{`@^edN;fE@}G{St|f#>&8oLZy&{hkl?&oSO*dk;dysf&uu zDW0mSz1)jfqSGb=@e#Bhf3NsrvwmrtviY+g{oV4XrJ+Xdk)38R=JUmZ@F$N|x8C?& zlJnwCl^=}lridy!(dvFCn@7;ztCEKa;RQz0%eEB>NNKiC)uCE^ZM*G1`o3I6qpsb) zbGc2EDAcO9b>8oM!zsWzxWvv#;+KCeP3++*aB^sC2(1}pxL=%1q0;oo>;@`uPRl`W zxnhQO&XmA3d+A(pWk-0G?!QOwSD?nSWTh92BWXifBpJv~8aZWd4JM1UfJ}YSQ-}sL zXiJ+-6>Ve8cuZ6Y=E`dC(?dp<u>R7vQ#qPM#P9X5lkb`qLV$0$&l9|xdNV`nq?9KhqnDY)m2 z$3@p?%wE@!(vT_Q%L zZFV&Ag^ucEGx7Z-D<`JSER}wz>43rt5ruMmz`|?>8|o5Bb3Q;y&(kH(S`b^VQQAD@ zxZMSrHI2q`I=ZI~-cACs6;h&_7cf8)6fu2EPH0>a=*06-_tcja$#X=W$?QjrcBl`@! zox_8I7HU&>V2ZftvSoq*)4wKaHHos}&NfQB=PK0^Daki@;AGNH{mZ~ejuKoj`^VB> z2i1UCURjABS*a|(g47oZP84WI2Sb;b0=)^Xu|fFxSyoirrGSKsC?yNxy*ithu;ss+j0wmR2s?2FUG4 z?r(LhC5d5x7ekF@RI5|vPexbxo-r~$8^*~kVIWosyDwb-P4AaY^H#)tiBj6un`0l* z07c*jAr(!O#`n9vs{}olQ=1Xo%Um>#EHXBP#4+LM2-}c~ZaWeyrRLQg0fq$5EO6HJ z@R=({$P~UNU$NI`0TeW*sD;rK^N1Z!Il+dH;qwXV{zomlusS|i^9V<1i5+PpV*JUT z6V(4~+i35}i`j?>1%_ujE`%;+pLwn@^lf(beHA(*u$vSZg;rsY8;4sN)atmyv(^fH z=T=z=jNl?*ATS6J*&HQil3i(S1qTM6tF@!N-9C$R8-`U_UH%kdaJwk)VRK|#(#$O9 zQOykf4u&0CLxDxdq&s+0-U`<@h%B-kWWI=Pgiy%ZcHy;%()K^IARNguOeB$wM%>cU zMD1jrRgGrbEVPd9LhNCj$nz6TxHuXO_QI&ysE2ZsKM!2iTSjMSvy(0 zAt8_Ev@Y#a?wdN3df=UMT3x6xV!fm6Bq02>tk%R89J&C7od#bz?MuM?j1F!4_ICN& z1|-aBgsC6t!^pIH&!T%sKr*~X{)X`NS} zDvU8Rg4wx%FgWIdB@>eqjyH9>xxRG*$Za!sve+=3$RH~2=ENt;gV!dFF6$6s%@ub8 zXmH&ytPs7Y7%l7H2pX5RmhG}G1|>%TO(Wi|6 zvEZ12%WJlRjOC|yB0t3wMH1`}HmA`pgEJAtL7L ze+HV{9Q5#IDym>EQ(+EB%UGusC3>B#3Qq5cEsN`-YFc+S)#o>Ovpvwe;VSdy=(ncI zM|+*r6z^{FwuyzEc7S*pGGf11m&~@(&c|lNHdq>_WW`$1=f0Yec0fiY>`A#chgYIo z-=P(f##Jb&T+{WA2aG_iD6LyIMBQ`&yar)`FCujEz{?l88#W{D!-89}{9IoR3S-Q? z8556EX{$;i9tClx;{OT2Ix_*w(6eeoSQ>CFhxD$M)RanDq@^OEi2$)BB0H!qg<{KB zF8Ne45W*w<2fs$_wRsiuC;aRk_~o*U#c@vPrBbHaT3_k(fHO4_p8)O4wI%jjZbH2> zKFJ;Ism6?(qBeI8g-V&`r!w0F)+!1`9_2LqO37Nn)JbKHFJ7?8<+VP}AHd$E?(h)P2IH1?lt^Zgi$*0h)NxM8$@gv!zAtx<38^tJPn1LoLapxOp>Ks+lC6UE0 zsZ$Ke6-HNg2(C0~o})RR{Miobrg$LR%lbNuPp6!rCAivKvjKzpuqT-7iz6t=kF?bl ze|D~j8-^$ZtcB*i+x!r=`LVU%HbI}W?bwF2NDnmuC)^a&rV<9xxjWvdM|i?~+JA%)9I z_>DRz@-dh_J1I$pgfr5Gyz?`4CFji>_(m7LVUzo@kW}ies-z}!B|G(ST;YlZqhlAL zZY)R2%Mzd7g(<+opD5*nL`u~2w<^@eufx!+GZMjSwx^RDtq~9g%C5T7qFMH#p}rA*c~cR(WyJC)_Q`$pFHP<|AnDc_Bv;;1*>dwf z`oTBcVw!jJwJ6<9 zUz)`FTcTB@dSHxAA&>9*edtXhwrAGWBG&aVQyeGvwj8I9UYy>5n)e=MIS2>e;G*y% z1N#ropA)>1 z$VB}pgDaB3R3}$A@jI6o6-%znIA>+dN%4g@bwRw+zNeqU!pRVG+Q=>iCmrZKnrpFe z>*A{m2SVHMqsJF=@KqZqM?4~=DPXVRr7}f3%Ob`)%VL_&%gLw}{}tg5kVOz4|3)JM z-?NeralPqhPRW0^=#P#XFLlS75CQCcz!9=YIb_7Ie!i%wHk`X8rU?d-udECK zD3v0FrP38s5cKPm7bT+TX+RCyR-vNtA&l58@&18S4 zrX>FHCSh|9P;Tg&6loX>Yd~j%@y@h2!8q=_cd((*BY>>ttIg=V(g6M;q+2E?w&NY# zr{Tb?YO7@?#A69q4Yo(9?h+9-S$?lceve8SvTwNLLuPDBa%o=D3ds)!MHEz9JxEz9-t-^guVB> zVum3UbljA<9bCpkj_cPp0B)FAp0PE1s(a~!{B?Hqvj+YE3Qa8HJ5tnP_UectkuekeMlDK!plCka0y!RO`)fYk33ZaC(hv6g% z)qkx%79$E#K|IUx#{Eoz z0Dyi*3tM#DvE4Ve+)fvFEWIVsxyv(I)ECpC(&U|IFLIV^h_WdNVm1S1W5X*7`&UD} z2Sl9jm@Dxs$w)|tq4Ic+!E}aX0{&f;M@4Z3s^vYqL@F)NR{5`)O-^p%FjlI*oKl4V z_5U~14XUCbSa0xpMsGzLTP?`E``?he_Gg}1E?LL~7^Xa<=z?*O+mGlaucBC>1`3Kw zcHjpm3K_}x*YRG*kR%$XuS|eGSGt#ZUY~!WUkWLo7wpd5_`Mi2e8ugxw}2EfXSu{6 ztk{^mR`CT-*@svO+FH9*`TFDV28uS%7pLD&ZNjoQw<;Z^`524!YsmTmw#Df0Hbhwk z95cK@9cP703~_Iv)BTczvne^nBj?Q$RO|9dxKe66)c+=tmEZNO z8hjJv4af}f!s-&f(RRls7sv-jH?kMGP@ln3l&;OeBk5G*^kuzCm@X>UZ*7*3!Bt|N zEbuV0+6S5*w(zT+EsGo&66adWvz=fp0(2?Yain1}sbHKz z+TvP=QWkIZ6vF{HP2u)r3TS;+>w-?5?Pk$vc-;33)3@Sb+9&FB-C7JyYl`H+5ATsV zFF{%&l!xCAa$VY8mB*KzSeXadYt%u?$iq^<>cR~nyEK{-O|1xOT7PgG$`XMaEB$G0 zPm+Ltkdj`@Anzuo1YP%7czlNUDZjmJye zPt?D!Dkc4DBQZJk4s%bKMcm^-d%zM_{LhWo^0|$FG9i1&l3;1a500e+q(2pxpUs6* z^~|~fDmz}~dtlig>H>IU)IeS+y|$*}nUQRBe+)$QAEqW4R$L(~`Vli5R=kDsS}E{| zb;BeatE(auvgkD?E=Q)A`Rz$ye%FM>rxKIb$fNoLzo2MCophFxfo;-}%xCOmmMNT| z(%G`Dx1GLVZvD;g>tvxU91!))33N;($0giR)>;c5A+teoDVp z(L7@L!#T~Xn_e}&V9Z});>|ws{-yyicMt9LwP19tT#fm3i5-sGge@$ObcmecVl;b; z%7;F1IK?tN#kV#U1VT#R9S5Mg)o-Hnl8LH_0Oe%w4jVOA#Vy|O@`B-IpK>qPu@&3r zRxZ4|;|B;E{fM-kn_=7wjkcFNKfWS=8U{;nD{$@R6qZY&VBIcU*dAEbmmyXzmoE zjqYyfU${;)Z9#kr2>2U)g&De4ajU%6w_0p7-K(}&VCY!^J0A&*VhmO`!Lbaq6-fgm zhrn>r`<$Qi#N7)xM?k@fAzHj0p(YT-NS*YLe!VaA(E;rZR`mR4op+*Av!p4|B)FrB zPe*g#CttY7wV}dq;3?Yl#`a?IVmKZKZ!zTeL!;IBbT|2P5&cc*90~phlz_fY1{5U(co=T8hS3g14@iLqfXIjF!ULi_KWs2 zT#oENdo6oO69u7{9yXWLqC_sLXs@#jU&&hiP1OYa50m2B|ElfCWPKheO*;&gjFRJ_ z*=#vV&*T6cDR>i!l%?fuIQe- zD$j@-+&aAJBbTtOPqYfS_RZOt;=9KaQ(!ivC7=ZW>u^8US>CNj<(L0V%myvLbg?*i z(BE8PH3w>_lD2s_SwWQd#kq9JH;|O7FVuO#HsPCVP5cZ7+0J;@XKz#)o<9b z4z69W@HDZ!NH8qO30{`mUP4NsW#(v_)djd-Qc7faLkhiu8%~0_HAsmLRzw69d?jUZ zB?Isf_~7qP!r-XEYepyvzaFJ>e$~^eA7FzO(h;b+;`}TFV-Q%(HIU&kL z#X#iQk52Nk1TTL*H`&Iz2yfIYR5{Y}<&gf- zJ^*v+#cdmhh%eX0Yh^prK*M#yp}T-1#EA=haZH_8BancY>L9*pJ4$Q!9_=r)Un}S- zA?-#^0n1xTb~<_>@lN87?%|u^pGnMD?JD*Rk!%?S6C%f{7D4T@+_Eo#%|g+%)jvmF zIv%fL4lqpQTIufGZrS@jn_T$qy%+()$E8COA9(b>yt|7fYG0g1o8k3#ris)POCuT& zs#J`#$KcyxBl*k>5nUWCN`Wn6d>%g__wSlzh7YRQzMIp_25iKesUMzWc5aVPIy&=U zbt-5Y4a81~mTu|#5<6kDh(fb1b-JF9pqh1lA-}a5an(9vT`V1&8N05?+4LwZV~ln7 z5Ak>NFF0AQ8yB(s|y@ zj(J>$u{jNqVBg|lG1(E)F>FogY2V|qfOf}QAOJ6q^}ur3Bq>bW#%CIYuH;mKkXq%3 zP|40mJV8jyx;#ELnY$)e^Fq;TilO8g+dTd5iB5DIpH@dSLOX8na#f1BSo@ZJIw`5? zpUz@J7!R~A+XT873tj_Kjfm7|bpPeeQx-foVoA&}PeqYN#^(^lQHb z|G^S!d3tKn>yr>O0_;IF=LQxBni@-o_f^;V+#UFJY8=(Qy?dINjexlW{G7hprlTU4KT0 zS+s-%h4Fm%9A0!ASJV{SW(H(@mz%vEd_%vOrpxymLCofzBi}fw9clBVgXVJbbNJ1_ z*yU=)*DmEIM8D4^9EM~B#5j}PC36cCmDyVTj?)O0D4|ihPij=Wywn!x)WQ=$-2gDjp~W>8RiTwQjg0vGLiOf9&~8YCTglv%;t%o8XYh+jaKrVYga{1 zxy|24+=mdc{rQKUC%O}A*}s~tj=v~6rK(p)KWCrc5Xn3%D?|Ir6znoygbXHZ*?jaC z6hbn(S6=W704<27W%b@9Tn`!D1{ch>PjBvzOd6Q+WXOj;`i1B>M=)mmJH03F$iiF5_slTJ? zv+zmLxp2AGLIFhCv{sHG>HN+ zu*^!mU$>Die|0lt(F{wQ1h_oG!g?>H@S?LPl0!2Rw<0@vr473_47iow9<(AC+{G+j z=D4Y-5G>mzDtWoPnscKDR=~$e>kLoma&qxsQLseJtLOSdt#KaRLs0kysH@yU*VdyR z(wRLBEf&&wmYV?XpEvD^zKWsYgto^j8N&8+w@DZaJ`6XH%Q9_1WBKcADA$1;81*sW z6gxmm_z`hX_3DV}D6#K=YU>>CTjazf7)ui2^DB92w)ATbF(M{*S5kfgA?DA+N2 zvfWF(3dIi*GS{Q{oSS3RDxe9DBt|h@*NR!)O}6~W`ALZjzE%;y`c_P8)5SjZk>-)ZRl; z5O*$7wY!+1Un6#nWeL%Ukj)dz1U}(bVlNMu?E)($?p!V^RE{^czn5t}T%*jZ z#$rNjCSh3Fi9|S=-~;d}(rk}PuH8Ky9WLxaaF{=bG+#-sbhWFM?v=3!xOm;1Y(?0A z9XH@l!78$cXi(Eb61}FFBt0N3QQYVkcF8ZOwL@#4UsrRt?SYHv3ID7B_ z2+r^DEglxFbG`=6tfs-ix+AW%hdc2uEr#!dG9OTi&0%eHYryDiLO=9>uDR0pKVXLt zkulTt75Hr3T;k0ohLj8DbSQ(L1#ITo%7^Q-bW7WjC%j-}f7tB?yLy0)OzpCOe=?C8 zh*hkS>zF}dS^{r~bstG1&)JK4csjTakPKj#$YZ9TFhk|`|J7gW8x(-=krG8)Mz4E* zADIc-*>V|jFg5~r^g=r%#I)3;$pgm-GGSA?%}PBiWU<5Su$~`{p=)rMk9H*or)&D= z6}+rW8H$$lYIWM9TDFKdUgJ~tu7y@HUrro1&`c8)16+tAPS9-AiQ{uh`x-IfW>*MF}|18C*z1PGS)ol1j*nlBGs1e(|IJ`Gw)-piRDM3f~#2*QtaV4SgVqPp5&n^I)G zZ?`fL??)(jYUHn!QBrg22Pz4=RAjv8J9RA4Xg8cz`Zk?8(H|C@BnFZF#1~dFdsx|L zofjj*5ERh$hCL4|8wuUMM@W&80ur91Uo*6izM#p0&10%FJA6lnkt?>+8o@m9{Wg23 zpw3~L@)L-(-tym#<*@Lzn~fgkSsF~4jul*z4os+pjh6k z?fKb_Vfmy-?T)$HHiwduwn1CWD}rNm{e!?$Mc0L+*cCqtI3*qw1+cXOZLQPTqXjGb z?@w!sdk=x%dP+{PKC?`*H@3RVGZ>Hxm*S20SBEKHBwD`8RQuA_G|Sih`I%#gZNrfe zj-NBo+(Xiw06R|>vF;T56@v2eDJxYKZ%2aZ!$#a8q9yz8R;Rirso{4U!6co++K+`Q z>klf0&G&n1#zgWqq&@IlZKv%0o)4NNPHkpytj0GWgu@P3KD@TeJl%&RXGPQRyL!e< zG@kHNIpJRShZF}T0tvI2o*l7oU2?-4xAq!B=R5f);RqasRG z5Af#}q!c%xpU5(3mL^0%%qtx;CQvPnEwVF zrlRMTtxN1*Y&Sr0kfr5lDwfGOYAw0E6nCha6}-Rz@D0{0T^Y|DTD79t#CR<(Qp#6_`W~EAy@ZCO3P#)bV%|0l0U?btYv##PG1Wsd9GMa3~#Zt48cdwVP0Z zW}P7K)Io|yErKhlHA?_qcMuNuaRRj#ai{tbg+i$W+(G`RQmod%MGcp1BkdKn#|1sa z96V{x#i87`563WEbtPaJeW96V^ewnGjTGeA>Ja=%%P_)z1p%AZ`3S!Cbda@!|rApm|yR-iwQc7_TEv@w(;aoLpd?DuVQm~t@mWM=@ zeP>@5@6iSqwjrx70|lqvDyo(yOe1rnJF9FfHppul;C1+iEyM74OT|lR&V8PI+9tkL zV4K*j!$4w#)h{DqOh$x-W%aSNLJp9{#3SpglnZoEZQb;mH^MrkqRELPMXJ3;d67pF zdC!mgEH3{{;k(0(tCXt#VKsytYM;-!EN$s;q+lKnK?6;)P&ViJ^urr#`$=k9RoN`0 zn~kbrKivZO%^5I}2wr$Ki6?r*fp!E{W)gyhlY&(U(o30oG~^ZVfkC_YgfoP@C?QUK z>ZUP^mh(Zxs>b7Ds1aU1wj#4mMYT7Q!to9SFCW>rVtf4$8DseGEwf#Veu3f!qDmzV z)m|siI4BwxL{Os2k=D+1>aFGtL9D)-ZAK-yEL}c3PQX*@_H_sQqGkUUA?F7r)|~ny zed`$O)BHQqdEYG^d#@4|ceG8@5ZCF4f?)_d{$V4VQ6B%y_6#ajXm72YqQ{_=6TOqT zx0VM_{xJECL;Exum$1F<-~%V*4M+&;-Kj9RC@tZSJzFlkojVrm&BEV#=mv8FR(AC= zUV8lJRE?zmRS(uK5)d<`2#%2OggUL4JU5W5gc?F#T#~wmqZvBl+B? zn2vMcYj|wAm88lP-Y#5gkl*K*8Dft4@Xiow@GsNTvP0j^ng`PBPkngO}%`JG@3Wxcvy1s;57 z`aBbOBdMG*w0!q>HYrRcZ}NhC4Z}mya4fH4fhsPzqF>n>gGZsI`3a+!Pc_$S1m&X` z&GI}7=OQ?ygkm*dG|#TH*miNtL?LWUVseX(eboF$8FI`QW&4i|4xv{K@RnGp3L&zj z^uG0+X?3d0;(VlhDnePtXgl|<8N;G-)8YjQ%ZJYIvBV>}V1>dv(T;7j!#+X*6cv*8 zqhZcIa*!7{mfNzHUI{9u*5H@rxwebxDW_TF^N_;xF=Y~)Qe>%1xDf-iscLqR`5;-* zCkj7I$zHQT(YyKu*EuKZaJEd)SX<`u2E}RDD_izCj~|apu<5_?50+4z`m%ZN24_iPDc_DrT0(8wHZp*L^ajrI3r@2!#}Mtf+X@U2_~a;$Gar;s01`Bmhl!2CJ!t# zPdXt6&<_7r%kUnh2wfso(#m~Hg-HS@YM*rRK}NbLBkIX~H-EG#%QZtaR5nBEbVl$w zS&~Gl-O_U@+f9u%k8bGc*PX=x6p5|cgXM%8c}h3)mIDANHWl3w6~fM zgOwYh55+8k8i|~dtkZB?2&vTR-VGxHWO@?KW)Hl;fZqrndo#g!60OQY$e~6DDL48< zImnRAEYvcqRKek z3d?&Ixz9PC+G9P_-iYMxQQF7pvC{b0SYI6H>7*V`l&ad%c6*8ZV~304ns_E&0eoe( zkc|45z4iJR;_OdLD2$sWRQ$nR_6m2d_NvSlX~Y&Jz#`u;d3Pq+2eLU;G3T1}Ebnv6 z3fI^)>lrMum$6?`s9u)T5SOx;+!gTqv6+F2OT&Np3F3D4CV6e1((}QfT4yE1O#7*R zvufTj2x!EphT+oTk}rihOIjky9%{PE(_L~(Ro+?62#;Ec-CB0@9ZGMJQo1j$GBo}^ zuK~x<_Qd^Amz46|>QOBx(PLq1$}jwVLeAFF`e&=C2%kcP@wPH2n&+ppMI0lQKhd;0 zY1cjhZj}g|Eew2P5I6DA`i25wDF}O}P%IIql@~|{OJz8k^N$=l;^IsQ<};_Ev9U|J z)cb%S^`$E;FBs_FIHDpJmUx`i73ZQ055D#w$tId96M8 z+ruZS z1@zeZ?2HSPr~eB{*NVQlA}XH0h%A%uj?P1u28SdN&C4aht5HY_yZ zT6e*P$4+3E8&2k}Rq_6mwbzx+J!MDiYUF-A3D$7xiH(ch=rzZgMmfV16v5v3LDo@@ z^yz*A<{-k@WB{!!pu`Yh&s^nZ^sWi~wEkZ7!(i6RG24UAnY@-g!WHttm}Xifz%X9V z+j9?PwHDoayNU{HL{cng%2d?|y^yaS1t@e4nehr1GvDn4h}ac1sy({oriC+CXV0b< zbCWu)dWCmg4g~0dW6G$<hea%UQkYlhfxPEXA*`_V3U;9lf&gRPaXd3{UO^z3veInpVsx3urP=109l`lJuc9BawSE;j^NlDyMwVHI?MYO$p&`2B{cP z-`z5T{As%Ps6NO~L0enqkR~;e!#mqjVKo7mJ;eKaZvL(d^F`ubS!^RC3c7sYWM8Vy z(u*pxBxUWEelRxE<`|~Ycd>&fPf!a5pZ9^2dSH@R_%%_)B|cZ;jwc-}559nS{HT5b zdcV*Ur#Jk*24V1OMBup#nb6x{$)okq*j4hFr!mz!~Z$DoGMk}DT3a83?3vt8LX162jh}Ya*UOy*2S60uV|Z|cNQ|H zqS%<`){}d!Osu|%NFm7*N5tsppYXejNWpWF+yu1v2*!(g9Oa$g8tf(%zDMz%HJL;e znM$~QwGEh&9jrqe+{o}|4cM$tyz$U)mO`+Qa?COs<2$$v!hWxY2c0~hujs5;uye$s zoThvt)4r!ul4wXe?wA=CMqpTGwbU8q>wHEH<+@Q! zqI@9E;WtO@@4;<_b^G9#U`xc&jsfi**qLfvLv2wnkP1E@9a5sI@7e%_?_)i44=sO? zEOGX#Ym|w>6jZaGU6YLEPdr#?P^ZU@!KX;ZFh)WjHc{rOP9M^Oc1z@GRB%P_-bHUR z?F}1!j(K0wY?W1Q8{(?FPF6>iA=~Jl$7#E4`*&C~xK>f}Vk4n|S#v?^L-i`Q8y6v)^Zp6kvy|b?n^d8=|j7o;^>+3(}S}DLa!GQP6s&UWu9-JS_=0 zP3Vsa^wQASw}jzS&ef`%)GR34eT=@s6a|~ox$y80?GPA^6cO;gWP~1NI zV4bfVE>3l=KP567Q%udlwKW!CjcQ?-){>c-d8U;(i;4@Xrw@*@v87?z4`#YbXF|1M z8stL9<)hU=+denM2`W5FMhC$ZtM z(6{ilE10o{4-x}rtVQOH*a$Q*ONqgk+mWvlj-eahLx-h#fYAseI^mNo?XHF^sv(bOb5H4&3uj2@QOz7> zWjs%Xw0m^G4a$8W%!Y{z(NEIbU)R2F-<+ofLZ(hMu-z7mF}QExSvuyemSi~qPU{Jd ze>E4FVS|XBv9{g2p-gsVbA_qMDTNN>Ir~6OrfqSq{=aHQ*#9q@5oT7V|Iv!5-*?Dv z)_PqaH$0oefl;;$`zF8t2ENgg)?4-t*jgt_lYo51@a33|6q7(9`co3#es$8o%L~e#moqU&H+pQb4qjF3@0W=~pdyCyPWvvF!wj)d>?eyf3R_>f>7}Sle$@Ln zQ{r2C;!vU~+Wx6H$(m!->(SygF8`pX;P0UTd!7#Ej zu(SS8Y&?+Yp}B<{9a}tG+>YPoIsmxQ(d^?7ITORH8;2i-_j;;f`YCDuFg|&4+17q6 zwQACnm)AoB{J^xn6R0NlftpuU$l&G(tUzTtem}Vb z(ZbN+r8oI-g&`glIs!fP@Rd?BEc2km4`%f+76UDE198>GNT3={5t_)){3NqAF3}B6 zRNjyX$**dq)L3&$KP|bZu2C|4O+lvMN2$)X@Gew*&j~Bkiw@3+DOruDp#=Xl{{R*RJ3Qx|-z?7G2X+PAxZj5RhNzEMl=Nvvy zyNWVS9yFpv=e@}>0c0xu6Rc6;H)kgs+ZXF1QVJ_F}ncxz~PQEtPoZ+k-Jd9nxgMq$oK(oL7ItK1@SFQcvQYR>nqp}#1 za85WYt%%Smmorn{o9s#=B8sLs*hJJ?W^HCc`NSdAT$q zLRMKUY@c1bl40qs`8Dznr-49N$y569os1C^!uRQ8wYf5%tp|pQ z3(FMY0?%z3>GmV=@jog{`ztHh5lr&8{no(>EVM3Gg^GJ2Hg_OR%x}+B*tFIGA!C(! zMR{cE5sYfLYL%0K@v&*}!JS6;{0q}rVBx5@5TsZMPL8qi4+tNmSM zFZI5g=m4N+<6tG zx8&;?qW>lF`%GP#8wxXLAKxW_+JMtWJsN$_5ZNBKg%T}+xYtw@4GH&!7j%MP=sO|t zTG00X_3Ml1Ku7@gtAZV2oM$CaVZr;2gDtDx=6D9v`ftri{hobV3y@+ zgWZ>9VDM>Zs$qCpFg|1Mc}t`AR^zdIwkF5&n1;G@^yt(#p2T%)in7h%-OYjoy!SvH zhMQC~4v?LLMnKAY?@FVVMB}4Z6vf&13VDvDEq-E1I0;NH>(+PV)Esx=j4em@ZPQxd zUUC#plROGuInCo5Y`oP9FYa$8uk=%mRW)dqT{UhXAcKGwhaNxNq&WHcjhW$k?F4`P z;}zFWt`zT{2VwRQ2;2tc-?lq}GFT``hj%fD#n&lvZ=dKnLl9lTh=KeL`!J8k6_%?w4#1M|bT#KZFd`X&1KWCQ-M z6V^s+GI+0piM;@)TA?^oz*A#QZsoi7=JelV(wnn-;FM9QW>0L*ofK9{u9Q?I4}?|+o(hRSG!*=MJ2G&-mGr=!iV$|+B$2&4YxzAv zgayeheQs**u|sb;0#@-s)LHwaADG!(#8PP|0;;rF2Ai#I-w2!vD$eZM%on;~LeC^D zoTOG*j5Q(%Ft?N*K8y(^F+=9_wy#S}(nX>+xX+?b*RQIfpb^ge%;6eiRITAKxc~M3 zal2Mp6&*ch1R$~81j7-sSi!DRnINMSJ8@ZWJKbj`mB2Pa_}W2+?q%%&4zj;lVFfrs z3FRw>d(pO1=IA6U&p9oUVJ8FxARI3=mqd}0^EU;l@;!zIO)3EoT~3N4zxK=K4+f%X zLzuE0*tc{Z%T7)yPd5ucZ+jqY{xJekue1EOBGOEj@s$Y{$|!BWw}mZzB*g`s&{k?v zss@+#lbHIwuIxJC40phc1t0nKmj|Yca%U8rq?HnsUG{KyOoDFyC|);VK)m#5_tE~f zsfLrsaU=~&vBEO2-`D1Rcb!so!23#Y`K~?GfZ!{%NLBobmqn9^y_0>CsUo7b{YBFnXjM!kf1y0bi_Qmcg6-p+BSQ9(L%G@GD%T<-i^sC)R{;%KogHY z_td*k)Y1rKEaBmFL9;Z%kS8d6QHj#;i?G)W!zYgdT6}YB-wMUCb!gKdB3FrD%6u_-sN~04o;wr5A262 zqh%8?yulTqtLB7qCN%~ZYMB~nuy`(;1sXU~9h)09d1UDT9pu(TYvniAz(JAQ_?-G}4e~j<>OtHC28!KMewt2Zc!hI*^f=yzZ%uko8(hu=-Ru>=Ab(m|A9l ziIR~w_fe^082x4mPVi#04U+#k&zKy4#qELMBXi)Uc?=>C>jJ!2y1UNj5RPlyU=464 z-<0W;&${d1SYdyzXAqxJBtqHcipst}Z4qn&9CyQH9Nk)F6p z={uW9yz9S|LANFsXz$vn5^Pl^#Tt4>N5q31KayO{K7-NDa+nnkmyJAr0(F`d|3uh4 zPufAx=`9IfeWKKJQbhTf%u~3K<%=MMd8~@pMFLoMZTW(Es7K~QzQOXPOX2_daL|vBFZLv&oRUUy9O@QFb zfzp1*lER?l#c^#NGSZQoLEK<{?vi>}&g&SW8^oAw$X^5HX<{T1sc-A6`o#;A`u2T= zj0XfuU#o~~FxhE;X`s&!PK`KZ(E4OwsDGi(i(d6Kjn9(xIiI6tPWAX~Gk9>CDXFgH z0w#>YY(ldoX5t~JNrnhL;)AMnaD6QcIm+~@ruxKO#wiSWK~2!tQnlh6`^=C4%0 z`;38w3LArrLaKtX!!SB_V~mE7wy}2=Wzdal2O` z6{JrwK;K+u8Peb3LFMU|WeZMd?Z`s`_`mtEhmm5!OtL-Zg=fTLvoKZ*^Hk>WZ^g*^T^zl4X9au)E6ItF?byv`t-{ia@WO6H7>;y z7S(GN&0Sl@bQg5$vmUFNPk#RS3|(*Cbs<9$As`mKP}1~!1v|sW`DupNG)_y0w|fF; zFmpyYpd-2S$C8nA&hX_IbH?gk`ps($$oCT6Y&TI2F-EG%bVJs8CQkv9aQ%}!I2&-1 zK`rOgT_#6#HVT`2sjfjg?A<}TR zu?)>@x$+{|3n*o1$Vl>Bw8wtBnNs{xtqI0yu)C2?WTr|cGo@&VHrZqW*)%;o1q>YG zPc&5igl&C(kITA;$DAiOeYyj_@Q8QeHJLI<{czC9Du}sVk(?lCurVs^AK|`4-^9ls zG}1#ethl3)1WF%=JRy4l^ZW03i$8sA63#a|CwnRRJ&BI=`8fJ*NFN*%s*kd#~y z&i0mnROLCLfM*f`j`#ls!ZQ;%`61@u`zR>Xg3#kOehY2^%k*;mT z39CT?xrrYtcz8prllzKF4B;q!CVIr7LIy!0Ngd)tCv;mr9zEvVu(LPbk`3I zii#y4WGO#&2wqE@MJ1#lb=t%aQ|{_JvMYb%3t{PKABK$mEqI&GtQ zckLPp9L);z||J!EQ}u;W)ntcd{MNO2i$@i*Hmhq5 z-Na(F@$h09=N+PygUVe4WGZ`T4O($x{yn-G)<4=!ch1h4$wO-GO2qA&3(j!x>`fSK z!eYs;INwH!K|mDmy92npnwqnCc-)Dwo<)bxx3EaMk{0u&tE9`b zgRTUx%-mW47p+casF;g-LAQYwrU)kj55eoc6x9oK`08GFmbxCDg?NF z6p&AZi6w~q8V*}`rUR4rUF&OvGF=c<$Yzo1<=k!=&LSJwu>#FR*KAgJ@8Bi=VoKQH z2~e;>(OZR1P?b9Vy`@3RpPjRI2q@47KD1h;X_Zud#WEidCmJ3+Ik{m_tiE-u^<9-J{5HV;l`|t?N&U)O zaw9ZMBy?|KffYP_t8m-8e0Aad^Jc$FM!!|Z^?3Zt&a-bYWsvl3CSzLx`VZ-~4BA(A69>+olDndd27z+&tQel&56r)$gS6=r7{|K?imMI;Y5 z7L#`uKij&;W+vUO^34NW4#xu8HB+WXB>rxpXrqFsr*H)3@I{p_Fez@4EozaMajR$jQZlzz#L(N!Mutizt~^eIyMUmi=c^e#Wp4)cAL7<5jkd6GeeVa!FtbPn5LQ@W!Z2PJ&MpcQw89Nei_s6260iguGlP5 z`w*Y%EVsA3SPL9mlwjZwI4WbK0J~RtIL`N`MPs-O*7bIFhxH3;yw<>DU1G1v$!{;Ywq`N9R*YtN$^bG1#4i^P zkKr+~d<-|`NhfPE89I$adlYjE431TXgmH1MKj@ZqW-r;ZXOh`wyIV^s{* z5Kg4ZQKcP7%(5NTx{*oh;b7hTV7ItIJtxZz{UXOQ|6mWY?@ikT%w!}@y@$^Nic-vSsc-0Y;m`MEq&5*`~QQ)YmdgF_ZbF2+B z*g{Y17w4WJhco=tI~jF4Vv-0`#cN-GhlEET0dUD8VeEUd^fh{J=to!^e`~%%v8Ov~ zy`ydwwkw2C7GYm{KC?-NS6b`juz~}PeSd9JP8in}yBq|CoOTaHQI@v9nj@2CYIlX{ z7SX}2FW{zh)>QV4&K(S{t~wzRr^*DzA%6qfuXNv|%Z}m?Qp>q$?mmV<;25v~d4P-g z7yG-JjdFrXRI9o#{S(r)ea6=tcWS|0=z{SQBC7h=I|ymH+V6eD>DGMoEOT*vof4C`B?2^f3qZLTf3N9G zlN-;#nJoqOtL~XKiZ7c=H%=bgG!YwaRsb!T$6;8YZDlA{nxJY4hZs5wFVo^KiQgQX ziPZA}N`07W!pml9Ckn~3oBq8Uos`kqd#rFMf^6ut%Q(duJw1Pdn$nv?xpH+1!Sd~3 zb&q9EcRqoRE^7kYtZ6oGp@FI$Au#pOyjugM322NkD7sNTRlMsL_@E8z={HECA04~K zs@PnudNslsDz1xZ2Y$>UAhZfCYdx z37Wl2-8j$_xlLQ=JoZbxUp5mrFd(TAo`7JuFdJ&aW(J+70jQud>Fu0VTxFjfRXT!x zOVQ$JOS67w{1! zA-_E^=;JY}qERr%pkVEsvYvgS;1EcYD)opJ~-M{!(me+f7|W*V`X@;hal zvSeN`@nzd~28#I8+Sl`=8IqM|?4t$Jcsnj|&W{QYCe}B~ep><)EJo}6Lu51!JDPQb|py3R6aKTU?6%mfs+hE6P?@WD>I3M^ zk+YPXSJdTjPtgQCp^AyM-YFBobfP4XaqoD{*g&bl6%-*qU4@_;W_bJGQK)YE#WR+z zvUaZ5gah3x;;HpZ!2HS^7;s*XDo`4T1ZHIB6V6z%`wGty1L zv-HEGtxyV#_cy;2UgUnyT&T160hgNIzcX7XRAe8s!^5{-NG8pGu-8nLt@RCxuID4k zKPbI_@sfqM!m8;@3Y9te-$m?lFT9R&HcV0zt&eHD=c5!ZW}D{o(7M~%c3+R-!vs{G zA4dD^M*pCFYZljS^3Szdy=~1G(_V~D#x0>(9TU~8`*IwCI_+I9tg7z&J@9;xW${;yEZg4RzyX84-AAcrNAaoL)m`yI}@=h^_ijaT1 z2PLYtwse_>pthtoLg0*&0myv+IerEq%qV;Vzse>3!;PH@O%PosF+B0Zy)&X#po+*H z0~DviqOnNE1qArC3rZqoVZ&|QC%ZW4)S~QiYE-leITcvJ?}Ak|q_`@=5#RivDXqw| zG$r}ZU*-VG^TV^Kw=5+u_@t$eR15^ue21p+N%XGb-kT~HFyKg-T@9q^5;Yp0mWctB z4AX9-V;r$xbZ)ZoT@*B<(VEm=$q01X^UmGz7lNMp8eYD{u$wv@wBCU-(;Rf_mfhu^ zXAh1yHE?r=>HAEk-?1Rus0W}xs@aT@F>Yg;nyNDfDOG@y;H>#7MD(BQLtMFbws4=gmto3?S zTwaUj{XVjzd0)1fST7k|inN=FqOhxhXIBI_Ami$9;VlZgtgqm1>jcOR1}na?)mw=x zj20qw){+@gJL^Fba{3%BEr`87PBYf9>mb7_IG^?+IGsSo`ys8h!0 zl*1)xE#JPK9BkF+3_pGt!iaGa^K=U-Sx1?Wu-$CX=wmr|lYMP;)+NfQMKe@aNtu`T zxI*FQ=W-*Q!BM}7v4WIk_L)_;8wY~K>X*}Cy*ee#EeO6_5${oJm6D`M4}_7?rrq2M zLPSlJ6Lvv-CfpMk7ak0XH-7-!Ng_&V;S_H7bQt3V6i7i7R%4+}*t7LQN|C%E<^HK} zSn-RHP0}KrxiO6)xHhvKC7OhEJZnM6uxIyg3kXMBq0-jW&Q)|BXV=ll!uS;UC_N;n z=4WgRM0AD+gh-@uZ5nG3#4d}Jvikl3?#g^u0_$@re`Hh^emoy}$A1MSxcP$Ca~K_X8j^5*P8)6iKt+_j{6jl1a8z6r?s@A260=Tubr^H zjq-Fn!_E0xdM?=l8Ol6(#x9e3=X&Xkz+XZX2&kf%pqw*~4ApSC1@);0 z0e@@x16m4Dh=1W+YmlY7oviAc|0bt${#clE$HmF6x%}xTl4=8F@$#jv49iU9&dMPC zY`az<$(xj?P}i}D>x&;*8wu9lfvESrYnE+0X;!JN68Y z!TgIMYAY&JdOiZ6f{v7U1zjY4{a-`aX9-S>i@Jo#D@m&uI@S=%mQf4<-FX+>vCP~E zWz}g%lUvZ^YTs+H8o&|^KD-MFG+}(IkzS%_D0-5a6IFPGn|Rh#ZoNwU?-nzBOaX9A z*x3`xTsp&!Cq+5zrXre2XiBokad4;2w9(Gqhk(_-qtH+L+J$FBy#^9RJylcYq>i-d z&igyfB(qa+Y|dX2K<4&%QXo^6X!eEtxDIYd#-9nnB^u*IJF z;J8k}h95G$m-4BmQ73-`2fFx*a2Kd>S$Z;f`4d5wbR!i?s~Y6_Bysla${SeXLc?mqO>Yf5my6TozYY+31D z&cRBq-@nCd#4QYreyp$iYg*e6DXQ^9(VXO=kDcCc4^4XaA>*EKb38;nq?H|loZ}s5 zEYk-K6hWIn> zCCSgYd3x`qE1bAEz@UmAj(~DQ#+qO&QlcIis||p)l3M490nTy;A$qJyebBlII80om z?|o$b+G_q232I>{jOZw3TF6VgB&Qv**1?k9ziZhP^#BCo0M-PfYjuMyPi*f01nrFf zK;z-|aL4foT3O|qECJXd2*!*QWQCyveLtnChfI`}_KF3d^Ig@%S`KcfXauZ^~_wrb?v>hFzCig~;bOX!_G-fsCb2`EF?*N#&> zBW30*yavPBR-fPCA>Uv}<|g71!&G)70@aV}PmB`dd|9>*w+*NzswNol~iG?`d*`RqSDo+Dt;;b><`w+y-ekR+gMPvY~d z%`k?Wg4jc2Ur&eRAlBFj7CfK^?X?akYytDD1IWnP|JWn8ZhI__7EJh?pnDV(q`ajY zyGbL|n_%L0hv{_}XC0t~T~_vn`h2f-(|;qFzL~t2OcMJ>jjjlpFeb93neKi&E(WA^ za%_T2&2+lJ08VT-RH3G^_IO>ySjVkj3eF#dzU*#X zcCFqBSk*qJqr5Q{38Fj1&k;A^7Si)y`iO4fRri=@2wYmwA1k&4GYP{NB+&Zq-uYw@ z-duVaa?vqIX}Fd+-~zR8nSW>eTh~^_vN!g}6{wyB*s23g7>YuB{#l(FT)ICWM zt9!WG&eGfu6F?V+#*;8G_LqOa=Kqo3ntR!*``ycUy0jwv6rwj1ig1<&ty)h#fX@TU zQT7KaFUo^e?2owKGdrZ1uymDW+}xLXcoSmq_JySxr-yI`cWU0mf7IMGZCAASEGm0M z?7|;+*&7y*2-+L>I@M0&XO&aMhBNkfW8(s!VUD;MK40mLrE=a#pv-lyPEfv%O=J2?IQ8Rnq7vt_)Q)gb&ntgp~tdDD2z z-URZ&Z^59PS)YsIH3xfs8-RHy3<5sF|_>CIPSGDg|Z6@oTvx@X_PKz4tzn&I$fgNTouj^42v?V|@ zV_b*jAdRSlOe!~{OP?0ZmwGoHWx81L&{Lno#^!}1z&`rQQp$q%yk#UU|F}RjlUx)j zz_mPiW#piw60nAYy9+t#-Vo_Ij?Ym#Qxk-7xOZo`#7?bAPH%FRk zv;Er2@uGV1qOEFT0+&FQfzqyuX1#s%P{T{8#!1>OYw(gFc+f&q%6qMhYBK5CVJ=br>2heW{$-JQObn$%XjAef*I=BT9sVkP;}z`3uK1Li0Rj6@iuqhZ3Wz?51{01(jA_)sCNcwb^x{^CI2O zErO{Jmr2TNCRZcr_X*{W;Kdp!P$CoCRm0ZaJ9{$uir=U1xjF zbzkkkP}9BEL~O^+EUz3aB^E`~R8S_jZNmaE9|c_-T)$XMS5t~h@>x!H56XjrlNjeL zg;MxGVzwOr8_f3qqoG;BgqjyZyOChXdLylB5n4_3to&kB2?-NT7vvDx4=1m#4JYWu zh6~6{->$CX{{apf=kRF~K?+8HN{pAwv}0pyXabRsMw5+|taeFE-ZMO-o-RJ`%>srq zE$fBbc8v0Kb42?=`X>j?PoaLEjW(9gO)d=!7IS-<=W`C%J2{|yv10qufKQw#^O<%h zLD~S~A+Lr>MefL2r8 z>x+|D9v0;J)b9eBwun(00k_=9X*8+BqK0Q_wu=;fg{K%d`k^b;?!QhfXLA^3mWsE( zt3UR(gbuii<0+o)P9!8u`g?o&C4}pP1`9xLUKh?1N8ChYLZgM!O+srQ>ax)=ZXE?(U?pu&>E=m-|5OaJ~g0D;S>{5#w`a834|K4-aR%8j&O6 z2{JW{>2VJ;1t^N1{6B|f>EeEr@iD{y8gwta9BZNga)@{&)kl+5Vis@Qad=E4 zCz%dS>m(}};j~V0+8aq1)_OzQ)OE`y_R91rq;NlXT;4S5`mxwQKXL0h{hvfUlgcZpf@Us$9-q;b1i#Uh`moCqF0}IbF?p)pHPrT(syzskvJsQ zK$UoVM1)wU>{rd_9w}PX+3Ir~qy5qB`KBfB|623bDNk^T7T11)p>5>T!D@s5 zT_)qj^8lh$ClfxjC@G zaE3>5QJw*y>St9Kf2vc~6LcBqa-~KJ4fono!|XH3cxU^Hqj`9;0V-%+wV%*xcOv!h zmXw`>-YDX`0rmJ2tq#jjQ0cF7$uBVzf9A!p+xlQvR`<)w1j6xcRy`_{kq)|wR7cPgy}d#dOj>I;Pw_HZW^>~lTM*R1J3ThkL@-T3K2LP1gQ4^ z9D%d9X|`1y+syw}Ng_=MI{4;H0GmXilXGW(UyiIhZg~y%%|Z@CT)0#>KcS{(z_WZk9|uJ++&D8%;no z+zlY}B0PJ78GDYTG{#TR2kH?A3oEtIDIBC?k^lNjo3JVDWH6Eneyjb$a~KTe82oMs z=@G`^LEC(#4TbCbO-fn{%v_>09({tvH3w0mr_nO32}c# z7%pjm3Z~9#rORK_2li$@$+oH=KqM9%ff$!lSmHkVC;X@XI@GeWV%wXSo2*%AR2ic= z5<0^P!J+$FR=TW`-yC}7>T~6o>DVNZY<(}7w>^7lAJmz<4xSWQEL#jT#)Kpf>wY{1 zsA!;>)PM{RlXYzxt2y87Kg$JeX3 zzyoQtTAX%PPN#_@dVf3lve0==!v6QP4D9E*zf;UsNuc-oMx-*CULa>zpq78rI{o0p zc?|STPB%_neiWHoJ{nB28tTJ*;Mqd5UZ=dp(WsS%%$e>ZmS>N8##@o()awl|(4zJ+ zTg*4hr$`g2n^yuOgV9p??Di0!#Sbdygs1{Vuv{7%Z*R@i%zWFa()S8^aBAVa|6f`g z+=Pdm*i^?HcF2BW3XLHLdWqs_(CYXm$u_MUaG(5*^d>Mo;wj6+O;Gd}9U0zF$(`da zm8gPu@f5u(vXi&;>9%d-Cuwx!A+b@llUlGcpA`cLG9b0|rk{LKYc-R&0?`_NYfc&G=CFq`NCrvZ?IF$sua&27eGuqThJ32*32VM1#mfSb19 zUS_pfob!mTT4ntd8LF5fsqdeqw8}ck+Ewehjxh>_8>d3Lsfz}dwhWi`r+Du3ojQ3s z%&{UZ@nK8$dgo6n0d3L&wrohWMxQ3$H_m1oq>?RL6^rBaITiD0!|jx+d>Jda@)+u9 zcfA&%uPKRHW>12VhD-*nTgCH2oMZ#+1Xdob;nwhKkl~rt|KZDbw2~=77QoWRV~2z~ zfkVYHxZ-Bo->Ip5Np_K?;7Q`kF$Br(%O(25eDyV*(KEJ}S`4Ir4{v|^{&JD@dV zWV`D&Py-yfUGG~Rq&3^hk;R8Nr1LL} z)3n-w7bWBg(cAkK03ceGQFs)U-vfqRdn_m~FLhNY(be#!6-@}m=S+Mt0}1!UuH?)! z?DRQpR@c#Q$+XOK!X_0?3!f$ap&|8!eA$^^%oFyh(oHtV5F@rXCpD~Za$*_BkFAjX zTuWO1qdS*rui?Cj{-ZA{J{gRKY4j`kFgMu(Pmy-vG7$sh8fBO#zkOjVIH?Can^X)D zl`F&ezoJ>0@b^c;AoZ`Qw3I3u!2ful2o!eHh!iEpHrk+1W@&>g+sAdF{CRYNs^VRccwF`9?)<>pW!PHl*F4sw5(S07#0Va9eYk*HTOwX&4Oh> z#%lfiCLA&CKo~1?&QC-A*82@I^mk* zcdL#Me;nBr(_5U&oPLcsP>EHApev$M@K??aV==0K0&J!EmvNHAt7(AITj2sk8 z0xgHbk;#&mp`r?U%PBkoa3=RO!R>~uJ0O=FpED$D2qxBV{9?~u2daBcxoffkp%V_U zQh7`%LiDJCi>RbOQBev2Mod0orD$FOOib|vmWS!$rY>P;IwGA-c6@sZjrRxXAxLaQ z^DrlU+&ICaVbY9Q=SU`?t{#uh8rKz?&Wl~p3V(<}1S>!f8{P0{*fjHm?-BhhO@JuJ zTgkm6N!ZVFxPcCiiaeyT@NTJW;O7@p2V^sx7c^vKZ4>? zP*D}F129eq^lfn{3B0ng7HOtxaI5khXJ6wl8I?mgE#*2c!q?>&^q&hsqGF;m6$}>? zmS6)i%!MPX@dB__UxyUja`U?tY2-V6QC{kGn(>D(?JUmc{g&d0-kJv9(I24C&rLDw zmb>olX<0brw?us|XKE}W(}t1YikzbsWOlu3L!e)3MUtRWOujUhooW-`bbj1J?_D7q zHFkIdlEyP$ieO9T3Lxw;o{anid2+u4w8_SeEZ=&-XeHE4BWbROIYn!`9I$TD(*DFi zxz_Uh76>1k&8k`9iTV55>`=NGp2o&XsDhktw@i!VOlrN72b9tG2-8VZX^IZn-YTUz zY`&+BwcD&|D3R#2RQIYtqM!^d?UT8-@how$Sdsas-_+YRPs>lsz7#g|UiA)>4?Z1_ zv=jswNC{llR+;*Arcf@8W$$2cS)Nf}Qe3f;FPM{m8~^MZyfQ>SmTy!Ub4!ZOl+;TG z8wIn$j}}j5BAsaWg5t9th@Fdp1q=PRMlhm^-<$5W4Y-&4HPO$0VmHOixTA%u|OzS@EUz zvELQU&JBm$EFwpS#!VnCl^zV9%)OrYJcnUS8;+gRsGqBH(GL25g5d;3RX)^E9oigU!ve_`^`&YRoy;FqDc0A%}sSr_Z5e1n65VI7%oKEIxM zz0YJPLG&<$&{U$!srd>xDX6D!8Ag6wW-+zR|t{WS4Ul$s?=Z^kzC(k9qAuo5$4Yr{flJ(V|_*0|4 zj#s`3J*1!7KQ`S$4%FmFp$QzF<)&n?C6kd-3Pe5=BWj?zHm4K#P8cyx^`;+8?(d!P zeNN^b+x@}7JC|(2j^NKiDExokUXG@tlO6u-9LPsCs>sXeym%czaK6enO3r6?fZHHm zl)G)eNY6sdW}mvu%>dFd_>FcWd%Fk!GIbo}Uq5=WDsr*~UoS%*AM`@}eu}0z zz4R4DcY#0Aef1q}^H3BS0pf^E64ym!&(d);O;OG5NJ>_U-H4Y)k2k+nk3KR-mX1Pt6|?>rM8n`4q` zrUdxBVc004%yHUEL-04IsuW@EMZ=mNV8JR_BY3U~dLs zBQHd~hYY)1+KJ(&Tq`Cob@Kr& zlRQmhtfD)!oLF|&^=IkwWMNy;Q7p*2qqhZpy*fQCp(11r7w#YC46A$5Hu{`Vods$^ z0A0`A$gsHRH7xB=@a1RkJQ#W)cP_Gx1U+u>=tvex&xO7JGi$ZFilNOVq~4$v!Q_3* z%UqXGv9ZU|W&U6$!+^=nPgZ5~>+}K0wayc!v=gXsw71FcW2m|6&+Zh+AN|KN+W;! zbP&^%U?W$(=M(Yo2v02Xy9uTY`8HP zFZR!?0omBCmDd->v7#g<%|n$t?POpv3>Z>@UZtn|(|2(xN5T_?0ZRYIC>c0p&L8rG zh&_&F8UbQU7O6z)3=JgOy@ZvnsVS$a78ME$lX00HG??YTFO83QpC@^YeYY0O7~Fpk zcFPagg$iZsjQ2~01?&(k+cU{~tImp>HP>~n0lm`P&ii8r@cl*MlmOdJ;@_X&E4<+9 z$OJsh-Z0_vf=|0@CEY$ox|N>aUgb;KT25yuuBO3T@KqIIEq|P#YS%w67wRk-VoMl1 zd)3dM5guy<=wWTdZxr$D#Mk_fJShDI_`QSSeZ94LU^eppbU@-hrhW;Kaxu9=zf{xl1R`k=-f5$Wb1PVLYye+V%(Q)I9u}=t z=`Kf~JRFjVG6F%`CJl;&eCwSKxV8ZziRF?wL2ntfXh-T2Z;O5;eE?GbrstA(k-nZm zC>;6)=8;CNF?l+lzk>a7)L!pCaUr>u7GC15T=q?YY>NXe&EmMMs6iIw`~3;fgsWuP zxkWg5d#xGAq`2VWa1t$S>b}+G^P1DA&jlz;(Ln)@8b7_Wjzh1Slo^{&YfA!ss>ufs zq#^Uvo(#zQY{P@%;W(4<8!CiocK| zIzZ4n!Hu_>NiYDgu4mYi{E^M=DnHOVP004*XlWRh9v-Xg@DC503;GqdzO zbr(huDad)O(IeXk;0FYe(Y(?mp)pj6q&~xpZ9}}$o}ojD5OOb7z3j7%0pCO9RyR{M z+Ve-LuslWygK$d<1e$?-D@4C&mw3;;fQR&ynF?(&6oW%%#^ZL z%PMuc-ks?48p9{Ww*U%8WwT$L=em#~?0S8!%z%$iO^jyrxNK>#h7lOhm(=IVF`*KP z@E5D$D^ZYz`L{VDgS35I6=8kX{*6VcNr_t^3P@bb*|6HxA*^hS*Z^L$r-8*q9Qky= z_A2D43%`go<7#n$Ze0~Znh)z?CSPSqM-YSD5d{Wnz;5+58mE|O*9&{0G1p3&k2Tcb z6QO{@PY#<2k}LHjtifs>mllgOQ{3(XuL2+jRtM0VJnRQ3ex8Mi78%v5IL~dA!`isHc zb*>RJs&K`hQq*4U(*dzg5k`cfcSfKjny;~OwdO{?wNJicah( zn8RC+ytQd<-@AxL%Q$2KJT3er4JPiD%@jv9d{07-NJ}+1b>A&IpGYLf~C(^kAARVrc$) z7Z7eW0@%v2)sTDguu+u^b6>G0LhdDnZ5i*Ph77IgNJ%zRBEYWF=(~VI-pt@QMeZsC z@55M~$JH>yz@C*p0r_k=R{>>=Gw_B0aOwnt(;B=nGCUDjmbLyo@6+i25#5J1(o}8F-9THo{GMs)}M~RfSa7tM}9t5(v>< zWaQdTG^xfY9S811Qg=UHE^elIP9xy3^gx&3WP8viRfr(opq`G)koQr>>Giky(Qo+O zg(h%hx}@un@1=nf-LgSxc}ahk?-zXgfY6kg3IzE15&g+B1bxf0hv?^=!^_IC#Zz1M ztkeWlMwQ)2ll~tIIyhN&KL?a~i8^LJV@^wZ-3|sM$UC zvNHn3-oztgZg{IaC1f1x(KcM96reluKRk$u{w=vk#x4Ax{dl zs4|Po4U@PLnBq7^@bhO~wY7Q}Ff(^Fc;*l~`g{)XBi7-tV*nf>|-TDft=f7Y16_csq3wwxe$Z2tFYx zhoq3ab(u4 z%lXgU^T0xigMU&C$ZiC;3+A#7#EW^Xz1t=Kwu6vccf5;aPMe$nk7{_MJ$5En z%b6AOZn9Us*NABJP{rI%i}-%R{I-fv_rQCr0tA+#@25eYh@!+<5%XCppOYzIq69i0 z4U%H8Z>dc8@>(6WHiuLwCEYi}+7uQ|wwI?gYXPpQKaw9$3gtG*-?-$*1u0vsHEHI; z;ozUTR%sc5k9K|q9dt$-Lwe6R3O8vhN!>!|DOEcdt$r`c;Y|~@055#FBvv>#w&;OT zT?g~Oid%aV0(cc7t}AdrY6pV36YEe)+DQm^abaDrSKGi8rQbA@XQyZa@&&&5+Jgya z&Nyxvh(3Ws9Q+YN8wUG-AP2TwxQo${&nWOM)1KI>^uVwQRt&Pz7*7G&3%1}6)}x+x ztTXp+H4o^t5&!!8)(L0&9xbhb9Q_~gA{~qjr5g&(4G|S?`IPP0W#3DnC&Yz< zOq-Y&dFbe_s74=CS3*oQ(C&K%O#u%VOZKeQk-DC<{!_Up!3xE3bQ8#>Buz*x&}JxH zpH?m|@H5FyK9cLsv;*Crm5<5gOZGomwghu5CLYgI6SVDl9u zDPl-O2%d2YKBNA#KPW-4rN)46}&CzVO;SM34fuD-sxLd@4sM`|F~AclBX!f zoOWrT_@uiITMrHHJccm-f6 z@zj@TtWw1H0?P2`8R>0A8a%-Nuh7j%vIASe-_k(Y!}|VHTth-r2*f_(@pyK%zC?ns z7nglfvUY5X5yKj9*+XVBv@br=KFSwV5x#I(OVlceX5bj+bp#QKlpg=bD|AcSZ$pj3 zH7~%O!V@!}GFrEn&4Me-R=G*$gfqN9^>)DE?FdBh*wh&uhudgK5!_|9gc0XGnCd<{ z&1@af?nPta=NPt-j7bRNOg6_?cJ7GKnBT_xQ(&RH_agb)m?KKMki-k^YLU-^i{Jr?)x6E$E7M@O!PN$ye`2aEfx<3f=Gzada4n93yD5ezkV-?|DVEzY+p z8wB%uo`VPQ_8sTHTdLzQGG-DGdyXJFZu)#wuTSi(X2EQf_Yu(#R`?oc0j5H>z2!Ro z(mNTdsD@;I?l%%)MOG|tB~`z*@m0L^t-s$bxhXMc)#PA>7PU(`g~w_;tZijUKu6ZW zQxlL#RM#2CgbNnog~WC5x_F`Lx)9~O6tFwpOH7vKQjS_O_YG!eOkq2o?O-;=!Fylc zk(Orm!R>newoM4r1BZeFz4OJnFDrquhE%Gyb)Det@>`dqZrA#HkOVL89OUh50}5O_ zekB!n3b3;Ks<`u3_6W+=kK>;^z;{;eAK)NieXH|&`sVm+q;@NQZOuP2$=Rl{6;$A+ zMAD{cuR58We_V0`Ii@UGR$~2iY$d+gM?@k#>@5#}m!3JDfJ%8z(Zmc?VGkmJpXz=8 zhp}_&&P5B_Y;60DZDYr_ZQHhO+qR7z+qP|+J4v6u>F$f~qW?pURikP>HD}>+A~&Kc zPe{I$N`P!2N$nQ5sho|vu*i`aU-<|F7w9jh@XKBmq2jb*acSF}00F#bOQsX%0}ax| ztgF0#@zg97v=RT;zPIu`jxzlom#npN(qQ?n;TUa2;*_5HBIRx@BiCsVhfL z&W&k$UYM0iAoNI?LU70? z?>>+e0q<&h1{4KTwR4|{*YguOs?Cm%&;5s_tw%RDB3%_W`Cm@f&C;%Maz8yc0#L48 z;b`%K=Fkj|yV{~W?a~nBaA$EL=Jn6baw%jt>yck`6#MEdha|!DCxb#k89|2cNpA-XKgc6YEawkmx8HH zB+4P5B$lcwxi9XJx$#ft`iuMzP}L|8H6W9VL$HaEyBcZGLf}eTjAAPs(U?Hp zMdTA>K8~X)BJoBdB`dHnI+X03({3{hShSXK>2A*5Osnm1>JtPWN%(?M$yc#-Isb-v z%j+HJ9RBOgfY?W>bt3DGm6$!-iR)=Bkt#ZJX0FaJD(AKs7i7P*jYst)Adx6TArjXE z7exKxNmArG#7lp#Xk|VQMD*r^1mkp{@L$>6&WVmFj$G>9mGj~*CE;_UTfu9oNB}fp z#)6uM^gr#IDQ2y|cdc6(w z?y#M)b}`3?RGo7KMCjBH0s%wEjmq^6r9(1+N4d)5mCmcVb6{8>Yg}ttfhu?X@WZ2b z#fY!Z<_*-uuFLP-oPp2eCMW-%6AnaI94o?} z;?yD`Y^~DbU*`k1uu^l<_5&*PEe=F|&n@HV2JqneDQH8+hqa1ueYm0eO*_(?AeN8# zJU=Gsd`Kpx6$V1&5c=k)S&wyl1Ud2D23YF>bGnx*bwrQ-DvU}!XF1`1mj$W+!fBA8 zYnc+M>6SWXfd8BypQpxCJP@RwJW3>o} zBj)qom`(EiIziQK=0;K?#0)194@qBVeM^x~xY+4RD?6^{H4`$|G#?9Rr3IuesJcbU zF%A1g;x{(kNw62q2nl~mpHo4W>eKTrOR}TeId%?$D~;|SPU!8>paCh^em|3i?y_J& zJ(b?M3Mdc2+f(0YwX#$0Hh)l}PzV01(j;zaU6_4`02xZfmfn*KHX1kS^M}Gjt6!=F zWSiy^+(PY#lM+AUzn?1&x>m~}Z)!2tzz+F_40b_7n(4>F{5!#S?C2%XZwemPh7)nHeTJ>$nAlu_bW3Z$xaF*Hs*8G82(6* z6(Zi>J_sM^PjBk+f}geX{5E0aI7XE0@ww=0&WQrhU<4M)yfR7sGN@PJjV3&OY!~jR z)zk{IMy+v926`Q4Ujm$K;wIOmv{N)Iz^D!e6b!gq$|3X()WgH$u!%JyF9q;3)B&-$ zD@&1`4&Mk>0rJdKU=6ynm5S`AmB*yS2g+e`wZ}`4;#|-nf&vxYv_bk2AXqSH$T*N=lj`FBfbwm%N&`;$;a}r|Z2-!mC(Wfc{KU7s z=>Zog&ebc?`U*v=^qNcoQy%C@Pj4NQsGg<1w@ss`>I-s6+ywokmZPXKBJ<&z316$jLgw1v$(?DK#gmo+~XxS}uP@ zi`gj<_Xkh@v9nvZxCef1M{Xz24e(}pp){FT6Ea5*ud|w!R_2SUYWZH#y&n1jdx^2P zfgL~aVP(!&4n*a)O8fpKQg`fMSn1H(+iHwpZGOE-&`SN#1hfY$yIa1 z6dBPFcS>-`{2L3R$C=;=@9I?{;+>w=oS%<0-CPgl^X@aT6iNj1ZVo6drG)$oF+Z@xn6%+yQB%VC7(+d6i1&h;oy@1)S4i z7D2)ohM4tiIy=FN(@*DvacdJ_LQrae*fUW?GfpCYG~Vf6XvHZ3TeC(@d#zQePX~@c zU_=(`JTOhn*9PdnT#V=bZ@hD#4p4yX6ESIE!W7psn!?vhOM+R+*#{{GFzzgF9gQJ; z*+4ojsC87jPrl`EgEFz?h|eFam&Z=+ zQw5uW)i}+MJtSzaLeA7w{7^@)>56gn1v`FAc9eI-Na+?M1Z-Mnr6CmCtOt5p;*^u( zaGlW}og6?`Q@~`#gaB>rE;)az*X-5&+g?8A{KXi|{&a=8$=6`Z>KCp$ zmFQ4ytcG?LwM`73i-zvx3{zJ*4h!Myh(HeVAF!=*n0R&?=#gObnCJQCCk3!ly~+9J zfr~M=p}ISEJ@)-5M*U;;=-aN}@g|;c^vai#I5CC`W#3qTA2l~2OlU0(`u58PEMt4= zkRJ^!4w2zp(6YctuuN<2NG{HA6&Z2su{5l-k0OCg@i2wKXk=+TJ$!#&hLb>}vJQO& zWJD=lt&D}nS?Nrg{m!A(WgQHhWv`e&_76>7l+BTMh40wY-L9T%n6 zffk?LY?iz;l&o1XV*6{icbL&ne^v?lIbrQu8*oZOoJd-6h(#8|?|#^Rz4f!ZjD~I$ zX4M6=-)GNd2Dy-0aK7jR+rrg|cs9nckPL0zijkLIT{M!Dl_-9yE!X+&e8V4Tn89a+ z;0my3YD??>_Jld`=E^(CR)cltz%T%Oc7WM>hHLCB!$Mm)OrOl(eFsFbjpI4pTfE%Y z$9T=y@0my-;e@Uw1iO8_jB00x=rCfUwBj`1D-pL1`XqN{}~4WRNuheIv$=rVSdZ zeBtA5klSVA1v_r)KJ^)XRu)JiDjU9F`?YT{Vxxjtoz%gMnUX{Oa+Qn$L(we&fvW`m zB~Nsm!1FZ*-H+~&7$Ipi6uu~4po9D+7E_`2_BohQ`<}SW?~-`Lv;3xYUN!@SqAW?t z1o*WK_X9p;_{^e<%R76sNAnI{WjaoJLc6hk!^t9CVWvTTsXS1OI9-OCnBiOf)L*$> zBZ+Q?S7*&6I{tl~J$aamk4wUKVNfrF$BOI2nfC2TQx!k){6gNnD7WJcz?}|~prO4g zOs+InG&ZT<66C!ZOmnirM4Ek-Mk0l=>D_0o;^RR>$n``RG5JoaZf5 zaVAxV#qP#&dlgWQdZ`6`h9#UkPT;*$%(WAAvPbLp(oEaYTx4pCB^f^JDZ<|m8fCVV zkLQg3u{R&<8UPY$oh*tB2t4#5ehF}=*D4Tw^~V+IyZealsu36JKnMvF9(vt#@<=CR z`n9kTFwI~}Sew66ehXHM%mrO>c|eB{!hlKO_j@fL8>s|vL3309r8t3tQ_I-DktNMt z)IkEoVQ=xZ$%Rt~-Mund;|)4VxW((zV>_dszFJkJbCFf$n32AwgTPFtO3# zrE>+u1?!9;b4>4zQJ~#(|M_qcpfroV*n@=JCEg4y674h+rw^fE(9>G61?E!JB$Qi; z^XRrj1IAx@j@;H|_olX%Nhpy1k+i|97j;?vFekARs?bcMRU{cct`35-Xl7m7hDJ+g zgrtLWb^B9r_Q*5(_DM<4gNeLZM95dq--qr?gI7zXpgYY9~s@-VHf$khyL+&{-nxvs>Tm+xGyR+1%UEQ{hPpv(jJD&hGobsB zS&?vb4zOV^aos{@r^1^PN&*@h)8`UyZ&3lgry;tSbZAWOBl#e$I3=#WB2V8c{d!c4rjs$jJ#z>G?a`J;2k9 z$4RZ$e5x%4!En*xL&`}cgl#AmHC>t;*;BIk$OclHh2;R*6y z{tuy~_`n_(ima{*6AVWD6)e-kGgU>YmRuXGWT9vD>&l^1b27ajwhN|KXOc{_zbQec z@c{N#faOLg1HQY(+$RXL#Bm#e%v7!w=8q z=z6@tGQ7oOMH5b&4hUW{SS$>3rd`Gn_oKOnoZR=BRBhWrW&=FYtv6O8GPHI_`aAZC zAEk32JrsE zVhvp{EGsZ$NG)usj|)9(9YbO$zNx<*h&gulYY13+u+#ZNuJa{RK8vXKx8UIAfO_cuXx=+Cb~=A~d>#h0_@<YBFQqulk>IYI<4Tg1r$#KrFOKUEn}H0~z%2BX*zO-q zQ_4IPpXHri-a%W!zLlA&`KOCv`@cXiv+V#M=3%+=HBimtD&?{m4enKU6f9X%R;MP3&JW_7zbRAJ=MX~gE)_-P_%lXZ_j^ck@A8+t-i^Q zP7PFZog}jwbj!qe;>f=p-0?LJ^7hOH?&lmsG$te(eUvmXPDp194{f^j)?DvWHTgp@ zvAq+PY47{&q^kD&IsdW~*?xY8qyRu$NwUjlj>%ey*=&y&xNFczlp0OY#cF{)rIPr` z@K}em97}-##Kw0~&>WL6+Tm0C>P!Grj|R|ysGQ?BrGN5TV1n;Hi~%2|dnObL6yN@Q z;J7%m<@!XEp+zqTcTB-!YY2zXd+5b2$TAR?O?M$l>^0m>dnzyelwu6#XKiOuuC&#O|p5e zU4iy=r`?vq2e?8MmZLGWpuT zh#6AWd2=i%Od!_TAuYr|fhm#pc@TQ_M_l<3@#pUOgI^iv@d*cMTk88$Y&> zmIMfn%i4>#TX4X4QlGItIq%p;!R}4$ketUftE`i$!5>dwel)rk+DMGx7hD~(7V^Yt z(h}9oJAOd|Ime&yvsc$jd7HCw0o+B+oBD=RYh{H(m|SEpo$kQPHWl-%t1&e)`tF-h)pGu~|6@;;*}ByjCO z%Rsu^;89}tBPyzq%x%Bd3-Eaph?$3@v*JrwL^zDr^0|4^g{^Ye@dWuS)Dy$4wW^8r zM9;C^*>F=;wBGWZaEgfXo(U;OCg%jFq!0@SnOSf#q~UY0xk*Bc%6x zxWjY<8{SS@{|dXM`m$!1k82xzZYWv&Rif9FN|eEYN*dorCA;ffFNW-(1vnl^Cir4H zrToj~9D)46%eRcOx7BMS_WvT8dJE}Ami?%k9mTwZG*SZ=}J z>m2(WpZ-Iy3s8S!$vom3K7c$^C|bLpOM_E&_AUog^m?@$AziN}ZeM*{0&`8Zfz~$2 zG0y2{=7YEVcCHod24{XAX5JNQU(kYV1zao!Kp3{PV7=@cb8@ z6(NW~gMLK89e^a06}QPdKOa7MMA!wSX!h%sRL|G^mi z2Qm1+*n<2H!AAI{ZU1sb#UN7E3@M|P*Yk*xT;DKr?0mmU(%Mjz4JvMVbQ4EvtzAv0 z?%wMX^Av*8_{PK8%(yV9qPg9H$#LT(p|?cZrVu6L%#<>rN8Dkvm7)5&Z@ zj-6?nyBtayd8uXh0ooB=k=~UT3C=pBL(tX>ozGEO=vJ zu^Og!IvPR~-rKAya@gdt8RB@NS4;{ZJv@o^IUggA@8NGULAz#ozWGYE+f_ZUk!LA% zb5cvn3Wgb%bV-ij`A@Vq&Z9v8z+s9d3K5iufNNNk4E@NuY&g0}8FXg5=BsF5@NcB6 ziB}nSpL#eaayT?W;X?Tdz=>yDdR+foHqrf-9y91hc7v4;XHO-Lbu=}ayF|8gge7~b zPr2;G-mBc_Suf}h>Y{{&uEKPThDhX{LqI80$n>OD3)G?%U`_M#|F`1^8zu zEDV|mqJH0*FS4*ch$s%(0pi_6OWZPI}6B6%Y1X*Ykw6X^fDEl zh2R4m-s1KgFr61)fiK_Qo&uEAD)Nf0BCkcSk-%y-cD70XJ?Hv5n{(_VM8($kVc`u@V zr)vpganc_n$J~p;BlpfL+-S&+x}7V{JAJ}^ewCd60;atIDeVM4N2!kaJ=IdLkWW7p znlwko7sJroZ@oa*B_ChiTv@UzgVY2e7I4x-X9z7oN$xDClYQttP<|rs|8cJmTn)^G zrmps>u#8TRwoPL7;)vq?u9-R}MRmn`M?u1KQ1o_^qbqQY|E}I z=yXm}ZR;VGfH;<-ij{=JrNK>5zQ62SydOnwaRrob_}2+4DjWDNvV9M5$w42dyq<)` zx~b)1#&@L7tsm#wqp}8UMVN;o)XiA>#!FBkl85r<&;-(9*+wg~e>_t~ z=dqrg(?AJ1+7xIME^S>nTNKrqvEA!1&1fnJ)A_@yRBz;NVt~81{mixManEt6V8Y7@ zrej{a%Qi0*b?I(bL55a`crRK)mPgRt1ei%iUQKXnl0&G@EfCKXi6_6)ME{Y1%Fo}` z;a=n{m@v?^b-1x?t^TAYT>*{;aP-4NYNc?B22Pk(YteR9dN7*Yx=Tj51Qw!&=a5MhhtfFUqziU zQ~7i7uPfrF4?DQWI=+`>Ma9;GXi=k-PX%}DE5H7M(b?tn1fsS!YIz^i8{}ahPcd3S zP@de5n?;z0V-}X4N0yNcSnF8RugSMT4oCE621F7V|0@}eX_ElALS3K^$@M7J)V8;b zR;M?tNBJf9u{*vjLr^EEijaocns-MZjObmOK)=r<2|+1dc-Otme|FGmOZ%b44#B)h15t``w94Okip#9il+JrS87)pi_`% zP9cRm(M9qwZ@8r%Hl~WO=6`9XbF?6FNX^l_yT0*^$;0x#c->KCRNAu>k=%zS3b})P zt~k(5eUJ)EFUnO+h7eMC=j_cNW^QJ$gixU5yFvbm@A6Hnn*_4^O6SzP`oCxWcx_Kv zf3V{fw=nLXv>XN9msG6__;Y<2LmnC{W<(J1AMrBTn$B>xPo*^E6{IyXtS0hv{Qf~O zu$b{a%Rq?VFowV{TCBNDj@nSzj?r0EKe84CtyiZo(&57~)_sO47uMe}IRv0Rd5I=~ zM{#Dz9|*0Cio5{@7123mC?`NbIpt>_hjquK^uMIHy0hT%45SW&EcO}=hj9#<3AAcG zp0&ty!U7RtqjM6IJ!5n9acUP*;bGl94oIla%3=>u)nGJ3W3()NW_HpHeq^yL=!5)3 zKh~R9MgY)56lZ9a4Soxo8vQUknmJ3>$>E$XF*Ra9p*x7+24&A-4WBP-4Y8~gHo_EG zWB#g{bvW8@-|gP}BWNYgMaEh!1xJS`kjDd3H~!@ismGa>zX5+=1y?cJH~hKPG;P6- z4}(upIa1y75`?I=PC5o8oRGI1Am9!8DgiUv0Pmqj-|F7<^L>#d)D)KzEJ0{F6_l=q z-|c4{&?L2fdyB_kzd97D9JWJb-T?Wj9=sAgb_hNo1p3ODMhcd5SgQHxWjDopM42l@Q4HH$jfvgO%_IDSNOMzLTG5KgYy5_8n<(~4&tAoqE2mEj%@+mq zto%D+Oy~govdc?t`eF+l-W9s@P_l-YQ(QG4q81Iv}3sjDAfyw5wj6duHpLW9dEh-|9jV3IA~~dVFBcmMM<+4e`Qt zb?;MUM!_Kz-568MP*l9}f}p}I58@mn%R}!Z+`L~346c`Tp*nk8Wrd&yy2(aQ%UNF0 zavIkw|J6Vz@hEo0FetI&FK^UO=GI&{J@f^Ae7+f7(WqVeqGS(zQ9N9;GN+D{ZFBtU z&e7QuqN7Q;0SXHs*Z$+0y2Fv)k;C@Io3X`FNO7T)>4|_0mRs5~tj)NvqUCn8HBA{~ zzD;G9syButcDU`%JI-6c`N}U&Z9&LWGA#?AjoRvrS#jTlm|9hmMsm&3w0CinqE@V)gG1(8vA`lnv&k%~!GF2BOK|$(oY4(8j z7j%RZeE5lvjQ-Cl-^C%u+}_X_&9bK#H<-{fF9d7+cVZhfU^DRV$I{S}KnZdUzN)vj zp2x*xU!Cz|ZFtSOL8o14uH4k&U+i4`G@Csq)b^n`yHVd@F#tv$=fr6vmvJQ4N6w!P zX?Vk*cBPSw%i#kpNbbXMFp8I^~x~BqsJ`K&5`W&CW z_dWDBX}oG49Lw4|<~ixGBn8$M?(z{n$s$!e&o21G;~1>KE|-8Mn>>p}#LTNtO`fs^ zMVSw)L#_?EBpr9$=lbPQJs`w~e`tyM5j@pCo@(0$#T<87q}q48mwfOEgYh7<8GUSq`(=t|N|vu+ayT%DPz}SR z8+cxx#Yzp+1DrWmQy%-j#bVnNx4W{H5RTw$7=MPl>3VS`mM7>mRyDQvxV)l=@EBf2 z)^cg~`>kxYL=6K2lmY8qM$(fX|08%S_ zBo3xnPLeu~=-UP^is((e@&2f7ZH@z)%%p*d;C;fOHNdKt0Bk&-N+ht4iX$+>HxZaqzg9>MYkztn zG8O~(SmD2qJs~=xRrX?aau=dXrYaSCF_xM@KpVe^llf`TwMw!zW#FMCRjr^{_Vgt# zy9djOvBu=V2^F*fu}5aIT0<3eO9Kj2Zpx;^A{;80_R$9 zK1s^I=2H77H2zrKNbP7)6Kqv20}<(|sa0L^WStLEbqK%VYyv#8R{p;6x77~(hgoz0 zqruLQ%=AJx+cIjS2}?`15Fpo6LrticabTlR=!#OWjQ1aahJHBC39&r)f%<|>DP8X9 zRrQ=8@yk#9_Wi z7?G2#Sprqx(IsES7HKdLOUYhY2dTej_LU2-tIGA9DCcC!jF|+H7G#k8+|>@Xe@S z=em?t#_|@h0858jAsN=4hK<*(ykktXJjqO=JZ5mS#2sG|{W&4Eq#^O)fFGA5;Sa1T zm;bqs3^7d37?kq`AJ=Nir4{L+0BB-Es1Q~ME_w1=0E?zA-$v3Xzlf6`K_Qp1a}@Ms zlN-{=cKdfXuPdib*JTO;Od0oY*vJ+KNyKnr+6JEj@lk!4;Y(XbGFj?g^blFzYzeKD3f^ zyx-6C4Q9T(QzR@pI8sq)cyw-C_=a2k$VtOfxDXc=lRP|jw^O#KnXr351RehaPM;P91xeoA|Aw*_E9kNPus|$K!ufC%z)z6 z+Z7RduF{3ha0(c>ad!JKmo_l@_FYwT$Qfj6jpHLStO`_ATxbsBQUfD+u|x&*pH}>| zg0~&0XccXPw^*y)2zIn_M#G~ZQW0ia5akQ(S1VIpLzpA;dY!sxr@ zw7FN`vJ;HskYf~s3DKZ%eL5-wj4Nc!JFuuMB6|h2vPN}0c#rNCY{#UDOJK4}5@+zx zY1k2jg!2jPIPaj9093BzkhEbSu$)f?#L6wb<^a^PZ(fF0fq5Wqs-^^e7za_;g(ss_ z&Gif;5)k_H>Zy0lVC<&~!jxgrLbe};m)M{$PXu3X!JHoN!uU&74F7Vi#MZ|DChNP0 zny%*=Ns}*i7=`hSc)2$V(=a6L5^B`Uhc2>g#u?CtZhil(gFqT#=7&9VUo|sZxxBD* z(Hm>J9xcWQ4cxMPd0{VNtR1@d!w+CC*@l1-dH)|uK$TtDPOq0kqb+GaG{M~NKW z92qIg^J8Y0lTH<(54PV1aRFGEssQl#``;`}!Rg%$%1%o;Cpja@BCVs#;-6& z)x?3lg~qE*t|Ge|&_S1YGw&XYNs^4%g*1iZAI&}R`zkuUcZ4Olg4CxPHkJk$Tq@D3 zios!m2yqr2Z`RQb(1z?khuaGogStf1d!=#yqnYP3Gi}0J^N!3L9J9SfNKWBH22g?p)gA*C}lv?D6i~YHEN`70PD@&-v?Q3Dn|>p0gHg2igKT z9uq1n?Tx!-&D7qL7^X-1xML~tFkH)2n`4LM6ko$&e_*N@hIcw^MB7;56?Ni^k(@Jq z0!Jb}VM(s4EH&LM6ASUg>Wu#_0=u6l1Cdt)tNjFawZcUpnI2%AK>ukc=y&=H(;fOf z-`B6!Rwa`j#kMJ*ts9#DLavAMy!d1~<$2^O4K-VTA{CMCr9GU@C*Qra@@-Bp*PKS` zlMA$*A)!YJ<{O9N60tTAlar`f(VL0lnh$ow!)m8G&qc8=|Cx<{!k>BfjXDS^io`55 zWu#YRah5XYvT+A+o;40jrmQvb6zP+abuyAO{3s;DE(=L*TBicvmuT2FDSwhmgmExb zqFnSA&Wo;s;~ni<5G9sFbS`FQ&Vz%lzG)G`OKQIu=$s=lvR}Zp{xC<2@@q@x1nycK zLN(xf0FF6(xlGN^pn*3dzIPEYf9(gSU7IMTC>2bW?yCq2GqTji3R|LC%=v1?vh6xN zM?bu{UA#G%T6w2Bk?c!vzHF1H42GtbvqCjkj0vxsY8wUx?XwC2O;~ZiukZ)#$%q%t@W%{~ZZwJUX$}8)8XU5n;v6H@Y^q(7WQ>|OmVuxfq82on|(m2!=!TuYOQ z-Q(k9EL2lWF4a}`*WtJ-QWJD)d+F8B;A>A){}q=tEB`x zMe>CrAGmYbNd4d@@vw1>E6maw&yGmpNAA+h~DjHQ+hMc zZrrF@Nh7On`aW)#fcG;&xdahO6f7-!ls*ju9KQ>ezg4GvgamJ(*t{K~Fa#uv(uHfN-$2XD=msCROz_fVD%oe&u$Jc^Weq&%9}TDF^ha3(_0fDUdqM%WzS zB?`FTq)y?jB1%;@Bt-?G!P}@)qR)(VX{)=8+7X%Mi6+Vf$+cu?5}_~ux9;ZGgUcI zGjoN0QZRfzU*$|hF~jU7=u9tjx0DU~j*}GBf9wB5WGdf3rPvh-n#eu-$3Hn~aIL%T zkiEY9@>VfFi7$EqpZiVxkyLzY0dQ^_=LCu{nn`iHCi_{%VH=-EgkrO)-Wuy{>(D}2 zbG{PiC4HQ=^Bz#;ZIwJnR=J`SMph73zHZ#Hhe^7+qlpkRHy%Lz1DCpFb9AtXws(wi z>-ZRj`Kgj#&C3s3O?-dpKej1J_WyH87Qd2>?!8dD6FB5o)QL<_L3ueK3tm z=~){BQr-<{y_h3#tAm6MP0&LK%7)WVTq_MEvp%NmIT<%slNR#@+f6NG{Bs<;^qbuV zH@M9{ZeOgW{Sv5qPXzbS>LFKcjMd^;$;drFB|$X{ zBGmO)!naKWoi&S5ln5|MRq85aM%j}hS!14Gkj|Y>R`Ich1)W@#_r?C|<*`a(vxG>y zWmj>F^{)HxqA*0c^Pt8qYDNbouq%;33#%>@)pMWUKC89apB*tIWE`{ z(ANYN*%LMMCld-H%Fv?g9}_=F_tDR16EAp!L~<0rcXn#CHi_7bVJ(}9oPghsiVhwR zez_H_N(~AatUtIq`js~WvaW;~DFer=a7K&Qt+xr_tGua!Yg43)vAsaeykXn5zqSeJ z=hamg{tk|CPn)ri&^7kyj~A!<+^aYM-C29qc;bU?;r2Em%a&zW2vS>mRMs<{#HHyJ zrHn*CkL<}pGRzLTL}fAAJ2Mj{B={;$1j-_h=SFcuro0QmG!q2Mt@B@v?ly@%I;Mk# z^rxztJ1X|7gFoP7apL@Tq}by6jD|_EV!qOmc&NO&6Bf7$s5RACw&wxc+Mplva^VjN zYVbcHSUlMRi;ilcLNd-KNA)2nR(>3C#!3?8I4e8Wg6Dw9dS3>(_??&1X!z&b4g%0< zT}1C*NdTEHU^o$~ZH^ASK-P(?*#utebZ=?*8b-SW(_Nf?u~h33hp%n`3y#e?mi9I( zCTiJ1B}_2%RLi{NKd2ec^>LZQTQM=D^ahjyzCi5f*lx7BD3qt`U)6`7sAmn})vTzM zpXleTYaD>o+{49k@0|=c(9qI&LeLbJLy*|Q#&b`uEcH9QP$566w|G9rCv3T9wr8=o z0*qY;gn7kNZvO$P49{tGvK3&CMq1!)r0H@dI*1+#w#zFayXIen+ZUuEPEX1y^T{rq zh`pX!gm3qjgQIjJ1tqmSsSX9X$=Tg{X*UIa9|bAzKBwT#_?c^Hy=3N}RRK}5G5Me5 zZWHSB&8fSmi*5|#odOc)10gIeroIAU5V}GB!Fb3gcx)Y*RdC1QFTWx8Zz6Gr@U+pK zCNie2EqUXYV6PBz7ElOLYLQ;xyDF7%w^v=GHpbER=4=%e8zU*o;pZsqw=LZ;fFKYe=(n`vt(5m{1q>kqvH7R_gdJf`oB!IYe7_gyDv=PqyeR_tf{p; z`~0KQ-)I&&=(n&-Or{AC*>nz|MNCTlb}hF53o$^>zkS;{-(1fHeLw@SK;Yelko)}GiOkIcFHu2_J@|jN_nqcRhasb9KOFtEQ;xurkvZlA~@lV zp=r?drt>TC{rB9&KIyF7Oorb1hni)%_|00m1P*;u)Lg+8>qsxpp*e+eR~#OISRLU> zmMScXlZUVQ-Z^(_+4Tg?)~@N4p7?GjKfkfnsn4>ND9Ca08xa^bw-FG-xBE#L=Lmly z=r55(Dd%jkCz%8Lms^$m2mYKoKG!i+>na@R6!`MACjKCAs24Wmd}(e|fQnC;0L6wF z)*jMq6=_%#&llBLe4waSwh+w66vFLU=7ee_*;S8Ild{uF5J)m1K`_~hqI{F#$gm+% z#xg{o5Rxh%=>&MBASX0nl%pLVPwwgGEWq@2bVV)WGcpr3%Rwa5mSozcph@gM^967o z3K?OA59-XrPobGNi-5(_))W6GZwJo~YkN`WIeeQSH<2ND{^D6nPm}iDTozyZxQ3jM z<;SLi+O>#B6_xqeT}ruoLNmEzx<*AGCjeB*`b+U{?2{7-f%7`e*axqJq=Im-)^ZB2 zTcRr{5s(BUM%Kkt)D=VyGtFmgfhBdNW7!L|>Y}A2E2nFa;VA21;o})OK9d z7H&4Hx4W{RfXGbI&eK6V$Hv?~94&W;@oa>8XhiKX3Q1ODYZMN<1R5(ty zsJFYUEU*l7*>Z;ch)b*oy_%aKEtx9cmk*!wD7p9ac zu61EyUN|4B&@(L%Py3`YhxqN;-lDJ=IZoS$d5rG*tC(crc!FvKo4tEtp5knBt(RdP zkAs*kJ%`!K24<)75E)w)w*p>4;n>A04uKIs74tl~eES7YoymRh2?d_B=EWB8oxHrB z!%0Oq=Cbw|n@44$Y??|S3qoa0cQ88b=rncg1S{hrR7BxS{&=;6{geu0pOXA{9OT>{ zU23AF&3K4J+rlH&Jq&Mw>2o*(*mVJYT_a~!FLow(r_@Q>FK6K#8Am3+S1o}}0EJdw zJ87}wnC#<{HeLkNU=YcNDI{E4NuUm^e&!JFL&9B{p5x%uw3ex5y8O`{5o*g)kO^a$ zHQChZeJNh;*(}d_TYqZyld5|yGbrTCS%@nT=h&mJwTUnSw&k18vC7KCfj?oT@O`~R zl^cu9OW+M_3f(Q@d7@h1?T*ter8t5wOB9b4-gXRi<6_ z%(T)7Tx!$P)d3yHo3kV)db$7ZM6d-=koAB|Mo$hsbH4e~i}&&{(mT(x!Ky4N3E6Fb8lt$vRwWaCcg_AEM%VtFPd);^cLr;@1ewn;4YjH)#2B>E}|=+V|_8r|<@l`cXVYe0<6=hv4jYqzEuz%Q`oVNO< zjyr>05OTWFv1LbKH+IA+nkBI!)B_Ix>L7y{-V(4E9-{(3Z4d|307BfR(5nz4rV!sz z(a0A&^1~W!kFohdgVdz zLhBN!mZ2Gr+O3pNJWd4YFdXz{Kc(^H8jcBoCUR8LWgV#Qa}{4L4t5iHSTDO4mZYbq zm4;aBIu@&u4GFXca~vd@#Z}8=mtm?or-(!b0hH(7A-BxW`A$i5548| zF3L_SEF`pVJ$`$nj~V^-;wyg_90|P-L}*WiJ$-}0gnaN-bUyIOCi})&u>+e$eiK0v zNBa5$wjkj8KxYJqb@KIBAS^)*MqeDSR)Y1E3}Eyy-AvftMoo= z1&rPr>$C;unK-Rq%+<*U2$d}i6_3Vr;5b3hbI;O|&4Y%7^hPy}U~hK|K9F*bylmI2 z3%#dZ+PryEQa+aLbi@P~{H&iR*|Ms9jXMKxoY4`Q^SXNz#JJ#3X|FJw__yK4;m$Q5 z=JE#oc5WH}>jvj~G6cZ-RX2oORRE8=oWz(k6jNyvTeD=tm=<-6h~b5$^PKWgby`vY>~G$fyRZsAKs zLFTxE*iqg?nnkxko1I;?328d4*T%W>of_Qsed;zmHi@x~hc!dhTkodcT*>br>>-Xf zKQk=zCw%ad5_g&(>!`Eb{Y@#G2Geczm+aEvhDN5o#lUwHMARA<~5F{c)Vb&-(Cse==Zii)%^Bj6r31i)}uEUrGDMj zoqCvCeI>}`C55;fStlHvtSU>dDcW79%7Vm&^ZK&x=?^}A%m1hpJZ8Ck1I{N)X~hWE z=`{;n{p6p{@$(2RpqE+PWz)TR2fc)3SLRq01LNwS@jF?XxpjgEJAdzDO}kB%ugQKW zlq`*bT>WWCUiioZfC0t#F2+Q{TQK}~^7ssE!OP7!Y=jmDfPAA}BOasy+&k~wQNtn1 znF|OjS!aAOz6qN!@Dwx{1b?U4Jn1jgcnJ zK;e>hO9azmyuzh-j5cnntEnklXTo%f4)$^5E+;K22uT!NVj3)P{b+9n`n>rYl1c`H zV>e}wQ5g^I5bPT-pqTD_u>mRA{Bnw?U(VLph1`RyM9Dnk9#SHDVNw3RBa)7AJKCuN ziaKIu0ZA}n`(e>4HVB=Z!$7F`SvYd>a?(#AKMWL!NJofh6}U|bi=)7Vcn=va)A=dP z3nJOL{{L+``&@0vAB~$`N@_-lGlVlV{l=#j%3*{Y8LOIP?4QBzHG~pQLXj#RUZH+D zI^b^J&kD$UkldWgHEqTnz=$2qfjW2m`BP-~m;|xK12@P5=6kA{I4bZqHz*HKxs@_E z>lShx**Ayyr8}Q~lKNEMB9nXVoV$VaC<#tH;?5a$+w1K_Z0$V6`zqjv)JL2Z*1z+W zTzHTVtH_)FCLi8_8Ib>TKt*TIG+P#I9C=KHyKZ>oHsM+r%U&E zuXFz?6<{eOImf&jVd=Yz-h#?u@|A5EBk_;dR7f z)E;}nI4`U=Ub3A+akre1^9^X}MpMjY?YQ!JLlbz|~K1o2{yaZZU zU)`AJ`pYybH_(W>COgavWM}(FYturZnkx0%Qqh{>Gok+<(&tv>Qi4}*`A^dLp**Pd znWxXrcSMUwPILNlE^f~&1tk<|8TQ9uO^tjomv20+c14wrOh{ME$(@_S{@p6P{HZYh z21>^}OmLqbXPURPlZ0ZoMy{}CcFqUU$?6TQaq+~nI01D)^~zZbGk$G)A)-rktDX)Q zGR6-gi_psp9DHdi(g_&hd=GXss0$z^A6b4OW3))6X1;0KY1P7WkCNT{L#9c2L;GiQ zI=Lgt7B%DlmVXV(xKDb2knMoYQ6Sxo;ouHfV0XWA~@l91ov zh%Ahwjn*rVcdTP+VQlB!ap!J!;R8=!f%(UN<}iP0sm&WPPNU@w?JX%4Ti!>C3A#ZEp zuUxY0c=;OS=!Fw4zDJitkDILf z8amIk)J-B-b^rfB(37*+#3rRq{5H86zGc(?j%jbmrktL-bM<+*t4AB@1eJh9_<;4@ zMIX7=oJP#WJO(Z;3|Niz4Pa~dryz;{V;@2q_qe++;7E`A%uWE|G#BE(H`jC5IfRK+ z*)*P=_p4ZRh;tJBtH9%$fDC(60h4L3S2O9TkMG6!&NzG#=U2aZhhVrwh6ANAF{mKq zBj^RKf18Qo8a{aj8jw9|3EdV(@B&9e?AZ2hdi-M&fY=`{_KL&Q ze?{NJ@qFoIm23Z9PXt5&J3@t4C`ez@3QuKkmZXW?n&1p%NgJs7Vmrz~p7o72HpK1) z2fzdS9=n`u>3oirzx(|jOt}f)b&2%`%Gq+!JyjvBKjq{cTb2+v26=Ms%*q8-!0lTk zE-T&arSeS_ANgxs;p@}HtLkca!#0)1Q>B1J1AluyJ%k#wX(L-6E)F?E7QH|N0154u z#~n`vL_!<=5_!H5_`JUlvQTVKIZIfGFNl+2L{GC6I_6LeeK}M9TUjKgdKt4rMMtZ! z;R=sMDLtX7aJb%J&}nk(cQ!z-c@9r=ROg&qgL;dRn@nfYT_>jqgp|YJoTy;U(?R?A zw1BpE0Ie4X2})?9?DKL1%sYKLr6i#b;zTX|lI!OblD;pwASmXe(0 zv$*aaNGOOJ!HZ+x%VH~LgT|>|4sQ?a{Laot)G@Milxmk?ligKr|-_MsZ2=W}3@^>5C4xt0jp&aDP zHgJNyV(2-3ep{~;0 zei}BF1)lFcMPSqX6D8>L1QG~XXC?IeCgMAUTe-GTa;)Y>vEjr<&ycRwU9iVWrlmFF zvjO4pRz1&??Qa1UWxvc)s6V?|$V2quo%^Y3%}@`Zx>$t?KFDtZvc3Xr7=3Yr1Bcy; zv{^n32EO(E?6m^6g|DoCEonY&Ag$HlPz%Uz8ZBltSqJ2MH!FCBG^#%6l(b!ain}pB zPQ=*W#tRY^U-K}$c8^2O$YjR1|B|GY=a0_R#hoM^O2W}Le50K#vQndQUtoQX4H+(T zd?kjK(DL%Zr$(7xC`+UycE2c-QbmKqff>M2E~Vjaoo;vHAYbn&m!)F*eLS&KJi`T3 z{30WJN>8d69cf9k}EB`UyCO~xV?PIi8n-8&5MEy1#+q7#wCm4pW&@G*7f7D;e zW6Q7aK9TsJEHC8;RbY27xkKl1n0l61Rx}_$f)B9!!nY#Tk67oOs79*|^#!I5x#vVF zBNdC#_^9utSlf~M;(q&>OXEs&6NH&V6es!v><3vNYq!7m6BtH@w94qVR->P`V?lYFmZz-$NC3EO z`c!uP31}sM1i^ah?`kTu2YVVjZ}UgCRaBI>gYZTv5`r!%+NnRmI1p+h{A@Kk4TVU7 zqxacV3(~=b+eo#W=n$mY8K^x#I;x6fpr1ZvmOyP`{-F1n&hHK8UtNY@Pte103O6ez zaP$dib4lGD3uL$)$CmCLDaaEtuAKSi(nSHRIE(IpB7T%9fTRr87`bfS@ENg$L(?g_ z%NY<>&r8EZj=Ae5YBzR?6z*qNmdqQp*aR-RjwM}G(oT7$S&QFU5MGjY2q1Q{C@z`* zHl(IqPZ%P*YgjpXO^wI=`|$QZlVxW|bd1Rfm3uat0sj^h;SuwfR;)l;&V{q;}fkfC_~l_SP-Q#VOOtn_k(SYfmP3#-SHZ!fT1tSkLWL6B- z?hTc!1V^gp!mz?uzDm;hX5l^`R^|!jIV1G4@CkE?C{i2dpVpqZ8znT%(lVeJPckLo zi`1E;2^&%ek$ly<(K%*H8zy2;R)6U(UT1U5E(rdagpm9O5K1RepnJV5H{mQ-O*D}j zET7PY6}zhxjvpw&WIlIAy|LZn25eR^im6s9+4ZrD^_P%`+jeC{RS6dlq#yuDW>Ly2 zJ6JXl@a$NR)SF1rEK;ZX#LV8GF_H832BOzc@s}bkEh#GNE24SquM?r{#woQ8_ab&J z02Kl-%k^3bEm#pDMFXht4oQ@5E(^B>cLse-i;Sn?P++ zOgZ4nTX+E~@%{Q`q(etA`?gqf!%&=OIMpK$K|_(>5k8Wl9RJ;B{~iN#kC#t z>my=rEz~=HVbD|&U=EFYYTGPKvfH0)t22sMfne7#Dp71ZOMcX8RTC~Zu38Yg+$*Jj zVXPMkT4*MWkXCmH?JVkt>I{AWMIcu(nPE}B>VPDT(Q=ub*Ds4E3qmOtj{&1`sY8@{ zdnw~4CnKig=9jE~BWc(M__Sgb#oq^0P^QlEPzk{X)?|d?84O0dK zyfQ8>77kG5zOhj4e35Zt&LG_`C2HX_lOdou zqRKOYO)30>_drmp)%^xFnb3d};7{oTgUKt7MYL@60L+6yUN0Z>_x153GPab>CCMwf zGD?Nz!%ZXW*)vU4m1WN?St_z!_5cnOQewCL^7V) zeTZ?dixrHAz?>WE;Z>I1vF5A4ZIB1@O0Ht8HMUNOKv@(Vuh(?gVBch-7KoscQ%`n~ zZXh3-*vbN8mC6iN@wN;nqDs`yrhkBGb%0z6Mu=}A=nY$V?i znNCv)<7w3Z5E$w>D1NZ64#M)7Hkj!V`7XP)5wyOX?#>N&(6Q)lwG9!Bh-G_o)lCxd~YaM?`UcX_V=G59W8*3vU1JSGPrSah;jXX5^$2)=Fm$gO|jNhfR*o5TH~@Owr-_OQU@PvK3uPW8}sU zmIQm#*BQ2gn8%9y1zT;eI~)8-=KpKmE!W2|WcmT5hdUIh*`B{SZ&#s4yh}~^MuCt` z#6oHh#)OL$?en1EGwalw0h>Hea1oES5Vqud(Br*9d>AfkVhzT$)S0rJ1GjZwacC zKxaM8dMJv_?Z0~(4t8B04_xJM4c6sSMbMHpGuqH0(I~CYgxvdH7!DYXsFEwybcAF< zPi3Oj?dJJid5Z0vir=>fSTSOZ^|a7N3u#0O7>u&o2-=-YlYMWH$&bBTEA$;{+4aULI_}+ zp5*G?$*)7oCd?nIZ0Noa8W=Nam7GB?JXqQSbXO%5%S42Ok&_o0S-QXfy+x6#<@w~aWuKf@Y~rZm6}$vnt-an-dJOHH#1sK=g1Mg+ab3^BjC zDFgyB3qTFe?%;X~d>wJ{Z%ZnZ{YS`z2H=J1H2`_>(4fi|)q`Tp{^qbjnFj2#*PE(0 zQ9UiUEnlhtj3Q7JKw^H`(9ha~+daz&(}31r4$Mo@`QQ)!?cS)`_!;fR{EIdsP0+r5N-UG1=8pP0mf&eszQp+v(Iupn ztAg`X**HbTN2&whqleor2Ux|NBiZ&dX;%`bFq6z&+rcEr)vBT zKDAcqI8s{w;)Oac`12`6^~z}ZaMHQ;*$!IaU3V-o`wCu{DG?QwX5`WPBnO0ojHAbN z>W%7}^y;pkosMbWcM0vr5MF$MCiyF@70?7mN^#8R8nH_ABgT!rG6wTdY-r{&K5s0Y zR@nk7Es8~W;wf%Z=&>9%ZDv28} znw^q_7+1OkP}zN9Rl)Ub#{Sb~jALSF&=t7XJ8^cVc#ah|i5N7ciG``sL;{MY7;S-* znb>k230YSYE7zYs!V9zjZGJ_*yXMLQ`k`+gM;${NguzO=m>Dliy@gI-Bt+|sB%~_i z1ksqT{)L~dbZ)7+{`r}S>tozn(&`N z75=ZifPOsCDf4ZAzs`wki5}dE^3EK5vY0uF6a8Df9-RV)v3I`XzYO5BEU>bHC30aH z5ttkQs*+;pd5gwbPx2-el^ME%ftQO#+J6-xK{#Gr#0*fZZH6wLUsY`4a@%;(cauz! zSIE2Y`UxIo&H-4hNdFY%tjB!RZcVvui{VDxzZ<^51J0|j59!@7{e*reY|Sau7klHb z1Iy!Vsjd)!H7jhIh&2QWJc-8hkI1GBo$kYn_f-oTa>LrFsb52vtzoxKov1*43RdzymGhwW)V2sJHhjxzDc5ywh~445Fzb~?XnIU z1op-#3J3jIxn<;Td4Yxi**?h1kFWxu4UpMQxMO<6-uix|c!_Od_nCrY5@J{!h=l0nV#FFdTK3_P-%?H8<(PC(EF#QjiV$Xi$;?)L z4(x!76VXj(E-k}LL(Yt)`G+bR$}-R79g}r$wOwPR8W>vBAfZD(ZvIK}_yQZSD~@Q_*xoo?jd7RM78jU)Q4^ZD z{wO(7Oi0#ITVB}Fu**%RDtVddC{@7zq(*g0j6V(h!Qf__dCm29z?&cN z5w5Igqq}Jtr8*3Iy3XDiWBpEmsH7fT2h|ot;YW}K$b5U0tE%Zkd?KtWJ8{{q{Mmom zA!-zq89i2qb8Yrh!Pp}iTAVx{&NVC|?%0S@nr88xaT_37zQ zxEWB|JIh26d}`K*E38xZd}30Y~w z+JP`P#=p&9Fy>?eh^*9xGts+)tjn$6F@!#h?E!zn6<1$cco=DUB+R$4-N~;f{W^Jp zJoT%TKL}CS#=2MF$Ch(q2lz0gMftkEAe@7R-`d_+e^a9{WwUV)4pi3;2GqwK7hrJJ zkRxrQBAScE$e=lbURH~U6c^g&nHHXGphF?OJ3DzmskZ9>&aEAV!ulJozIAF1LC%1v zKh*pbhGaTs)n6YYXs* zZN(61%~L(BL;{nBrb_y>X%HLLBDiF3r^Fo{5Tq1bHOx)kc|&9q<#X2wQ)NKW&uTW_ zbVLqZdS+x&5Pe4H%<)L+e23@b6CF*Axl}+4Wia@Xiw++KDZv-0?gU9G1o73cNG@I>>AJ6P~ zKOMqI;0n|_QDLw2rCs6&;gD<3V2@%Z<2Czuo4L+UP~^}qSwMUNDSl;>#*DE*HTzoK zt|HVZQ=6j-O*AUTAtgG4z>4B*1RE2Qw^Ahpz|y-oF)=(QNBKKYOQm~*QY>$kv#Rks zTIepb%Xus1lcLlyo0qv+P(E;AT0`a9BBU7CJ%TGysX)c1FKVF}YPfuucZ$k-(JrOH zhIPQ#-Fsc%5Wi-{>?HNBFGagVO3?^#RH`GIQ!!4}btV6CL9jpCoBfl?oZ0_lZrd6I z=#m86E(3h<#2vjC1<=9!q*r@Rye%8Q|N9gAg0YqiN3(rWWs}@T zpCW)37J!ociQnogB9xZgAKECwVmDnmw%^<$L2|U7Yov^j_egR8ws(j0ect2wx0o)d zp7)awa%p{EtL9mC3ZjO7)^bWYDH5G&h0q1Kwu4EP(qLS@+zXQb-@OTz@Hks%ceyd3 z-_>LDj4CDs)&TkR<{)+n_580_WS%@;U7Mqi*>!`FS$X4vqHD6V8`*(duOReTMqX`j z^1m=?q)TZKhsdAt4Eh+N1}5J3w!=(7OxLkwHU;u8z;-*5I0}w-)a2jkcmEx=hirk$ z^DCmBRy5PNJV|~D-HU?DRe(B$tb)a>;5HEgr}Ayl30pX+Sj&XyyL|m7*)juk<9Y9- z>f!+};9b_9m6wimgW*)zECQLs2@B_d3Ja!XUh^(r0G;T&j~`h|zMhzJaDp;N;Vx!u z!#HE&{sgTtvm>Uv#ys+9At*E%VlN^tor5KW8R4zyb{|)=-fM^kVxMk$mwUDU5d-KD z=Qg&Z(JlfwhR)B=RC-V@x9fZ@qW@x7$a94bz z=5O?0NIyLU9q`OV4UIAlgIj0*dG%IFW_$RaVlMO4Xq6%^E!;*(6VfPmh5{I=c#P+> zr}kqS+a|rS&p)s^*WPn|2nJ{(Xyxz2pRLxjWROhPzQLPH%(c?#6gTP$Ffwq7xJ}JN zWZ@}k(n$lA)daCPhmj#OxFgy}OV8p#%u!HmP}SX}iC~RP3{j;E}vffiYpkI0ZJ&Rl4eOM~7*030$3SAofbrlvS zD?P<9^ZO2pjNZ9o3v4P3&ejYEF*HS;;qviJjP-{QOcWCA!KE>EJBsMvDnEzPAffIS+CHM>ndhr zTw*DEo(|WpXe(W`6z`xuh;B|*+$rBuJpm#K14gR+?n^%7M^WVa5XxUH`>sbuRsxk{ zAYEYv)pY5VZq(ly6+udqceVk#M@^(JfZE{UFZ$m~VE28Imo~q$t^Ez)c>!h;bn5g^ zBrTX$R$Z)#l3ym@uhD&Rrud-|Nn4{C#92|iK$maBlwR&Vx0G?uj3WJ@mKl;sIse59 zg8QLB0dod2`3g$S_eVwGNTsM@Y|mE)@*j;K1v434@Ro$;wci3KY6zuY%5ezBKMzcY zpo_)TflN@4-lW*K(6eYwoexx=t$oBKDOmTBlA<>2B-fs-OIH=Evlulo#CcW;A>0rX z|NcLZUs;(;y6S>Lk;D zAge)|)B7n9sOv)a7FxzfwmBoIHg5%mxq1%lSY1# z#(a2h8ckW(82pcx=jeam-|2xQ-dMBH;!M<}d~AMp=0jUcYHcC^R)iU$?gZ1m476U> zwb?;>mz`;8Q~`AS0YejqDx$OZdhjW_DloyQi0iG`NdPxA0#|ZhCFaSj)#)b9CXXT+ zJ#H^Xn@zo>uFvJAUoJ?DvbtTylZpp~j&c?T;hD1%{jWYl+th#vv1gmZc6q=Mq^4#O zW02AtsX{NG`#@iN&3G6|!l;@JU6!ArPE(YlW*7>Ly}U}$Zl&`5XcK!WYq;2e)p7{W z%~*O1uwDB*v<1A88m#%g#{4Hit%r8zvjvCKikr2Zbg>eJ43FBKMxYZF#!SQ46@Xcb?HdM|r)OL}{Hm=4H3Wsi*xUZ2vP4?n zx#FfOB6MwO65!aM^U2c}E=>gJPYy96q7USvE<%Zga&M9?`4`r$qt*2>{S1sc( z(cnm2pRXUICr~0&ofHCVcEm(2P;f?~|6W=M^nQ2~1f`|L;Qu|v__V23?Se-+C^UBH zK|xND&C9DvP)Um19^An$w6TRiJ;r^CRB#3K{es)eM%On3e@LT{FK2}gZhf2!iJ+IG z1>*1Mm5G7fK2W;9J z5_x~~@SLG1{c=(h7Qg#O1NE$x!!Ej5B@P=ZU*N(bw$%OW5Sk(#dXUTl8R*|yy-Y9z?0 zlqXNZs4Proa|mMPTMUb!->bZ5wKRt7pg{{961aTFp%XtWJ|jyMt<>P#G!P!pIbYEvf!mso|L54Umia`N%=YmiG#3pvH~tBkCD zU|9PH0!~qp$Oc^^H+6nk9+NKvrM?Q~tPpIORuZfX0XpIs#en?ya3P04YjuKB(CswX zXCo>bt|S!+q`tq8`eMBiT_P2*e$~)+0sdSrWcHAjYqy+6oPT(_BTz(o{fz57VVbv> zt^MB?3?TuI@6G#=c|SL_Ew z&Az7@T1ZY-(y(5cTPmO0())et(Xs6l{Y`b!d*J7_5iyMzOUVS_4ZQoG)SQnNBI^-_ zOT!$;?hl2WfEM*HdxUjbyiU4geaf?&U!l0RyhOX z!^-%n&6cj2A8&~#M)1bQ@27rjYHeJ23qrHXeri@<_DojxOZ6qSaW_ASFg6Na8x}sz z!K##VY{M`u3m|IHG*L%Uyw#5?G>Y3(U^?>3Vldox}UogO}yE8L&l)YB_cTcnTH)IlTk7~RUbM)O}3G_mkMaz|M}8y!(7}i6YNwFbc*Z!>HBUvUkn(8 z8GRHxVN2EKdEl_^6n98ZuiQ5x79qe_CC)bB)g7F|Br z>iHrTJxp;sJ@X~gE%Nn69R_4?QzjbO;>!x?L$3I0FEE79-bzVY<=a`nJ_>PErtGO- zFmGT+HvW9yIsjG5VUuU7eZ5gXmtrVwDm(}~Zb9~tN#TyH&p?xQ{A{mNdIZNBkJ`C{ z&+jaDjLM~JFGn+USFR)IcR8#yr6%*c3YxEJ1AZaMkzxPJsfz#D?q@C!A!RXGFpQpW z)B-pBYRIYBJ5>L1sTHBHv5tU2%RD5vhgXR0D62&&=63iuGZgYPeb1yp_yKd_&W-_1 zO?2K)h~gzr6fE)UgE@qeitui^fGMEZVv$ zpWlkWo>=?P+{Zli7=Rb#^kQ`k7e9l_UDQ=*G4~>e(h?JBkNKWc{st|wln_lThB@_% zP0Z$9O>8sa`pynn=duV1iF`;74*4oIji~1}9fqHIWBMq7jN00dCJeoE&BCww%sBT{11x8E7?WrArn#Ak& z79zly=%e8e453^A+8ksrNEADca>uY-w9HHgUR3@&ojtkW*vuN!T87Yat(iZjd~lLd zf}K%>`f5i)p_6)U??q-dY_h_(BG!JRAwvc?q5B?G7OoRsZ>9ier%G&0J< z6%&-vqarWuLZIpk9K3|hEHHmP7|Z*YnAPQkc1i~O(NJmRZfl)&?OwSCk4n+rXG$Pa z^j43TemdiGM_>Pk{+zc8I_nv{{H*BwV9P^lv5$0JjrRk$h9ksw@!pW*RC1Nv^9MN-om^=R48Ku#VmsbDJ^zzdELLvWB-`?V zUV4;#?p;kZ6aaN-g0<`e(10=s&|2L+9oqlY+~O=)G2zGEg62;dt(_Vy(E|6=UGjb+ zCk6X79#fwkkR-9xPG5h-Ls5V+k4e$;&n4r3@Edyp*7ZIFs!Ed<~#vT=`IPVPmFPq;zFt9=2!MAe)cgNKJSQ)soGCxZ6p7GK=-G4Cu8Kc8@Wlg@$L$9aS~ z2g?`NDJj9kM0R7Me9Gan*%dIpnnFw|2#1&r;|)U64TQG zU$eEqdZzm5)ygjzYj0`45iG^i=C@f-7ly%KmL>^v#S4wEN7XxfX6)L~@jd-Z4;#%8 z=J3tM)VbJGFVM&?cC~z7=Tn*R#1MTYL^B=rFo`r}w*Cwm~!J&Atzw3Tg}r9Et0k4TY2b1L$B2*xt|k~jO^T;=2QNX?!O&E{bg$K{m?l| z@&u;2LBqtsY=DE*Cfmq{@qcsq#jA+qzp`$mCseB{=~FlU=vQ5o{9869yeDim0&R$v zfzA+x?Mn8aVPzEDw-F165eOmxTl|aOh!E!XQ9iHEAlP@Wu)&0L;8+bQZFh1z2-||6?^{ox9`m{&c<<3ptU{ zdp~7J#jDVhFvYY~DmJU^91*cN38kIb6pNnRs1Zw?K0akLb;Jfct4B;pX@I z%1Cn2o?l6;pBGf4*VAo!{gO<_P{(?D8LQxld~%OrmgUi8N^H}+rMTb`m%djY%7}5 zMF@nmDx_Yn3zUkpbNe_niuVS(#TUaWTzmG$KZtc2=sf|b>)-{6KUzv9wC_y`oz8Dj z_G*QYPqj6m!la=zXb5;^nNhdsg%jNZb>NwF(1a}v##R_6eAf|VaSc5DFp3QOCuGgI zyU#XX1*g>dp* zf4Ve112*)jOtQor*gp=8+yXPqkoYW~i8D+fj=NK5!_xy>lp<^;&zMH@H&INq(&S9n zeiGMhm~cbVw)1czgiXnFk{yO#ZUy2D2mSl`efmUzAx+2t6LsN}@?djFrT)N|#^rfM zd_XZ^l&ny*o^h>mD%koh4CkJ7RG1biA&hzR7b#iz)OHge7Yv*X`AGqj+O)|T1h;4v zv6rQTCoC;w8;LMK)MA|Ccv_}TFWY)9%RgRi1jYO4q3$Dnm2>~x)o4N>tG6}Y9=~lC z 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�B*6pIybR1JH>tfBU`GpKQUn$|xh?9_1=pPB7p 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 z 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

Jhv?1Ii^JG8TA~ZLa91yvM0Y!8 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⪚Qfg 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%0Dte2 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
    7rCRxG%e#IBJ#PZe!`{+i zX8?dSi{>M1r^c5gH3KIgZ%PZPZmlM&$}oy)riaOJ|6bSBLL6E<5N}ksNGNCrM7HZ( zq#77airey8iHNEECA|fD%j>x%o5?tnKhf}Rd?DeslO;w0nf=*Fz>m-?)vpK8yi%_2e^YI$5VQruf0!B?wRp9WJKa)5452Us!w8k@~5Vvy`iianvz z+0VBHAw?ZAc{Y@DOjdUOUP@GCeZR?dbaYbC8sO?a4r- zMHEr4Mo{n6jb{=iBhqPVc%GUrZ48G*LR_p4&j)4#XqozP2mmpimTj;|?_CY0I(+}v zBcijzs1z6D$-Uwi6>UY^qEOHv()8vg)+|~41&DMbfjg2MT%#@k36dQ^`ED!^w~~y{ z{wD^*Y0TFoJsReY)#*6m5>!mm=;6Vb(PwYwQZ&j(euCn&+w?XbW6Q9fVc9UjPTj)e z9b``&F+IdZ(KGT{W?|`Ym!=at{XC!jgoaO{srt(au>K2=tU$H8gR7wCV?%-O59kXm(U#m&Q}f=IG?2313)>7P*$Y_k36WD-07gct$MTM1UDg}&4lb2sCb<@)13Bqq64V~oiLMnt&4jH zSmcSh0;y_KjKLeq8Wb^e!DBcBVR00eW%JZ7j3c(~0u!M}li=_4U3IAZAKO{y8g5!u z3CJlkJOumRAY*wm;0@L7^wLJhtgM4z@|!>Y%x}W|Lkv1mQ{?>|?qiBdHCes^ZfX&c z*DH^}IKalf1>Wje)x~)LG)?VS5XXu`!M1v370yKRFb7rf8MaIZM;kHKqQ>KC0_(h#`?6O1j67Hfa$Nak;#agy8bC*AQ=|XL{N-w+ysDWDVdu1+bR!Plo1H_Sd!(5tW)s)gxzpMIfZDkfl z$Wz$ChLc#Z6BP#yN#s!An*vk}{kx)mP6oaTb~1U?0^8VUHhjU>aP1RGlsR&rzmC@qw z4Gr%7u*0uU7!jM2-NK!my5N0LUFT!a9MPFxoipMs=#nx)U%OhJpiTg&%l<#t%^?zd z+-ti?k8$GuF0eTk1ki~lgJ5T$|FyD>*`5uoWaw`VjSLad+6a(UR9RlkdBN=uVzUUc z5L?TZJr1WKjq>$xU%&$j(OC}PBXz1pMq0pyNnd}4S~&m50irC0(71P-lR3<{%i}4p z>zv>%vS?O63LLVc1swaX$9)uX>TEvGzlEIe7N(KvC3Y&s5~kODawARw$K@Xh+TOl$ zUxoQJO`=-1{5g|87u4!e0X-xzy~KR5Yw$BU=EMN-`wGej?Jt*~h;_>xa=DoK6~#8TGblp7142+18kqKmm3&E0E zf+rQt*xK;t&R0Y%ZoMFzn)i;^q~j@7jD&?sKZ?lP>6MDTyvh)&w<^)Yv( zx07g0|JS)t_b2@8?-3-{E|ei3gR(U<-`W=_MX1BaAPph$6|KO}(=2x}&=q0Y)7nz= zWT%1fLcAT1{(OIwj`m#`s+a$wG|8VSYf8hbeC!b}CxZ-31`V?uVnek5a7#eJ2UV<&tcNiEyPWa@ zmN~s%CPQl*KbTpp$Kp#un!+UdO%r_vwLoC85O*sS_`32-b{Q+l3Z~GINV>KsJbNbZ z0+HC(g;#&+DrAYz#tRw3qX~oc*u-uu?KQ5QB1JaIYP`$;XGXQch72=kS+|kecfdae zA0rQtt#iz7Q(^;uUaIjuZ?SwU-4yvnnLxt_%Y~l#P0@GJ$C{2H6*km%EBJ7NrQj^l z_)pj9PWC)vn0ma39-~`YbqB(BMkh~ghTT(O8I)iAllc+UISYt{SK{W!l;pp8$@o&h z`L8Jsp*TK=#Zt~eOc+>HSVont83f>exPEu_`_BB2KtoI<0&m+kgwoOaMG31Vt=|T5iZX`Guse`ZTvp(4jAr>=S}<*=77PqPqdPwP z11;*~k}=kKGf(YKmV{83$FmQ7+j2;Ac}%O1S+S;T2@SjGPy1R$CldPl@<8avC;#jj zi)>ljMl`T>(73{@^6+u2Xoefm#@i+IY8#_@2%N}vj#_Zbb#FXw9DkK$9E&JfY2!M1 z*Qtnd60=VkaLPRT-eWBnatQ_7>Xf8jfB8}WvWFs2&9++|SL$%|KQf1*^V*@j(gc|2 zbr|s`0YY2KbkwsYYsxB})Y7Z4jWpcpSvj*qj+9Vf%SjHZ!VgsVvtB;0S0Gt&Bg-cl zvso>>)WEahSVC@%=mTf52uZ|)bztc4|5#u#GxFZGQ>_ZslJXjw#AVEqam3X!TcBSM z`4k)TiyQkJB8Due^skq#J5l~Egr*16cSbcXW1mmU#D;Sl@g#kLyDZ7SWM6d?`Oz%z zQqNVWaz2RF(g}rflQ|Qa4zZjVi8SogWLPb}GosrJtvV;qy@?Co%Rw)TEh3PVnG-0C zZXi;;(BUmdyjHiq1GK4jQ^yK&ScbVr?~9O;Z#+;I|0+iwctYA>LPLmUD}-SG(F06j z)Osl9d_hxrKuIJ2?ps|s>Pwzl=&?-EuQd0ra3F)4%ITdmhA%aGPcJ+-P?T{yo=rEN`=ggH1Z#1kv zDarw*P!r<$wo&kRXo_n(r?-2OSZdQv$NX8Cvt@&DzfIxK(kWn{w(iEp=?cidp$s9T zc9PJnHfK)*i0|H;Cvt*uC`gsdx@Q?vE%{Sub;-hIA>Xq9ijupu)rWA!1q6E*QEOS9 zTpjscyH}xckmYrQxWnt0Bwjt(w7_eG1}0mJGO#-t%CCZXuwADT%pn#Gif-CRX{iNc+d%kT`Chw+Xtq;QV;=Pe+sd;90goCW7xwIs4W8=DuPBHw<5C z+>aSTw8)Uuuy#MENzl%v0RsPMTp-qrkJV)>92G{%w>-MkG$yNT_q6 zGBT3JxY`RrcC|9<1(_|v+0J9ODo=T@@ozN7A-KRA-2I@=k~xI`%VE#^M{| z-0!NBC-h}i+gh0n$rAiK^*>Wb1`S;~p4@*kR>Kav_te< zo7P;?Op=~4(xGO>eIEXR>|}GU;|ystuMZUWx|y8kvYe?(;;A6wC2jJnE`~EXVovD6 z3`gH;l;0XAQ0x-%RQ!z4iCs;05z@r19_C!Xsste^Suos~=I?FI^!+7w9MGg0X5}uN z@DzU_Z@Ics7srn6E{|5a(-Bd}06QTU?;8G*@$JvYGvQ;za!5W^3g>$`8aCrsH#?$R zN8B&%D+r0DT+%=L?rX{ZDe&lXH19ieVsTbzU*e-s7G6;Z0C`Q5fIM;+uqQQiFHItT zOm4ip-^;=JLKC_ztYZa3m+&NR=0ZsPbCI=M>L$s8(x9aB5@jfbNrf`;i(5hz%xDL< z()$B~-T`Pj8UFC`v#iNfx&CO|*g-(#a>Sb$%kzcq{ReV{@h}ASnMYZ<3iL1z5uV1a zUI(Cd&gKmz_!05QL6?5ve*9by%KWClrjTRgq2XN;X1ZXF=y}LPQwWf!*ZCVz0>>Pn zsGl)F@*&`^byPVU3#@^G=<*Y|7lGtO)7~YVB?G|o;^+Ofi3%S8Y8AmE)?n2gnCFF` zUX^L{!ukSvhvGWU3V2H)>_tcyjWs zcavlto5oPl*wVlJTo{q??i92Uv$X!fBHfw=vy6ASYN^Qt)iKBj7x}?vZ#A+%#)a!p zR7l?BwY}bU4UlN7A}Hn77uUy&K8!Y3a*J;uE_x*#2nqz>^}6Z^hPTyTb~KDdNHsrX zXwv_H91wjyr5F}>TPFc4i=Yo=Jn9|T+w8yHJRr(}WU3mYD z^txNkM^J{bpMe5)?w=R?QAAz2X-9ro+D_%y))`q?@jTbsWO>>X)lL3l2v(ZaHyQP- zzrqneK7aXF{@Zj%q}=iRm*Cg@8%mWZw-XTRKdZDYMoQDzl4N} zWQKq!3L{2);E7opQ0!Q0PBSUZzyRb2>0!xDm5`-YkA`|FdZ&rz>MN=vvfi_W*z}Bt zh!@gFd?W=4kX9uAF*p|`= zwx>m`mtdL=aP&77aA`gCZlElKci8j~43sX1_t%Yqr0?@xC2Ce3Ga;3z zMX+hLY4KYhFfpWYY*A5G_WCfG!%1^Sc(F=sn~bWoY1tAbq)oED!l#C=f!k5m@XhK8 z1y)9oIkt;d<8i{t!U{2!4%Ii5&lut zG%K%ZsAsr(t2}s77bE)^2#i2L{+p9}EpF`R&Q1B7jftOL}6hLz%e6@4S z1vG72${QIr6%^5i&Vm>7gKDo>J5Pi+0#K{y40X`Ho{nh*SS_ynfR`AotA;79>`()w zDWm&VhHyP$ar<0kG6VLkPs&-)vtFJiJg~K2EUuVDPnXZHuo;`%_n~)3A=!@8oKOQI zF&@^E#suh6bZCaqcfm*b<)kjcb!$BmG%4TMzM6DoOFk1lg!t8{@z4&r{BB=R}_rieTmGX z=}hD2MlH0R3lqs5_bDSqqya2u1(J@Nt$AW8kREl|Gr56xfup7G2r(kLOMpBTX<4@Y z6gfs?K)?)I);9k>5V9l{<0i!~I*jqfnAD&8&s6nGK+uNP#I`^pzv`+^!pMcG=x285rNZVxNTNXBDH8gn=5x*Z2!mI*b zd*V*~O#jTV$9(_eq5+dFb1p}0w&0^aPnqlAD1rJFI;uPVgGyUD^5rN}RNv#X9@C-o zkTtRCZY0Q|>0DJs7qO`=&Oz-Pmpl^`PGWF{{|par<;FKlF9C6P0Yra9o)M<@H0E6Q zlU&HtQf5IEjV)F2M8BVE6j3g;(}L>PM&$m{)vEmbp{`?JJD2;&k}z^EeSwYYgyaY5mcwxn4dy0P^j=A73jyNS z#Gd3r%#iYd`isIe^%V!jxlPWrQ`xweNo!CMS{{`-zdyS|iBh;uLqYy&=^1{^&n=xFo4~XfX+GNh`C5VSovoZ4kL_xq_)c;JUOvU&biElD zHbOPQZQOad>c%3?v>AC|0aNKv1$LlgZ*2EY6#0YWHfU5G5FmI@KP<|S)zC&62FJab zQr6PN0qiX{=~Z8ID-C9PcXYH(L`0P20lLIGm6!qMai+$jVey5Lmt97sVaZr@wE*u5 z-;$WEb`RfKj)L99@y|Ixr<(~L#sB-jxOi72Vh-Z+U7r7ADQnaSv%1t=8Pqp#KznT5 zvn=`(zMS^001$ViA;EwU+Z|pO*XV7VOQc z>Con(BAmY4h(rGfsJ4e|G@&}x=0P)Em z%oJkB_?I8o{y#iaKey1pW}5is8J8@y;WpbBxdW*iGS{o9-jd>SE^};aFq~K`Xh;1w z&~Gl0l+Y&~9S?0_9cm1LHDibIm3>E(2fNHQK38RD5d~a(HGmXMcnM9cEE3X5{aSRI zefl4mez*-d4hJ4-+i%7psX<8oLj49JBv8$^{|R!)F$LV9F>t2`IT-*$AILBS8Df6I zp^;OM9MhjW%f@jo+5&x#Gr%Zc7Rb6ip$b@ji5s9IL}^Hu+NF4zrGYfQSVzZ5!cbY4 zL5(rR2P&sAo6W!-3><-$eYI!6q!^P&uir(O_`)aQevd@;gLAe37!v?qaE4}1t(sRF z%t?xQbb-f_P$UhvW#EaSfSy5c&S?x0RBFY}t4EM9{@ySHH_`#SWHy=7-6My{=S6-) zf1igI)xAvT83YqNGk4jbv<%Qt{PlTz7X*~z{u^)ysxm+Hp#6xe2G*%B+Xnr`LWLn` zkqr9@xT8=Pv15*FKc$)HGT_trm^jw#$2P-|M0m;g{YM!2^M1N56ov9mD=1&w>dk25 zh+5!aSdim}%9tXYHXGD*R(T~B~;d@`E)a2W9D zNA$wA=!7kXYoY85{3RLTsuXmRf@(Wro!T{OAn&0|WY%jDe*qP5leMI`bB__Rf|G~; zHA)?uU486}#{@Kd&}F+nTX{~`;naJr5EtxrHs4&*yUqPM-CgzA^weEmpOzBW=SFsl zz!V4oOM!rAHQk8YQz5k}fgs_Z(fr}{-G96?6^`(@*dG&LU%p`n?2EsnEk6ZlG&~Nu z8{*8Lnio2J)Wal&u*_;CY&5}=A{_SKTt@{v@|eNlc{{9cF|u8*Xg|0A5d z&1R9BL|3Rih^=k;8v1y0i}vECIX>IX+R1_#XUl@=sDyY$|0@H6O$oItNNujB0u%xK z#tH%eUm3SFAN|;I_IBk9SQtVH8lqgiX%*x*dod{(*3vp{dOb|P?Ll6GO3S0`P6Aab z-{|7Hyrl6O)Zi=<9OAdFwC$|#6E%$B*gET5sK78={Q_s~ayKkQD$GVpD>nuADY%V? z5k}X$b!M1m!-VPr9M5ycZ$||IF*7)9^$*Pk#XsvNv>F#l;?@~VeD;;gi?a||&T8Y; z08?D4Lu7e@m0j$O!(RZW zm*3hE%WHE77|t;Txr2OzO4l#*gX%m9iQUqWLfnzY#@bsxkZ;o9KK-M3BV95{q-iYz z3TJ%QgMWb1mK)4hlYI6HjV9UnoIF{mQaY;5{b+18Dx ztlxVcb;BU7=fqj1Iv57yU)J*p8HFmFT~pU?F~fduTqwZQpG&09frAixH?7OVOAuUibpPv;!Lv0DtQ0i@}G zbs*aDwHQMuFH||MrwYQBhwdcOz{!?-wsp`Cgn%z?>=-FK6|qh>p2#JrP$f?nOo|kV zACt9!GefO>MUETC>;{+%nklPj5YaB>0=*1vOO!KcfZzLx!%c_j0ntg|y)z(@@6#%h zhy>)X6;H4}*h7{;+=`$14pzALL$+A1O#K!;txZ3Na(PIwhw_sOxyL1C$xoOqLsisR z9)(0`F@wTV!Wa0TG&x5PC3^Q7Ut%j5DhtE*ytV+z++%D-*~xWS-elN$s)M*%dtfGp z=Fk=P4t$T0P*pzpl01PVz_iy_Gwf6xUoe@9=vMO#s=ygOOwDOYSrP{pOxlkM0vF;Q z#w>oq8wV*daOVuFz_gQjxwmrq{0jJEFsiI?SLRnr(1&;l4Iwpz} zHg?r35uV_4GeKc@^kB@l`doq_L8h|C=u!GLHqD;HnJHXAgNS}AbRTGwN|@dgawEY7 zR?grcFd_7*%45Fbd8^+X%YFf@ib0%(9pzkYUs-YRi^GmtiXxZ@(Gp9l{6giNO;rNf zq}T5UH9kogU5US3kK#((U_wkhf6R>nH~;Jy5PO@x`v_M2TRn%+d+jg;?ZAykm3gC$ zcij>kOolvzjvJ$txF}G67I?k z%903on*4?A;4jM&r+UtMti?l$r=V4!e?>shL=loDVa&^Oz zN>lpbWXX6{ulytOZNt)!-LF$`#Ggu;Oh$MRGs!l|rT(T}eP%jy-@ne`I54qMMoX=A z$exF7Hji{kK{in90op8B@J{+IiRsh+wrIikU1TpbTxU9YfNw>9R&Y^l*IhUn6#r0D zyt72~%6HuvKFXs0L@xUypeM#Y*~a0}66Erfa#sXlqw=|VQ>Ih2EU^|Y2OxGSaGY=R zlPD2hSV_-ZWm^_gU+dYk7Y>)_i$b{mM
    Uz$is2PCAoRI_yp)oOblGTx3;?bI+{Q7r^;_tQ!N~z{2>SoczkV@f{4)|qe!G!t;Sqy<|?1K{x zRQP;Ckv}0x1Oykl+w)L`7jA(}PXj%F4&nS09_r_$3;A0;=yY&WX{YsQbcxSnvIl6z zO7bL})%GzL7|OK3<2H@>EBj~9mgeohb+8jIi^I+NI(H$Y&ztE^<1HZ}kY|wWB=YXw zz|q`Jk2B??{AuAMuw1C4Tdf@a0DBA^{MpEa!2qh7q>@Wy8AbHW=^&i{LE5je{69fr z0ipm|Zf#`f-LDk~IcVP-eO`p>1Rg*i1ssJ~-r+;8aNWmq$f~#H%NX_!&#qXxfHbOM ztxfipNx9t@br`^WxNMw-);~RSmP-6kwv6z*-N=6_&XSVGdW(-8BAGln%+QFtmRB+3!o zK=-?}Wc_QS)4%MZZ)st5wbIyY=p~(F-qj;n$%ryBe_avf}{+`#QP0toh)PJU3VuL>Lsoar=gRu}EA>!x#SYVUDEz}17Jwwqs#TA=9 znmXT|NG&2{cAS@-oJh=X_O7{$>)^N;lJ3iEBEVh?*ae9cEM4ZS%2OTE!c&rWmXk}@ zP<=L`_u?2~cud6rr08L2>>4_~oAMUs-+P`PRRt>PZ^OXZ!c-!PaUt2iPcU|5cX8X{ zts;)QAV>Sje_(e z&n?4xibtcbneI#PD+HzUAh=Y8fIdMJ^kA^D|%xCM}eTjX?4CI2N@CLBEz(47x^ z#^}+#BlDka`E_OxSGLZgnxexzE2)6WiVao9wFB|!ed!6kBuyH*ziH+EB#0rA9xUGv z4!@Zy>M@KHfm1mpa=*zABJCQ7JmQu_T$>p8Xk4MLz+=~^x66N(BzTEcmnz6L*9ZMm zc?8{_{a+|JA&tDbzLY1-2~w-4Sy$tsm@J59pbZ&{rfeC4^Q;VIuh0o5)MNKcKt4xC zmh!e~M9Yhd|2x>Lt(w$5VSB3Af5tJNxELdE^XNG%T%I1_(|J4gw^n>)+E`aUA*+J* zhj7jTfM<3RcX44`%)MM%!FF)D%a}f1~I8_7O6Gq&z7EF&QSF2DZh;>+S+TF zGqG5mdj_e(h4p5CvbFd*S5x6#pEML*$Hif684hk-;CfnWiRgz(%7Y9Z;dO4YJSCSj z^Uy@0co34GxKgXY`K;iWxes=dPgF0&i=EXB+GjNTEyR`3(`O_+Vk7kP!?4wshN-ab zb>@ct?a38brQ6mvEoKc$H$HRYzYJ!kMM#ddJXS1snnv(+U=j5fa!&1avb4%AqaH2g zU2c=~%+2UraRDVK>=SLhVoWvtu;?GeIO#XRJ0@Yy7t84ATWTX>{0}KtYztNe6zkGx!gcTm8eCj{{RlW7w+j^O|SV9<|cYM*f8H9**8mtuCi z58F4l3N=gb>~DH4<=hgyFfM7BG4cWAc78LpzYY4&abpoG>nVla4IL052@5T$#E$FX z;TyGgymHv&=>V&9|JLS7CA?%lTAKKZK*I!c@+kRkx*gY}NR{U8(byK0kGfd&v1@=< z<7H#TpVY>z*UA~jx7`uW4$C>(2yTTsWd`tZp_8t@t+pu0zIz=&3*$iy)dFz~_cc(* zw&%@PKhIe`x9dTe%zMj|iuTKsh9*`p2u9R`7~+La(OP>Y#_-aIj6^NYeNeNsU;&*h^$nJ1Txe9 zh=)*N_q{uFVQOZ?X7lDA^%&JS54_2ajENECcwlE5LiP?Q;n;P$ z`Q0NuL|l%+UR;Ed5~tNCH(FGQ+1#Q2%UDVD#w%F6Gx5G z$_xEq)<8&b6=ad^*TiR}PbW!_enoknp9_s4BU8dK&m2ieV)XI$&-+b!(mdE9y_<^J zLJyuqmiw1`-x;V8ZIgV2ck);Lbs^$>PPWVb?G3(za&JvmOqPUh?(QNpbOYh|Q1Ky= z+xkd)*z(Kdv5w^aw|`eA9=qUFe-T49$TG4piQYG)Z;xW2y%PI`hY@#r(@fjdD_&!w ztH+N!kByiTxkS%v@m~jlZl~BX>(b%yh!6Jb5QPiJ zebS>eDLGv8S^v{zv}?B{GA}IY;3%#Zs>|HZlR@NW)fxnjWeJY;upx3((7{QSGH{ql zxaN@y6+cv1rq+=~x6Fuf;7mLN*fj$JeVRopYG?Q79bArS4sxD2bP;@2u#_0uDf+!A z#6Z{_cQ#tu110M_pf*RmrQK_Jmm`rbeOXZsaiho)z4R2WBsCV@G$gZ``uh$g)u_<% zl2OrpQyN}4E?34TL8)>EiDpq6PeE&Xon2MOa<>+&B64^(^P~EQfZlkT!KZ!W!C9|w zL6i&;Gg}Tk5(XlAfu7Xi_AQ7(C%)amlu^iyOal zdF>L?-e96u3X?VUOQ@x7cV#Uw0?dGAWYjWWXljE6AVEVj@;xY!BwNaR!e`e2N#!t6 z`UeWN2DM@}Jxjope3$5Q<{QPm(sZ`V$^CXvv86^YZqyLv%K?Sia$j-2y^v=cst=1T0#r3^7_Y0}9E zPP0*=B$6SNA+c4nBY@f3KVi*Ja5R)+t1|j}zPiXu7i2H{EGKE3as|aRp(0qG zY%Vv!d4*-Bl{e+i0=nBHgqJ3s|EKfP8q=|j^xaFjq4`oZ+WfPqux5(WfxhmCs*Bui z@>oz~l*G`}!8gRrosvf*2F4}eFmx|Gp!o9Zn=8}xH)Huiakqow zf9U8tS=jxR$(?9sNsPx>Q~*-_dun%`KP0i0K)6&2X)G?qQR@-T^EmlEFH(thq`QMo z<;5tKuiX%vLe_g;Td+Fl!Jv49*YevVNsBefrGnnr`Om2a@c4FN7Ysh)IZZmN;fVQn) z5RNrm1`t2Wi;^T|$#i z_;ECI-kzCfDwH%=zY)eql=-vE7O(Cw2MWXqw zUO78_c``EYN-e31vfaNS)+Dd=OhyT?5cAbq5q&A0G#OPC|M^vpJl9E4$g#kxw(r4h zkmgB}h)F>Zm{l#r@#*pqhnE#_fTZh1i0=6s1(};Rd9aS*zWB2yi#pzG#8Ol>ixOML z#HPJa6sx09e$v>|ju2!;75e^%yEtcfTgIk4_O_VYwhTeFbzj}9f#t3|G8xt(nxA7W zKR)ySU?|Ba90FGmxs?2msB@Kjdy~mX)KTBzwUeL#h?PLNQMldhmx7)#E@b-zUyrh+ z6Du3%!W3>fQ7I>gO=e4@@3j-Z?-9Lzd3j+ED7#+84rhLsWGUoZkq7OU0jkhO6^vber;zmCi&hZ z0!e!N(Gc&3h&^HIY4|Y_+UL0VFU2p7%U`yDRaWM^km&ZO166a05Z;jNFo*ha z>3aeX&$e0xX>|I-!y&{3bk~$EkUDHf_o~@S;`2M#{Z?WcY1B1z4x&s@B3RN#tI!TL zH@h=hz3V|t7o5oNa~kO~GBkjbK5ncH*oL5IJAm+lvgfsIL!F$A{6|FRLY3JW za^e|xuUy~%eZM|8m=(AzeDszGMkPazNB%@~k+IBl?P5pLDyZ_p?a&5x2bYX%6|L%S zKu+z#0z*SkP0GS&XG0Iuv*O86?H3I~X>w1J0zG0?utXU?bP@yFE?J3*n+*&<+}+?5 z<`it3s{hEXS$@nwe6`V)ZdVkMWbzl|cnvc!Uc~b;(=cIeqpG5P9q*=h^%j#k6My<~ z;*TF_c-%wJSI-QJqfN4{P0fb1Yw?MMB^Vhl@RVp}D*Wk@CR^VxElmmo%f}hFvnR>6 z%-Y9P7`}dW6C)kOJo4wR>F|Ng=Fo{)iC+Sl$$mkYD5yM1?S#5v2Q3WLR{}thRyr;` zsy+VPLD-J6?A8ZJfs{+T{+s0*yicC*=k9z>w-LeLSS1%|9UQr=Lt2yaj z4l=$sAqaD{lNab3*@Y_&9SqfMb|~!RuVl9-OlXSv1S$m6gf~ zlA+YY-0Odput*R+txRR7=kzOtOhA2-ffza0O*>@lRtjqfN#apS zI3fu^?zp&1Jy9OzWfvg!
    E@Kw&1F#9K7%Ax2=z!!80nusqxwdgB+wfDnQc%kz;Y zGLi8Q{b<0wn@6aMRS|J-N8dO)+ziP^u-9%sE7Uw-I1PNl!ZE{T@n%*LwfGVJbQQ3L7wQJTb$?ikvxyl{OV_L*EXK zez_7x0K7k`hM3KtMIPPKHJ~L23#3ISkYbEXarLJ@m&Pr?rc5&Biy3oCT;s}a1~*u_ z3h1|khOs1BwhK}dd1$u2CV)9mYA_+_tss4GnhLYT0i+FQ_F9O_{WOUKf&(v*Dd#Zz zo>z%Ejvq;OWO`djns6-G3QjEN!P@U2LZYlsNrM*lNtR@-((_?>q#~2!%e-t4&XkWU z3tpy?fkD?k_(Hdndgxm77C0`?5*G9IVeldKc)s9Qdcyy!Y#syE@D&%dxRy5e{eB;I zRU?|n~$|{<* z0LU2LU^cY*2=^}L{p8l$AJU79)%ovg0DhpFl%S(}1xlJuHrb=4KPk_}WVIupZaJ~7 zVm~hj2>KIaPd*KsYKCkFmWg`ZfY4M{Vhi~oEkMp29BgUB{(%9!n?eV<;H$<7Qc+@E zN|&eI&pKP&ebat+k{s^k$Y12^3#~A&npf|V2TGA=$jsVc7s~_qmfW!U z*2o7H0YTHf6sxSMDrdmx%vZsJSNuR5!*FvDf}!Pj=8izRk59^i#rJB4xyR7qI!(7* zy^$a&w;J;cA3PQs6yVWVdrGEESU1(irm(8+CbdCcV~B0&)(;?% zKV`+f;|Oe*?DU0mIT;YVZKUiwKk2p%t|pih0tZ>j$S>?$^(|nTQeM7mj^SJyEv?UG zg6rIC4Q#6GXW@jZT_tI-cr7(a;rF{gI^LxaiW()@lX%#~ct{4Dw>YwEFMjc*aE-5` zM7aqtl6dAMB;FD#829rLk8?pO~@`?y)(H3GO;v4EQNBKSI4 zi~uYiab2ag6b>n_A4N*3NaGIg!j*EsmkpM>^V2elxm@Ay34}ALrYqf)#8lwD>chxB zq+mg;@si9MiuDBjB#$dQrmG(1cw8nWcR30M5ZU=w{BldUD_p(On7{o8aLYRUXueBg_DUgzVIS|p^ zltx2YT5n(y9R9>VC&#*R>z&&r^NH4)f?}AXp#(+4YXmDr!sRnJ+Lu$$DALEmh#h*K zA8uw%*9;T`i)mpT)7`?()*xpMa_7{@=Gd(3NWG_o z=Gpx>KVZ-s29Ar6_B72sJ(b;_k-=FqsK`vGD`4e47-|qa@rI|e3Q1=VS=UDi4~i8j zaOi|Og6+8aKeh}FUL-h6nXVDZ8y9?$oP_?J3j+ppfIQ#`5^eEQy~YkLYZfX1xY)H zzEwmL`>CK7yBkAA!A!w_627dnmggEsYlx6;i$A(($q>;iD_6Tuf4oTI{fr0L41qd@ zD%iqr?yL@4PqGD-nMk1E?E|Aq!OgZ|z?8>$rV|HeHfyYdp}sQ+-NKO^0ox5e)N zHy=6h{&GvMqst=v4<{nfHrjsmF5opMHEkw%4RQrF{|a;KR=XVddh8=HLn|l%(SkPe z^{WxOa?7@=_>Oc} zr|aeuuHmj~3k_SC*g8zmwp|pxC(D{w)FK@EWbi9*zzc^)365qfN$7Z0u04(r5r3s) z{+eaeKxnyPw#p$diz;;&aVuc1Vu>)j)mdH0SzdTiUurb!^){+;FHZ{EKq9U z2;0^nP(N8?9U#sE7pOib$rBP?SK1F@(!;zZ`VmgfQ~R1qHEajISnreqd3+~@;`J6N zN&vZP5FHfRF;ZtVitOaJ{~XX@oB1>b+3lpWc#p#x@FzhjKjr4J{-FVqB(o^?1B7!8 zQC6B7`%97Lp)RWM?$nH~x%F!JoVLkW2^3I(5bTA9Z?wHT{2_I=11Ha$G&2&7!6;F` ztdLEbW}S24lUCu@x4ZnHXgQd!p$db9a?1tIx3wA->cD(;lTJ=RN2MQ~WjemiL6#80 zSF$jEW)R|la+lqo(@WGU$>^DsD4MdJ_J3Zfvv&$UHq$kx2m+$RZ^ce#qOIC35W%j$ z#_T0N5fXt+>lOQ4W(u1HiOcyrVgGA)UA1w2ZvlETwIOMlE;UuM=4O=JIMA*bWM1CP z2-GTy*g4lgs94^gvn(!3^WBJOq+GR)xmW9&SmK-r_|35N1DE`KL_Z3y0ZpMV=6G9H z=^(>|F`xFr8}$~J<@7PU<=GH0eDRAo^pWnzE}`CcZPuhGzvcNRyhz+dubYq(Gn=`R z4>BD6%FOhzZA`=! zrZ$*c7G3yKc^17c$*+orClfPYUMT~8H!Q{>vr$Hhm;H6Oc}+Og7h`fX538Er%v`3Z zcIG@mkEYB!d5@66q-)B2DK#yLk}8LNmJxXPZ zDM_K^TJKvi!AsVDiJ);w^XW~nI<6VT%ST30<0kcyJGZT0>?X0%=qGXWcpBvbiv zn3n5~z1A1{n7P2eOVCR?o@HByf@Ffwkn829D2G0 zr>1SB>inmu*3Z&K&RgoLhQDuZu?&#_#Puk_{9?k_6 z4uw2`l%N9Xd)vemIZjx1S~VObTI;B~nAX-)iod*BD7rNfWDQb8-3YuZZoWMEp}MV_ z#PRNvaQNDespA?uLz=k;1g4hJnuv; zgl>a`QgBB9{rz2_CTzC!pnB0QlUh!Ph_`G{WEMdra8#G9ZrUwsHTO;*CeVI~B5k4v z{WDe!S8e=F8Hrp#obx5ASL)g4<9q8(rwE@n9bO&>;c$TV+5a4k-$MSFjJeZ&^XzWD zi%)i&aZOMH8u|{GNEJWFgia8ExvZ|&{DhG{J>U<|dg!QO4TW62^I7agHO=lxqM0Gr_!vL1*)<}Z^Re*wDC7&q2sEX{j+x&OYDJQnsd*)!f=l;$=Yln4ND+VyQ0wK zwp=}XAhn-Gp5PMRftN0T%pKI)XyUEf zyzdjIe1|lIgMTyka0CDDvvzO>i|=i}iI?{{hsxyN$0f?8G;+;bAe7OLE`J66`I~E2 zG@~>t8Mc~z1V&?kB>ntaMY~FwET$8Vdt*J|RMwVaAxYK#eO5tVZ6t7Z7u(;58Qvi= zT6z6dFQsv2@rf|1OV`Rs*rheZGs@%*JZ^&8O_OlG2pbAgC+_F@9M*YXGxigGrA?Rk z*9d2sD@~yp44=|HKx+lLhzjvx9r=1h5fkhKjBQNM&2z8>&z9Mnp>u1=qKV3^oWiGD zBvyo|qYnv!e;&vM%b;lY&Hqp)=E^2CEo&<|_|duU0pYC(t_5n<(I8m2pUW~ELT=!- z^Q4d)t&7r~p0))KWu-3MabM|aq%deT-}3qDV_tN8V|8;$u~Y)4^#b`o?f^?8y?xP3 zKeWNtAar330KT~Jt;W#dusLT31+DDs!+5W{v7VFGNmPg0kEk?gZz;3GkmyWo7Q~)H zoT_E}u8?PwA}N4#a_N-sRUnB_a9LP{&1B9jWuV&YD5B0S60OJYKA;LJ!$a*NhYlni zp=r@RZ81#$gu4mP`+TZfJBQHf(Y_Wxj(W4;PXZ9>3=b(26O`EGVJXVzQ`A$86~Z`i zyh)LhJ!$69*_fnUISA#C-64nq#f(ett^0?N@4#KIo*e5$7AjllxvTd=?J}or&vUVgKhRwK# z9QfNqZaQ@x0UXP{txMHc(?7vxJ){N`!0GPrh%%~m6OUl+zpcH|!Gz_4&+VZgwAdxaN$mt1Y_s;QDFOYdYq~dDkftORb(gttJ z7r0hSi=2e8qJrqBRqN3CQ6QifwW*)M;N+e=>;}(Oi2S~-*s@?Lg;Vp80?Krq4aMoI z;}76L&upA{qM|mNb7{$&`jaF>iIo8_UYJVBlsy+tdoY5jttQ!jYS?3E01yA zDpXA)KIJG6)cZvcrYb3E1oiKx18{ziZnP(LgkPX<%Kgyw5AZuZyMkmzc%~8|%9b`g zFZMZaJtdpjwQBSi2o)TTN}OzCma*91!MNBMFNP?ccE)&L+!wKb0-MwfuJis4&zMWo zos7y{Eba^|bNZ-NYj=1KK3vM)k9?FijyoL+>y9h`u2M6 zf;HPzTmMQ3Zq5qiJg4PLaO&3~4vj)P>eQZlI&hKi2UnIk_NH=^aleiSOn*j+4)rbd zNBg=tc>6?e>s=A4{5Zpntw+!PZ0F~jj5}Zt5^V@Qd?Rl&U5^~Jg>=D!bN(zu+F(Nx zwrF1mKUu;aOJ{PAf-lOfsYD!a@}Q!<);6El&&qLWy>h(_#f50k|E-k?vT&-*1y~m> zPed{1!1G+YI_lz(XOX*>uK8TTq)T!iT#7}jWL)WoN^B5-0RK{biRx#Akta{})`9AL zdfMeDJN1tZ?as$rXTfw)ebgqa6hJO^0)B?*C~gt?rr1FA`H%?p zVPU={l(>? z@bZ64rRB{UGWxfhXv-aMOkDP21piVR;N_5skKT-f-vujzgMy@0G>An|1@PS~SR6jC zy8mO_=d(1B39{!*P7w|3D+h7N0XQX-(ib~3Juah&kY z+`*Zzjd=MnS-rUf+E)*Zzw=TuN?Q!=wR!ZnnV}Nq1oF;fnTI4tvFZ)c_bEFa>M+MA zWozUJIs9$?J3oRGG(NW^T?T@!i>B{L0Lx5>-;`CXf~q9HCC z*mOnmRdMFcK4;L(Li70v?bA4NPPIGJIXEfXuGmkvU_w_?_Oev&@Ujlul1dFEV4LUe zvezRBFLv3c` zXx!xd8Q0+gE9g8g7eVeU;-k|4D!pRf7o+;iEk4UcO((f16UjW#5+ zV(RdWRD!*q$!Zb7_dmLnRt9W5r{ZD|>o|h}@GrZmIz98>kqV8SE|N=ccQ83mNPsrK zjYzB}aEpz31*@OC33QoC8eW%^dR(O!{T_t0Vz3%1-8C87c7Q+6F)K=T?JOdl>a)@A za}CO(b(YWZN571@XX_(n`;;sl0ZMUyq&A|r^gTAp*et`zcaw$z-*>0G;}mLouMr~V zeSaJ|<+Rv^)*ceiRvL0lnrE%~R+9kF5Im~MJ)VLqAXjyxI&DpPW#Z)w0Z8l`-`TjK zdkE_#Y-vRfEn?DFuG`RQ>H9{xT%n^?5;_POLYsfb^Vdm9OgKPmQ`PJehBs$G@=wu) z7Um-J&BpeXV!d%u=mYVh^FIMUsWli(;`;eO8;KFyEoX+-@&yCN$@<({WBS+W4o$0LiE-Gn6JL#nYX20>*_Dj}Z zg9nv}rUt=CX#JvN_45yZ?xPQ+={D@G15VZ@bau;3%`!51LS5^pdD{|~y(r-?)5*$q z0$}|G)OvGX!00+rT9hh@_oJ^VKp&C-9|c zdL{t@qpYD`%7aS9^WA^P7!M-*X^@P*7%aw`Xb1qHtt~*HA2DOQUD1j@V3!`lm|V6{ z0VAzDYDZWb+hy>gX5Fm1if`cnzX$=iCNv-`Z)r;BF4TkFwDG)}KVtB}L(7w;GtUAYzIwf>s zKN$i=k*E{LX_gP@)(wf`U9KVqAuYu~`R&!iiW<(vL4m?c_#zvY*-dLuT`m|xQg4vJ z>wjpFXDU^1B*NE8i9*oa@CqseIBRG+pem)Czb9Y7$7paUBUGt4f9KY4TJ~39J#lRI z_t~n_P`{6Y$$URL`%YEEoEercGLkBE{HD;op(>I}4pwyWO)s$tt=5AP>?w0Lo~nn> zHy7hr?++3v)A6v7N%~Z#sn!yOOy#ERxQ}{Lxrsk0ZpRyzN$2`Ny0-5P@v?|@S?mO- zSqP{Tn)JNwRp)_?c)POYDVgXe+e+XrQ@T)MlSus$2bT6IvJVu|=)K}9rbVIdf7|}o z9gJ0+jV$Z@DRb3q$?`=<@VGm>I4#oYS=X|pMy??L-zO)oqIviqgu%pZl4Dj=LkajG zB0~*yWS2dvs9dN>V>AaCcN&|#(W4LCq6}KSF>Ys64LJQXv4DuY__nB?hp*lKb>s&q zE$r<%K|heHP0~Kvg}n5?X?==zOS>R}&0Yk%e^kH8UA0>VeFw|)VnqNUtNhly+oRih z)@oI2pe!DzSLXclyBQI1fDCGV8nOs0XNhn@+M67k^3y-WF;@~TRxD*v?#NdP2bEd4 zqful-G!#GRm=srBEl3+LhKu;CYOmxE#)#HdoTttE0bR^3%NvyfFhqny+MbhI=Z$w* zM{`S#bal5+SY8n%EHtDnfvw3d=N_gnt=KZ0*V?nsigBz1nTJ>!4_g?N-zEkxJdCBS z&887@na~W;P&NlI`EaU(AG4brbx>n8ZPekzcpG1-ZFkZR!7=@tcQ<(uvjwC!P|E~| zT$+ovDl?kSGzNDoXRBbqw=c&@dl}wFWiOM)ACOiq|6g`BbB`nKX}CcO{S}O_DsSV; zX{wz3(FZT^sjN)c@w+)c^5wKzj*Ei*0Q}hTlRqF+nmo11Ha8TyVgL>?$gy!|$UX$C z{ePl`?@8fh_qb{<~rCUqE@O@CoUXw z5A?k!I*>o=WmRu1Hiq%z{n$WdTYoVauKO=$RPT=)pP@NhQ|rQj4nV}k%aq@#I5PIv6KH7bX@S$UFdajT>TWoEh`vP z!&JfC)wxVEYrib@n2G23o8Avkbb$|v~?!1G`h=3mm2&IT*|UXyjLVzkIM>0Zaf zxzG^-1`k?*;?in;E|7L>Ly)`5_tt8IUWy2sBio?_+Y}=Qjc0=rw0rrY`hoH5-~L2g zH=>31r2jh$tmWH9N2{skGF_U_{iUKar5Jj%j$${fiEY8)ZgUd25>iwVS#;$2Z}2c~ zh63ofN1!8pYLc-#%UXf#^6yYBN;{k?x;$Q^N}&FYO2p`Y9R`gU_0%7HH8{DBOa+hY z1IgX)q#C{EU?ml-uyOr&%7*kQ=;GG0u9YFnzFodSWzUYl9lV`=OtWc zPB`BwR}DlfT3n9o2lX7OotpvFK?hPFHfXnO#LO7$Nf`A{OoBKi2B&&q559)m#Br_8 z?aEcR8w6$?+1ty%ju0(I7L8V(wU^@2(7pQ>jdc3$h2{4Jr$JuIRXof!m1RR_`#r@Rr1eg8(@9H$;U zrqY!z0P@=+xrn#sK*yb;=?xVG?ZWu6c0{ukRai4);K(g?DSSPOnGLF z(dPPAG_>%W@M+_=-|9a$DG9<>?hUg%wHAXGy_vOSwGK>+;d_y#H?iy_qZNvW$&eJs z-&aty;riV0E4Q^&I@iI$-$e8<)5sp`d!j#L`4Brb*9@oSZusTM>Or=AzTyH|q2YvosWW%mqW` zJh8tXw|s4vV|akREM&NTMN`b8O_uU|LDG=7GSV2Wxa&Jgyh%e+MFPsDg|_C2X9PGx zk62FVSM)izvNO);`w_AN3>xTL;M;BLKolt-IoAoAvz8~HgCzjc$D<`9K|weybyCg+ zgt9B+D)J;VOCszoxTnY?Nf#f?dE)~NiWdb!$hw_D+Tx{UYACAD4^uC0(IRi+a(^$! z><`uLWjQKA=e9ldLa6g3_%rc_e!p2i^~y<2IX*{QVxeOGaFn<#hoAVev1i11Xm+%? zWhDL9Q<^n|F^9T6fwdTjp}isHRtg~$<)*qQy?_K3ycSBwgnB2>Nrjd>e^%cMZ)PLd!Jfr zE=C~2N8FyaC{50SL8$cwKpWmcM4k6zMESy)^LWjGzbvYoptDP{dip~y z8cAjExc;|8MM@p5U~JTrh3)l$0haieGVcb)4Gufhp4^A`PeUO7b!=YaHw(uti4 zsP2rJkl780U%jOZaAxA5*oU&|)J6+P5-T`Kn$b0-U$^y~-oUZ7dk6)ANurEj_q`S| zVLQj%JW$bB(W56>{m7ZGiVSeRd1bQX@D#oo07W!cqG2>R6)bYu&=>+Cb$9C)&B+yp zRDn_kjUsdHYmRfNxLDB6$rk=6)8+7hTtn>9tPYZ}p29tmYofm#Z>f@oCOv`ps8F|+ zXFN~Es`lWtrfcIi(sAE`LZcb=K$nf(fcgQL=!`T84F6Jj?HKBV+m;xw8d|S=Tc}9I z=N42m9!ISDJDL)Bk_(AKIZ8RK3!(fiZbixz*&W?(6wNd9S2p1x(6W(XX}H5klM8X+ z26k|O>jK?#N~Y@0167VHVo_ddk-{9p_f2iJCp?y#fmfE!gaGeW90ev^cL$tZCi|AE~zilhV`oyL+&;|9{LfznE zYJL##d=qgNhL)Qb^6wX90>9Sl=Pt)H@-9HQvdXQx2c^kC)x}bMnwB+3gc;m?1$he> z#h(q`2L^sIYS+rN1Bt$5dHK(cBeGN>WD}*rmVk?V4{8%D!MpfwTiVTE*>2;Rqx#Tf z<~uI9Wfng&sLgT`K&jAA7OnLy0jacilzVkMB=aV|ADw%-DJHW`;vLboM+7MW)NZ8< zPF#hW>e5`~^ezX)s18J~qB8^CqVw99TAxv7G7Pygr6)Zy^%XE?Tm5V8V{#;<_yacj zXj{qUS{atV>y_D3FprhfdL5TSSMmRd1DXKjr{yxd_VLWNB6qANEI|GU+4Y>&ovZ$c z`cORr-Z8pmPZZU|&(}>_o80S$clB9{cgs)DRGoxa|4H2RkiMo}FpKnCUjNDMsS)Y9 zx?mI-#f(D3dMpRYg@i3}qI2Sa;U%7D{0=&we^fvuyG39JL_=B|#cp2Bf?KI?N;fZc zJ{s=5e|)HT$7`dJtll~!@jN^_@?&Qkc0Yahquihw8vG1od6o>X7H`bZP2ow0u}b8*$X1k0=_e% z;fG0F@mwZC>(aA6(^&vnM&*6FiftonBF=(OwQQjM28dXzrFZh4QOZXn4HNb}HjVxp zMAxOhH$!W3Iw1K}04{3jBiuqq0joNY#X|*oX4(i^0aIlldxcVS_3=L;U(qnA)z2cJ z?%wabJRM~>=}Vc9OsYu%1a2K4wCAmYkoiclOK>nfwJpkB`~GE%#rw7iN;9cYS;}eX zi{966L4G>;Z)3>mDSnc6*X#hvX`w;VgFHuoMJGQQDhrmHYs7xTOFP|-Id$w1JiBG^@hAXasJ=FzSp8lUy zTT<{>I``;}FWfSKqWU^Hhn8@AzK638$3AVjApSBr@3qFyFZrSt6wl{QD)sClOx9}d zfQFenjd>Snc`m3vqe}OW@P_}aV3yatZUj!~PE#Tj+=Of|K+h|0y4N^Br;N5gaRO}J z_uGjF`h@*la`D>5>4jF3nZ{E{^$*ke5%lAzlh1tz}4lNlnF zq+EW&S)wqF(#xR04YV^RqK~AnmnMHKIbM;txmbF>PJy7>wGQGLoi&q60%`<%^!=jy{icbb9ira6o5wO- z1XPIJW-4@Q?>v=E1%PNcp=PDAd>_OT4*Z4ATL1$6)>$74!~C>4hF`j zuG6s6K=BL258UW{YQILaE571$gFKHi?4ckq28!K{1>D!^5_30!BihR2q~#uKQQ4IZ zB8vQW8VQ&9k53qjirY{z<;j!Vom5@YuJV>n9;kWDT8+Us8l%sW+${r-o#)%G4{o)V z#jV6cZ>@^P(wowMSZbH7##Vc2gb7_2Gp0TI*{0B{ZyJuvKRU-ffaBPQUB45x_EUb8 z`X`Lmwn^9D=>8H6k5K$n6pQDE)O~EhFeav>jK3*0>!{j_9CP4U5SFB9$s(dOi3wJ} z4T#oi-bl}3*0g0Rx_QcY*l?{<>c!}U(%=xg#Xua4Yc|jJopaX#|7Wxties|_aep8# z%D=w%@iDctO33-^Okp5VcI$Wnn=NMzwuMOqJhflLhztr;w8<%;-23rodPIuil<){YgWLV8k zl)?!b=E1(*Os$-X4u(yx-nrFD^=k2C8AEcy-^jSr#*C1uqItOXAegPLRy2dEg>A*z zp>f@}+8;zNCxwn6zlWBOScRz{1I71njA(@|0H`0jq2On=chON&u1nWN*xWTVyyn|; z7BW=UVpcq2ym$F>GQ{`f@7b(mO2>^W3} zJ7Zw}|4G#ZYYq}}2Yje`_e2jf>3X3yk)*U<-%o!F?Bbt#(mpq1>w7m~F9OtFJIrif zL8Ycoh;k%2(iY=-U*QD#ImF&^!hwS61#wbgAMBZG#+5zbT4}2QB_8A6Ix< zEov~cFMd&ooEDmyfU#tXPYICHVmfjZBX=dJOwkuY-+Wj{Dr%Ci9gaTr7CX*nijYt; z<`a_gVOu+%KKNGq|1X-Jp$;e}n--DQ$>XVNEDaVUHwVuFHjKS(F3_o>$e9d9;_Pn3 z=i7sJQUKYs%Y)~?h~R@>su+xmjXg_;+Ld`bYGmLGK2Da5xYD$qSJF7um5{UNPGAi# z>;YZ1z(A+t*4a<6yH?RTyO4j%eB|;EY3HSjmK*s&=cq zJ5HjDIKlvOccnUMt5kAZoz)GuM)s;lV3Hu6e9WEZ$7KO#jBEM>(#7HPOCU6*4#(695lIZdRm&x&`A#~uPu;58 z1cMaZHer8tk^j^}S=xcSV8ucUH1IdLxPz>E^3P%3R!rV2g0tKj7|>@G5)uEVg^sdI zJ!crbi-Sr<^eKa^zD;v94h*le*9U=vvW8=LVUYoC_2-D{*oXebY09f4Po0W*K?E`w z?IB_);ag1_)I1kgZTWQzsLj z;)J<5#umjWm|l1qU#lf?=R1*M)Q?MT>`?B>915PGZqL9vUbw3EeONkr=eSR2!=GTb z?)%?A_l}gh8hq< zn~RZQQxiPuzd=M+lc5nr=D zZ^%CG-GKRT1e~Y=XzU^pWjFkFQwEA3m9FPhnYc7R)i`&Jox^(rD-Ll95_H-%4jQ$r zRRYB%dSd7tTQ)pEt8~oHn54rs5s0?hW0e?>k1?yZAqd0OW;@ z=OP;$ImB*j?-F+o*vCQm+KT)x+zxmUW8Ljhxl=snE8#D{+G3ZxI|FI!7k)@!B?e)&P?(*5yV!6F@XAc|o4S z+eZUMbowL`YDaEnrlm}q$i1)IzJ~`WcaSqMNi~fONGy`pY{XP(O;BNbsqixNCdUgos*jS?E1NocpdWu74$2y{vkCng{P4R>+C zB0YI=N@%2&hS_ui* zzH^_exLI(Zu=0BP3Zo0dAfk4>?jMkxLEQH%W6(P2s20C`;XzEun>UGm0sI=?3Z2&HUkY%v4Kbn+0ntL4jyW z4+sA1bGn?e`dpO>%glORO{PS%@l6FupTK0|_*Y6n-Q5(~ustZ@Sw<9$74W$rz8wjU zV&TM@-uhTj1dKlv;s?o6a6eCA7&T^yR_^;R0J1(I!%}}$Ra_B~wIcPw z$HU{*fm(Vd$OyWzUR(r?>rvXCrYKkF075{$zYiiYLfm3fc{D)Ia*+UPw)7iWu($ny z(%zJO4y=62(0?lw8*zfLkd4G_uGDRYv2NX*j=j65f#J3O^RajaC4gD`o+Uy zWwEo~AabIcBIVW_@57+R;BQ%7 zSfO25sWc3RM7jXne`j%L68#XvGqg(!uL<{urnZ?Ny6F)+xACf@N7Ky!%5yR&9|!xQ zS%$k~B)1adYGlND1HwmG_F9<0gf4fI1Qwo!Rp$lxAumWh$s3rg$Jf@^8aRGBRJXyQTXdh9YM0s8##dCP2|NP5nJ5I9D)N90 zUfC;5Z;)6_yY!)9Lw?GY)hg-3)2>kqkpGB@6-wyFp`FPh>htR}UKmnR+oTLAs^^1h zl{0&$1|#LTB#_{jH)T>ks}u94JIi2;7w))|p>E>DA{h7~+A1tU_W7=aA{vuE&++i= zemoMj|1+ZVy{Mg|W3c`mt}zUWf;JApCqfKLjkNT}94XKwB`u;h-x9@3(gJ2wc5~Xq zWog*qyqe@!#ds<7fs3Pvz4(~EZS8yC|1dvPSz43uhGUorM~OXHfIxe|G46#&x-_{@ z`cBc*TYv@3+zXgoRdN6vk!#3BL$2T!{6&53JQ!p(e(m-e~1Q+av0$G%zNV=*idpPnN{g4sqUxCh;W&p4~=UXk9AC=oHUYTi4Z|!VD9~4igaH| z9f74R7Yr^)hpJm`GaE88k@{3P@+@O_9+LP(%o7RAvBta-UyY2tnEAKl31vm$4z7Hc z277%z9Z4eNP$f)E2m@{%V6os*kv!x;E9Mz-aoPOL=kd{2$8rQkE-QHyM^~~hYP3GP z8_mEntcA(x7{&D0`Gq0nGO-3#a{QwW2P=_!lcINi@YCej$=B}&u70}%6acOpY=opB z5#&?cHoF6a0GqMW%x5@IaE(!1y3~!_(7UWu{~I|?sxf$);33Te9AY`$%eNq~Xx2AI zT~Lx)OT0g8n$m+!ES@`}%FQwC3!_Fe=@gVGJZI7TQ!F=SGnSN2lic@@^K^71*U%6p zzR~_Y74ONgU~eeb6P9dwAz+YSFJYf_F9b;sQ-N7nrhv^ibV)~#xAGPy!B65c3g!^vF=ieA6ew85hj6`q)f=Y}#6 zEdoCYma>U9!?&!uzcOv@zmVG-27N zGZdO?8t=zsb}|6n@yezu4>EYuNz-o~%ID=9HE4{;K zValQ69@Zg>K&WqxKY$`VnY=6byD9mVnHBi$qH_}Xh2^R zB`ip2UlAj?t0IPr>X1n7yBcK%-DW1(%MC%&)ICz z|M!d+hOrJ_i%0G1T^d-wp6vCr3ybcC=NMLnWa4W_NIG|iKY0|noNMq;(}C7FS0b&{ zq|KPDEwaP_o!{^7s6s(e^Dilp6ej%c4PES8kY*`!ha&=94n9O|A#4x z!_5)?Hggs6_4PxVThG76hX}x0p9ERSl9-u0C0bm!1w@n59RzE3UpG>3!f1A-B*F-E z3%NnH!E}h! z5>N5@SBWqZ6=-kH6IFHCds0esrs71kzk_~*C+!RQey|O+Q7`$m)azxvD25R%$5X!q zc~_M`^gp}7hZ&ZtsRi++Fz#$5+0fGW1-c8ql6w%UYHnGjlc)Q3-#O*3K6K&clba?) zKt*TEetsozT;>HKokTv}!>-^dgts;v$El(^=z40go(9*hZ0Nm<{;h!|!=Bicz~N~lT~?852^5+>U#1$sqZoa1>X zWJWxhbJr`&`vJm)$&M?5!TGG1)LtTw^0iG#fy~(MG&nMcUoe`KB2SWnXBx6fQL6Vy zJ&-s!^?P@X`-1C37tTa);Wlj|SGHfsyB1L#`VA5Wsl+@~=K5CZeTYxXk8 zX~rswC*9XnF*r1Oo+@?XzKL6ugo#l4f1?3P zk`vU;8%bB+Ns}KUT8RV(Q^dw8Ob|~3f*C83};}GtM=# z(0;2-%l$Sp*dPWi0cmn{vcM+Z! zKdzS8-o%=mt&=;!OgGP-?%qZ66>r~!+Z@CN7Imu4G60(PUep%j=zPX%0k#G@DV@>U zf3xj?t)hz{BxstpR)VK{Bu18_c;8qcM>mPzHJpq)#{nTrhYvF5>6GJ#T=O{cq@Y=I zrKxj{>F^(lA)k^OEH_o`?qJ32(8?$FV))BBS5b#Azng>=8&cF&!w#r&y9UM@Lq{_0yKGRk&#X!8n*7iv^x#CCWxFNn#5zg!QZL8~oWI+8?I+pz-25umzYf%Bt`pOj*tqgD$%h~HDQwAC#X?>)Gu;$)id~$J_oCE%(l$^Ega`)0 z-~I23_&J2^FlTK=y+hz#7+6r4`eKy+wZ))3UpMoK=EHBd+0x>r1A zXu#@&a@&rbUfp8gNexSKPHVAqfOzaL+g_h|f;V2^)3#AO#*cg;4s^G!i`d<7*$~^X z4~6J;t|0J7-{r6ks#cWgZZ$w%?P$JF~9f3ILqUgDF>^D z4;@kkMD(5iFi|&r4;3YVK{(&rc>aC@SBcrhIOnU_&?87fKYgLE5xA)5Vjzy}FrJovc<-bWNSV1#TN{%v)kgdaJH=?tet5ncvEVyI%EDE7%t< z(48U?7W>+x;K&zwul)u8+q)zWm%&ozJLNlp>}DY#ctPN!ykO{E#?NY+ta;{f`9*=! zd*iqKpk4sxsiT<&YrRfJ3P>#!2uiC-i9ks*c-x&}*zdfNHK11-T}{#= z@qU5G^U!>JWx-ZBS=3n1#5PMkE-RK2^$~5}tkxb8y4j&EO z;$H)Q_WKcdp_NUt`?^#&y2;YnqfmZ4-0A|(Db~2uG3sJW5`&!WY;&ZwlIx?&A?gd1 zOsCh)yM5?*Yq3h4v7h8j`{Z7NqZ}c2n(ewkakZW1!+x(5r$s@rV@6T<$*Yik6C}Sn! ziAentjMG=&=x5f@0CM!Me!|5yfE$#D55jk4UaMKwDO8v@gKrZ*T|pOR^fw~s#PF|! ztg+$|s?3<7>d6W8&89ixc0SNlj-`XWHoj{UX+pn&lLjJ6y;|}8dbt_aL=%4T+H9H& zK*R%I3NYS-)mmwb9k~x+mK=j|`~_Qb1%(*n|E3UIxWuP|3^Rq!0QD z#qVu@P&9jvT~-;8uggp))Xf5EweS1dNd)l|$P&>p9JA^?ew@tTi=@A4d5Tpq%9{Pe z^Xr|!td=G19xObtJ-v-JlYu7anEnydjYgEfK*4DFdV|eCO@l5@gvEO3cx|Lk1s5){ zpCBY7s0XprV@wjg6(sTm*n<}tp^eTAvE0+!gOoO69%5%;?_4EtcXEAG0tfhz!vYm{ zjL?1F!ax}3y6MsSGEiIB^Z#IS?0#}ppoxzH2V|Xp=mIJ?0Arim%)mWq73LGQGivI) z?kZ;y66{z*WU>6JYUvWiY47`Y!L2-Pc8?kEiooYKzS%)Ftq^ZwfTcW|=UFu}IBC~l zG(i%Rao?SF^nMDGQTl@yXAE3{7yYw2%1XGfEikQJ=r$xQeejVx4y$;1d%T+JOt>9{ z_p%#dh%~UK+zCHT>C=_m*buoPE)Z-3UQU)M&mA-E*RQySow#azzfUhAUIR$Rc!fa5 z|2WgpV1&u*pVf{k)=oR%mODH8y_&TX-3@e9x0D?8)i$_R_9bE6WWHX?9sQB>My=0jS9*Z-?~0+$=u_O+OMz} zH?_${VrYx83?Asl?Mta^wx{&ooLX(Oc7h#%;js-HpaC8|x&%aM5E_Z^m@>#(;6hSv zGlSUqSGBNY+NuY~Oc=?Q2UVfA9O5Z?*HRFV80(o=gp+ zgcn{}XDqY;?jbz1lB4aAzVdiH_dwqIowt1z5|bC19sATA-J+jC%}$ZVHEx^hCh=tF zSbQEP%Ehl#G+8!_Rf2ee2l-fMd1`^Lk50H%>*$d*u*=KG+#r@~fj&D(<9=o{N z8!gSV$AeXw9n&oAq7p#u9SREidF#(4Ov5+A65vHrSvHMT(m)Y|#O5@v+L3ON6VDw9 zOWNa9FQfC!-_Py+HO7wX4aDI4&3j)qSW^&~{D`kVfW0j%n&CqscCZ#Nl6%lD&<|zx zyuiA7_Whc=R}Pe~$ehw7ag&lqdRTgGXe~(ft3Akn&8P?Kf2}28Vn;9RsNptDZIou&pI{-W_@R8n zKY`y%bml9&D3|?!`Plc7)#_h@4_xOb#QYZwMs_{ydmoS5*YMaoI&XCi7R%&nhsL(Y zKioxKynIi&)8TJ^pn}QCOV&Bus*lzXC6S^pq`=rW-a3@Iq7fj<`@+N=xKIiE%k$j? z6t#72>qso|!=4jbJ+!$fEpnCiN9{=Y4Lmh%cL|Qv@BPSlA59>p<=I+cRM>l|w2drj zZnwQ(!YuInt)Kf1(T8SWT|&3f#ML=HM>!H|HRF%zcC&F0ySuvXrNI>GPjpWVz#I`lb4`tnGBk4? z6qprH6>!|>XLHH?AgvuxMEQ2HX&PE6I7mwcL}GQnp_ufPrKU&+XeT#lcG%pNBV$Gi z6ny!WM^%M-M6j;l2mxw0og6j8F6|E9yTc^l2DoeS z-i%CsgRh2q`D=^aHEcxdL&^}FZ{Q^^d}llnJo^IBn1r{AHjF#9X3#YA6})Z#mjMp8N}h%s9{32L>E!08KUqi>&MIow2BGO{ zjf*VqS&ZOrhB^V$psI-}Kthda<9@-i8?3bw5XTEEHuD9fs-g4Qeaor`k&76vIvhsx zR8O3OG3v`3AeXi>m&Y0S5!q=_;@T;W{QjS{Lj@qIh1!ToD3DW4>X_ojQ%n_#NsAQF z1nV&B%xFC&y{mFId|>z}^G+?jPL2MS0g%R}^{RN2eNqOWeNdVhvD{M<=qSDA2O zVXN!7+OMt@HIYLBP|{RE2U^;4>PL6)IM91aryH)3|2IsA`W9Hbg*3XUx$s)L%D7l* zQ|BW%`c7SAp1LsAJUTP?!S=)P5AAXiFOUrKRD*aO zp+@+hu#^E+!P<|7lu+bdp7KevzC~=Pk9h92nH}^f?0DGs z7dGO6?k`GzH#M1^HV6|%MC_)ND@KdY+Xz{6_i*VoNqP`lGe12RTtK0%V`)BKJ}{&J zs4KKC%4>D=8~WSi3N%awtywT6a3FP0H{#xw$nWx1e^#;xgZotsENgk8nF!bOzJmw< z{gMtu*Dh|3H6~~r3{oj(oC4??23xA_EQ}xId0bvow)esgw_{nJmwFZ%R*Ru0`+@bo zd$vCh^gt?vee5$;m;j9nIq!jzYm zYsv4B)-;yI+8GC4mfeMaP11-{j9B|v7L3~hR?EMc;&;NZ-+jsr;oxhPFJ*;PF*WsO z)f<6>I;W_4m`Rd(d5;pC90Juj*n$$dz0ZnW`cCQKB-cJSSuZb)Bbs}PM{{Y~ffAgQ ziQ(DY6Ltn`d0+HJgpDcUDgbp0stY#2P=AVrwR9NCSLj1)MD+lQ`Is<%QVBg!DLCuFF*e)8)NIwA)53T$l-zH5v zgV|<8;k+9f``i80W+|wQfVCvGGg89Z&18I?Z=LH@=qr@={as!{#@t4UIh@*4QL$5u zJIE+uIJvV;z4PQm{ns5p0u46#?*TTlt(MZ$%k<`fHz|^=xC}w~G)`wcLPjUAtv_LA|f{F_hR841Bc=!hk9&iNTm&iaopz`_dqCKU& z0`EP_h#At+7(ol$oka~#RV<>5h*kr7R$|7p#b`yo)<2Mn^&bv#it@{~+j*2IvGUFJ z;jc8qjMy$4CHL7`xxtL_78&6u%Q`7r3(2tAJ1tkX+)+FYJUD|uml z;!H|17&+12z+@fYTDzI2o^uNM(Xf}k0v36xdx`4d8y@%ioV_=N9=9L#*xix}BY=nb zp!VNub$O9B!8XmBrmIDlDp*4E1FXDqBjg}=Gb}!;=c{%K6t1cr>3t{b6u7k>L=ivQ#a-7_OUnm0GQb(e$&XBsXJpWEJcuOCGxM=VN465{kKmp5CB!XhqQzIrm!PV_l=v_@9Fb zsL*Qho)B0eQYZHA!+TUfdtd%@A&11Vvd44bx&(;DCf^Ut{I#|lAoaKxc%4+oWZ~4C z*yR7I&ePl}EvF@-moR6H&9)I7yvXMHxO-OSyH0idX8QfnO8Wc}gz!m=SiT@aYTyE? z4k`IAIcEH#n^z?;Qz_+;Sk zIvg4T0<^U2*lsf0qUHR(0{d(ksMNz-{9?CpV42Kl^NBwVin)6+5H1 zK&Vp}IeSV=20asM@P~?5viPka#o{DU*A27@H+mIB%3@b1Nu#utqR!GY->o+w!+Sc3 z!%Jd}e}h(neo<1tjx}>IlDh*I-N8v8$Bu(2iQ;0r%!c;hUJzIyF6?$5j=UHKcNlws zR+gzq9biTe?K5w4&sq#WIX?YeW6!+^8&gQ-&0A$Bd-{8W|7?%-CsUp=@DmU)?^-+6 zgU3vv#o(&e=!;6UJ|U}0yc);utV^}hiDP^-0r;dO$GT(Lu_9y|9|{K}MrZt$4Z3xG zne`=^@g@eDcM3run7uns-uS>X*T4`d-vRR*f&oZSuPXM+T(|ygoGpII(tDL8q)R)iiK}K zkZJ?BKNOk=RZ4cgsaWHQZttkeFmNjM4Isi{Z9^%8K1JQ-vP35C$0_b_8a9_|fS=v7 z%eWv;UCz4c@90S5J^B`o5jxZV>xn#B2^ad&C=z9WU~9qj;YSb9hN=W(ho^`e=c=v= za`aP_WzF@W&^FKb#F+wl5qojUzDM#6Iadcq5jIsPP? z3tiEihgs%mkWxxyN~?rmHnI-es~vb97^2@=2#5TTM~pI_Q0z@tK?}nT*e!d#mI_yG zbaK+>Sb!0PMMaGs60g4w=kVTl@K z3Z$dsVfK&@Ytdryft$O%wj+vk+994Tq_Q@xQgb27xd~W~51;5|qOGjZE(Fa6hVH3Yr_b8iv zy^Y`7emsHnTE=l1@#9OXq0tv~d|V2EiE?L?=L@WhhN$zX&oONu!2AgNM&mVbpK{96 zt`U1Zl~M-#!kiC|wx0_1!MoetGYMzE+ggD}#({yxvbesx(G?oymA`%6nlQfCPXte8 zS{N24RFo9s3t86lEV$m7$H?xPn!z1Vowr;D6RHRuxsu{+V;2a~`55t#@>X&!8^>mS zwDYD8;%iN>KVqn4C53V=W!*X{;`%3ud=XSq{61H4fxE&Kv**d zF0MQ3j&`a^P_bTOC!XFrFbbfeng-C0>|x|%Ziw0$A{CG1h5sP9i6UMr3FC#1{`3^` zB>Zg;-_pcXHdlYcK;jAvsoPo_vy$)&I#TF)6Y2cvfA&BDej!~?1q1{YoB18dhF)Pt zmx*l`^Df$WL$c% z#Toua3y~0hW@+#EN-2(|Qa`KDu%nIe35KWBqEW#59Fi$#O&Xkr8ywPhO~$9H=yx&;yyMWpbAJc{-@I=@V8DUOw5 zvC}_Hv$vldl+@n@M$yguFqre!{&(`X_b9ayp-cnpLXP$%8_dD@WV8g16RKF1`fxHX zsH?B<Aw!^_)$jS@Lv$NREC^{Ige zF5k27Qcw>rN4FGK9MgBE3XRKh)J&q-DgLjo6}x~BO2zFF!>;mu`HA8cAOsf3U$EZ` z4E^l>{>Z!)DKg|lZAKyQ}WxKoIU0rZfF@zF7x%acB>rQ0G5MD`+1X9fH1C zE~%rtYis`;Mg!?@Ar-HwZo;(gMc93LxOv7Rn2*1C7aKUeaR~5LM;chUs+5JUk-_Qe z#m*$cFxBO?Rf!5MFTMnD4^OFIquY~^Z0a>w#fG6xpi^40NxF@N7g_olhEHEr>x!R9 zQ0(7rYpX|rxY2eYE}<#T7LCSB3)J&3y}PLMVD)tjK_p8<=?hd1|VZ@Qrnx$BG9*sTxedwN0fjQ zGy+A?Co$Nn{g%L1y8Y`Z~-M=~Zs)D{LJ#w|B36w@FpoFS?Q|fxxai-@D>sw)OC0ii}y1tr9IamuaW2O70jRCPX3 z5Z31L|7wV=Sx4*3j)zEo5Rihi8R-I|0y_h*@!o(zi1vM(q>W)Hmf%}_qY%7RnkD38 zi`~_8dR=NCX$0{6l1(Z(_JO2A)){ee3iWGM+CAb%DO8O!`NUvw(-^Y_72jG(`R`%| z{hpW7tm9A;q&$b)0Y3bKf@;3EYAuisI`(%hgLl6$fi>u}=}fVCe!7Poo*X5N&vi%_ zWFXSO^L&*cMnmeM=iB~7KO@OM7*J~O-AX&(l{;<$R;b%NPBe@fD&M3dSz(j1KiuZT z%bOV!M5CpFyt;bSN$H>-TgkRli#qkIzDw^F+R4sU)M*#nFBEXpk8pM8ejz98G^T3M zZB5J!dHJD%Xm6M@H$@eWDMGYfXYGUE@*ERGyexXgWBmATkE7y^%N(`mv?J|Rv&&9U zWgQ(<-&q9oY1!Z@vrLxt5%08TBBsmjW5lzSv?dxAeH@lT=_1(FM(pZX!K%JGk(l3!}3-)|RSOMD|dggQ_=HXXxOp{_xNm8Lo zd!Z{J3m_Ads-=kv$SpBk>^Rg3M<26&;Y(Q)dar4z1`kq4g2wnNGR&$&Fu#`a>&p!j z`!n%s4r{64!&$5bkVw*}XB|qSsSEu@GQZx>ZY=wPPoMq%qW)-w^Ssg592GCA(;uw^ zZG671Jjx(a$ZCE9xcXbHQ~UYOaBWfDZ@!qVxX6VUO+FHGt-V(qC6#sc?ZqvqN1ptB zV0@BeTn??+E5v%F(qr;tW5M8`&iEe3lP$s-Iet(Cy&R_F8;=7PZvS8wO@Y%v+3pYU zXTxXpMPCe2>CTh@xsNa#be6*tV7}?1&+a!@5gucClEsYn4p>|?)3Z-a7evV?)NQEV zHm^4=@CW(92DnnIz;WQi3RKKw^^?#R&dM>t`lVWbOBIM&*f(|`uoL5(F9I!Kpdc=*3{PbEkbL{nRpxgs87{xiku zvWsV?8?U6Zq2cH1hb|)Z(-ZPr3Sn%>mdkl?Kz>Jai$KS@u3_PoOKcsiv&te25_QpD zwB#gvV>Uez88sY79Zwgzt+0WR$Pnufz-z!B(6LUw^v8x!15vA@Pg(GYRnE1-s;@pW zX3IpQl&j-d-jsthXXSo?e8%uuts)?EKg4Au`cO6+9mE765&&nR-bs z0o^ypBIw!*!zJOp8oVOQ)&tzvT$4eqGt%n(9!4$DRrI2ADAR({!*bqV`tH^&r1Q-w zOJ64|dq(;GzOfgnEASj&@V%FJg4ExZUQ7Hz_X80@=*~MX!Pr^+DHcQjeX{tRG7S_Su zp=iz-*ocl}?a~||1htqJtecS+vFYz4nsLQY2wneulo1>7HP*X>?t)Cig;z@?j4BF5 zUm-gR8SI0Zk^(MpdMG~v1!7=g4HR&DS)SA&1AwsErYtS{{jnh`tVXGFhE~&NsNsL( zuDx6LNOS5!g>``uxDMEL;TP_Bier)yHVW*HyVJ;&VT7`x`p>-9Qq4LmWtGChN2Q^Q zZPZFXPv{s;SXdERR4eQ2yO&V$T=_6xe>|>>?PgQ|fB_Elnl+T#?;mi2O0`_%Sx@h4 z5=C8uj{U>1-@_A>+bFKgpc&+k>68LDayO3N$LyU}U7)r=PLdRFu)>R_bBw8!jDs-E zXSaCpTy9Y|Y#iWDw+96dup_V3L+pC}91pWO!H7}BQr~NLUX}!5+NM1uGHr74(&Bp& zj2kP-*5`W}%%Nqi}@=;M}c8P8;HP zl-%BuNtZomJPcfVil165Jst}FAb4L~1BX##zTqu0BNfA?!M^1xZCMs5La2buv~B5q~1=9_#-IVd53~@A4HFa;NByE3N{~Kl@wW)DnT@seL0R zFn;&*OcNiS7pm6APwbB@{8M+zHK1;j^haMHy@4tq3?Es@pD^uLnK!A5HBNQLj zL^-)b@`6?$gNg{729Gtghw<3E=~djEvHM@P8|YG)lo0=kjLS|#G;X2(x*TB+G>|hs z7jBpL_-j)Fru0s?2SdmY2NDXv_P4J+2o&N*5u!+3>&{3BxzH@op}nk7f2K7zkk(Pu zVC)!i(EVpxB06BpD)RrMqzQ~OgnGAQm3Y>vU4~Kugdopt*F)2UjAdv8)L-W0-tYs( zQ^X&A8HV3ic;cI3Q219~Cv#Nmya2&6SLGd$nxLW<@%?qZ#0fGyDlvq8N>W~f!KgHS z{V%ThMRI6w&V3I!nWIlQrL5Wyr)a}_UP*9ZGzp_dqKsLO63RbvUx)%u# zZC2Ap6rME1I|P2PdE0z=dK(N~Sl$w2Au@B}Qx)i1dB+$dP3~av9A>}jBtP+QpR8r8 z`11Fh;Pqj;dq1`xriS`O9=DL$axACL@}!qOT#jhh{<1X-lI5=}YKl|xit@a}l*|Di z^)skA^>cn7ZQqPdO`58T3HS#ELa_+N$afIKqjWP#;eYFUD%O}e|ICL0#z{&?nJm6{}(1)ZMc+v z#e1eM$^lQEdczy%+N|{9BxyLip%;bNMFN1_P{fmrIAv77YhLXU1 z@<}CT$`)V;zE-u{S8}3}0!qiwRwK(pe1BiJwROEyH3-B3Y3QsJXNCOiK7RI!Xp?MB zjzl>CNf&WZpk9&5fk)()HBZo;oLc+;O@eLYaIgXkp|LA)ezbTwlRTI$I!~ zJSpCE8jRDRd?|vSpr#yOdMBD9DC5v*6We0^QsTpE1Nsy50eb9LLNIxvc=u(?`&*Us zxutIM;+dpHO};w5rE!^_aozlyXNmtG&*S3Ml-i5%gaY>uvgbN*IXs3RbKY3LCBTW- znK}?A5#-FaAUu$*>U+XQGxFy<$2>}HBqObGHyf=Z#5$i~_x=PvO>jMv4$~Sh5F#RpAi|ONO$v-f5tM1BF)0JC7c{EBX2}slN4N@ zFCPOEvyZqu?I_5|iZz>wG%Ux-AH*7nDd!t8B;$9&$)QIlepC*}b5518N32uSNv}qT16ogvpd=Bz%ePh|ybdd`=ydE!Ww} zBfut{eOeN4PF9*V%`sLrkAH&61Gc>ygOC$HccIK_3~fgEe5C9Rn45F5MP01|)|c?D z1!V7KiXVbxQa>+~z2&Yf*_6^9|*Og z)W#z(u8R}65aQ(dl5Ek?wlH!%&uDFcH3Rb}P6r$#>x!z;ri!MvXj>Guz!7$)V3{A&Fm?F+ZujjJT3{5Fd;b=wD7yntc< zCOY$BO9M~>Msa&B-;Nae}0Ii(N!-b2cfz#`?e# z*f?h#)%Uw$dGdjM97LZXJ;;oFgiR(lWOP~DSb@W7duK*rZpY&lW!BC1ZRU+UN;Ksj zTkC$xSkR}PRTF)~JL_;DpInhP8?h))zfFsm<#gxPdJ-17OLgry5r%mYA&-_ZhG1*P z(sm~5HZ)d>(ZoKLGSPl}GBeVS>3+J9M}UbLDE>QsqSElEKck>Wn{^_bRNJ;Uc+uaF zse7~T+2=zuIX>Pq@fz384CwIa9J$pr?9iBWP-~3uAA@}wilRvVHhf54*aV9;rKjHn zw;?E`aT+E0JRX{iIX!X3)zlL=b^aVO{J18$tZK+rbY?H7(uWf0PiGbIIh50>^1`r_ zZ_j-iXK=MILvT++>BbdsVrorxBic@ayu)%gga^h8>BDEo#vCfKzug@HfJ`d#MCG|s zR9RBn!5F8DxNFp}iXSzqNq9g4iX9gF*r&}gZ z$5>gOG6gFARI7kulQ7MDuqL!x_T7w{{2EgyOlK)yMV$2|+B zhet1d!v12_+^K%Pu``u3oxJ1%AvpW)vA3>^w2HKYrGl%S22W@djzTVuv>IYxir=%Y zj2<7H=|2p*99WHmnH!YTl6_wKR7alDD@l8eOU-u?mQHUJ!3-=I<+uY}gFm~!Ac{|r zph6LH^4vX<0^wO4{wNoS;`rR@T;C9Cm>>$Dl57p9)wM+F$fbogMc;NCBUXhzEKbf7oF6?Hid1el@w4wj=m=?bcoN$E+&7b%}V~6_^cTQM{y?p*mC#|Sz zaj?q@H^{OT29HZH?F$G(vMYb?O89w+;B8>lK` ziM|7mYq&aYu~er-1Y9EGo$F19rjz9SVFiSDqkVxN-MNJ~D>!(4*zz1fOtzi&A51$0 z)Y25wyoe=Yk(VZI*tx!fn3X!vt0|Hb|BQh$^KOULP}nUrr1SY?iw|WPjEoe(;@P7Y z9D%%u=UT04`~9A;4S8AKOsc4D{vrp0kRz4~S!mjI0EmhzOs8r`&d2H}aiZ1!*SXUOI07~6 zc>;v&2IOai+Nx&~kCjhQBg8V|G-Qv@N61a5B1&X+cT@p-@vYn$u8S;u?x>MJtAY{f zA-%UZk-`O}9;$k7x}_fY@{k?gm&L7_VrWdA9m=-cxClg-Jln;+f&w)!#?`(?^W zjR;@R?*a^`8066eue-8A;zMNe+BBQtOKa4!9UF>ts>V_omv5)03=d2fbv5<6y7Z6p zVSx~BlHr?E9+Ke^9rF#5Zuy>?AvD#k^?W$}a|Pytt&~4&UbEz8Nz7EV3z#EyGT~NX_RiAKpQfhEDc~f<3S`ik|HyS3ScuF3TW+vdWS}N5#NWugfECjz)>u%&% z79e?R)dc1bIENmfvg5>(#A^dn8C#IA^Sz-ljQEw;guUL2ROWl`gRSdJUbKD1s;MuO zd>6V>y(fM2YIPo49YPud8dUN2{FVuhlat)?z5yw zgAhJS74|jC47Ywfd|k>+qbq!dY^}x~98d(HGr8rR3sQ{cT1+`2$4=4iz6+*A5y0UX z^OEAkl3d!9wR0vdWN3vVJ$C}F(McL}dtL{w@==odSJg6r^SzBU7~gILKTcA72GM^rcpewzywe+!9yHZH@2k!Ia*@Cc?%MQLC9%0DV<| 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 z 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
  1. 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

    sHmT@Ww*Z{fV)ahkxisa{9 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 Xvvma_RY~cDPW@@s@ip!JW%rl( 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 kry}OHANO^wZ~ya-@rc*|A9pO)xc~qF literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/libcsp_py3.so b/Program/libcsp/build/libcsp_py3.so new file mode 100755 index 0000000000000000000000000000000000000000..7f30c26bb5ef8b55ea02cbe09e5032de87ae8360 GIT binary patch literal 103352 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 Oq50eOPRKpJ@_zw2WiU+u literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/csp_system.c.2.o b/Program/libcsp/build/src/arch/csp_system.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..1e22942df185965ae2a82885513d7dccb0cbe182 GIT binary patch literal 8832 zcmb_h3v3)m8J@lK`7X8NICkRLaVoBXv?=uNZ1?hPlRCES*sbdeZcIbfvbo2eee}G0 z-Q9E22W^y)KGIeMQPc-53Y3=$La7k6r9fL+3K9rWTA_$%rBZ}wrScFIltTFbng8Eg zj~yWaBYWomzxiMD&tqrzZX1~xjTnaDVu+oh!7&Q$xeavE{=zsPZwEuhLpFDl$%$aMRm(BD4KTBwOgO{`& zKk3zLHOKX>QZfa6vhG=KvRt=|e#Nnqp5=?8S2MjEJ=2@5`z7aqjk;JEcddfs_~MNw zA>a>6LT0B`(xK|U5FIfR$VDP?*)*vpp&FxE^~rQan_?B)7m9s3&! z6Mgz4KqeIa4$|$4{wLDiivAbUNkyMQdSeSzA|?!E`V?bGW~*W%k{MJ?lVrve6O+sy z#WYK1pJEcmtq|dU#hhb&6qs4Xv>F(2O)>3~@fFiySkQA&F+t28@q^&XbC{SjP6O zVm28kz|RXpuA10GavHj0CvcD|m7hV9=+EMCX&SzOqiu(Yy%MnI#EZZ!$N9&w+lGKZ z6lYVSCmHP&E3m5_tJq}*;))&&(YqwQ5@nk2K%a`dvq9b!knyz`$nxi)YL5!hA>uJ; zq(ZzGkS&cfk6F7|3X1C)$xmhtcy8 zpv!<&MS*KiE&#i*&lr%4S&4}uYK?~t*ez?2TM0zNP&WyP*8uJ@rj7m{V{fCo$9R8( zfw3PW12XOHB92zqq6y<7HY9gFA`kC^&R*4tfg00rR${w;=?EVMaT(#)fM|IAFCs(( zGQu_yN2@Brb?6*RBSIXsif|p~7b0v3eM=ZCjSX#`Ez!2#wv|Rlyd8pzyhpUO>;y=N zD3M^TsY^uLwzpi;GTsSGZ3T$HYQhHj`1t~x#AZLuf8nem^9{I0>m{Wmwzxt06@7Semink^*L33GSK7?adA6CWKk8R4v~7)e?>gZ$I3Y z95YDh;z1Pi)oLMMyk14NYxs(hz0%QK-o4&(aW)|rb(_Y3anY?w#<`#avp70FF=E!L zbx#^O;8uJ~CDk0Ao*dpgo|`mHIpH=W43dk9l^IShFtvMfIyt;;TXIW!Q@Ssin)Bm>@$)`4Flc||xD(59r5a|wB_@I<3dp?XPRdXHRD*BEKeJ*6RF?h=l zW-$QOu*@JILC(yoHE&f-%gz_77G%EaK(^H63=a z^5WVYpB&9m?&Wfu_i=!{YA`Aa8HQ$x%$!xKDC?i4*=c?6S?6lglSs`A#ilOIUC-Lau;D7GFLJ=W-VXp2U%z! z_t;#lnyhLz3A1j)ivaYhJ*hSgtcH3`Wt)ScL^P5wy@}n!!`qV^rweu4udCIUy0|X6 z{#*OEru(uNDpVfY@}2{fanqDA4z?S;t?|ThI1TYW#!p;+Dx++l)Dr6YQfX_SYD-Aj zF~Y;L*DfJT(4q!h!s+^_GmAO^h%Wuc2Y7JnTA&tH?;i^=xE6qwrr`0#aiUNZ-VgM0 zJ^%)s-0(D%MP68e+6w<@hYQ=8lDItSWtY5rl2BAV0aztyqe8xN1w0c`^&-S<&_>k_ zJm8s#s*5|bK^qk~>cu6hZrh7GqUy%H053^yaefevs%!iL`3i6yq50zc+(J0>eEq!} za9nG8c@%)9@Tbm#YqpQog0uJR zvRg!YVmPGGIJp*jlP2X=K|iH;PvnMnO_;gS(W^%GntOK*!E;G0{U}`OX%HMqT!bkKB3`d;;+*12*sb* zaK8An9>+;y;s#CrZnAT`h94mOxQ6qy=TjQ~9OdD04NnpOeGUIK$-k`Oj}ZSG4d-*? z4Gq78__sCulN5iH^2&LL&<0zf;nx!1tKml}PM$Zmvxod`(&WEN_>hJlAUin?e~sc~ z|7`zJ!Yi8mlVoRJ!+Cul(eT?S9=tnXVf)+3&LbNBk`fb-Y4|q@e?r4sDb5!({M{t~ zl7?r=@2@rdS0w+2hMy$+f7kFQ2#=9H9@lpW@6hn?5&kX>{}JIAY4{NF+cf-TlHaZ2 zpCEox!`D#U*J$`rvQyUZLnQBN_!o(PT*D_x{u>%TOZ;~=yqEm`Si=V?|3BC8^<@8b z4Id-^j~f0gW0T3dyB4{BsmfR>Q9&e7lDKgX|1y_=_Yzs^P5^&xD4% zBtNC$w-8^}@Sl?3>ot5G;qw~aMEGICF$_GC_5^mCjVi|!w*C9=$p$cAsp@SdHaVD-ps<#z8%8DcGl3j%j0^B{GLlVvS|NuvX#~3 zuOqud8vYl;Cp0^p&!Q&J^T=}hrzb>WWcd)bI92@%OJ0z;`ot^VcX2dF*2OUq60LB=OGppg8XTGWe2caM7@Y<9r zByfRb8kHUozUQ#5hLjK&5cn4DFYeQ2$Dm`W{LgkMjXwEf9sGg-Y#jc1{G9&}0;bzU z%`RFHH)x$2E2?MFzXP2?=~GQm>-sa$vsC;K$RBqa`WQc+C3^ga0Ml&(B%UDue9j_< zMVGx9u%-O}fc$fw(0?oZ>;CT{oBBAO8riGA%@3-P9Ef?6Lx#0G?Up#8Erl>MJ7xO-Y}rS4yBn6Bvb0bMdOMFhyCXAq zhI{WU%e!espoP#TCgo9*qG%MODH;((1cVe56BEQ3RKx})K_T&xAef@-|DW^!ckZ6u z#zZ~YIp_bs^S{o29{1e4cMXq^gbYJ)F~knh)a;YFUfwfTC5VI_iab+<S>tB}5%l}_%Xnwt$ zuxnnzZPe>E$FquwB=CubYdMKh!!CH`nw@Yh4@G4uxOLOL#WmgOhF7fJZ0opV)1sQVYK*Arlj#e$M9Q`&LUGAS2ci2v2Lg(G z0Le%^8b1haNNL89mfhhu2AOQx`&A&L@oz#Mzs^Ui3Oxis>^Z2Gz)!pp`Cud@#5qVu z{*J;#pSc6bxWYe1x?R!#M7m4S|3W&U=sBb}wn8N$!a$~1F@|KeDJCSDe#Nv%W>hf| z$?Q^0R5E)N6F2UJ2=^)G9ODbXOeCjqgA^@)$9? z9|3d;u&O9eofxRG2hL7x&tE*kuYkCW@Vh`Xz5W*w zq5&CUn~0%R72!H`j-?qP4q8RH4)Y5UHidpDj1|WEw$9dYTTj~xqa)T1!G%60T3dGj zBt)1%Id9q$mS;_n`xZ z2z4DD1bA&wS*acy>_+XLhzb)TK>c+ofx+2r$`b^LYe+7Ce~JKr5`3&EMAapD3WZ=1 z!ps?G+Ll2rpXtb_Qfb#Iq;pPTTBIAUlP=qZN~36{XSZ!JxAY||WxFw(oU$9~eA#oA zNTr-lPZbIaMYgiG0JCfeo|y~HYXY#V)sxk;s;L5AF}z#qmYbT!VY*(iXqAA*&EFK8 z#^)M@Qm*-8l7xpNKB6thsgzw$^`TnP$~UHfl~2?qDt(ZiaF4Na=KPh~g2!u90t) zcrgBLg7h|-8570~12Cl>5H<5T*Ahe5>@u$#n4ADhQ#M>yz^o&|U6a|}*`e&XFiYi% zW!IYSExRZxHG3+77YDOc$xXRZV|a2hJLy|TDYMXU%tEcwsM=CuaL>rdFo@JDMH~~} zg19Z#Oh2Iu2T{mXD*0UDMitq>(3QixrK4)jxzTcPHX#=co5p}~?VQ+?7`pV*#Mad2 zRBs|#^%}Odeaf;er(6IQ*XDLuj>#>3iR4rwnROFMu(BN%B`76JyT*o~c0KT!tUEQ& zDtI*qBpevGpc|RY!91rpLnCA3!)CqGaAkluJ7v#O6K0O=nHbtVmYpz7xtJgnm_`>T zP0n6ofhjjPW2sr9C2B&({F(K$q{1=%9Qk=PE7puvF)cfnuUIe}l^SGFP1q)3R%=BI zGgoVPxN~^NrpcGuH8>(#J7rrf9W^95z0ip^X^r8?g;}q;!My^0*i~50b1!Pr`E8G zunTf{1y92+2WRPgqg*M1X}Wv+{(XS=!+3V+N@3d8ECh~@xAXy^No{{B%ayUec4-m}*=5 zWLsRyjuIY}yDB_&MoKwAiU_CAmaY*Yo1zIy@$-h;CcX7TKvZt$B9B= zcu&yF1^^5=!QrVWi@dl3wGDn~hYQ=8l(;V+k&Zruwy!s_Nc4=+k?VSW$}tLywc`7&@Ff%)S6+)g<2 za{T~y7=F0c^zt|Wi{a0n1wREi`kf#{?B_RxUrRXq<%35ZXuQGoL(>c#t@`g&Q- zKX01{tS-A%q{fE=3UEl%mYwfSm^;U_g9GDcc4Xw5;oau$fkAjyNJsJ_p`F)@KN1&v z0{F)l4xM)j-bQfs@(PBlrYt%RS5{drf*M}|K8CL&ST-nFUJCIYkD8UM^#@F~Lec)Wl-#=~}Q3*fjr94EozCQbe*+4-V|-$D2h4d-XiqZ4s}=k@ohhCe~_ zuWR^Y#Q#pi`P_IREpyBUGY53pRS#XXG{qh|WRrt=%c_uSrCHc|u z1PNe_!8rRgob$~07MACE+^5O&Iut4QmMVM~fYx(VJI$11RdOj0-`!KioR<@+yz7dT zQ$q&DGpP)-(4w%qkeBUJ4OH+epP9?&9cyM@ch1S#Qx;lks=&uhi&em~NEK?;ss&%9 zQt)3vD+S-B;4>0_%2Gz^hyUT?(u=Nt1GAkgL}2B6QPq zga0G|9fO~qe|(?PZ2}}V(1N&0>(p3LIg9==bOxnYHGZw@PeIRO@t?$n1%>r7emqO` z`1b>*+XP6wO8!5ub!x1@_rS&cpC`K?J?+B zOn-El(zu8fsbxKGPXNwzP}Cv)AcnLq`#r++^*c-Yb}9smFU literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/csp_time.c.2.o b/Program/libcsp/build/src/arch/csp_time.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..0231b9869dd1b8ab37456c5debb0302b9d756771 GIT binary patch literal 3976 zcmbtXJ!~9R5Po~>#Alowb`p|Y9HB-0B_y|J6XX2h#IdoRAd^HSK|mzddwc7<6L-7T z{v;O)K%|NgB1lM3q(U?lNFXZeG&E2kfe;b}9Y{1OsDcz`-kVwPJ=PT?`OVBXKX2yk z`#Ha}xUy6-48dfGQ({A7REV<=ZOC&{oD+|TUE=J`zsi50esfl$>DF6YP&g#V*YExY z@{qKYW!i00&J9*hE*WLiN~K}Rh7>C+W^7e9nb;iK(g_lkxpeR(29>3uq}=3`=Ds(; zAYo(Abr45POo1eG8C3+CEE0@6KY=9YG$z~umDfIM zw@M`_FAd^OEAX2ZZV(JV@~o4{d0Kwr#KLhhup0&~YtVlki*aHnTw9C%1Z(CN>)HIC z$YQ*<8woiqpTA-)96xRywV$&mty(Wh1An&V2Y%G?K*dFxg>|XTOk1^44Sd1_xxtZt^3#9 zpnl%J{z}+Qdw#tYg=x@qV78IfuEw0cDl`MiBehvA(j^wPFM%7G}0hRRb#ay zsnn+4o;qevP9Ib#e1cu@hh)6BSa@@@E{i0_vcAuQxCRK~7W2DcuWC4&$+ z)%PCcF_z83n+ZO@+7IlOag%PI3;+S|A0vmWyGePN>aNJUOW9PnK>=Rehnbzj!4Ol7 z4g#c^V*4ie!<*n^o8WNcXoPFOBe!lA*=xXyvMg+Z=MO4x5I!V$Fz{?KE}Z3+3-f1I zoC`}!mliKOm(R?vEIQf#im?QFD+9;%ABVqx9w_1!!n2LG`-JoUVx0Z=fe(_7%L^WG ze759Wj!r=Q{veKX@db}HATj=uQsIqL#P~37P@t+}a%Ho72(W{Mqd)#JO_IQQnxr4q z@SjOPrQxKCMGZeh`ih4CN%|!X|C@A2!!6Rg8vZ@$@}q&w^+$yFHGkg8H#J=SIuP<9 zL6bV?W6B-)jDRVcgB(`P2EGmWN+TUT>avH~IaV%Y*xb@%+AG z8D04->2=jy>i35_Wu}m$(h!Nu+q2rO5BPcH;NpS!%k8E9^!Luc}0wej{x; zonS2lo0Q!~Bl54Y)(yP@Pd9RdmOmH`&$Z9~Fr~1)u-Eh9?Xd%Rm27z6;8lWGiW2#4 zXDxDjJ~i?`nFaBAn}ireo;-1A&j{Vo}t6R|_!oyGM?EeR7sc3)|qo0>tBF?7?sPgI7{(*U)(=Cehvb<&M`o| zU$A~-VB>gR*P^*GMW5#XiVB8*n*{!<(&KR&{pHXvHhobn~RR1?J JYGcsj{{`YQbXWiY literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/csp_time.c.3.o b/Program/libcsp/build/src/arch/csp_time.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..0c62324a34ff227101b0942b3beb2f1da33b600e GIT binary patch literal 3984 zcmbtWOKjX!6n!42&4jc=(iGZh5HjUk=-3Gj>5sJeG%b~eHli&8D&crM&Wy#39r@Fy zEFhw*3L!us(M6?7hz$!Q5G&T*uwsD(3nV1iv0&46k;=W#_qv{kv*Jo~Kj(hleb4VR z?=Lq`S2Rs9Y2t)Bw6Lkf#aA|m5xdlCWqAby$uct zYkRJOI-+9EcZP)PF z9%$t$F*x1MJ|}4zlK+=|15ibL z3|!Oh)pi1xy9GX`W|~$Uxt0^TU16nhWch*HOWU5cab(t>ooV#^Al+zmg4AmHNh~0o z1KfB$OB0~kiQo537q?wLf813J_9YRxx4?RF{^ zXfF+7zY}7T0LoeEi=!HSY7zj((u?IW0!?m^8OR!a*nUxRgiaf{d zI+2iUuqX~0cf%+dEKd!|gfr(Z8B0fx8i&o7%qgSMPtw4f>v(||`7W5am~*gxjoBHa z(J>n5W1|5}F$b#%NsYCYvrE9^#BtwgtVdzuxk(s7Li63Dit&;Nab{`hnDN}DRvIK})^_7i zDy`}FrjM9YGY2wM?w#F|!{&JRHKA>cX_GsKtDnG^Mf@@H87NQH#xBU0C;04R75X$3sHqp}D+yEBU6QrELvp#(3Vhn}Cu!4zGL z4gzH9V&@k4!&~5ETi|f>D1>XjtFUec`5Pe1sw{1R7Y{6N5k571*ccb~ndbS$g{FP} z^yv%B7wwA+i_K*_-(fMfAa7@oxc=kt`{#Z}yh3=!(RYt<-d~J!{62_5QgM0F1CGy^ zywfoVh~FW^aje@20$~qGjGxL(cFOaA0Q^7wY`+|bsBimMRcwr><6#OdL@}q&y{riM(DDeT=*A;w*Yln&s zN$v9%)lqSSaGXl$*ItX9 zzDE=JpTdBAT%+QeV##@AK!)TG7{(T95)8aA=8GWcn^bU>@LeD=m-hzz36t~;aKz<5 zj0}=|wV)SOb^L?i#F|^>V{b)L?OAZDH8Fk_8PK1Z$hjIj4W6?3|3UMAgEkq?AMaju z{)>RAH31R}1b&1@fz;R)@TnMv|3u)EgdkguWbA-jnDfG$H#j{9e)!rtjT?XD(Pn$e?=LPO_m=* zbXop>+Gx*HJrsmH8me{26zomvJ0K%6rG<}(I}8QfBgSYmVcA_|Gtoms+#{V DXBKp! literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_clock.c.2.o b/Program/libcsp/build/src/arch/posix/csp_clock.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..73b302fdeafb2058d9a5ba4ef385d38b77953ed5 GIT binary patch literal 5696 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 U{m1uPn*Rtr%|A={BCGrV1L69Y-2eap literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_malloc.c.3.o b/Program/libcsp/build/src/arch/posix/csp_malloc.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..651fe5b3fd780c711a71bee02e3beb17d6fd8bc2 GIT binary patch literal 4872 zcmbtYO>7%Q6rSC68V9Fo+E9oIm0XDyituiuhV%#8rVeQmDQZgVR7gFz>-EMlwb#*l z-I}U`s^w6A1VsXIsRT$IKnPI*7Y^JD2TmM%r1IX(yxsA1BO!QEcHaBm z@4TIvo#d6drQ@byFd~B;VTnX2W4AXa{0wJj*mm|H`vv*r@h13YxH`+D40B$2Y*BdA z$f9JLgM7${Au9%Blh6&|U}XjxLBz}~moiyXXoc=h2`r?_6yDs|*om%4+zv+L=6CQM zT#rI#?DSCs#A`t2JXAbntXRJrD~vsWh_Qo=P)efg0?V8*2yg(>#5m~1BexcK{<)%E@3W#L_a# zFnC)ZNPRren;Mb`I1)=S|E*&=&9Qu6MoKN#KCB$JLM#=Np7AO0G`V;DmbpX|q`)+O z2#m?D!qYJR8rcj_zIkC`7`E+nLeFtSZ_Qb6cN#tBbUUHb2)t&u<_n?Os5*7eb9x7+ zE7McOW+UkKiuIuD?2ql3*IBQ$+-9@w*&dz+ou~$G_8Qg+e9d14-ok>0MCHI)4ZDQL82Q9x<<&|*1Sm&*|A>)rE z{#rYXc&wyw?&*owM= zf4J@ke%SCp#Ks?n#ulfi3dMS%xZEiepeK@bRIsH=$f59K|@tr*)cN5bEdGWHpX@F|&hPQWq#h?JK!{39u!*6={eu7>+k zeo@2ENx7}z^dY{i;ZkJRG#tNkNY}*>*S{!bnm6?m=Z*A*7`VNByp+}^+>xFd&GJig>zQ3 zmoS^x>?!Z_3XXX{lMZLJI5gj;Vvl)geXnnT_cZ)V8UOMI_^TRzOv=|cz-ez{EmR|> zpfe2J)cy4~DuHyoz)@kV+D~aXgdN0iGywr-^DvVJm#x>$Xzv z0;k>ZM4aC%1;n4r3a_$yemq|==705{246iU=A-<0H&RIx*(4~_=6^>{ z^b=Va&L7vHKK~M6dQ5=WPZInV1%-6mlc3WvG`}e~!_SH@vbycL6b$XI$hztKg&30V ze-^N``Cl34=JEXz=a1h-ef|+(dQ9}ZCG&rbfk`!n>7C)QP(h&QHXEXUzU(<4<%Sm~l+?55x{|ERjSNF#?q3>PvUyz2gC@7@Q TAMbBz{-g40{*~g3tnU90(&3v@ literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_queue.c.2.o b/Program/libcsp/build/src/arch/posix/csp_queue.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..90a3ff2a89a7c6836c82c83e5a828b7df72b22ae GIT binary patch literal 9368 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_queue.c.3.o b/Program/libcsp/build/src/arch/posix/csp_queue.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..49d463822288a529b3bd2a7201e26990ac8be616 GIT binary patch literal 8784 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_semaphore.c.3.o b/Program/libcsp/build/src/arch/posix/csp_semaphore.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..232b5ab07b7d3b7292ef3ffabea204a17a5726d5 GIT binary patch literal 17648 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 Pr}X0Km&%NLH1+=nz?bA` literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_system.c.2.o b/Program/libcsp/build/src/arch/posix/csp_system.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..d308b33849a4012269105148faa3c57e05437004 GIT binary patch literal 16888 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_system.c.3.o b/Program/libcsp/build/src/arch/posix/csp_system.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..e9273c87bca27633751891f241a147ae82d0bf40 GIT binary patch literal 16864 zcmbtb33yahmcFklOF=><5D0{|fCLFms*(^E*$ml8G$a^86Grq|NxdZ1RH|atD+ub? z2(1GHcI#)`Zm6i=XHV1Zv~9P3v}2FXpfft(=rGzdjqQwEZ?@3mHsabc=iGbFtCyRK z_SbVi^4>ZBJ@;&PdH3B{e7(87#bX$Piy_vF49BPtN7rQNdP&xcGBHDJX+8MK!S`GD zpDDiXZ0n(1tg%CTM+{*%wH~~>-1jCTt%thHeNBf%>kZ41J^0cSXrksxS$TTa-Vu+m zXHw-89#>WF-+g}W+_~2MPZb|Lb;${m0AosR&69s|;&=qaPqbcp<^bGVZvcyt)G}Os=?58p zVxW1UAzQj6-UC;^K*5Vx&7ME8(0KbfUBQn);^0R$&+dP%=-e~=Kg!=-(0ao(^rz_2 zLeI6odk3h;Fgg3r1?&a8Cq9Nb+<&h4^pySQsvq+LV;4S_Be8nhQ}Y7nQ>FU%P$4Q( zs{{SvXv~TP>_osCvHH@swKR~l>~t~?pp{G}lB)w1k)=q+6G+NNBpMOj;ndDpG-U_k z2|Ezp1-in$F)NUW2R3(ZY3mV5t2dFb#b7vQi&>Xcq}NoWhtRT9=FSVuU$C&ef`Pu& zu$kJEGE;+TJCfKPH`A$Te8407G_bG>Syw;rdSTCbca1SU)fpB(aql6GAl zl&}Ikh7SpkCtu!j)Xk@EMxLsZ$L$Bd>5nIhnFj6qVXCq zgNi9M(BWal6idcd%oJl7YDN@OYSaOe^^nDmEb;AP~ZL!GneGjla-vSsTML4+7?cxR?5XIh0sqE4toAZ;*7J?+z4N4kGz@DZw@q{tA6i<(zM8}HOK!dB{Z>sQJ!EGnb zLWHJ>M@=YcykLRn0jSCI;Yg9X3(GTPEh<##$_%*%NjY&Q&A=X2lIy$bgQB# zp8|UGwBc|>6iq?8OW`Fb)1&CANMEk#X} z(+W{sQv|DyoYU(1B`bs|nhEmwHx-s4=uS#+@p{xV9eKmVD;8Xouoy?4fXW$?G;u}3 zQic~Jj7i6$u`@jr6pmNffp9mjpEU*Gi4dwP_snMMMZo76TaB7IM)w4#9%|>JgwcaN z&Se1+#*tO9BF{sv6^Kl;011d!K$@lMj{OzlSWBxd-@PKDjz%a%c zfO=*A=LjDfQ{HsBy^;1o)Hw1u2xRfbao_`R;HYxIW$251Q06Xjo67`W2R=)4O+aK6 z1~}d^!Ou`Z<`&|{=F4M8wKDcu!iTn$GtF*iGO=R$MK?Z89Msvoi z&~hQhWvs^4s61(dlhmMrRIHFuw;I5qNRK5&4&r76jVJyI94a;K0+{GxbJWEjJ zX(E=ez%;OrPQ7nz)#t`nP{z}Pdc8Q`WQsgJ-vpk>ddQZLV%~oA&pVIBy!}|WR8(Ql zafuOO9Krcm`3zN6zDPvSEnH5*52GkcIBf!~vmE?)f(fZ$v}r!axY&EsVBQ>~%aej; zW29@fz(cItyRDkZg6F&rJh|3^r%cMgC39+6x|RvK^%hRcsTB@c{J1bC8x{VN060r1U4I^0C@h^WB?&*GYrNZ$30}Hp++cBdYIVI@9c8z1e*PJVbYF#`IH!8DjI(L_U{+h;nYcG~sR> z3k1jHUJ2mdFI#Zj@M@BpC~!@bWlSPimNmPKaP#a&SR=2A(2&U{s`H4O2ASSLm?17^ zl1=}q`ny?w#L=~dNw==Dmo%U z=~OZljrYaU5i2yZYK6I?t|}Idr$?#=;^|Ot)J`dpShP1Z(APIsWF@y2pqv%K;e<3Y zO8qD%6iy9Q4Onq28SNWgA+2l5MoWxw6OJ{U0}nVI3HHHM5Ggx}2P*xEq#f;#T9M!& zW<6y`qKR5X+k1wsR0fXQRcScCh&xEc>IWL82A#E_>Op*+f@DM!j+i82F~ZXvI6cBs zB2|};1BrH_a=@|^!?xL%NLs2AELFu~E9!uQZIkQ_lN|y8ltttHXax2dXg^~0rU!t9 zF{6%rfQDTL7yxg8Rt``bsF3Ga3SZlsj>hb&XnegIArsW-1IBy4aa4G6j0f|6fVVtP z`82qD^7`|9t(SVueK{WQDkI16w%SNt2-K#Y_R_(T?z7u(_WFH~O-;6+n!BTYyRUlg z4mUl`Tk6~QweDSCJ>b2vXN7m9$6L^o$D%x$f0-Ob$3X3D~z0uj-l zw5-ACz+k3o^l=>>s3|3_ZB5NCyJ(IqLr_WS+UBm#?oN;v{pon09Zkf^{`Thf_Rej> z?1wYTcp{S$D;^O;i3kp0@>hnWBH3xd;bqKBBZSH7kA(+P5TWeuXdDuh>>J)A?KXFH zb*ju^rckTdmqv}T^iUj{s4juz?-XVt7Qvo@Bmk}Mk%Z}tLGpOhhKWCxI9=Ls2Z}VsugvCs)0aNXDUzy<6<2wUeKtje{)+STvK+q zZ)eqTGGSYNb|MK9Nk|!=*=8Li%W9=#Ep6@1=5Qd zaXey<;6jGoXvPwK&^xk|YgO7YVfY?}ifKkbw+jfgFGZRg+P5|fSb4(90YW-DyEbiT zM=T1%fR?s#j-gdQb~SIoeu5<^rEH-mG;uLOP-Vq;MIoocgoVt}IqGPdW{PW(l#@%1 z9M%6gc4}ZB;}Mu_VVut)SdGE65YE8}ncUdb z+}r`N$zh0d%*1aIA`Lw-WMN0ZKViZ&x75NUWPD?u)gg*lJ>gW>G<3E%$za+$AwoG9 z<#Gi*g5NQ4%t*J;3XV`SZjFE~oYyPrs0-!VD;G~^fZ_t7GC688a>`?g0W%CStM4bE zu73!YI`zZ?4o>)L)D0#Pa?8}MPTiKf=8{~A((!c4iqzt0Mjv_5HGvD^q!p0^07iH( zOycygnmnmJ@jkSO-$G>6QfQZrGlmx}_7-L(jw4u^!x8s9mLWS!mYKrGjM&)NxH_vjN6GEOO_z!C$=J z)8-F&F7p>R`hD1Lt*piKMkp8gi(CCZIJ*|2n{Yly!Ft|4Zp6Bc{u_<2D;;~0hcXW@ zpraFXp!{vfLs@{ACV%mE!ub_LmwyK3pt$AHm)8)4a+$h~d&QTZ9P#eCYyw`~hh-_= z%=^ZuS}$&{vJ@}wZnT1LcOI91-X&K6ZormmnB=)HRuaBh!`le2CS0Ce0euPKm+xOxj2+b>s3kz64^cxS}LwS+ggFeI-hyjQ~y5gyg>8wrnVII>>#@n%%b zEx>Ufx+}gv4t`=B{O9A~uLC{>Mg)&PoP${2gTHKcKL#A-_re_ukE9})Du}CmWKL}7 z0iI3IdE?-#NDrSI$oUR-4v!<>P4Z`?H?$4_Jv@&5v2pM;>G8uI3){V!@G8RPIs^4T zBAicXc%3-`c(!=?$*i7!yta>d5@oh!!MbHN`1~1-tk4lS7u95H>)?sHt-G-`SW_c{ z?TyuVkyI^G%kWZ%7kH3uZ0~H?&~A3Nw7?e0?B37-+ePWAd|lHva$_FKqqfx?67Oet z->2hhpTj6W+%ivJZI{7<**0TY>u9qhpRg>T{YZfxyyMi80;kq_nHu$)!7CG5rq!M7s_MVC(~Sjyws zBQ!rveq7hkJBY*CvRI0NK#|}7;m-IXdZekZAQ>D# zh-1ON!-D2Xh2$&cRmsb*_{8(LW&Nv25AH{>F#Z795zhU|@~25| zizdH=?3x<>3(8|m!`Bghg@*G^Mm^^<{$ES}e@By_Pxw&{KTI8k&tWX=|3bwId=6t_ z{Fqnq&#Ie)@1(f?O~dDr{{PVMw@ChF4WC5uzOLc@WcPO(E`P}f*dH_;e?o%geRXsE zyn*-|;yk=Te1V4Vrnq=sv-}IBcZMc^hQ<%iYnFe8{0V9D+lXJI z;k=G-)NuR-4wfw%u6`;hgsI_wN&U4`!yh3(cWb!%y_gW+(C|)WR@|iFdx*bV!#^VZ z-`DVE~|jd%l&m7$(3k$5BVR^ z@FkR=Dh*#jc2{dS?)R{4)bLj*58WF68^XgHeunV4hQCkvRT};Y;RiH)8sWEScoD^W zzlQ&e;yR|`e&Qe1@T*AwKWg|br2lyhf0^`8qC5A?cS&xFhF?tlTn#@=<7bJ6U!c-2 zS~R?j^s_#;dm+i~(Bx;3{{tF+lJxA;@Xv_&U=&(Y*} zQ~oP8yp!^o{t6AhoZ>&I;oB*$TQr=X-}h?x zOXSaQG(186oYwFiG=ARI@cqPpsNr=a|3?k?l3g$P%l+~p$xqPm&D>uaUQ2oxX!vx> zPnCw>PWqP-j$xuJ{C<0(CJ(;>k)_*(^RpByIN$95J|!;tH2L!hA9Ufkzvbt5(uJdb z&NHub>?i+n;oBsSIFfwMa<>b|xcF=JPh7ZL{z<~w|HG8Ge{sp99zGX%U6Vh7l~7K* zF4)>eJ&jRpG$t;>cTNZKL5Jcg}d|iunR~3S^v)nXaA4Tc>ZUXJnA_Ee^_48 zUGk`Zvy>L%T^EjeJ|O&a4d;Dr8NE2@d0XPb-TE&ioc(`|#!t6P9_{iu*G^5I{ZG5( zQU5Ucd5sH4J^Wm|*@a{NdrAH-7mo6rx4(7aZv8(coc;ePjn`*2oZru1)9?Yx<6AEM zX!m;ZNBysi%==Lj<)?rSq|q+U_nS$+*oEWz&`;xG9^u?C-zE7~8vZolEt;Md(z98U z-%Ij+n*4h-&WAMl7|DOrC6E4dzuY>G{5>vtewRm8$6Pq-DJ8o<*6;?xk8ApQ|8UZU zV;44{awz}h(j(Vf%KsS+f0XbKH9U`S?*yff$BE+Lj6%at()cMSocoLAFL23YyjM|N zts4F^;TLOq0;K3`n*4b<=%A!D{8GY4G(8ncTwJH&oVPn&IE5rz{Mdz~>Ptz_vo0Lv zmlOVT!Z~mJzISRI{8bHar1|x$aq!a`&hH^_kAt7paQvA(mQTjP)qhyZ%wOJ5s{gPw z7N3NHLg9GN(!85I4qmF^AsTNpHT*If4*?Bl`3eo^{YT|Excbjj89yH;{dJl=?CzL)J?<5SIN-^D0o`#@A780Z50g}gRw|u>Z^ZL`H;d_bade+11@HaGhejXjs z@H52oK7#e|{^4IWdEOWOTEltYB7&(sL-4&D?sih$2boG*v2f7FFa5zt*ba+eZz?5% z$pkVeUK51R8H$BF3aif*@+T8ShkJXI)~-?2@MD5ed^j1755Rvrpcc%z6vA)$EUpH- zBG{K08nWPbQ9<}`lvWUa+ylSGfzSG+)*3YX;X}SfA^*Q_0cee5fyWUmt0#i@uZ*Lt zyWm+fPO*A72=v~C3h1H1gx?~tEiLcrzXSolh;W*Az^U>F-4NkAycBTM`RBH;fwri# z7XI9Y?W^y%nHsjw_j;&8n!$N%4lWeu$diW@823KiM% zf2u;YcnBZ5P%!_vMbh)X9k6WnSJGngLoF~}Ha1TC-{Qj+%D2Cy{Q$^h^Zx+7u;Di* zEa*R`LiZo{AG%Kfi7V;jLNzk3qRV3cX0v~k>~njxUkHD?{X>B1Isp>L{zUtCkJJ8_ z)Sk~_P$w4M*6o00^Z#U){9%{q{vRWq94D}{Tty#t?$j0rw$JxRKpJVied%naXNkHw zS8m7mzlR#89U&m7y-E2yMS|G>_?rc8&*KvP z(QRXs>N$87VlOI(G9CU9(%a*gm9q_gc9G`jma;GeU6=+sUd%Mh)Ke6zFXS|=RNms z&#}`&0w$Cr4NW9yK}toTRRvO&wxX?|(+y1GS&%eE| z`{?`j#m|ZkA-dMTUkKds6BOTmkL{ktNLYy<|6EfbUOLxXdMjS~qvV06(vKD6UyG-& zJNg%UPW)I`Q=q5hYl@=whrvyeifry3BjmrltXFRcjll^2>62%ka?dcW!Ej{nhuW*}@Z$n(V-H|4q=~4=CkHRH_0~aQ7(BYLq2^$UEn|AkTqIcxz0olsqpF zVgTIkg}NGT=H3RkU%*w<2{%K?@O=+I2Z|EEdV?cAf?X=~8)bvjWrJ^_fkzETM(JOI ztn=X#>-_7sLMDPJ`!|%ujp!rhV(fdMU52q%Wz@g<6M#?(YO8%4(eSc60Slpzx*N*2 zD$)SB?6hk27&Izz{nr4k3Oo+?y5n$r60QZVDxzkLNsz~7+M|WDjb>$U;`V}kYJp83`j0!xD8B!(P$B331Y@l44%s~Bp9b^ z!A?cJ^g+l67E*tpG*)>`)G9MsHr85^70Xh*8Ov~by(do`R_ZF8FYn2F4qqZ$n>ny$ zsAAzkl;E*eHciaWO`=_m4|64)RDK%3N5BbF2@MW@1K`g(IHcHUEjOm1@h#PeL8%F7 zFm`&zfoGQo7KOuOfvEu(@lT(ZssOIfOXUdQ=KGB!&RG#=)WPPyx16!L6GmAMyW~|y z+5BAD1Rf2e&R7v#SmO;Y3Dy}4szVT=r%BY*Yz7E&OCszDzQw{D+)%TzrUzENzZOj3 zp}-3D>dOUIfrW-QSW|;m2B>r9J1*82I1A|`-o&hyXPXkO?=}rSu)GFg{xEJQd({QpA8XBQNU;`{Nwt)x4-A&KJX&o&s z4;Gm(ajDSnvKr`SK{ZBnX+&VqR#3$&M7RtHvAnE6n7FgQNYj6wYD4t1$nOoGc+cp6 zn3suO!;>uwII_6jf%dStnIOf*+MQ)X7I{nf@13?ej(se;9s4Rq%hrb2$>P%v*G(+C zxprOv*DmJb&B_o5Safskx&W@d%;k36djXCE?D(WJp#3bmxdvu%aqjPS9CxtzkOS=@ z$*JNb?RQN2oHi0xK@D#MDDqcwY%K=Cjf}P7F@SSTI|Ayz+fC5dZM<)7G5LSjCCvVXGJ&%-DqsFp1ieW9D>20bMa| zsxT(I6au7#J(4$*=|~C#l75j99A3fB7gKh^&WxIcF*5}qY~!eb1iSQ@a&tMjxJCp# zgheY;u+z$V*tBzFb|RI_qdTyh`Mi~z#-tS3AysN2LEa@s;9&nhf4Fa8VBoI1UJ67v zMsK`s;C@e2eec26<9k2sFP;`2pHUT9Q1$TBo+Xf1dpuzk%#;{Q=98nQZRQIcXTqGw z*dl4$`OIL^hTN#|6BgKsv3w?%&)Aa!{L#HIlFQp+{GFIc*oUM^B2kzuq>|ZeqL9s5 z!wGCMt?^7gXNkON7xPwPBx$9yrcBYHoMno1ax$A49$1=2Sfqn`CQS? z00;IJmN$w9@-N9L{fQLJoozxePH&ENbks~|l2LO!X+^I$5AMlji=$?A7^tmuqF^WO zOwNjCGlRGq28)?&T1HaHn&wzyw7{cE<B>u%mU3l@IeF+hYV9Kj!K?1A2KrV%UJ2@ z0TxUQ8-3(++mTA{Xk zt;q+%m3}K}<>chc6^xHOCKCQ|;BuByBey1ol9}xEuC++gCeH4pV}tHVcn&Nfwr$z6 zA-uAGuxQyuwUnAy7p2yEd+WMLOWTzS#ci`5Z%~XwyM!?jGM3D%4xE4ussk|jLlGdGvNMP~b_lMU;lctx zmEa>g7(z}PWhj$)>kWpcJYB&K&u}mllWvI4D7caP#JlHbGyvem9d(xC#hrAP;#D74 zGg`d3o6b_aLVn=RXz^=wNA{piL}_NuSb zX)u1TE^y_CU*%!Iaenl&27uXcd|l6m4_3f$uYez~fInIRe*$ofpW~M62(U91?0-r2 zFG7t)t}&?p0M~5szgYoyJ;CtCc0J?IX!bY3~-EojD`-wOG_0>3u4*$e(^J#?bo_+ zH@`fy0=v0zu?(U*Od%ZG_L4u29SdT3eF+sP@<0J<#^;kg#)bt|=LZ+aS0V@n?d92) z)P!iEnt9$Jp0ygDCNlmOV*3`tyEXf#2=CSK`GoJ*@NJ|gHQYz>@Vs-se`!R;R@$;pX?O?ek7+om0-t*<9M4Xrir-Vs_`gVhL&IMq{ap>;PH}#u;kb`s zsiu4||6K|e^%~wtJdGNDjK|fFF`w0J&hVLQ#9Sz@3@qD1+?WBK9 zHC9N$?~i)oC0TW``1A`;mk9SczNC!UqtvVnmy0!go_{hUQY4fuG#Z@@c|9z z_#fAJ@O&4`6Pmq3h4`6f|5IxCtqaHTt|$Ce7mjgWML6#Vh@t&y!p~~V1_2k%&#TsYc?5rnc@ z!#R#l4euqMUKfu1J{spv!qE(&EpTBOa@k|Qr-^6Gg(J@f;wfr82ap8Hy&8VCg2kg6 zehcBxY4~k~pVRQq6YjwmFBFdd+e#IS3CGy+x`zBOu7EGs@ZZsRS5&}PY4{%EZ>fM^ zt>O3^1Ay3V2$>&#CamNCiBn;p3E_LIs?E z3*lV3zluWC56>^Dg5Og*9wq}!7o|)hX$|LnY(m3%9}|(n|PFq~El<)BT<$-%+AInElKbxgB_^DJu^POaSDa4KlB zJ#;A|sodzO38xwn3l3T$aApGsEpWO*PUc8r2v5amApd6-27k;c&j-_Wkf5K1(lTQ+ z`EN6vVz%do6SUy}MgabHM_=Aw;lBj3Tn=}{X}Ks6?sw=NQHu`a87^}Eum1Qws&isj z-2Z23{UU}%w`~P%w(%dKgO3LK@r~ohb*_)Ua~4j3#7Fc{oY6YeRI#Ii|8uxmL*d^A zN}Cz~&CsB8qU}x>HfGTv=jp(#Dmx&ln+(q+&OOy)PXRY|H@^`;t4jSTKE4CZqiwA literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/csp_thread.c.3.o b/Program/libcsp/build/src/arch/posix/csp_thread.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..f92e685484e5953e01ba202171870df856c5fba0 GIT binary patch literal 9256 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 Yuc4=?dgEIA54=NpuK)l5 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/pthread_queue.c.2.o b/Program/libcsp/build/src/arch/posix/pthread_queue.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..937ff875229ff49d0626f42accc81ff4ec6f1f8d GIT binary patch literal 19096 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/arch/posix/pthread_queue.c.3.o b/Program/libcsp/build/src/arch/posix/pthread_queue.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..d48170879e559fd7c00def37f5efb2a943df8071 GIT binary patch literal 19104 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/bindings/python/pycsp.c.4.o b/Program/libcsp/build/src/bindings/python/pycsp.c.4.o new file mode 100755 index 0000000000000000000000000000000000000000..0b4dc41dab0e324f944d357e33ceccb2c2a2d333 GIT binary patch literal 157552 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�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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/crypto/csp_hmac.c.2.o b/Program/libcsp/build/src/crypto/csp_hmac.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..fc67c42a36a990b72db111228f6c5fa6b002a3ff GIT binary patch literal 15840 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/crypto/csp_hmac.c.3.o b/Program/libcsp/build/src/crypto/csp_hmac.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..635c04c9b8af68bcfde62f5bbd32f65acbb7fd6c GIT binary patch literal 15848 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 bJc)PJ$v$E{y`ZL4{STA==XEmJX8->NHW&ax literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/crypto/csp_sha1.c.2.o b/Program/libcsp/build/src/crypto/csp_sha1.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..68cb3e86407ee0ced529a0ac079fe9b34a14fe2f GIT binary patch literal 11832 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_bridge.c.2.o b/Program/libcsp/build/src/csp_bridge.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..32935b3ec97ca5785f46ab1b581497ea37136224 GIT binary patch literal 13336 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 GZ2y0NNJ)zT literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_bridge.c.3.o b/Program/libcsp/build/src/csp_bridge.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..ff971a9cf7eff5f8003e0fda51d892cdce2d4cb1 GIT binary patch literal 13352 zcmbtaYjj-Ibv}1q8f)Z{EMY8R#~MKLTcd}KEQ23<+ET1#$&w5DL8>Z7c?cj)cu{a&&<`a zwEClGE#15KclP=AKKnfGopW__SMOezWeHs@v0D^0jS4XqF37D?Y!$1-`J!#;&|vq> z+YPbqIZy2ds_35Wtl7|by7y$P#@{>p=3B7+gVVVWy65U3cF%pGrtJ8Q9${Zz`b0-D zHT8Giwtso&Tt`V_Zhx@*z-W+7riH!<2L&d zx9L8)>o=dx&v(yCxba11pMBP@<}hY{I)A)H*k#lsm zI~~f#Q!&v#(9^lEOYAM6c9e+iX!aV>v`h#jT?oIN0VPs)TzVW6!)5tV<8l?rn@8RJ z>Sp->x@Ao*hTY|ogQAf2+X(S^yvdZ!HXAR4jo)E&`^|(X^OF$0exLu_FjCY-kY%;I zvOh0Y4d=xRY%O}uw3F!fcyHcA;Zqlh>{j^m_$yhRm8!3t)!UR>B8p>KTX^TB>Mat* z+02OW-mX-aD4xtDh4-XXUBnmgc&|T9E=uCl)au3;2wMIsT~wUjJK;Vcyly?OMVhe;Hrr|1H(4B?B?AJ7FAtb+Zo^Qynh`|{hQt$?ZbRfsJA0_}>+lQH3a zT?SV%f>w(D6B5q@{W6a6T~NxjdOs?sKFMi**mucUk|npVc`d4yy!~Dh{Yq|uT&Cn5 zXJ{ZR%O~ud@LdZ3A%$OtE?rb^PYd5p#9vdMA#oSP4a#CSMWcbQL!e(vEXzoT9ip=+|6WkuW3H)&Y3qm&Fq z`BXA0ie%V+;qyOCP!VjT{Tcs%e~(s+wD2(MB~vGpb?V@fHp z5b&f@%A{f|rQG@o)l4hpd<#qUxKdVGJ*1paN~QG9mISiHl`_W02 z$_F5_{2;o^!|)ySwv2}G6k$I9MjFG?Zxe*DXlcYD1CwK@wb|GNSe`18rTgU@<#oue}hDy|14eCB8pE*sFoKu=DN@S z0k!k_u_yTaSo}VJ5nW3$A#2G(X2ep#mfW|J5E*yL{UB4~1K6pR_??2mBL#y;Vc=2^ z2^rP$)$J0YSUApLI7QU5GPqT4FlD71o*+n$aOp<5FqOOsf%}zh>E>@j@mp(O*0xr) zv{m(1=*NVI;KsTLCd;G?=pkIJix+|yO0XZH>vDtz>)wy(DR&Vxs~@9k93$1~w?4(R20{a#(8}D#ToC4LOyA?)R-jwbp>uP-`6~d8pPp zQm7Z}6ccrt9)H9GGe>(N*2BQ6ouhzsd5;C_UId`JSBvpL*`RJhoM9n^yR{kP#pv6zs{prZX{}o$8`fe48VYb7#~o$wQXUXd7Emoc~064xw6D? zkcegX7t*}NG>r>s^6A*5(m@ndHsXR3wDV%%hk3EIDKD0-&x|SpgR6rp ztn#8V+MHZ9A`sY35M|?h;SOFJxGd09L2n$4Q&`?oGNCnw8>))d3Ecb@Rv-X#imb7K{RKP*mg|c!*p%Na-3+2Y!L9LF zy93CF&cNq3P`fqca_vfMeU%Ej+AD(&6&PH!OJ5ka_Ef1%!w@6UTKTQ^Ds=NAZ$6JM z8l8)&C1((7&Fl$_#;{Rlr1rKGmT*@H8;|@rQc*%ANyun-6$F#mIDpUbI9InSth5B4JQ=d$YjOSwU`stSD zNb|P3@nkADT{oJ_)ek4_tTGu-4%d&4jGSw-UAGp*sEJ0hlM9%Qy838lWK0OMiVSCx zvC(*V1TopiCga)g7B%&j6vS27ss%zzg*Ss&vEha4wOEXA~{%nraYfDBLyHiQoAvGgk_i$K^}-+yU3+*2_0Md*llQ zST8c_uYW1DXWBn!O1_Bn^hL(gBiE2w62I(`eM*by80?Sq_I2!+2GlfyALj}DkQcG29o^a_ zE3VBX?YOMUrLxJ<6#bCLk7fiR_8mAB>e#U(v^{)DxFJ+WzqV5GU8C_-Jd+$D71LlB zO}e_~ZK1l+P+ea(R7bvd(bS_xb&39-4!UOT=*Ts7lbN&~AF3A-*8olxaq~=n@gl*<;ART1FA_ueKlrKP5LGJye)kT>}Gs1K0>@+pWj;kl*_9Gax_b zVwvPrJVTkJ4Do6%=&}^`e37Q|H_L%ID8as@Fh@~S4 zL{4VOzqhBiD>6Br%TgEhILI-C*(A-uxJ{jtds_^>#IB)6VBw@rkH>V^F(RO)1f#i{ zi)|hIyN0BAMccpuk#9UA=aF!vv?vLGzF2X@W)`6PH#Db&B^e z8H&nlK0M?VG02t5b3)0sP!oxkENwA#8J5$#u~|fjD4F8js)^KGCNhE;Q<4e?o{?BG zLtC43^3t@T$%}}Zw;|EFR4yBjQFF>Bc49f5#lDV?OG6tD4d+sJPVKRETXRxtys5Dz z+^}tMgHn+3zp5eTvr4azL~Ivx{)h-IRDrD0+1Cqo|=mk zxB6{-PK}$7fz1jx9@j>}Nv6xeFZ)Osz2p<>p;H%Cbm-NLYhB-K8E5kaFJW%H1T0eA z3#l$s!C~awPh>!j?XnOczn}n6FSZeW_)STAQgHcmq%_I|GGq#J?ivFoCggYbtq4(o8(zdvgY|m#^INKL+A0= z7&raC>A^CxQ=Cj4Yg9BvE z-{#=K5vIoV&Qna7bNA4B1&&?fPWnU9JA=j_F4z(3FSUo!9yxxXU@{ut*s zXW-8>&j|yk-(0fXV&FSDo0Y1;J0%g=p0KH&7Wk)&l-3&_xJA%yo&vP zYT!p0_p^V^f0TJD47`u=Y6Bl)9^G%vbC&J58}@(0c!z=i6XQn>{4h#Zz$aP%R|B8p@%oj4ryH`u&v{&)G4MMW|Cxb*!u+oo_}4g||1|L5GSB-4eh=I02bmtPTXxaK)y;8PsW8wS3X<9U~Hs2CF6-wzFY{dGwF z4SO%!w>WV9&W|R$95~+p13Z8BIdItP z_vu~-4*L^4A1-&`u)mxBP>woq*x$nTaR(0jw_!}>Y6lMc>)C#aah*?TOqW@QJ$PEV zzjrw7k)IIb4;i@TIpx6NQlDGATf%Xq%6bKvOj6#Lz5@ZdK&%1(zp^4TU)A@&=%UKfWA{3+&782q)&bCZFe zWc+Ri&O<0`9(3U7?~mF3c>{lg@z)$Uc=S2bSqBcDU$gx@<2rATaZ=sOl!1vC8+bhr za&QTJrGbaozG?|PWZ;i*GHRBzJP-##%89!2C#%~j5a-zvH?ze6a z48^of6SkQD4Rz9dfq$gL^ndFjoM^d&{l8~8G*mG|wu|{c%>MQK!}uYkrvI-K22Qh| z8&?oWdmDK8oIAeO_O5t-aSeXJ;qlKlgX{ z&z!y1x4*si+G{_~KIaVXXlz>Hu`I#K5=(@uF)GA$D_yx>iuGcw7$d^HZ~DT!&qXA> z^K{1lx|B}jOA3Oj%!D@{YiMcM&~hPEFCTI5L}ZV+S6YdMcjry3#F~BQRro^vy~k$s z{^`RJcYZ8Q^geMqyt6;tC+%lCsLn5Zz*kMUh08+yjiI+z_5FFoy=S2Py|caNE%@t} z8DX!iOpb+~Y3h5m;q>uvU%fBfmscUJ^u2!aiO@4AeNL0Rn<{*<@Z4hQSl`o`eAQU* zBjuNEYPh^%(=q5riQoeuR& z&dIgm-K%}!1y5u&*5W~|S>#KmjEWxeLMvn=yn8~$2`^5;aPKkbaz;kJmZroDZm<29 z4HqbjIn&cJ}wJJe8d^Xfy^50)|>mMYqvP zY!eCw&QWM{#PvT#m-k+L>iz$KhDTRq#yb%|fF*q&IdM2y7hZJnhnX{o;1*@FC&%t? zKDG1lELYC7Ikh;(>rOwu^YOmsQ%(b!rGq$CpC4hhT>D-PJ>$$coZe<<%a4WnF`P3l z4EKFJ;@%y@6&u1>Mr$hEcOu;PQh4ub|2wx{cI+6%^bP1QEN3_9AkX&h1IY6B#>& zY{goY*aEcA=PZ*Bfb%Ik8rvRdPubus8=yjPBAy6j({`YBJN5)5a9Onh+;@wF$iqMh zpWJWd1|W61RH;&_c`P619#5gn@?_>+gpf}`RsojCD&A>TSm2TISICT7K=SkQp{vB1 zsVZxnJ=Z%1_M%weD?9|5&vyr0J<7fpWoa_6yu}g6bvWXg+gZ$ytz@y_1r&$n74Fyo zT^$axDBOkZ=lRM>?UQQ3C{n+w)M8N-OJ_vkZmH%MilTI?O%(1?sz(&{q~fA*uT(u? zuQ;#p3*FE}iM2*eBDaK)2%Ip|ycAPWC|a6xb+ zx-b04;erLEqV=a7b(p{Kc?*0Ph19~|p-A#eSZ{b)JSGZXLFbA`Z-c8}nI8$fGh}qg z$G@RTpKk`>g%jX1#^<{S>U%3e9t(na!S~)#*e+!|zV}lIDf#0gAo`U23CeyYe~NOs zl0QQ^pybmiSC+#?_=JT@jZ!SB%vXv>D)maqlS)`A`BGV{lme-2REp0!2_9adl;PIf zpmZvw*h)b=JxcLQC8Ly4)@~@-rj#)j&e!XdGS*rH%9oW=ZhZjOdX+N4DulVXODWT= zZvyQ`rBqpmK>3zZf>OCfDb-RrqLdn`{8%Y-tXHAV&y+G(`qr-`Zoy8fP#!{&# zx70#h$@QAtAms_j8TJ)yQ;EA=vCk2QpD7&)Li^W%v5CT)f=pHzJ|2-tg?YG$ibBUh zISXy7t0iTRyn5v|PhRuowLtiv20s2xgdGB`lhL9jXb1j-*}ecr!so+@E(2Fn61)+1 z9T~Wi8eC!|&%r6K0#`B@Wi@|GYEf46x1;%M4s{h66jQP+2 zC#Wow^;D%_ZtzNVym_h!7&GgjXx7rhgjm-cZFkTH}p2h22i;k2-Q}LRa0$kaN|6XbA&i^b8x;1c8*KV2G3Tow$7>% zPK$@25N0_Jyz>7BZa(AqkG)e7zG0yMd&&O*QmunHoSuD`J018pu)P%Of?v={Xc!8O zmTP3qZZvCUfErTztB}o+Vg{R_32-U5jwL(r0?9h?rsLkFSPxSGFIHrLdsmq5-2?8u z^!e_okTjz;Obb*7ZB`5uZcqBb(AiWZo&<&bovY99UpjSho=r#1s#`|jT&b?cn}@K% z1Pb}6gUVt;?t@nA;=-zzOBujl%@tlQY<6Q<_lSAk^>-(USI0g1W66F9bl*@(u{D5-nKpd>i z+64A7E$Reeu};K?JWSO(O+6a|%B4%%!3CIYPCwoR`Z2)tP&kFS#9o($EuJ(|a;>ov zAi_EvL~^2ymT;jOi%<(FGAM;nIic|G6hfC1|j##|5 zfl(K`#1%KY;z~yxG0zoeI%08yE4B)2q&2OytjJqBzI3EDs?ZO27*B;LDp~>%4E=Pm zstj(OV}!SKVbP)@RPw19MzUZ8FyZ_#PqKWdA!AsXRaAs@3zXp{PTiuSlA_|G`B0+> zK%X+`g2iLCY9%fMPR%8sxoX~jz$Y8oPlhdY-4b- zjxDpirLM2#WFud3$8ooXII|3Tu^3KV<7-uSfU|V%zP+^Ws4bBKU>*GY_{%#<1JRI zf;MPOv137~1CuKx$Efd#a{YySgzK#kbB9w;gs5e4q$R{T zMPPkYA+}tnwG7_QE3#T3o6iowW@a{7I}YnD3{t;k#1UCkD?7fphzbxpS2ZNW5-h~7 zEe(R;^j(O09I3_Q5~XS!g=laAmK$wO*PF|=0_d1v|$jaMrKfzS%hKa>G2U^EsvjerT zxXyvrv3R8ewXoPjP=VMg3a0uGvYsYf#htaUxdvGLXM()qD*r)NZXQsZwSRYOvv{{& zn-v~H)wT+Qd%cDN(@#0f0T!Pis6gzy0z1R{a}J)7on)P3Jaj{au&gl6pd1=v@oa)r zMb_rHL>6xtKveeJYX^z^h9Bm=Td1V(6Yv;Q#U>ViLy%Wov*REuzjt{gIT`!%sOu(+ zPY-aDwdY+TiyZu+BlbBJBQyja#}jQ`*_d6uZGK&(uC}Txp2%*i>PTd(TjLox zNof?Nbj4e%JKEX?^XIWC0p{6iTe`jAt}!NpVXSb=Z<&wDSqsmgbF z?;PJ@-yH|f_dT)t-AzriFP(Gcw*9AjFZJED`rZ9a3(>4qO?7^YN{4R^W?6~dSm3Kb zZJ*LmREVblimH91eK(D%YFW3>Te30F<2`Y0CeQNTZQZw|?7^}hO)1NIESPYSNV2^> zk`X=87z|#Ah_rP^;|UqH^yb#~NZJ)M0^hd-7YDc}lL9G{?u6NZ&)4u`J+iE2#frxD zA`(Hud?-%YTjJ?>Qkj!O6|oaC7m-!XkvWl21ZD+{aYX81C(;^C+tS#@4eQs)w&O8u zD1xg2U;59TBT+RmBW+#Dge_t{;01UmU)w_mQqscO_01camp3;_zG}S#m4pPo1uT;I=YJVNLw}) zX-jrxyHzL2EqvD>N!jUSHq~aQ1)=DE1Y;;87^=g5!H12_B9iQi;W(siKq!wTBhGxM zkj|Y0H4s$x(xN@yo{T^rIx?MFCn>~{cseCfHT$)Sk)C9-ONFRm`T30-aB0$*wK$&RmiCn7+}inYs8J626osP*~^t{S^~=#EC|dCo)fGIRCQ;v3H#g*8(N6B zfr{JNxv+Uw)zt>7Is#SA=|B~9`CQmSp;A?QIumW%T-B3GX6&|1G6iKR7<`e5rZ-2n zCO6v&(QS9P^=y~@mm3fSeT&@%Ga%a9Wyhrdp*or=b3_E^7X~$%h4FMJdOQ)4CVHSb z@H`_h!gg8(DIMKntJ#k=?IB8b3d z8-m@FRH3I`RSh#n7F?DTwc6EMiP5gvFegIKZal*+cs=Mu2JX&pUi6*Mo*jq2cwPsg$ zq>|Z040exb2KJX~xPgEV)veihS4^9w)CJr~7doad%aKh$QgaliYgiYH9f7h|AqC z6~jB$w#e3aB9`1L$5u`b+;7x=7m2`j9RdT8!F0oHuF7gvc8;v2)}7p@vI+RI2wb(@ zs_~?KAuTsgcY;Om-l@Cq>{z&^<2bcKEVHl+;a06SN3FIy4`S_Iku+?txI<}!0?|lr zu{8%(r|tGO7*eM`=r1N6D<^E=DOd6IE7J1B+oyGmWiKAChDcsKx($)M>f_0P5_p#dR`TG} zqDq{fNjSkyIqF_K`VEo1cm^CIc?Z;X30?s&T!%ukriPwqXz#^|G83>T(RUeNB zm3hU;K^OvF^|@$3*(|9I?ynqsh=ZKFS`9UK^Th=khN9x-i-dtMk$S$^V&KaOKVaZt z!ut(ewU;mWsgH}-6Mv|w;*~R&nJT{+vQZkD`*#)KIG4@z6#$09zm)?&1UTAfyK;>K zc2^EQei$6e{_!06b2;$WbKw6AIQqkn`23xv7?##h?M?w4`TPhi_Y|-Z%E4ci1HUK- z-bwcP@mlUlVE>Cb_%{)sUtq|+3iyW!=Qk*7z6x=a@Dh5S<~`}L9QN^XANxDb;J-%r zG{Sk`(C%7rOmc5Z>R3Z}V|n-uHZ89aa0%gM4qoQsr4}#e;H3^P^YAiXGo+3L?!i8? zvZ;AlLsO)A#fl3XH$*lxEQ52ecGIGJ9eSefi_YQQz01l|4l=ZJ`hceuEK`8<@HFT= zl; zg7}CB;ID#o-k%wtLilFN(f(xkWBc0(XZwtQNy7smvz^_9qaDPUzn^fngXNfRQ<;oI z0A#jvkA@?c?eN*ewDT+CBX_FCe~ED9kJs=I2}gc~hEIa^jS2Yy_`@Qx{00l{>h0oh!7yQ_+nKK6@a@EDx0-O%&OD8ec0QvxG-&u} z&CUfm?4&ikLgPQ6*}=B)57V<6e>UhGpVu{9w=lxfXm*xpxXxdt;bS!Z zr5djDV;TZRX3CI5E<8rOW*X``maNLWyzx#67`L@PKJ3KDm*YI(gojY^b`KiX& z;Q_$04kkY~1_{SYZ+C)*2cV4kl{xS;2*<1j{y1*@ z1OUG>7;w7ha|Yu0%yFFN6Ru@UjNd|j(@~6|l8|jhbY6HKG_9;Af zW8!{|BYcm79h_8gvw?qs?B8YJ^9aA+z$Mb;Jc)k@cd!mbIJcZ4SXm0&-WwlZw>kLxWPY6?ed3P=HpLwG5yKl^E2Ej1OHgj z#is_|ME(rt9C)~2?Ii!l8u(JeD-3))`4cj5-e34W$o}sjJLenxeS~i`@Ovl@wt+uD zc*?+!5x&E~pCEjXf&YqdzTdH*8;EzC!N*@zV)}`J-%mQ{Z08liPZ<0x*?HE$@jET1 zmks<)(kD^8+5URsPc`r;@v9Ad7wL-(oX`C$4LqOhuQzZ$uWT~#zfr$B4SWmP={4}T z$rW<5ad_9jXOn$?<;eZLhU^qmIpcovzudszBmXN5d=ud{2EK;;SZv_$6CO732dUi+ z2ELE>u`3Mx8>Dv`c!J`v&A@H4f4zZUME3U?coEq-VBp^(|8F;NJVRqTYT&!b{zC>n zhU`CS;GfdCyk_82lzH)Y1IK^2gXuHEQAHQ|ep*QF^Z5Ri_+^AMA8lZoVDP_7eooi; z2=RNX1qQ#I^hN`}g#2qZ?C^WEb_3`4Wf{ZHPo$SZTx;<8J>7nTpP+URYBl|PO|@?h9mzM#DA137ei

    !=;EFg!BUqNB$$kf7HPLoABQfj=p0YM$&lw!Qk`z;tvcy$3gwWL=}6q z#plb>w9wf8cxrbF;XE$SqqA7gz~3Z%jbZ0X+GqaBz@H=gaRcXho;C2h$^H()*&lvi z|4oC>_HWT}?As5>&cA9n#*^DUYTz7)hY9C)*V8z@Y~cJ{@s?rdeB!@j@G+K{h7VIY z+vn%ru?CLsVlYi3oX5*Y>!RA=^Y@h%2A}U|Yc(8g716k~XgJ2_eVT8V8~Ah@-&Vre ze_j`x4g9<4JfvNk9c-816YbS-epi6}TMRqDK@ieI2EJUu;u!-^68^G*f1U964g8OU zd(k;a+^&uFjut;Jl7{44m(Gy9}K7ha(2g=Yf6$=kwAF2F~ZtcMY7+x9Wd>;QG(&WdijV z`-Fddt`@=c_HOuj8RVIi$~##~*KY9u#;J1fC z_!%So_7HwtMP}_z_-c&5Mg6~~02shf@qA)?^(0i$JY<~0%BuWkhm?8;QNoc~1dw6; zCWLi)uHrWhOw-{Hak>p4BvZH1F5_nVc>X|}X8j(j&+CEfbNj4^KtP*w7@(Z%^ZQ*c z=Jq*ngaVeCgZXwkpL|H`m&;6UJroQXzZzBJX$%}B%rKPfKgSQ>^P4sS5?77HEBwaY z2#m?a=Pwh(dcWp&jd3u!c#bhKtp7SWNZmk4CX;(5phNY48wM5<*GG5o-e>mzTEI-3 z0Eu$?AXATumQ3zGC^IpnZ>0LY`ldJp7r$!^<^K`#pT`OP$L~L;|9Jky_PL)R%Jd?B z42Q(e%Sv;7WuK2g!BF-4rl=ac40F}Li|TVZ=SQhN>zs4DtUn3@Vn&$6&!~Q-QGxr< z^&bXdsQC3${7w-Ok5xjx5rsJ5}nAEx3}h{tID;`0lJ)U1!kY-5Q4BE*qOnTbyf X{|#0Ceq^ZnKVG5gKdmz7YS#Y;6%9r6 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_buffer.c.3.o b/Program/libcsp/build/src/csp_buffer.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..430fe1fd07d54df81db58d4103c79910b54aaff7 GIT binary patch literal 19608 zcmb_jdwf*YwcckYkC7xpAP7NG2M7?6JcdLFPZOSlM1ly4Ry|HKC&`p#Ce8zbt%41p zX~0YDrM{?0YnAq1tzPw7UlogpRWjP9-fPX-*~zqj+`E6| zoVC9F?X}ll`*HT{bJ(=Faf!#W1Sd<(7p}&r5J#4{a=jGm#TYSKgnItu3-!%IB((KZ zs`!smI+QCZ2&z02UV8uvmPbN;Ig`qf)w`&yG`K(1C(8|gyuLg%>tr$~xc^uK8{e_I ztT41ARaP82w5Y5Y&BMJA@5*)`prNh%Q!j_+)cev056M=9diEEG`WnkhBcYl?SyL)k z(R-dRKd|N!aH2HSSAkXr_~IMn%jDp%H(xKr@GbWMH?-q?EE4K{uJ@DR{@^KT^1W>c zspbY>3-uli9m**~8u>S>EVT8t^cl)d>PoT^JQdt83CAuB^uwD3)>Ff`>_eY- zTy~uL{;xlV`bU+ePTyPy@%@CFI(*BGKsz=yH0QFDsSyLRQeQq+(${o+>r3e|fDaYd zQ!j0OskiBPO6JcU6x6AkyR!yWjqBc{!Plr07sE z)390&wqi2`WLA#A9c#z*{Ql(d$FH9}{0E=PjGmvIf*~F1mG)9CnDrwc)SybaISs+r z76<>jtoIMYA74Cq(T=i`MYE2tFAsT7SMJDGH1__v;nWKl+feT+A2n!E@9&Pi9DMDV zFH;>%792Thvh*HyyRi66S2bMOa8<+AFl~bG%V`fo28?|={P9i0T#pX&8qoUz%#Tp- zTPN-f_5Se+9CmJ84v3|TSI-VKq*6|2S1OQ-2f`g4@s@DP0XZJ%2q)T{KqQR9%uE6+ta8(4jFIlyC z@$A5wShyqF7IPvxw<{ivrJMw^6>C{+J<$F!XMuD8oKHC6$i_fx!U1R50A+#`(O4jz zbOOyAu_YjZ%c>6GzEdDX4)&Aq$#qvQX;P=lOqDA&kA>YYJf3`c%aJ$l9E5xdvhpxT z7V%EPVde42(W8(lwSeU2B)^5_ zhLuDkBLBDOT;Zs0xE3q(BY=0hj1Kwu0h;vrrU0Hl4lbj8zQ>@vw;bd#Ac!Nrj~{^t zfUL*&*91aJ{&XLRJ|%yKaN4ZqVU!WXN@+p+dOW`7X!a}85DV9{~l;V*}y;5?d z5>iU8R8}e_PbzDb;QW+e> ztQDYqO(~_;-@sarQpQ>NFcxoC$|UQXK-;O53TrPYw=1PmD)%U*N-F!5QZ1E-lrr5q z3T1w%lp5*Vex;mm6+u1Ei?NU|e0R!jDD~ZgjZ~rBiz3P2#^zEt+=s0#hVFb4F<%Yz zVKL4ibX)d1qS%`fJ&Vy2aR!jYnRxMCU?HyLdQEPS@;Kz2b`#dA#G75QHzN)^Lpo9k z^i0k=I;#%@f6kfscP@!3qJ^ z$!NiRv;+TOw9mqx@cD3{%fM9^RqljUM+UB_8mAb^({YHaz!lY?tj2FqEy`;A7R^9@ zK$V?|@^~fJp*%s!vrwL>Zc3Mn zt?_TL%hm)8lycdcDBC8@SY=3oS&jXB6hyU3$QW3Y?gJoz<*f4G0dyL4mr4P=SyOTL zx!`ySzJwIE_nP1MSlTX!Ksb} zYj+?YLWi1_Axx6$i|@-;38B>gVs-KuxwMl3EcjDcvc;5n1W%dH!W1T!Gx=&C^am?- z;HWqkHS1o+-X_7?{Z7WOd)e`+uptoEzhRE2|C;l-%vYd|*8(=pT4Pm<0q`z{r&+7r zzz^g+L7bW_oNZwKb;()n*#MPX43%Ws&<~j~>~SQhmTY6MQkj-uqg8~r4Q$B{YDoa8 z)*kFmPydyf2HXj@S3+6v3z`cRL#9!)+*n$jXx7>a)Jkco6Gu&z6jN9Q4S*}ScFgI) z3nXjz=Nb2|z;c)Zc(LpO?p!#@UO>+Kt0c4ape`6eg-=&V@mF3lS)$vmmE3C@({;HBn*JGk}jDp+;4MYHYpy z<%ckKJ4T+nT=NkJZpPskfOj4i!1OavK7(4IpjGE`FvOVxa>&d;w&xt|5$`f+knA|m zIo|=D#0jt*k|?`nCJrM`CrPk&;{=})qpZ4(Ak5N<+lV+rr_E+FoI9rzT=4X-%(UZ8 zp#KCgJph?ZoNph<%r%}QQnJmgQ9y)AIf#^rFYpvY(*+6+tx?+I&-5!kuh zw!%b4EON)kSXKg$%F)8>pItDg0F_+IhAzt+4ouiD%#f}(=Lf;uQs0H9A9biu+gTCpOR0lVZPS;27E6gdr`0N~OegQ^223)=e_HW}W#RX$kaHou2R)T#{UwYdDFg&5s8Zrml zJhAs{mKb5}S}-;UT3K!;#2)CsNm>n{PCm;DmaMYYj9FW7x$KcCxguDC#ByZ?O`NM& zmT>~BnhMsatI*%`pbU(epbY)AuY((&(*6aIQK4H{RuYg^Rl1(R%I^9FoB3hnGn^H% zIKmQQdI4A;nU6KsXf=bkwFS@yAOt(RscpT@$_z56JPV@!Xe zJ2W{XlC?b1e+@Q9{VIVYfefCKjbxppH*`h3F}X_BheMLZFhQyyYwa$P#is`lNy*$U zriRL2kbqiZ&=|OdC_kXPC9Y=iM+AAr4V(6`a>(Unsv&`W$#nzA;&6ggdsrLo5?SQn z4;`_8P;l3P8cf%w0igN_o_ku-kHIup^ieB0I(L!&?{qgqq?bi`EX~hxbT{X#$=?Fb zdBi$sgJpdR&r1sua8R$Ttip4ts&q0@6^*rYq$5sMcijwoMr}n$G?wnJXp5z*nxm=Y z0E$vNqRmxpEiHrjGue~?^K7*x*=49z;Y16JG{~^ksc2;j`jkv1qOmr+HJ(UCTcb{- zvK@n)+SuhJm6%LL;4rWv4VRdXfD8eI+=$Z(G6V-rb3ynu0}e;yZV42zz{aHQBoZCb zWJ={>sfg2@ZUYrcp?YoFNjsqCN!7)pu_zV-uaVU$PlOc>b~-d|VW;$}uo|Db{K2Ol ztiJH06Dz*x@40+$w5`#1>x&-=PmU!o6(D)??#}b=dZOp@TPu9sJEr@(eOvY{_Z_+L zqpKRHT`~R3-MdcpT;aR*!jE=6IJ*%GR{2)ot<5(YZ)s^^ZJw_TwSJ|cs1Q$HYo4#l zH_AKGx3lD#l0SIgxFPW5$5$lUy(Le2V{_-EgKx}9UvvQ$m<1Q_OL$q2m%H#X4=>9z zmus)S=!*H?zr%jenm+ZSZT)lRRpofRKfhsZj^%y8nk(hGApeK8);la!@_@&JQD@un z)>b@VAi$-A(ZHQCecpbbLx*s+_#Nk4#xzlh64JuTRZXj#7B)3XzN)-OJDgZtR*eVm;9Eqr$CIg8xYH3}xD8I+q3YI-a9dJZT)b*k6SNOpM^}+KO`MM=pKpNnL$q> zt(gub5LEV(qBYtYx1kMfsdlZA6kOe(jDjjp?wK*{-5p4k#*N%CxQdP{T4OFxR zDw>jk3NSqn)+;Df(YkWkLbxVV;g)q3U5R+gX-UNsz(_!-RlEn(hH+l9tZ}j3)sarh zsBcI_Q;rQok0P3s3k6i4fRPA6(Spz(jzv0fuwu}K9HxN**4;STZog?gy&=BNiHT09v!!dJtWvH_&=KpM4j2{T<_;$!>kZDJ(KB7xIOZ_W@ig?Y zJNTn9Tbk&Cpg@f&fl+sos=ablVsq6ap~`g+mSr0jM0lHlwr~(ZQ4SbPW;7PG_yPt|3`}*) zA+~JAk|v5j4k5P*Hbhw1>r)sm9`ssZAWkYWI3z_?rxS^WtDN=WSk($=!=*UmoT|1& zJROU`8WK*yDpLi|5-?xYoQ`%xw4p#vz%>Mi9;|TdY;211Q#Fq!5iVTDER#)=BSD*J za+*MxaH+w$A}6(4_vEz3)v&Q?;c~sX38xcQR$OD%^c8jt-z&)lct$OCpX_nD1|}l- z@ancVL}QWo2HCfA7~-mMLP%v;06N>Z#C*xt8VAZQfku3#VQ?xw}!w~i>~TV zS{;&d3DtTBAEUbanRN>ncI>BSh-DhqB3!W55~-DT$3djE!%o5?i|druDG-hLdPj3m zHQH%yfi8u|5iIDk`OVOLt(f#eEM2&8cA$JsGceO?F{-FZOD%Xqu&%PY_FRR+IRfpw ztm{?@tGn1bvoPPc6SfA3kE1-fD_`U`IAI+kdDUCxK{?*c%aMUuUQsjx040WeY{bNj9Zd@x&xo3h}yXTkT9eYPvt0Kgv2 z!ha?U{_`yOJAkAA{L5LcC4imC!Y_a+G*r7vv*1$!NBjJ%n%AQFS@^4o&*v8WUM!M@ zzn=Jfpu%fJUl#tI#4n*K&u#fW;S&iz4DHACWEMLIv*53j9X_CwYa7^kmvBDTV?VVg z8f>B52bS9M&^}#mk1HD&RtvZU@iHARHF&AT%lUYjftQ(hsnZOp?Si}Yx0g0HEof-8 zo0crOWbtZyb;APK&}t7fdJdu|>Y16@-sAo#vxk?PAS4aml?~q33@{<<8ghfG|G*ez zdQg-2*MxGw{Eb18%QRsCOSk3jg4`*8H zrNo5i0B{(QdE)Sji`ZH4_t`0xNT8~{jC&~Uw;^R6V z(D)I;**@CCv_;*d-{V1M`;Tb&1Pwn(INC4M@HaI)py9k8VZ9g=wx0*{2^0D;3H}%# zNx11}na0N#H_V@_@keU-VvVocw>5r=#&6HU-=OhFY5bln{O@VF9=8*k9c(lHVH$=F zg@iixHMi>=4cF~75^l!7nQ*+FuGzU>!$)iQziK$VRLRu)EyB%yc~s-$7-m18$-;j{ zGa--d{7%F5xcSH+-X?1N z(=}X=PbJ}IJcn!cr)hS0r#uWWeHYBnQN(d?UV#CG#Oo*H_mN#3+n5-?pZvfvh6$$` znUMOq@~ZenB;yVH0u$SrM|Nf^ID;Q0V`|^(@&kllXz+Upzu3TECY@i8alMxi-eT}u z$)9!uUrt-|>kRxpT3>K~iiz!yC49SrGdQW@HUqzr>_2Sa^9X;+z$>X^Uoddo*J1jZ zx@GG1lO29uu%GI81njd6K8`s|pQu~L&JwEkG^&T~_z1`SEGEVeDpkY`{BFW;H1OY2 zKW;a0p8vNQ_yc6;h=KbEf5*Vjqd1JDdf3k`G|p=c{1w9M4SWLG<>vz1xr6v?4ZfH7 z5d&A>z{9t%2EK{n`Bek|9_cq5_*>MjT?T$L#o^lqUPJ!;z`)0o|4$qE4D#nC1K&sW zzHZ<}G>?97;Kk(6aRdL9@XrnW8uEvqFC6Es|yA1qX8V`F7e3zmNeok^6*pCMceu(&w82Be- z{|N(sgZR%H_@&%m2F|a`j~I9Zwd?l={wl@cBLkmK_W5Xz+tp8Y3MrrQV)DP#z&|Gc z;S(yEn9rY4R2%qe@?)-ne@1x7z@MRdR~z_kw2ob4;CGPTVc?Hb9J&qMA^Tel{7SOl zZ{P)FXSadhP5$3+;P~4B(<26c3)z3xz(CYODc3zbzd^%;|9}><7F382dQPl5wbP&V!7Sebt zF>v;0JmF{q+to<*O)>a%^(^11dmH5{pL z68|9$mm<~sq=qB)ed51i;2!GtV}x@Y#!&x$Xz=;`*GChO`5cFl8jg8WsoqH%j&ZJ{ zdTR*h{_+$5VgsK@xNX?!qW+B=_?u+^Is@lff8sS{;%}@r@aRYx`!Qu}&W-5QST52uF>JN%L2D+a!Z?EKQeuOj@YfnP`X=LXKdsi2tTUfxD@exJg(t5q&kR?{|x~Xs>r_x6-cLRIPz~I{&^aX{1}oU&D3z@4l$f4@gvTb$*?J^L$xp;5^^?_bb}KKYqUN zH2A##*=OLqk7avohxf6E4L(0F_;(odc^_Lx?PZ+z;i59Ru@gS&f_o~V?(HlkoQ`m1 z3cq=(lwX@wHp6Fbm5DeiNDo%RyH-h3uPdXm);Lh{t6w|Z+zcO+vIgI~4Pb^7;aD4d zXGvt%G+XfDw8Pm@m8fiqcXm4Pp;2WFzC)~p4;$e-MEIbI%sTDxHWt4E{lBIF7{E~R zcw&3?B=GNR#wo0<%Kxa1L$yAGC}H1JbuXvqF}~}t3bBF4e+D4I ztRMFoXwxj;P33t$upO?S^&kjnGxL8WDTB-Nc`)<2e!efJ@|@3iKKK43&0og39P9NU z3>Ck_{6dyCSQtO-Ble%;cQIh5O@Ksn1YTj^Yy`&S+Q2a}EcXqp5YiX_qZU z<#K#~n9A!Mly9T*CeGy;e*pxG@Le)v9~%X3_Z zsvC>^_e8u3@gf?BgwqH^YL>_Cv@yg15n^Atyot{Y{|!~XR~)LmZ;2{@Slu#Lv;6-8 D8jV7` literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_conn.c.2.o b/Program/libcsp/build/src/csp_conn.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..4b37422c04b2eb2ba466ada937a9a19577fa74e7 GIT binary patch literal 37800 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 J$UEBQ|1Zjk)Nud+ literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_conn.c.3.o b/Program/libcsp/build/src/csp_conn.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..8e32c550ac84e9424769b99c5e18ad3165f67885 GIT binary patch literal 37872 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 CwR1%P literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_crc32.c.2.o b/Program/libcsp/build/src/csp_crc32.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..087f8a6f0bb5a545c9da185fe34675ab74c8ed0e GIT binary patch literal 11960 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_debug.c.2.o b/Program/libcsp/build/src/csp_debug.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..f671dab84a2364279a74478eacb9bcf330c927b3 GIT binary patch literal 13752 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 Ib6x*`06$?mTmS$7 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_debug.c.3.o b/Program/libcsp/build/src/csp_debug.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..12e08aab65116e541f4560c490b8e902a2a425fa GIT binary patch literal 13768 zcmb_jdw5jGb)UPd$D%g~gLoN%7Z4AvBoH9{z>?6yDwZW7BpxYnS*`AhHLG2D9|CMX zhlfp2DH!_M@rzj432y4zj+@xA9Otufh~v0+W4FZ#Y14jg;?yK=`r+8M^Ch#YEt;;Y3Cqt|j8IDmQ0yP=BQId^fx|k*cM{|)2 z3^$zX*$^21FmT{MF9Lt(*}!nOw=po><_)wBw|G0-fZCk8wsc{OcSq^MHt%5R!h5{? zL9%q=Dennce%*UomQQ$}mgO_vv$Fi2_bn*<0!MS^RRIwIb5(U`4_(eH{qi4>KYA79 zV)*y_uXl;kJKqEP*rv;)lb}5Ghuqx_fn&v39|+}~3>ZJU{LbiP;NG7znuo>oQ8yOl zqu7i0i$?RY$Q><*g6sy4J>$iQyxQU|D+3tH$+cL0Eb1)_45z#mfnzCeZQy7DGL?b5 zUP}S>o51kDUH*snw++9F(E#CnUXP@Xws?!4zX*-i{bS(Ra;$p^!~MwzN4veA;g{>q zDtT!@){y=UC@SffE-@7VV^w{DWhySITqSzo2Uz~uwsR1n-NiIM!KDS!U}a69wb~Y47G6O zsKTQP0|y1_3fY$XFCu^_@)(l2o;=TS6jDa=k(Sjt)3-C3 zd!ZS~JkPz5=RXaZ2Qw*^SM@rO6W}M#!>{07$naN)8bZiERpg5~&=nbqe1RT0=^Vlj z1MG3oWz<0EEL2E47d-#{go|`NA8!I!+421G2#`wG^C{A0(vIgdq$?EtIntGizKnEL z31q?}3}k8*V@Re!F)qn8DkeuV0mbA>rc*I_lG&^nkMS;exI-}o#&3YxshA=I9UfFn znPgImnPdz?%^t-}G3tTYub8PuD=-HYQ(;^JYljpw(-5#2jwoiHaXW~eP)xOffxKTa zKFOR`OpRo|p_p39Jgu0e#u?BVRm?K!+gZgdH}asJABa+@7oG>zaC%N-CsimPL6Yc4 zvAZ-3k6~}iV9tCSusqKa82^IfXavmB+{p9bXi9VnqvfCjX(DEx8x6!2-RPj3B#k?j znDAw6Q;|n9z#Xz*xcW7~5r3j#@*xFQFMN^T5 zDqJ)bo}vZIfR&*wTKFJ9L@!19HMFnfl9`y55cdQ$QXyPvog)X+_+sX zU4>A{0X^k~T}mn3ZYwD3DUx+q-);-1SomsbJcR>cbPJ`~z?vs$FEvgT!Jes_X<$ua zaX2u|uEgB9mff5q+3Ro*bDunM$6RDFZBvDK7q;JPQb}R-;o!MX9=XH2Rc_2w4}}q) z2}1Lt1kdN1y#OpQdW^aSMt3HrusJPv7?4W>jqHk`kxr_b=hv;>>9FQXg5mY9A<(OG zdc#i{W8kl|dh``#!|BXI_Vx_aEn?k3<8iR6}o2&{T6kk6klu<)#u#RL>ZzQ8bA%MBn3=Ridb zXcUzj?vlbnw1aqYv2C;gYD<)Ut}+%(!?vg9N@pv|jf_9joW@)gLQJn0>!b~2X84R7r>P(; zn1<16thldP+M1bb_rnDdoaGd3EgvI#wL=ta&W4|;%ruMYa~v#G&n<*Onv{<|UjsEB zH3;aCca~9C-evSm-CVdu#&ce-s4GVk^M?-_pj8Jt3;z6|AzT$Fn?a!p70?(fECe~B zA7ZV6F$<-E&N*Pfnqn457@RgFzK|_eMNlsl8tXs=@y<#Bg{Ncpi8uj zFn!j>R*W$Hs*NohVfx25wtR%?w{2|Y2-E*em~5CC4wxZ2IZE^Fo^_IjUDQ(5Mk)*N zET+;G{biZ3ZEhpWa(Si52Cm|gwG(6|PyCLn#*|BdljkNljyn_2Sto|{b!2ZHm912= zOS=3wq246|kQ>GyVUsiv{MMEF#D|DbiXfzE+tcak@!;I zPK-!u@1T`bB*L*&bsDmmjr3VzpkWxHHkjyF^!2^zNHkR)iLJ&sfX9)ztsqG_q$Kwy zO)HUzMv^I2mvLgJfTI<%p=dm`3u@uXjV!37tO3QtiBOFfG~ixpOdgr*+CJ&`@LFo* zoyhalHEr;8ZKZJ@Qq55D!stiDQc9bhon z+11hA0or0P0izlw(JlVAwvJ803`e3?ES~AM73&kxc&xt?-|o$DG}xbn*vPSt#7yo5 z+VyvJb#&SOqn;T`C(xhtKuosW+_QGAA4KBOJ`MwyeR0zcp5EJVIu?T9st(`Ww9en& z-2^`1oLsiluIOoR@prYgw)-Kp(X@(PXVaRS{N2*0fnZ{nm5|dsCekqq3U+E;dr#$> zRjVpj`j-1@E2{@m>6mpxzZJ6*kr1%BT5f=~S-qmZvbw*rx+7Ux4TE(9tWZ#@4tKV$ zfjpTChIUmCCgLe8l!_-nA^|}Y@gXY_j>dPJuuR}*1ywA^w2w1vZEKs~9E_$Rw!rO9 zL{gTVaJXQ=5tw;NoIY~8LDz@W(7|-vCFI6l2kGB|pU z;F-^0KbzP5uRi&KPq1JlW-Tib6E=1>ZQ#giC4qqPiiF-5}aH|03Ukq^fc z1HqK28L;{y!5V8Q7^`Wwc5lSxVb$~};^|l)>;l15Bp$1Q?GuKr2A3JfVO^Ks-;P^3 zJUD9XF@??BL@kI6Oa?O?j6ipIVW_P@bxLk*%^htmawWEPKu^#}Dl%Y!`T$S@X4)Re zu{SH~DbRB3lY0?%PIgAFY%@6Mh;F|ly5Rw|F&ONtQw7W&opxtGlPMAaHJV z8<+*hh+di8>bmWU3b#GlW2@ZuolpjsH)2`hFiDE!stf3hxTM_nby21QUhTk}%(!sR z@m3?7_lJh!+O_Z) zF}s_Z;X$hl%17cjCy=oZMck$ENs~EfW!tw*=M!ek!&*KYuh_8BhCGT(yXrBO!7`g` z1{-s{#I>Ok&L@oBrdAwi8g!nZ0 zv7Oa~qkWtojCVQYr#tXo2aY$WEFW>$!3%lDV-9)TpBdldz@2^`bKrOx%<^9&9Q*5x z&*(V#>*L^{E)(__fBcG$alyp+&lGF#l#IVjINy>o{s!T^#u)!8;r!fU{1=4t4qX5| z?;Tjh_7TUu?IY@s{MZ3JTO?Pe;q8Ra((oD@_eC1cw{^5e>hE#T-E7=NkSY z#o;{-KTLkkpmw<32+1wb@NUBEHT<{4w`uq>lJC;+sl;#AaO#%WuHp9*->2apk-{w+ z-b(EbYWOMY?~sOHkk{&`2k`HRyK)1PW~Hj+P+=*0k85AJ**LO?HlJ^86)l#DSy#=o6;L9XOic^YC*T z&fg;6((rv0pI>SCEW$5q_({Tx)n9Aa&x`w|H}Dr(grgXBN!F~;H2k;J?tq4~o!d10m(=bZI;EdQ8>KS%v~ zd>s65HT*V;&$Hv;-_!7CX#JiY2d|}m<2aIO>CvNviJT7vNqK&M*XKhI z%_AMJlvgcS|?Quu|y z*B49$g|9c66uv|p85FPc)d7n_3L{3{Yeiz=IOyT$W;58^o3Mt)RKu5@F?=u)jP+Y! zUTH8Vtt$w=l3QF2jSF8WJ}_Xxry5@jKEe6mn;v|EgKr09*4k-?6G8Z<@c)x4!3>TW zk2hOwB!bWXjMFePEC22cr(UCtD58QsHtZ(_JVPMKcQ|;bg=s$g5U1sYkW5o(UOML< zR_N_70Ss;G`jw>5?V&Cvov#B7Z7#)1M`C@Rmt4i|bLoc)q^UU;6H5r-esTpZQ)WdY zP}$;lKVI%ZI-v@Ar-x(2{N9h>q-B*OU5YPPyeZ1$&=Ko-|RJZTz(0?3D-TwoCWoy5k z`px%!%G#B(cyE@i{nJ_6FV50Fj&HX1@AyBq|Fv=SpCbKlYsNKJJUov7Z;}5z&oF+t z_v`WdCbh4}DL4@-Aid^%*Z|M%bNOAubp1uxAf!dAuyfYq@*LDKZ3_X>P5Mp@XehG;eP@m+xTCk`0XJ7k3tj}>pfAqFd{J_sq$HVLFnB|{4(g7WdY*?rlp*^jvI zZQ4|^&_LTjqac4ESfq3u0U5D6DoFXGS_af%0R2NdiVQfYARxntFvv$e=iYO7H>aDw zyfbLG*jPdpE(T7Jw|g2eCho zznS2SguX_CcPLmVYLm7jymw0Itr4|$AtAhn6m*H&i9%X(I%_vr z-TW+23txtZiqm@+b{`Plf6PK1MBe*mS$ykoiGAlW5Jmklcpw?V@J0P`cwhrT^!`){ z`a|A7z741WRlP5xNb)OaSKF9Q3h!$&xTXYJDfgd%xCq@ZpcvmpmoyJ9HJ3jBW1vv8 z7)B@;*eTzCjzHpNPreVb&_?pd-v!aH_)ky{Dfv^Bo0a?-%3&p+MtRK=cnF^`5Uf+c zkf28amjt~EcqAB9z$?La1$+`*r-0u$1rhF4pw@T=z?cGc1_nH#Ku7{dfkp!t_ihE2 z7`Q@jQDCXD6~I0PnvK`N+q449jrRc@RA7~HH>lmEK*Tr<;M)pBB{-r$OoB%gSSP_T z1v-r1fz6W&bjsLHC~%?iU+Cus*;?59l5G;rpd?!G;oD>&ujJkexlhW=P^abq_Nl~!WpSn? z`j=rK^{vqVm%&-9s4=0E2L4uL>Tib!{_;}#Z87gSPpXunR}JmQaxfgN}6B*m%@T<=~5#Bl}#;3EF%KOu87t)$nNqo z>w@!4z z(GL6y5MkolWg1rA0lcgE?tbWVRa9U=xuEJ-PdU``bqTd0hP5cyFi>t$bRN_|uT77D zMf6~W11W}yxSeW4+(1&PS__igSVF$GOT2bmB1q8hei)W4VXE7y9;NzLs(FQP8JCE` z(=a}UgkxV*Q+#N~fim{QjV=I+RdL))g zB+gX1NLvf=s2wHji8-EGTP$8kj0pi+X3|O)C!(;aVarZUSax&_6J$F{xRykU@W_>z zq%{gMoHA&qmEmB3(9-#mmK0&D+f%k_6$+WO?Wi`@+ek455Uiw=bk+joQwYwM&JNWG z8&pjbB+I?p*f@CZcK06Vg-6|WqsNb5yW#P*WA4eQf7)Feg&UP&ps$H|V%%~}N0?i; znVYu`4agp(Pcv&}^MxrHQVwF0Dt3I*GOb)v*kk#E6UJMZo!(=C1N4?oqNn`msBI~a zy9#N?GAA4`9?is4wlGc1PG<-8I8q!nN8+|6tz}Y82S#T*@$3ZYws(VWasql2W;R|J zw+i3|f-P9_q>Mym2fWw*(=6YuQ6xxz7J^0`!4K5!^z zCZ8Br9Ku-EN~Ys6YcigTU1{z5LOxT>TCr3iU(6*nr|A!R`-(+PmMm^Q%DjdXW~BdKs?n;nioP#a(Y zgHdD@{3pgE6NS8EC7gT#+6oYBX`al9Oc4?>k%xy3X@sb?9!yGy*$#<;U0{~| z>ozrc5G}488L?aoI7c|2YN^P@U>0*l+e&tn=UJ{GP{Q?st53#^Gb~q!nZsMNjJI7? zV2aUq3bQ|-&nR%Az^RAzkc9YBw1DRu0jv#EErc^PRG=7ziTUpC!u1KB+q+?rry=!u zSO#NpNV#mM;f=s-!V;C^lNq8N0g-0&Nvk|mm4QhoK9aHYd}4m&&Qs>)GeX#MW2k9^ zL&D5hlU4>&gx0W0on*eK(n~V~(3E}QN{7(UG6e@f))r#RWtUwXUNbyW%sEB1Y9pOR ziQ2#3-VtF7Wu`2-@!YLa+<44ZDQ@~Qt!!EdzyN+Hk-b#o-41zO zv~&USVQT258Y{Pele}nN zK3}c4)%E|3Cby_RgWCv9V@3Y;9bg#vYTn1^;lDNyUp}Yc2r3;%raH6Ac+P=Veq~fB zRK5$$EkoP-`-aSIn>X(mxW>GuuYYL3l-}pO=_)sa9yz{HaSiB8k^Gn;4)?$(r&Ym^ zJ}g>a^O!Fz=mS5#G(UhO6s@oK%nn7Dc&)#49zI1p_n%|>+CSVHWT}Ox{5^xPUP;K~ z4-6)4G5L`QSo3vs!;l}66?_}%>--=jRgi=@Up|!|+h4`BozkzUq@ka<38SfC@$M|L%*8#@IDb8;(zK{5a8GoGO z{4wKSA^bGsPmum|jDLsl?-{>^@ZT8UL4Mw6{4*4%o5rW}{}}0gk?~g&pJDuaMK_rXz{{i_q$$9egBIEx=_*2G{8&OMk+P{bN8W`V0xQ+38O-C4?r4H6J{wU!A z#y>^+S22E;@^B;L?;xCJyh(nFjPKO>WIX;(ishS({}JKCjQ;`od6e;K;(yL~z0XfF zUa#Yq82=^m^B2ZnP5eI@znAzA8UF&!qlen{{O-{6%lPjQKAZ8Ayw2Aq#{ZS{KhOA2Xe zznb_7#y?4Z4l@3Aihq{zza{<08UHWJ!&Af~L~$qedy?rNBK}3DA13}3(|?Wpzs~eY zUA)8e_50()3Vj-qGzrobSkL3%$x(9!k8QfFX1snctgYbnodj(*5|3eHzj&|2GQ@cK z+br-Y#`jBYA&M3L@t)(M@l4Ib-@4fDV%s7r*`$SEhw0pC9@?ZF9~miFlN!P2 z;2h0(A)ZTFV6Bujs_+Frw^_Ow0ua$eKAW}RSCeQCezJ(duOIM}1$^|9TWic5EyS~y z9{2xShrt2nOy^ts>m^~oCa9(~m)KU2aO!(Yj1rE~h4&Qk_!}nL>baEv-2i+Z@w9yb zsq(BASk3!i3+?EW+rLV7N2u0SSPN8lL(P3+)2sM^qW-+!1IK*=CEg~*UIZ0|>+XX#&Y}8R%6p16GAM2a-D>eS(}$j3rx-t; zqdfj^0Ea&HI6;)<9y+A!(RoGD{p7pSWA)ONZ)3N2bLDS_}j*;jHX zbKNJ1b1}u2$bOLVdiwBYQ*0Na7%G}oMyiF dff8%z{5gQ2qVVyfS~dGYivO1twkUG@{{h!J_6Ps~ literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_dedup.c.3.o b/Program/libcsp/build/src/csp_dedup.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..8bf285f7c2e176900e9d4f3f67d61c88c8c34aa7 GIT binary patch literal 8856 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_endian.c.2.o b/Program/libcsp/build/src/csp_endian.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..a1cc8950b2b47d80cb0db530e9af5c9f38b7f675 GIT binary patch literal 9144 zcmbuEe~c968OPt*SzzJr_Le&i?xflcU@4T_y_4&S0(t>~Lq)0P6jJQ5dpCExx;J~- zokg@jDK(a}+JZ$2mPD&(TWu4qnx?kKYKcml(vrre+9r)nG|^yFZEK||4Sl}vJkRXx zdrSXl-{fZA_w)REf4}d}ePP|T>m!z>Bw6YTRV@isYUf4Oe4oztsWvr7O`N&=&Ex!N zK5_i?Kl>-n^ds{TLlGW7{l|$j$4|e3#~(=P`03x`Inuo6)&4KN7kdXjC$3r){abT_ zo?HHlpg(NVKM`H@*XBfY5m}s1@b)yNqPos8-LyuX4?QMB`G^%mDH55XUs3-R^Iz6< zUq%jHStgY;hn~C_@3-UpB{^u#H?W|Xpghru* zFp_l)bo#KWif43%^t37TUXArJo~aG#A+lM&pj?B{qg01RYamk5AQIEv)P#cdL&UO6 z^oUbHU25K;V%CpG2qg&p1PY0~vYvkw2D5i$3d(w6BSCJ%5B`iir)nEOr;jKr5YPB~ zNKfi%JspcieA}sQxHsH}w`$uE4YlE0h-LSZpEw27C2B*|dTc471fg$30d4rs5ybM_ z@OTpfw*Xk*MB6??<<@GEMTa3O1R`Bje&5{<{Hv*9^aW-cw^8Zm6DUPpV?M?i))xg(fzB5uvDmGDdEm`TOI<9YL?Y;blYkk|`vVJY2 zr@uyOMbgP(UF2WV`nS^4vi=osqNl#j(L%9OsdTwCq|%jgDV=wR3YB3ey>mtHU~f-n zA@5dpc8rXNul5nEa!?P zFNvEN%(ASCyh~PeSPTxrZuuo-=V!Znt1hw*Y3PSoAgFdMwV+Cl6p9&76^ia?5J=aF zMCmbyIxy|*$hhh2oZD|I7Aj*-dbCumxWj{GFXQElZn}`qlDBlWk}nLa4c84M*Iss6 z^3v3&Q(eii!Jr1RWQc zqMt#7KGgj{&I=e!e=KU0xfcuQXXG&`G-^Q=bUpPLfU*MW2yQ%A3n+Km*}OEL?`?Wv>J&n)V@(EYcqj^4PThyK5dnZ6M8#}k|5 zF+DEF&cmM#^NsPu^{oHPI-ILB-*)wqW$>n&vJ`C9EZLg3tw*Z{>4L53R%IlRmQepl3o&-!QkM53 z=Cjz3@HBI&k<7Wvna^f@>8W+h=|ZEE=x=6z0dw)cjrqr!%gE)JFEI2y=8Fyez08*~ zm$>&b$7zlv{*O=|{ebo%iT)(z!MioB>OaN2hq>ruZ9|`SG@WE!onVfBLK6MgC=dNr zn#%VOrQT%T$6T*5%D=~4E=t0&FTjsnfP_bB!GO!{N4Va{gNp^90Qj*b+cRhRToPK{ z%kgtjXmu;s#}j)CPU!G~FZTr2366DrRbcOO-atpru0X#UOCM+8;d4~ZeAW++PMm3> zV>Gz8fa5x`k^33rf<5}|IX`93!*_)^zDS7v1LxuT0~N`zo+J;|Mm#8i*gxctm~Kja6o zpI|>98hj6zFXeVfKRn0!>kWRA^=~lvR^}Olvl}&L@J*~gVek!Ho;0|${~3d?;qp%n zZgKfn2A6sNdxO8t_4$XvcXI<~^T8w&d)PQlU6hqnRmX+)=02nm!>qqE8`JYN$9i=Fmr>luI9^ zQuJ+$K1k6ADt6@L21iPnF^4NsZx%&b-pK{o;`U2u-#_1b4 z(supCZyG;NjLS0bKf#>0ZI&waR*BBI29S2h4ZN~SL6f4%mf z;`SfGW=aX|hby!FYlxXX38|AjAh#Goqo{Chn+*0#IZ)0J8bv)mCWHO`{Ntkwg-|ke zKTEQD?ayIiP!fBzA1=-Id&Eqigw)SC{>vzYlBruHS-tp2IKIp?#BZQKGyYy;@G14A ztWIC%4L*+zB$On+ys>}Ovwy$QHT$L=s;QD}|E2_D z$I^a@GfA0x{r432UxFQ@{}S{k_R_C#Z^kA>|AEs_wVf9xmIJ)F3}p>Oew81mcb4)q^_tZLW* literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_endian.c.3.o b/Program/libcsp/build/src/csp_endian.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..95892feed5fddb2857e6e9b4f87f3e6833a9d093 GIT binary patch literal 9064 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_iflist.c.2.o b/Program/libcsp/build/src/csp_iflist.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..a7ebd4047ac9733e340ad8e0151649ce1e934af8 GIT binary patch literal 14224 zcmbta4RBn=k)F3JtyWrjEnEJPY_Qi@0@+wAtt8vRzmhE5Yml*QOW5Y`d9^>%#?r3X zeJjgA∪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 GuK)jBjg$BQ literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_init.c.2.o b/Program/libcsp/build/src/csp_init.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..c00bd4adfb86ed1bf93b826e324f9fd9aeb4c97c GIT binary patch literal 14856 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_port.c.2.o b/Program/libcsp/build/src/csp_port.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..bca6310901f9291b9c937585593fd5fa8c4381cd GIT binary patch literal 14704 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 J6X~qC|35m#Q7`}i literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_promisc.c.2.o b/Program/libcsp/build/src/csp_promisc.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..1a5e4c6e7265b67b95a5a36bc95ed6754c7c0eed GIT binary patch literal 5080 zcmbVQU2IfE6rQ`cKMUKI)&@jDvm}b5?%fvJQc$o;5E>Ct1JM^RcXy}TD|heR+@D%_ z5Tfxn8Zky=NQ}sXKM(#qm}pFlKBy!{6GdZq!kFNT527(@A}XFUb7tF~?h`lJne%<; zXXc!lduQ6i+jrfTvn*jAOKcT$$go13UN$FBC~-pci)CVoEkuXHdF9qKXC_3>$|KC> zx>eVqyS(nKF0Jdt&hF^+!&Kz*3aNnB)4M^T#b;3L%y;Dz=yTe$8)c==on8-OSN;&R z-A_TIMm=r+u{KHmT_ujPMG?$`3aD6iD=e<&BVd;#TamqH_KVIdgO zz*1mbgPZ~r8gwYIQ-e+g_Gr+hz`Yvetvg_b`!!f<-2-4+gB}Yf+|;07fmDM_ti7O_ z)nJ8n6@VieTxx9s@UR9et@|L_BO0u>d;m{qaJ97`%#LbMvJL=vNdrfL;~JC|cte9B z1>V(Qy>%FTKG0x;n%gHDj9L+l^QkC+Uf9RfGOVY$31ZiFxuZO72I)j>mCKEj}?PKG_mG zFUN`W9EIiwupAKG-x-I_Rmk-G4GsPVU>ib5(Ym&tLtqV9SN9DT?7mff{g=W=tYme7`1x=r?{wF@!!CsKLsz(NG&MCg;-*RwORwh2uqG1!kRx3Rbcy<>9(bueKiILAPNpSTl`97AAf@l(iy$^LFgsTimv3Q*om+>I@Z2 zjWi48mbwgO>{kJLadmnN6tgroQY_Vrr8|>i2?pN+B?YI_RFZnt1EpphrLvkvG3eqb ztP9K{k&r|qs>%695N>ta^FvW?$eQn!<%}1WcgqL&MM2h(<$4@tVGU~GrG6Bap`=i* zawYSFno1$@W+>HG4iGL@1Hg=95y0TZmJahvrlUAz6qb4}9@ZCEA&9C6u*Q({0U0O4 zZAQ?{El-rCus&0PS5Kg>2^1Q)MiN(XTewhyhM!cOD&!v2TKQv86+}mc^t0HlVzzn) zwDd4{jO_<9jFdSpqh8Zc&cdW-Qm+z76SlR9+(6FA02UmzkOmrH4q2Eb5|$s93Z^Yo zkuVk9JZ>|{bYgnzsQsm?g!MwJ3an|?r14e4dLIqz`WiFsjyp>2vJu^l!e&*wOAmT$ z6a^}%+RHj6wI*0Uv18k|&Bbf?Rb-+01y8T@!N$q zDm*pY(ZK5u4OiNrY4_ObeO;`vg}O>CQrMz<5r>4WPoPCQTc~5K4Zq-4)6(1eple|z zEZmB%nPKGlvosNr$FuPW{O}pjotg>qA5rO+GyX5a@F7Vg2A$9Qx7oMF7AI7b-2mhg*=FA+Y$ z_~R7kZN|eZqMi>KZ|eRzD8;#+@dpWyGyXZk+Zq2Wje9ra3l!gF{5ymL#-Ac=#y5GLBmOaFzn0=Z&-mYo zKhF3wgx_NP_cZ?x8UH%PIm!5Y$^JXWyTt#<_|GWLFO2_^`16c6`y)?!Q-{5TS1{hx z|4qgxWd9!H?|=QP-Nx1*P-N8)i;`>$Lic4VfHIXKaz%BRY~bl-fw}DsV1s`hOu%pcvtRuoE5z5d_`RS+J9GA~BxC&E^O&f*gU0=o z>`cdP_keZwedGSp7ZVeFVL0lI^#&a@iRUCi^9nBP1l)3=aX%0(U(323oM7o uzevIH9}sw#Ght0#ahtF$rsC|O{bTMkiiC#G74L!V{CAS$v&NBn?*BhM^C)Qm literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_promisc.c.3.o b/Program/libcsp/build/src/csp_promisc.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..611b04f20b55638132c55d0dda0fade020312038 GIT binary patch literal 5080 zcmbVQU1(fI6rQ^`Kih7SCI)M3t878*@7_(?Bu&-SXs9*x$NE!Ie7L>4JK0=v_ul3H z#MTE}6o09xh*bok3W`2dd{B^rC@2bwsHG1TL=p5wLGeLFYt?gR&TO(L@ue3sbH4BV z%$zfG@66`V_FXsSEK8Wj65GTAGOQ4%S1rhsN}Lq^VwG573(=u)Ub*!wmTt=%xg{Ti&aZU-={L63zKZfel4K&ruc);`c2 z&|tN734p^ITwrYl@PGzuth*uFgBq;2d;pJXaH+K)%%0MqWX%D1UIRygV;Yndcuj*L z1>V$PlXVDu-qB#Qn%nytj9L+l^Pwn!Uf3_FWmsb$!z6VnUqX@OmoZ&hhF3A$eptfw zz;)%H1=NGfi_`AK#YGlZQ?Z8(J1F{4rM9Mhy@kA%Cl|>#D7haEJ08I?wfN|Q_*hHq zybveS^At4Sg5`kdK4ly_*CEsM7c}@c0NW5ciq^I57X;RTb!p#V!R}kv*M9+Q)JsI6 zuniy-gG4Av$7*5sT~oNWFg*x+dKH*Ja@Zm6-YBrk4_bC#p@3Evz!kkMmvOLONw9Nz z5MjXtgy~t<^dNflZh$ytQ1%Ui>ve0PFe5q!I9MM$+h zp8?8=kD;}!Gkv|#s;>vU{8l+j;<6uBgRCaY2gb+Tv5`{XhuMKrJ08`Q?yw7?{LmGy8_mp&jku{&#L}y|GOUTjzfTf()AX+GI50$2 zHuuJUD&2~gNChj|jPh{ZrdQhp@u1th5UiQTV#l6+#i^}Zi(8ygXQ)_eq**8@>N1qE zUj^vJ)!7NCUukTlSgIFGw-svf5lhmuum6~ys%4!ErO^zhn0ph z%*i+rZZm>rVUeONg;kmfym|uFO`zPkL6W$No5O{AH2kFMR3Z1E*2*7)svtTlq@TrZ z6|>bdpbY?X$Jl-#!$_IqV(OI*-riq?T-6O?X?lzjlz~y z`#=wRV-y7{BekP-N@`88eqzVe)HTJ+_f@hm&GfD;ZO#-LzJGY!85+4lvu$63Hh_nJ zhxqm1Hj)6Gn#<8}n(7Y?SK6Ri?y=STx>REeb(L76utoP04hdVIKudJCP{-IZeA}(2 zrMLA#*TPC@--NB1VdTZLG!c=neneuoHrN`FNbZa|H1gR#COm- znDyO7b_0wr6TX=7M=8!#j6Xzpobk^Q-p=^nY24cwKS1$a#=lKCVEk#q2O0kx;fEQ2 zHN}61@qZG3jPc(SKF;{BY5pe|f1Kic%=o*={uJX~;=g13rxfRB#-Akq4CBA2IC;{W z^}UDiYQ`TS|BD#^Bk@--ek0*g#=lGUH!$AR@i60?gdbu&OV(!3JCo zgah|5-Om~+#jAr;^HNVZl_U{PECbI`cTm?4XClzyebn_Tl~~TVslC_>>k?eF1>B~k zks-Qps!^jM;d`cdP_kx0RXgh#|!BbT2Lc?u$f@-<>579wt=85yiTN0l?e$RMJpu{kZ z|0RM&54XiFh}_U38x(U?H~W9;Z{pxNznp(3P4r3@*Z7$p|3zWs#inJG=wfmiTlA$@ zzRhxo{EHME{{ew_ITO~@6}JgXQN`Iy`^Vg86bTKVE8YW_^S_xKpEQotbN~MU8d@lJ literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_qfifo.c.2.o b/Program/libcsp/build/src/csp_qfifo.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..60539f4ac6290f704a50baaa7bb161434c7b2d55 GIT binary patch literal 15288 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 z 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

  2. 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 XV1?!1j!jj*q*JJQMck~bTK<0keV(G} literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_service_handler.c.2.o b/Program/libcsp/build/src/csp_service_handler.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..8a4b0f9f4a113b4a5f85599129114b521e4742cd GIT binary patch literal 27968 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_service_handler.c.3.o b/Program/libcsp/build/src/csp_service_handler.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..1dc4633b049a7232faac68bb0ebb39d3a331e544 GIT binary patch literal 27808 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 c74jgy)HiW1m;X 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/csp_sfp.c.2.o b/Program/libcsp/build/src/csp_sfp.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..13e0ec6769ded007120fd3f0bdb60f08aafafa68 GIT binary patch literal 21392 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 Jv#+N7{{y2Cs*(Tz literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/drivers/can/can_socketcan.c.3.o b/Program/libcsp/build/src/drivers/can/can_socketcan.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..ffa13674939c7c06e0a7862f478720c5ad612d0d GIT binary patch literal 32976 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
    [/mask] [via] + + * address: is the destination address, the routing table will match it against the CSP header destination. + * mask (optional): determines how many MSB bits of address are to be matched. mask = 1 will only match the MSB bit, mask = 2 will match 2 MSB bits. Mask values different from 0 and 5, is only supported by the cidr rtable. + * interface name: name of the interface to route the packet on + * via (optional) address: if different from 255, route the packet to the `via` address, instead of the address in the CSP header. + +Here are some examples: + + - "10 I2C" route destination address 10 to the "I2C" interface and send it to address 10 (no `via`). + - "10 I2C 30" route destination address 10 to the "I2C" interface and send it to address 30 (`via`). The original destination address 10 is not changed in the CSP header of the packet. + - "16/1 CAN 4" (CIDR only) route all destinations addresses 16-31 to address 4 on the CAN interface. + - "0/0 CAN" default route, if no other matching route is found, route packet onto the CAN interface. + + +Interface +--------- + +The interface typically implements :ref:`layer2`, and uses drivers from :ref:`layer1` to send/receive data. +The interface is a generic struct, with no knowledge of any specific interface , protocol or driver: + +.. literalinclude:: ../include/csp/csp_interface.h + :language: c + :start-after: //doc-begin:csp_iface_s + :end-before: //doc-end:csp_iface_s + +If an interface implementation needs to store data, e.g. state information (KISS), it can use the pointer `interface_data` to reference any data structure needed. The driver implementation can use the pointer `driver_data` for storing data, e.g. device number. + +See function `csp_can_socketcan_open_and_add_interface()` in `src/drivers/can/can_socketcan.c` for an example of how to implement a CAN driver and hooking it into CSP, using the CSP standard CAN interface. + +Send +^^^^ + +When CSP needs to send a packet, it calls `nexthop` on the interface returned by route lookup. +If the interface succeeds in sending the packet, it must free the packet. +In case of failure, the packet must not be freed by the interface. The original idea was, that the packet could be retried later on, without having to re-create the packet again. However, the current implementation does not yet fully support this as some interfaces modifies header (endian conversion) or data (adding CRC32). + +Receive +^^^^^^^ + +When receiving data, the driver calls into the interface with the received data, e.g. `csp_can_rx()`. The interface will convert/copy the data into a packet (e.g. by assembling all CAN frames). Once a complete packet is received, the packet is queued for later CSP processing, by calling `csp_qfifo_write()`. + diff --git a/Program/libcsp/doc/example.rst b/Program/libcsp/doc/example.rst new file mode 100755 index 0000000..7871a73 --- /dev/null +++ b/Program/libcsp/doc/example.rst @@ -0,0 +1,61 @@ +Client and server example +========================= + +The example in `example/csp_server_client.c` provides a simple server/client setup, where the client sends a request to the server and receives a reply. The code can be compiled to an executable using `./examples/buildall.py`. + +The example supports the drivers and interfaces in CSP: + + - ZMQHUB: -z + + Requires no extra hardware, as it uses standard network. The zmqproxy will need to be started. + + - CAN: -c + + Requires a physical CAN interface. There are several CAN dongles on the market, for example https://www.peak-system.com/PCAN-USB.199.0.html. + + To achieve best performance and stabilty, following options can be set on the CAN device: + + .. code-block:: none + + linux: sudo ip link set dev can0 down + linux: sudo ip link set dev can0 up type can bitrate 1000000 restart-ms 100 + linux: sudo ip link set dev can0 txqueuelen 100 + + - KISS: -k + + Requires a serial interface, e.g. USB dongle. + + +Running the example +^^^^^^^^^^^^^^^^^^^ +If the example is started without any interfaces, it will use the loopback interface for communication between client and server:: + + ubuntu-18:~/libcsp$ ./build/csp_server_client + 1586816581.410181 Initialising CSP + Connection table + [00 0x55a00f7adee0] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [01 0x55a00f7adf68] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [02 0x55a00f7adff0] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [03 0x55a00f7ae078] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [04 0x55a00f7ae100] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [05 0x55a00f7ae188] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [06 0x55a00f7ae210] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [07 0x55a00f7ae298] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [08 0x55a00f7ae320] S:0, 0 -> 0, 0 -> 0, sock: (nil) + [09 0x55a00f7ae3a8] S:0, 0 -> 0, 0 -> 0, sock: (nil) + Interfaces + LOOP tx: 00000 rx: 00000 txe: 00000 rxe: 00000 + drop: 00000 autherr: 00000 frame: 00000 + txb: 0 (0.0B) rxb: 0 (0.0B) MTU: 0 + + Route table + 1/5 LOOP + 0/0 LOOP + 1586816581.410405 Server task started + 1586816581.410453 Binding socket 0x55a00f7adf68 to port 25 + 1586816581.410543 Client task started + 1586816582.410983 SERVICE: Ping received + 1586816582.411135 Ping address: 1, result 0 [mS] + 1586816582.411174 reboot system request sent to address: 1 + 1586816582.461341 csp_sys_reboot not supported - no user function set + 1586816582.512532 Packet received on MY_SERVER_PORT: Hello World (1) diff --git a/Program/libcsp/doc/history.rst b/Program/libcsp/doc/history.rst new file mode 100755 index 0000000..ec3a92a --- /dev/null +++ b/Program/libcsp/doc/history.rst @@ -0,0 +1,21 @@ +History +======= + +The idea was developed by a group of students from Aalborg University in 2008. In 2009 the main developer started working for GomSpace, and CSP became integrated into the GomSpace products. + +The three letter acronym CSP was originally an abbreviation for CAN Space Protocol because the first MAC-layer driver was written for CAN-bus. Now the physical layer has extended to include SpaceWire, I2C and RS232, the name was therefore extended to the more general CubeSat Space Protocol without changing the abbreviation. + +Satellites using CSP +-------------------- + +Here is a list of some of the known satellites or organisations, that uses CSP: + + * GomSpace GATOSS GOMX-1 + * AAUSAT-3 + * EgyCubeSat + * EuroLuna + * NUTS + * Hawaiian Space Flight Laboratory + * GomSpace GOMX-3, GOMX-4 A & B + +See list of libcsp fork's here: https://github.com/libcsp/libcsp/network/members diff --git a/Program/libcsp/doc/libcsp.rst b/Program/libcsp/doc/libcsp.rst new file mode 100755 index 0000000..07efec7 --- /dev/null +++ b/Program/libcsp/doc/libcsp.rst @@ -0,0 +1,21 @@ +.. CSP Documentation master file. + +.. _libcsp: + +********************** +CubeSat Space Protocol +********************** + +.. toctree:: + :maxdepth: 3 + + ../README + history + structure + basic + memory + protocolstack + topology + mtu + example + diff --git a/Program/libcsp/doc/memory.rst b/Program/libcsp/doc/memory.rst new file mode 100755 index 0000000..85b5471 --- /dev/null +++ b/Program/libcsp/doc/memory.rst @@ -0,0 +1,16 @@ +How CSP uses memory +=================== + +CSP has been written for small microprocessor systems. The way memory is handled is therefore a tradeoff between the amount used and the code efficiency. + +The current libcsp implementation primarily uses dynamic memory allocation during initialization, where all structures are allocated: port tables, connection pools, buffer pools, message queues, semaphores, tasks, etc. + +Once the initiallization is complete, there are only a few functions that uses dynamic allocation, such as: + + * csp_sfp_recv() - sending larger memory chuncks than can fit into a single CSP message. + * csp_rtable (cidr only) - adding new elements may allocate memory. + +This means that there are no `alloc/free` after initialization, possibly causing fragmented memory which especially can be a problem on small systems with limited memory. +It also allows for a very simple memory allocator (implementation of `csp_malloc()`), as `free` can be avoided. + +Future versions of libcsp may provide a `pure` static memory layout, since newer FreeRTOS versions allows for specifying memory for queues, semaphores, tasks, etc. diff --git a/Program/libcsp/doc/mtu.rst b/Program/libcsp/doc/mtu.rst new file mode 100755 index 0000000..eb8207d --- /dev/null +++ b/Program/libcsp/doc/mtu.rst @@ -0,0 +1,19 @@ +Maximum Transfer Unit +===================== + +There are two things limiting the MTU of CSP. + + 1. The pre-allocated buffer pool’s allocation size + 2. The link layer protocol. + +So let’s assume that you have made a protocol called KISS with a MTU of 256. The 256 is the total amount of data that you can put into the CSP-packet. However, you need to take the overhead of the link layer into account. Typically this could consist of a length field and/or a start/stop flag. So the actual frame size on the link layer would for example be 256 bytes of data + 2 bytes sync flag + 2 bytes length field. + +This requires a buffer allocation of at lest 256 + 2 + 2. However, the CSP packet itself has some reserved bytes in the beginning of the packet (which you can see in csp.h) - so the recommended buffer allocation size is MAX MTU + 16 bytes. In this case the max MTU would be 256. + +If you try to pass data which is longer than the MTU, the chance is that you will also make a buffer overflow in the CSP buffer pool. However, lets assume that you have two interfaces one with an MTU of 200 bytes and another with an MTU of 100 bytes. In this case you might successfully transfer 150 bytes over the first interface, but the packet will be rejected once it comes to the second interface. + +If you want to increase your MTU of a specific link layer, it is up to the link layer protocol to implement its own fragmentation protocol. A good example is CAN-bus which only allows a frame size of 8 bytes. libcsp have a small protocol for this called the “CAN fragmentation protocol" or CFP for short. This allows data of much larger size to be transferred over the CAN bus. + +Okay, but what if you want to transfer 1000 bytes, and the network maximum MTU is 256? Well, since CSP does not include streaming sockets, only packet’s. Somebody will have to split that data up into chunks. It might be that your application have special knowledge about the datatype you are transmitting, and that it makes sense to split the 1000 byte content into 10 chunks of 100 byte status messages. This, application layer delimitation might be good if you have a situation with packet loss, because your receiver could still make good usage of the partially delivered chunks. + +But, what if you just want 1000 bytes transmitted, and you don’t care about the fragmentation unit, and also don’t want the hassle of writing the fragmentation code yourself? - In this case, libcsp provides SFP (small fragmentation protocol), designed to work on the application layer. For this purpose you will not use csp_send and csp_recv, but csp_sfp_send and csp_sfp_recv. This will split your data into chunks of a certain size, enumerate them and transfer over a given connection. If a chunk is missing the SFP client will abort the reception, because SFP does not provide retransmission. If you wish to also have retransmission and orderly delivery you will have to open an RDP connection and send your SFP message to that connection. diff --git a/Program/libcsp/doc/protocolstack.rst b/Program/libcsp/doc/protocolstack.rst new file mode 100755 index 0000000..8ae388d --- /dev/null +++ b/Program/libcsp/doc/protocolstack.rst @@ -0,0 +1,61 @@ +The Protocol Stack +================== + +The CSP protocol stack includes functionality on all layers of the TCP/IP model: + +.. _layer1: + +Layer 1: Drivers +---------------- + +CSP is not designed for any specific processor or hardware peripheral, but yet these drivers are required in order to work. The intention of LibCSP is not to provide CAN, I2C or UART drivers for all platforms, however some drivers has only been included for some specific platforms. If you do not find your driver supported, it is quite simple to add a driver that conforms to the CSP interface. +For good stability and performance interrupt driven drivers are preferred in favor of polled drivers. Where applicable also DMA usage is recommended. + +.. _layer2: + +Layer 2: MAC interfaces +----------------------- + +CSP has interfaces for I2C, CAN, RS232 (KISS) and Loopback. The layer 2 protocol software defines a frame-format that is suitable for the media. CSP can be easily extended with implementations for even more links. For example a radio-link and IP-networks. The file `csp_interface.h` declares the rx and tx functions needed in order to define a network interface in CSP. During initialisation of CSP each interface will be inserted into a linked list of interfaces that is available to the router. In cases where link-layer addresses are required, such as I2C, the routing table supports specifying a `via` link-layer address directly. This avoids the need to implement an address resolution protocol to translate CSP addresses to I2C addresses. + +Layer 3: Network Router +----------------------- + +The router core is the backbone of the CSP implementation. The router works by looking at a 32-bit CSP header which contains the destination and source address together with port numbers for the connection. The router supports both local destination and forwarding to an external destination. Messages will never exit the router on the same interface that they arrives at, this concept is called split horizon, and helps prevent routing loops. + +The main purpose of the router is to accept incoming packets and deliver them to the right message queue. Therefore, in order to listen on a port-number on the network, a task must create a socket and call the accept() call. This will make the task block and wait for incoming traffic, just like a web-server or similar. When an incoming connection is opened, the task is woken. Depending on the task-priority, the task can even preempt another task and start execution immediately. + +There is no routing protocol for automatic route discovery, all routing tables are pre-programmed into the subsystems. The table itself contains a separate route to each of the possible 32 nodes in the network and the additional default route. This means that the overall topology must be decided before putting sub-systems together, as explained in the :ref:`topology` section. However CSP has an extension on port zero CMP (CSP management protocol), which allows for over-the-network routing table configuration. This has the advantage that default routes could be changed if for example the primary radio fails, and the secondary should be used instead. + +.. _layer4: + +Layer 4: Transport Layer +------------------------ + +LibCSP implements two different Transport Layer protocols, they are called UDP (unreliable datagram protocol) and RDP (reliable datagram protocol). The name UDP has not been chosen to be an exact replica of the UDP (user datagram protocol) known from the TCP/IP model, but they have certain similarities. + +The most important thing to notice is that CSP is entirely a datagram service. There is no stream based service like TCP. A datagram is a defined block of data with a specified size and structure. This block enters the transport layer as a single datagram and exits the transport layer in the other end as a single datagram. CSP preserves this structure all the way to the physical layer for I2C, KISS and Loopback interfaces. The CAN-bus interface has to fragment the datagram into CAN-frames of 8 bytes, however only a fully completed datagram will arrive at the receiver. + +UDP +^^^ + +UDP uses a simple transmission model without implicit hand-shaking dialogues for guaranteeing reliability, ordering, or data integrity. Thus, UDP provides an unreliable service and datagrams may arrive out of order, appear duplicated, or go missing without notice. UDP assumes that error checking and correction is either not necessary or performed in the application, avoiding the overhead of such processing at the network interface level. Time-sensitive applications often use UDP because dropping packets is preferable to waiting for delayed packets, which may not be an option in a real-time system. + +UDP is very practical to implement request/reply based communication where a single packet forms the request and a single packet forms the reply. In this case a typical request and wait protocol is used between the client and server, which will simply return an error if a reply is not received within a specified time limit. An error would normally lead to a retransmission of the request from the user or operator which sent the request. + +While UDP is very simple, it also has some limitations. Normally a human in the loop is a good thing when operating the satellite over UDP. But when it comes to larger file transfers, the human becomes the bottleneck. When a high-speed file transfer is initiated data acknowledgment should be done automatically in order to speed up the transfer. This is where the RDP protocol can help. + +RDP +^^^ +CSP provides a transport layer extension called RDP (reliable datagram protocol) which is an implementation of RFC908 and RFC1151. RDP provides a few additional features: + + * Three-way handshake + * Flow Control + * Data-buffering + * Packet re-ordering + * Retransmission + * Windowing + * Extended Acknowledgment + +For more information on this, please refer to RFC908 and RFC1151. + diff --git a/Program/libcsp/doc/structure.rst b/Program/libcsp/doc/structure.rst new file mode 100755 index 0000000..b79c87b --- /dev/null +++ b/Program/libcsp/doc/structure.rst @@ -0,0 +1,29 @@ +Structure +========= +The Cubesat Space Protocol library is structured as shown in the following table: + +============================= ========================================================================= +**Folder** **Description** +============================= ========================================================================= +libcsp/include/csp Public header files +libcsp/include/csp/arch Architecture (platform) +libcsp/include/csp/interfaces Interfaces +libcsp/include/csp/drivers Drivers +libcsp/src Source modules and internal header files +libcsp/src/arch Architecture (platform) specific code +libcsp/src/arch/freertos FreeRTOS +libcsp/src/arch/macosx Mac OS X +libcsp/src/arch/posix Posix (Linux) +libcsp/src/arch/windows Windows +libcsp/src/bindings/python Python3 wrapper for libcsp +libcsp/src/crypto HMAC, SHA and XTEA. +libcsp/src/drivers Drivers, mostly platform specific (Linux) +libcsp/src/drivers/can CAN +libcsp/src/drivers/usart USART +libcsp/src/interfaces Interfaces, CAN, I2C, KISS, LOOPBACK and ZMQHUB +libcsp/src/rtable Routing tables +libcsp/src/transport Transport layer: UDP, RDP +libcsp/utils Utilities, Python scripts for decoding CSP headers. +libcsp/examples CSP examples, C/Python, zmqproxy +libcsp/doc RST based documention (this documentation) +============================= ========================================================================= diff --git a/Program/libcsp/doc/topology.rst b/Program/libcsp/doc/topology.rst new file mode 100755 index 0000000..139caec --- /dev/null +++ b/Program/libcsp/doc/topology.rst @@ -0,0 +1,27 @@ + +.. _topology: + +Network Topology +================ + +CSP uses a network oriented terminology similar to what is known from the Internet and the TCP/IP model. A CSP network can be configured for several different topologies. The most common topology is to create two segments, one for the Satellite and one for the Ground-Station. + +.. code-block:: none + + +-------+-------+-------+-------+ bus: I2C, CAN, KISS + | | | | | + +---+ +---+ +---+ +---+ +---+ + |OBC| |COM| |EPS| |PL1| |PL2| Nodes 0 - 15 (Space segment) + +---+ +---+ +---+ +---+ +---+ + ^ + | Radio + v + +---+ +----+ + |TNC| | PC | Nodes 16 - 31 (Ground segment) + +---+ +----+ + | | + +---------------+ bus: KISS, ZMQ + +The address range, from 0 to 31, has been segmented into two equal size segments. This allows for easy routing in the network. All addresses starting with binary 1 is on the ground-segment, and all addresses starting with 0 is on the space segment. + +The network is configured using static routes initialised at boot-up of each sub-system. This means that the basic routing table must be assigned compile-time of each subsystem. However each node supports assigning an individual route to every single node in the network and can be changed run-time. This means that the network topology can be easily reconfigured after startup. diff --git a/Program/libcsp/examples/buildall.py b/Program/libcsp/examples/buildall.py new file mode 100755 index 0000000..97cc7d1 --- /dev/null +++ b/Program/libcsp/examples/buildall.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import subprocess +import sys + + +os = 'posix' # default OS +options = sys.argv[1:] +if (len(options) > 0) and not options[0].startswith('--'): + os = options[0] + options = options[1:] + +options += [ + '--with-os=' + os, + '--enable-rdp', + '--enable-promisc', + '--enable-crc32', + '--enable-hmac', + '--enable-xtea', + '--enable-dedup', + '--with-loglevel=debug', + '--enable-debug-timestamp' +] + +waf = ['./waf'] +if os in ['posix']: + options += [ + '--enable-python3-bindings', + '--enable-can-socketcan', + '--with-driver-usart=linux', + '--enable-if-zmqhub', + '--enable-shlib' + ] + +if os in ['macosx']: + options += [ + '--with-driver-usart=linux', + ] + +if os in ['windows']: + options += [ + '--with-driver-usart=windows', + ] + waf = ['python', '-x', 'waf'] + +# Build +waf += ['distclean', 'configure', 'build'] +print("Waf build command:", waf) +subprocess.check_call(waf + options + + ['--enable-qos', '--with-rtable=cidr', '--disable-stlib', '--disable-output']) +subprocess.check_call(waf + options + ['--enable-examples']) diff --git a/Program/libcsp/examples/csp_arch.c b/Program/libcsp/examples/csp_arch.c new file mode 100755 index 0000000..5c088e6 --- /dev/null +++ b/Program/libcsp/examples/csp_arch.c @@ -0,0 +1,159 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#define CSP_USE_ASSERT 1 // always enable CSP assert + +#include +#include +#include +#include +#include +#include +#include + +#include + +static bool thread_executed = false; + +void csp_assert_fail_action(const char *assertion, const char *file, int line) { + printf("assertion: [%s], file: %s:%d\r\n", assertion, file, line); + exit(1); +} + +CSP_DEFINE_TASK(thread_func) { + csp_log_info("Thread started"); + thread_executed = true; + csp_sleep_ms(10000); // safty - ensure process terminates + exit(1); + return CSP_TASK_RETURN; +} + +int main(int argc, char * argv[]) { + + // debug/log - enable all levels + for (int i = 0; i <= CSP_LOCK; ++i) { + csp_debug_set_level(i, true); + } + csp_log_error("csp_log_error(...), level: %d", CSP_ERROR); + csp_log_warn("csp_log_warn(...), level: %d", CSP_WARN); + csp_log_info("csp_log_info((...), level: %d", CSP_INFO); + csp_log_buffer("csp_log_buffer(...), level: %d", CSP_BUFFER); + csp_log_packet("csp_log_packet(...), level: %d", CSP_PACKET); + csp_log_protocol("csp_log_protocol(...), level: %d", CSP_PROTOCOL); + csp_log_lock("csp_log_lock(...), level: %d", CSP_LOCK); + + // create a thread - csp_thread doesn't support join + csp_thread_handle_t thread = 0; + int res = csp_thread_create(thread_func, "thread", 0, NULL, 0, &thread); + csp_assert(res == CSP_ERR_NONE); + csp_assert(thread != 0); + + // clock + csp_timestamp_t csp_clock = {}; + csp_clock_get_time(&csp_clock); + csp_assert(csp_clock.tv_sec != 0); + csp_log_info("csp_clock_get_time(..) -> sec:nsec = %"PRIu32":%"PRIu32, csp_clock.tv_sec, csp_clock.tv_nsec); + + // relative time + const uint32_t msec1 = csp_get_ms(); + const uint32_t msec2 = csp_get_ms_isr(); + const uint32_t sec1 = csp_get_s(); + const uint32_t sec2 = csp_get_s_isr(); + csp_sleep_ms(2000); + csp_assert(csp_get_ms() >= (msec1 + 500)); + csp_assert(csp_get_ms_isr() >= (msec2 + 500)); + csp_assert(csp_get_s() >= (sec1 + 1)); + csp_assert(csp_get_s_isr() >= (sec2 + 1)); + + // malloc + uint32_t * ptr = csp_malloc(sizeof(*ptr)); + csp_assert(ptr != NULL); + ptr[0] = 10; + csp_free(ptr); + ptr = csp_calloc(1, sizeof(*ptr)); + csp_assert(ptr != NULL); + csp_assert(*ptr == 0); + ptr[0] = 20; + csp_free(ptr); + + // check thread actually executed + csp_assert(thread_executed != false); + + // queue handling + uint32_t value; + csp_queue_handle_t q = csp_queue_create(3, sizeof(value)); + csp_assert(csp_queue_size(q) == 0); + csp_assert(csp_queue_size_isr(q) == 0); + csp_assert(csp_queue_dequeue(q, &value, 0) == CSP_QUEUE_ERROR); + csp_assert(csp_queue_dequeue(q, &value, 200) == CSP_QUEUE_ERROR); + csp_assert(csp_queue_dequeue_isr(q, &value, NULL) == CSP_QUEUE_ERROR); + value = 1; + csp_assert(csp_queue_enqueue(q, &value, 0) == CSP_QUEUE_OK); + value = 2; + csp_assert(csp_queue_enqueue(q, &value, 200) == CSP_QUEUE_OK); + value = 3; + csp_assert(csp_queue_enqueue_isr(q, &value, NULL) == CSP_QUEUE_OK); + csp_assert(csp_queue_size(q) == 3); + csp_assert(csp_queue_size_isr(q) == 3); + value = 10; + csp_assert(csp_queue_enqueue(q, &value, 0) == CSP_QUEUE_ERROR); + value = 20; + csp_assert(csp_queue_enqueue(q, &value, 200) == CSP_QUEUE_ERROR); + value = 30; + csp_assert(csp_queue_enqueue_isr(q, &value, NULL) == CSP_QUEUE_ERROR); + value = 100; + csp_assert(csp_queue_dequeue(q, &value, 0) == CSP_QUEUE_OK); + csp_assert(value == 1); + csp_assert(csp_queue_dequeue(q, &value, 200) == CSP_QUEUE_OK); + csp_assert(value == 2); + csp_assert(csp_queue_dequeue_isr(q, &value, NULL) == CSP_QUEUE_OK); + csp_assert(value == 3); + csp_queue_remove(q); + + // mutex - the actual mutex lock can't be tested from a single thread + csp_mutex_t m; + csp_assert(csp_mutex_create(&m) == CSP_MUTEX_OK); + csp_assert(csp_mutex_lock(&m, 0) == CSP_MUTEX_OK); +#if (CSP_WINDOWS) // implementations differ in return value if already locked + csp_assert(csp_mutex_lock(&m, 200) == CSP_MUTEX_OK); +#else + csp_assert(csp_mutex_lock(&m, 200) == CSP_MUTEX_ERROR); +#endif + csp_assert(csp_mutex_unlock(&m) == CSP_MUTEX_OK); + csp_assert(csp_mutex_lock(&m, 200) == CSP_MUTEX_OK); + csp_assert(csp_mutex_unlock(&m) == CSP_MUTEX_OK); + csp_assert(csp_mutex_remove(&m) == CSP_MUTEX_OK); + + // semaphore + csp_bin_sem_handle_t s; + csp_assert(csp_bin_sem_create(&s) == CSP_SEMAPHORE_OK); + csp_assert(csp_bin_sem_wait(&s, 0) == CSP_SEMAPHORE_OK); + csp_assert(csp_bin_sem_post(&s) == CSP_SEMAPHORE_OK); +#if (CSP_POSIX) // implementations differ in return value if already posted/signaled + csp_assert(csp_bin_sem_post_isr(&s, NULL) == CSP_SEMAPHORE_OK); +#else + csp_assert(csp_bin_sem_post_isr(&s, NULL) == CSP_SEMAPHORE_ERROR); +#endif + csp_assert(csp_bin_sem_wait(&s, 200) == CSP_SEMAPHORE_OK); + csp_assert(csp_bin_sem_wait(&s, 200) == CSP_SEMAPHORE_ERROR); + csp_assert(csp_bin_sem_remove(&s) == CSP_SEMAPHORE_OK); + + return 0; +} diff --git a/Program/libcsp/examples/csp_server_client.c b/Program/libcsp/examples/csp_server_client.c new file mode 100755 index 0000000..9bd62b4 --- /dev/null +++ b/Program/libcsp/examples/csp_server_client.c @@ -0,0 +1,316 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Server port, the port the server listens on for incoming connections from the client. */ +#define MY_SERVER_PORT 10 + +/* Commandline options */ +static uint8_t server_address = 255; + +/* test mode, used for verifying that host & client can exchange packets over the loopback interface */ +static bool test_mode = false; +static unsigned int server_received = 0; + +/* Server task - handles requests from clients */ +CSP_DEFINE_TASK(task_server) { + + csp_log_info("Server task started"); + + /* Create socket with no specific socket options, e.g. accepts CRC32, HMAC, XTEA, etc. if enabled during compilation */ + csp_socket_t *sock = csp_socket(CSP_SO_NONE); + + /* Bind socket to all ports, e.g. all incoming connections will be handled here */ + csp_bind(sock, CSP_ANY); + + /* Create a backlog of 10 connections, i.e. up to 10 new connections can be queued */ + csp_listen(sock, 10); + + /* Wait for connections and then process packets on the connection */ + while (1) { + + /* Wait for a new connection, 10000 mS timeout */ + csp_conn_t *conn; + if ((conn = csp_accept(sock, 10000)) == NULL) { + /* timeout */ + continue; + } + + /* Read packets on connection, timout is 100 mS */ + csp_packet_t *packet; + while ((packet = csp_read(conn, 50)) != NULL) { + switch (csp_conn_dport(conn)) { + case MY_SERVER_PORT: + /* Process packet here */ + csp_log_info("Packet received on MY_SERVER_PORT: %s", (char *) packet->data); + csp_buffer_free(packet); + ++server_received; + break; + + default: + /* Call the default CSP service handler, handle pings, buffer use, etc. */ + csp_service_handler(conn, packet); + break; + } + } + + /* Close current connection */ + csp_close(conn); + + } + + return CSP_TASK_RETURN; + +} +/* End of server task */ + +/* Client task sending requests to server task */ +CSP_DEFINE_TASK(task_client) { + + csp_log_info("Client task started"); + + unsigned int count = 0; + + while (1) { + + csp_sleep_ms(test_mode ? 200 : 1000); + + /* Send ping to server, timeout 1000 mS, ping size 100 bytes */ + int result = csp_ping(server_address, 1000, 100, CSP_O_NONE); + csp_log_info("Ping address: %u, result %d [mS]", server_address, result); + + /* Send reboot request to server, the server has no actual implementation of csp_sys_reboot() and fails to reboot */ + csp_reboot(server_address); + csp_log_info("reboot system request sent to address: %u", server_address); + + /* Send data packet (string) to server */ + + /* 1. Connect to host on 'server_address', port MY_SERVER_PORT with regular UDP-like protocol and 1000 ms timeout */ + csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, server_address, MY_SERVER_PORT, 1000, CSP_O_NONE); + if (conn == NULL) { + /* Connect failed */ + csp_log_error("Connection failed"); + return CSP_TASK_RETURN; + } + + /* 2. Get packet buffer for message/data */ + csp_packet_t * packet = csp_buffer_get(100); + if (packet == NULL) { + /* Could not get buffer element */ + csp_log_error("Failed to get CSP buffer"); + return CSP_TASK_RETURN; + } + + /* 3. Copy data to packet */ + snprintf((char *) packet->data, csp_buffer_data_size(), "Hello World (%u)", ++count); + + /* 4. Set packet length */ + packet->length = (strlen((char *) packet->data) + 1); /* include the 0 termination */ + + /* 5. Send packet */ + if (!csp_send(conn, packet, 1000)) { + /* Send failed */ + csp_log_error("Send failed"); + csp_buffer_free(packet); + } + + /* 6. Close connection */ + csp_close(conn); + } + + return CSP_TASK_RETURN; +} +/* End of client task */ + +/* main - initialization of CSP and start of server/client tasks */ +int main(int argc, char * argv[]) { + + uint8_t address = 1; + csp_debug_level_t debug_level = CSP_INFO; +#if (CSP_HAVE_LIBSOCKETCAN) + const char * can_device = NULL; +#endif + const char * kiss_device = NULL; +#if (CSP_HAVE_LIBZMQ) + const char * zmq_device = NULL; +#endif + const char * rtable = NULL; + int opt; + while ((opt = getopt(argc, argv, "a:d:r:c:k:z:tR:h")) != -1) { + switch (opt) { + case 'a': + address = atoi(optarg); + break; + case 'd': + debug_level = atoi(optarg); + break; + case 'r': + server_address = atoi(optarg); + break; +#if (CSP_HAVE_LIBSOCKETCAN) + case 'c': + can_device = optarg; + break; +#endif + case 'k': + kiss_device = optarg; + break; +#if (CSP_HAVE_LIBZMQ) + case 'z': + zmq_device = optarg; + break; +#endif + case 't': + test_mode = true; + break; + case 'R': + rtable = optarg; + break; + default: + printf("Usage:\n" + " -a
    local CSP address\n" + " -d debug level, 0 - 6\n" + " -r
    run client against server address\n" + " -c add CAN device\n" + " -k add KISS device (serial)\n" + " -z add ZMQ device, e.g. \"localhost\"\n" + " -R set routing table\n" + " -t enable test mode\n"); + exit(1); + break; + } + } + + /* enable/disable debug levels */ + for (csp_debug_level_t i = 0; i <= CSP_LOCK; ++i) { + csp_debug_set_level(i, (i <= debug_level) ? true : false); + } + + csp_log_info("Initialising CSP"); + + /* Init CSP with address and default settings */ + csp_conf_t csp_conf; + csp_conf_get_defaults(&csp_conf); + csp_conf.address = address; + int error = csp_init(&csp_conf); + if (error != CSP_ERR_NONE) { + csp_log_error("csp_init() failed, error: %d", error); + exit(1); + } + + /* Start router task with 10000 bytes of stack (priority is only supported on FreeRTOS) */ + csp_route_start_task(500, 0); + + /* Add interface(s) */ + csp_iface_t * default_iface = NULL; + if (kiss_device) { + csp_usart_conf_t conf = { + .device = kiss_device, + .baudrate = 115200, /* supported on all platforms */ + .databits = 8, + .stopbits = 1, + .paritysetting = 0, + .checkparity = 0}; + error = csp_usart_open_and_add_kiss_interface(&conf, CSP_IF_KISS_DEFAULT_NAME, &default_iface); + if (error != CSP_ERR_NONE) { + csp_log_error("failed to add KISS interface [%s], error: %d", kiss_device, error); + exit(1); + } + } +#if (CSP_HAVE_LIBSOCKETCAN) + if (can_device) { + error = csp_can_socketcan_open_and_add_interface(can_device, CSP_IF_CAN_DEFAULT_NAME, 0, false, &default_iface); + if (error != CSP_ERR_NONE) { + csp_log_error("failed to add CAN interface [%s], error: %d", can_device, error); + exit(1); + } + } +#endif +#if (CSP_HAVE_LIBZMQ) + if (zmq_device) { + error = csp_zmqhub_init(csp_get_address(), zmq_device, 0, &default_iface); + if (error != CSP_ERR_NONE) { + csp_log_error("failed to add ZMQ interface [%s], error: %d", zmq_device, error); + exit(1); + } + } +#endif + + if (rtable) { + error = csp_rtable_load(rtable); + if (error < 1) { + csp_log_error("csp_rtable_load(%s) failed, error: %d", rtable, error); + exit(1); + } + } else if (default_iface) { + csp_rtable_set(CSP_DEFAULT_ROUTE, 0, default_iface, CSP_NO_VIA_ADDRESS); + } else { + /* no interfaces configured - run server and client in process, using loopback interface */ + server_address = address; + } + + printf("Connection table\r\n"); + csp_conn_print_table(); + + printf("Interfaces\r\n"); + csp_route_print_interfaces(); + + printf("Route table\r\n"); + csp_route_print_table(); + + /* Start server thread */ + if ((server_address == 255) || /* no server address specified, I must be server */ + (default_iface == NULL)) { /* no interfaces specified -> run server & client via loopback */ + csp_thread_create(task_server, "SERVER", 1000, NULL, 0, NULL); + } + + /* Start client thread */ + if ((server_address != 255) || /* server address specified, I must be client */ + (default_iface == NULL)) { /* no interfaces specified -> run server & client via loopback */ + csp_thread_create(task_client, "CLIENT", 1000, NULL, 0, NULL); + } + + /* Wait for execution to end (ctrl+c) */ + while(1) { + csp_sleep_ms(3000); + + if (test_mode) { + /* Test mode is intended for checking that host & client can exchange packets over loopback */ + if (server_received < 5) { + csp_log_error("Server received %u packets", server_received); + exit(1); + } + csp_log_info("Server received %u packets", server_received); + exit(0); + } + } + + return 0; +} diff --git a/Program/libcsp/examples/python_bindings_example_client.py b/Program/libcsp/examples/python_bindings_example_client.py new file mode 100755 index 0000000..d87fc5e --- /dev/null +++ b/Program/libcsp/examples/python_bindings_example_client.py @@ -0,0 +1,63 @@ +#!/usr/bin/python3 + +# Build required code: +# $ ./examples/buildall.py +# +# Start zmqproxy (only one instance) +# $ ./build/zmqproxy +# +# Run client against server using ZMQ: +# $ LD_LIBRARY_PATH=build PYTHONPATH=build python3 examples/python_bindings_example_client.py -z localhost +# + +import os +import time +import sys +import argparse + +import libcsp_py3 as libcsp + + +def getOptions(): + parser = argparse.ArgumentParser(description="Parses command.") + parser.add_argument("-a", "--address", type=int, default=10, help="Local CSP address") + parser.add_argument("-c", "--can", help="Add CAN interface") + parser.add_argument("-z", "--zmq", help="Add ZMQ interface") + parser.add_argument("-s", "--server-address", type=int, default=27, help="Server address") + parser.add_argument("-R", "--routing-table", help="Routing table") + return parser.parse_args(sys.argv[1:]) + + +if __name__ == "__main__": + + options = getOptions() + + libcsp.init(options.address, "host", "model", "1.2.3", 10, 300) + + if options.can: + libcsp.can_socketcan_init(options.can) + if options.zmq: + libcsp.zmqhub_init(options.address, options.zmq) + libcsp.rtable_load("0/0 ZMQHUB") + if options.routing_table: + libcsp.rtable_load(options.routing_table) + + libcsp.route_start_task() + time.sleep(0.2) # allow router task startup + + print("Connections:") + libcsp.print_connections() + + print("Routes:") + libcsp.print_routes() + + print("CMP ident:", libcsp.cmp_ident(options.server_address)) + + print("Ping: %d mS" % libcsp.ping(options.server_address)) + + # transaction + outbuf = bytearray().fromhex('01') + inbuf = bytearray(1) + print ("Exchange data with server using csp_transaction ...") + libcsp.transaction(0, options.server_address, 10, 1000, outbuf, inbuf) + print (" got reply from server [%s]" % (''.join('{:02x}'.format(x) for x in inbuf))) diff --git a/Program/libcsp/examples/python_bindings_example_server.py b/Program/libcsp/examples/python_bindings_example_server.py new file mode 100755 index 0000000..8152455 --- /dev/null +++ b/Program/libcsp/examples/python_bindings_example_server.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 + +# Build required code: +# $ ./examples/buildall.py +# +# Start zmqproxy (only one instance) +# $ ./build/zmqproxy +# +# Run server, default enabling ZMQ interface: +# $ LD_LIBRARY_PATH=build PYTHONPATH=build python3 examples/python_bindings_example_server.py +# + +import os +import time +import sys +import threading + +import libcsp_py3 as libcsp + + +def csp_server(): + sock = libcsp.socket() + libcsp.bind(sock, libcsp.CSP_ANY) + libcsp.listen(sock, 5) + while True: + # wait for incoming connection + conn = libcsp.accept(sock, libcsp.CSP_MAX_TIMEOUT) + if not conn: + continue + + print ("connection: source=%i:%i, dest=%i:%i" % (libcsp.conn_src(conn), + libcsp.conn_sport(conn), + libcsp.conn_dst(conn), + libcsp.conn_dport(conn))) + + while True: + # Read all packets on the connection + packet = libcsp.read(conn, 100) + if packet is None: + break + + if libcsp.conn_dport(conn) == 10: + # print request + data = bytearray(libcsp.packet_get_data(packet)) + length = libcsp.packet_get_length(packet) + print ("got packet, len=" + str(length) + ", data=" + ''.join('{:02x}'.format(x) for x in data)) + # send reply + data[0] = data[0] + 1 + reply = libcsp.buffer_get(1) + libcsp.packet_set_data(reply, data) + libcsp.sendto_reply(packet, reply, libcsp.CSP_O_NONE) + + else: + # pass request on to service handler + libcsp.service_handler(conn, packet) + + +if __name__ == "__main__": + + # init csp + libcsp.init(27, "test_service", "bindings", "1.2.3", 10, 300) + libcsp.zmqhub_init(27, "localhost") + libcsp.rtable_set(0, 0, "ZMQHUB") + libcsp.route_start_task() + + print("Hostname: %s" % libcsp.get_hostname()) + print("Model: %s" % libcsp.get_model()) + print("Revision: %s" % libcsp.get_revision()) + + print("Routes:") + libcsp.print_routes() + + # start CSP server + threading.Thread(target=csp_server).start() diff --git a/Program/libcsp/examples/zmqproxy.c b/Program/libcsp/examples/zmqproxy.c new file mode 100755 index 0000000..0c7c35c --- /dev/null +++ b/Program/libcsp/examples/zmqproxy.c @@ -0,0 +1,115 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include + +#include + +static void * task_capture(void *ctx) { + + /* Subscriber (RX) */ + void *subscriber = zmq_socket(ctx, ZMQ_SUB); + assert(zmq_connect(subscriber, "tcp://localhost:7000") == 0); + assert(zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0) == 0); + + /* Allocated 'raw' CSP packet */ + csp_packet_t * packet = malloc(1024); + assert(packet != NULL); + + while (1) { + zmq_msg_t msg; + zmq_msg_init_size(&msg, 1024); + + /* Receive data */ + if (zmq_msg_recv(&msg, subscriber, 0) < 0) { + zmq_msg_close(&msg); + csp_log_error("ZMQ: %s\r\n", zmq_strerror(zmq_errno())); + continue; + } + + int datalen = zmq_msg_size(&msg); + if (datalen < 5) { + csp_log_warn("ZMQ: Too short datalen: %u\r\n", datalen); + while(zmq_msg_recv(&msg, subscriber, ZMQ_NOBLOCK) > 0) + zmq_msg_close(&msg); + continue; + } + + /* Copy the data from zmq to csp */ + char * satidptr = ((char *) &packet->id) - 1; + memcpy(satidptr, zmq_msg_data(&msg), datalen); + packet->length = datalen - sizeof(packet->id) - 1; + + csp_log_packet("Input: Src %u, Dst %u, Dport %u, Sport %u, Pri %u, Flags 0x%02X, Size %"PRIu16, + packet->id.src, packet->id.dst, packet->id.dport, + packet->id.sport, packet->id.pri, packet->id.flags, packet->length); + + zmq_msg_close(&msg); + } +} + +int main(int argc, char ** argv) { + + csp_debug_level_t debug_level = CSP_PACKET; + int opt; + while ((opt = getopt(argc, argv, "d:h")) != -1) { + switch (opt) { + case 'd': + debug_level = atoi(optarg); + break; + default: + printf("Usage:\n" + " -d debug level, 0 - 6\n"); + exit(1); + break; + } + } + + /* enable/disable debug levels */ + for (csp_debug_level_t i = 0; i <= CSP_LOCK; ++i) { + csp_debug_set_level(i, (i <= debug_level) ? true : false); + } + + void * ctx = zmq_ctx_new(); + assert(ctx); + + void *frontend = zmq_socket(ctx, ZMQ_XSUB); + assert(frontend); + assert(zmq_bind (frontend, "tcp://*:6000") == 0); + + void *backend = zmq_socket(ctx, ZMQ_XPUB); + assert(backend); + assert(zmq_bind(backend, "tcp://*:7000") == 0); + + pthread_t capworker; + pthread_create(&capworker, NULL, task_capture, ctx); + + csp_log_info("Starting ZMQproxy"); + zmq_proxy(frontend, backend, NULL); + + csp_log_info("Closing ZMQproxy"); + zmq_ctx_destroy(ctx); + + return 0; +} diff --git a/Program/libcsp/include/csp/arch/csp_clock.h b/Program/libcsp/include/csp/arch/csp_clock.h new file mode 100755 index 0000000..dc995df --- /dev/null +++ b/Program/libcsp/include/csp/arch/csp_clock.h @@ -0,0 +1,70 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_ARCH_CLOCK_H_ +#define _CSP_ARCH_CLOCK_H_ + +/** + @file + + Clock interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Timestamp (cross platform). +*/ +typedef struct { + //! Seconds + uint32_t tv_sec; + //! Nano-seconds. + uint32_t tv_nsec; +} csp_timestamp_t; + +/** + Get time. + + This function is 'weak' in libcsp, providing a working implementation for following OS's: POSIX, Windows and Macosx. + This function is expected to be equivalent to standard POSIX clock_gettime(CLOCK_REALTIME, ...). + + @param[out] time current time. +*/ +void csp_clock_get_time(csp_timestamp_t * time); + +/** + Set time. + + This function is 'weak' in libcsp, providing a working implementation for following OS's: POSIX, Windows and Macosx. + This function is expected to be equivalent to standard POSIX clock_settime(CLOCK_REALTIME, ...). + + @param[in] time time to set. + @return #CSP_ERR_NONE on success. +*/ +int csp_clock_set_time(const csp_timestamp_t * time); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/csp_malloc.h b/Program/libcsp/include/csp/arch/csp_malloc.h new file mode 100755 index 0000000..fe6eca9 --- /dev/null +++ b/Program/libcsp/include/csp/arch/csp_malloc.h @@ -0,0 +1,60 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_MALLOC_H_ +#define _CSP_MALLOC_H_ + +/** + @file + + Memory interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Allocate chunk of memory (POSIX). + @param[in] size size of memory chunk (bytes). + @return Pointer to allocated memory, or NULL on failure. +*/ +void * csp_malloc(size_t size); + +/** + Allocate chunk of memory and set it to zero (POSIX). + @param[in] nmemb number of members/chunks to allocate. + @param[in] size size of memory chunk (bytes). + @return Pointer to allocated memory, or NULL on failure. +*/ +void * csp_calloc(size_t nmemb, size_t size); + +/** + Free allocated memory (POSIX). + @param[in] ptr memory to free. NULL pointer is ignored. +*/ +void csp_free(void * ptr); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/csp_queue.h b/Program/libcsp/include/csp/arch/csp_queue.h new file mode 100755 index 0000000..716b3d2 --- /dev/null +++ b/Program/libcsp/include/csp/arch/csp_queue.h @@ -0,0 +1,126 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_ARCH_QUEUE_H_ +#define _CSP_ARCH_QUEUE_H_ + +/** + @file + + Queue interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + No error. + @note Value is 1! +*/ +#define CSP_QUEUE_OK 1 + +/** + Queue full. + @note Value is 0! +*/ +#define CSP_QUEUE_FULL 0 + +/** + Queue error. + @note Value is 0! +*/ +#define CSP_QUEUE_ERROR 0 + +/** + Queue handle. +*/ +typedef void * csp_queue_handle_t; + +/** + Create queue. + @param[in] length max length of queue, number of elements. + @param[in] item_size size of queue elements (bytes). + @return Create queue on success, otherwise NULL. +*/ +csp_queue_handle_t csp_queue_create(int length, size_t item_size); + +/** + Remove/delete queue. + @param[in] queue queue. +*/ +void csp_queue_remove(csp_queue_handle_t queue); + +/** + Enqueue (back) value. + @param[in] handle queue. + @param[in] value value to add (by copy) + @param[in] timeout timeout, time to wait for free space + @return #CSP_QUEUE_OK on success, otherwise a queue error code. +*/ +int csp_queue_enqueue(csp_queue_handle_t handle, const void *value, uint32_t timeout); + +/** + Enqueue (back) value from ISR. + @param[in] handle queue. + @param[in] value value to add (by copy) + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! + @return #CSP_QUEUE_OK on success, otherwise a queue error code. +*/ +int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * pxTaskWoken); + +/** + Dequeue value (front). + @param[in] handle queue. + @param[out] buf extracted element (by copy). + @param[in] timeout timeout, time to wait for element in queue. + @return #CSP_QUEUE_OK on success, otherwise a queue error code. +*/ +int csp_queue_dequeue(csp_queue_handle_t handle, void *buf, uint32_t timeout); + +/** + Dequeue value (front) from ISR. + @param[in] handle queue. + @param[out] buf extracted element (by copy). + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! + @return #CSP_QUEUE_OK on success, otherwise a queue error code. +*/ +int csp_queue_dequeue_isr(csp_queue_handle_t handle, void * buf, CSP_BASE_TYPE * pxTaskWoken); + +/** + Queue size. + @param[in] handle queue. + @return Number of elements in the queue. +*/ +int csp_queue_size(csp_queue_handle_t handle); + +/** + Queue size from ISR. + @param[in] handle queue. + @return Number of elements in the queue. +*/ +int csp_queue_size_isr(csp_queue_handle_t handle); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/csp_semaphore.h b/Program/libcsp/include/csp/arch/csp_semaphore.h new file mode 100755 index 0000000..bbb2625 --- /dev/null +++ b/Program/libcsp/include/csp/arch/csp_semaphore.h @@ -0,0 +1,206 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_SEMAPHORE_H_ +#define _CSP_SEMAPHORE_H_ + +/** + @file + + Semaphore and Mutex interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX interface */ +#if (CSP_POSIX || __DOXYGEN__) + +#include +#include + +/** + Semaphore (or mutex) call OK. + + @note Platform specific (this is Posix) and differs from standard CSP error codes. +*/ +#define CSP_SEMAPHORE_OK 1 +/** + Semaphore (or mutex) call failed. + + @note Platform specific (this is Posix) and differs from standard CSP error codes. +*/ +#define CSP_SEMAPHORE_ERROR 2 + +/** + Semaphore handle. + + @note Platform specific (this is Posix) +*/ +typedef sem_t csp_bin_sem_handle_t; +/** + Mutex handle. + + @note Platform specific (this is Posix) +*/ +typedef pthread_mutex_t csp_mutex_t; + +#endif // CSP_POSIX + +/* MAC OS X interface */ +#if (CSP_MACOSX) + +#include +#include "posix/pthread_queue.h" + +#define CSP_SEMAPHORE_OK PTHREAD_QUEUE_OK +#define CSP_SEMAPHORE_ERROR PTHREAD_QUEUE_EMPTY + +typedef pthread_queue_t * csp_bin_sem_handle_t; +typedef pthread_queue_t * csp_mutex_t; + +#endif // CSP_MACOSX + +#if (CSP_WINDOWS) + +#include + +#define CSP_SEMAPHORE_OK 1 +#define CSP_SEMAPHORE_ERROR 2 + +typedef HANDLE csp_bin_sem_handle_t; +typedef HANDLE csp_mutex_t; + +#endif // CSP_WINDOWS + +/* FreeRTOS interface */ +#if (CSP_FREERTOS) + +#include +#include + +#define CSP_SEMAPHORE_OK pdPASS +#define CSP_SEMAPHORE_ERROR pdFAIL + +typedef xSemaphoreHandle csp_bin_sem_handle_t; +typedef xSemaphoreHandle csp_mutex_t; + +#endif // CSP_FREERTOS + +/** + Mutex call OK. + + @note Value is different from standard CSP error codes, see #CSP_SEMAPHORE_OK +*/ +#define CSP_MUTEX_OK CSP_SEMAPHORE_OK + +/** + Mutex call failed. + + @note Value is different from standard CSP error codes, see #CSP_SEMAPHORE_ERROR +*/ +#define CSP_MUTEX_ERROR CSP_SEMAPHORE_ERROR + +/** + Create/initialize a mutex. + + @param[in] mutex mutex. + @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR +*/ +int csp_mutex_create(csp_mutex_t * mutex); + +/** + Free a mutex. + + @param[in] mutex mutex. + @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR +*/ +int csp_mutex_remove(csp_mutex_t * mutex); + +/** + Lock mutex. + + @param[in] mutex mutex + @param[in] timeout timeout in mS. Use #CSP_MAX_TIMEOUT for no timeout, e.g. wait forever until locked. + @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR +*/ +int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout); + +/** + Unlock mutex. + + @param[in] mutex mutex + @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR +*/ +int csp_mutex_unlock(csp_mutex_t * mutex); + +/** + Create/initialize a binary semaphore. + + The semaphore is created in state \a unlocked (value 1). + + On platforms supporting max values, the semaphore is created with a max value of 1, hence the naming \a binary. + + @param[in] sem semaphore + @return #CSP_SEMAPHORE_OK on success, otherwise #CSP_SEMAPHORE_ERROR +*/ +int csp_bin_sem_create(csp_bin_sem_handle_t * sem); + +/** + Free a semaphore. + + @param[in] sem semaphore. + @return #CSP_SEMAPHORE_OK on success, otherwise #CSP_SEMAPHORE_ERROR +*/ +int csp_bin_sem_remove(csp_bin_sem_handle_t * sem); + +/** + Wait/lock semaphore. + + @param[in] sem semaphore + @param[in] timeout timeout in mS. Use #CSP_MAX_TIMEOUT for no timeout, e.g. wait forever until locked. + @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR +*/ +int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout); + +/** + Signal/unlock semaphore. + + @param[in] sem semaphore + @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR +*/ +int csp_bin_sem_post(csp_bin_sem_handle_t * sem); + +/** + Signal/unlock semaphore from an ISR context. + + @param[in] sem semaphore + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! + @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR* +*/ +int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * pxTaskWoken); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/csp_system.h b/Program/libcsp/include/csp/arch/csp_system.h new file mode 100755 index 0000000..87eb506 --- /dev/null +++ b/Program/libcsp/include/csp/arch/csp_system.h @@ -0,0 +1,135 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_SYSTEM_H_ +#define _CSP_SYSTEM_H_ + +/** + @file + + System interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Color mask */ +#define COLOR_MASK_COLOR 0x0F +/** Color modifier mask */ +#define COLOR_MASK_MODIFIER 0xF0 + +/** + Color and color modifiers. +*/ +typedef enum { + /* Colors */ + COLOR_RESET = 0xF0, + COLOR_BLACK = 0x01, + COLOR_RED = 0x02, + COLOR_GREEN = 0x03, + COLOR_YELLOW = 0x04, + COLOR_BLUE = 0x05, + COLOR_MAGENTA = 0x06, + COLOR_CYAN = 0x07, + COLOR_WHITE = 0x08, + /* Modifiers */ + COLOR_NORMAL = 0x0F, + COLOR_BOLD = 0x10, + COLOR_UNDERLINE = 0x20, + COLOR_BLINK = 0x30, + COLOR_HIDE = 0x40, +} csp_color_t; + +/** + Get task list. + Write task list into a pre-allocate buffer. The buffer must be at least the size returned by csp_sys_tasklist_size(). + @param[out] out pre-allocate buffer for returning task. + @return #CSP_ERR_NONE on success. +*/ +int csp_sys_tasklist(char * out); + +/** + Get size of task buffer. + @return Size of task list buffer to allocate for the csp_sys_tasklist(). +*/ +int csp_sys_tasklist_size(void); + +/** + Free system memory. + + @return Free system memory (bytes) +*/ +uint32_t csp_sys_memfree(void); + +/** + Callback function for system reboot request. + @return #CSP_ERR_NONE on success (if function returns at all), or error code. +*/ +typedef int (*csp_sys_reboot_t)(void); + +/** + Set system reboot/reset function. + Function will be called by csp_sys_reboot(). + @param[in] reboot callback. + @see csp_sys_reboot_using_system(), csp_sys_reboot_using_reboot() +*/ +void csp_sys_set_reboot(csp_sys_reboot_t reboot); + +/** + Reboot/reset system. + Reboot/resets the system by calling the function set by csp_sys_set_reboot(). + @return #CSP_ERR_NONE on success (if function returns at all), or error code. +*/ +int csp_sys_reboot(void); + +/** + Callback function for system shutdown request. + @return #CSP_ERR_NONE on success (if function returns at all), or error code. +*/ +typedef int (*csp_sys_shutdown_t)(void); + +/** + Set system shutdown function. + Function will be called by csp_sys_shutdown(). + @param[in] shutdown callback. + @see csp_sys_shutdown_using_system(), csp_sys_shutdown_using_reboot() +*/ +void csp_sys_set_shutdown(csp_sys_shutdown_t shutdown); + +/** + Shutdown system. + Shuts down the system by calling the function set by csp_sys_set_shutdown(). + @return #CSP_ERR_NONE on success (if function returns at all), or error code. +*/ +int csp_sys_shutdown(void); + +/** + Set color on stdout. + @param[in] color color. +*/ +void csp_sys_set_color(csp_color_t color); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/csp_thread.h b/Program/libcsp/include/csp/arch/csp_thread.h new file mode 100755 index 0000000..6c2df59 --- /dev/null +++ b/Program/libcsp/include/csp/arch/csp_thread.h @@ -0,0 +1,133 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_THREAD_H_ +#define _CSP_THREAD_H_ + +/** + @file + + Thread (task) interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + POSIX interface +*/ +#if (CSP_POSIX || CSP_MACOSX || __DOXYGEN__) + +#include + +/** + Platform specific thread handle. +*/ +typedef pthread_t csp_thread_handle_t; + +/** + Platform specific thread return type. +*/ +typedef void * csp_thread_return_t; + +/** + Platform specific thread function. + @param[in] parameter parameter to thread function #csp_thread_return_t. +*/ +typedef csp_thread_return_t (* csp_thread_func_t)(void * parameter); + +/** + Macro for creating a thread. +*/ +#define CSP_DEFINE_TASK(task_name) csp_thread_return_t task_name(void * param) + +/** + Return value for a thread function. + Can be used as argument for normal return, eg "return CSP_TASK_RETURN"; +*/ +#define CSP_TASK_RETURN NULL + +#endif // CSP_POSIX + +/* + Windows interface +*/ +#if (CSP_WINDOWS) + +#include + +typedef HANDLE csp_thread_handle_t; +typedef unsigned int csp_thread_return_t; +typedef csp_thread_return_t (* csp_thread_func_t)(void *) __attribute__((stdcall)); + +#define CSP_DEFINE_TASK(task_name) csp_thread_return_t __attribute__((stdcall)) task_name(void * param) +#define CSP_TASK_RETURN 0 + +#endif // CSP_WINDOWS + +/* + FreeRTOS interface +*/ +#if (CSP_FREERTOS) + +#include +#include + +typedef xTaskHandle csp_thread_handle_t; +typedef void csp_thread_return_t; +typedef csp_thread_return_t (* csp_thread_func_t)(void *); + +#define CSP_DEFINE_TASK(task_name) csp_thread_return_t task_name(void * param) +#define CSP_TASK_RETURN + +#endif // CSP_FREERTOS + +/** + Create thread (task). + + @param[in] func thread function + @param[in] name name of thread, supported on: FreeRTOS. + @param[in] stack_size stack size, supported on: posix (bytes), FreeRTOS (words, word = 4 bytes). + @param[in] parameter parameter for thread function. + @param[in] priority thread priority, supported on: FreeRTOS. + @param[out] handle reference to created thread. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_thread_create(csp_thread_func_t func, const char * const name, unsigned int stack_size, void * parameter, unsigned int priority, csp_thread_handle_t * handle); + +/** + Exit current thread. + @note Not supported on all platforms. +*/ +void csp_thread_exit(void); + +/** + Sleep X mS. + @param[in] time_ms mS to sleep. +*/ +void csp_sleep_ms(unsigned int time_ms); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/csp_time.h b/Program/libcsp/include/csp/arch/csp_time.h new file mode 100755 index 0000000..f0a3867 --- /dev/null +++ b/Program/libcsp/include/csp/arch/csp_time.h @@ -0,0 +1,73 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_TIME_H_ +#define _CSP_TIME_H_ + +/** + @file + + Relative time interface. + + @note The returned values will eventually wrap. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Return uptime in seconds. + The function uses csp_get_s() for relative time. First time the function is called (by csp_init()), it saves an offset + in case the platform doesn't start from 0, e.g. Linux. + @return uptime in seconds. +*/ +uint32_t csp_get_uptime_s(void); + +/** + Return current time in mS. + @return mS. +*/ +uint32_t csp_get_ms(void); + +/** + Return current time in mS (from ISR). + @return mS. +*/ +uint32_t csp_get_ms_isr(void); + +/** + Return current time in seconds. + @return seconds. +*/ +uint32_t csp_get_s(void); + +/** + Return current time in seconds (from ISR). + @return seconds. +*/ +uint32_t csp_get_s_isr(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/posix/csp_system.h b/Program/libcsp/include/csp/arch/posix/csp_system.h new file mode 100755 index 0000000..785941d --- /dev/null +++ b/Program/libcsp/include/csp/arch/posix/csp_system.h @@ -0,0 +1,59 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_ARCH_POSIX_CSP_SYSTEM_H_ +#define _CSP_ARCH_POSIX_CSP_SYSTEM_H_ + +/** + @file + + Posix extension to system interface. +*/ + +#include + +#ifdef __cplusplus +yextern "C" { +#endif + +/** + Executes 'system("reboot")' for system reboot. +*/ +int csp_sys_reboot_using_system(void); + +/** + Executes 'sync() and reboot(LINUX_REBOOT_CMD_RESTART)' for system reboot. +*/ +int csp_sys_reboot_using_reboot(void); + +/** + Executes 'system("halt")' for system shutdown. +*/ +int csp_sys_shutdown_using_system(void); + +/** + Executes 'sync() and reboot(LINUX_REBOOT_CMD_HALT)' for system shutdown. +*/ +int csp_sys_shutdown_using_reboot(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/arch/posix/pthread_queue.h b/Program/libcsp/include/csp/arch/posix/pthread_queue.h new file mode 100755 index 0000000..19ac0c3 --- /dev/null +++ b/Program/libcsp/include/csp/arch/posix/pthread_queue.h @@ -0,0 +1,114 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _PTHREAD_QUEUE_H_ +#define _PTHREAD_QUEUE_H_ + +/** + @file + + Queue implemented using pthread locks and conds. + + Inspired by c-pthread-queue by Matthew Dickinson: http://code.google.com/p/c-pthread-queue/ +*/ + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Queue error codes. + @{ +*/ +/** + General error code - something went wrong. +*/ +#define PTHREAD_QUEUE_ERROR CSP_QUEUE_ERROR +/** + Queue is empty - cannot extract element. +*/ +#define PTHREAD_QUEUE_EMPTY CSP_QUEUE_ERROR +/** + Queue is full - cannot insert element. +*/ +#define PTHREAD_QUEUE_FULL CSP_QUEUE_ERROR +/** + Ok - no error. +*/ +#define PTHREAD_QUEUE_OK CSP_QUEUE_OK +/** @{ */ + +/** + Queue handle. +*/ +typedef struct pthread_queue_s { + //! Memory area. + void * buffer; + //! Memory size. + int size; + //! Item/element size. + int item_size; + //! Items/elements in queue. + int items; + //! Insert point. + int in; + //! Extract point. + int out; + //! Lock. + pthread_mutex_t mutex; + //! Wait because queue is full (insert). + pthread_cond_t cond_full; + //! Wait because queue is empty (extract). + pthread_cond_t cond_empty; +} pthread_queue_t; + +/** + Create queue. +*/ +pthread_queue_t * pthread_queue_create(int length, size_t item_size); + +/** + Delete queue. +*/ +void pthread_queue_delete(pthread_queue_t * q); + +/** + Enqueue/insert element. +*/ +int pthread_queue_enqueue(pthread_queue_t * queue, const void * value, uint32_t timeout); + +/** + Dequeue/extract element. +*/ +int pthread_queue_dequeue(pthread_queue_t * queue, void * buf, uint32_t timeout); + +/** + Return number of elements in the queue. +*/ +int pthread_queue_items(pthread_queue_t * queue); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/crypto/csp_hmac.h b/Program/libcsp/include/csp/crypto/csp_hmac.h new file mode 100755 index 0000000..31eabb4 --- /dev/null +++ b/Program/libcsp/include/csp/crypto/csp_hmac.h @@ -0,0 +1,82 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_CRYPTO_HMAC_H_ +#define _CSP_CRYPTO_HMAC_H_ + +/** + @file + HMAC support. + + Hash-based Message Authentication Code - based on code from libtom.org. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Number of bytes from the HMAC calculation, that is appended to the CSP message. +*/ +#define CSP_HMAC_LENGTH 4 + +/** + * Append HMAC to packet + * @param packet CSP packet, must be valid. + * @param include_header use header in hmac calculation (this will not modify the flags field) + * @return #CSP_ERR_NONE on success, otherwise an error code. + */ +int csp_hmac_append(csp_packet_t * packet, bool include_header); + +/** + * Verify HMAC of packet + * @param packet CSP packet, must be valid. + * @param include_header use header in hmac calculation (this will not modify the flags field) + * @return #CSP_ERR_NONE on success, otherwise an error code. + */ +int csp_hmac_verify(csp_packet_t * packet, bool include_header); + +/** + * Calculate HMAC on buffer + * + * This function is used by append/verify but cal also be called separately. + * @param key HMAC key + * @param keylen HMAC key length + * @param data pointer to data + * @param datalen lehgth of data + * @param[out] hmac calculated HMAC hash, minimum #CSP_SHA1_DIGESTSIZE bytes. + * @return #CSP_ERR_NONE on success, otherwise an error code. + */ +int csp_hmac_memory(const void * key, uint32_t keylen, const void * data, uint32_t datalen, uint8_t * hmac); + +/** + * Save a copy of the key string for use by the append/verify functions + * @param key HMAC key + * @param keylen HMAC key length + * @return #CSP_ERR_NONE on success, otherwise an error code. + */ +int csp_hmac_set_key(const void * key, uint32_t keylen); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/crypto/csp_sha1.h b/Program/libcsp/include/csp/crypto/csp_sha1.h new file mode 100755 index 0000000..43b4a67 --- /dev/null +++ b/Program/libcsp/include/csp/crypto/csp_sha1.h @@ -0,0 +1,89 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_CRYPTO_SHA1_H_ +#define _CSP_CRYPTO_SHA1_H_ + +/** + @file + SHA1 support. + + Code originally from Python's SHA1 Module, who based it on libtom.org. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** The SHA1 block size in bytes */ +#define CSP_SHA1_BLOCKSIZE 64 + +/** The SHA1 digest (hash) size in bytes */ +#define CSP_SHA1_DIGESTSIZE 20 + +/** + SHA1 state. +*/ +typedef struct { + //! Internal SHA1 state. + uint64_t length; + //! Internal SHA1 state. + uint32_t state[5]; + //! Internal SHA1 state. + uint32_t curlen; + //! Internal SHA1 state. + uint8_t buf[CSP_SHA1_BLOCKSIZE]; +} csp_sha1_state_t; + +/** + Initialize the hash state + @param[in] state hash state. +*/ +void csp_sha1_init(csp_sha1_state_t * state); + +/** + Process a block of memory through the hash. + @param[in] state hash state + @param[in] data data. + @param[in] length length of \a data. +*/ +void csp_sha1_process(csp_sha1_state_t * state, const void * data, uint32_t length); + +/** + Terminate the hash calculation and get the SHA1. + @param[in] state hash state + @param[out] sha1 user supplied buffer of minimum #CSP_SHA1_DIGESTSIZE bytes. +*/ +void csp_sha1_done(csp_sha1_state_t * state, uint8_t * sha1); + +/** + Calculate SHA1 hash of block of memory. + @param[in] data data. + @param[in] length length of \a data. + @param[out] sha1 user supplied buffer of minimum #CSP_SHA1_DIGESTSIZE bytes. +*/ +void csp_sha1_memory(const void * data, uint32_t length, uint8_t * sha1); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/crypto/csp_xtea.h b/Program/libcsp/include/csp/crypto/csp_xtea.h new file mode 100755 index 0000000..3324e62 --- /dev/null +++ b/Program/libcsp/include/csp/crypto/csp_xtea.h @@ -0,0 +1,78 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_CRYPTO_XTEA_H_ +#define _CSP_CRYPTO_XTEA_H_ + +/** + @file + XTEA support. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Set XTEA key + @param[in] key XTEA key + @param[in] keylen length of key + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_xtea_set_key(const void * key, uint32_t keylen); + +/** + XTEA encrypt byte array + @param[in] data data to be encrypted. + @param[in] len Length of \a data. + @param[in] iv Initialization vector + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_xtea_encrypt(void * data, uint32_t len, uint32_t iv[2]); + +/** + XTEA encrypt message. + @param packet CSP packet, must be valid. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_xtea_encrypt_packet(csp_packet_t * packet); + +/** + Decrypt XTEA encrypted byte array. + @param[in,out] encrypted data be decrypted. + @param[in] len length of \a encrypted data. + @param[in] iv Initialization vector. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_xtea_decrypt(void * encrypted, uint32_t len, uint32_t iv[2]); + +/** + XTEA decrypt message. + @param packet CSP packet, must be valid. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_xtea_decrypt_packet(csp_packet_t * packet); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp.h b/Program/libcsp/include/csp/csp.h new file mode 100755 index 0000000..959fbd2 --- /dev/null +++ b/Program/libcsp/include/csp/csp.h @@ -0,0 +1,491 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_H_ +#define _CSP_H_ + +/** + @file + CSP. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + CSP configuration. + @see csp_init() +*/ +typedef struct csp_conf_s { + + uint8_t address; /**< CSP address of the system */ + + const char *hostname; /**< Host name, returned by the #CSP_CMP_IDENT request */ + const char *model; /**< Model, returned by the #CSP_CMP_IDENT request */ + const char *revision; /**< Revision, returned by the #CSP_CMP_IDENT request */ + + uint8_t conn_max; /**< Max number of connections. A fixed connection array is allocated by csp_init() */ + uint8_t conn_queue_length; /**< Max queue length (max queued Rx messages). */ + uint8_t fifo_length; /**< Length of incoming message queue, used for handover to router task. */ + uint8_t port_max_bind; /**< Max/highest port for use with csp_bind() */ + uint8_t rdp_max_window; /**< Max RDP window size */ + uint16_t buffers; /**< Number of CSP buffers */ + uint16_t buffer_data_size; /**< Data size of a CSP buffer. Total size will be sizeof(#csp_packet_t) + data_size. */ + uint32_t conn_dfl_so; /**< Default connection options. Options will always be or'ed onto new connections, see csp_connect() */ +} csp_conf_t; + +/** + Get default CSP configuration. +*/ +static inline void csp_conf_get_defaults(csp_conf_t * conf) { + conf->address = 1; + conf->hostname = "hostname"; + conf->model = "model"; + conf->revision = "resvision"; + conf->conn_max = 10; + conf->conn_queue_length = 10; + conf->fifo_length = 25; + conf->port_max_bind = 24; + conf->rdp_max_window = 20; + conf->buffers = 10; + conf->buffer_data_size = 256; + conf->conn_dfl_so = CSP_O_NONE; +} + +/** + Initialize CSP. + This will configure/allocate basic structures. + @param[in] conf configuration. A shallow copy will be done of the provided configuration, i.e. only copy references to strings/structers. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_init(const csp_conf_t * conf); + +/** + Free allocated resorces in CSP. + This is intended for testing of CSP, in order to be able re-initialize CSP by calling csp_init() again. +*/ +void csp_free_resources(void); + +/** + Get a \a read-only reference to the active CSP configuration. + @return Active CSP configuration (read-only). +*/ +const csp_conf_t * csp_get_conf(void); + +/** + Get the system's own address. + @return system's own address +*/ +uint8_t csp_get_address(void); + +/** + Create a CSP socket endpoint. + @param[in] opts socket options, see @ref CSP_SOCKET_OPTIONS. + @return Socket on success, NULL on failure +*/ +csp_socket_t *csp_socket(uint32_t opts); + +/** + Wait/accept a new connection. + @param[in] socket socket to accept connections on, created by calling csp_socket(). + @param[in] timeout timeout in mS to wait for a connection, use #CSP_MAX_TIMEOUT for infinite timeout. + @return New connection on success, NULL on failure or timeout. +*/ +csp_conn_t *csp_accept(csp_socket_t *socket, uint32_t timeout); + +/** + Read packet from a connection. + This fuction will wait on the connection's RX queue for the specified timeout. + @param[in] conn connection + @param[in] timeout timeout in mS to wait for a packet, use #CSP_MAX_TIMEOUT for infinite timeout. + @return Packet or NULL in case of failure or timeout. +*/ +csp_packet_t *csp_read(csp_conn_t *conn, uint32_t timeout); + +/** + Send packet on a connection. + @param[in] conn connection + @param[in] packet packet to send + @param[in] timeout unused as of CSP version 1.6 + @return 1 on success, 0 on failure and the packet must be freed by calling csp_buffer_free() +*/ +int csp_send(csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout); + +/** + Change the default priority of the connection and send a packet. + @note The priority of the connection will be changed. If you need to change it back, call csp_send_prio() again. + + @param[in] prio priority to set on the connection + @param[in] conn connection + @param[in] packet packet to send + @param[in] timeout unused as of CSP version 1.6 + @return 1 on success, 0 on failure and the packet must be freed by calling csp_buffer_free() + */ +int csp_send_prio(uint8_t prio, csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout); + +/** + Perform an entire request & reply transaction. + Creates a connection, send \a outbuf, wait for reply, copy reply to \a inbuf and close the connection. + @param[in] prio priority, see #csp_prio_t + @param[in] dst destination address + @param[in] dst_port destination port + @param[in] timeout timeout in mS to wait for a reply + @param[in] outbuf outgoing data (request) + @param[in] outlen length of data in \a outbuf (request) + @param[out] inbuf user provided buffer for receiving data (reply) + @param[in] inlen length of expected reply, -1 for unknown size (inbuf MUST be large enough), 0 for no reply. + @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. + @return 1 or reply size on success, 0 on failure (error, incoming length does not match, timeout) +*/ +int csp_transaction_w_opts(uint8_t prio, uint8_t dst, uint8_t dst_port, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen, uint32_t opts); + +/** + Perform an entire request & reply transaction. + Creates a connection, send \a outbuf, wait for reply, copy reply to \a inbuf and close the connection. + @param[in] prio priority, see #csp_prio_t + @param[in] dest destination address + @param[in] port destination port + @param[in] timeout timeout in mS to wait for a reply + @param[in] outbuf outgoing data (request) + @param[in] outlen length of data in \a outbuf (request) + @param[out] inbuf user provided buffer for receiving data (reply) + @param[in] inlen length of expected reply, -1 for unknown size (inbuf MUST be large enough), 0 for no reply. + @return 1 or reply size on success, 0 on failure (error, incoming length does not match, timeout) +*/ +static inline int csp_transaction(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void * outbuf, int outlen, void * inbuf, int inlen) { + return csp_transaction_w_opts(prio, dest, port, timeout, outbuf, outlen, inbuf, inlen, 0); +} + +/** + Perform an entire request & reply transaction on an existing connection. + Send \a outbuf, wait for reply and copy reply to \a inbuf. + @param[in] conn connection + @param[in] timeout timeout in mS to wait for a reply + @param[in] outbuf outgoing data (request) + @param[in] outlen length of data in \a outbuf (request) + @param[out] inbuf user provided buffer for receiving data (reply) + @param[in] inlen length of expected reply, -1 for unknown size (inbuf MUST be large enough), 0 for no reply. + @return 1 or reply size on success, 0 on failure (error, incoming length does not match, timeout) +*/ +int csp_transaction_persistent(csp_conn_t *conn, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen); + +/** + Read data from a connection-less server socket. + @param[in] socket connection-less socket. + @param[in] timeout timeout in mS to wait for a packet, use #CSP_MAX_TIMEOUT for infinite timeout. + @return Packet on success, or NULL on failure or timeout. +*/ +csp_packet_t *csp_recvfrom(csp_socket_t *socket, uint32_t timeout); + +/** + Send a packet (without connection). + @param[in] prio packet priority, see #csp_prio_t + @param[in] dst destination address + @param[in] dst_port destination port + @param[in] src_port source port + @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. + @param[in] packet packet to send + @param[in] timeout unused as of CSP version 1.6 + @return #CSP_ERR_NONE on success, otherwise an error code and the packet must be freed by calling csp_buffer_free(). +*/ +int csp_sendto(uint8_t prio, uint8_t dst, uint8_t dst_port, uint8_t src_port, uint32_t opts, csp_packet_t *packet, uint32_t timeout); + +/** + Send a packet as a reply to a request (without a connection). + Calls csp_sendto() with the source address and port from the request. + @param[in] request incoming request + @param[in] reply reply packet + @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. + @param[in] timeout unused as of CSP version 1.6 + @return #CSP_ERR_NONE on success, otherwise an error code and the reply must be freed by calling csp_buffer_free(). +*/ +int csp_sendto_reply(const csp_packet_t * request, csp_packet_t * reply, uint32_t opts, uint32_t timeout); + +/** + Establish outgoing connection. + The call will return immediately, unless it is a RDP connection (#CSP_O_RDP) in which case it will wait until the other + end acknowleges the connection (timeout is determined by the current connection timeout set by csp_rdp_set_opt()). + @param[in] prio priority, see #csp_prio_t + @param[in] dst Destination address + @param[in] dst_port Destination port + @param[in] timeout unused. + @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. + @return Established connection or NULL on failure (no free connections, timeout). +*/ +csp_conn_t *csp_connect(uint8_t prio, uint8_t dst, uint8_t dst_port, uint32_t timeout, uint32_t opts); + +/** + Close an open connection. + Any packets in the RX queue will be freed. + @param[in] conn connection. Closing a NULL connection is acceptable. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_close(csp_conn_t *conn); + +/** + Return destination port of connection. + @param[in] conn connection + @return destination port of an incoming connection +*/ +int csp_conn_dport(csp_conn_t *conn); + +/** + Return source port of connection. + @param conn connection + @return source port of an incoming connection +*/ +int csp_conn_sport(csp_conn_t *conn); + +/** + Return destination address of connection. + @param[in] conn connection + @return destination address of an incoming connection +*/ +int csp_conn_dst(csp_conn_t *conn); + +/** + Return source address of connection. + @param conn connection + @return source address of an incoming connection +*/ +int csp_conn_src(csp_conn_t *conn); + +/** + Return flags of connection. + @param[in] conn connection + @return flags of an incoming connection, see @ref CSP_HEADER_FLAGS +*/ +int csp_conn_flags(csp_conn_t *conn); + +/** + Set socket to listen for incoming connections. + @param[in] socket socket + @param[in] backlog max length of backlog queue. The backlog queue holds incoming connections, waiting to be returned by call to csp_accept(). + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_listen(csp_socket_t *socket, size_t backlog); + +/** + Bind port to socket. + @param[in] socket socket to bind port to + @param[in] port port number to bind, use #CSP_ANY for all ports. Bindnig to a specific will take precedence over #CSP_ANY. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_bind(csp_socket_t *socket, uint8_t port); + +/** + Start the router task. + The router task calls csp_route_work() to do the actual work. + @param[in] task_stack_size stack size for the task, see csp_thread_create() for details on the stack size parameter. + @param[in] task_priority priority for the task, see csp_thread_create() for details on the stack size parameter. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_route_start_task(unsigned int task_stack_size, unsigned int task_priority); + +/** + Route packet from the incoming router queue and check RDP timeouts. + In order for incoming packets to routed and RDP timeouts to be checked, this function must be called reguarly. + If the router task is started by calling csp_route_start_task(), there function should not be called. + @param[in] timeout timeout in mS to wait for an incoming packet. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_route_work(uint32_t timeout); + +/** + Start the bridge task. + The bridge will copy packets between interfaces, i.e. packets received on A will be sent on B, and vice versa. + @param[in] task_stack_size stack size for the task, see csp_thread_create() for details on the stack size parameter. + @param[in] task_priority priority for the task, see csp_thread_create() for details on the stack size parameter. + @param[in] if_a interface/side A + @param[in] if_b interface/side B + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_bridge_start(unsigned int task_stack_size, unsigned int task_priority, csp_iface_t * if_a, csp_iface_t * if_b); + +/** + Handle CSP service request. + If the given packet is a service-request (the destination port matches one of CSP service ports #csp_service_port_t), + the packet will be processed by the specific CSP service handler. + The packet will either process it or free it, so this function is typically called in the last "default" clause of + a switch/case statement in a CSP listener task. + In order to listen to csp service ports, bind your listener to the specific services ports #csp_service_port_t or + use #CSP_ANY to all ports. + @param[in] conn connection + @param[in] packet first packet, obtained by using csp_read() +*/ +void csp_service_handler(csp_conn_t *conn, csp_packet_t *packet); + +/** + Send a single ping/echo packet. + @param[in] node address of subsystem. + @param[in] timeout timeout in ms to wait for reply. + @param[in] size payload size in bytes. + @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. + @return >0 = echo time in mS on success, otherwise -1 for error. +*/ +int csp_ping(uint8_t node, uint32_t timeout, unsigned int size, uint8_t opts); + +/** + Send a single ping/echo packet without waiting for reply. + Payload is 1 byte. + @param[in] node address of subsystem. +*/ +void csp_ping_noreply(uint8_t node); + +/** + Request process list. + @note This is currently only supported on FreeRTOS systems. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for replies. The function will not return until the timeout occurrs. +*/ +void csp_ps(uint8_t node, uint32_t timeout); + +/** + Request free memory. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply. + @param[out] size free memory on subsystem. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_get_memfree(uint8_t node, uint32_t timeout, uint32_t * size); + +/** + Request free memory and print to stdout. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply. +*/ +void csp_memfree(uint8_t node, uint32_t timeout); + +/** + Request free buffers. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply. + @param[out] size free buffers. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_get_buf_free(uint8_t node, uint32_t timeout, uint32_t * size); + +/** + Request free buffers and print to stdout. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply. +*/ +void csp_buf_free(uint8_t node, uint32_t timeout); + +/** + Reboot subsystem. + If handled by the standard CSP service handler, the reboot handler set by csp_sys_set_reboot() on the subsystem, will be invoked. + @param[in] node address of subsystem. +*/ +void csp_reboot(uint8_t node); + +/** + Shutdown subsystem. + If handled by the standard CSP service handler, the shutdown handler set by csp_sys_set_shutdown() on the subsystem, will be invoked. + @param[in] node address of subsystem. +*/ +void csp_shutdown(uint8_t node); + +/** + Request uptime and print to stdout. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply. +*/ +void csp_uptime(uint8_t node, uint32_t timeout); + +/** + Request uptime + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply. + @param[out] uptime uptime in seconds. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_get_uptime(uint8_t node, uint32_t timeout, uint32_t * uptime); + +/** + Set RDP options. + The RDP options are used from the connecting/client side. When a RDP connection is established, the client tranmits the options to the server. + @param[in] window_size window size + @param[in] conn_timeout_ms connection timeout in mS + @param[in] packet_timeout_ms packet timeout in mS. + @param[in] delayed_acks enable/disable delayed acknowledgements. + @param[in] ack_timeout acknowledgement timeout when delayed ACKs is enabled + @param[in] ack_delay_count send acknowledgement for every ack_delay_count packets. +*/ +void csp_rdp_set_opt(unsigned int window_size, unsigned int conn_timeout_ms, + unsigned int packet_timeout_ms, unsigned int delayed_acks, + unsigned int ack_timeout, unsigned int ack_delay_count); + +/** + Get RDP options. + @see csp_rdp_set_opt() + @param[out] window_size Window size + @param[out] conn_timeout_ms connection timeout in ms + @param[out] packet_timeout_ms packet timeout in ms + @param[out] delayed_acks enable/disable delayed acknowledgements + @param[out] ack_timeout acknowledgement timeout when delayed ACKs is enabled + @param[out] ack_delay_count send acknowledgement for every ack_delay_count packets +*/ +void csp_rdp_get_opt(unsigned int *window_size, unsigned int *conn_timeout_ms, + unsigned int *packet_timeout_ms, unsigned int *delayed_acks, + unsigned int *ack_timeout, unsigned int *ack_delay_count); + +/** + Print connection table to stdout. +*/ +void csp_conn_print_table(void); + +/** + Print connection table to string. +*/ +int csp_conn_print_table_str(char * str_buf, int str_size); + +/** + Print buffer usage table to stdout. +*/ +void csp_buffer_print_table(void); + +/** + Hex dump memory to stdout. + @param[in] desc description printed on first line. + @param[in] addr memory address. + @param[in] len number of bytes to dump, starting from \a addr. +*/ +void csp_hex_dump(const char *desc, void *addr, int len); + +/** + Set platform specific memory copy function. +*/ +void csp_cmp_set_memcpy(csp_memcpy_fnc_t fnc); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_buffer.h b/Program/libcsp/include/csp/csp_buffer.h new file mode 100755 index 0000000..d8d9752 --- /dev/null +++ b/Program/libcsp/include/csp/csp_buffer.h @@ -0,0 +1,94 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_BUFFER_H_ +#define _CSP_BUFFER_H_ + +/** + @file + Message buffer. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Get free buffer (from task context). + + @param[in] data_size minimum data size of requested buffer. + @return Buffer (pointer to #csp_packet_t) or NULL if no buffers available or size too big. +*/ +void * csp_buffer_get(size_t data_size); + +/** + Get free buffer (from ISR context). + + @param[in] data_size minimum data size of requested buffer. + @return Buffer (pointer to #csp_packet_t) or NULL if no buffers available or size too big. +*/ +void * csp_buffer_get_isr(size_t data_size); + +/** + Free buffer (from task context). + @param[in] buffer buffer to free. NULL is handled gracefully. +*/ +void csp_buffer_free(void *buffer); + +/** + Free buffer (from ISR context). + @param[in] buffer buffer to free. NULL is handled gracefully. +*/ +void csp_buffer_free_isr(void *buffer); + +/** + Clone an existing buffer. + The existing \a buffer content is copied to the new buffer. + @param[in] buffer buffer to clone. + @return cloned buffer on success, or NULL on failure. +*/ +void * csp_buffer_clone(void *buffer); + +/** + Return number of remaining/free buffers. + The number of buffers is set by csp_init(). + @return number of remaining/free buffers +*/ +int csp_buffer_remaining(void); + +/** + Return the size of a CSP buffer. + @return size of a CSP buffer, sizeof(#csp_packet_t) + data_size. +*/ +size_t csp_buffer_size(void); + +/** + Return the data size of a CSP buffer. + The data size is set by csp_init(). + @return data size of a CSP buffer +*/ +size_t csp_buffer_data_size(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_cmp.h b/Program/libcsp/include/csp/csp_cmp.h new file mode 100755 index 0000000..58d5b57 --- /dev/null +++ b/Program/libcsp/include/csp/csp_cmp.h @@ -0,0 +1,214 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_CMP_H_ +#define _CSP_CMP_H_ + +/** + @file + CSP Management Protocol (CMP). +*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + CMP type. + @{ +*/ +/** + CMP request. +*/ +#define CSP_CMP_REQUEST 0x00 +/** + CMP reply. +*/ +#define CSP_CMP_REPLY 0xff +/**@}*/ + +/** + CMP requests. + @{ +*/ +/** + CMP request codes. +*/ +/** + Request identification, compile time, revision, hostname and model. +*/ +#define CSP_CMP_IDENT 1 +/** + Set/configure routing. +*/ +#define CSP_CMP_ROUTE_SET 2 +/** + Request interface statistics. +*/ +#define CSP_CMP_IF_STATS 3 +/** + Peek/read data from memory. +*/ +#define CSP_CMP_PEEK 4 +/** + Poke/write data from memory. +*/ +#define CSP_CMP_POKE 5 +/** + Get/set clock. +*/ +#define CSP_CMP_CLOCK 6 +/**@}*/ + +/** + CMP identification - max revision length. +*/ +#define CSP_CMP_IDENT_REV_LEN 20 +/** + CMP identification - max date length. +*/ +#define CSP_CMP_IDENT_DATE_LEN 12 +/** + CMP identification - max time length. +*/ +#define CSP_CMP_IDENT_TIME_LEN 9 + +/** + CMP interface statistics - max interface name length. +*/ +#define CSP_CMP_ROUTE_IFACE_LEN 11 + +/** + CMP peek/read memeory - max read length. +*/ +#define CSP_CMP_PEEK_MAX_LEN 200 + +/** + CMP poke/write memeory - max write length. +*/ +#define CSP_CMP_POKE_MAX_LEN 200 + +/** + CSP management protocol description. +*/ +struct csp_cmp_message { + //! CMP request type. + uint8_t type; + //! CMP request code. + uint8_t code; + union { + struct { + char hostname[CSP_HOSTNAME_LEN]; + char model[CSP_MODEL_LEN]; + char revision[CSP_CMP_IDENT_REV_LEN]; + char date[CSP_CMP_IDENT_DATE_LEN]; + char time[CSP_CMP_IDENT_TIME_LEN]; + } ident; + struct { + uint8_t dest_node; + uint8_t next_hop_via; + char interface[CSP_CMP_ROUTE_IFACE_LEN]; + } route_set; + struct __attribute__((__packed__)) { + char interface[CSP_CMP_ROUTE_IFACE_LEN]; + uint32_t tx; + uint32_t rx; + uint32_t tx_error; + uint32_t rx_error; + uint32_t drop; + uint32_t autherr; + uint32_t frame; + uint32_t txbytes; + uint32_t rxbytes; + uint32_t irq; + } if_stats; + struct { + uint32_t addr; + uint8_t len; + char data[CSP_CMP_PEEK_MAX_LEN]; + } peek; + struct { + uint32_t addr; + uint8_t len; + char data[CSP_CMP_POKE_MAX_LEN]; + } poke; + csp_timestamp_t clock; + }; +} __attribute__ ((packed)); + +/** + Macro for calculating total size of management message. +*/ +#define CMP_SIZE(_memb) (sizeof(((struct csp_cmp_message *)0)->type) + sizeof(((struct csp_cmp_message *)0)->code) + sizeof(((struct csp_cmp_message *)0)->_memb)) + +/** + Generic send management message request. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply.. + @param[in] code request code. + @param[in] msg_size size of \a msg. + @param[in,out] msg data. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_cmp(uint8_t node, uint32_t timeout, uint8_t code, int msg_size, struct csp_cmp_message *msg); + +/** + Macro for defining management handling function. +*/ +#define CMP_MESSAGE(_code, _memb) \ +static inline int csp_cmp_##_memb(uint8_t node, uint32_t timeout, struct csp_cmp_message *msg) { \ + return csp_cmp(node, timeout, _code, CMP_SIZE(_memb), msg); \ +} + +CMP_MESSAGE(CSP_CMP_IDENT, ident) +CMP_MESSAGE(CSP_CMP_ROUTE_SET, route_set) +CMP_MESSAGE(CSP_CMP_IF_STATS, if_stats) +CMP_MESSAGE(CSP_CMP_CLOCK, clock) + +/** + Peek (read) memory on remote node. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply.. + @param[in] msg memory address and number of bytes to peek. + @param[out] msg peeked/read memory. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +static inline int csp_cmp_peek(uint8_t node, uint32_t timeout, struct csp_cmp_message *msg) { + return csp_cmp(node, timeout, CSP_CMP_PEEK, CMP_SIZE(peek) - sizeof(msg->peek.data) + msg->peek.len, msg); +} + +/** + Poke (write) memory on remote node. + @param[in] node address of subsystem. + @param[in] timeout timeout in mS to wait for reply.. + @param[in] msg memory address, number of bytes and the actual bytes to poke/write. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +static inline int csp_cmp_poke(uint8_t node, uint32_t timeout, struct csp_cmp_message *msg) { + return csp_cmp(node, timeout, CSP_CMP_POKE, CMP_SIZE(poke) - sizeof(msg->poke.data) + msg->poke.len, msg); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_crc32.h b/Program/libcsp/include/csp/csp_crc32.h new file mode 100755 index 0000000..5ff92eb --- /dev/null +++ b/Program/libcsp/include/csp/csp_crc32.h @@ -0,0 +1,62 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_CRC32_H_ +#define _CSP_CRC32_H_ + +/** + @file + CRC32 support. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Append CRC32 checksum to packet + @param[in] packet CSP packet, must be valid. + @param[in] include_header include the CSP header in the CRC32, otherwise just the data part. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_crc32_append(csp_packet_t * packet, bool include_header); + +/** + Verify CRC32 checksum on packet. + @param[in] packet CSP packet, must be valid. + @param[in] include_header include the CSP header in the CRC32, otherwise just the data part. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_crc32_verify(csp_packet_t * packet, bool include_header); + +/** + Calculate checksum for a given memory area. + @param[in] addr memory address + @param[in] length length of memory to do checksum on + @return checksum +*/ +uint32_t csp_crc32_memory(const uint8_t * addr, uint32_t length); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_debug.h b/Program/libcsp/include/csp/csp_debug.h new file mode 100755 index 0000000..f01b547 --- /dev/null +++ b/Program/libcsp/include/csp/csp_debug.h @@ -0,0 +1,226 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_DEBUG_H_ +#define _CSP_DEBUG_H_ + +/** + @file + Debug and log. +*/ + +#include +#include +#include +#include + +#include + +#if (CSP_USE_EXTERNAL_DEBUG) +/* Use external csp_debug API */ +#include + +#else + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Debug levels. +*/ +typedef enum { + CSP_ERROR = 0, //!< Error + CSP_WARN = 1, //!< Warning + CSP_INFO = 2, //!< Informational + CSP_BUFFER = 3, //!< Buffer, e.g. csp_packet get/free + CSP_PACKET = 4, //!< Packet routing + CSP_PROTOCOL = 5, //!< Protocol, i.e. RDP + CSP_LOCK = 6, //!< Locking, i.e. semaphore +} csp_debug_level_t; + +/** + Debug level enabled/disabled. +*/ +extern bool csp_debug_level_enabled[]; + +/** + Extract filename component from path +*/ +#define BASENAME(_file) ((strrchr(_file, '/') ? : (strrchr(_file, '\\') ? : _file)) + 1) + +/** + Implement csp_assert_fail_action to override default failure action +*/ +extern void __attribute__((weak)) csp_assert_fail_action(const char *assertion, const char *file, int line); + +/** + CSP assert. +*/ +#if (!defined(NDEBUG) || CSP_USE_ASSERT) +#define csp_assert(exp) { \ + if (!(exp)) { \ + const char *assertion = #exp; \ + const char *file = BASENAME(__FILE__); \ + int line = __LINE__; \ + printf("\E[1;31mAssertion \'%s\' failed in %s:%d\E[0m\r\n", \ + assertion, file, line); \ + if (csp_assert_fail_action) \ + csp_assert_fail_action(assertion, file, line); \ + } \ + } +#else +#define csp_assert(...) {} +#endif + +#if !(__DOXYGEN__) +/* Ensure defines are 'defined' */ +#if !defined(CSP_DEBUG) +#define CSP_DEBUG 0 +#endif + +#if !defined(CSP_LOG_LEVEL_DEBUG) +#define CSP_LOG_LEVEL_DEBUG 0 +#endif + +#if !defined(CSP_LOG_LEVEL_INFO) +#define CSP_LOG_LEVEL_INFO 0 +#endif + +#if !defined(CSP_LOG_LEVEL_WARN) +#define CSP_LOG_LEVEL_WARN 0 +#endif + +#if !defined(CSP_LOG_LEVEL_ERROR) +#define CSP_LOG_LEVEL_ERROR 0 +#endif +#endif // __DOXYGEN__ + +#ifdef __AVR__ + #include + #include + #define CONSTSTR(data) PSTR(data) + #undef printf + #undef sscanf + #undef scanf + #undef sprintf + #undef snprintf + #define printf(s, ...) printf_P(PSTR(s), ## __VA_ARGS__) + #define sscanf(buf, s, ...) sscanf_P(buf, PSTR(s), ## __VA_ARGS__) + #define scanf(s, ...) scanf_P(PSTR(s), ## __VA_ARGS__) + #define sprintf(buf, s, ...) sprintf_P(buf, PSTR(s), ## __VA_ARGS__) + #define snprintf(buf, size, s, ...) snprintf_P(buf, size, PSTR(s), ## __VA_ARGS__) +#define csp_debug(level, format, ...) { if (CSP_DEBUG && csp_debug_level_enabled[level]) do_csp_debug(level, PSTR(format), ##__VA_ARGS__); } +#else +/** + * Log message with specific level. + * @param level log level + * @param format log message, printf syntax. + */ +#define csp_debug(level, format, ...) { if (CSP_DEBUG && csp_debug_level_enabled[level]) do_csp_debug(level, format, ##__VA_ARGS__); } +#endif + +/** + * Log message with level #CSP_ERROR. + * @param format log message, printf syntax. + */ +#define csp_log_error(format, ...) { if (CSP_LOG_LEVEL_ERROR) csp_debug(CSP_ERROR, format, ##__VA_ARGS__); } + +/** + * Log message with level #CSP_WARN. + * @param format log message, printf syntax. + */ +#define csp_log_warn(format, ...) { if (CSP_LOG_LEVEL_WARN) csp_debug(CSP_WARN, format, ##__VA_ARGS__); } + +/** + * Log message with level #CSP_INFO. + * @param format log message, printf syntax. + */ +#define csp_log_info(format, ...) { if (CSP_LOG_LEVEL_INFO) csp_debug(CSP_INFO, format, ##__VA_ARGS__); } + +/** + * Log message with level #CSP_BUFFER. + * @param format log message, printf syntax. + */ +#define csp_log_buffer(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_BUFFER, format, ##__VA_ARGS__); } + +/** + * Log message with level #CSP_PACKET. + * @param format log message, printf syntax. + */ +#define csp_log_packet(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_PACKET, format, ##__VA_ARGS__); } + +/** + * Log message with level #CSP_PROTOCOL. + * @param format log message, printf syntax. + */ +#define csp_log_protocol(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_PROTOCOL, format, ##__VA_ARGS__); } + +/** + * Log message with level #CSP_LOCK. + * @param format log message, printf syntax. + */ +#define csp_log_lock(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_LOCK, format, ##__VA_ARGS__); } + +/** + * Do the actual logging (don't use directly). + * @note Use the csp_log_() macros instead. + * @param level log level + * @param format log message, printf syntax. + */ +void do_csp_debug(csp_debug_level_t level, const char *format, ...) __attribute__ ((format (__printf__, 2, 3))); + +/** + * Toggle debug level on/off + * @param level Level to toggle + */ +void csp_debug_toggle_level(csp_debug_level_t level); + +/** + * Set debug level + * @param level Level to set + * @param value New level value + */ +void csp_debug_set_level(csp_debug_level_t level, bool value); + +/** + * Get current debug level value + * @param level Level to get + * @return Level value + */ +int csp_debug_get_level(csp_debug_level_t level); + +/** + * Debug hook function. + */ +typedef void (*csp_debug_hook_func_t)(csp_debug_level_t level, const char *format, va_list args); + +/** + * Set debug/log hook function. + */ +void csp_debug_hook_set(csp_debug_hook_func_t f); + +#ifdef __cplusplus +} +#endif + +#endif // CSP_USE_EXTERNAL_DEBUG + +#endif // _CSP_DEBUG_H_ diff --git a/Program/libcsp/include/csp/csp_endian.h b/Program/libcsp/include/csp/csp_endian.h new file mode 100755 index 0000000..6ffe1d4 --- /dev/null +++ b/Program/libcsp/include/csp/csp_endian.h @@ -0,0 +1,148 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_ENDIAN_H_ +#define _CSP_ENDIAN_H_ + +/** + @file + Endian support. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Convert from host order to network order. +*/ +uint16_t csp_hton16(uint16_t h16); + +/** + Convert from network order to host order. +*/ +uint16_t csp_ntoh16(uint16_t n16); + +/** + Convert from host order to network order. +*/ +uint32_t csp_hton32(uint32_t h32); + +/** + Convert from network order to host order. +*/ +uint32_t csp_ntoh32(uint32_t n32); + +/** + Convert from host order to network order. +*/ +uint64_t csp_hton64(uint64_t h64); + +/** + Convert from network order to host order. +*/ +uint64_t csp_ntoh64(uint64_t n64); + +/** + Convert from host order to big endian. +*/ +uint16_t csp_htobe16(uint16_t h16); + +/** + Convert from host order to little endian. +*/ +uint16_t csp_htole16(uint16_t h16); + +/** + Convert from big endian to host order. +*/ +uint16_t csp_betoh16(uint16_t be16); + +/** + Convert from little endian to host order. +*/ +uint16_t csp_letoh16(uint16_t le16); + +/** + Convert from host order to big endian. + */ +uint32_t csp_htobe32(uint32_t h32); + +/** + Convert from host order to little endian. +*/ +uint32_t csp_htole32(uint32_t h32); + +/** + Convert from big endian to host order. +*/ +uint32_t csp_betoh32(uint32_t be32); + +/** + Convert from little endian to host order. +*/ +uint32_t csp_letoh32(uint32_t le32); + +/** + Convert from host order to big endian. +*/ +uint64_t csp_htobe64(uint64_t h64); + +/** + Convert from host order to little endian. +*/ +uint64_t csp_htole64(uint64_t h64); + +/** + Convert from big endian to host order. +*/ +uint64_t csp_betoh64(uint64_t be64); + +/** + Convert from little endian to host order. +*/ +uint64_t csp_letoh64(uint64_t le64); + +/** + Convert from host order to network order. +*/ +float csp_htonflt(float f); + +/** + Convert from network order to host order. +*/ +float csp_ntohflt(float f); + +/** + Convert from host order to network order. +*/ +double csp_htondbl(double d); + +/** + Convert from network order to host order. +*/ +double csp_ntohdbl(double d); + +#ifdef __cplusplus +} +#endif +#endif // _CSP_ENDIAN_H_ diff --git a/Program/libcsp/include/csp/csp_error.h b/Program/libcsp/include/csp/csp_error.h new file mode 100755 index 0000000..28c07c0 --- /dev/null +++ b/Program/libcsp/include/csp/csp_error.h @@ -0,0 +1,60 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_ERROR_H_ +#define _CSP_ERROR_H_ + +/** + @file + + Error codes. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @defgroup CSP_ERR CSP error codes. + @{ +*/ +#define CSP_ERR_NONE 0 /**< No error */ +#define CSP_ERR_NOMEM -1 /**< Not enough memory */ +#define CSP_ERR_INVAL -2 /**< Invalid argument */ +#define CSP_ERR_TIMEDOUT -3 /**< Operation timed out */ +#define CSP_ERR_USED -4 /**< Resource already in use */ +#define CSP_ERR_NOTSUP -5 /**< Operation not supported */ +#define CSP_ERR_BUSY -6 /**< Device or resource busy */ +#define CSP_ERR_ALREADY -7 /**< Connection already in progress */ +#define CSP_ERR_RESET -8 /**< Connection reset */ +#define CSP_ERR_NOBUFS -9 /**< No more buffer space available */ +#define CSP_ERR_TX -10 /**< Transmission failed */ +#define CSP_ERR_DRIVER -11 /**< Error in driver layer */ +#define CSP_ERR_AGAIN -12 /**< Resource temporarily unavailable */ +#define CSP_ERR_HMAC -100 /**< HMAC failed */ +#define CSP_ERR_XTEA -101 /**< XTEA failed */ +#define CSP_ERR_CRC32 -102 /**< CRC32 failed */ +#define CSP_ERR_SFP -103 /**< SFP protocol error or inconsistency */ +/**@}*/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_iflist.h b/Program/libcsp/include/csp/csp_iflist.h new file mode 100755 index 0000000..2cc0419 --- /dev/null +++ b/Program/libcsp/include/csp/csp_iflist.h @@ -0,0 +1,76 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_IFLIST_H_ +#define CSP_IFLIST_H_ + +/** + @file + + Interface list. + + Linked-list of interfaces in the system. + + This API is not thread-safe. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Add interface to the list. + + @param[in] iface interface. The interface must remain valid as long as the application is running. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_iflist_add(csp_iface_t * iface); + +/** + Get interface by name. + + @param[in] name interface name. + @return Interface or NULL if not found. +*/ +csp_iface_t * csp_iflist_get_by_name(const char *name); + +/** + Print list of interfaces to stdout. +*/ +void csp_iflist_print(void); + +/** + Return list of interfaces. + + @return First interface or NULL, if no interfaces added. +*/ +csp_iface_t * csp_iflist_get(void); + +/** + Convert bytes to readable string. +*/ +int csp_bytesize(char *buffer, int buffer_len, unsigned long int bytes); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_interface.h b/Program/libcsp/include/csp/csp_interface.h new file mode 100755 index 0000000..fcdd8d7 --- /dev/null +++ b/Program/libcsp/include/csp/csp_interface.h @@ -0,0 +1,95 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_INTERFACE_H_ +#define _CSP_INTERFACE_H_ + +/** + @file + Interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Max unique length of interface name, when matching names. +*/ +#define CSP_IFLIST_NAME_MAX 10 + +/** + Interface Tx function. + + @param[in] ifroute contains the interface and the \a mac adddress. + @param[in] packet CSP packet to send. On success, the packet must be freed using csp_buffer_free(). + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +typedef int (*nexthop_t)(const csp_route_t * ifroute, csp_packet_t *packet); + +//doc-begin:csp_iface_s +/** + CSP interface. +*/ +struct csp_iface_s { + const char *name; //!< Name, max compare length is #CSP_IFLIST_NAME_MAX + void * interface_data; //!< Interface data, only known/used by the interface layer, e.g. state information. + void * driver_data; //!< Driver data, only known/used by the driver layer, e.g. device/channel references. + nexthop_t nexthop; //!< Next hop (Tx) function + uint16_t mtu; //!< Maximum Transmission Unit of interface + uint8_t split_horizon_off; //!< Disable the route-loop prevention + uint32_t tx; //!< Successfully transmitted packets + uint32_t rx; //!< Successfully received packets + uint32_t tx_error; //!< Transmit errors (packets) + uint32_t rx_error; //!< Receive errors, e.g. too large message + uint32_t drop; //!< Dropped packets + uint32_t autherr; //!< Authentication errors (packets) + uint32_t frame; //!< Frame format errors (packets) + uint32_t txbytes; //!< Transmitted bytes + uint32_t rxbytes; //!< Received bytes + uint32_t irq; //!< Interrupts + struct csp_iface_s *next; //!< Internal, interfaces are stored in a linked list +}; +//doc-end:csp_iface_s + +/** + Inputs a new packet into the system. + + This function can be called from interface drivers (ISR) or tasks, to route and accept packets. + + @note EXTREMELY IMPORTANT: \a pxTaskWoken must ALWAYS be NULL if called from task, and ALWAYS + be NON NULL if called from ISR. If this condition is met, this call is completely thread-safe + + This function is fire and forget, it returns void, meaning that the \a packet will always be + either accepted or dropped, so the memory will always be freed. + + @param[in] packet A pointer to the incoming packet + @param[in] iface A pointer to the incoming interface TX function. + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! +*/ +void csp_qfifo_write(csp_packet_t *packet, csp_iface_t *iface, CSP_BASE_TYPE *pxTaskWoken); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/Program/libcsp/include/csp/csp_platform.h b/Program/libcsp/include/csp/csp_platform.h new file mode 100755 index 0000000..345df56 --- /dev/null +++ b/Program/libcsp/include/csp/csp_platform.h @@ -0,0 +1,70 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_PLATFORM_H_ +#define _CSP_PLATFORM_H_ + +/** + @file + Platform support. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set OS */ +#if (CSP_POSIX || CSP_WINDOWS || CSP_MACOSX || __DOXYGEN__) + /** Base type. Mainly used for FreeRTOS calls to trigger task re-scheduling. */ + #define CSP_BASE_TYPE int + /** Max timeout time. On platforms supporting no timeouts (e.g. Linux), the timeout will be converted to \a forever. */ + #define CSP_MAX_TIMEOUT (UINT32_MAX) + /** Declare critical lock. */ + #define CSP_DEFINE_CRITICAL(lock) static csp_bin_sem_handle_t lock + /** Initialize critical lock. */ + #define CSP_INIT_CRITICAL(lock) ({(csp_bin_sem_create(&lock) == CSP_SEMAPHORE_OK) ? CSP_ERR_NONE : CSP_ERR_NOMEM;}) + /** Enter/take critical lock. */ + #define CSP_ENTER_CRITICAL(lock) do { csp_bin_sem_wait(&lock, CSP_MAX_DELAY); } while(0) + /** Exit/release critical lock. */ + #define CSP_EXIT_CRITICAL(lock) do { csp_bin_sem_post(&lock); } while(0) +#elif (CSP_FREERTOS) + #include "FreeRTOS.h" + #define CSP_BASE_TYPE portBASE_TYPE + #define CSP_MAX_TIMEOUT portMAX_DELAY + #define CSP_DEFINE_CRITICAL(lock) + #define CSP_INIT_CRITICAL(lock) ({CSP_ERR_NONE;}) + #define CSP_ENTER_CRITICAL(lock) do { portENTER_CRITICAL(); } while (0) + #define CSP_EXIT_CRITICAL(lock) do { portEXIT_CRITICAL(); } while (0) +#else + #error "OS must be either CSP_POSIX, CSP_MACOSX, CSP_FREERTOS or CSP_WINDOWS" +#endif + +/** Legacy definition for #CSP_MAX_TIMEOUT. */ +#define CSP_MAX_DELAY CSP_MAX_TIMEOUT + +/** Legacy definition for #CSP_MAX_TIMEOUT. */ +#define CSP_INFINITY CSP_MAX_TIMEOUT + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_promisc.h b/Program/libcsp/include/csp/csp_promisc.h new file mode 100755 index 0000000..59e2ae5 --- /dev/null +++ b/Program/libcsp/include/csp/csp_promisc.h @@ -0,0 +1,64 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_CSP_PROMISC_H_ +#define _CSP_CSP_PROMISC_H_ + +/** + #file + + Promiscuous packet queue. + + This function is used to enable promiscuous mode for incoming packets, e.g. router, bridge. + If enabled, a copy of all incoming packets are cloned (using csp_buffer_clone()) and placed in a + FIFO queue, that can be read using csp_promisc_read(). +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Enable promiscuous packet queue. + @param[in] queue_size Size (max length) of queue for incoming packets. + @return #CSP_ERR_NONE on success, otherwise an error code. + */ +int csp_promisc_enable(unsigned int queue_size); + +/** + Disable promiscuous mode. +*/ +void csp_promisc_disable(void); + +/** + Get/dequeue packet from promiscuous packet queue. + + Returns the first packet from the promiscuous packet queue. + @param[in] timeout Timeout in ms to wait for a packet. + @return Packet (free with csp_buffer_free() or re-use packet), NULL on error or timeout. +*/ +csp_packet_t *csp_promisc_read(uint32_t timeout); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_rtable.h b/Program/libcsp/include/csp/csp_rtable.h new file mode 100755 index 0000000..60307f1 --- /dev/null +++ b/Program/libcsp/include/csp/csp_rtable.h @@ -0,0 +1,172 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_RTABLE_H_ +#define CSP_RTABLE_H_ + +/** + @file + + Routing table. + + The routing table maps a CSP destination address to an interface (and optional a via address). + + Normal routing: If the route's via address is set to #CSP_NO_VIA_ADDRESS, the packet will be sent directly to the destination address + specified in the CSP header, otherwise the packet will be sent the to the route's via address. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + No via address specified for the route, use CSP header destination. +*/ +#define CSP_NO_VIA_ADDRESS 0xFF + +/** + Legacy definition for #CSP_NO_VIA_ADDRESS. +*/ +#define CSP_NODE_MAC CSP_NO_VIA_ADDRESS + +/** + Route entry. + @see csp_rtable_find_route(). +*/ +struct csp_route_s { + /** Which interface to route packet on */ + csp_iface_t * iface; + /** If different from #CSP_NO_VIA_ADDRESS, send packet to this address, instead of the destination address in the CSP header. */ + uint8_t via; +}; + +/** + Find route to address/node. + @param[in] dest_address destination address. + @return Route or NULL if no route found. +*/ +const csp_route_t * csp_rtable_find_route(uint8_t dest_address); + +/** + Set route to destination address/node. + @param[in] dest_address destination address. + @param[in] mask number of bits in netmask + @param[in] ifc interface. + @param[in] via assosicated via address. + @return #CSP_ERR_NONE on success, or an error code. +*/ +int csp_rtable_set(uint8_t dest_address, uint8_t mask, csp_iface_t *ifc, uint8_t via); + +/** + Save routing table as a string (readable format). + @see csp_rtable_load() for additional information, e.g. format. + @param[out] buffer user supplied buffer. + @param[in] buffer_size size of \a buffer. + @return #CSP_ERR_NONE on success, or an error code. +*/ +int csp_rtable_save(char * buffer, size_t buffer_size); + +/** + Load routing table from a string. + Table will be loaded on-top of existing routes, possibly overwriting existing entries. + Format: \[/mask] \ [via][, next entry] + Example: "0/0 CAN, 8 KISS, 10 I2C 10", same as "0/0 CAN, 8/5 KISS, 10/5 I2C 10". + @see csp_rtable_save(), csp_rtable_clear(), csp_rtable_free() + @param[in] rtable routing table (nul terminated) + @return @ref CSP_ERR or number of entries. +*/ +int csp_rtable_load(const char * rtable); + +/** + Load routing table from a string. + Table will be loaded on-top of existing routes, possibly overwriting existing entries. + Format: \[/mask] \ [via][, next entry] + Example: "0/0 CAN, 8 KISS, 10 I2C 10", same as "0/0 CAN, 8/5 KISS, 10/5 I2C 10". + @see csp_rtable_save(), csp_rtable_clear(), csp_rtable_free() + @param[in] rtable routing table (nul terminated) + @return @ref CSP_ERR or number of entries. +*/ +int csp_rtable_load(const char * rtable); + +/** + Check string for valid routing elements. + @param[in] rtable routing table (nul terminated) + @return @ref CSP_ERR or number of entries. +*/ +int csp_rtable_check(const char * rtable); + +/** + Clear routing table and add loopback route. + @see csp_rtable_free() +*/ +void csp_rtable_clear(void); + +/** + Clear/free all entries in the routing table. +*/ +void csp_rtable_free(void); + +/** + Print routing table +*/ +void csp_rtable_print(void); + +/** Iterator for looping through the routing table. */ +typedef bool (*csp_rtable_iterator_t)(void * ctx, uint8_t address, uint8_t mask, const csp_route_t * route); + +/** + Iterate routing table. +*/ +void csp_rtable_iterate(csp_rtable_iterator_t iter, void * ctx); + +/** + Set route to destination address/node. + @deprecated Use csp_rtable_set() instead. + @param[in] dest_address destination address. + @param[in] ifc interface. + @param[in] via assosicated via address. + @return #CSP_ERR_NONE on success, or an error code. +*/ +static inline int csp_route_set(uint8_t dest_address, csp_iface_t *ifc, uint8_t via) { + return csp_rtable_set(dest_address, CSP_ID_HOST_SIZE, ifc, via); +} + +/** + Print routing table. + @deprecated Use csp_rtable_print() instead. +*/ +static inline void csp_route_print_table() { + csp_rtable_print(); +} + +/** + Print list of interfaces. + @deprecated Use csp_iflist_print() instead. +*/ +static inline void csp_route_print_interfaces(void) { + csp_iflist_print(); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_sfp.h b/Program/libcsp/include/csp/csp_sfp.h new file mode 100755 index 0000000..1fc5d31 --- /dev/null +++ b/Program/libcsp/include/csp/csp_sfp.h @@ -0,0 +1,111 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_SFP_H_ +#define _CSP_SFP_H_ + +/** + @file + + Simple Fragmentation Protocol (SFP). + + The SFP API can transfer a blob of data across an established CSP connection, by chopping the data into smaller chuncks of data, that + can fit into a single CSP message. + + SFP will add a small header to each packet, containing information about the transfer. + SFP is usually sent over a RDP connection (which also adds a header), +*/ + +#include // memcpy() + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Send data over a CSP connection. + + Data will be send in chunks of \a mtu bytes. The MTU must be small enough to fit into a CSP packat + SFP header + other transport headers. + + csp_sfp_recv() or csp_sfp_recv_fp() can be used at the other end to receive data. + + This is usefull if you wish to send data stored in flash memory or another location, where standard memcpy() doesn't work. + + @param[in] conn established connection for sending SFP packets. + @param[in] data data to send + @param[in] datasize size of \a data + @param[in] mtu maximum transfer unit (bytes), max data chunk to send. + @param[in] timeout unused as of CSP version 1.6 + @param[in] memcpyfcn memory copy function. + @return #CSP_ERR_NONE on success, otherwise an error. +*/ +int csp_sfp_send_own_memcpy(csp_conn_t * conn, const void * data, unsigned int datasize, unsigned int mtu, uint32_t timeout, csp_memcpy_fnc_t memcpyfcn); + +/** + Send data over a CSP connection. + + Uses csp_sfp_send_own_memcpy() with standard memcpy(). + + @param[in] conn established connection for sending SFP packets. + @param[in] data data to send + @param[in] datasize size of \a data + @param[in] mtu maximum transfer unit (bytes), max data chunk to send. + @param[in] timeout unused as of CSP version 1.6 + @return #CSP_ERR_NONE on success, otherwise an error. +*/ +static inline int csp_sfp_send(csp_conn_t * conn, const void * data, unsigned int datasize, unsigned int mtu, uint32_t timeout) { + return csp_sfp_send_own_memcpy(conn, data, datasize, mtu, timeout, (csp_memcpy_fnc_t) &memcpy); +} + +/** + Receive data over a CSP connection. + + This is the counterpart to the csp_sfp_send() and csp_sfp_send_own_memcpy(). + + @param[in] conn established connection for receiving SFP packets. + @param[out] dataout received data on success. Allocated with csp_malloc(), so should be freed with csp_free(). The pointer will be NULL on failure. + @param[out] datasize size of received data. + @param[in] timeout timeout in ms to wait for csp_read() + @param[in] first_packet First packet of a SFP transfer. Use NULL to receive first packet on the connection. + @return #CSP_ERR_NONE on success, otherwise an error. +*/ +int csp_sfp_recv_fp(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout, csp_packet_t * first_packet); + +/** + Receive data over a CSP connection. + + This is the counterpart to the csp_sfp_send() and csp_sfp_send_own_memcpy(). + + @param[in] conn established connection for receiving SFP packets. + @param[out] dataout received data on success. Allocated with csp_malloc(), so should be freed with csp_free(). The pointer will be NULL on failure. + @param[out] datasize size of received data. + @param[in] timeout timeout in ms to wait for csp_read() + @return #CSP_ERR_NONE on success, otherwise an error. +*/ +static inline int csp_sfp_recv(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout) { + return csp_sfp_recv_fp(conn, dataout, datasize, timeout, NULL); +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/csp_types.h b/Program/libcsp/include/csp/csp_types.h new file mode 100755 index 0000000..1a0f492 --- /dev/null +++ b/Program/libcsp/include/csp/csp_types.h @@ -0,0 +1,292 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_TYPES_H_ +#define CSP_TYPES_H_ + +/** + @file + Basic types. +*/ + +#include +#include +#include + +#include // -> CSP_X defines (compile configuration) +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if (CSP_BIG_ENDIAN && CSP_LITTLE_ENDIAN) +#error "Only define/set either CSP_BIG_ENDIAN or CSP_LITTLE_ENDIAN" +#endif + +/** + Reserved ports for CSP services. +*/ +typedef enum { + CSP_CMP = 0, //!< CSP management, e.g. memory, routes, stats + CSP_PING = 1, //!< Ping - return ping + CSP_PS = 2, //!< Current process list + CSP_MEMFREE = 3, //!< Free memory + CSP_REBOOT = 4, //!< Reboot, see #CSP_REBOOT_MAGIC and #CSP_REBOOT_SHUTDOWN_MAGIC + CSP_BUF_FREE = 5, //!< Free CSP buffers + CSP_UPTIME = 6, //!< Uptime +} csp_service_port_t; + +/** Listen on all ports, primarily used with csp_bind() */ +#define CSP_ANY 255 + +/** + Message priority. +*/ +typedef enum { + CSP_PRIO_CRITICAL = 0, //!< Critical + CSP_PRIO_HIGH = 1, //!< High + CSP_PRIO_NORM = 2, //!< Normal (default) + CSP_PRIO_LOW = 3, //!< Low +} csp_prio_t; + +#define CSP_PRIORITIES (1 << CSP_ID_PRIO_SIZE) //!< Number of CSP message priorities. + +#if (CSP_USE_QOS || __DOXYGEN__) +#define CSP_ROUTE_FIFOS CSP_PRIORITIES //!< Number of fifos for incoming messages (handover to router) +#define CSP_RX_QUEUES CSP_PRIORITIES //!< Number of fifos for incoming message per message-queue +#else +#define CSP_ROUTE_FIFOS 1 +#define CSP_RX_QUEUES 1 +#endif + +/** + @defgroup CSP_HEADER_DEF CSP header definition. + @{ +*/ +#define CSP_ID_PRIO_SIZE 2 //!< Bits for priority, see #csp_prio_t +#define CSP_ID_HOST_SIZE 5 //!< Bits for host (destination/source address) +#define CSP_ID_PORT_SIZE 6 //!< Bits for port (destination/source port) +#define CSP_ID_FLAGS_SIZE 8 //!< Bits for flags, see @ref CSP_HEADER_FLAGS + +/** Number of bits in CSP header */ +#define CSP_HEADER_BITS (CSP_ID_PRIO_SIZE + (2 * CSP_ID_HOST_SIZE) + (2 * CSP_ID_PORT_SIZE) + CSP_ID_FLAGS_SIZE) +/** CSP header size in bytes */ +#define CSP_HEADER_LENGTH (CSP_HEADER_BITS / 8) + +#if CSP_HEADER_BITS != 32 && __GNUC__ +#error "Header length must be 32 bits" +#endif + +#define CSP_ID_PRIO_MAX ((1 << (CSP_ID_PRIO_SIZE)) - 1) //!< Max priority value in header +#define CSP_ID_HOST_MAX ((1 << (CSP_ID_HOST_SIZE)) - 1) //!< Max host value in header +#define CSP_ID_PORT_MAX ((1 << (CSP_ID_PORT_SIZE)) - 1) //!< Max port value in header +#define CSP_ID_FLAGS_MAX ((1 << (CSP_ID_FLAGS_SIZE)) - 1) //!< Max flag(s) value in header + +/** CSP identifier/header - priority mask */ +#define CSP_ID_PRIO_MASK ((uint32_t) CSP_ID_PRIO_MAX << (CSP_ID_FLAGS_SIZE + (2 * CSP_ID_PORT_SIZE) + (2 * CSP_ID_HOST_SIZE))) +/** CSP identifier/header - source address mask */ +#define CSP_ID_SRC_MASK ((uint32_t) CSP_ID_HOST_MAX << (CSP_ID_FLAGS_SIZE + (2 * CSP_ID_PORT_SIZE) + (1 * CSP_ID_HOST_SIZE))) +/** CSP identifier/header - destination address mask */ +#define CSP_ID_DST_MASK ((uint32_t) CSP_ID_HOST_MAX << (CSP_ID_FLAGS_SIZE + (2 * CSP_ID_PORT_SIZE))) +/** CSP identifier/header - destination port mask */ +#define CSP_ID_DPORT_MASK ((uint32_t) CSP_ID_PORT_MAX << (CSP_ID_FLAGS_SIZE + (1 * CSP_ID_PORT_SIZE))) +/** CSP identifier/header - source port mask */ +#define CSP_ID_SPORT_MASK ((uint32_t) CSP_ID_PORT_MAX << (CSP_ID_FLAGS_SIZE)) +/** CSP identifier/header - flag mask */ +#define CSP_ID_FLAGS_MASK ((uint32_t) CSP_ID_FLAGS_MAX << (0)) +/** CSP identifier/header - connection mask (source & destination address + source & destination ports) */ +#define CSP_ID_CONN_MASK (CSP_ID_SRC_MASK | CSP_ID_DST_MASK | CSP_ID_DPORT_MASK | CSP_ID_SPORT_MASK) +/**@}*/ + +/** + CSP identifier/header. + This union is sent directly on the wire, hence the big/little endian definitions +*/ +typedef union { + /** Entire identifier. */ + uint32_t ext; + /** Individual fields. */ + struct __attribute__((__packed__)) { +#if (CSP_BIG_ENDIAN || __DOXYGEN__) + unsigned int pri : CSP_ID_PRIO_SIZE; //!< Priority + unsigned int src : CSP_ID_HOST_SIZE; //!< Source address + unsigned int dst : CSP_ID_HOST_SIZE; //!< Destination address + unsigned int dport : CSP_ID_PORT_SIZE; //!< Destination port + unsigned int sport : CSP_ID_PORT_SIZE; //!< Source port + unsigned int flags : CSP_ID_FLAGS_SIZE; //!< Flags, see @ref CSP_HEADER_FLAGS +#elif (CSP_LITTLE_ENDIAN) + unsigned int flags : CSP_ID_FLAGS_SIZE; + unsigned int sport : CSP_ID_PORT_SIZE; + unsigned int dport : CSP_ID_PORT_SIZE; + unsigned int dst : CSP_ID_HOST_SIZE; + unsigned int src : CSP_ID_HOST_SIZE; + unsigned int pri : CSP_ID_PRIO_SIZE; +#endif + }; +} csp_id_t; + +/** Broadcast address */ +#define CSP_BROADCAST_ADDR CSP_ID_HOST_MAX + +/** Default routing address */ +#define CSP_DEFAULT_ROUTE (CSP_ID_HOST_MAX + 1) + +/** + @defgroup CSP_HEADER_FLAGS CSP header flags. + @{ +*/ +#define CSP_FRES1 0x80 //!< Reserved for future use +#define CSP_FRES2 0x40 //!< Reserved for future use +#define CSP_FRES3 0x20 //!< Reserved for future use +#define CSP_FFRAG 0x10 //!< Use fragmentation +#define CSP_FHMAC 0x08 //!< Use HMAC verification +#define CSP_FXTEA 0x04 //!< Use XTEA encryption +#define CSP_FRDP 0x02 //!< Use RDP protocol +#define CSP_FCRC32 0x01 //!< Use CRC32 checksum +/**@}*/ + +/** + @defgroup CSP_SOCKET_OPTIONS CSP Socket options. + @{ +*/ +#define CSP_SO_NONE 0x0000 //!< No socket options +#define CSP_SO_RDPREQ 0x0001 //!< Require RDP +#define CSP_SO_RDPPROHIB 0x0002 //!< Prohibit RDP +#define CSP_SO_HMACREQ 0x0004 //!< Require HMAC +#define CSP_SO_HMACPROHIB 0x0008 //!< Prohibit HMAC +#define CSP_SO_XTEAREQ 0x0010 //!< Require XTEA +#define CSP_SO_XTEAPROHIB 0x0020 //!< Prohibit HMAC +#define CSP_SO_CRC32REQ 0x0040 //!< Require CRC32 +#define CSP_SO_CRC32PROHIB 0x0080 //!< Prohibit CRC32 +#define CSP_SO_CONN_LESS 0x0100 //!< Enable Connection Less mode +#define CSP_SO_INTERNAL_LISTEN 0x1000 //!< Internal flag: listen called on socket +/**@}*/ + +/** + @defgroup CSP_CONNECTION_OPTIONS CSP Connect options. + @{ +*/ +#define CSP_O_NONE CSP_SO_NONE //!< No connection options +#define CSP_O_RDP CSP_SO_RDPREQ //!< Enable RDP +#define CSP_O_NORDP CSP_SO_RDPPROHIB //!< Disable RDP +#define CSP_O_HMAC CSP_SO_HMACREQ //!< Enable HMAC +#define CSP_O_NOHMAC CSP_SO_HMACPROHIB //!< Disable HMAC +#define CSP_O_XTEA CSP_SO_XTEAREQ //!< Enable XTEA +#define CSP_O_NOXTEA CSP_SO_XTEAPROHIB //!< Disable XTEA +#define CSP_O_CRC32 CSP_SO_CRC32REQ //!< Enable CRC32 +#define CSP_O_NOCRC32 CSP_SO_CRC32PROHIB //!< Disable CRC32 +/**@}*/ + +/** + Padding size in #csp_packet_t. + 10 bytes ensure correct aligned \a id and \a data in #csp_packet_t. +*/ +#define CSP_PADDING_BYTES 10 + +//doc-begin:csp_packet_t +/** + CSP Packet. + + This structure is constructed to fit with all interface and protocols to prevent the + need to copy data (zero copy). + + @note In most cases a CSP packet cannot be reused in case of send failure, because the + lower layers may add additional data causing increased length (e.g. CRC32), convert + the CSP id to different endian (e.g. I2C), etc. +*/ +typedef struct { + /** + Padding. These bytes are intended for use by protocols, which want to prepend + data before sending it, without having to copy/reorganize the entire message. + */ + uint8_t padding[CSP_PADDING_BYTES]; + /** Data length. Must be just before CSP ID.*/ + uint16_t length; + /** CSP id. Must be just before data, as it allows the interface to id and data + in a single operation. */ + csp_id_t id; + /** + Data part of packet. + When using the csp_buffer API, the size of the data part is set by + csp_buffer_init(), and can later be accessed by csp_buffer_data_size() + */ + union { + /** Access data as uint8_t. */ + uint8_t data[0]; + /** Access data as uint16_t */ + uint16_t data16[0]; + /** Access data as uint32_t */ + uint32_t data32[0]; + }; +} csp_packet_t; +//doc-end:csp_packet_t + +/** + Size of the packet overhead in #csp_packet_t. + The overhead is the difference between the total buffer size (returned by csp_buffer_size()) and the data part + of the #csp_packet_t (returned by csp_buffer_data_size()). +*/ +#define CSP_BUFFER_PACKET_OVERHEAD (sizeof(csp_packet_t) - sizeof(((csp_packet_t *)0)->data)) + +/** Forward declaration of CSP interface, see #csp_iface_s for details. */ +typedef struct csp_iface_s csp_iface_t; +/** Forward declaration of outgoing CSP route, see #csp_route_s for details. */ +typedef struct csp_route_s csp_route_t; + +/** Forward declaration of socket structure */ +typedef struct csp_conn_s csp_socket_t; +/** Forward declaration of connection structure */ +typedef struct csp_conn_s csp_conn_t; + +/** Max length of host name - including zero termination */ +#define CSP_HOSTNAME_LEN 20 +/** Max length of model name - including zero termination */ +#define CSP_MODEL_LEN 30 + +/** Magic number for reboot request, for service-code #CSP_REBOOT */ +#define CSP_REBOOT_MAGIC 0x80078007 +/** Magic number for shutdown request, for service-code #CSP_REBOOT */ +#define CSP_REBOOT_SHUTDOWN_MAGIC 0xD1E5529A + +#ifdef __AVR__ +typedef uint32_t csp_memptr_t; +typedef const uint32_t csp_const_memptr_t; +#else +/** Memory pointer */ +typedef void * csp_memptr_t; +/** Const memory pointer */ +typedef const void * csp_const_memptr_t; +#endif + +/** + Platform specific memory copy function. +*/ +typedef csp_memptr_t (*csp_memcpy_fnc_t)(csp_memptr_t, csp_const_memptr_t, size_t); + +/** + Compile check/asserts. +*/ +#define CSP_STATIC_ASSERT(condition, name) typedef char name[(condition) ? 1 : -1] + +#ifdef __cplusplus +} +#endif +#endif /* CSP_TYPES_H_ */ diff --git a/Program/libcsp/include/csp/drivers/can_socketcan.h b/Program/libcsp/include/csp/drivers/can_socketcan.h new file mode 100755 index 0000000..e33b711 --- /dev/null +++ b/Program/libcsp/include/csp/drivers/can_socketcan.h @@ -0,0 +1,73 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef LIB_CSP_INCLUDE_CSP_DRIVERS_CAN_SOCKETCAN_H_ +#define LIB_CSP_INCLUDE_CSP_DRIVERS_CAN_SOCKETCAN_H_ + +/** + @file + + Socket CAN driver (Linux). + + This driver requires the libsocketcan library. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Open CAN socket and add CSP interface. + + @param[in] device CAN device name (Linux device). + @param[in] ifname CSP interface name, use #CSP_IF_CAN_DEFAULT_NAME for default name. + @param[in] bitrate if different from 0, it will be attempted to change the bitrate on the CAN device - this may require increased OS privileges. + @param[in] promisc if \a true, receive all CAN frames. If \a false a filter is set on the CAN device, using csp_get_address(). + @param[out] return_iface the added interface. + @return The added interface, or NULL in case of failure. +*/ +int csp_can_socketcan_open_and_add_interface(const char * device, const char * ifname, int bitrate, bool promisc, csp_iface_t ** return_iface); + +/** + Initialize socketcan and add CSP interface. + + @deprecated version 1.6, use csp_can_socketcan_open_and_add_interface() + @param[in] device CAN device name (Linux device). + @param[in] bitrate if different from 0, it will be attempted to change the bitrate on the CAN device - this may require increased OS privileges. + @param[in] promisc if \a true, receive all CAN frames. If \a false a filter is set on the CAN device, using csp_get_address(). + @return The added interface, or NULL in case of failure. +*/ +csp_iface_t * csp_can_socketcan_init(const char * device, int bitrate, bool promisc); + +/** + Stop the Rx thread and free resources (testing). + + @note This will invalidate CSP, because an interface can't be removed. This is primarily for testing. + + @param[in] iface interface to stop. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_can_socketcan_stop(csp_iface_t * iface); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/drivers/usart.h b/Program/libcsp/include/csp/drivers/usart.h new file mode 100755 index 0000000..d5af368 --- /dev/null +++ b/Program/libcsp/include/csp/drivers/usart.h @@ -0,0 +1,121 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_DRIVERS_USART_H +#define CSP_DRIVERS_USART_H + +/** + @file + + USART driver. + + @note This interface implementation only support ONE open UART connection. +*/ + +#include + +#if (CSP_WINDOWS) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + OS file handle. +*/ +#if (CSP_WINDOWS) + typedef HANDLE csp_usart_fd_t; +#else + typedef int csp_usart_fd_t; +#endif + +/** + Usart configuration. + @see csp_usart_open() +*/ +typedef struct csp_usart_conf { + //! USART device. + const char *device; + //! bits per second. + uint32_t baudrate; + //! Number of data bits. + uint8_t databits; + //! Number of stop bits. + uint8_t stopbits; + //! Parity setting. + uint8_t paritysetting; + //! Enable parity checking (Windows only). + uint8_t checkparity; +} csp_usart_conf_t; + +/** + Callback for returning data to application. + + @param[in] buf data received. + @param[in] len data length (number of bytes in \a buf). + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! +*/ +typedef void (*csp_usart_callback_t) (void * user_data, uint8_t *buf, size_t len, void *pxTaskWoken); + +/** + Opens an UART device. + + Opens the UART device and creates a thread for reading/returning data to the application. + + @note On read failure, exit() will be called - terminating the process. + + @param[in] conf UART configuration. + @param[in] rx_callback receive data callback. + @param[in] user_data reference forwarded to the \a rx_callback function. + @param[out] fd the opened file descriptor. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_usart_open(const csp_usart_conf_t *conf, csp_usart_callback_t rx_callback, void * user_data, csp_usart_fd_t * fd); + +/** + Write data on open UART. + + @param[in] fd file descriptor. + @param[in] data data to write. + @param[in] data_length length of \a data. + @return number of bytes written on success, a negative value on failure. +*/ +int csp_usart_write(csp_usart_fd_t fd, const void * data, size_t data_length); + +/** + Opens UART device and add KISS interface. + + This is a convience function for opening an UART device and adding it as an interface with a given name. + + @note On read failures, exit() will be called - terminating the process. + + @param[in] conf UART configuration. + @param[in] ifname internface name (will be copied), or use NULL for default name. + @param[out] return_iface the added interface. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_usart_open_and_add_kiss_interface(const csp_usart_conf_t *conf, const char * ifname, csp_iface_t ** return_iface); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_can.h b/Program/libcsp/include/csp/interfaces/csp_if_can.h new file mode 100755 index 0000000..bfe4be3 --- /dev/null +++ b/Program/libcsp/include/csp/interfaces/csp_if_can.h @@ -0,0 +1,178 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_INTERFACES_CSP_IF_CAN_H +#define CSP_INTERFACES_CSP_IF_CAN_H + +/** + @file + + CAN interface. + + CAN frames contains at most 8 bytes of data, so in order to transmit CSP + packets larger than this, a fragmentation protocol is required. + The CAN Fragmentation Protocol (CFP) is based on CAN2.0B, using all 29 bits of the + identifier. The CAN identifier is divided into these fields: + + - Source: 5 bits + - Destination: 5 bits + - Type: 1 bit + - Remain: 8 bits + - Identifier: 10 bits + + The \b Source and \b Destination fields must match the source and destiantion addressses in the CSP packet. + The \b Type field is used to distinguish the first and subsequent frames in a fragmented CSP + packet. Type is BEGIN (0) for the first fragment and MORE (1) for all other fragments. + The \b Remain field indicates number of remaining fragments, and must be decremented by one for each fragment sent. + The \b identifier field serves the same purpose as in the Internet Protocol, and should be an auto incrementing + integer to uniquely separate sessions. + + Other CAN communication using a standard 11 bit identifier, can co-exist on the wire. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @defgroup CFP_SIZE CAN message id field size. + @{ +*/ +/** Host - source/destination address. */ +#define CFP_HOST_SIZE 5 +/** Type - \a begin fragment or \a more fragments. */ +#define CFP_TYPE_SIZE 1 +/** Remaining fragments */ +#define CFP_REMAIN_SIZE 8 +/** CFP identification. */ +#define CFP_ID_SIZE 10 +/** @} */ + +/** + @defgroup CFP_FIELDS Macros for extracting fields from CAN message id. + @{ +*/ +/** Helper macro */ +#define CFP_FIELD(id,rsiz,fsiz) ((uint32_t)((uint32_t)((id) >> (rsiz)) & (uint32_t)((1 << (fsiz)) - 1))) +/** Extract source address */ +#define CFP_SRC(id) CFP_FIELD(id, CFP_HOST_SIZE + CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_HOST_SIZE) +/** Extract destination address */ +#define CFP_DST(id) CFP_FIELD(id, CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_HOST_SIZE) +/** Extract type (begin or more) */ +#define CFP_TYPE(id) CFP_FIELD(id, CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_TYPE_SIZE) +/** Extract remaining fragments */ +#define CFP_REMAIN(id) CFP_FIELD(id, CFP_ID_SIZE, CFP_REMAIN_SIZE) +/** Extract CFP identification */ +#define CFP_ID(id) CFP_FIELD(id, 0, CFP_ID_SIZE) +/** @} */ + +/** + @defgroup CFP_MAKE Macros for building CAN message id. + @{ +*/ +/** Helper macro */ +#define CFP_MAKE_FIELD(id,fsiz,rsiz) ((uint32_t)(((id) & (uint32_t)((uint32_t)(1 << (fsiz)) - 1)) << (rsiz))) +/** Make source */ +#define CFP_MAKE_SRC(id) CFP_MAKE_FIELD(id, CFP_HOST_SIZE, CFP_HOST_SIZE + CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE) +/** Make destination */ +#define CFP_MAKE_DST(id) CFP_MAKE_FIELD(id, CFP_HOST_SIZE, CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE) +/** Make type */ +#define CFP_MAKE_TYPE(id) CFP_MAKE_FIELD(id, CFP_TYPE_SIZE, CFP_REMAIN_SIZE + CFP_ID_SIZE) +/** Make remaining fragments */ +#define CFP_MAKE_REMAIN(id) CFP_MAKE_FIELD(id, CFP_REMAIN_SIZE, CFP_ID_SIZE) +/** Make CFP id */ +#define CFP_MAKE_ID(id) CFP_MAKE_FIELD(id, CFP_ID_SIZE, 0) +/** @} */ + +/** Mask to uniquely separate connections */ +#define CFP_ID_CONN_MASK (CFP_MAKE_SRC((uint32_t)(1 << CFP_HOST_SIZE) - 1) | \ + CFP_MAKE_DST((uint32_t)(1 << CFP_HOST_SIZE) - 1) | \ + CFP_MAKE_ID((uint32_t)(1 << CFP_ID_SIZE) - 1)) + +/** + Default interface name. +*/ +#define CSP_IF_CAN_DEFAULT_NAME "CAN" + +/** + Send CAN frame (implemented by driver). + + Used by csp_can_tx() to send CAN frames. + + @param[in] driver_data driver data from #csp_iface_t + @param[in] id CAM message id. + @param[in] data CAN data + @param[in] dlc data length of \a data. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +typedef int (*csp_can_driver_tx_t)(void * driver_data, uint32_t id, const uint8_t * data, uint8_t dlc); + +/** + Interface data (state information). +*/ +typedef struct { + /** CFP Identification number - same number on all fragments from same CSP packet. */ + uint32_t cfp_frame_id; + /** Tx function */ + csp_can_driver_tx_t tx_func; +} csp_can_interface_data_t; + +/** + Add interface. + + If the MTU is not set, it will be set to the maximum value of 2042 bytes (max length when using CFP). + + @param[in] iface CSP interface, initialized with name and inteface_data pointing to a valid #csp_can_interface_data_t structure. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_can_add_interface(csp_iface_t * iface); + +/** + Send CSP packet over CAN (nexthop). + + This function will split the CSP packet into several fragments and call csp_can_tx_fram() for sending each fragment. + + @param[in] ifroute route. + @param[in] packet CSP packet to send. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_can_tx(const csp_route_t * ifroute, csp_packet_t *packet); + +/** + Process received CAN frame. + + Called from driver when a single CAN frame (up to 8 bytes) has been received. The function will gather the fragments into a single + CSP packet and route it on when complete. + + @param[in] iface incoming interface. + @param[in] id received CAN message identifier. + @param[in] data received CAN data. + @param[in] dlc length of received \a data. + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_can_rx(csp_iface_t * iface, uint32_t id, const uint8_t * data, uint8_t dlc, CSP_BASE_TYPE *pxTaskWoken); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_i2c.h b/Program/libcsp/include/csp/interfaces/csp_if_i2c.h new file mode 100755 index 0000000..5aa2e52 --- /dev/null +++ b/Program/libcsp/include/csp/interfaces/csp_if_i2c.h @@ -0,0 +1,118 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_IF_I2C_H_ +#define _CSP_IF_I2C_H_ + +/** + @file + + I2C interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Default name of I2C interface. +*/ +#define CSP_IF_I2C_DEFAULT_NAME "I2C" + +//doc-begin:csp_i2c_frame_t +/** + I2C frame. + This struct fits on top of a #csp_packet_t, removing the need for copying data. +*/ +typedef struct i2c_frame_s { + //! Not used (-> csp_packet_t.padding) + uint8_t padding[3]; + //! Cleared before Tx (-> csp_packet_t.padding) + uint8_t retries; + //! Not used (-> csp_packet_t.padding) + uint32_t reserved; + //! Destination address (-> csp_packet_t.padding) + uint8_t dest; + //! Cleared before Tx (-> csp_packet_t.padding) + uint8_t len_rx; + //! Length of \a data part (-> csp_packet_t.length) + uint16_t len; + //! CSP id + data (-> csp_packet_t.id) + uint8_t data[0]; +} csp_i2c_frame_t; +//doc-end:csp_i2c_frame_t + +/** + Send I2C frame (implemented by driver). + + Used by csp_i2c_tx() to send a frame. + + The function must free the frame/packet using csp_buffer_free(), if the send succeeds (returning #CSP_ERR_NONE). + + @param[in] driver_data driver data from #csp_iface_t + @param[in] frame destination, length and data. This is actually a #csp_packet_t buffer, casted to #csp_i2c_frame_t. + @return #CSP_ERR_NONE on success, or an error code. +*/ +typedef int (*csp_i2c_driver_tx_t)(void * driver_data, csp_i2c_frame_t * frame); + +/** + Interface data (state information). +*/ +typedef struct { + /** Tx function */ + csp_i2c_driver_tx_t tx_func; +} csp_i2c_interface_data_t; + +/** + Add interface. + + @param[in] iface CSP interface, initialized with name and inteface_data pointing to a valid #csp_i2c_interface_data_t. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_i2c_add_interface(csp_iface_t * iface); + +/** + Send CSP packet over I2C (nexthop). + + @param[in] ifroute route. + @param[in] packet CSP packet to send. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_i2c_tx(const csp_route_t * ifroute, csp_packet_t * packet); + +/** + Process received I2C frame. + + @note The received #csp_i2c_frame_t must actually be pointing to an #csp_packet_t. + + Called from driver, when a frame has been received. + + @param[in] iface incoming interface. + @param[in] frame received data, routed on as a #csp_packet_t. + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! +*/ +void csp_i2c_rx(csp_iface_t * iface, csp_i2c_frame_t * frame, void * pxTaskWoken); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_kiss.h b/Program/libcsp/include/csp/interfaces/csp_if_kiss.h new file mode 100755 index 0000000..e931107 --- /dev/null +++ b/Program/libcsp/include/csp/interfaces/csp_if_kiss.h @@ -0,0 +1,116 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_INTERFACES_CSP_IF_KISS_H +#define CSP_INTERFACES_CSP_IF_KISS_H + +/** + @file + + KISS interface (serial). +*/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Default name of KISS interface. +*/ +#define CSP_IF_KISS_DEFAULT_NAME "KISS" + +/** + Send KISS frame (implemented by driver). + + @param[in] driver_data driver data from #csp_iface_t + @param[in] data data to send + @param[in] len length of \a data. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +typedef int (*csp_kiss_driver_tx_t)(void *driver_data, const uint8_t * data, size_t len); + +/** + KISS Rx mode/state. +*/ +typedef enum { + KISS_MODE_NOT_STARTED, //!< No start detected + KISS_MODE_STARTED, //!< Started on a KISS frame + KISS_MODE_ESCAPED, //!< Rx escape character + KISS_MODE_SKIP_FRAME, //!< Skip remaining frame, wait for end character +} csp_kiss_mode_t; + +/** + KISS interface data (state information). +*/ +typedef struct { + /** Max Rx length */ + unsigned int max_rx_length; + /** Tx function */ + csp_kiss_driver_tx_t tx_func; + /** Tx lock. Current implementation doesn't transfer data to driver in a single 'write', hence locking is necessary. */ + csp_mutex_t lock; + /** Rx mode/state. */ + csp_kiss_mode_t rx_mode; + /** Rx length */ + unsigned int rx_length; + /** Rx first - if set, waiting for first character (== TNC_DATA) after start */ + bool rx_first; + /** CSP packet for storing Rx data. */ + csp_packet_t * rx_packet; +} csp_kiss_interface_data_t; + +/** + Add interface. + + If the MTU is not set, it will be set to the csp_buffer_data_size() - sizeof(uint32_t), to make room for the CRC32 added to the packet. + + @param[in] iface CSP interface, initialized with name and inteface_data pointing to a valid #csp_kiss_interface_data_t. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_kiss_add_interface(csp_iface_t * iface); + +/** + Send CSP packet over KISS (nexthop). + + @param[in] ifroute route. + @param[in] packet CSP packet to send. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_kiss_tx(const csp_route_t * ifroute, csp_packet_t * packet); + +/** + Process received CAN frame. + + Called from driver when a chunk of data has been received. Once a complete frame has been received, the CSP packet will be routed on. + + @param[in] iface incoming interface. + @param[in] buf reveived data. + @param[in] len length of \a buf. + @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! +*/ +void csp_kiss_rx(csp_iface_t * iface, const uint8_t * buf, size_t len, void * pxTaskWoken); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_lo.h b/Program/libcsp/include/csp/interfaces/csp_if_lo.h new file mode 100755 index 0000000..865d299 --- /dev/null +++ b/Program/libcsp/include/csp/interfaces/csp_if_lo.h @@ -0,0 +1,49 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_IF_LO_H_ +#define _CSP_IF_LO_H_ + +/** + @file + + Loopback interface. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Name of loopback interface. +*/ +#define CSP_IF_LOOPBACK_NAME "LOOP" + +/** + Loopback interface. +*/ +extern csp_iface_t csp_if_lo; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h b/Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h new file mode 100755 index 0000000..c61f83f --- /dev/null +++ b/Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h @@ -0,0 +1,118 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef CSP_IF_ZMQHUB_H_ +#define CSP_IF_ZMQHUB_H_ + +/** + @file + + ZMQ (ZeroMQ) interface. + + The ZMQ interface is designed to connect to a ZMQ hub, also refered to as \a zmqproxy. The zmqproxy can be found under examples, + and is based on zmq_proxy() - provided by the ZMQ API. + + For further details on ZMQ, see http://www.zeromq.org. +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + zmqproxy default subscribe (rx) port. + The client must connect it's publish endpoint to the zmqproxy's subscribe port. +*/ +#define CSP_ZMQPROXY_SUBSCRIBE_PORT 6000 + +/** + zmqproxy default publish (tx) port. + The client must connect it's subscribe endpoint to the zmqproxy's publish port. +*/ +#define CSP_ZMQPROXY_PUBLISH_PORT 7000 + +/** + Default ZMQ interface name. +*/ +#define CSP_ZMQHUB_IF_NAME "ZMQHUB" + +/** + Format endpoint connection string for ZMQ. + + @param[in] host host name of IP. + @param[in] port IP port. + @param[out] buf user allocated buffer for receiving formatted string. + @param[in] buf_size size of \a buf. + @return #CSP_ERR_NONE on succcess. + @return #CSP_ERR_NOMEM if supplied buffer too small. +*/ +int csp_zmqhub_make_endpoint(const char * host, uint16_t port, char * buf, size_t buf_size); + +/** + Setup ZMQ interface. + @param[in] addr only receive messages matching this address (255 means all). This is set as \a rx_filter in call to + @param[in] host host name or IP of zmqproxy host. Endpoints are created using the \a host and the default subscribe/publish ports. + @param[in] flags flags for controlling features on the connection. + @param[out] return_interface created CSP interface. + @return #CSP_ERR_NONE on succcess - else assert. +*/ +int csp_zmqhub_init(uint8_t addr, + const char * host, + uint32_t flags, + csp_iface_t ** return_interface); + +/** + Setup ZMQ interface. + @param[in] addr only receive messages matching this address (255 means all). This is set as a \a rx_filter. + @param[in] publish_endpoint publish (tx) endpoint -> connect to zmqproxy's subscribe port #CSP_ZMQPROXY_SUBSCRIBE_PORT. + @param[in] subscribe_endpoint subscribe (rx) endpoint -> connect to zmqproxy's publish port #CSP_ZMQPROXY_PUBLISH_PORT. + @param[in] flags flags for controlling features on the connection. + @param[out] return_interface created CSP interface. + @return #CSP_ERR_NONE on succcess - else assert. +*/ +int csp_zmqhub_init_w_endpoints(uint8_t addr, + const char * publish_endpoint, + const char * subscribe_endpoint, + uint32_t flags, + csp_iface_t ** return_interface); + +/** + Setup ZMQ interface. + @param[in] ifname Name of CSP interface, use NULL for default name #CSP_ZMQHUB_IF_NAME. + @param[in] rx_filter Rx filters, use NULL for no filters - receive all messages. + @param[in] rx_filter_count Number of Rx filters in \a rx_filter. + @param[in] publish_endpoint publish (tx) endpoint -> connect to zmqproxy's subscribe port #CSP_ZMQPROXY_SUBSCRIBE_PORT. + @param[in] subscribe_endpoint subscribe (rx) endpoint -> connect to zmqproxy's publish port #CSP_ZMQPROXY_PUBLISH_PORT. + @param[in] flags flags for controlling features on the connection. + @param[out] return_interface created CSP interface. + @return #CSP_ERR_NONE on succcess - else assert. +*/ +int csp_zmqhub_init_w_name_endpoints_rxfilter(const char * ifname, + const uint8_t rx_filter[], unsigned int rx_filter_count, + const char * publish_endpoint, + const char * subscribe_endpoint, + uint32_t flags, + csp_iface_t ** return_interface); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/arch/csp_system.c b/Program/libcsp/src/arch/csp_system.c new file mode 100755 index 0000000..8094cb2 --- /dev/null +++ b/Program/libcsp/src/arch/csp_system.c @@ -0,0 +1,58 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +static csp_sys_reboot_t csp_sys_reboot_callback = NULL; +static csp_sys_shutdown_t csp_sys_shutdown_callback = NULL; + +void csp_sys_set_reboot(csp_sys_reboot_t reboot) { + + csp_sys_reboot_callback = reboot; + +} + +int csp_sys_reboot(void) { + + if (csp_sys_reboot_callback) { + return (csp_sys_reboot_callback)(); + } + csp_log_warn("%s not supported - no user function set", __FUNCTION__); + return CSP_ERR_NOTSUP; + +} + +void csp_sys_set_shutdown(csp_sys_shutdown_t shutdown) { + + csp_sys_shutdown_callback = shutdown; + +} + +int csp_sys_shutdown(void) { + + if (csp_sys_shutdown_callback) { + return (csp_sys_shutdown_callback)(); + } + csp_log_warn("%s not supported - no user function set", __FUNCTION__); + return CSP_ERR_NOTSUP; + +} diff --git a/Program/libcsp/src/arch/csp_time.c b/Program/libcsp/src/arch/csp_time.c new file mode 100755 index 0000000..b8423f3 --- /dev/null +++ b/Program/libcsp/src/arch/csp_time.c @@ -0,0 +1,32 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +static uint32_t uptime_s_offset = 0; + +uint32_t csp_get_uptime_s(void) { + + uint32_t seconds = csp_get_s(); + if (uptime_s_offset == 0) { + uptime_s_offset = seconds; + } + return (seconds - uptime_s_offset); +} diff --git a/Program/libcsp/src/arch/freertos/csp_clock.c b/Program/libcsp/src/arch/freertos/csp_clock.c new file mode 100755 index 0000000..ff261d0 --- /dev/null +++ b/Program/libcsp/src/arch/freertos/csp_clock.c @@ -0,0 +1,32 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +__attribute__((weak)) void csp_clock_get_time(csp_timestamp_t * time) { + time->tv_sec = 0; + time->tv_nsec = 0; +} + +__attribute__((weak)) int csp_clock_set_time(const csp_timestamp_t * time) { + csp_log_warn("csp_clock_set_time() not supported"); + return CSP_ERR_NOTSUP; +} diff --git a/Program/libcsp/src/arch/freertos/csp_malloc.c b/Program/libcsp/src/arch/freertos/csp_malloc.c new file mode 100755 index 0000000..e346aab --- /dev/null +++ b/Program/libcsp/src/arch/freertos/csp_malloc.c @@ -0,0 +1,42 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +#include + +void * csp_malloc(size_t size) { + return pvPortMalloc(size); +} + +void * csp_calloc(size_t nmemb, size_t size) { + size = (nmemb * size); + void * ptr = csp_malloc(size); + if (ptr) { + memset(ptr, 0, size); + } + return ptr; +} + +void csp_free(void *ptr) { + vPortFree(ptr); +} diff --git a/Program/libcsp/src/arch/freertos/csp_queue.c b/Program/libcsp/src/arch/freertos/csp_queue.c new file mode 100755 index 0000000..14ed7cb --- /dev/null +++ b/Program/libcsp/src/arch/freertos/csp_queue.c @@ -0,0 +1,60 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include // FreeRTOS + +csp_queue_handle_t csp_queue_create(int length, size_t item_size) { + return xQueueCreate(length, item_size); +} + +void csp_queue_remove(csp_queue_handle_t queue) { + vQueueDelete(queue); +} + +int csp_queue_enqueue(csp_queue_handle_t handle, const void * value, uint32_t timeout) { + if (timeout != CSP_MAX_TIMEOUT) + timeout = timeout / portTICK_RATE_MS; + return xQueueSendToBack(handle, value, timeout); +} + +int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * task_woken) { + return xQueueSendToBackFromISR(handle, value, task_woken); +} + +int csp_queue_dequeue(csp_queue_handle_t handle, void * buf, uint32_t timeout) { + if (timeout != CSP_MAX_TIMEOUT) + timeout = timeout / portTICK_RATE_MS; + return xQueueReceive(handle, buf, timeout); +} + +int csp_queue_dequeue_isr(csp_queue_handle_t handle, void * buf, CSP_BASE_TYPE * task_woken) { + return xQueueReceiveFromISR(handle, buf, task_woken); +} + +int csp_queue_size(csp_queue_handle_t handle) { + return uxQueueMessagesWaiting(handle); +} + +int csp_queue_size_isr(csp_queue_handle_t handle) { + return uxQueueMessagesWaitingFromISR(handle); +} diff --git a/Program/libcsp/src/arch/freertos/csp_semaphore.c b/Program/libcsp/src/arch/freertos/csp_semaphore.c new file mode 100755 index 0000000..2ecaeae --- /dev/null +++ b/Program/libcsp/src/arch/freertos/csp_semaphore.c @@ -0,0 +1,84 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +int csp_mutex_create(csp_mutex_t * mutex) { + *mutex = xSemaphoreCreateMutex(); + if (*mutex) { + return CSP_SEMAPHORE_OK; + } else { + return CSP_SEMAPHORE_ERROR; + } +} + +int csp_mutex_remove(csp_mutex_t * mutex) { + return csp_bin_sem_remove(mutex); +} + +int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { + return csp_bin_sem_wait(mutex, timeout); +} + +int csp_mutex_unlock(csp_mutex_t * mutex) { + return csp_bin_sem_post(mutex); +} + +int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { + vSemaphoreCreateBinary(*sem); + return CSP_SEMAPHORE_OK; +} + +int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { + if ((sem != NULL) && (*sem != NULL)) { + vSemaphoreDelete(*sem); + } + return CSP_SEMAPHORE_OK; +} + +int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { + csp_log_lock("Wait: %p", sem); + if (timeout != CSP_MAX_TIMEOUT) { + timeout = timeout / portTICK_RATE_MS; + } + if (xSemaphoreTake(*sem, timeout) == pdPASS) { + return CSP_SEMAPHORE_OK; + } + return CSP_SEMAPHORE_ERROR; +} + +int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { + csp_log_lock("Post: %p", sem); + if (xSemaphoreGive(*sem) == pdPASS) { + return CSP_SEMAPHORE_OK; + } + return CSP_SEMAPHORE_ERROR; +} + +int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * pxTaskWoken) { + csp_log_lock("Post: %p", sem); + if (xSemaphoreGiveFromISR(*sem, pxTaskWoken) == pdPASS) { + return CSP_SEMAPHORE_OK; + } else { + return CSP_SEMAPHORE_ERROR; + } +} + diff --git a/Program/libcsp/src/arch/freertos/csp_system.c b/Program/libcsp/src/arch/freertos/csp_system.c new file mode 100755 index 0000000..cafe5f5 --- /dev/null +++ b/Program/libcsp/src/arch/freertos/csp_system.c @@ -0,0 +1,88 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include // FreeRTOS + +#include + +int csp_sys_tasklist(char * out) { +#if (tskKERNEL_VERSION_MAJOR < 8) + vTaskList((signed portCHAR *) out); +#else + vTaskList(out); +#endif + return CSP_ERR_NONE; +} + +int csp_sys_tasklist_size(void) { + + return 40 * uxTaskGetNumberOfTasks(); +} + +uint32_t csp_sys_memfree(void) { + + return (uint32_t) xPortGetFreeHeapSize(); + +} + +void csp_sys_set_color(csp_color_t color) { + + unsigned int color_code, modifier_code; + switch (color & COLOR_MASK_COLOR) { + case COLOR_BLACK: + color_code = 30; break; + case COLOR_RED: + color_code = 31; break; + case COLOR_GREEN: + color_code = 32; break; + case COLOR_YELLOW: + color_code = 33; break; + case COLOR_BLUE: + color_code = 34; break; + case COLOR_MAGENTA: + color_code = 35; break; + case COLOR_CYAN: + color_code = 36; break; + case COLOR_WHITE: + color_code = 37; break; + case COLOR_RESET: + default: + color_code = 0; break; + } + + switch (color & COLOR_MASK_MODIFIER) { + case COLOR_BOLD: + modifier_code = 1; break; + case COLOR_UNDERLINE: + modifier_code = 2; break; + case COLOR_BLINK: + modifier_code = 3; break; + case COLOR_HIDE: + modifier_code = 4; break; + case COLOR_NORMAL: + default: + modifier_code = 0; break; + } + + printf("\033[%u;%um", modifier_code, color_code); +} diff --git a/Program/libcsp/src/arch/freertos/csp_thread.c b/Program/libcsp/src/arch/freertos/csp_thread.c new file mode 100755 index 0000000..4c6a45d --- /dev/null +++ b/Program/libcsp/src/arch/freertos/csp_thread.c @@ -0,0 +1,48 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { + + csp_thread_handle_t handle; +#if (tskKERNEL_VERSION_MAJOR >= 8) + portBASE_TYPE ret = xTaskCreate(routine, thread_name, stack_size, parameters, priority, &handle); +#else + portBASE_TYPE ret = xTaskCreate(routine, (signed char *) thread_name, stack_size, parameters, priority, &handle); +#endif + if (ret != pdTRUE) { + return CSP_ERR_NOMEM; + } + if (return_handle) { + *return_handle = handle; + } + return CSP_ERR_NONE; +} + +void csp_thread_exit(void) { + + vTaskDelete(NULL); // Function must exist, otherwise code wont behave the same on all platforms. +} + +void csp_sleep_ms(unsigned int time_ms) { + + vTaskDelay(time_ms / portTICK_RATE_MS); +} diff --git a/Program/libcsp/src/arch/freertos/csp_time.c b/Program/libcsp/src/arch/freertos/csp_time.c new file mode 100755 index 0000000..4b2c21f --- /dev/null +++ b/Program/libcsp/src/arch/freertos/csp_time.c @@ -0,0 +1,40 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include // FreeRTOS + +uint32_t csp_get_ms(void) { + return (uint32_t)(xTaskGetTickCount() * (1000/configTICK_RATE_HZ)); +} + +uint32_t csp_get_ms_isr(void) { + return (uint32_t)(xTaskGetTickCountFromISR() * (1000/configTICK_RATE_HZ)); +} + +uint32_t csp_get_s(void) { + return (uint32_t)(xTaskGetTickCount()/configTICK_RATE_HZ); +} + +uint32_t csp_get_s_isr(void) { + return (uint32_t)(xTaskGetTickCountFromISR()/configTICK_RATE_HZ); +} diff --git a/Program/libcsp/src/arch/macosx/csp_clock.c b/Program/libcsp/src/arch/macosx/csp_clock.c new file mode 100755 index 0000000..5734a9e --- /dev/null +++ b/Program/libcsp/src/arch/macosx/csp_clock.c @@ -0,0 +1,22 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Use POSIX implementation +#include "../posix/csp_clock.c" diff --git a/Program/libcsp/src/arch/macosx/csp_malloc.c b/Program/libcsp/src/arch/macosx/csp_malloc.c new file mode 100755 index 0000000..b948e50 --- /dev/null +++ b/Program/libcsp/src/arch/macosx/csp_malloc.c @@ -0,0 +1,22 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Use POSIX implementation +#include "../posix/csp_malloc.c" diff --git a/Program/libcsp/src/arch/macosx/csp_queue.c b/Program/libcsp/src/arch/macosx/csp_queue.c new file mode 100755 index 0000000..621bf89 --- /dev/null +++ b/Program/libcsp/src/arch/macosx/csp_queue.c @@ -0,0 +1,22 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Use POSIX implementation +#include "../posix/csp_queue.c" diff --git a/Program/libcsp/src/arch/macosx/csp_semaphore.c b/Program/libcsp/src/arch/macosx/csp_semaphore.c new file mode 100755 index 0000000..b35e6f9 --- /dev/null +++ b/Program/libcsp/src/arch/macosx/csp_semaphore.c @@ -0,0 +1,85 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include + +#include + +int csp_mutex_create(csp_mutex_t * mutex) { + csp_log_lock("Mutex init: %p", mutex); + *mutex = pthread_queue_create(1, sizeof(int)); + if (*mutex) { + int dummy = 0; + pthread_queue_enqueue(*mutex, &dummy, 0); + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} + +int csp_mutex_remove(csp_mutex_t * mutex) { + pthread_queue_delete(*mutex); + return CSP_SEMAPHORE_OK; +} + +int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { + + csp_log_lock("Wait: %p timeout %"PRIu32, mutex, timeout); + + int dummy = 0; + if (pthread_queue_dequeue(*mutex, &dummy, timeout) == PTHREAD_QUEUE_OK) { + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} + +int csp_mutex_unlock(csp_mutex_t * mutex) { + int dummy = 0; + if (pthread_queue_enqueue(*mutex, &dummy, 0) == PTHREAD_QUEUE_OK) { + return CSP_SEMAPHORE_OK; + } + return CSP_SEMAPHORE_ERROR; +} + +int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { + return csp_mutex_create(sem); +} + +int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { + return csp_mutex_remove(sem); +} + +int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { + return csp_mutex_lock(sem, timeout); +} + +int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { + return csp_mutex_unlock(sem); +} + +int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * task_woken) { + return csp_mutex_unlock(sem); +} diff --git a/Program/libcsp/src/arch/macosx/csp_system.c b/Program/libcsp/src/arch/macosx/csp_system.c new file mode 100755 index 0000000..fb03f9f --- /dev/null +++ b/Program/libcsp/src/arch/macosx/csp_system.c @@ -0,0 +1,87 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include + +#include + +int csp_sys_tasklist(char * out) { + + strcpy(out, "Tasklist not available on OSX"); + return CSP_ERR_NONE; + +} + +int csp_sys_tasklist_size(void) { + + return 100; + +} + +uint32_t csp_sys_memfree(void) { + + return 0; // not implemented + +} + +void csp_sys_set_color(csp_color_t color) { + + unsigned int color_code, modifier_code; + switch (color & COLOR_MASK_COLOR) { + case COLOR_BLACK: + color_code = 30; break; + case COLOR_RED: + color_code = 31; break; + case COLOR_GREEN: + color_code = 32; break; + case COLOR_YELLOW: + color_code = 33; break; + case COLOR_BLUE: + color_code = 34; break; + case COLOR_MAGENTA: + color_code = 35; break; + case COLOR_CYAN: + color_code = 36; break; + case COLOR_WHITE: + color_code = 37; break; + case COLOR_RESET: + default: + color_code = 0; break; + } + + switch (color & COLOR_MASK_MODIFIER) { + case COLOR_BOLD: + modifier_code = 1; break; + case COLOR_UNDERLINE: + modifier_code = 2; break; + case COLOR_BLINK: + modifier_code = 3; break; + case COLOR_HIDE: + modifier_code = 4; break; + case COLOR_NORMAL: + default: + modifier_code = 0; break; + } + + printf("\033[%u;%um", modifier_code, color_code); +} diff --git a/Program/libcsp/src/arch/macosx/csp_thread.c b/Program/libcsp/src/arch/macosx/csp_thread.c new file mode 100755 index 0000000..6a51bb4 --- /dev/null +++ b/Program/libcsp/src/arch/macosx/csp_thread.c @@ -0,0 +1,55 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include + +int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { + + pthread_t handle; + int res = pthread_create(&handle, NULL, routine, parameters); + if (res) { + return CSP_ERR_NOMEM; + } + if (return_handle) { + *return_handle = handle; + } + + return CSP_ERR_NONE; +} + +void csp_thread_exit(void) { + + pthread_exit(CSP_TASK_RETURN); +} + +void csp_sleep_ms(unsigned int time_ms) { + + + struct timespec req, rem; + req.tv_sec = (time_ms / 1000U); + req.tv_nsec = ((time_ms % 1000U) * 1000000U); + + while ((nanosleep(&req, &rem) < 0) && (errno == EINTR)) { + req = rem; + } +} diff --git a/Program/libcsp/src/arch/macosx/csp_time.c b/Program/libcsp/src/arch/macosx/csp_time.c new file mode 100755 index 0000000..8b67d5c --- /dev/null +++ b/Program/libcsp/src/arch/macosx/csp_time.c @@ -0,0 +1,22 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Use POSIX implementation +#include "../posix/csp_time.c" diff --git a/Program/libcsp/src/arch/macosx/pthread_queue.c b/Program/libcsp/src/arch/macosx/pthread_queue.c new file mode 100755 index 0000000..6e9ea98 --- /dev/null +++ b/Program/libcsp/src/arch/macosx/pthread_queue.c @@ -0,0 +1,178 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* +Inspired by c-pthread-queue by Matthew Dickinson +http://code.google.com/p/c-pthread-queue/ +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +pthread_queue_t * pthread_queue_create(int length, size_t item_size) { + + pthread_queue_t * q = malloc(sizeof(pthread_queue_t)); + + if (q != NULL) { + q->buffer = malloc(length*item_size); + if (q->buffer != NULL) { + q->size = length; + q->item_size = item_size; + q->items = 0; + q->in = 0; + q->out = 0; + if (pthread_mutex_init(&(q->mutex), NULL) || pthread_cond_init(&(q->cond_full), NULL) || pthread_cond_init(&(q->cond_empty), NULL)) { + free(q->buffer); + free(q); + q = NULL; + } + } else { + free(q); + q = NULL; + } + } + + return q; + +} + +void pthread_queue_delete(pthread_queue_t * q) { + + if (q == NULL) + return; + + free(q->buffer); + free(q); + + return; + +} + +int pthread_queue_enqueue(pthread_queue_t * queue, const void * value, uint32_t timeout) { + + int ret; + + /* Calculate timeout */ + struct timespec ts; + + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + ts.tv_sec = mts.tv_sec; + ts.tv_nsec = mts.tv_nsec; + + uint32_t sec = timeout / 1000; + uint32_t nsec = (timeout - 1000 * sec) * 1000000; + + ts.tv_sec += sec; + + if (ts.tv_nsec + nsec > 1000000000) + ts.tv_sec++; + + ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; + + /* Get queue lock */ + pthread_mutex_lock(&(queue->mutex)); + while (queue->items == queue->size) { + ret = pthread_cond_timedwait(&(queue->cond_full), &(queue->mutex), &ts); + if (ret != 0) { + pthread_mutex_unlock(&(queue->mutex)); + return PTHREAD_QUEUE_FULL; + } + } + + /* Coby object from input buffer */ + memcpy(queue->buffer+(queue->in * queue->item_size), value, queue->item_size); + queue->items++; + queue->in = (queue->in + 1) % queue->size; + pthread_mutex_unlock(&(queue->mutex)); + + /* Nofify blocked threads */ + pthread_cond_broadcast(&(queue->cond_empty)); + + return PTHREAD_QUEUE_OK; + +} + +int pthread_queue_dequeue(pthread_queue_t * queue, void * buf, uint32_t timeout) { + + int ret; + + /* Calculate timeout */ + struct timespec ts; + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + ts.tv_sec = mts.tv_sec; + ts.tv_nsec = mts.tv_nsec; + + uint32_t sec = timeout / 1000; + uint32_t nsec = (timeout - 1000 * sec) * 1000000; + + ts.tv_sec += sec; + + if (ts.tv_nsec + nsec > 1000000000) + ts.tv_sec++; + + ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; + + /* Get queue lock */ + pthread_mutex_lock(&(queue->mutex)); + while (queue->items == 0) { + ret = pthread_cond_timedwait(&(queue->cond_empty), &(queue->mutex), &ts); + if (ret != 0) { + pthread_mutex_unlock(&(queue->mutex)); + return PTHREAD_QUEUE_EMPTY; + } + } + + /* Coby object to output buffer */ + memcpy(buf, queue->buffer+(queue->out * queue->item_size), queue->item_size); + queue->items--; + queue->out = (queue->out + 1) % queue->size; + pthread_mutex_unlock(&(queue->mutex)); + + /* Nofify blocked threads */ + pthread_cond_broadcast(&(queue->cond_full)); + + return PTHREAD_QUEUE_OK; + +} + +int pthread_queue_items(pthread_queue_t * queue) { + + pthread_mutex_lock(&(queue->mutex)); + int items = queue->items; + pthread_mutex_unlock(&(queue->mutex)); + + return items; + +} diff --git a/Program/libcsp/src/arch/posix/csp_clock.c b/Program/libcsp/src/arch/posix/csp_clock.c new file mode 100755 index 0000000..2661cda --- /dev/null +++ b/Program/libcsp/src/arch/posix/csp_clock.c @@ -0,0 +1,45 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +__attribute__((weak)) void csp_clock_get_time(csp_timestamp_t * time) { + + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { + time->tv_sec = ts.tv_sec; + time->tv_nsec = ts.tv_nsec; + } else { + time->tv_sec = 0; + time->tv_nsec = 0; + } +} + +__attribute__((weak)) int csp_clock_set_time(const csp_timestamp_t * time) { + + struct timespec ts = {.tv_sec = time->tv_sec, .tv_nsec = time->tv_nsec}; + if (clock_settime(CLOCK_REALTIME, &ts) == 0) { + return CSP_ERR_NONE; + } + return CSP_ERR_INVAL; // CSP doesn't have any matching error codes + +} diff --git a/Program/libcsp/src/arch/posix/csp_malloc.c b/Program/libcsp/src/arch/posix/csp_malloc.c new file mode 100755 index 0000000..6fa9c1f --- /dev/null +++ b/Program/libcsp/src/arch/posix/csp_malloc.c @@ -0,0 +1,36 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +void * csp_malloc(size_t size) { + return malloc(size); +} + +void * csp_calloc(size_t nmemb, size_t size) { + return calloc(nmemb, size); +} + +void csp_free(void *ptr) { + free(ptr); +} + diff --git a/Program/libcsp/src/arch/posix/csp_queue.c b/Program/libcsp/src/arch/posix/csp_queue.c new file mode 100755 index 0000000..b40443f --- /dev/null +++ b/Program/libcsp/src/arch/posix/csp_queue.c @@ -0,0 +1,60 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +csp_queue_handle_t csp_queue_create(int length, size_t item_size) { + return pthread_queue_create(length, item_size); +} + +void csp_queue_remove(csp_queue_handle_t queue) { + return pthread_queue_delete(queue); +} + +int csp_queue_enqueue(csp_queue_handle_t handle, const void *value, uint32_t timeout) { + return pthread_queue_enqueue(handle, value, timeout); +} + +int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * task_woken) { + if (task_woken != NULL) { + *task_woken = 0; + } + return csp_queue_enqueue(handle, value, 0); +} + +int csp_queue_dequeue(csp_queue_handle_t handle, void *buf, uint32_t timeout) { + return pthread_queue_dequeue(handle, buf, timeout); +} + +int csp_queue_dequeue_isr(csp_queue_handle_t handle, void *buf, CSP_BASE_TYPE * task_woken) { + if (task_woken != NULL) { + *task_woken = 0; + } + return csp_queue_dequeue(handle, buf, 0); +} + +int csp_queue_size(csp_queue_handle_t handle) { + return pthread_queue_items(handle); +} + +int csp_queue_size_isr(csp_queue_handle_t handle) { + return pthread_queue_items(handle); +} diff --git a/Program/libcsp/src/arch/posix/csp_semaphore.c b/Program/libcsp/src/arch/posix/csp_semaphore.c new file mode 100755 index 0000000..00e9cd5 --- /dev/null +++ b/Program/libcsp/src/arch/posix/csp_semaphore.c @@ -0,0 +1,155 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +int csp_mutex_create(csp_mutex_t * mutex) { + csp_log_lock("Mutex init: %p", mutex); + if (pthread_mutex_init(mutex, NULL) == 0) { + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} + +int csp_mutex_remove(csp_mutex_t * mutex) { + if (pthread_mutex_destroy(mutex) == 0) { + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} + +int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { + + int ret; + + csp_log_lock("Wait: %p timeout %"PRIu32, mutex, timeout); + + if (timeout == CSP_MAX_TIMEOUT) { + ret = pthread_mutex_lock(mutex); + } else { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts)) { + return CSP_SEMAPHORE_ERROR; + } + + uint32_t sec = timeout / 1000; + uint32_t nsec = (timeout - 1000 * sec) * 1000000; + + ts.tv_sec += sec; + + if (ts.tv_nsec + nsec >= 1000000000) { + ts.tv_sec++; + } + + ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; + + ret = pthread_mutex_timedlock(mutex, &ts); + } + + if (ret != 0) + return CSP_SEMAPHORE_ERROR; + + return CSP_SEMAPHORE_OK; +} + +int csp_mutex_unlock(csp_mutex_t * mutex) { + if (pthread_mutex_unlock(mutex) == 0) { + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} + +int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { + csp_log_lock("Semaphore init: %p", sem); + if (sem_init(sem, 0, 1) == 0) { + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} + +int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { + if (sem_destroy(sem) == 0) { + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} + +int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { + + int ret; + + csp_log_lock("Wait: %p timeout %"PRIu32, sem, timeout); + + if (timeout == CSP_MAX_TIMEOUT) { + ret = sem_wait(sem); + } else { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts)) { + return CSP_SEMAPHORE_ERROR; + } + + uint32_t sec = timeout / 1000; + uint32_t nsec = (timeout - 1000 * sec) * 1000000; + + ts.tv_sec += sec; + + if (ts.tv_nsec + nsec >= 1000000000) { + ts.tv_sec++; + } + + ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; + + ret = sem_timedwait(sem, &ts); + } + + if (ret != 0) + return CSP_SEMAPHORE_ERROR; + + return CSP_SEMAPHORE_OK; +} + +int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * task_woken) { + if (task_woken) { + *task_woken = 0; + } + return csp_bin_sem_post(sem); +} + +int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { + csp_log_lock("Post: %p", sem); + + int value; + sem_getvalue(sem, &value); + if (value > 0) { + return CSP_SEMAPHORE_OK; + } + + if (sem_post(sem) == 0) { + return CSP_SEMAPHORE_OK; + } + + return CSP_SEMAPHORE_ERROR; +} diff --git a/Program/libcsp/src/arch/posix/csp_system.c b/Program/libcsp/src/arch/posix/csp_system.c new file mode 100755 index 0000000..6f20833 --- /dev/null +++ b/Program/libcsp/src/arch/posix/csp_system.c @@ -0,0 +1,135 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int csp_sys_tasklist(char * out) { + + strcpy(out, "Tasklist not available on POSIX"); + return CSP_ERR_NONE; + +} + +int csp_sys_tasklist_size(void) { + + return 100; + +} + +uint32_t csp_sys_memfree(void) { + + uint32_t total = 0; + struct sysinfo info; + sysinfo(&info); + total = info.freeram * info.mem_unit; + return total; + +} + +// helper for doing log and mapping result to CSP_ERR +static int csp_sys_log_and_return(const char * function, int res) { + + if (res != 0) { + csp_log_warn("%s: failed to execute, returned error: %d, errno: %d", function, res, errno); + return CSP_ERR_INVAL; // no real suitable error code + } + csp_log_info("%s: executed", function); + return CSP_ERR_NONE; + +} + +int csp_sys_reboot_using_system(void) { + + return csp_sys_log_and_return(__FUNCTION__, system("reboot")); + +} + +int csp_sys_reboot_using_reboot(void) { + + sync(); // Sync filesystem + return csp_sys_log_and_return(__FUNCTION__, reboot(LINUX_REBOOT_CMD_RESTART)); + +} + +int csp_sys_shutdown_using_system(void) { + + return csp_sys_log_and_return(__FUNCTION__, system("halt")); + +} + +int csp_sys_shutdown_using_reboot(void) { + + sync(); // Sync filesystem + return csp_sys_log_and_return(__FUNCTION__, reboot(LINUX_REBOOT_CMD_HALT)); + +} + +void csp_sys_set_color(csp_color_t color) { + + unsigned int color_code, modifier_code; + switch (color & COLOR_MASK_COLOR) { + case COLOR_BLACK: + color_code = 30; break; + case COLOR_RED: + color_code = 31; break; + case COLOR_GREEN: + color_code = 32; break; + case COLOR_YELLOW: + color_code = 33; break; + case COLOR_BLUE: + color_code = 34; break; + case COLOR_MAGENTA: + color_code = 35; break; + case COLOR_CYAN: + color_code = 36; break; + case COLOR_WHITE: + color_code = 37; break; + case COLOR_RESET: + default: + color_code = 0; break; + } + + switch (color & COLOR_MASK_MODIFIER) { + case COLOR_BOLD: + modifier_code = 1; break; + case COLOR_UNDERLINE: + modifier_code = 2; break; + case COLOR_BLINK: + modifier_code = 3; break; + case COLOR_HIDE: + modifier_code = 4; break; + case COLOR_NORMAL: + default: + modifier_code = 0; break; + } + + printf("\033[%u;%um", modifier_code, color_code); +} diff --git a/Program/libcsp/src/arch/posix/csp_thread.c b/Program/libcsp/src/arch/posix/csp_thread.c new file mode 100755 index 0000000..621c1b9 --- /dev/null +++ b/Program/libcsp/src/arch/posix/csp_thread.c @@ -0,0 +1,72 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include + +int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { + + pthread_attr_t attributes; + if (pthread_attr_init(&attributes) != 0) { + return CSP_ERR_NOMEM; + } + // if stack size is 0, use default stack size + if (stack_size) { + unsigned int min_stack_size = PTHREAD_STACK_MIN;// use at least one memory + while (min_stack_size < stack_size) { // must reach at least the provided size + min_stack_size += PTHREAD_STACK_MIN;// keep memory page boundary (some systems may fail otherwise)) + } + pthread_attr_setstacksize(&attributes, min_stack_size); + } + pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);// no need to join with thread to free its resources + + pthread_t handle; + int return_code = pthread_create(&handle, &attributes, routine, parameters); + pthread_attr_destroy(&attributes); + + if (return_code != 0) { + return CSP_ERR_NOMEM; + } + if (return_handle) { + *return_handle = handle; + } + + return CSP_ERR_NONE; +} + +void csp_thread_exit(void) { + + pthread_exit(CSP_TASK_RETURN); +} + +void csp_sleep_ms(unsigned int time_ms) { + + struct timespec req, rem; + req.tv_sec = (time_ms / 1000U); + req.tv_nsec = ((time_ms % 1000U) * 1000000U); + + while ((nanosleep(&req, &rem) < 0) && (errno == EINTR)) { + req = rem; + } +} diff --git a/Program/libcsp/src/arch/posix/csp_time.c b/Program/libcsp/src/arch/posix/csp_time.c new file mode 100755 index 0000000..9485447 --- /dev/null +++ b/Program/libcsp/src/arch/posix/csp_time.c @@ -0,0 +1,57 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include + +uint32_t csp_get_ms(void) { + + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + return (uint32_t)((ts.tv_sec*1000) + (ts.tv_nsec/1000000)); + } + return 0; + +} + +uint32_t csp_get_ms_isr(void) { + + return csp_get_ms(); + +} + +uint32_t csp_get_s(void) { + + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + return (uint32_t)ts.tv_sec; + } + return 0; + +} + +uint32_t csp_get_s_isr(void) { + + return csp_get_s(); + +} diff --git a/Program/libcsp/src/arch/posix/pthread_queue.c b/Program/libcsp/src/arch/posix/pthread_queue.c new file mode 100755 index 0000000..066620b --- /dev/null +++ b/Program/libcsp/src/arch/posix/pthread_queue.c @@ -0,0 +1,239 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* +Inspired by c-pthread-queue by Matthew Dickinson +http://code.google.com/p/c-pthread-queue/ +*/ + +#include + +#include +#include + +#include + +static inline int get_deadline(struct timespec *ts, uint32_t timeout_ms) +{ + int ret = clock_gettime(CLOCK_MONOTONIC, ts); + + if (ret < 0) { + return ret; + } + + uint32_t sec = timeout_ms / 1000; + uint32_t nsec = (timeout_ms - 1000 * sec) * 1000000; + + ts->tv_sec += sec; + + if (ts->tv_nsec + nsec >= 1000000000) { + ts->tv_sec++; + } + + ts->tv_nsec = (ts->tv_nsec + nsec) % 1000000000; + + return ret; +} + +static inline int init_cond_clock_monotonic(pthread_cond_t * cond) +{ + + int ret; + pthread_condattr_t attr; + + pthread_condattr_init(&attr); + ret = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + + if (ret == 0) { + ret = pthread_cond_init(cond, &attr); + } + + pthread_condattr_destroy(&attr); + return ret; + +} + +pthread_queue_t * pthread_queue_create(int length, size_t item_size) { + + pthread_queue_t * q = csp_malloc(sizeof(pthread_queue_t)); + + if (q != NULL) { + q->buffer = csp_malloc(length*item_size); + if (q->buffer != NULL) { + q->size = length; + q->item_size = item_size; + q->items = 0; + q->in = 0; + q->out = 0; + if (pthread_mutex_init(&(q->mutex), NULL) || init_cond_clock_monotonic(&(q->cond_full)) || init_cond_clock_monotonic(&(q->cond_empty))) { + csp_free(q->buffer); + csp_free(q); + q = NULL; + } + } else { + csp_free(q); + q = NULL; + } + } + + return q; + +} + +void pthread_queue_delete(pthread_queue_t * q) { + + if (q == NULL) + return; + + csp_free(q->buffer); + csp_free(q); + + return; + +} + + +static inline int wait_slot_available(pthread_queue_t * queue, struct timespec *ts) { + + int ret; + + while (queue->items == queue->size) { + + if (ts != NULL) { + ret = pthread_cond_timedwait(&(queue->cond_full), &(queue->mutex), ts); + } else { + ret = pthread_cond_wait(&(queue->cond_full), &(queue->mutex)); + } + + if (ret != 0 && errno != EINTR) { + return PTHREAD_QUEUE_FULL; //Timeout + } + } + + return PTHREAD_QUEUE_OK; + +} + +int pthread_queue_enqueue(pthread_queue_t * queue, const void * value, uint32_t timeout) { + + int ret; + struct timespec ts; + struct timespec *pts = NULL; + + /* Calculate timeout */ + if (timeout != CSP_MAX_TIMEOUT) { + if (get_deadline(&ts, timeout) != 0) { + return PTHREAD_QUEUE_ERROR; + } + pts = &ts; + } else { + pts = NULL; + } + + /* Get queue lock */ + pthread_mutex_lock(&(queue->mutex)); + + ret = wait_slot_available(queue, pts); + if (ret == PTHREAD_QUEUE_OK) { + /* Copy object from input buffer */ + memcpy(queue->buffer+(queue->in * queue->item_size), value, queue->item_size); + queue->items++; + queue->in = (queue->in + 1) % queue->size; + } + + pthread_mutex_unlock(&(queue->mutex)); + + if (ret == PTHREAD_QUEUE_OK) { + /* Nofify blocked threads */ + pthread_cond_broadcast(&(queue->cond_empty)); + } + + return ret; + +} + +static inline int wait_item_available(pthread_queue_t * queue, struct timespec *ts) { + + int ret; + + while (queue->items == 0) { + + if (ts != NULL) { + ret = pthread_cond_timedwait(&(queue->cond_empty), &(queue->mutex), ts); + } else { + ret = pthread_cond_wait(&(queue->cond_empty), &(queue->mutex)); + } + + if (ret != 0 && errno != EINTR) { + return PTHREAD_QUEUE_EMPTY; //Timeout + } + } + + return PTHREAD_QUEUE_OK; + +} + +int pthread_queue_dequeue(pthread_queue_t * queue, void * buf, uint32_t timeout) { + + int ret; + struct timespec ts; + struct timespec *pts; + + /* Calculate timeout */ + if (timeout != CSP_MAX_TIMEOUT) { + if (get_deadline(&ts, timeout) != 0) { + return PTHREAD_QUEUE_ERROR; + } + pts = &ts; + } else { + pts = NULL; + } + + /* Get queue lock */ + pthread_mutex_lock(&(queue->mutex)); + + ret = wait_item_available(queue, pts); + if (ret == PTHREAD_QUEUE_OK) { + /* Coby object to output buffer */ + memcpy(buf, queue->buffer+(queue->out * queue->item_size), queue->item_size); + queue->items--; + queue->out = (queue->out + 1) % queue->size; + } + + pthread_mutex_unlock(&(queue->mutex)); + + if (ret == PTHREAD_QUEUE_OK) { + /* Nofify blocked threads */ + pthread_cond_broadcast(&(queue->cond_full)); + } + + return ret; + +} + +int pthread_queue_items(pthread_queue_t * queue) { + + pthread_mutex_lock(&(queue->mutex)); + int items = queue->items; + pthread_mutex_unlock(&(queue->mutex)); + + return items; + +} diff --git a/Program/libcsp/src/arch/windows/README b/Program/libcsp/src/arch/windows/README new file mode 100755 index 0000000..b97ce7f --- /dev/null +++ b/Program/libcsp/src/arch/windows/README @@ -0,0 +1,18 @@ +This directory contains files specific to the windows port of libcsp. + +To compile and create a static library, execute: + + python waf configure --with-os=windows build + +from the root of this project. Note python must be in PATH. + +The build requirements are: + * Windows Vista SP1 + * A recent version of MinGW _or_ MinGW-w64 + * Windows API headers + * cPython 2.5 or newer + +What provides the Windows API headers depends on the development environment: +Using MinGW: Headers provided by w32api package. windows_glue.h header is needed because these headers do not declare condition variables. +Using MinGW-w64: Headers should be available in the default configuration. You may have to compile the distribution from source. windows_glue.h should not be needed. + diff --git a/Program/libcsp/src/arch/windows/csp_clock.c b/Program/libcsp/src/arch/windows/csp_clock.c new file mode 100755 index 0000000..a398a61 --- /dev/null +++ b/Program/libcsp/src/arch/windows/csp_clock.c @@ -0,0 +1,42 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +#include + +//__attribute__((weak)) void csp_clock_get_time(csp_timestamp_t * time) { +void csp_clock_get_time(csp_timestamp_t * time) { + + FILETIME ftime; // 64-bit, representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). + GetSystemTimeAsFileTime(&ftime); + ULARGE_INTEGER itime = {.LowPart = ftime.dwLowDateTime, .HighPart = ftime.dwHighDateTime}; + itime.QuadPart -= 116444736000000000ULL; // 1 jan 1601 to 1 jan 1970 + time->tv_sec = itime.QuadPart / (1000ULL * 1000ULL * 10ULL); + time->tv_nsec = (itime.QuadPart % (1000ULL * 1000ULL * 10ULL)) * 100ULL; +} + +//__attribute__((weak)) int csp_clock_set_time(const csp_timestamp_t * time) { +int csp_clock_set_time(const csp_timestamp_t * time) { + csp_log_warn("csp_clock_set_time() not supported"); + return CSP_ERR_NOTSUP; +} diff --git a/Program/libcsp/src/arch/windows/csp_malloc.c b/Program/libcsp/src/arch/windows/csp_malloc.c new file mode 100755 index 0000000..03faca7 --- /dev/null +++ b/Program/libcsp/src/arch/windows/csp_malloc.c @@ -0,0 +1,35 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +void * csp_malloc(size_t size) { + return malloc(size); +} + +void * csp_calloc(size_t nmemb, size_t size) { + return calloc(nmemb, size); +} + +void csp_free(void * ptr) { + free(ptr); +} diff --git a/Program/libcsp/src/arch/windows/csp_queue.c b/Program/libcsp/src/arch/windows/csp_queue.c new file mode 100755 index 0000000..eb49738 --- /dev/null +++ b/Program/libcsp/src/arch/windows/csp_queue.c @@ -0,0 +1,59 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include "windows_queue.h" + +csp_queue_handle_t csp_queue_create(int length, size_t item_size) { + return windows_queue_create(length, item_size); +} + +void csp_queue_remove(csp_queue_handle_t queue) { + windows_queue_delete(queue); +} + +int csp_queue_enqueue(csp_queue_handle_t handle, const void *value, uint32_t timeout) { + return windows_queue_enqueue(handle, value, timeout); +} + +int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * task_woken) { + if( task_woken != NULL ) + *task_woken = 0; + return windows_queue_enqueue(handle, value, 0); +} + +int csp_queue_dequeue(csp_queue_handle_t handle, void *buf, uint32_t timeout) { + return windows_queue_dequeue(handle, buf, timeout); +} + +int csp_queue_dequeue_isr(csp_queue_handle_t handle, void * buf, CSP_BASE_TYPE * task_woken) { + if (task_woken != NULL) { + *task_woken = 0; + } + return windows_queue_dequeue(handle, buf, 0); +} + +int csp_queue_size(csp_queue_handle_t handle) { + return windows_queue_items(handle); +} + +int csp_queue_size_isr(csp_queue_handle_t handle) { + return windows_queue_items(handle); +} diff --git a/Program/libcsp/src/arch/windows/csp_semaphore.c b/Program/libcsp/src/arch/windows/csp_semaphore.c new file mode 100755 index 0000000..7f44478 --- /dev/null +++ b/Program/libcsp/src/arch/windows/csp_semaphore.c @@ -0,0 +1,100 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +int csp_mutex_create(csp_mutex_t * mutex) { + + HANDLE mutexHandle = CreateMutex(NULL, FALSE, FALSE); + if( mutexHandle == NULL ) { + return CSP_MUTEX_ERROR; + } + *mutex = mutexHandle; + return CSP_MUTEX_OK; +} + +int csp_mutex_remove(csp_mutex_t * mutex) { + + if( !CloseHandle(*mutex) ) { + return CSP_MUTEX_ERROR; + } + return CSP_MUTEX_OK; +} + +int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { + + if(WaitForSingleObject(*mutex, timeout) == WAIT_OBJECT_0) { + return CSP_MUTEX_OK; + } + return CSP_MUTEX_ERROR; +} + +int csp_mutex_unlock(csp_mutex_t * mutex) { + + if( !ReleaseMutex(*mutex) ) { + return CSP_MUTEX_ERROR; + } + return CSP_MUTEX_OK; +} + +int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { + + HANDLE semHandle = CreateSemaphore(NULL, 1, 1, NULL); + if( semHandle == NULL ) { + return CSP_SEMAPHORE_ERROR; + } + *sem = semHandle; + return CSP_SEMAPHORE_OK; +} + +int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { + + if( !CloseHandle(*sem) ) { + return CSP_SEMAPHORE_ERROR; + } + return CSP_SEMAPHORE_OK; +} + +int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { + + if( WaitForSingleObject(*sem, timeout) == WAIT_OBJECT_0 ) { + return CSP_SEMAPHORE_OK; + } + return CSP_SEMAPHORE_ERROR; +} + +int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { + + if( !ReleaseSemaphore(*sem, 1, NULL) ) { + return CSP_SEMAPHORE_ERROR; + } + return CSP_SEMAPHORE_OK; +} + +int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * task_woken) { + + if( task_woken != NULL ) { + *task_woken = 0; + } + return csp_bin_sem_post(sem); +} + diff --git a/Program/libcsp/src/arch/windows/csp_system.c b/Program/libcsp/src/arch/windows/csp_system.c new file mode 100755 index 0000000..a88ae48 --- /dev/null +++ b/Program/libcsp/src/arch/windows/csp_system.c @@ -0,0 +1,54 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include + +#include + +int csp_sys_tasklist(char * out) { + + strcpy(out, "Tasklist not available on Windows"); + return CSP_ERR_NONE; + +} + +int csp_sys_tasklist_size(void) { + + return 100; + +} + +uint32_t csp_sys_memfree(void) { + + MEMORYSTATUSEX statex; + statex.dwLength = sizeof(statex); + GlobalMemoryStatusEx(&statex); + DWORDLONG freePhysicalMem = statex.ullAvailPhys; + size_t total = (size_t) freePhysicalMem; + return (uint32_t)total; + +} + +void csp_sys_set_color(csp_color_t color) { + // not implemented +} diff --git a/Program/libcsp/src/arch/windows/csp_thread.c b/Program/libcsp/src/arch/windows/csp_thread.c new file mode 100755 index 0000000..af01945 --- /dev/null +++ b/Program/libcsp/src/arch/windows/csp_thread.c @@ -0,0 +1,46 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { + + HANDLE handle = (HANDLE) _beginthreadex(NULL, 0, routine, parameters, 0, 0); + if (handle == 0) { + return CSP_ERR_NOMEM; + } + if (return_handle) { + *return_handle = handle; + } + + return CSP_ERR_NONE; +} + +void csp_thread_exit(void) { + + _endthreadex(CSP_TASK_RETURN); +} + +void csp_sleep_ms(unsigned int time_ms) { + + Sleep(time_ms); +} diff --git a/Program/libcsp/src/arch/windows/csp_time.c b/Program/libcsp/src/arch/windows/csp_time.c new file mode 100755 index 0000000..7ca919d --- /dev/null +++ b/Program/libcsp/src/arch/windows/csp_time.c @@ -0,0 +1,44 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +uint32_t csp_get_ms(void) { + + return (uint32_t)GetTickCount(); +} + +uint32_t csp_get_ms_isr(void) { + + return csp_get_ms(); +} + +uint32_t csp_get_s(void) { + + uint32_t time_ms = csp_get_ms(); + return time_ms/1000; +} + +uint32_t csp_get_s_isr(void) { + + return csp_get_s(); +} diff --git a/Program/libcsp/src/arch/windows/windows_queue.c b/Program/libcsp/src/arch/windows/windows_queue.c new file mode 100755 index 0000000..815aa33 --- /dev/null +++ b/Program/libcsp/src/arch/windows/windows_queue.c @@ -0,0 +1,127 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "windows_queue.h" +#include +#include + +struct windows_queue_s { + void * buffer; + int size; + int item_size; + int items; + int head_idx; + CRITICAL_SECTION mutex; + CONDITION_VARIABLE cond_full; + CONDITION_VARIABLE cond_empty; +}; + +static int queueFull(windows_queue_t * queue) { + return queue->items == queue->size; +} + +static int queueEmpty(windows_queue_t * queue) { + return queue->items == 0; +} + +windows_queue_t * windows_queue_create(int length, size_t item_size) { + + windows_queue_t *queue = (windows_queue_t*)malloc(sizeof(windows_queue_t)); + if(queue == NULL) + goto queue_malloc_failed; + + queue->buffer = malloc(length*item_size); + if(queue->buffer == NULL) + goto buffer_malloc_failed; + + queue->size = length; + queue->item_size = item_size; + queue->items = 0; + queue->head_idx = 0; + + InitializeCriticalSection(&(queue->mutex)); + InitializeConditionVariable(&(queue->cond_full)); + InitializeConditionVariable(&(queue->cond_empty)); + goto queue_init_success; + +buffer_malloc_failed: + free(queue); + queue = NULL; +queue_malloc_failed: +queue_init_success: + return queue; +} + +void windows_queue_delete(windows_queue_t * q) { + + if(q==NULL) return; + DeleteCriticalSection(&(q->mutex)); + free(q->buffer); + free(q); +} + +int windows_queue_enqueue(windows_queue_t * queue, const void * value, int timeout) { + + int offset; + EnterCriticalSection(&(queue->mutex)); + while(queueFull(queue)) { + int ret = SleepConditionVariableCS(&(queue->cond_full), &(queue->mutex), timeout); + if( !ret ) { + LeaveCriticalSection(&(queue->mutex)); + return ret == WAIT_TIMEOUT ? WINDOWS_QUEUE_FULL : WINDOWS_QUEUE_ERROR; + } + } + offset = ((queue->head_idx+queue->items) % queue->size) * queue->item_size; + memcpy((unsigned char*)queue->buffer + offset, value, queue->item_size); + queue->items++; + + LeaveCriticalSection(&(queue->mutex)); + WakeAllConditionVariable(&(queue->cond_empty)); + return WINDOWS_QUEUE_OK; +} + +int windows_queue_dequeue(windows_queue_t * queue, void * buf, int timeout) { + + EnterCriticalSection(&(queue->mutex)); + while(queueEmpty(queue)) { + int ret = SleepConditionVariableCS(&(queue->cond_empty), &(queue->mutex), timeout); + if( !ret ) { + LeaveCriticalSection(&(queue->mutex)); + return ret == WAIT_TIMEOUT ? WINDOWS_QUEUE_EMPTY : WINDOWS_QUEUE_ERROR; + } + } + memcpy(buf, (unsigned char*)queue->buffer+(queue->head_idx%queue->size*queue->item_size), queue->item_size); + queue->items--; + queue->head_idx = (queue->head_idx + 1) % queue->size; + + LeaveCriticalSection(&(queue->mutex)); + WakeAllConditionVariable(&(queue->cond_full)); + return WINDOWS_QUEUE_OK; +} + +int windows_queue_items(windows_queue_t * queue) { + + int items; + EnterCriticalSection(&(queue->mutex)); + items = queue->items; + LeaveCriticalSection(&(queue->mutex)); + + return items; +} diff --git a/Program/libcsp/src/arch/windows/windows_queue.h b/Program/libcsp/src/arch/windows/windows_queue.h new file mode 100755 index 0000000..1bee749 --- /dev/null +++ b/Program/libcsp/src/arch/windows/windows_queue.h @@ -0,0 +1,46 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _WINDOWS_QUEUE_H_ +#define _WINDOWS_QUEUE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define WINDOWS_QUEUE_ERROR CSP_QUEUE_ERROR +#define WINDOWS_QUEUE_EMPTY CSP_QUEUE_ERROR +#define WINDOWS_QUEUE_FULL CSP_QUEUE_ERROR +#define WINDOWS_QUEUE_OK CSP_QUEUE_OK + +typedef struct windows_queue_s windows_queue_t; + +windows_queue_t * windows_queue_create(int length, size_t item_size); +void windows_queue_delete(windows_queue_t * q); +int windows_queue_enqueue(windows_queue_t * queue, const void * value, int timeout); +int windows_queue_dequeue(windows_queue_t * queue, void * buf, int timeout); +int windows_queue_items(windows_queue_t * queue); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/bindings/python/pycsp.c b/Program/libcsp/src/bindings/python/pycsp.c new file mode 100755 index 0000000..9f909c3 --- /dev/null +++ b/Program/libcsp/src/bindings/python/pycsp.c @@ -0,0 +1,1121 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +// #include +#include + +#include + +#define SOCKET_CAPSULE "csp_socket_t" +#define CONNECTION_CAPSULE "csp_conn_t" +#define PACKET_CAPSULE "csp_packet_t" + +static PyObject *Error = NULL; + +static int CSP_POINTER_HAS_BEEN_FREED = 0; // used to indicate pointer has been freed, because a NULL pointer can't be set. + +static void * get_capsule_pointer(PyObject* capsule, const char* expected_type, bool allow_null) { + const char* capsule_name = PyCapsule_GetName(capsule); + if (strcmp(capsule_name, expected_type) != 0) { + PyErr_Format(PyExc_TypeError, + "capsule contains unexpected type, expected=%s, got=%s", + expected_type, capsule_name); // TypeError is thrown + return NULL; + } + void * ptr = PyCapsule_GetPointer(capsule, expected_type); + if (ptr == &CSP_POINTER_HAS_BEEN_FREED) { + ptr = NULL; + } + if ((ptr == NULL) && !allow_null) { + PyErr_Format(PyExc_TypeError, + "capsule: type=%s - already freed", + expected_type); // TypeError is thrown + return NULL; + } + return ptr; +} + +static csp_packet_t * get_obj_as_packet(PyObject* obj, bool allow_null) { + return get_capsule_pointer(obj, PACKET_CAPSULE, allow_null); +} + +static csp_conn_t * get_obj_as_conn(PyObject* obj, bool allow_null) { + return get_capsule_pointer(obj, CONNECTION_CAPSULE, allow_null); +} + +static csp_socket_t * get_obj_as_socket(PyObject* obj, bool allow_null) { + return get_capsule_pointer(obj, SOCKET_CAPSULE, allow_null); +} + +static PyObject* PyErr_Error(const char * message, int error) { + PyErr_Format(Error, "%s, result/error: %d", message, error); // should set error as member + return NULL; +} + +static void pycsp_free_csp_buffer(PyObject *obj) { + csp_packet_t * packet = get_obj_as_packet(obj, true); + if (packet) { + csp_buffer_free(packet); + } + PyCapsule_SetPointer(obj, &CSP_POINTER_HAS_BEEN_FREED); +} + +static void pycsp_free_csp_conn(PyObject *obj) { + csp_conn_t * conn = get_obj_as_conn(obj, true); + if (conn) { + csp_close(conn); + } + PyCapsule_SetPointer(obj, &CSP_POINTER_HAS_BEEN_FREED); +} + +static void pycsp_free_csp_socket(PyObject *obj) { + csp_conn_t * socket = get_obj_as_socket(obj, true); + if (socket) { + csp_close(socket); + } + PyCapsule_SetPointer(obj, &CSP_POINTER_HAS_BEEN_FREED); +} + +static PyObject* pycsp_service_handler(PyObject *self, PyObject *args) { + PyObject* conn_capsule; + PyObject* packet_capsule; + if (!PyArg_ParseTuple(args, "OO", &conn_capsule, &packet_capsule)) { + return NULL; // TypeError is thrown + } + csp_conn_t* conn = get_obj_as_conn(conn_capsule, false); + if (conn == NULL) { + return NULL; + } + csp_packet_t* packet = get_obj_as_packet(packet_capsule, false); + if (packet == NULL) { + return NULL; + } + + csp_service_handler(conn, packet); + PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); + Py_RETURN_NONE; +} + +static void copy_string(const char * from, char * to, size_t size_to) { + memset(to, 0, size_to); + if (from && from[0]) { + strncpy(to, from, size_to - 1); + } +} + +static PyObject* pycsp_init(PyObject *self, PyObject *args) { + + csp_conf_t conf; + csp_conf_get_defaults(&conf); + + if (!PyArg_ParseTuple(args, "bsssHH", &conf.address, &conf.hostname, &conf.model, &conf.revision, &conf.buffers, &conf.buffer_data_size)) { + return NULL; // TypeError is thrown + } + + // csp_conf only saves the pointer, so the strings needs to be stored somewhere + static char hostname[CSP_HOSTNAME_LEN + 1]; + static char model[CSP_MODEL_LEN + 1]; + static char revision[CSP_CMP_IDENT_REV_LEN + 1]; + + copy_string(conf.hostname, hostname, sizeof(hostname)); + copy_string(conf.model, model, sizeof(model)); + copy_string(conf.revision, revision, sizeof(revision)); + + conf.hostname = hostname; + conf.model = model; + conf.revision = revision; + + int res = csp_init(&conf); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_init()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_get_hostname(PyObject *self, PyObject *args) { + return Py_BuildValue("s", csp_get_conf()->hostname); +} + +static PyObject* pycsp_get_model(PyObject *self, PyObject *args) { + return Py_BuildValue("s", csp_get_conf()->model); +} + +static PyObject* pycsp_get_revision(PyObject *self, PyObject *args) { + return Py_BuildValue("s", csp_get_conf()->revision); +} + +static PyObject* pycsp_socket(PyObject *self, PyObject *args) { + uint32_t opts = CSP_SO_NONE; + if (!PyArg_ParseTuple(args, "|I", &opts)) { + return NULL; // TypeError is thrown + } + + csp_socket_t * socket = csp_socket(opts); + if (socket == NULL) { + return PyErr_Error("csp_socket() - no free sockets/connections", CSP_ERR_NOBUFS); + } + return PyCapsule_New(socket, SOCKET_CAPSULE, pycsp_free_csp_socket); +} + +static PyObject* pycsp_accept(PyObject *self, PyObject *args) { + PyObject* socket_capsule; + uint32_t timeout = CSP_MAX_TIMEOUT; + if (!PyArg_ParseTuple(args, "O|I", &socket_capsule, &timeout)) { + return NULL; // TypeError is thrown + } + csp_socket_t* socket = get_obj_as_socket(socket_capsule, false); + if (socket == NULL) { + return NULL; + } + csp_conn_t* conn; + Py_BEGIN_ALLOW_THREADS; + conn = csp_accept(socket, timeout); + Py_END_ALLOW_THREADS; + if (conn == NULL) { + Py_RETURN_NONE; // timeout -> None + } + + return PyCapsule_New(conn, CONNECTION_CAPSULE, pycsp_free_csp_conn); +} + +static PyObject* pycsp_read(PyObject *self, PyObject *args) { + PyObject* conn_capsule; + uint32_t timeout = 500; + if (!PyArg_ParseTuple(args, "O|I", &conn_capsule, &timeout)) { + return NULL; // TypeError is thrown + } + csp_conn_t* conn = get_obj_as_conn(conn_capsule, false); + if (conn == NULL) { + return NULL; + } + csp_packet_t* packet; + Py_BEGIN_ALLOW_THREADS; + packet = csp_read(conn, timeout); + Py_END_ALLOW_THREADS; + if (packet == NULL) { + Py_RETURN_NONE; // timeout -> None + } + + return PyCapsule_New(packet, PACKET_CAPSULE, pycsp_free_csp_buffer); +} + +static PyObject* pycsp_send(PyObject *self, PyObject *args) { + PyObject* conn_capsule; + PyObject* packet_capsule; + uint32_t timeout = 1000; + if (!PyArg_ParseTuple(args, "OO|I", &conn_capsule, &packet_capsule, &timeout)) { + return NULL; // TypeError is thrown + } + csp_conn_t* conn = get_obj_as_conn(conn_capsule, false); + if (conn == NULL) { + return NULL; + } + csp_packet_t* packet = get_obj_as_packet(packet_capsule, false); + if (packet == NULL) { + return NULL; + } + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_send(conn, packet, timeout); + Py_END_ALLOW_THREADS; + if (res != 1) { + return PyErr_Error("csp_send()", res); + } + PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); + + Py_RETURN_NONE; +} + +static PyObject* pycsp_transaction(PyObject *self, PyObject *args) { + uint8_t prio; + uint8_t dest; + uint8_t port; + uint32_t timeout; + Py_buffer inbuf; + Py_buffer outbuf; + if (!PyArg_ParseTuple(args, "bbbIw*w*", &prio, &dest, &port, &timeout, &outbuf, &inbuf)) { + return NULL; // TypeError is thrown + } + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_transaction(prio, dest, port, timeout, outbuf.buf, outbuf.len, inbuf.buf, inbuf.len); + Py_END_ALLOW_THREADS; + if (res < 1) { + return PyErr_Error("csp_transaction()", res); + } + + return Py_BuildValue("i", res); +} + +static PyObject* pycsp_sendto(PyObject *self, PyObject *args) { + uint8_t prio; + uint8_t dest; + uint8_t dport; + uint8_t src_port; + uint32_t opts; + PyObject* packet_capsule; + uint32_t timeout = 1000; + if (!PyArg_ParseTuple(args, "bbbbIO|I", &prio, &dest, &dport, &src_port, &opts, &packet_capsule, &timeout)) { + Py_RETURN_NONE; + } + csp_packet_t* packet = get_obj_as_packet(packet_capsule, false); + if (packet == NULL) { + return NULL; + } + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_sendto(prio, dest, dport, src_port, opts, packet, timeout); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_sendto()", res); + } + PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); + + Py_RETURN_NONE; +} + +static PyObject* pycsp_sendto_reply(PyObject *self, PyObject *args) { + PyObject* request_packet_capsule; + PyObject* reply_packet_capsule; + uint32_t opts = CSP_O_NONE; + uint32_t timeout = 1000; + if (!PyArg_ParseTuple(args, "OO|II", &request_packet_capsule, &reply_packet_capsule, &opts, &timeout)) { + return NULL; // TypeError is thrown + } + csp_packet_t* request = get_obj_as_packet(request_packet_capsule, false); + if (request == NULL) { + return NULL; + } + csp_packet_t* reply = get_obj_as_packet(reply_packet_capsule, false); + if (reply == NULL) { + return NULL; + } + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_sendto_reply(request, reply, opts, timeout); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_sendto_reply()", res); + } + + PyCapsule_SetPointer(reply_packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); + Py_RETURN_NONE; +} + +static PyObject* pycsp_connect(PyObject *self, PyObject *args) { + uint8_t prio; + uint8_t dest; + uint8_t dport; + uint32_t timeout; + uint32_t opts; + if (!PyArg_ParseTuple(args, "bbbII", &prio, &dest, &dport, &timeout, &opts)) { + return NULL; // TypeError is thrown + } + + csp_conn_t *conn; + Py_BEGIN_ALLOW_THREADS; + conn = csp_connect(prio, dest, dport, timeout, opts); + Py_END_ALLOW_THREADS; + if (conn == NULL) { + return PyErr_Error("csp_connect() timeout or failed", CSP_ERR_TIMEDOUT); + } + + return PyCapsule_New(conn, CONNECTION_CAPSULE, pycsp_free_csp_conn); +} + +static PyObject* pycsp_close(PyObject *self, PyObject *conn_capsule) { + csp_conn_t * conn = get_obj_as_conn(conn_capsule, true); + if (conn) { + csp_close(conn); + PyCapsule_SetPointer(conn_capsule, &CSP_POINTER_HAS_BEEN_FREED); + } + + return Py_BuildValue("i", CSP_ERR_NONE); +} + +static PyObject* pycsp_conn_dport(PyObject *self, PyObject *conn_capsule) { + csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); + if (conn == NULL) { + return NULL; // TypeError is thrown + } + return Py_BuildValue("i", csp_conn_dport(conn)); +} + +static PyObject* pycsp_conn_sport(PyObject *self, PyObject *conn_capsule) { + csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); + if (conn == NULL) { + return NULL; // TypeError is thrown + } + return Py_BuildValue("i", csp_conn_sport(conn)); +} + +static PyObject* pycsp_conn_dst(PyObject *self, PyObject *conn_capsule) { + csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); + if (conn == NULL) { + return NULL; // TypeError is thrown + } + return Py_BuildValue("i", csp_conn_dst(conn)); +} + +static PyObject* pycsp_conn_src(PyObject *self, PyObject *conn_capsule) { + csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); + if (conn == NULL) { + return NULL; // TypeError is thrown + } + return Py_BuildValue("i", csp_conn_src(conn)); +} + +static PyObject* pycsp_listen(PyObject *self, PyObject *args) { + PyObject* socket_capsule; + size_t conn_queue_len = 10; + if (!PyArg_ParseTuple(args, "O|n", &socket_capsule, &conn_queue_len)) { + return NULL; // TypeError is thrown + } + + csp_socket_t * sock = get_obj_as_socket(socket_capsule, false); + if (sock == NULL) { + return NULL; // TypeError is thrown + } + + int res = csp_listen(sock, conn_queue_len); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_listen()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_bind(PyObject *self, PyObject *args) { + PyObject* socket_capsule; + uint8_t port; + if (!PyArg_ParseTuple(args, "Ob", &socket_capsule, &port)) { + return NULL; // TypeError is thrown + } + + csp_socket_t * sock = get_obj_as_socket(socket_capsule, false); + if (sock == NULL) { + return NULL; // TypeError is thrown + } + + int res = csp_bind(sock, port); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_bind()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_route_start_task(PyObject *self, PyObject *args) { + unsigned int priority = CSP_PRIO_NORM; + if (!PyArg_ParseTuple(args, "|I", &priority)) { + return NULL; // TypeError is thrown + } + + int res = csp_route_start_task(0, priority); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_route_start_task()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_ping(PyObject *self, PyObject *args) { + uint8_t node; + uint32_t timeout = 1000; + unsigned int size = 10; + uint8_t conn_options = CSP_O_NONE; + if (!PyArg_ParseTuple(args, "b|IIb", &node, &timeout, &size, &conn_options)) { + return NULL; // TypeError is thrown + } + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_ping(node, timeout, size, conn_options); + Py_END_ALLOW_THREADS; + + if (res < 0) { + return PyErr_Error("csp_ping()", res); + } + + return Py_BuildValue("i", res); +} + +static PyObject* pycsp_reboot(PyObject *self, PyObject *args) { + uint8_t node; + if (!PyArg_ParseTuple(args, "b", &node)) { + return NULL; // TypeError is thrown + } + + csp_reboot(node); + Py_RETURN_NONE; +} + +static PyObject* pycsp_shutdown(PyObject *self, PyObject *args) { + uint8_t node; + if (!PyArg_ParseTuple(args, "b", &node)) { + return NULL; // TypeError is thrown + } + + csp_shutdown(node); + Py_RETURN_NONE; +} + +static PyObject* pycsp_rdp_set_opt(PyObject *self, PyObject *args) { + unsigned int window_size; + unsigned int conn_timeout_ms; + unsigned int packet_timeout_ms; + unsigned int delayed_acks; + unsigned int ack_timeout; + unsigned int ack_delay_count; + if (!PyArg_ParseTuple(args, "IIIIII", &window_size, &conn_timeout_ms, + &packet_timeout_ms, &delayed_acks, + &ack_timeout, &ack_delay_count)) { + return NULL; // TypeError is thrown + } +#if (CSP_USE_RDP) + csp_rdp_set_opt(window_size, conn_timeout_ms, packet_timeout_ms, + delayed_acks, ack_timeout, ack_delay_count); +#endif + Py_RETURN_NONE; +} + +static PyObject* pycsp_rdp_get_opt(PyObject *self, PyObject *args) { + + unsigned int window_size = 0; + unsigned int conn_timeout_ms = 0; + unsigned int packet_timeout_ms = 0; + unsigned int delayed_acks = 0; + unsigned int ack_timeout = 0; + unsigned int ack_delay_count = 0; +#if (CSP_USE_RDP) + csp_rdp_get_opt(&window_size, + &conn_timeout_ms, + &packet_timeout_ms, + &delayed_acks, + &ack_timeout, + &ack_delay_count); +#endif + return Py_BuildValue("IIIIII", + window_size, + conn_timeout_ms, + packet_timeout_ms, + delayed_acks, + ack_timeout, + ack_delay_count); +} + +static PyObject* pycsp_xtea_set_key(PyObject *self, PyObject *args) { + char* key; + uint32_t keylen; + if (!PyArg_ParseTuple(args, "si", &key, &keylen)) { + return NULL; // TypeError is thrown + } + + int res = csp_xtea_set_key(key, keylen); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_xtea_set_key()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_rtable_set(PyObject *self, PyObject *args) { + uint8_t node; + uint8_t mask; + char* interface_name; + uint8_t via = CSP_NO_VIA_ADDRESS; + if (!PyArg_ParseTuple(args, "bbs|b", &node, &mask, &interface_name, &via)) { + return NULL; // TypeError is thrown + } + + int res = csp_rtable_set(node, mask, csp_iflist_get_by_name(interface_name), via); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_rtable_set()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_rtable_clear(PyObject *self, PyObject *args) { + csp_rtable_clear(); + Py_RETURN_NONE; +} + +static PyObject* pycsp_rtable_check(PyObject *self, PyObject *args) { + char* buffer; + if (!PyArg_ParseTuple(args, "s", &buffer)) { + return NULL; // TypeError is thrown + } + + int res = csp_rtable_check(buffer); + if (res <= 0) { + return PyErr_Error("csp_rtable_check()", res); + } + return Py_BuildValue("i", res); +} + +static PyObject* pycsp_rtable_load(PyObject *self, PyObject *args) { + char* buffer; + if (!PyArg_ParseTuple(args, "s", &buffer)) { + return NULL; // TypeError is thrown + } + + int res = csp_rtable_load(buffer); + if (res <= 0) { + return PyErr_Error("csp_rtable_load()", res); + } + return Py_BuildValue("i", res); +} + +static PyObject* pycsp_buffer_get(PyObject *self, PyObject *args) { + size_t size; + if (!PyArg_ParseTuple(args, "n", &size)) { + return NULL; // TypeError is thrown + } + + void* packet = csp_buffer_get(size); + if (packet == NULL) { + return PyErr_Error("csp_buffer_get() - no free buffers or data overrun", CSP_ERR_NOMEM); + } + + return PyCapsule_New(packet, PACKET_CAPSULE, pycsp_free_csp_buffer); +} + +static PyObject* pycsp_buffer_free(PyObject *self, PyObject *args) { + PyObject* packet_capsule; + if (!PyArg_ParseTuple(args, "O", &packet_capsule)) { + return NULL; // TypeError is thrown + } + + csp_packet_t * packet = get_obj_as_packet(packet_capsule, true); + if (packet) { + csp_buffer_free(packet); + } + PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); + Py_RETURN_NONE; +} + +static PyObject* pycsp_buffer_remaining(PyObject *self, PyObject *args) { + return Py_BuildValue("i", csp_buffer_remaining()); +} + +static PyObject* pycsp_cmp_ident(PyObject *self, PyObject *args) { + uint8_t node; + uint32_t timeout = 1000; + if (!PyArg_ParseTuple(args, "b|i", &node, &timeout)) { + return NULL; // TypeError is thrown + } + + struct csp_cmp_message msg; + memset(&msg, 0, sizeof(msg)); + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_cmp_ident(node, timeout, &msg); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_cmp_ident()", res); + } + return Py_BuildValue("isssss", + res, + msg.ident.hostname, + msg.ident.model, + msg.ident.revision, + msg.ident.date, + msg.ident.time); +} + +static PyObject* pycsp_cmp_route_set(PyObject *self, PyObject *args) { + uint8_t node; + uint32_t timeout = 1000; + uint8_t addr; + uint8_t via; + char* ifstr; + if (!PyArg_ParseTuple(args, "bibbs", &node, &timeout, &addr, &via, &ifstr)) { + return NULL; // TypeError is thrown + } + + struct csp_cmp_message msg; + memset(&msg, 0, sizeof(msg)); + msg.route_set.dest_node = addr; + msg.route_set.next_hop_via = via; + strncpy(msg.route_set.interface, ifstr, sizeof(msg.route_set.interface) - 1); + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_cmp_route_set(node, timeout, &msg); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_cmp_route_set()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_cmp_peek(PyObject *self, PyObject *args) { + uint8_t node; + uint32_t timeout; + uint32_t addr; + uint8_t len; + Py_buffer outbuf; + if (!PyArg_ParseTuple(args, "biIbw*", &node, &timeout, &addr, &len, &outbuf)) { + Py_RETURN_NONE; + } + + if ((len > CSP_CMP_PEEK_MAX_LEN) || (len > outbuf.len)) { + return PyErr_Error("csp_cmp_peek() - exceeding max size", CSP_ERR_INVAL); + } + + struct csp_cmp_message msg; + memset(&msg, 0, sizeof(msg)); + msg.peek.addr = csp_hton32(addr); + msg.peek.len = len; + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_cmp_peek(node, timeout, &msg); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_cmp_peek()", res); + } + memcpy(outbuf.buf, msg.peek.data, len); + outbuf.len = len; + + Py_RETURN_NONE; +} + +static PyObject* pycsp_cmp_poke(PyObject *self, PyObject *args) { + uint8_t node; + uint32_t timeout; + uint8_t len; + uint32_t addr; + Py_buffer inbuf; + + if (!PyArg_ParseTuple(args, "biIbw*", &node, &timeout, &addr, &len, &inbuf)) { + Py_RETURN_NONE; + } + + if (len > CSP_CMP_POKE_MAX_LEN) { + return PyErr_Error("csp_cmp_poke() - exceeding max size", CSP_ERR_INVAL); + } + struct csp_cmp_message msg; + msg.poke.addr = csp_hton32(addr); + msg.poke.len = len; + memcpy(msg.poke.data, inbuf.buf, len); + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_cmp_poke(node, timeout, &msg); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_cmp_poke()", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_cmp_clock_set(PyObject *self, PyObject *args) { + uint8_t node; + uint32_t sec; + uint32_t nsec; + uint32_t timeout = 1000; + if (!PyArg_ParseTuple(args, "bII|I", &node, &sec, &nsec, &timeout)) { + Py_RETURN_NONE; + } + + if (sec == 0) { + return PyErr_Error("csp_cmp_clock(set) - seconds are 0", CSP_ERR_INVAL); + } + + struct csp_cmp_message msg; + memset(&msg, 0, sizeof(msg)); + msg.clock.tv_sec = csp_hton32(sec); + msg.clock.tv_nsec = csp_hton32(nsec); + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_cmp_clock(node, timeout, &msg); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_cmp_clock(set)", res); + } + + Py_RETURN_NONE; +} + +static PyObject* pycsp_cmp_clock_get(PyObject *self, PyObject *args) { + uint8_t node; + uint32_t timeout = 1000; + if (!PyArg_ParseTuple(args, "b|I", &node, &timeout)) { + Py_RETURN_NONE; + } + + struct csp_cmp_message msg; + memset(&msg, 0, sizeof(msg)); + + int res; + Py_BEGIN_ALLOW_THREADS; + res = csp_cmp_clock(node, timeout, &msg); + Py_END_ALLOW_THREADS; + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_cmp_clock(get)", res); + } + + return Py_BuildValue("II", + csp_ntoh32(msg.clock.tv_sec), + csp_ntoh32(msg.clock.tv_nsec)); +} + +static PyObject* pycsp_zmqhub_init(PyObject *self, PyObject *args) { + char addr; + char* host; + if (!PyArg_ParseTuple(args, "bs", &addr, &host)) { + return NULL; // TypeError is thrown + } + + int res = csp_zmqhub_init(addr, host, 0, NULL); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_zmqhub_init()", res); + } + + Py_RETURN_NONE; +} + +// static PyObject* pycsp_can_socketcan_init(PyObject *self, PyObject *args) { +// char* ifc; +// int bitrate = 1000000; +// int promisc = 0; +// if (!PyArg_ParseTuple(args, "s|ii", &ifc, &bitrate, &promisc)) { +// return NULL; +// } +// +// int res = csp_can_socketcan_open_and_add_interface(ifc, CSP_IF_CAN_DEFAULT_NAME, bitrate, promisc, NULL); +// if (res != CSP_ERR_NONE) { +// return PyErr_Error("csp_can_socketcan_open_and_add_interface()", res); +// } +// +// Py_RETURN_NONE; +// } + +static PyObject* pycsp_kiss_init(PyObject *self, PyObject *args) { + char* device; + uint32_t baudrate = 500000; + uint32_t mtu = 512; + const char* if_name = CSP_IF_KISS_DEFAULT_NAME; + if (!PyArg_ParseTuple(args, "s|IIs", &device, &baudrate, &mtu, &if_name)) { + return NULL; // TypeError is thrown + } + + csp_usart_conf_t conf = {.device = device, .baudrate = baudrate}; + int res = csp_usart_open_and_add_kiss_interface(&conf, if_name, NULL); + if (res != CSP_ERR_NONE) { + return PyErr_Error("csp_usart_open_and_add_kiss_interface()", res); + } + + Py_RETURN_NONE; +} + +/* FIFO INTERFACE */ +pthread_t rx_thread; +int rx_channel, tx_channel; +#define BUF_SIZE 250 + +int csp_fifo_tx(const csp_route_t * ifroute, csp_packet_t *packet); + +csp_iface_t csp_if_fifo = { + .name = "fifo", + .nexthop = csp_fifo_tx, + .mtu = BUF_SIZE, +}; + +int csp_fifo_tx(const csp_route_t * ifroute, csp_packet_t *packet) { + /* Write packet to fifo */ + if (write(tx_channel, &packet->length, packet->length + sizeof(uint32_t) + sizeof(uint16_t)) < 0) + printf("Failed to write frame\r\n"); + fsync(tx_channel); + csp_buffer_free(packet); + + return CSP_ERR_NONE; +} + +void * fifo_rx(void * parameters) { + csp_packet_t *buf = csp_buffer_get(BUF_SIZE); + /* Wait for packet on fifo */ + while (read(rx_channel, &buf->length, BUF_SIZE) > 0) { + csp_qfifo_write(buf, &csp_if_fifo, NULL); + buf = csp_buffer_get(BUF_SIZE); + } + + return NULL; +} +/** FIFO INTERFACE ENDS **/ + +static PyObject* csp_init_fifo_iface(PyObject *self, PyObject *args) { + char *tx_channel_name, *rx_channel_name; + tx_channel_name = "/datavolume1/ground_to_sat"; + rx_channel_name = "/datavolume1/sat_to_ground"; + tx_channel = open(tx_channel_name, O_RDWR); + if (tx_channel < 0) { + printf("Failed to open TX channel\r\n"); + return NULL; + } + + rx_channel = open(rx_channel_name, O_RDWR); + if (rx_channel < 0) { + printf("Failed to open RX channel\r\n"); + return NULL; + } + pthread_create(&rx_thread, NULL, fifo_rx, NULL); + csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_fifo, CSP_NODE_MAC); + Py_RETURN_NONE; +} + + +static PyObject* pycsp_packet_set_data(PyObject *self, PyObject *args) { + PyObject* packet_capsule; + Py_buffer data; + if (!PyArg_ParseTuple(args, "Ow*", &packet_capsule, &data)) { + return NULL; // TypeError is thrown + } + + csp_packet_t * packet = get_obj_as_packet(packet_capsule, false); + if (packet == NULL) { + return NULL; // TypeError is thrown + } + if (data.len > (int)csp_buffer_data_size()) { + return PyErr_Error("packet_set_data() - exceeding data size", CSP_ERR_INVAL); + } + + memcpy(packet->data, data.buf, data.len); + packet->length = data.len; + + Py_RETURN_NONE; +} + +static PyObject* pycsp_packet_get_data(PyObject *self, PyObject *packet_capsule) { + csp_packet_t * packet = get_obj_as_packet(packet_capsule, false); + if (packet == NULL) { + return NULL; // TypeError is thrown + } + return Py_BuildValue("y#", packet->data, packet->length); +} + +static PyObject* pycsp_packet_get_length(PyObject *self, PyObject *packet_capsule) { + csp_packet_t * packet = get_obj_as_packet(packet_capsule, false); + if (packet == NULL) { + return NULL; // TypeError is thrown + } + return Py_BuildValue("H", packet->length); +} + +static PyObject* pycsp_print_connections(PyObject *self, PyObject *args) { +#if (CSP_DEBUG) + csp_conn_print_table(); +#endif + Py_RETURN_NONE; +} + +static PyObject* pycsp_print_routes(PyObject *self, PyObject *args) { +#if (CSP_DEBUG) + csp_rtable_print(); +#endif + Py_RETURN_NONE; +} + +static PyObject* pycsp_get_buffer_stats(PyObject *self, PyObject *args) { + return Py_BuildValue("iii", (int)csp_buffer_remaining(), (int)csp_buffer_size(), (int)csp_buffer_data_size()); +} + +static PyMethodDef methods[] = { + + /* csp/csp.h */ + {"service_handler", pycsp_service_handler, METH_VARARGS, ""}, + {"init", pycsp_init, METH_VARARGS, ""}, + {"get_hostname", pycsp_get_hostname, METH_NOARGS, ""}, + {"get_model", pycsp_get_model, METH_NOARGS, ""}, + {"get_revision", pycsp_get_revision, METH_NOARGS, ""}, + {"socket", pycsp_socket, METH_VARARGS, ""}, + {"accept", pycsp_accept, METH_VARARGS, ""}, + {"read", pycsp_read, METH_VARARGS, ""}, + {"send", pycsp_send, METH_VARARGS, ""}, + {"transaction", pycsp_transaction, METH_VARARGS, ""}, + {"sendto_reply", pycsp_sendto_reply, METH_VARARGS, ""}, + {"sendto", pycsp_sendto, METH_VARARGS, ""}, + {"connect", pycsp_connect, METH_VARARGS, ""}, + {"close", pycsp_close, METH_O, ""}, + {"conn_dport", pycsp_conn_dport, METH_O, ""}, + {"conn_sport", pycsp_conn_sport, METH_O, ""}, + {"conn_dst", pycsp_conn_dst, METH_O, ""}, + {"conn_src", pycsp_conn_src, METH_O, ""}, + {"listen", pycsp_listen, METH_VARARGS, ""}, + {"bind", pycsp_bind, METH_VARARGS, ""}, + {"route_start_task", pycsp_route_start_task, METH_VARARGS, ""}, + {"ping", pycsp_ping, METH_VARARGS, ""}, + {"reboot", pycsp_reboot, METH_VARARGS, ""}, + {"shutdown", pycsp_shutdown, METH_VARARGS, ""}, + {"rdp_set_opt", pycsp_rdp_set_opt, METH_VARARGS, ""}, + {"rdp_get_opt", pycsp_rdp_get_opt, METH_NOARGS, ""}, + {"xtea_set_key", pycsp_xtea_set_key, METH_VARARGS, ""}, + + /* csp/csp_rtable.h */ + {"rtable_set", pycsp_rtable_set, METH_VARARGS, ""}, + {"rtable_clear", pycsp_rtable_clear, METH_NOARGS, ""}, + {"rtable_check", pycsp_rtable_check, METH_VARARGS, ""}, + {"rtable_load", pycsp_rtable_load, METH_VARARGS, ""}, + + /* csp/csp_buffer.h */ + {"buffer_free", pycsp_buffer_free, METH_VARARGS, ""}, + {"buffer_get", pycsp_buffer_get, METH_VARARGS, ""}, + {"buffer_remaining", pycsp_buffer_remaining, METH_NOARGS, ""}, + + /* csp/csp_cmp.h */ + {"cmp_ident", pycsp_cmp_ident, METH_VARARGS, ""}, + {"cmp_route_set", pycsp_cmp_route_set, METH_VARARGS, ""}, + {"cmp_peek", pycsp_cmp_peek, METH_VARARGS, ""}, + {"cmp_poke", pycsp_cmp_poke, METH_VARARGS, ""}, + {"cmp_clock_set", pycsp_cmp_clock_set, METH_VARARGS, ""}, + {"cmp_clock_get", pycsp_cmp_clock_get, METH_VARARGS, ""}, + + /* csp/interfaces/csp_if_zmqhub.h */ + {"zmqhub_init", pycsp_zmqhub_init, METH_VARARGS, ""}, + {"kiss_init", pycsp_kiss_init, METH_VARARGS, ""}, + {"fifo_init", csp_init_fifo_iface, METH_VARARGS, ""}, + + /* csp/drivers/can_socketcan.h */ + // {"can_socketcan_init", pycsp_can_socketcan_init, METH_VARARGS, ""}, + + /* helpers */ + {"packet_get_length", pycsp_packet_get_length, METH_O, ""}, + {"packet_get_data", pycsp_packet_get_data, METH_O, ""}, + {"packet_set_data", pycsp_packet_set_data, METH_VARARGS, ""}, + {"print_connections", pycsp_print_connections, METH_NOARGS, ""}, + {"print_routes", pycsp_print_routes, METH_NOARGS, ""}, + {"get_buffer_stats", pycsp_get_buffer_stats, METH_NOARGS, ""}, + + /* sentinel */ + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "libcsp_py3", + NULL, + -1, + methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit_libcsp_py3(void) { + + PyObject * m = PyModule_Create(&moduledef); + + /* Exceptions */ + Error = PyErr_NewException((char*)"csp.Error", NULL, NULL); + Py_INCREF(Error); + + /* Add exception object to your module */ + PyModule_AddObject(m, "Error", Error); + + /* RESERVED PORTS */ + PyModule_AddIntConstant(m, "CSP_CMP", CSP_CMP); + PyModule_AddIntConstant(m, "CSP_PING", CSP_PING); + PyModule_AddIntConstant(m, "CSP_PS", CSP_PS); + PyModule_AddIntConstant(m, "CSP_MEMFREE", CSP_MEMFREE); + PyModule_AddIntConstant(m, "CSP_REBOOT", CSP_REBOOT); + PyModule_AddIntConstant(m, "CSP_BUF_FREE", CSP_BUF_FREE); + PyModule_AddIntConstant(m, "CSP_UPTIME", CSP_UPTIME); + PyModule_AddIntConstant(m, "CSP_ANY", CSP_ANY); + + /* PRIORITIES */ + PyModule_AddIntConstant(m, "CSP_PRIO_CRITICAL", CSP_PRIO_CRITICAL); + PyModule_AddIntConstant(m, "CSP_PRIO_HIGH", CSP_PRIO_HIGH); + PyModule_AddIntConstant(m, "CSP_PRIO_NORM", CSP_PRIO_NORM); + PyModule_AddIntConstant(m, "CSP_PRIO_LOW", CSP_PRIO_LOW); + + /* FLAGS */ + PyModule_AddIntConstant(m, "CSP_FFRAG", CSP_FFRAG); + PyModule_AddIntConstant(m, "CSP_FHMAC", CSP_FHMAC); + PyModule_AddIntConstant(m, "CSP_FXTEA", CSP_FXTEA); + PyModule_AddIntConstant(m, "CSP_FRDP", CSP_FRDP); + PyModule_AddIntConstant(m, "CSP_FCRC32", CSP_FCRC32); + + /* SOCKET OPTIONS */ + PyModule_AddIntConstant(m, "CSP_SO_NONE", CSP_SO_NONE); + PyModule_AddIntConstant(m, "CSP_SO_RDPREQ", CSP_SO_RDPREQ); + PyModule_AddIntConstant(m, "CSP_SO_RDPPROHIB", CSP_SO_RDPPROHIB); + PyModule_AddIntConstant(m, "CSP_SO_HMACREQ", CSP_SO_HMACREQ); + PyModule_AddIntConstant(m, "CSP_SO_HMACPROHIB", CSP_SO_HMACPROHIB); + PyModule_AddIntConstant(m, "CSP_SO_XTEAREQ", CSP_SO_XTEAREQ); + PyModule_AddIntConstant(m, "CSP_SO_XTEAPROHIB", CSP_SO_XTEAPROHIB); + PyModule_AddIntConstant(m, "CSP_SO_CRC32REQ", CSP_SO_CRC32REQ); + PyModule_AddIntConstant(m, "CSP_SO_CRC32PROHIB", CSP_SO_CRC32PROHIB); + PyModule_AddIntConstant(m, "CSP_SO_CONN_LESS", CSP_SO_CONN_LESS); + + /* CONNECT OPTIONS */ + PyModule_AddIntConstant(m, "CSP_O_NONE", CSP_O_NONE); + PyModule_AddIntConstant(m, "CSP_O_RDP", CSP_O_RDP); + PyModule_AddIntConstant(m, "CSP_O_NORDP", CSP_O_NORDP); + PyModule_AddIntConstant(m, "CSP_O_HMAC", CSP_O_HMAC); + PyModule_AddIntConstant(m, "CSP_O_NOHMAC", CSP_O_NOHMAC); + PyModule_AddIntConstant(m, "CSP_O_XTEA", CSP_O_XTEA); + PyModule_AddIntConstant(m, "CSP_O_NOXTEA", CSP_O_NOXTEA); + PyModule_AddIntConstant(m, "CSP_O_CRC32", CSP_O_CRC32); + PyModule_AddIntConstant(m, "CSP_O_NOCRC32", CSP_O_NOCRC32); + + /* csp/csp_error.h */ + PyModule_AddIntConstant(m, "CSP_ERR_NONE", CSP_ERR_NONE); + PyModule_AddIntConstant(m, "CSP_ERR_NOMEM", CSP_ERR_NOMEM); + PyModule_AddIntConstant(m, "CSP_ERR_INVAL", CSP_ERR_INVAL); + PyModule_AddIntConstant(m, "CSP_ERR_TIMEDOUT", CSP_ERR_TIMEDOUT); + PyModule_AddIntConstant(m, "CSP_ERR_USED", CSP_ERR_USED); + PyModule_AddIntConstant(m, "CSP_ERR_NOTSUP", CSP_ERR_NOTSUP); + PyModule_AddIntConstant(m, "CSP_ERR_BUSY", CSP_ERR_BUSY); + PyModule_AddIntConstant(m, "CSP_ERR_ALREADY", CSP_ERR_ALREADY); + PyModule_AddIntConstant(m, "CSP_ERR_RESET", CSP_ERR_RESET); + PyModule_AddIntConstant(m, "CSP_ERR_NOBUFS", CSP_ERR_NOBUFS); + PyModule_AddIntConstant(m, "CSP_ERR_TX", CSP_ERR_TX); + PyModule_AddIntConstant(m, "CSP_ERR_DRIVER", CSP_ERR_DRIVER); + PyModule_AddIntConstant(m, "CSP_ERR_AGAIN", CSP_ERR_AGAIN); + PyModule_AddIntConstant(m, "CSP_ERR_HMAC", CSP_ERR_HMAC); + PyModule_AddIntConstant(m, "CSP_ERR_XTEA", CSP_ERR_XTEA); + PyModule_AddIntConstant(m, "CSP_ERR_CRC32", CSP_ERR_CRC32); + PyModule_AddIntConstant(m, "CSP_ERR_SFP", CSP_ERR_SFP); + + /* misc */ + PyModule_AddIntConstant(m, "CSP_NODE_MAC", CSP_NODE_MAC); + PyModule_AddIntConstant(m, "CSP_NO_VIA_ADDRESS", CSP_NO_VIA_ADDRESS); + PyModule_AddIntConstant(m, "CSP_MAX_TIMEOUT", CSP_MAX_TIMEOUT); + + return m; +} diff --git a/Program/libcsp/src/crypto/csp_hmac.c b/Program/libcsp/src/crypto/csp_hmac.c new file mode 100755 index 0000000..8d29880 --- /dev/null +++ b/Program/libcsp/src/crypto/csp_hmac.c @@ -0,0 +1,194 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* Hash-based Message Authentication Code - based on code from libtom.org */ + +#include + +#include + +#include +#include + +#define HMAC_KEY_LENGTH 16 + +/* HMAC key */ +static uint8_t csp_hmac_key[HMAC_KEY_LENGTH]; + +/* HMAC state structure */ +typedef struct { + csp_sha1_state_t md; + uint8_t key[CSP_SHA1_BLOCKSIZE]; +} hmac_state; + +static int csp_hmac_init(hmac_state * hmac, const uint8_t * key, uint32_t keylen) { + uint32_t i; + uint8_t buf[CSP_SHA1_BLOCKSIZE]; + + /* NULL pointer and key check */ + if (!hmac || !key || keylen < 1) + return CSP_ERR_INVAL; + + /* Make sure we have a large enough key */ + if(keylen > CSP_SHA1_BLOCKSIZE) { + csp_sha1_memory(key, keylen, hmac->key); + if(CSP_SHA1_DIGESTSIZE < CSP_SHA1_BLOCKSIZE) + memset((hmac->key) + CSP_SHA1_DIGESTSIZE, 0, (CSP_SHA1_BLOCKSIZE - CSP_SHA1_DIGESTSIZE)); + } else { + memcpy(hmac->key, key, keylen); + if(keylen < CSP_SHA1_BLOCKSIZE) + memset((hmac->key) + keylen, 0, (CSP_SHA1_BLOCKSIZE - keylen)); + } + + /* Create the initial vector */ + for(i = 0; i < CSP_SHA1_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x36; + } + + /* Prepend to the hash data */ + csp_sha1_init(&hmac->md); + csp_sha1_process(&hmac->md, buf, CSP_SHA1_BLOCKSIZE); + + return CSP_ERR_NONE; +} + +static int csp_hmac_process(hmac_state * hmac, const uint8_t * in, uint32_t inlen) { + + /* NULL pointer check */ + if (!hmac || !in) + return CSP_ERR_INVAL; + + /* Process data */ + csp_sha1_process(&hmac->md, in, inlen); + + return CSP_ERR_NONE; +} + +static int csp_hmac_done(hmac_state * hmac, uint8_t * out) { + + if (!hmac || !out) + return CSP_ERR_INVAL; + + /* Get the hash of the first HMAC vector plus the data */ + uint8_t isha[CSP_SHA1_DIGESTSIZE]; + csp_sha1_done(&hmac->md, isha); + + /* Create the second HMAC vector vector */ + uint8_t buf[CSP_SHA1_BLOCKSIZE]; + for(unsigned int i = 0; i < sizeof(buf); i++) { + buf[i] = hmac->key[i] ^ 0x5C; + } + + /* Now calculate the outer hash */ + csp_sha1_init(&hmac->md); + csp_sha1_process(&hmac->md, buf, sizeof(buf)); + csp_sha1_process(&hmac->md, isha, sizeof(isha)); + csp_sha1_done(&hmac->md, buf); + + /* Copy to output */ + memcpy(out, buf, CSP_SHA1_DIGESTSIZE); + + return CSP_ERR_NONE; +} + +int csp_hmac_memory(const void * key, uint32_t keylen, const void * data, uint32_t datalen, uint8_t * hmac) { + hmac_state state; + + /* NULL pointer check */ + if (!key || !data || !hmac) + return CSP_ERR_INVAL; + + /* Init HMAC state */ + if (csp_hmac_init(&state, key, keylen) != 0) + return CSP_ERR_INVAL; + + /* Process data */ + if (csp_hmac_process(&state, data, datalen) != 0) + return CSP_ERR_INVAL; + + /* Output HMAC */ + if (csp_hmac_done(&state, hmac) != 0) + return CSP_ERR_INVAL; + + return CSP_ERR_NONE; +} + +int csp_hmac_set_key(const void * key, uint32_t keylen) { + + /* Use SHA1 as KDF */ + uint8_t hash[CSP_SHA1_DIGESTSIZE]; + csp_sha1_memory(key, keylen, hash); + + /* Copy key */ + memcpy(csp_hmac_key, hash, sizeof(csp_hmac_key)); + + return CSP_ERR_NONE; + +} + +int csp_hmac_append(csp_packet_t * packet, bool include_header) { + + if ((packet->length + (unsigned int)CSP_HMAC_LENGTH) > csp_buffer_data_size()) { + return CSP_ERR_NOMEM; + } + + /* Calculate HMAC */ + uint8_t hmac[CSP_SHA1_DIGESTSIZE]; + if (include_header) { + csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), &packet->id, packet->length + sizeof(packet->id), hmac); + } else { + csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), packet->data, packet->length, hmac); + } + + /* Truncate hash and copy to packet */ + memcpy(&packet->data[packet->length], hmac, CSP_HMAC_LENGTH); + packet->length += CSP_HMAC_LENGTH; + + return CSP_ERR_NONE; + +} + +int csp_hmac_verify(csp_packet_t * packet, bool include_header) { + + if (packet->length < (unsigned int)CSP_HMAC_LENGTH) { + return CSP_ERR_HMAC; + } + + uint8_t hmac[CSP_SHA1_DIGESTSIZE]; + + /* Calculate HMAC */ + if (include_header) { + csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), &packet->id, packet->length + sizeof(packet->id) - CSP_HMAC_LENGTH, hmac); + } else { + csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), packet->data, packet->length - CSP_HMAC_LENGTH, hmac); + } + + /* Compare calculated HMAC with packet header */ + if (memcmp(&packet->data[packet->length] - CSP_HMAC_LENGTH, hmac, CSP_HMAC_LENGTH) != 0) { + /* HMAC failed */ + return CSP_ERR_HMAC; + } + + /* Strip HMAC */ + packet->length -= CSP_HMAC_LENGTH; + return CSP_ERR_NONE; + +} + diff --git a/Program/libcsp/src/crypto/csp_sha1.c b/Program/libcsp/src/crypto/csp_sha1.c new file mode 100755 index 0000000..55c2516 --- /dev/null +++ b/Program/libcsp/src/crypto/csp_sha1.c @@ -0,0 +1,211 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* Code originally from Python's SHA1 Module, who based it on libtom.org */ + +#include + +#include + +/* Rotate left macro */ +#define ROL(x,y) (((x) << (y)) | ((x) >> (32-y))) + +/* Endian Neutral macros that work on all platforms */ +#define STORE32H(x, y) do { (y)[0] = (uint8_t)(((x) >> 24) & 0xff); \ + (y)[1] = (uint8_t)(((x) >> 16) & 0xff); \ + (y)[2] = (uint8_t)(((x) >> 8) & 0xff); \ + (y)[3] = (uint8_t)(((x) >> 0) & 0xff); } while (0) + +#define LOAD32H(x, y) do { (x) = ((uint32_t)((y)[0] & 0xff) << 24) | \ + ((uint32_t)((y)[1] & 0xff) << 16) | \ + ((uint32_t)((y)[2] & 0xff) << 8) | \ + ((uint32_t)((y)[3] & 0xff) << 0); } while (0) + +#define STORE64H(x, y) do { (y)[0] = (uint8_t)(((x) >> 56) & 0xff); \ + (y)[1] = (uint8_t)(((x) >> 48) & 0xff); \ + (y)[2] = (uint8_t)(((x) >> 40) & 0xff); \ + (y)[3] = (uint8_t)(((x) >> 32) & 0xff); \ + (y)[4] = (uint8_t)(((x) >> 24) & 0xff); \ + (y)[5] = (uint8_t)(((x) >> 16) & 0xff); \ + (y)[6] = (uint8_t)(((x) >> 8) & 0xff); \ + (y)[7] = (uint8_t)(((x) >> 0) & 0xff); } while (0) + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +/* SHA1 macros */ +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +#define FF_0(a, b, c, d, e, i) do {e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);} while (0) +#define FF_1(a, b, c, d, e, i) do {e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);} while (0) +#define FF_2(a, b, c, d, e, i) do {e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);} while (0) +#define FF_3(a, b, c, d, e, i) do {e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);} while (0) + +static void csp_sha1_compress(csp_sha1_state_t * sha1, const uint8_t * buf) { + + uint32_t a, b, c, d, e, W[80], i; + + /* Copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) + LOAD32H(W[i], buf + (4*i)); + + /* Copy state */ + a = sha1->state[0]; + b = sha1->state[1]; + c = sha1->state[2]; + d = sha1->state[3]; + e = sha1->state[4]; + + /* Expand it */ + for (i = 16; i < 80; i++) + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + + /* Compress */ + i = 0; + + /* Round one */ + for (; i < 20;) { + FF_0(a, b, c, d, e, i++); + FF_0(e, a, b, c, d, i++); + FF_0(d, e, a, b, c, i++); + FF_0(c, d, e, a, b, i++); + FF_0(b, c, d, e, a, i++); + } + + /* Round two */ + for (; i < 40;) { + FF_1(a, b, c, d, e, i++); + FF_1(e, a, b, c, d, i++); + FF_1(d, e, a, b, c, i++); + FF_1(c, d, e, a, b, i++); + FF_1(b, c, d, e, a, i++); + } + + /* Round three */ + for (; i < 60;) { + FF_2(a, b, c, d, e, i++); + FF_2(e, a, b, c, d, i++); + FF_2(d, e, a, b, c, i++); + FF_2(c, d, e, a, b, i++); + FF_2(b, c, d, e, a, i++); + } + + /* Round four */ + for (; i < 80;) { + FF_3(a, b, c, d, e, i++); + FF_3(e, a, b, c, d, i++); + FF_3(d, e, a, b, c, i++); + FF_3(c, d, e, a, b, i++); + FF_3(b, c, d, e, a, i++); + } + + /* Store */ + sha1->state[0] += a; + sha1->state[1] += b; + sha1->state[2] += c; + sha1->state[3] += d; + sha1->state[4] += e; + +} + +void csp_sha1_init(csp_sha1_state_t * sha1) { + + sha1->state[0] = 0x67452301UL; + sha1->state[1] = 0xefcdab89UL; + sha1->state[2] = 0x98badcfeUL; + sha1->state[3] = 0x10325476UL; + sha1->state[4] = 0xc3d2e1f0UL; + sha1->curlen = 0; + sha1->length = 0; + +} + +void csp_sha1_process(csp_sha1_state_t * sha1, const void * data, uint32_t inlen) { + + const uint8_t * in = data; + uint32_t n; + while (inlen > 0) { + if (sha1->curlen == 0 && inlen >= CSP_SHA1_BLOCKSIZE) { + csp_sha1_compress(sha1, in); + sha1->length += (CSP_SHA1_BLOCKSIZE * 8); + in += CSP_SHA1_BLOCKSIZE; + inlen -= CSP_SHA1_BLOCKSIZE; + } else { + n = MIN(inlen, (CSP_SHA1_BLOCKSIZE - sha1->curlen)); + memcpy(sha1->buf + sha1->curlen, in, (size_t)n); + sha1->curlen += n; + in += n; + inlen -= n; + if (sha1->curlen == CSP_SHA1_BLOCKSIZE) { + csp_sha1_compress(sha1, sha1->buf); + sha1->length += (CSP_SHA1_BLOCKSIZE * 8); + sha1->curlen = 0; + } + } + } + +} + +void csp_sha1_done(csp_sha1_state_t * sha1, uint8_t * out) { + + uint32_t i; + + /* Increase the length of the message */ + sha1->length += sha1->curlen * 8; + + /* Append the '1' bit */ + sha1->buf[sha1->curlen++] = 0x80; + + /* If the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (sha1->curlen > 56) { + while (sha1->curlen < 64) + sha1->buf[sha1->curlen++] = 0; + csp_sha1_compress(sha1, sha1->buf); + sha1->curlen = 0; + } + + /* Pad up to 56 bytes of zeroes */ + while (sha1->curlen < 56) + sha1->buf[sha1->curlen++] = 0; + + /* Store length */ + STORE64H(sha1->length, sha1->buf + 56); + csp_sha1_compress(sha1, sha1->buf); + + /* Copy output */ + for (i = 0; i < 5; i++) + STORE32H(sha1->state[i], out + (4 * i)); + +} + +void csp_sha1_memory(const void * msg, uint32_t len, uint8_t * hash) { + + csp_sha1_state_t md; + csp_sha1_init(&md); + csp_sha1_process(&md, msg, len); + csp_sha1_done(&md, hash); + +} + diff --git a/Program/libcsp/src/crypto/csp_xtea.c b/Program/libcsp/src/crypto/csp_xtea.c new file mode 100755 index 0000000..cd03941 --- /dev/null +++ b/Program/libcsp/src/crypto/csp_xtea.c @@ -0,0 +1,181 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* Simple implementation of XTEA in CTR mode */ + +#include + +#include +#include + +#include +#include +#include + +#define XTEA_BLOCKSIZE 8 +#define XTEA_ROUNDS 32 +#define XTEA_KEY_LENGTH 16 + +/* XTEA key */ +static uint32_t csp_xtea_key[XTEA_KEY_LENGTH/sizeof(uint32_t)] __attribute__ ((aligned(sizeof(uint32_t)))); + +#define STORE32L(x, y) do { (y)[3] = (uint8_t)(((x) >> 24) & 0xff); \ + (y)[2] = (uint8_t)(((x) >> 16) & 0xff); \ + (y)[1] = (uint8_t)(((x) >> 8) & 0xff); \ + (y)[0] = (uint8_t)(((x) >> 0) & 0xff); } while (0) + +#define LOAD32L(x, y) do { (x) = ((uint32_t)((y)[3] & 0xff) << 24) | \ + ((uint32_t)((y)[2] & 0xff) << 16) | \ + ((uint32_t)((y)[1] & 0xff) << 8) | \ + ((uint32_t)((y)[0] & 0xff) << 0); } while (0) + +/* This function takes 64 bits of data in block and the 128 bits key in key */ +static inline void csp_xtea_encrypt_block(uint8_t *block, uint8_t const *key) { + + uint32_t i, v0, v1, delta = 0x9E3779B9, sum = 0, k[4]; + + LOAD32L(k[0], &key[0]); + LOAD32L(k[1], &key[4]); + LOAD32L(k[2], &key[8]); + LOAD32L(k[3], &key[12]); + + LOAD32L(v0, &block[0]); + LOAD32L(v1, &block[4]); + + for (i = 0; i < XTEA_ROUNDS; i++) { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); + } + + STORE32L(v0, &block[0]); + STORE32L(v1, &block[4]); + +} + +static inline void csp_xtea_xor_byte(uint8_t * dst, uint8_t * src, uint32_t len) { + + unsigned int i; + for (i = 0; i < len; i++) + dst[i] ^= src[i]; + +} + +int csp_xtea_set_key(const void * key, uint32_t keylen) { + + /* Use SHA1 as KDF */ + uint8_t hash[CSP_SHA1_DIGESTSIZE]; + csp_sha1_memory(key, keylen, hash); + + /* Copy key */ + memcpy(csp_xtea_key, hash, XTEA_KEY_LENGTH); + + return CSP_ERR_NONE; + +} + +int csp_xtea_encrypt(void * plain, const uint32_t len, uint32_t iv[2]) { + + unsigned int i; + uint32_t stream[2]; + + uint32_t blocks = (len + XTEA_BLOCKSIZE - 1)/ XTEA_BLOCKSIZE; + uint32_t remain; + + /* Initialize stream */ + stream[0] = csp_htobe32(iv[0]); + stream[1] = csp_htobe32(iv[1]); + + for (i = 0; i < blocks; i++) { + /* Create stream */ + csp_xtea_encrypt_block((uint8_t *)stream, (uint8_t *)csp_xtea_key); + + /* Calculate remaining bytes */ + remain = len - i * XTEA_BLOCKSIZE; + + /* XOR plain text with stream to generate cipher text */ + csp_xtea_xor_byte(&((uint8_t*)plain)[len - remain], (uint8_t *)stream, remain < XTEA_BLOCKSIZE ? remain : XTEA_BLOCKSIZE); + + /* Increment counter */ + stream[0] = csp_htobe32(iv[0]); + stream[1] = csp_htobe32(iv[1]++); + } + + return CSP_ERR_NONE; + +} + +int csp_xtea_encrypt_packet(csp_packet_t * packet) { + + /* Create nonce */ + const uint32_t nonce = (uint32_t)rand(); + const uint32_t nonce_n = csp_hton32(nonce); + + if ((packet->length + sizeof(nonce_n)) > csp_buffer_data_size()) { + return CSP_ERR_NOMEM; + } + + /* Create initialization vector */ + uint32_t iv[2] = {nonce, 1}; + + /* Encrypt data */ + if (csp_xtea_encrypt(packet->data, packet->length, iv) != CSP_ERR_NONE) { + return CSP_ERR_XTEA; + } + + memcpy(&packet->data[packet->length], &nonce_n, sizeof(nonce_n)); + packet->length += sizeof(nonce_n); + + return CSP_ERR_NONE; + +} + +int csp_xtea_decrypt(void * cipher, const uint32_t len, uint32_t iv[2]) { + + /* Since we use counter mode, we can reuse the encryption function */ + return csp_xtea_encrypt(cipher, len, iv); + +} + +int csp_xtea_decrypt_packet(csp_packet_t * packet) { + + /* Read nonce */ + uint32_t nonce; + + if (packet->length < sizeof(nonce)) { + return CSP_ERR_XTEA; + } + + memcpy(&nonce, &packet->data[packet->length - sizeof(nonce)], sizeof(nonce)); + nonce = csp_ntoh32(nonce); + + /* Create initialization vector */ + uint32_t iv[2] = {nonce, 1}; + + /* Decrypt data */ + if (csp_xtea_decrypt(packet->data, packet->length, iv) != CSP_ERR_NONE) { + return CSP_ERR_XTEA; + } + + packet->length -= sizeof(nonce); + + return CSP_ERR_NONE; + +} diff --git a/Program/libcsp/src/csp_bridge.c b/Program/libcsp/src/csp_bridge.c new file mode 100755 index 0000000..0801cfe --- /dev/null +++ b/Program/libcsp/src/csp_bridge.c @@ -0,0 +1,96 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include "csp_qfifo.h" +#include "csp_io.h" +#include "csp_promisc.h" + +typedef struct { + csp_iface_t* iface; +} bridge_interface_t; + +static bridge_interface_t bif_a; +static bridge_interface_t bif_b; + +static CSP_DEFINE_TASK(csp_bridge) { + + /* Here there be bridging */ + while (1) { + + /* Get next packet to route */ + csp_qfifo_t input; + if (csp_qfifo_read(&input) != CSP_ERR_NONE) { + continue; + } + + csp_packet_t * packet = input.packet; + + csp_log_packet("Input: Src %u, Dst %u, Dport %u, Sport %u, Pri %u, Flags 0x%02X, Size %"PRIu16, + packet->id.src, packet->id.dst, packet->id.dport, + packet->id.sport, packet->id.pri, packet->id.flags, packet->length); + + /* Here there be promiscuous mode */ +#if (CSP_USE_PROMISC) + csp_promisc_add(packet); +#endif + + /* Find the opposing interface */ + csp_route_t route; + if (input.iface == bif_a.iface) { + route.iface = bif_b.iface; + route.via = CSP_NO_VIA_ADDRESS; + } else { + route.iface = bif_a.iface; + route.via = CSP_NO_VIA_ADDRESS; + } + + /* Send to the interface directly, no hassle */ + if (csp_send_direct(packet->id, packet, &route, 0) != CSP_ERR_NONE) { + csp_log_warn("Router failed to send"); + csp_buffer_free(packet); + } + } + + return CSP_TASK_RETURN; + +} + +int csp_bridge_start(unsigned int task_stack_size, unsigned int task_priority, csp_iface_t * if_a, csp_iface_t * if_b) { + + /* Set static references to A/B side of bridge */ + bif_a.iface = if_a; + bif_b.iface = if_b; + + static csp_thread_handle_t handle; + int ret = csp_thread_create(csp_bridge, "BRIDGE", task_stack_size, NULL, task_priority, &handle); + + if (ret != 0) { + csp_log_error("Failed to start task"); + return CSP_ERR_NOMEM; + } + + return CSP_ERR_NONE; + +} diff --git a/Program/libcsp/src/csp_buffer.c b/Program/libcsp/src/csp_buffer.c new file mode 100755 index 0000000..ebc9154 --- /dev/null +++ b/Program/libcsp/src/csp_buffer.c @@ -0,0 +1,224 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include "csp_init.h" + +#ifndef CSP_BUFFER_ALIGN +#define CSP_BUFFER_ALIGN (sizeof(int *)) +#endif + +/** Internal buffer header */ +typedef struct csp_skbf_s { + unsigned int refcount; + void * skbf_addr; + char skbf_data[]; // -> csp_packet_t +} csp_skbf_t; + +// Queue of free CSP buffers +static csp_queue_handle_t csp_buffers; +// Chunk of memory allocated for CSP buffers +static char * csp_buffer_pool; + +// Ensure the csp_packet is correctly aligned (as it is not packed) +CSP_STATIC_ASSERT(CSP_HEADER_LENGTH == sizeof(csp_id_t), csp_header_length); +CSP_STATIC_ASSERT(sizeof(csp_packet_t) == 16, csp_packet); +CSP_STATIC_ASSERT(offsetof(csp_packet_t, length) == 10, length_field_misaligned); +CSP_STATIC_ASSERT(offsetof(csp_packet_t, id) == 12, csp_id_field_misaligned); +CSP_STATIC_ASSERT(offsetof(csp_packet_t, data) == 16, data_field_misaligned); + +int csp_buffer_init(void) { + + // calculate total size and ensure correct alignment (int *) for buffers + const unsigned int skbfsize = CSP_BUFFER_ALIGN * ((sizeof(csp_skbf_t) + csp_buffer_size() + (CSP_BUFFER_ALIGN - 1)) / CSP_BUFFER_ALIGN); + + csp_buffer_pool = csp_malloc(csp_conf.buffers * skbfsize); + if (csp_buffer_pool == NULL) + goto fail_malloc; + + csp_buffers = csp_queue_create(csp_conf.buffers, sizeof(void *)); + if (!csp_buffers) + goto fail_queue; + + for (unsigned int i = 0; i < csp_conf.buffers; i++) { + csp_skbf_t * buf = (void *) &csp_buffer_pool[i * skbfsize]; + buf->skbf_addr = buf; + csp_queue_enqueue(csp_buffers, &buf, 0); + } + + return CSP_ERR_NONE; + +fail_queue: + csp_buffer_free_resources(); +fail_malloc: + return CSP_ERR_NOMEM; + +} + +void csp_buffer_free_resources(void) { + + if (csp_buffers) { + csp_queue_remove(csp_buffers); + csp_buffers = NULL; + } + csp_free(csp_buffer_pool); + csp_buffer_pool = NULL; + +} + +void *csp_buffer_get_isr(size_t _data_size) { + + if (_data_size > csp_conf.buffer_data_size) + return NULL; + + csp_skbf_t * buffer = NULL; + CSP_BASE_TYPE task_woken = 0; + csp_queue_dequeue_isr(csp_buffers, &buffer, &task_woken); + if (buffer == NULL) + return NULL; + + if (buffer != buffer->skbf_addr) + return NULL; + + buffer->refcount = 1; + return buffer->skbf_data; + +} + +void *csp_buffer_get(size_t _data_size) { + + if (_data_size > csp_conf.buffer_data_size) { + csp_log_error("GET: Attempt to allocate too large data size %u > max %u", (unsigned int) _data_size, (unsigned int) csp_conf.buffer_data_size); + return NULL; + } + + csp_skbf_t * buffer = NULL; + csp_queue_dequeue(csp_buffers, &buffer, 0); + if (buffer == NULL) { + csp_log_error("GET: Out of buffers"); + return NULL; + } + + if (buffer != buffer->skbf_addr) { + csp_log_error("GET: Corrupt CSP buffer %p != %p", buffer, buffer->skbf_addr); + return NULL; + } + + csp_log_buffer("GET: %p", buffer); + + buffer->refcount = 1; + return buffer->skbf_data; +} + +void csp_buffer_free_isr(void *packet) { + + if (packet == NULL) { + // freeing a NULL pointer is OK, e.g. standard free() + return; + } + + csp_skbf_t * buf = (void*)(((uint8_t*)packet) - sizeof(csp_skbf_t)); + + if (((uintptr_t) buf % CSP_BUFFER_ALIGN) > 0) { + return; + } + + if (buf->skbf_addr != buf) { + return; + } + + if (buf->refcount == 0) { + return; + } + + if (--(buf->refcount) > 0) { + return; + } + + CSP_BASE_TYPE task_woken = 0; + csp_queue_enqueue_isr(csp_buffers, &buf, &task_woken); + +} + +void csp_buffer_free(void *packet) { + + if (packet == NULL) { + /* freeing a NULL pointer is OK, e.g. standard free() */ + return; + } + + csp_skbf_t * buf = (void*)(((uint8_t*)packet) - sizeof(csp_skbf_t)); + + if (((uintptr_t) buf % CSP_BUFFER_ALIGN) > 0) { + csp_log_error("FREE: Unaligned CSP buffer pointer %p", packet); + return; + } + + if (buf->skbf_addr != buf) { + csp_log_error("FREE: Invalid CSP buffer pointer %p", packet); + return; + } + + if (buf->refcount == 0) { + csp_log_error("FREE: Buffer already free %p", buf); + return; + } + + if (--(buf->refcount) > 0) { + csp_log_error("FREE: Buffer %p in use by %u users", buf, buf->refcount); + return; + } + + csp_log_buffer("FREE: %p", buf); + csp_queue_enqueue(csp_buffers, &buf, 0); + +} + +void *csp_buffer_clone(void *buffer) { + + csp_packet_t *packet = (csp_packet_t *) buffer; + if (!packet) { + return NULL; + } + + csp_packet_t *clone = csp_buffer_get(packet->length); + if (clone) { + memcpy(clone, packet, csp_buffer_size()); + } + + return clone; + +} + +int csp_buffer_remaining(void) { + return csp_queue_size(csp_buffers); +} + +size_t csp_buffer_size(void) { + return (csp_conf.buffer_data_size + CSP_BUFFER_PACKET_OVERHEAD); +} + +size_t csp_buffer_data_size(void) { + return csp_conf.buffer_data_size; +} diff --git a/Program/libcsp/src/csp_conn.c b/Program/libcsp/src/csp_conn.c new file mode 100755 index 0000000..472f6ca --- /dev/null +++ b/Program/libcsp/src/csp_conn.c @@ -0,0 +1,527 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_conn.h" + +#include +#include + +#include +#include +#include +#include +#include +#include "csp_init.h" +#include "transport/csp_transport.h" + +/* Connection pool */ +static csp_conn_t * arr_conn; + +/* Connection pool lock */ +static csp_bin_sem_handle_t conn_lock; + +/* Last used 'source' port */ +static uint8_t sport; + +/* Source port lock */ +static csp_bin_sem_handle_t sport_lock; + +void csp_conn_check_timeouts(void) { +#if (CSP_USE_RDP) + for (int i = 0; i < csp_conf.conn_max; i++) { + if (arr_conn[i].state == CONN_OPEN) { + if (arr_conn[i].idin.flags & CSP_FRDP) { + csp_rdp_check_timeouts(&arr_conn[i]); + } + } + } +#endif +} + +int csp_conn_get_rxq(int prio) { + +#if (CSP_USE_QOS) + return prio; +#else + return 0; +#endif + +} + +int csp_conn_enqueue_packet(csp_conn_t * conn, csp_packet_t * packet) { + + if (!conn) + return CSP_ERR_INVAL; + + int rxq; + if (packet != NULL) { + rxq = csp_conn_get_rxq(packet->id.pri); + } else { + rxq = CSP_RX_QUEUES - 1; + } + + if (csp_queue_enqueue(conn->rx_queue[rxq], &packet, 0) != CSP_QUEUE_OK) { + csp_log_error("RX queue %p full with %u items", conn->rx_queue[rxq], csp_queue_size(conn->rx_queue[rxq])); + return CSP_ERR_NOMEM; + } + +#if (CSP_USE_QOS) + int event = 0; + if (csp_queue_enqueue(conn->rx_event, &event, 0) != CSP_QUEUE_OK) { + csp_log_error("QOS event queue full"); + return CSP_ERR_NOMEM; + } +#endif + + return CSP_ERR_NONE; +} + +int csp_conn_init(void) { + + arr_conn = csp_calloc(csp_conf.conn_max, sizeof(*arr_conn)); + if (arr_conn == NULL) { + csp_log_error("Allocation for %u connections failed", csp_conf.conn_max); + return CSP_ERR_NOMEM; + } + + if (csp_bin_sem_create(&conn_lock) != CSP_SEMAPHORE_OK) { + csp_log_error("csp_bin_sem_create(&conn_lock) failed"); + return CSP_ERR_NOMEM; + } + + /* Initialize source port */ + srand(csp_get_ms()); + sport = (rand() % (CSP_ID_PORT_MAX - csp_conf.port_max_bind)) + (csp_conf.port_max_bind + 1); + + if (csp_bin_sem_create(&sport_lock) != CSP_SEMAPHORE_OK) { + csp_log_error("csp_bin_sem_create(&sport_lock) failed"); + return CSP_ERR_NOMEM; + } + + for (int i = 0; i < csp_conf.conn_max; i++) { + csp_conn_t * conn = &arr_conn[i]; + for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { + conn->rx_queue[prio] = csp_queue_create(csp_conf.conn_queue_length, sizeof(csp_packet_t *)); + if (conn->rx_queue[prio] == NULL) { + csp_log_error("rx_queue = csp_queue_create() failed"); + return CSP_ERR_NOMEM; + } + } + +#if (CSP_USE_QOS) + conn->rx_event = csp_queue_create(csp_conf.conn_queue_length, sizeof(int)); + if (conn->rx_event == NULL) { + csp_log_error("rx_event = csp_queue_create() failed"); + return CSP_ERR_NOMEM; + } +#endif + +#if (CSP_USE_RDP) + if (csp_rdp_init(conn) != CSP_ERR_NONE) { + csp_log_error("csp_rdp_allocate(conn) failed"); + return CSP_ERR_NOMEM; + } +#endif + } + + return CSP_ERR_NONE; + +} + +void csp_conn_free_resources(void) { + + if (arr_conn) { + + for (unsigned int i = 0; i < csp_conf.conn_max; i++) { + csp_conn_t * conn = &arr_conn[i]; + + for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { + if (conn->rx_queue[prio]) { + csp_queue_remove(conn->rx_queue[prio]); + } + } + +#if (CSP_USE_QOS) + if (conn->rx_event) { + csp_queue_remove(conn->rx_event); + } +#endif + +#if (CSP_USE_RDP) + csp_rdp_free_resources(conn); +#endif + } + + csp_free(arr_conn); + arr_conn = NULL; + + //csp_bin_sem_remove(&conn_lock); + memset(&conn_lock, 0, sizeof(conn_lock)); + + //csp_bin_sem_remove(&sport_lock); + memset(&sport_lock, 0, sizeof(sport_lock)); + + sport = 0; + } +} + +csp_conn_t * csp_conn_find(uint32_t id, uint32_t mask) { + + /* Search for matching connection */ + id = (id & mask); + for (int i = 0; i < csp_conf.conn_max; i++) { + csp_conn_t * conn = &arr_conn[i]; + if ((conn->state == CONN_OPEN) && (conn->type == CONN_CLIENT) && ((conn->idin.ext & mask) == id)) { + return conn; + } + } + + return NULL; + +} + +static int csp_conn_flush_rx_queue(csp_conn_t * conn) { + + csp_packet_t * packet; + + int prio; + + /* Flush packet queues */ + for (prio = 0; prio < CSP_RX_QUEUES; prio++) { + while (csp_queue_dequeue(conn->rx_queue[prio], &packet, 0) == CSP_QUEUE_OK) + if (packet != NULL) + csp_buffer_free(packet); + } + + /* Flush event queue */ +#if (CSP_USE_QOS) + int event; + while (csp_queue_dequeue(conn->rx_event, &event, 0) == CSP_QUEUE_OK); +#endif + + return CSP_ERR_NONE; + +} + +csp_conn_t * csp_conn_allocate(csp_conn_type_t type) { + + static uint8_t csp_conn_last_given = 0; + + if (csp_bin_sem_wait(&conn_lock, CSP_MAX_TIMEOUT) != CSP_SEMAPHORE_OK) { + csp_log_error("Failed to lock conn array"); + return NULL; + } + + /* Search for free connection */ + csp_conn_t * conn = NULL; + int i = csp_conn_last_given; + for (int j = 0; j < csp_conf.conn_max; j++) { + i = (i + 1) % csp_conf.conn_max; + conn = &arr_conn[i]; + if (conn->state == CONN_CLOSED) { + break; + } + } + + if (conn && (conn->state == CONN_CLOSED)) { + conn->idin.ext = 0; + conn->idout.ext = 0; + conn->socket = NULL; + conn->timestamp = 0; + conn->type = type; + conn->state = CONN_OPEN; + csp_conn_last_given = i; + } else { + // no free connections + conn = NULL; + } + + csp_bin_sem_post(&conn_lock); + + if (conn == NULL) { + csp_log_error("No free connections, max %u", csp_conf.conn_max); + } + + return conn; + +} + +csp_conn_t * csp_conn_new(csp_id_t idin, csp_id_t idout) { + + /* Allocate connection structure */ + csp_conn_t * conn = csp_conn_allocate(CONN_CLIENT); + + if (conn) { + /* No lock is needed here, because nobody else * + * has a reference to this connection yet. */ + conn->idin.ext = idin.ext; + conn->idout.ext = idout.ext; + conn->timestamp = csp_get_ms(); + + /* Ensure connection queue is empty */ + csp_conn_flush_rx_queue(conn); + } + + return conn; + +} + +int csp_close(csp_conn_t * conn) { + return csp_conn_close(conn, CSP_RDP_CLOSED_BY_USERSPACE); +} + +int csp_conn_close(csp_conn_t * conn, uint8_t closed_by) { + + if (conn == NULL) { + return CSP_ERR_NONE; + } + + if (conn->state == CONN_CLOSED) { + csp_log_protocol("Conn already closed"); + return CSP_ERR_NONE; + } + +#if (CSP_USE_RDP) + /* Ensure RDP knows this connection is closing */ + if ((conn->idin.flags & CSP_FRDP) || (conn->idout.flags & CSP_FRDP)) { + if (csp_rdp_close(conn, closed_by) == CSP_ERR_AGAIN) { + return CSP_ERR_NONE; + } + } +#endif + + /* Lock connection array while closing connection */ + if (csp_bin_sem_wait(&conn_lock, CSP_MAX_TIMEOUT) != CSP_SEMAPHORE_OK) { + csp_log_error("Failed to lock conn array"); + return CSP_ERR_TIMEDOUT; + } + + /* Set to closed */ + conn->state = CONN_CLOSED; + + /* Ensure connection queue is empty */ + csp_conn_flush_rx_queue(conn); + + if (conn->socket && (conn->type == CONN_SERVER) && (conn->opts & (CSP_SO_CONN_LESS | CSP_SO_INTERNAL_LISTEN))) { + csp_queue_remove(conn->socket); + conn->socket = NULL; + } + + /* Reset RDP state */ +#if (CSP_USE_RDP) + if (conn->idin.flags & CSP_FRDP) { + csp_rdp_flush_all(conn); + } +#endif + + /* Unlock connection array */ + csp_bin_sem_post(&conn_lock); + + return CSP_ERR_NONE; +} + +csp_conn_t * csp_connect(uint8_t prio, uint8_t dest, uint8_t dport, uint32_t timeout, uint32_t opts) { + + /* Force options on all connections */ + opts |= csp_conf.conn_dfl_so; + + /* Generate identifier */ + csp_id_t incoming_id, outgoing_id; + incoming_id.pri = prio; + incoming_id.dst = csp_conf.address; + incoming_id.src = dest; + incoming_id.sport = dport; + incoming_id.flags = 0; + outgoing_id.pri = prio; + outgoing_id.dst = dest; + outgoing_id.src = csp_conf.address; + outgoing_id.dport = dport; + outgoing_id.flags = 0; + + /* Set connection options */ + if (opts & CSP_O_NOCRC32) { + opts &= ~CSP_O_CRC32; + } + + if (opts & CSP_O_RDP) { +#if (CSP_USE_RDP) + incoming_id.flags |= CSP_FRDP; + outgoing_id.flags |= CSP_FRDP; +#else + csp_log_error("Attempt to create RDP connection, but CSP was compiled without RDP support"); + return NULL; +#endif + } + + if (opts & CSP_O_HMAC) { +#if (CSP_USE_HMAC) + outgoing_id.flags |= CSP_FHMAC; + incoming_id.flags |= CSP_FHMAC; +#else + csp_log_error("Attempt to create HMAC authenticated connection, but CSP was compiled without HMAC support"); + return NULL; +#endif + } + + if (opts & CSP_O_XTEA) { +#if (CSP_USE_XTEA) + outgoing_id.flags |= CSP_FXTEA; + incoming_id.flags |= CSP_FXTEA; +#else + csp_log_error("Attempt to create XTEA encrypted connection, but CSP was compiled without XTEA support"); + return NULL; +#endif + } + + if (opts & CSP_O_CRC32) { +#if (CSP_USE_CRC32) + outgoing_id.flags |= CSP_FCRC32; + incoming_id.flags |= CSP_FCRC32; +#else + csp_log_error("Attempt to create CRC32 validated connection, but CSP was compiled without CRC32 support"); + return NULL; +#endif + } + + /* Find an unused ephemeral port */ + csp_conn_t * conn = NULL; + + /* Wait for sport lock - note that csp_conn_new(..) is called inside the lock! */ + if (csp_bin_sem_wait(&sport_lock, CSP_MAX_TIMEOUT) != CSP_SEMAPHORE_OK) { + return NULL; + } + + const uint8_t start = sport; + while (++sport != start) { + if (sport > CSP_ID_PORT_MAX) + sport = csp_conf.port_max_bind + 1; + + outgoing_id.sport = sport; + incoming_id.dport = sport; + + /* Match on destination port of _incoming_ identifier */ + if (csp_conn_find(incoming_id.ext, CSP_ID_DPORT_MASK) == NULL) { + /* Break - we found an unused ephemeral port + allocate connection while locked to mark port in use */ + conn = csp_conn_new(incoming_id, outgoing_id); + break; + } + } + + /* Post sport lock */ + csp_bin_sem_post(&sport_lock); + + if (conn == NULL) { + return NULL; + } + + /* Set connection options */ + conn->opts = opts; + +#if (CSP_USE_RDP) + /* Call Transport Layer connect */ + if (outgoing_id.flags & CSP_FRDP) { + /* If the transport layer has failed to connect + * deallocate connection structure again and return NULL */ + if (csp_rdp_connect(conn) != CSP_ERR_NONE) { + csp_close(conn); + return NULL; + } + } +#endif + + /* We have a successful connection */ + return conn; + +} + +int csp_conn_dport(csp_conn_t * conn) { + + return conn->idin.dport; + +} + +int csp_conn_sport(csp_conn_t * conn) { + + return conn->idin.sport; + +} + +int csp_conn_dst(csp_conn_t * conn) { + + return conn->idin.dst; + +} + +int csp_conn_src(csp_conn_t * conn) { + + return conn->idin.src; + +} + +int csp_conn_flags(csp_conn_t * conn) { + + return conn->idin.flags; + +} + +#if (CSP_DEBUG) +void csp_conn_print_table(void) { + + for (unsigned int i = 0; i < csp_conf.conn_max; i++) { + csp_conn_t * conn = &arr_conn[i]; + printf("[%02u %p] S:%u, %u -> %u, %u -> %u, sock: %p\r\n", + i, conn, conn->state, conn->idin.src, conn->idin.dst, + conn->idin.dport, conn->idin.sport, conn->socket); +#if (CSP_USE_RDP) + if (conn->idin.flags & CSP_FRDP) { + csp_rdp_conn_print(conn); + } +#endif + } +} + +int csp_conn_print_table_str(char * str_buf, int str_size) { + + /* Display up to 10 connections */ + unsigned int start = (csp_conf.conn_max > 10) ? (csp_conf.conn_max - 10) : 0; + + for (unsigned int i = start; i < csp_conf.conn_max; i++) { + csp_conn_t * conn = &arr_conn[i]; + char buf[100]; + snprintf(buf, sizeof(buf), "[%02u %p] S:%u, %u -> %u, %u -> %u, sock: %p\n", + i, conn, conn->state, conn->idin.src, conn->idin.dst, + conn->idin.dport, conn->idin.sport, conn->socket); + + strncat(str_buf, buf, str_size); + if ((str_size -= strlen(buf)) <= 0) { + break; + } + } + + return CSP_ERR_NONE; +} +#endif + +const csp_conn_t * csp_conn_get_array(size_t * size) +{ + *size = csp_conf.conn_max; + return arr_conn; +} diff --git a/Program/libcsp/src/csp_conn.h b/Program/libcsp/src/csp_conn.h new file mode 100755 index 0000000..60cdc41 --- /dev/null +++ b/Program/libcsp/src/csp_conn.h @@ -0,0 +1,119 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_CONN_H_ +#define _CSP_CONN_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef CSP_USE_RDP_FAST_CLOSE +#define CSP_USE_RDP_FAST_CLOSE 0 +#endif + +/** Connection states */ +typedef enum { + CONN_CLOSED = 0, + CONN_OPEN = 1, +} csp_conn_state_t; + +/** Connection types */ +typedef enum { + CONN_CLIENT = 0, + CONN_SERVER = 1, +} csp_conn_type_t; + +/** RDP Connection states */ +typedef enum { + RDP_CLOSED = 0, + RDP_SYN_SENT, + RDP_SYN_RCVD, + RDP_OPEN, + RDP_CLOSE_WAIT, +} csp_rdp_state_t; + +#define CSP_RDP_CLOSED_BY_USERSPACE 0x01 +#define CSP_RDP_CLOSED_BY_PROTOCOL 0x02 +#define CSP_RDP_CLOSED_BY_TIMEOUT 0x04 +#define CSP_RDP_CLOSED_BY_ALL (CSP_RDP_CLOSED_BY_USERSPACE | CSP_RDP_CLOSED_BY_PROTOCOL | CSP_RDP_CLOSED_BY_TIMEOUT) + +/** + * RDP Connection + */ +typedef struct { + csp_rdp_state_t state; /**< Connection state */ + uint8_t closed_by; /**< Tracks 'who' have closed the RDP connection */ + uint16_t snd_nxt; /**< The sequence number of the next segment that is to be sent */ + uint16_t snd_una; /**< The sequence number of the oldest unacknowledged segment */ + uint16_t snd_iss; /**< The initial send sequence number */ + uint16_t rcv_cur; /**< The sequence number of the last segment received correctly and in sequence */ + uint16_t rcv_irs; /**< The initial receive sequence number */ + uint16_t rcv_lsa; /**< The last sequence number acknowledged by the receiver */ + uint32_t window_size; + uint32_t conn_timeout; + uint32_t packet_timeout; + uint32_t delayed_acks; + uint32_t ack_timeout; + uint32_t ack_delay_count; + uint32_t ack_timestamp; + csp_bin_sem_handle_t tx_wait; + csp_queue_handle_t tx_queue; + csp_queue_handle_t rx_queue; +} csp_rdp_t; + +/** @brief Connection struct */ +struct csp_conn_s { + csp_conn_type_t type; /* Connection type (CONN_CLIENT or CONN_SERVER) */ + csp_conn_state_t state; /* Connection state (CONN_OPEN or CONN_CLOSED) */ + csp_id_t idin; /* Identifier received */ + csp_id_t idout; /* Identifier transmitted */ +#if (CSP_USE_QOS) + csp_queue_handle_t rx_event; /* Event queue for RX packets */ +#endif + csp_queue_handle_t rx_queue[CSP_RX_QUEUES]; /* Queue for RX packets */ + csp_queue_handle_t socket; /* Socket to be "woken" when first packet is ready */ + uint32_t timestamp; /* Time the connection was opened */ + uint32_t opts; /* Connection or socket options */ +#if (CSP_USE_RDP) + csp_rdp_t rdp; /* RDP state */ +#endif +}; + +int csp_conn_enqueue_packet(csp_conn_t * conn, csp_packet_t * packet); +int csp_conn_init(void); +csp_conn_t * csp_conn_allocate(csp_conn_type_t type); +csp_conn_t * csp_conn_find(uint32_t id, uint32_t mask); +csp_conn_t * csp_conn_new(csp_id_t idin, csp_id_t idout); +void csp_conn_check_timeouts(void); +int csp_conn_get_rxq(int prio); +int csp_conn_close(csp_conn_t * conn, uint8_t closed_by); + +const csp_conn_t * csp_conn_get_array(size_t * size); // for test purposes only! +void csp_conn_free_resources(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/csp_crc32.c b/Program/libcsp/src/csp_crc32.c new file mode 100755 index 0000000..85301fa --- /dev/null +++ b/Program/libcsp/src/csp_crc32.c @@ -0,0 +1,130 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +#ifdef __AVR__ +#include +static const uint32_t crc_tab[256] PROGMEM = { +#else +static const uint32_t crc_tab[256] = { +#endif + 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, + 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, + 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, + 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, + 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, + 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, + 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, + 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, + 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, + 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, + 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, + 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, + 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, + 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, + 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, + 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, + 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, + 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, + 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, + 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, + 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, + 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, + 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, + 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, + 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, + 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, + 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, + 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, + 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, + 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, + 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, + 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 }; + +uint32_t csp_crc32_memory(const uint8_t * data, uint32_t length) { + uint32_t crc; + + crc = 0xFFFFFFFF; + while (length--) +#ifdef __AVR__ + crc = pgm_read_dword(&crc_tab[(crc ^ *data++) & 0xFFL]) ^ (crc >> 8); +#else + crc = crc_tab[(crc ^ *data++) & 0xFFL] ^ (crc >> 8); +#endif + + return (crc ^ 0xFFFFFFFF); +} + +int csp_crc32_append(csp_packet_t * packet, bool include_header) { + + uint32_t crc; + + if ((packet->length + sizeof(crc)) > csp_buffer_data_size()) { + return CSP_ERR_NOMEM; + } + + /* Calculate CRC32, convert to network byte order */ + if (include_header) { + crc = csp_crc32_memory((uint8_t *) &packet->id, packet->length + sizeof(packet->id)); + } else { + crc = csp_crc32_memory(packet->data, packet->length); + } + /* Convert to network byte order */ + crc = csp_hton32(crc); + + /* Copy checksum to packet */ + memcpy(&packet->data[packet->length], &crc, sizeof(crc)); + packet->length += sizeof(crc); + + return CSP_ERR_NONE; + +} + +int csp_crc32_verify(csp_packet_t * packet, bool include_header) { + + uint32_t crc; + + if (packet->length < sizeof(crc)) { + return CSP_ERR_CRC32; + } + + /* Calculate CRC32, convert to network byte order */ + if (include_header) { + crc = csp_crc32_memory((uint8_t *) &packet->id, packet->length + sizeof(packet->id) - sizeof(crc)); + } else { + crc = csp_crc32_memory(packet->data, packet->length - sizeof(crc)); + } + crc = csp_hton32(crc); + + /* Compare calculated checksum with packet header */ + if (memcmp(&packet->data[packet->length] - sizeof(crc), &crc, sizeof(crc)) != 0) { + /* CRC32 failed */ + return CSP_ERR_CRC32; + } + + /* Strip CRC32 */ + packet->length -= sizeof(crc); + return CSP_ERR_NONE; + +} + diff --git a/Program/libcsp/src/csp_debug.c b/Program/libcsp/src/csp_debug.c new file mode 100755 index 0000000..74f0bd7 --- /dev/null +++ b/Program/libcsp/src/csp_debug.c @@ -0,0 +1,138 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include + +#ifdef __AVR__ +#include +#endif + +#include +#include +#include + +#if (CSP_DEBUG) && (CSP_USE_EXTERNAL_DEBUG == 0) + +/* Custom debug function */ +csp_debug_hook_func_t csp_debug_hook_func = NULL; + +/* Debug levels */ +bool csp_debug_level_enabled[] = { + [CSP_ERROR] = true, + [CSP_WARN] = true, + [CSP_INFO] = false, + [CSP_BUFFER] = false, + [CSP_PACKET] = false, + [CSP_PROTOCOL] = false, + [CSP_LOCK] = false, +}; + +void csp_debug_hook_set(csp_debug_hook_func_t f) { + + csp_debug_hook_func = f; +} + +void do_csp_debug(csp_debug_level_t level, const char *format, ...) { + + int color = COLOR_RESET; + va_list args; + + /* Don't print anything if log level is disabled */ + if (level > CSP_LOCK || !csp_debug_level_enabled[level]) + return; + + switch(level) { + case CSP_INFO: + color = COLOR_GREEN | COLOR_BOLD; + break; + case CSP_ERROR: + color = COLOR_RED | COLOR_BOLD; + break; + case CSP_WARN: + color = COLOR_YELLOW | COLOR_BOLD; + break; + case CSP_BUFFER: + color = COLOR_MAGENTA; + break; + case CSP_PACKET: + color = COLOR_GREEN; + break; + case CSP_PROTOCOL: + color = COLOR_BLUE; + break; + case CSP_LOCK: + color = COLOR_CYAN; + break; + default: + return; + } + + va_start(args, format); + + /* If csp_debug_hook symbol is defined, pass on the message. + * Otherwise, just print with pretty colors ... */ + if (csp_debug_hook_func) { + csp_debug_hook_func(level, format, args); + } else { + csp_sys_set_color(color); +#if (CSP_DEBUG_TIMESTAMP) + csp_timestamp_t ts; + csp_clock_get_time(&ts); + printf("%u.%06u ", ts.tv_sec, ts.tv_nsec / 1000U); +#endif +#ifdef __AVR__ + vfprintf_P(stdout, format, args); +#else + vprintf(format, args); +#endif + printf("\r\n"); + csp_sys_set_color(COLOR_RESET); + } + + va_end(args); +} + +void csp_debug_set_level(csp_debug_level_t level, bool value) { + + if (level <= CSP_LOCK) { + csp_debug_level_enabled[level] = value; + } +} + +int csp_debug_get_level(csp_debug_level_t level) { + + if (level <= CSP_LOCK) { + return csp_debug_level_enabled[level]; + } + return 0; +} + +void csp_debug_toggle_level(csp_debug_level_t level) { + + if (level <= CSP_LOCK) { + csp_debug_level_enabled[level] = (csp_debug_level_enabled[level]) ? false : true; + } +} + +#endif // (CSP_DEBUG) && !(CSP_USE_EXTERNAL_DEBUG) diff --git a/Program/libcsp/src/csp_dedup.c b/Program/libcsp/src/csp_dedup.c new file mode 100755 index 0000000..0190e7c --- /dev/null +++ b/Program/libcsp/src/csp_dedup.c @@ -0,0 +1,62 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_dedup.h" + +#include + +#include +#include + +/* Check the last CSP_DEDUP_COUNT packets for duplicates */ +#define CSP_DEDUP_COUNT 16 + +/* Only consider packet a duplicate if received under CSP_DEDUP_WINDOW_MS ago */ +#define CSP_DEDUP_WINDOW_MS 1000 + +/* Store packet CRC's in a ringbuffer */ +static uint32_t csp_dedup_array[CSP_DEDUP_COUNT] = {}; +static uint32_t csp_dedup_timestamp[CSP_DEDUP_COUNT] = {}; +static int csp_dedup_in = 0; + +bool csp_dedup_is_duplicate(csp_packet_t *packet) +{ + /* Calculate CRC32 for packet */ + uint32_t crc = csp_crc32_memory((const uint8_t *) &packet->id, packet->length + sizeof(packet->id)); + + /* Check if we have received this packet before */ + for (int i = 0; i < CSP_DEDUP_COUNT; i++) { + + /* Check for match */ + if (crc == csp_dedup_array[i]) { + + /* Check the timestamp */ + if (csp_get_ms() < csp_dedup_timestamp[i] + CSP_DEDUP_WINDOW_MS) + return true; + } + } + + /* If not, insert packet into duplicate list */ + csp_dedup_array[csp_dedup_in] = crc; + csp_dedup_timestamp[csp_dedup_in] = csp_get_ms(); + csp_dedup_in = (csp_dedup_in + 1) % CSP_DEDUP_COUNT; + + return false; +} diff --git a/Program/libcsp/src/csp_dedup.h b/Program/libcsp/src/csp_dedup.h new file mode 100755 index 0000000..3d08a2b --- /dev/null +++ b/Program/libcsp/src/csp_dedup.h @@ -0,0 +1,33 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_DEDUP_H_ +#define CSP_DEDUP_H_ + +#include + +/** + * Check for a duplicate packet + * @param packet pointer to packet + * @return false if not a duplicate, true if duplicate + */ +bool csp_dedup_is_duplicate(csp_packet_t *packet); + +#endif /* CSP_DEDUP_H_ */ diff --git a/Program/libcsp/src/csp_endian.c b/Program/libcsp/src/csp_endian.c new file mode 100755 index 0000000..ee6f99a --- /dev/null +++ b/Program/libcsp/src/csp_endian.c @@ -0,0 +1,200 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +/* Convert 16-bit number from host byte order to network byte order */ +inline uint16_t __attribute__ ((__const__)) csp_hton16(uint16_t h16) { +#if (CSP_BIG_ENDIAN) + return h16; +#else + return (((h16 & 0xff00) >> 8) | + ((h16 & 0x00ff) << 8)); +#endif +} + +/* Convert 16-bit number from network byte order to host byte order */ +inline uint16_t __attribute__ ((__const__)) csp_ntoh16(uint16_t n16) { + return csp_hton16(n16); +} + +/* Convert 32-bit number from host byte order to network byte order */ +inline uint32_t __attribute__ ((__const__)) csp_hton32(uint32_t h32) { +#if (CSP_BIG_ENDIAN) + return h32; +#else + return (((h32 & 0xff000000) >> 24) | + ((h32 & 0x000000ff) << 24) | + ((h32 & 0x0000ff00) << 8) | + ((h32 & 0x00ff0000) >> 8)); +#endif +} + +/* Convert 32-bit number from network byte order to host byte order */ +inline uint32_t __attribute__ ((__const__)) csp_ntoh32(uint32_t n32) { + return csp_hton32(n32); +} + +/* Convert 64-bit number from host byte order to network byte order */ +inline uint64_t __attribute__ ((__const__)) csp_hton64(uint64_t h64) { +#if (CSP_BIG_ENDIAN) + return h64; +#else + return (((h64 & 0xff00000000000000LL) >> 56) | + ((h64 & 0x00000000000000ffLL) << 56) | + ((h64 & 0x00ff000000000000LL) >> 40) | + ((h64 & 0x000000000000ff00LL) << 40) | + ((h64 & 0x0000ff0000000000LL) >> 24) | + ((h64 & 0x0000000000ff0000LL) << 24) | + ((h64 & 0x000000ff00000000LL) >> 8) | + ((h64 & 0x00000000ff000000LL) << 8)); +#endif +} + +/* Convert 64-bit number from host byte order to network byte order */ +inline uint64_t __attribute__ ((__const__)) csp_ntoh64(uint64_t n64) { + return csp_hton64(n64); +} + +/* Convert 16-bit number from host byte order to big endian byte order */ +inline uint16_t __attribute__ ((__const__)) csp_htobe16(uint16_t h16) { + return csp_hton16(h16); +} + +/* Convert 16-bit number from host byte order to little endian byte order */ +inline uint16_t __attribute__ ((__const__)) csp_htole16(uint16_t h16) { +#if (CSP_LITTLE_ENDIAN) + return h16; +#else + return (((h16 & 0xff00) >> 8) | + ((h16 & 0x00ff) << 8)); +#endif +} + +/* Convert 16-bit number from big endian byte order to little endian byte order */ +inline uint16_t __attribute__ ((__const__)) csp_betoh16(uint16_t be16) { + return csp_ntoh16(be16); +} + +/* Convert 16-bit number from little endian byte order to host byte order */ +inline uint16_t __attribute__ ((__const__)) csp_letoh16(uint16_t le16) { + return csp_htole16(le16); +} + +/* Convert 32-bit number from host byte order to big endian byte order */ +inline uint32_t __attribute__ ((__const__)) csp_htobe32(uint32_t h32) { + return csp_hton32(h32); +} + +/* Convert 32-bit number from little endian byte order to host byte order */ +inline uint32_t __attribute__ ((__const__)) csp_htole32(uint32_t h32) { +#if (CSP_LITTLE_ENDIAN) + return h32; +#else + return (((h32 & 0xff000000) >> 24) | + ((h32 & 0x000000ff) << 24) | + ((h32 & 0x0000ff00) << 8) | + ((h32 & 0x00ff0000) >> 8)); +#endif +} + +/* Convert 32-bit number from big endian byte order to host byte order */ +inline uint32_t __attribute__ ((__const__)) csp_betoh32(uint32_t be32) { + return csp_ntoh32(be32); +} + +/* Convert 32-bit number from little endian byte order to host byte order */ +inline uint32_t __attribute__ ((__const__)) csp_letoh32(uint32_t le32) { + return csp_htole32(le32); +} + +/* Convert 64-bit number from host byte order to big endian byte order */ +inline uint64_t __attribute__ ((__const__)) csp_htobe64(uint64_t h64) { + return csp_hton64(h64); +} + +/* Convert 64-bit number from host byte order to little endian byte order */ +inline uint64_t __attribute__ ((__const__)) csp_htole64(uint64_t h64) { +#if (CSP_LITTLE_ENDIAN) + return h64; +#else + return (((h64 & 0xff00000000000000LL) >> 56) | + ((h64 & 0x00000000000000ffLL) << 56) | + ((h64 & 0x00ff000000000000LL) >> 40) | + ((h64 & 0x000000000000ff00LL) << 40) | + ((h64 & 0x0000ff0000000000LL) >> 24) | + ((h64 & 0x0000000000ff0000LL) << 24) | + ((h64 & 0x000000ff00000000LL) >> 8) | + ((h64 & 0x00000000ff000000LL) << 8)); +#endif +} + +/* Convert 64-bit number from big endian byte order to host byte order */ +inline uint64_t __attribute__ ((__const__)) csp_betoh64(uint64_t be64) { + return csp_ntoh64(be64); +} + +/* Convert 64-bit number from little endian byte order to host byte order */ +inline uint64_t __attribute__ ((__const__)) csp_letoh64(uint64_t le64) { + return csp_htole64(le64); +} + + +/* Convert float from host byte order to network byte order */ +inline float __attribute__ ((__const__)) csp_htonflt(float f) { +#if (CSP_BIG_ENDIAN) + return f; +#else + union v { + float f; + uint32_t i; + }; + union v val; + val.f = f; + val.i = csp_hton32(val.i); + return val.f; +#endif +} + +/* Convert float from host byte order to network byte order */ +inline float __attribute__ ((__const__)) csp_ntohflt(float f) { + return csp_htonflt(f); +} + +/* Convert double from host byte order to network byte order */ +inline double __attribute__ ((__const__)) csp_htondbl(double d) { +#if (CSP_BIG_ENDIAN) + return d; +#else + union v { + double d; + uint64_t i; + }; + union v val; + val.d = d; + val.i = csp_hton64(val.i); + return val.d; +#endif +} + +/* Convert float from host byte order to network byte order */ +inline double __attribute__ ((__const__)) csp_ntohdbl(double d) { + return csp_htondbl(d); +} diff --git a/Program/libcsp/src/csp_hex_dump.c b/Program/libcsp/src/csp_hex_dump.c new file mode 100755 index 0000000..a31fd39 --- /dev/null +++ b/Program/libcsp/src/csp_hex_dump.c @@ -0,0 +1,76 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +void csp_hex_dump(const char *desc, void *addr, int len) +{ + int i; + unsigned char buff[17]; + unsigned char *pc = (unsigned char*)addr; + + // Output description if given. + if (desc != NULL) + printf ("%s:\r\n", desc); + + if (len == 0) { + printf(" ZERO LENGTH\r\n"); + return; + } + if (len < 0) { + printf(" NEGATIVE LENGTH: %i\r\n",len); + return; + } + + // Process every byte in the data. + for (i = 0; i < len; i++) { + // Multiple of 16 means new line (with line offset). + + if ((i % 16) == 0) { + // Just don't print ASCII for the zeroth line. + if (i != 0) + printf (" %s\r\n", buff); + + // Output the offset. + printf (" %p ", ((uint8_t*)addr) + i); + } + + // Now the hex code for the specific character. + printf (" %02x", pc[i]); + + // And store a printable ASCII character for later. + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) + buff[i % 16] = '.'; + else + buff[i % 16] = pc[i]; + buff[(i % 16) + 1] = '\0'; + } + + // Pad out last line if not exactly 16 characters. + while ((i % 16) != 0) { + printf (" "); + i++; + } + + // And print the final ASCII bit. + printf (" %s\r\n", buff); +} diff --git a/Program/libcsp/src/csp_iflist.c b/Program/libcsp/src/csp_iflist.c new file mode 100755 index 0000000..7accd8e --- /dev/null +++ b/Program/libcsp/src/csp_iflist.c @@ -0,0 +1,106 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include + +#include + +/* Interfaces are stored in a linked list */ +static csp_iface_t * interfaces = NULL; + +csp_iface_t * csp_iflist_get_by_name(const char *name) { + csp_iface_t *ifc = interfaces; + while(ifc) { + if (strncasecmp(ifc->name, name, CSP_IFLIST_NAME_MAX) == 0) { + break; + } + ifc = ifc->next; + } + return ifc; +} + +int csp_iflist_add(csp_iface_t *ifc) { + + ifc->next = NULL; + + /* Add interface to pool */ + if (interfaces == NULL) { + /* This is the first interface to be added */ + interfaces = ifc; + } else { + /* Insert interface last if not already in pool */ + csp_iface_t * last = NULL; + for (csp_iface_t * i = interfaces; i != NULL; i = i->next) { + if ((i == ifc) || (strncasecmp(ifc->name, i->name, CSP_IFLIST_NAME_MAX) == 0)) { + return CSP_ERR_ALREADY; + } + last = i; + } + + last->next = ifc; + } + + return CSP_ERR_NONE; +} + +csp_iface_t * csp_iflist_get(void) +{ + return interfaces; +} + +#if (CSP_DEBUG) +int csp_bytesize(char *buffer, int buffer_len, unsigned long int bytes) { + char postfix; + double size; + + if (bytes >= 1048576) { + size = bytes/1048576.0; + postfix = 'M'; + } else if (bytes >= 1024) { + size = bytes/1024.0; + postfix = 'K'; + } else { + size = bytes; + postfix = 'B'; + } + + return snprintf(buffer, buffer_len, "%.1f%c", size, postfix); +} + +void csp_iflist_print(void) { + csp_iface_t * i = interfaces; + char txbuf[25], rxbuf[25]; + + while (i) { + csp_bytesize(txbuf, sizeof(txbuf), i->txbytes); + csp_bytesize(rxbuf, sizeof(rxbuf), i->rxbytes); + printf("%-10s tx: %05"PRIu32" rx: %05"PRIu32" txe: %05"PRIu32" rxe: %05"PRIu32"\r\n" + " drop: %05"PRIu32" autherr: %05"PRIu32 " frame: %05"PRIu32"\r\n" + " txb: %"PRIu32" (%s) rxb: %"PRIu32" (%s) MTU: %u\r\n\r\n", + i->name, i->tx, i->rx, i->tx_error, i->rx_error, i->drop, + i->autherr, i->frame, i->txbytes, txbuf, i->rxbytes, rxbuf, i->mtu); + i = i->next; + } +} +#endif + diff --git a/Program/libcsp/src/csp_init.c b/Program/libcsp/src/csp_init.c new file mode 100755 index 0000000..94be820 --- /dev/null +++ b/Program/libcsp/src/csp_init.c @@ -0,0 +1,95 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_init.h" + +#include +#include +#include "csp_conn.h" +#include "csp_qfifo.h" +#include "csp_port.h" + +csp_conf_t csp_conf; + +uint8_t csp_get_address(void) { + + return csp_conf.address; +} + +int csp_init(const csp_conf_t * conf) { + + /* make offset first time, so uptime is counted from process/task boot */ + csp_get_uptime_s(); + + /* Make a copy of the configuration + * The copy is kept hidden for the user in csp_init.h + * Configuration cannot be changed after calling init + * unless specific get/set functions are made */ + memcpy(&csp_conf, conf, sizeof(csp_conf)); + + int ret = csp_buffer_init(); + if (ret != CSP_ERR_NONE) { + return ret; + } + + ret = csp_conn_init(); + if (ret != CSP_ERR_NONE) { + return ret; + } + + ret = csp_port_init(); + if (ret != CSP_ERR_NONE) { + return ret; + } + + ret = csp_qfifo_init(); + if (ret != CSP_ERR_NONE) { + return ret; + } + + /* Loopback */ + csp_iflist_add(&csp_if_lo); + + /* Register loopback route */ + csp_route_set(csp_conf.address, &csp_if_lo, CSP_NO_VIA_ADDRESS); + + /* Also register loopback as default, until user redefines default route */ + csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_lo, CSP_NO_VIA_ADDRESS); + + return CSP_ERR_NONE; + +} + +void csp_free_resources(void) { + + csp_rtable_free(); + csp_qfifo_free_resources(); + csp_port_free_resources(); + csp_conn_free_resources(); + csp_buffer_free_resources(); + memset(&csp_conf, 0, sizeof(csp_conf)); + +} + +const csp_conf_t * csp_get_conf(void) { + + return &csp_conf; + +} diff --git a/Program/libcsp/src/csp_init.h b/Program/libcsp/src/csp_init.h new file mode 100755 index 0000000..5e3c9c4 --- /dev/null +++ b/Program/libcsp/src/csp_init.h @@ -0,0 +1,38 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef LIB_CSP_SRC_CSP_INIT_H_ +#define LIB_CSP_SRC_CSP_INIT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern csp_conf_t csp_conf; + +int csp_buffer_init(void); +void csp_buffer_free_resources(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/csp_io.c b/Program/libcsp/src/csp_io.c new file mode 100755 index 0000000..9dbded6 --- /dev/null +++ b/Program/libcsp/src/csp_io.c @@ -0,0 +1,408 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_io.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "csp_init.h" +#include "csp_port.h" +#include "csp_conn.h" +#include "csp_promisc.h" +#include "csp_qfifo.h" +#include "transport/csp_transport.h" + +#if (CSP_USE_PROMISC) +extern csp_queue_handle_t csp_promisc_queue; +#endif + +csp_socket_t * csp_socket(uint32_t opts) { + + /* Validate socket options */ +#if (CSP_USE_RDP == 0) + if (opts & CSP_SO_RDPREQ) { + csp_log_error("Attempt to create socket that requires RDP, but CSP was compiled without RDP support"); + return NULL; + } +#endif + +#if (CSP_USE_XTEA == 0) + if (opts & CSP_SO_XTEAREQ) { + csp_log_error("Attempt to create socket that requires XTEA, but CSP was compiled without XTEA support"); + return NULL; + } +#endif + +#if (CSP_USE_HMAC == 0) + if (opts & CSP_SO_HMACREQ) { + csp_log_error("Attempt to create socket that requires HMAC, but CSP was compiled without HMAC support"); + return NULL; + } +#endif + +#if (CSP_USE_CRC32 == 0) + if (opts & CSP_SO_CRC32REQ) { + csp_log_error("Attempt to create socket that requires CRC32, but CSP was compiled without CRC32 support"); + return NULL; + } +#endif + + /* Drop packet if reserved flags are set */ + if (opts & ~(CSP_SO_RDPREQ | CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ | CSP_SO_CONN_LESS)) { + csp_log_error("Invalid socket option"); + return NULL; + } + + /* Use CSP buffers instead? */ + csp_socket_t * sock = csp_conn_allocate(CONN_SERVER); + if (sock == NULL) + return NULL; + + /* If connectionless, init the queue to a pre-defined size + * if not, the user must init the queue using csp_listen */ + if (opts & CSP_SO_CONN_LESS) { + sock->socket = csp_queue_create(csp_conf.conn_queue_length, sizeof(csp_packet_t *)); + if (sock->socket == NULL) { + csp_close(sock); + return NULL; + } + } else { + sock->socket = NULL; + } + sock->opts = opts; + + return sock; + +} + +csp_conn_t * csp_accept(csp_socket_t * sock, uint32_t timeout) { + + if (sock == NULL) + return NULL; + + if (sock->socket == NULL) + return NULL; + + csp_conn_t * conn; + if (csp_queue_dequeue(sock->socket, &conn, timeout) == CSP_QUEUE_OK) + return conn; + + return NULL; + +} + +csp_packet_t * csp_read(csp_conn_t * conn, uint32_t timeout) { + + csp_packet_t * packet = NULL; + + if ((conn == NULL) || (conn->state != CONN_OPEN)) { + return NULL; + } + +#if (CSP_USE_RDP) + // RDP: timeout can either be 0 (for no hang poll/check) or minimum the "connection timeout" + if (timeout && (conn->idin.flags & CSP_FRDP) && (timeout < conn->rdp.conn_timeout)) { + timeout = conn->rdp.conn_timeout; + } +#endif + +#if (CSP_USE_QOS) + int event; + if (csp_queue_dequeue(conn->rx_event, &event, timeout) != CSP_QUEUE_OK) { + return NULL; + } + + for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { + if (csp_queue_dequeue(conn->rx_queue[prio], &packet, 0) == CSP_QUEUE_OK) { + break; + } + } +#else + if (csp_queue_dequeue(conn->rx_queue[0], &packet, timeout) != CSP_QUEUE_OK) { + return NULL; + } +#endif + +#if (CSP_USE_RDP) + /* Packet read could trigger ACK transmission */ + if ((conn->idin.flags & CSP_FRDP) && conn->rdp.delayed_acks) { + csp_rdp_check_ack(conn); + } +#endif + + return packet; + +} + +int csp_send_direct(csp_id_t idout, csp_packet_t * packet, const csp_route_t * ifroute, uint32_t timeout) { + + if (packet == NULL) { + csp_log_error("csp_send_direct called with NULL packet"); + goto err; + } + + if (ifroute == NULL) { + csp_log_error("No route to host: %u (0x%08"PRIx32")", idout.dst, idout.ext); + goto err; + } + + csp_iface_t * ifout = ifroute->iface; + + csp_log_packet("OUT: S %u, D %u, Dp %u, Sp %u, Pr %u, Fl 0x%02X, Sz %u VIA: %s (%u)", + idout.src, idout.dst, idout.dport, idout.sport, idout.pri, idout.flags, packet->length, ifout->name, (ifroute->via != CSP_NO_VIA_ADDRESS) ? ifroute->via : idout.dst); + + /* Copy identifier to packet (before crc, xtea and hmac) */ + packet->id.ext = idout.ext; + +#if (CSP_USE_PROMISC) + /* Loopback traffic is added to promisc queue by the router */ + if (idout.dst != csp_get_address() && idout.src == csp_get_address()) { + packet->id.ext = idout.ext; + csp_promisc_add(packet); + } +#endif + + /* Only encrypt packets from the current node */ + if (idout.src == csp_conf.address) { + /* Append HMAC */ + if (idout.flags & CSP_FHMAC) { +#if (CSP_USE_HMAC) + /* Calculate and add HMAC (does not include header for backwards compatability with csp1.x) */ + if (csp_hmac_append(packet, false) != CSP_ERR_NONE) { + /* HMAC append failed */ + csp_log_warn("HMAC append failed!"); + goto tx_err; + } +#else + csp_log_warn("Attempt to send packet with HMAC, but CSP was compiled without HMAC support. Discarding packet"); + goto tx_err; +#endif + } + + /* Append CRC32 */ + if (idout.flags & CSP_FCRC32) { +#if (CSP_USE_CRC32) + /* Calculate and add CRC32 (does not include header for backwards compatability with csp1.x) */ + if (csp_crc32_append(packet, false) != CSP_ERR_NONE) { + /* CRC32 append failed */ + csp_log_warn("CRC32 append failed!"); + goto tx_err; + } +#else + csp_log_warn("Attempt to send packet with CRC32, but CSP was compiled without CRC32 support. Sending without CRC32r"); + idout.flags &= ~(CSP_FCRC32); +#endif + } + + if (idout.flags & CSP_FXTEA) { +#if (CSP_USE_XTEA) + /* Encrypt data */ + if (csp_xtea_encrypt_packet(packet) != CSP_ERR_NONE) { + /* Encryption failed */ + csp_log_warn("XTEA Encryption failed!"); + goto tx_err; + } +#else + csp_log_warn("Attempt to send XTEA encrypted packet, but CSP was compiled without XTEA support. Discarding packet"); + goto tx_err; +#endif + } + } + + /* Store length before passing to interface */ + uint16_t bytes = packet->length; + uint16_t mtu = ifout->mtu; + + if (mtu > 0 && bytes > mtu) + goto tx_err; + + if ((*ifout->nexthop)(ifroute, packet) != CSP_ERR_NONE) + goto tx_err; + + ifout->tx++; + ifout->txbytes += bytes; + return CSP_ERR_NONE; + +tx_err: + ifout->tx_error++; +err: + return CSP_ERR_TX; + +} + +int csp_send(csp_conn_t * conn, csp_packet_t * packet, uint32_t timeout) { + + if ((conn == NULL) || (packet == NULL) || (conn->state != CONN_OPEN)) { + csp_log_error("Invalid call to csp_send"); + return 0; + } + +#if (CSP_USE_RDP) + if (conn->idout.flags & CSP_FRDP) { + if (csp_rdp_send(conn, packet) != CSP_ERR_NONE) { + return 0; + } + } +#endif + + int ret = csp_send_direct(conn->idout, packet, csp_rtable_find_route(conn->idout.dst), timeout); + + return (ret == CSP_ERR_NONE) ? 1 : 0; + +} + +int csp_send_prio(uint8_t prio, csp_conn_t * conn, csp_packet_t * packet, uint32_t timeout) { + conn->idout.pri = prio; + return csp_send(conn, packet, timeout); +} + +int csp_transaction_persistent(csp_conn_t * conn, uint32_t timeout, void * outbuf, int outlen, void * inbuf, int inlen) { + + int size = (inlen > outlen) ? inlen : outlen; + csp_packet_t * packet = csp_buffer_get(size); + if (packet == NULL) + return 0; + + /* Copy the request */ + if (outlen > 0 && outbuf != NULL) + memcpy(packet->data, outbuf, outlen); + packet->length = outlen; + + if (!csp_send(conn, packet, timeout)) { + csp_buffer_free(packet); + return 0; + } + + /* If no reply is expected, return now */ + if (inlen == 0) + return 1; + + packet = csp_read(conn, timeout); + if (packet == NULL) + return 0; + + if ((inlen != -1) && ((int)packet->length != inlen)) { + csp_log_error("Reply length %u expected %u", packet->length, inlen); + csp_buffer_free(packet); + return 0; + } + + memcpy(inbuf, packet->data, packet->length); + int length = packet->length; + csp_buffer_free(packet); + return length; + +} + +int csp_transaction_w_opts(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void * outbuf, int outlen, void * inbuf, int inlen, uint32_t opts) { + + csp_conn_t * conn = csp_connect(prio, dest, port, 0, opts); + if (conn == NULL) + return 0; + + int status = csp_transaction_persistent(conn, timeout, outbuf, outlen, inbuf, inlen); + + csp_close(conn); + + return status; + +} + +csp_packet_t * csp_recvfrom(csp_socket_t * socket, uint32_t timeout) { + + if ((socket == NULL) || (!(socket->opts & CSP_SO_CONN_LESS))) + return NULL; + + csp_packet_t * packet = NULL; + csp_queue_dequeue(socket->socket, &packet, timeout); + + return packet; + +} + +int csp_sendto(uint8_t prio, uint8_t dest, uint8_t dport, uint8_t src_port, uint32_t opts, csp_packet_t * packet, uint32_t timeout) { + + packet->id.flags = 0; + + if (opts & CSP_O_RDP) { + csp_log_error("Attempt to create RDP packet on connection-less socket"); + return CSP_ERR_INVAL; + } + + if (opts & CSP_O_HMAC) { +#if (CSP_USE_HMAC) + packet->id.flags |= CSP_FHMAC; +#else + csp_log_error("Attempt to create HMAC authenticated packet, but CSP was compiled without HMAC support"); + return CSP_ERR_NOTSUP; +#endif + } + + if (opts & CSP_O_XTEA) { +#if (CSP_USE_XTEA) + packet->id.flags |= CSP_FXTEA; +#else + csp_log_error("Attempt to create XTEA encrypted packet, but CSP was compiled without XTEA support"); + return CSP_ERR_NOTSUP; +#endif + } + + if (opts & CSP_O_CRC32) { +#if (CSP_USE_CRC32) + packet->id.flags |= CSP_FCRC32; +#else + csp_log_error("Attempt to create CRC32 validated packet, but CSP was compiled without CRC32 support"); + return CSP_ERR_NOTSUP; +#endif + } + + packet->id.dst = dest; + packet->id.dport = dport; + packet->id.src = csp_conf.address; + packet->id.sport = src_port; + packet->id.pri = prio; + + if (csp_send_direct(packet->id, packet, csp_rtable_find_route(dest), timeout) != CSP_ERR_NONE) + return CSP_ERR_NOTSUP; + + return CSP_ERR_NONE; + +} + +int csp_sendto_reply(const csp_packet_t * request_packet, csp_packet_t * reply_packet, uint32_t opts, uint32_t timeout) { + if (request_packet == NULL) + return CSP_ERR_INVAL; + + return csp_sendto(request_packet->id.pri, request_packet->id.src, request_packet->id.sport, request_packet->id.dport, opts, reply_packet, timeout); +} diff --git a/Program/libcsp/src/csp_io.h b/Program/libcsp/src/csp_io.h new file mode 100755 index 0000000..57bfa77 --- /dev/null +++ b/Program/libcsp/src/csp_io.h @@ -0,0 +1,44 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_IO_H_ +#define _CSP_IO_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Send CSP packet via route (no existing connection). + + @param idout 32bit CSP identifier + @param packet packet to send - this will not be freed. + @param ifroute route to destination + @param timeout timeout to wait for TX to complete. NOTE: not all underlying drivers supports flow-control. + @return #CSP_ERR_NONE on success, otherwise an error code. +*/ +int csp_send_direct(csp_id_t idout, csp_packet_t * packet, const csp_route_t * ifroute, uint32_t timeout); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/csp_port.c b/Program/libcsp/src/csp_port.c new file mode 100755 index 0000000..b3913e4 --- /dev/null +++ b/Program/libcsp/src/csp_port.c @@ -0,0 +1,115 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_port.h" + +#include +#include +#include + +#include +#include +#include + +#include "csp_conn.h" +#include "csp_init.h" + +/* Dynamic allocated port array */ +static csp_port_t * ports; + +csp_socket_t * csp_port_get_socket(unsigned int port) { + + if (port > csp_conf.port_max_bind) { + return NULL; + } + + /* Match dport to socket or local "catch all" port number */ + if (ports[port].state == PORT_OPEN) { + return ports[port].socket; + } + + if (ports[csp_conf.port_max_bind + 1].state == PORT_OPEN) { + return ports[csp_conf.port_max_bind + 1].socket; + } + + return NULL; + +} + +int csp_port_init(void) { + + ports = csp_calloc(csp_conf.port_max_bind + 2, sizeof(*ports)); // +2 for max port and CSP_ANY + if (ports == NULL) { + return CSP_ERR_NOMEM; + } + + return CSP_ERR_NONE; + +} + +void csp_port_free_resources(void) { + + csp_free(ports); + ports = NULL; +} + +int csp_listen(csp_socket_t * socket, size_t backlog) { + + if (socket == NULL) + return CSP_ERR_INVAL; + + socket->socket = csp_queue_create(backlog, sizeof(csp_conn_t *)); + if (socket->socket == NULL) + return CSP_ERR_NOMEM; + + socket->opts |= CSP_SO_INTERNAL_LISTEN; + + return CSP_ERR_NONE; + +} + +int csp_bind(csp_socket_t * socket, uint8_t port) { + + if (socket == NULL) + return CSP_ERR_INVAL; + + if (port == CSP_ANY) { + port = csp_conf.port_max_bind + 1; + } else if (port > csp_conf.port_max_bind) { + csp_log_error("csp_bind: invalid port %u, only ports from 0-%u (+ CSP_ANY for default) are available for incoming ports", port, csp_conf.port_max_bind); + return CSP_ERR_INVAL; + } + + if (ports[port].state != PORT_CLOSED) { + csp_log_error("Port %d is already in use", port); + return CSP_ERR_USED; + } + + csp_log_info("Binding socket %p to port %u", socket, port); + + /* Save listener */ + ports[port].socket = socket; + ports[port].state = PORT_OPEN; + + return CSP_ERR_NONE; + +} + + diff --git a/Program/libcsp/src/csp_port.h b/Program/libcsp/src/csp_port.h new file mode 100755 index 0000000..ba0f909 --- /dev/null +++ b/Program/libcsp/src/csp_port.h @@ -0,0 +1,57 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_PORT_H_ +#define _CSP_PORT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Port states */ +typedef enum { + PORT_CLOSED = 0, + PORT_OPEN = 1, +} csp_port_state_t; + +/** @brief Port struct */ +typedef struct { + csp_port_state_t state; // Port state + csp_socket_t * socket; // New connections are added to this socket's conn queue +} csp_port_t; + +/** + * Init ports array + */ +int csp_port_init(void); + +/** + * Free all allocatged resources (testing) + */ +void csp_port_free_resources(void); + +csp_socket_t * csp_port_get_socket(unsigned int dport); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/csp_promisc.c b/Program/libcsp/src/csp_promisc.c new file mode 100755 index 0000000..1e53cfe --- /dev/null +++ b/Program/libcsp/src/csp_promisc.c @@ -0,0 +1,84 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_promisc.h" + +#include +#include + +#if (CSP_USE_PROMISC) + +static csp_queue_handle_t csp_promisc_queue = NULL; +static int csp_promisc_enabled = 0; + +int csp_promisc_enable(unsigned int queue_size) { + + /* If queue already initialised */ + if (csp_promisc_queue != NULL) { + csp_promisc_enabled = 1; + return CSP_ERR_NONE; + } + + /* Create packet queue */ + csp_promisc_queue = csp_queue_create(queue_size, sizeof(csp_packet_t *)); + + if (csp_promisc_queue == NULL) + return CSP_ERR_INVAL; + + csp_promisc_enabled = 1; + return CSP_ERR_NONE; + +} + +void csp_promisc_disable(void) { + csp_promisc_enabled = 0; +} + +csp_packet_t * csp_promisc_read(uint32_t timeout) { + + if (csp_promisc_queue == NULL) + return NULL; + + csp_packet_t * packet = NULL; + csp_queue_dequeue(csp_promisc_queue, &packet, timeout); + + return packet; + +} + +void csp_promisc_add(csp_packet_t * packet) { + + if (csp_promisc_enabled == 0) + return; + + if (csp_promisc_queue != NULL) { + /* Make a copy of the message and queue it to the promiscuous task */ + csp_packet_t *packet_copy = csp_buffer_clone(packet); + if (packet_copy != NULL) { + if (csp_queue_enqueue(csp_promisc_queue, &packet_copy, 0) != CSP_QUEUE_OK) { + csp_log_error("Promiscuous mode input queue full"); + csp_buffer_free(packet_copy); + } + } + } + +} + +#endif diff --git a/Program/libcsp/src/csp_promisc.h b/Program/libcsp/src/csp_promisc.h new file mode 100755 index 0000000..80c57fa --- /dev/null +++ b/Program/libcsp/src/csp_promisc.h @@ -0,0 +1,39 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _SRC_CSP_PROMISC_H_ +#define _SRC_CSP_PROMISC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Add packet to promiscuous mode packet queue + * @param packet Packet to add to the queue + */ +void csp_promisc_add(csp_packet_t * packet); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/csp_qfifo.c b/Program/libcsp/src/csp_qfifo.c new file mode 100755 index 0000000..37709f1 --- /dev/null +++ b/Program/libcsp/src/csp_qfifo.c @@ -0,0 +1,168 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_qfifo.h" + +#include + +#include "csp_init.h" + +static csp_queue_handle_t qfifo[CSP_ROUTE_FIFOS]; +#if (CSP_USE_QOS) +static csp_queue_handle_t qfifo_events; +#endif + +int csp_qfifo_init(void) { + + /* Create router fifos for each priority */ + for (int prio = 0; prio < CSP_ROUTE_FIFOS; prio++) { + if (qfifo[prio] == NULL) { + qfifo[prio] = csp_queue_create(csp_conf.fifo_length, sizeof(csp_qfifo_t)); + if (!qfifo[prio]) + return CSP_ERR_NOMEM; + } + } + +#if (CSP_USE_QOS) + /* Create QoS fifo notification queue */ + qfifo_events = csp_queue_create(csp_conf.fifo_length, sizeof(int)); + if (!qfifo_events) { + return CSP_ERR_NOMEM; + } +#endif + + return CSP_ERR_NONE; + +} + +void csp_qfifo_free_resources(void) { + + for (int prio = 0; prio < CSP_ROUTE_FIFOS; prio++) { + if (qfifo[prio]) { + csp_queue_remove(qfifo[prio]); + qfifo[prio] = NULL; + } + } + +#if (CSP_USE_QOS) + if (qfifo_events) { + csp_queue_remove(qfifo_events); + qfifo_events = NULL; + } +#endif + +} + +int csp_qfifo_read(csp_qfifo_t * input) { + +#if (CSP_USE_QOS) + int prio, found, event; + + /* Wait for packet in any queue */ + if (csp_queue_dequeue(qfifo_events, &event, FIFO_TIMEOUT) != CSP_QUEUE_OK) + return CSP_ERR_TIMEDOUT; + + /* Find packet with highest priority */ + found = 0; + for (prio = 0; prio < CSP_ROUTE_FIFOS; prio++) { + if (csp_queue_dequeue(qfifo[prio], input, 0) == CSP_QUEUE_OK) { + found = 1; + break; + } + } + + if (!found) { + csp_log_warn("Spurious wakeup: No packet found"); + return CSP_ERR_TIMEDOUT; + } +#else + if (csp_queue_dequeue(qfifo[0], input, FIFO_TIMEOUT) != CSP_QUEUE_OK) + return CSP_ERR_TIMEDOUT; +#endif + + return CSP_ERR_NONE; + +} + +void csp_qfifo_write(csp_packet_t * packet, csp_iface_t * iface, CSP_BASE_TYPE * pxTaskWoken) { + + int result; + + if (packet == NULL) { + if (pxTaskWoken == NULL) { // Only do logging in non-ISR context + csp_log_warn("csp_new packet called with NULL packet"); + } + return; + } + + if (iface == NULL) { + if (pxTaskWoken == NULL) { // Only do logging in non-ISR context + csp_log_warn("csp_new packet called with NULL interface"); + } + if (pxTaskWoken == NULL) + csp_buffer_free(packet); + else + csp_buffer_free_isr(packet); + return; + } + + csp_qfifo_t queue_element; + queue_element.iface = iface; + queue_element.packet = packet; + +#if (CSP_USE_QOS) + int fifo = packet->id.pri; +#else + int fifo = 0; +#endif + + if (pxTaskWoken == NULL) + result = csp_queue_enqueue(qfifo[fifo], &queue_element, 0); + else + result = csp_queue_enqueue_isr(qfifo[fifo], &queue_element, pxTaskWoken); + +#if (CSP_USE_QOS) + static int event = 0; + + if (result == CSP_QUEUE_OK) { + if (pxTaskWoken == NULL) + csp_queue_enqueue(qfifo_events, &event, 0); + else + csp_queue_enqueue_isr(qfifo_events, &event, pxTaskWoken); + } +#endif + + if (result != CSP_QUEUE_OK) { + if (pxTaskWoken == NULL) { // Only do logging in non-ISR context + csp_log_warn("ERROR: Routing input FIFO is FULL. Dropping packet."); + } + iface->drop++; + if (pxTaskWoken == NULL) + csp_buffer_free(packet); + else + csp_buffer_free_isr(packet); + } + +} + +void csp_qfifo_wake_up(void) { + const csp_qfifo_t queue_element = {.iface = NULL, .packet = NULL}; + csp_queue_enqueue(qfifo[0], &queue_element, 0); +} diff --git a/Program/libcsp/src/csp_qfifo.h b/Program/libcsp/src/csp_qfifo.h new file mode 100755 index 0000000..bf9214a --- /dev/null +++ b/Program/libcsp/src/csp_qfifo.h @@ -0,0 +1,58 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CSP_QFIFO_H_ +#define CSP_QFIFO_H_ + +#include + +#if (CSP_USE_RDP) +#define FIFO_TIMEOUT 100 //! If RDP is enabled, the router needs to awake some times to check timeouts +#else +#define FIFO_TIMEOUT CSP_MAX_TIMEOUT //! If no RDP, the router can sleep untill data arrives +#endif + +/** + * Init FIFO/QOS queues + * @return CSP_ERR type + */ +int csp_qfifo_init(void); + +void csp_qfifo_free_resources(void); + +typedef struct { + csp_iface_t * iface; + csp_packet_t * packet; +} csp_qfifo_t; + +/** + * Read next packet from router input queue + * @param input pointer to router queue item element + * @return CSP_ERR type + */ +int csp_qfifo_read(csp_qfifo_t * input); + +/** + * Wake up any task (e.g. router) waiting on messages. + * For testing. + */ +void csp_qfifo_wake_up(void); + +#endif /* CSP_QFIFO_H_ */ diff --git a/Program/libcsp/src/csp_route.c b/Program/libcsp/src/csp_route.c new file mode 100755 index 0000000..6e919c2 --- /dev/null +++ b/Program/libcsp/src/csp_route.c @@ -0,0 +1,337 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "csp_init.h" +#include "csp_port.h" +#include "csp_conn.h" +#include "csp_io.h" +#include "csp_promisc.h" +#include "csp_qfifo.h" +#include "csp_dedup.h" +#include "transport/csp_transport.h" + +/** + * Check supported packet options + * @param iface pointer to incoming interface + * @param packet pointer to packet + * @return CSP_ERR_NONE is all options are supported, CSP_ERR_NOTSUP if not + */ +static int csp_route_check_options(csp_iface_t *iface, csp_packet_t *packet) +{ +#if (CSP_USE_XTEA == 0) + /* Drop XTEA packets */ + if (packet->id.flags & CSP_FXTEA) { + csp_log_error("Received XTEA encrypted packet, but CSP was compiled without XTEA support. Discarding packet"); + iface->autherr++; + return CSP_ERR_NOTSUP; + } +#endif + +#if (CSP_USE_HMAC == 0) + /* Drop HMAC packets */ + if (packet->id.flags & CSP_FHMAC) { + csp_log_error("Received packet with HMAC, but CSP was compiled without HMAC support. Discarding packet"); + iface->autherr++; + return CSP_ERR_NOTSUP; + } +#endif + +#if (CSP_USE_RDP == 0) + /* Drop RDP packets */ + if (packet->id.flags & CSP_FRDP) { + csp_log_error("Received RDP packet, but CSP was compiled without RDP support. Discarding packet"); + iface->rx_error++; + return CSP_ERR_NOTSUP; + } +#endif + return CSP_ERR_NONE; +} + +/** + * Helper function to decrypt, check auth and CRC32 + * @param security_opts either socket_opts or conn_opts + * @param iface pointer to incoming interface + * @param packet pointer to packet + * @return #CSP_ERR_NONE on success, otherwise an error code. + */ +static int csp_route_security_check(uint32_t security_opts, csp_iface_t * iface, csp_packet_t * packet) { + +#if (CSP_USE_XTEA) + /* XTEA encrypted packet */ + if (packet->id.flags & CSP_FXTEA) { + /* Decrypt data */ + if (csp_xtea_decrypt_packet(packet) != CSP_ERR_NONE) { + csp_log_error("XTEA Decryption failed! Discarding packet"); + iface->autherr++; + return CSP_ERR_XTEA; + } + } else if (security_opts & CSP_SO_XTEAREQ) { + csp_log_warn("Received packet without XTEA encryption. Discarding packet"); + iface->autherr++; + return CSP_ERR_XTEA; + } +#endif + + /* CRC32 verified packet */ + if (packet->id.flags & CSP_FCRC32) { +#if (CSP_USE_CRC32) + /* Verify CRC32 (does not include header for backwards compatability with csp1.x) */ + if (csp_crc32_verify(packet, false) != CSP_ERR_NONE) { + csp_log_error("CRC32 verification error! Discarding packet"); + iface->rx_error++; + return CSP_ERR_CRC32; + } +#else + /* No CRC32 validation - but size must be checked and adjusted */ + if (packet->length < sizeof(uint32_t)) { + csp_log_error("CRC32 verification error! Discarding packet"); + iface->rx_error++; + return CSP_ERR_CRC32; + } + packet->length -= sizeof(uint32_t); +#endif + } else if (security_opts & CSP_SO_CRC32REQ) { + csp_log_warn("Received packet with CRC32, but CSP was compiled without CRC32 support. Accepting packet"); + } + +#if (CSP_USE_HMAC) + /* HMAC authenticated packet */ + if (packet->id.flags & CSP_FHMAC) { + /* Verify HMAC (does not include header for backwards compatability with csp1.x) */ + if (csp_hmac_verify(packet, false) != CSP_ERR_NONE) { + /* HMAC failed */ + csp_log_error("HMAC verification error! Discarding packet"); + iface->autherr++; + return CSP_ERR_HMAC; + } + } else if (security_opts & CSP_SO_HMACREQ) { + csp_log_warn("Received packet without HMAC. Discarding packet"); + iface->autherr++; + return CSP_ERR_HMAC; + } +#endif + +#if (CSP_USE_RDP) + /* RDP packet */ + if (!(packet->id.flags & CSP_FRDP)) { + if (security_opts & CSP_SO_RDPREQ) { + csp_log_warn("Received packet without RDP header. Discarding packet"); + iface->rx_error++; + return CSP_ERR_INVAL; + } + } +#endif + + return CSP_ERR_NONE; + +} + +int csp_route_work(uint32_t timeout) { + + csp_qfifo_t input; + csp_packet_t * packet; + csp_conn_t * conn; + csp_socket_t * socket; + +#if (CSP_USE_RDP) + /* Check connection timeouts (currently only for RDP) */ + csp_conn_check_timeouts(); +#endif + + /* Get next packet to route */ + if (csp_qfifo_read(&input) != CSP_ERR_NONE) { + return CSP_ERR_TIMEDOUT; + } + + packet = input.packet; + if (packet == NULL) { + return CSP_ERR_TIMEDOUT; + } + + csp_log_packet("INP: S %u, D %u, Dp %u, Sp %u, Pr %u, Fl 0x%02X, Sz %"PRIu16" VIA: %s", + packet->id.src, packet->id.dst, packet->id.dport, + packet->id.sport, packet->id.pri, packet->id.flags, packet->length, input.iface->name); + + /* Here there be promiscuous mode */ +#if (CSP_USE_PROMISC) + csp_promisc_add(packet); +#endif + +#if (CSP_USE_DEDUP) + /* Check for duplicates */ + if (csp_dedup_is_duplicate(packet)) { + /* Discard packet */ + csp_log_packet("Duplicate packet discarded"); + input.iface->drop++; + csp_buffer_free(packet); + return CSP_ERR_NONE; + } +#endif + + /* Now we count the message (since its deduplicated) */ + input.iface->rx++; + input.iface->rxbytes += packet->length; + + /* If the message is not to me, route the message to the correct interface */ + if ((packet->id.dst != csp_conf.address) && (packet->id.dst != CSP_BROADCAST_ADDR)) { + + /* Find the destination interface */ + const csp_route_t * ifroute = csp_rtable_find_route(packet->id.dst); + + /* If the message resolves to the input interface, don't loop it back out */ + if ((ifroute == NULL) || ((ifroute->iface == input.iface) && (input.iface->split_horizon_off == 0))) { + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + + /* Otherwise, actually send the message */ + if (csp_send_direct(packet->id, packet, ifroute, 0) != CSP_ERR_NONE) { + csp_log_warn("Router failed to send"); + csp_buffer_free(packet); + } + + /* Next message, please */ + return CSP_ERR_NONE; + } + + /* Discard packets with unsupported options */ + if (csp_route_check_options(input.iface, packet) != CSP_ERR_NONE) { + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + + /* The message is to me, search for incoming socket */ + socket = csp_port_get_socket(packet->id.dport); + + /* If the socket is connection-less, deliver now */ + if (socket && (socket->opts & CSP_SO_CONN_LESS)) { + if (csp_route_security_check(socket->opts, input.iface, packet) < 0) { + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + if (csp_queue_enqueue(socket->socket, &packet, 0) != CSP_QUEUE_OK) { + csp_log_error("Conn-less socket queue full"); + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + return CSP_ERR_NONE; + } + + /* Search for an existing connection */ + conn = csp_conn_find(packet->id.ext, CSP_ID_CONN_MASK); + + /* If this is an incoming packet on a new connection */ + if (conn == NULL) { + + /* Reject packet if no matching socket is found */ + if (!socket) { + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + + /* Run security check on incoming packet */ + if (csp_route_security_check(socket->opts, input.iface, packet) < 0) { + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + + /* New incoming connection accepted */ + csp_id_t idout; + idout.pri = packet->id.pri; + idout.src = csp_conf.address; + + idout.dst = packet->id.src; + idout.dport = packet->id.sport; + idout.sport = packet->id.dport; + idout.flags = packet->id.flags; + + /* Create connection */ + conn = csp_conn_new(packet->id, idout); + + if (!conn) { + csp_log_error("No more connections available"); + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + + /* Store the socket queue and options */ + conn->socket = socket->socket; + conn->opts = socket->opts; + + /* Packet to existing connection */ + } else { + + /* Run security check on incoming packet */ + if (csp_route_security_check(conn->opts, input.iface, packet) < 0) { + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + + } + +#if (CSP_USE_RDP) + /* Pass packet to RDP module */ + if (packet->id.flags & CSP_FRDP) { + bool close_connection = csp_rdp_new_packet(conn, packet); + if (close_connection) { + csp_close(conn); + } + return CSP_ERR_NONE; + } +#endif + + /* Pass packet to UDP module */ + csp_udp_new_packet(conn, packet); + return CSP_ERR_NONE; +} + +static CSP_DEFINE_TASK(csp_task_router) { + + /* Here there be routing */ + while (1) { + csp_route_work(FIFO_TIMEOUT); + } + + return CSP_TASK_RETURN; + +} + +int csp_route_start_task(unsigned int task_stack_size, unsigned int task_priority) { + + int ret = csp_thread_create(csp_task_router, "RTE", task_stack_size, NULL, task_priority, NULL); + if (ret != 0) { + csp_log_error("Failed to start router task, error: %d", ret); + return ret; + } + + return CSP_ERR_NONE; + +} diff --git a/Program/libcsp/src/csp_service_handler.c b/Program/libcsp/src/csp_service_handler.c new file mode 100755 index 0000000..e020fb8 --- /dev/null +++ b/Program/libcsp/src/csp_service_handler.c @@ -0,0 +1,338 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "csp_init.h" + +#define CSP_RPS_MTU 196 + +/** + * The CSP CMP mempy function is used to, override the function used to + * read/write memory by peek and poke. + */ +#ifdef __AVR__ +static uint32_t wrap_32bit_memcpy(uint32_t to, const uint32_t from, size_t size) { + return (uint32_t) (uintptr_t) memcpy((void *) (uintptr_t) to, (const void *) (uintptr_t) from, size); +} +static csp_memcpy_fnc_t csp_cmp_memcpy_fnc = wrap_32bit_memcpy; +#else +static csp_memcpy_fnc_t csp_cmp_memcpy_fnc = (csp_memcpy_fnc_t) memcpy; +#endif + + +void csp_cmp_set_memcpy(csp_memcpy_fnc_t fnc) { + csp_cmp_memcpy_fnc = fnc; +} + +static int do_cmp_ident(struct csp_cmp_message *cmp) { + + /* Copy revision */ + strncpy(cmp->ident.revision, csp_conf.revision, CSP_CMP_IDENT_REV_LEN); + cmp->ident.revision[CSP_CMP_IDENT_REV_LEN - 1] = '\0'; + + /* Copy compilation date */ + strncpy(cmp->ident.date, __DATE__, CSP_CMP_IDENT_DATE_LEN); + cmp->ident.date[CSP_CMP_IDENT_DATE_LEN - 1] = '\0'; + + /* Copy compilation time */ + strncpy(cmp->ident.time, __TIME__, CSP_CMP_IDENT_TIME_LEN); + cmp->ident.time[CSP_CMP_IDENT_TIME_LEN - 1] = '\0'; + + /* Copy hostname */ + strncpy(cmp->ident.hostname, csp_conf.hostname, CSP_HOSTNAME_LEN); + cmp->ident.hostname[CSP_HOSTNAME_LEN - 1] = '\0'; + + /* Copy model name */ + strncpy(cmp->ident.model, csp_conf.model, CSP_MODEL_LEN); + cmp->ident.model[CSP_MODEL_LEN - 1] = '\0'; + + return CSP_ERR_NONE; + +} + +static int do_cmp_route_set(struct csp_cmp_message *cmp) { + + csp_iface_t *ifc = csp_iflist_get_by_name(cmp->route_set.interface); + if (ifc == NULL) { + return CSP_ERR_INVAL; + } + + if (csp_route_set(cmp->route_set.dest_node, ifc, cmp->route_set.next_hop_via) != CSP_ERR_NONE) { + return CSP_ERR_INVAL; + } + + return CSP_ERR_NONE; + +} + +static int do_cmp_if_stats(struct csp_cmp_message *cmp) { + + csp_iface_t *ifc = csp_iflist_get_by_name(cmp->if_stats.interface); + if (ifc == NULL) + return CSP_ERR_INVAL; + + cmp->if_stats.tx = csp_hton32(ifc->tx); + cmp->if_stats.rx = csp_hton32(ifc->rx); + cmp->if_stats.tx_error = csp_hton32(ifc->tx_error); + cmp->if_stats.rx_error = csp_hton32(ifc->rx_error); + cmp->if_stats.drop = csp_hton32(ifc->drop); + cmp->if_stats.autherr = csp_hton32(ifc->autherr); + cmp->if_stats.frame = csp_hton32(ifc->frame); + cmp->if_stats.txbytes = csp_hton32(ifc->txbytes); + cmp->if_stats.rxbytes = csp_hton32(ifc->rxbytes); + cmp->if_stats.irq = csp_hton32(ifc->irq); + + return CSP_ERR_NONE; +} + +static int do_cmp_peek(struct csp_cmp_message *cmp) { + + cmp->peek.addr = csp_hton32(cmp->peek.addr); + if (cmp->peek.len > CSP_CMP_PEEK_MAX_LEN) + return CSP_ERR_INVAL; + + /* Dangerous, you better know what you are doing */ + csp_cmp_memcpy_fnc((csp_memptr_t) (uintptr_t) cmp->peek.data, (csp_memptr_t) (uintptr_t) cmp->peek.addr, cmp->peek.len); + + return CSP_ERR_NONE; + +} + +static int do_cmp_poke(struct csp_cmp_message *cmp) { + + cmp->poke.addr = csp_hton32(cmp->poke.addr); + if (cmp->poke.len > CSP_CMP_POKE_MAX_LEN) + return CSP_ERR_INVAL; + + /* Extremely dangerous, you better know what you are doing */ + csp_cmp_memcpy_fnc((csp_memptr_t) (uintptr_t) cmp->poke.addr, (csp_memptr_t) (uintptr_t) cmp->poke.data, cmp->poke.len); + + return CSP_ERR_NONE; + +} + +static int do_cmp_clock(struct csp_cmp_message *cmp) { + + csp_timestamp_t clock; + clock.tv_sec = csp_ntoh32(cmp->clock.tv_sec); + clock.tv_nsec = csp_ntoh32(cmp->clock.tv_nsec); + + int res = CSP_ERR_NONE; + if (clock.tv_sec != 0) { + // set time + res = csp_clock_set_time(&clock); + if (res != CSP_ERR_NONE) { + csp_log_warn("csp_clock_set_time(sec=%"PRIu32", nsec=%"PRIu32") failed, error: %d", clock.tv_sec, clock.tv_nsec, res); + } + } + + csp_clock_get_time(&clock); + + cmp->clock.tv_sec = csp_hton32(clock.tv_sec); + cmp->clock.tv_nsec = csp_hton32(clock.tv_nsec); + + return res; + +} + +/* CSP Management Protocol handler */ +static int csp_cmp_handler(csp_conn_t * conn, csp_packet_t * packet) { + + int ret = CSP_ERR_INVAL; + struct csp_cmp_message * cmp = (struct csp_cmp_message *) packet->data; + + /* Ignore everything but requests */ + if (cmp->type != CSP_CMP_REQUEST) + return ret; + + switch (cmp->code) { + case CSP_CMP_IDENT: + ret = do_cmp_ident(cmp); + packet->length = CMP_SIZE(ident); + break; + + case CSP_CMP_ROUTE_SET: + ret = do_cmp_route_set(cmp); + packet->length = CMP_SIZE(route_set); + break; + + case CSP_CMP_IF_STATS: + ret = do_cmp_if_stats(cmp); + packet->length = CMP_SIZE(if_stats); + break; + + case CSP_CMP_PEEK: + ret = do_cmp_peek(cmp); + break; + + case CSP_CMP_POKE: + ret = do_cmp_poke(cmp); + break; + + case CSP_CMP_CLOCK: + ret = do_cmp_clock(cmp); + break; + + default: + ret = CSP_ERR_INVAL; + break; + } + + cmp->type = CSP_CMP_REPLY; + + return ret; +} + +void csp_service_handler(csp_conn_t * conn, csp_packet_t * packet) { + + switch (csp_conn_dport(conn)) { + + case CSP_CMP: + /* Pass to CMP handler */ + if (csp_cmp_handler(conn, packet) != CSP_ERR_NONE) { + csp_buffer_free(packet); + return; + } + break; + + case CSP_PING: + /* A ping means, just echo the packet, so no changes */ + csp_log_info("SERVICE: Ping received"); + break; + + case CSP_PS: { + /* Sanity check on request */ + if ((packet->length != 1) || (packet->data[0] != 0x55)) { + /* Sanity check failed */ + csp_buffer_free(packet); + /* Clear the packet, it has been freed */ + packet = NULL; + break; + } + /* Start by allocating just the right amount of memory */ + int task_list_size = csp_sys_tasklist_size(); + char * pslist = csp_malloc(task_list_size); + /* Check for malloc fail */ + if (pslist == NULL) { + /* Send out the data */ + strcpy((char *)packet->data, "Not enough memory"); + packet->length = strlen((char *)packet->data); + /* Break and let the default handling send packet */ + break; + } + + /* Retrieve the tasklist */ + csp_sys_tasklist(pslist); + int pslen = strnlen(pslist, task_list_size); + + /* Split the potentially very long string into packets */ + int i = 0; + while(i < pslen) { + + /* Allocate packet buffer, if need be */ + if (packet == NULL) + packet = csp_buffer_get(CSP_RPS_MTU); + if (packet == NULL) + break; + + /* Calculate length, either full MTU or the remainder */ + packet->length = (pslen - i > CSP_RPS_MTU) ? CSP_RPS_MTU : (pslen - i); + + /* Send out the data */ + memcpy(packet->data, &pslist[i], packet->length); + i += packet->length; + if (!csp_send(conn, packet, 0)) + csp_buffer_free(packet); + + /* Clear the packet reference when sent */ + packet = NULL; + + } + csp_free(pslist); + break; + } + + case CSP_MEMFREE: { + uint32_t total = csp_sys_memfree(); + + total = csp_hton32(total); + memcpy(packet->data, &total, sizeof(total)); + packet->length = sizeof(total); + + break; + } + + case CSP_REBOOT: { + uint32_t magic_word; + memcpy(&magic_word, packet->data, sizeof(magic_word)); + + magic_word = csp_ntoh32(magic_word); + + /* If the magic word is valid, reboot */ + if (magic_word == CSP_REBOOT_MAGIC) { + csp_sys_reboot(); + } else if (magic_word == CSP_REBOOT_SHUTDOWN_MAGIC) { + csp_sys_shutdown(); + } + + csp_buffer_free(packet); + return; + } + + case CSP_BUF_FREE: { + uint32_t size = csp_buffer_remaining(); + size = csp_hton32(size); + memcpy(packet->data, &size, sizeof(size)); + packet->length = sizeof(size); + break; + } + + case CSP_UPTIME: { + uint32_t time = csp_get_uptime_s(); + time = csp_hton32(time); + memcpy(packet->data, &time, sizeof(time)); + packet->length = sizeof(time); + break; + } + + default: + csp_buffer_free(packet); + return; + } + + if (packet != NULL) { + if (!csp_send(conn, packet, 0)) + csp_buffer_free(packet); + } + +} diff --git a/Program/libcsp/src/csp_services.c b/Program/libcsp/src/csp_services.c new file mode 100755 index 0000000..9c29861 --- /dev/null +++ b/Program/libcsp/src/csp_services.c @@ -0,0 +1,254 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +#include +#include +#include + +int csp_ping(uint8_t node, uint32_t timeout, unsigned int size, uint8_t conn_options) { + + unsigned int i; + uint32_t start, time, status = 0; + + /* Counter */ + start = csp_get_ms(); + + /* Open connection */ + csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, node, CSP_PING, timeout, conn_options); + if (conn == NULL) + return -1; + + /* Prepare data */ + csp_packet_t * packet = csp_buffer_get(size); + if (packet == NULL) + goto out; + + /* Set data to increasing numbers */ + packet->length = size; + for (i = 0; i < size; i++) + packet->data[i] = i; + + /* Try to send frame */ + if (!csp_send(conn, packet, 0)) + goto out; + + /* Read incoming frame */ + packet = csp_read(conn, timeout); + if (packet == NULL) + goto out; + + /* Ensure that the data was actually echoed */ + for (i = 0; i < size; i++) { + if (packet->data[i] != i % (0xff + 1)) { + goto out; + } + } + status = 1; + +out: + /* Clean up */ + csp_buffer_free(packet); + csp_close(conn); + + /* We have a reply */ + time = (csp_get_ms() - start); + + if (status) { + return time; + } + + return -1; +} + +void csp_ping_noreply(uint8_t node) { + + /* Prepare data */ + csp_packet_t * packet = csp_buffer_get(1); + if (packet == NULL) + return; + + /* Open connection */ + csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, node, CSP_PING, 0, 0); + if (conn == NULL) { + csp_buffer_free(packet); + return; + } + + packet->data[0] = 0x55; + packet->length = 1; + + printf("Ping ignore reply node %u.\r\n", (unsigned int) node); + + /* Try to send frame */ + if (!csp_send(conn, packet, 0)) + csp_buffer_free(packet); + + csp_close(conn); + +} + +void csp_reboot(uint8_t node) { + uint32_t magic_word = csp_hton32(CSP_REBOOT_MAGIC); + csp_transaction(CSP_PRIO_NORM, node, CSP_REBOOT, 0, &magic_word, sizeof(magic_word), NULL, 0); +} + +void csp_shutdown(uint8_t node) { + uint32_t magic_word = csp_hton32(CSP_REBOOT_SHUTDOWN_MAGIC); + csp_transaction(CSP_PRIO_NORM, node, CSP_REBOOT, 0, &magic_word, sizeof(magic_word), NULL, 0); +} + +void csp_ps(uint8_t node, uint32_t timeout) { + + /* Open connection */ + csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, node, CSP_PS, 0, 0); + if (conn == NULL) { + return; + } + + /* Prepare data */ + csp_packet_t * packet = csp_buffer_get(95); + + /* Check malloc */ + if (packet == NULL) { + goto out; + } + + packet->data[0] = 0x55; + packet->length = 1; + + printf("PS node %u: \r\n", node); + + /* Try to send frame */ + if (!csp_send(conn, packet, 0)) { + goto out; + } + + while(1) { + + /* Read incoming frame */ + packet = csp_read(conn, timeout); + if (packet == NULL) { + break; + } + + /* We have a reply, ensure data is 0 (zero) termianted */ + const unsigned int length = (packet->length < csp_buffer_data_size()) ? packet->length : (csp_buffer_data_size() - 1); + packet->data[length] = 0; + printf("%s", packet->data); + + /* Each packet from csp_read must to be freed by user */ + csp_buffer_free(packet); + } + + printf("\r\n"); + + /* Clean up */ +out: + csp_buffer_free(packet); + csp_close(conn); + +} + +int csp_get_memfree(uint8_t node, uint32_t timeout, uint32_t * size) { + + int status = csp_transaction(CSP_PRIO_NORM, node, CSP_MEMFREE, timeout, NULL, 0, size, sizeof(*size)); + if (status == sizeof(*size)) { + *size = csp_ntoh32(*size); + return CSP_ERR_NONE; + } + *size = 0; + return CSP_ERR_TIMEDOUT; + +} + +void csp_memfree(uint8_t node, uint32_t timeout) { + + uint32_t memfree; + int err = csp_get_memfree(node, timeout, &memfree); + if (err == CSP_ERR_NONE) { + printf("Free Memory at node %u is %"PRIu32" bytes\r\n", node, memfree); + } else { + printf("Network error\r\n"); + } + +} + +int csp_get_buf_free(uint8_t node, uint32_t timeout, uint32_t * size) { + + int status = csp_transaction(CSP_PRIO_NORM, node, CSP_BUF_FREE, timeout, NULL, 0, size, sizeof(*size)); + if (status == sizeof(*size)) { + *size = csp_ntoh32(*size); + return CSP_ERR_NONE; + } + *size = 0; + return CSP_ERR_TIMEDOUT; + +} + +void csp_buf_free(uint8_t node, uint32_t timeout) { + + uint32_t size; + int err = csp_get_buf_free(node, timeout, &size); + if (err == CSP_ERR_NONE) { + printf("Free buffers at node %u is %"PRIu32"\r\n", node, size); + } else { + printf("Network error\r\n"); + } + +} + +int csp_get_uptime(uint8_t node, uint32_t timeout, uint32_t * uptime) { + + int status = csp_transaction(CSP_PRIO_NORM, node, CSP_UPTIME, timeout, NULL, 0, uptime, sizeof(*uptime)); + if (status == sizeof(*uptime)) { + *uptime = csp_ntoh32(*uptime); + return CSP_ERR_NONE; + } + *uptime = 0; + return CSP_ERR_TIMEDOUT; +} + +void csp_uptime(uint8_t node, uint32_t timeout) { + + uint32_t uptime; + int err = csp_get_uptime(node, timeout, &uptime); + if (err == CSP_ERR_NONE) { + printf("Uptime of node %u is %"PRIu32" s\r\n", node, uptime); + } else { + printf("Network error\r\n"); + } + +} + +int csp_cmp(uint8_t node, uint32_t timeout, uint8_t code, int msg_size, struct csp_cmp_message * msg) { + msg->type = CSP_CMP_REQUEST; + msg->code = code; + int status = csp_transaction(CSP_PRIO_NORM, node, CSP_CMP, timeout, msg, msg_size, msg, msg_size); + if (status == 0) { + return CSP_ERR_TIMEDOUT; + } + + return CSP_ERR_NONE; +} + diff --git a/Program/libcsp/src/csp_sfp.c b/Program/libcsp/src/csp_sfp.c new file mode 100755 index 0000000..54e3504 --- /dev/null +++ b/Program/libcsp/src/csp_sfp.c @@ -0,0 +1,229 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include + +#include "csp_conn.h" + +typedef struct __attribute__((__packed__)) { + uint32_t offset; + uint32_t totalsize; +} sfp_header_t; + +/** + * SFP Headers: + * The following functions are helper functions that handles the extra SFP + * information that needs to be appended to all data packets. + */ +static inline sfp_header_t * csp_sfp_header_add(csp_packet_t * packet) { + + sfp_header_t * header = (sfp_header_t *) &packet->data[packet->length]; + packet->length += sizeof(*header); + return header; +} + +static inline sfp_header_t * csp_sfp_header_remove(csp_packet_t * packet) { + + if ((packet->id.flags & CSP_FFRAG) == 0) { + return NULL; + } + sfp_header_t * header; + if (packet->length < sizeof(*header)) { + return NULL; + } + header = (sfp_header_t *) &packet->data[packet->length - sizeof(*header)]; + packet->length -= sizeof(*header); + + header->offset = csp_ntoh32(header->offset); + header->totalsize = csp_ntoh32(header->totalsize); + + if (header->offset > header->totalsize) { + return NULL; + } + + return header; +} + +int csp_sfp_send_own_memcpy(csp_conn_t * conn, const void * data, unsigned int totalsize, unsigned int mtu, uint32_t timeout, csp_memcpy_fnc_t memcpyfcn) { + if (mtu == 0) { + return CSP_ERR_INVAL; + } + + unsigned int count = 0; + while(count < totalsize) { + + sfp_header_t * sfp_header; + + /* Allocate packet */ + csp_packet_t * packet = csp_buffer_get(mtu + sizeof(*sfp_header)); + if (packet == NULL) { + return CSP_ERR_NOMEM; + } + + /* Calculate sending size */ + unsigned int size = totalsize - count; + if (size > mtu) { + size = mtu; + } + + /* Print debug */ + csp_log_protocol("%s: %d:%d, sending at %p size %u", + __FUNCTION__, csp_conn_src(conn), csp_conn_sport(conn), + ((uint8_t*)data) + count, size); + + /* Copy data */ + (memcpyfcn)((csp_memptr_t)(uintptr_t)packet->data, (csp_memptr_t)(uintptr_t)(((uint8_t*)data) + count), size); + packet->length = size; + + /* Set fragment flag */ + conn->idout.flags |= CSP_FFRAG; + + /* Add SFP header */ + sfp_header = csp_sfp_header_add(packet); // no check, because buffer was allocated with extra size. + sfp_header->totalsize = csp_hton32(totalsize); + sfp_header->offset = csp_hton32(count); + + /* Send data */ + if (!csp_send(conn, packet, timeout)) { + csp_buffer_free(packet); + return CSP_ERR_TX; + } + + /* Increment count */ + count += size; + + } + + return CSP_ERR_NONE; + +} + +int csp_sfp_recv_fp(csp_conn_t * conn, void ** return_data, int * return_datasize, uint32_t timeout, csp_packet_t * first_packet) { + + *return_data = NULL; /* Allow caller to assume csp_free() can always be called when dataout is non-NULL */ + *return_datasize = 0; + + /* Get first packet from user, or from connection */ + csp_packet_t * packet; + if (first_packet == NULL) { + packet = csp_read(conn, timeout); + if (packet == NULL) { + return CSP_ERR_TIMEDOUT; + } + } else { + packet = first_packet; + } + + uint8_t * data = NULL; + uint32_t datasize = 0; + uint32_t data_offset = 0; + int error = CSP_ERR_TIMEDOUT; + do { + /* Read SFP header */ + sfp_header_t * sfp_header = csp_sfp_header_remove(packet); + if (sfp_header == NULL) { + csp_log_warn("%s: %u:%u, invalid message, id.flags: 0x%x, length: %u", + __FUNCTION__, packet->id.src, packet->id.sport, + packet->id.flags, packet->length); + csp_buffer_free(packet); + + error = CSP_ERR_SFP; + goto error; + } + + csp_log_protocol("%s: %u:%u, fragment %"PRIu32"/%"PRIu32, + __FUNCTION__, packet->id.src, packet->id.sport, + sfp_header->offset + packet->length, sfp_header->totalsize); + + /* Consistency check */ + if (sfp_header->offset != data_offset) { + csp_log_warn("%s: %u:%u, invalid message, offset %"PRIu32" (expected %"PRIu32"), length: %u, totalsize %"PRIu32, + __FUNCTION__, packet->id.src, packet->id.sport, + sfp_header->offset, data_offset, packet->length, sfp_header->totalsize); + csp_buffer_free(packet); + + error = CSP_ERR_SFP; + goto error; + } + + /* Allocate memory */ + if (data == NULL) { + datasize = sfp_header->totalsize; + data = csp_malloc(datasize); + if (data == NULL) { + csp_log_warn("%s: %u:%u, csp_malloc(%"PRIu32") failed", + __FUNCTION__, packet->id.src, packet->id.sport, + datasize); + csp_buffer_free(packet); + + error = CSP_ERR_NOMEM; + goto error; + } + } + + /* Consistency check */ + if (((data_offset + packet->length) > datasize) || (datasize != sfp_header->totalsize)) { + csp_log_warn("%s: %u:%u, invalid size, sfp.offset: %"PRIu32", length: %u, total: %"PRIu32" / %"PRIu32"", + __FUNCTION__, packet->id.src, packet->id.sport, + sfp_header->offset, packet->length, datasize, sfp_header->totalsize); + csp_buffer_free(packet); + + error = CSP_ERR_SFP; + goto error; + } + + /* Copy data to output */ + memcpy(data + data_offset, packet->data, packet->length); + data_offset += packet->length; + + if (data_offset >= datasize) { + // transfer complete + csp_buffer_free(packet); + + *return_data = data; // must be freed by csp_free() + *return_datasize = datasize; + return CSP_ERR_NONE; + } + + /* Consistency check */ + if (packet->length == 0) { + csp_log_warn("%s: %u:%u, invalid size, sfp.offset: %"PRIu32", length: %u, total: %"PRIu32" / %"PRIu32"", + __FUNCTION__, packet->id.src, packet->id.sport, + sfp_header->offset, packet->length, datasize, sfp_header->totalsize); + csp_buffer_free(packet); + + error = CSP_ERR_SFP; + goto error; + } + + csp_buffer_free(packet); + + } while((packet = csp_read(conn, timeout)) != NULL); + +error: + csp_free(data); + return error; + +} diff --git a/Program/libcsp/src/drivers/can/can_socketcan.c b/Program/libcsp/src/drivers/can/can_socketcan.c new file mode 100755 index 0000000..5a554e3 --- /dev/null +++ b/Program/libcsp/src/drivers/can/can_socketcan.c @@ -0,0 +1,237 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if (CSP_HAVE_LIBSOCKETCAN) +#include +#endif + +#include +#include + +// CAN interface data, state, etc. +typedef struct { + char name[CSP_IFLIST_NAME_MAX + 1]; + csp_iface_t iface; + csp_can_interface_data_t ifdata; + pthread_t rx_thread; + int socket; +} can_context_t; + +static void socketcan_free(can_context_t * ctx) { + + if (ctx) { + if (ctx->socket >= 0) { + close(ctx->socket); + } + free(ctx); + } +} + +static void * socketcan_rx_thread(void * arg) +{ + can_context_t * ctx = arg; + + while (1) { + /* Read CAN frame */ + struct can_frame frame; + int nbytes = read(ctx->socket, &frame, sizeof(frame)); + if (nbytes < 0) { + csp_log_error("%s[%s]: read() failed, errno %d: %s", __FUNCTION__, ctx->name, errno, strerror(errno)); + continue; + } + + if (nbytes != sizeof(frame)) { + csp_log_warn("%s[%s]: Read incomplete CAN frame, size: %d, expected: %u bytes", __FUNCTION__, ctx->name, nbytes, (unsigned int) sizeof(frame)); + continue; + } + + /* Drop frames with standard id (CSP uses extended) */ + if (!(frame.can_id & CAN_EFF_FLAG)) { + continue; + } + + /* Drop error and remote frames */ + if (frame.can_id & (CAN_ERR_FLAG | CAN_RTR_FLAG)) { + csp_log_warn("%s[%s]: discarding ERR/RTR/SFF frame", __FUNCTION__, ctx->name); + continue; + } + + /* Strip flags */ + frame.can_id &= CAN_EFF_MASK; + + /* Call RX callbacsp_can_rx_frameck */ + csp_can_rx(&ctx->iface, frame.can_id, frame.data, frame.can_dlc, NULL); + } + + /* We should never reach this point */ + pthread_exit(NULL); +} + + +static int csp_can_tx_frame(void * driver_data, uint32_t id, const uint8_t * data, uint8_t dlc) +{ + if (dlc > 8) { + return CSP_ERR_INVAL; + } + + struct can_frame frame = {.can_id = id | CAN_EFF_FLAG, + .can_dlc = dlc}; + memcpy(frame.data, data, dlc); + + uint32_t elapsed_ms = 0; + can_context_t * ctx = driver_data; + while (write(ctx->socket, &frame, sizeof(frame)) != sizeof(frame)) { + if ((errno != ENOBUFS) || (elapsed_ms >= 1000)) { + csp_log_warn("%s[%s]: write() failed, errno %d: %s", __FUNCTION__, ctx->name, errno, strerror(errno)); + return CSP_ERR_TX; + } + csp_sleep_ms(5); + elapsed_ms += 5; + } + + return CSP_ERR_NONE; +} + +int csp_can_socketcan_open_and_add_interface(const char * device, const char * ifname, int bitrate, bool promisc, csp_iface_t ** return_iface) +{ + if (ifname == NULL) { + ifname = CSP_IF_CAN_DEFAULT_NAME; + } + + csp_log_info("INIT %s: device: [%s], bitrate: %d, promisc: %d", + ifname, device, bitrate, promisc); + +#if (CSP_HAVE_LIBSOCKETCAN) + /* Set interface up - this may require increased OS privileges */ + if (bitrate > 0) { + can_do_stop(device); + can_set_bitrate(device, bitrate); + can_set_restart_ms(device, 100); + can_do_start(device); + } +#endif + + can_context_t * ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + return CSP_ERR_NOMEM; + } + ctx->socket = -1; + + strncpy(ctx->name, ifname, sizeof(ctx->name) - 1); + ctx->iface.name = ctx->name; + ctx->iface.interface_data = &ctx->ifdata; + ctx->iface.driver_data = ctx; + ctx->ifdata.tx_func = csp_can_tx_frame; + + /* Create socket */ + if ((ctx->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { + csp_log_error("%s[%s]: socket() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); + socketcan_free(ctx); + return CSP_ERR_INVAL; + } + + /* Locate interface */ + struct ifreq ifr; + strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); + if (ioctl(ctx->socket, SIOCGIFINDEX, &ifr) < 0) { + csp_log_error("%s[%s]: device: [%s], ioctl() failed, error: %s", __FUNCTION__, ctx->name, device, strerror(errno)); + socketcan_free(ctx); + return CSP_ERR_INVAL; + } + struct sockaddr_can addr; + memset(&addr, 0, sizeof(addr)); + /* Bind the socket to CAN interface */ + addr.can_family = AF_CAN; + addr.can_ifindex = ifr.ifr_ifindex; + if (bind(ctx->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + csp_log_error("%s[%s]: bind() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); + socketcan_free(ctx); + return CSP_ERR_INVAL; + } + + /* Set filter mode */ + if (promisc == false) { + + struct can_filter filter = {.can_id = CFP_MAKE_DST(csp_get_address()), + .can_mask = CFP_MAKE_DST((1 << CFP_HOST_SIZE) - 1)}; + + if (setsockopt(ctx->socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) { + csp_log_error("%s[%s]: setsockopt() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); + socketcan_free(ctx); + return CSP_ERR_INVAL; + } + } + + /* Add interface to CSP */ + int res = csp_can_add_interface(&ctx->iface); + if (res != CSP_ERR_NONE) { + csp_log_error("%s[%s]: csp_can_add_interface() failed, error: %d", __FUNCTION__, ctx->name, res); + socketcan_free(ctx); + return res; + } + + /* Create receive thread */ + if (pthread_create(&ctx->rx_thread, NULL, socketcan_rx_thread, ctx) != 0) { + csp_log_error("%s[%s]: pthread_create() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); + //socketcan_free(ctx); // we already added it to CSP (no way to remove it) + return CSP_ERR_NOMEM; + } + + if (return_iface) { + *return_iface = &ctx->iface; + } + + return CSP_ERR_NONE; +} + +csp_iface_t * csp_can_socketcan_init(const char * device, int bitrate, bool promisc) +{ + csp_iface_t * return_iface; + int res = csp_can_socketcan_open_and_add_interface(device, CSP_IF_CAN_DEFAULT_NAME, bitrate, promisc, &return_iface); + return (res == CSP_ERR_NONE) ? return_iface : NULL; +} + +int csp_can_socketcan_stop(csp_iface_t *iface) +{ + can_context_t * ctx = iface->driver_data; + + int error = pthread_cancel(ctx->rx_thread); + if (error != 0) { + csp_log_error("%s[%s]: pthread_cancel() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); + return CSP_ERR_DRIVER; + } + error = pthread_join(ctx->rx_thread, NULL); + if (error != 0) { + csp_log_error("%s[%s]: pthread_join() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); + return CSP_ERR_DRIVER; + } + socketcan_free(ctx); + return CSP_ERR_NONE; +} diff --git a/Program/libcsp/src/drivers/usart/usart_kiss.c b/Program/libcsp/src/drivers/usart/usart_kiss.c new file mode 100755 index 0000000..c57fae8 --- /dev/null +++ b/Program/libcsp/src/drivers/usart/usart_kiss.c @@ -0,0 +1,86 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +#include +#include +#include + +typedef struct { + char name[CSP_IFLIST_NAME_MAX + 1]; + csp_iface_t iface; + csp_kiss_interface_data_t ifdata; + csp_usart_fd_t fd; +} kiss_context_t; + +static int kiss_driver_tx(void *driver_data, const unsigned char * data, size_t data_length) { + + kiss_context_t * ctx = driver_data; + if (csp_usart_write(ctx->fd, data, data_length) == (int) data_length) { + return CSP_ERR_NONE; + } + return CSP_ERR_TX; +} + +static void kiss_driver_rx(void * user_data, uint8_t * data, size_t data_size, void * pxTaskWoken) { + + kiss_context_t * ctx = user_data; + csp_kiss_rx(&ctx->iface, data, data_size, NULL); +} + +int csp_usart_open_and_add_kiss_interface(const csp_usart_conf_t *conf, const char * ifname, csp_iface_t ** return_iface) { + + if (ifname == NULL) { + ifname = CSP_IF_KISS_DEFAULT_NAME; + } + + csp_log_info("INIT %s: device: [%s], bitrate: %d", + ifname, conf->device, conf->baudrate); + + kiss_context_t * ctx = csp_calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + return CSP_ERR_NOMEM; + } + + strncpy(ctx->name, ifname, sizeof(ctx->name) - 1); + ctx->iface.name = ctx->name; + ctx->iface.driver_data = ctx; + ctx->iface.interface_data = &ctx->ifdata; + ctx->ifdata.tx_func = kiss_driver_tx; +#if (CSP_WINDOWS) + ctx->fd = NULL; +#else + ctx->fd = -1; +#endif + + int res = csp_kiss_add_interface(&ctx->iface); + if (res == CSP_ERR_NONE) { + res = csp_usart_open(conf, kiss_driver_rx, ctx, &ctx->fd); + } + + if (return_iface) { + *return_iface = &ctx->iface; + } + + return res; +} diff --git a/Program/libcsp/src/drivers/usart/usart_linux.c b/Program/libcsp/src/drivers/usart/usart_linux.c new file mode 100755 index 0000000..6196a6a --- /dev/null +++ b/Program/libcsp/src/drivers/usart/usart_linux.c @@ -0,0 +1,271 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef struct { + csp_usart_callback_t rx_callback; + void * user_data; + csp_usart_fd_t fd; + csp_thread_handle_t rx_thread; +} usart_context_t; + +static void * usart_rx_thread(void * arg) { + + usart_context_t * ctx = arg; + const unsigned int CBUF_SIZE = 400; + uint8_t * cbuf = malloc(CBUF_SIZE); + + // Receive loop + while (1) { + int length = read(ctx->fd, cbuf, CBUF_SIZE); + if (length <= 0) { + csp_log_error("%s: read() failed, returned: %d", __FUNCTION__, length); + exit(1); + } + ctx->rx_callback(ctx->user_data, cbuf, length, NULL); + } + return NULL; +} + +#if (0) // Unused function and no prototype in public heaaders +int getbaud(int ifd) { + struct termios termAttr; + int inputSpeed = -1; + speed_t baudRate; + tcgetattr(ifd, &termAttr); + /* Get the input speed. */ + baudRate = cfgetispeed(&termAttr); + switch (baudRate) { + case B0: + inputSpeed = 0; + break; + case B50: + inputSpeed = 50; + break; + case B110: + inputSpeed = 110; + break; + case B134: + inputSpeed = 134; + break; + case B150: + inputSpeed = 150; + break; + case B200: + inputSpeed = 200; + break; + case B300: + inputSpeed = 300; + break; + case B600: + inputSpeed = 600; + break; + case B1200: + inputSpeed = 1200; + break; + case B1800: + inputSpeed = 1800; + break; + case B2400: + inputSpeed = 2400; + break; + case B4800: + inputSpeed = 4800; + break; + case B9600: + inputSpeed = 9600; + break; + case B19200: + inputSpeed = 19200; + break; + case B38400: + inputSpeed = 38400; + break; + case B57600: + inputSpeed = 57600; + break; + case B115200: + inputSpeed = 115200; + break; + case B230400: + inputSpeed = 230400; + break; +#if (CSP_MACOSX == 0) + case B460800: + inputSpeed = 460800; + break; + case B500000: + inputSpeed = 500000; + break; + case B576000: + inputSpeed = 576000; + break; + case B921600: + inputSpeed = 921600; + break; + case B1000000: + inputSpeed = 1000000; + break; + case B1152000: + inputSpeed = 1152000; + break; + case B1500000: + inputSpeed = 1500000; + break; + case B2000000: + inputSpeed = 2000000; + break; + case B2500000: + inputSpeed = 2500000; + break; + case B3000000: + inputSpeed = 3000000; + break; + case B3500000: + inputSpeed = 3500000; + break; + case B4000000: + inputSpeed = 4000000; + break; +#endif + } + + return inputSpeed; + +} +#endif + +int csp_usart_write(csp_usart_fd_t fd, const void * data, size_t data_length) { + + if (fd >= 0) { + int res = write(fd, data, data_length); + if (res >= 0) { + return res; + } + } + return CSP_ERR_TX; // best matching CSP error code. + +} + +int csp_usart_open(const csp_usart_conf_t *conf, csp_usart_callback_t rx_callback, void * user_data, csp_usart_fd_t * return_fd) { + + int brate = 0; + switch(conf->baudrate) { + case 4800: brate=B4800; break; + case 9600: brate=B9600; break; + case 19200: brate=B19200; break; + case 38400: brate=B38400; break; + case 57600: brate=B57600; break; + case 115200: brate=B115200; break; + case 230400: brate=B230400; break; +#if (CSP_MACOSX == 0) + case 460800: brate=B460800; break; + case 500000: brate=B500000; break; + case 576000: brate=B576000; break; + case 921600: brate=B921600; break; + case 1000000: brate=B1000000; break; + case 1152000: brate=B1152000; break; + case 1500000: brate=B1500000; break; + case 2000000: brate=B2000000; break; + case 2500000: brate=B2500000; break; + case 3000000: brate=B3000000; break; + case 3500000: brate=B3500000; break; + case 4000000: brate=B4000000; break; +#endif + default: + csp_log_error("%s: Unsupported baudrate: %u", __FUNCTION__, conf->baudrate); + return CSP_ERR_INVAL; + } + + int fd = open(conf->device, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (fd < 0) { + csp_log_error("%s: failed to open device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); + return CSP_ERR_INVAL; + } + + struct termios options; + tcgetattr(fd, &options); + cfsetispeed(&options, brate); + cfsetospeed(&options, brate); + options.c_cflag |= (CLOCAL | CREAD); + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + options.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); + options.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON); + options.c_oflag &= ~(OCRNL | ONLCR | ONLRET | ONOCR | OFILL | OPOST); + options.c_cc[VTIME] = 0; + options.c_cc[VMIN] = 1; + /* tcsetattr() succeeds if just one attribute was changed, should read back attributes and check all has been changed */ + if (tcsetattr(fd, TCSANOW, &options) != 0) { + csp_log_error("%s: Failed to set attributes on device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); + close(fd); + return CSP_ERR_DRIVER; + } + fcntl(fd, F_SETFL, 0); + + /* Flush old transmissions */ + if (tcflush(fd, TCIOFLUSH) != 0) { + csp_log_error("%s: Error flushing device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); + close(fd); + return CSP_ERR_DRIVER; + } + + usart_context_t * ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + csp_log_error("%s: Error allocating context, device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); + close(fd); + return CSP_ERR_NOMEM; + } + ctx->rx_callback = rx_callback; + ctx->user_data = user_data; + ctx->fd = fd; + + if (rx_callback) { + if (csp_thread_create(usart_rx_thread, "usart_rx", 0, ctx, 0, &ctx->rx_thread) != CSP_ERR_NONE) { + csp_log_error("%s: csp_thread_create() failed to create Rx thread for device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); + free(ctx); + close(fd); + return CSP_ERR_NOMEM; + } + } + + if (return_fd) { + *return_fd = fd; + } + + return CSP_ERR_NONE; +} diff --git a/Program/libcsp/src/drivers/usart/usart_windows.c b/Program/libcsp/src/drivers/usart/usart_windows.c new file mode 100755 index 0000000..ff59ab7 --- /dev/null +++ b/Program/libcsp/src/drivers/usart/usart_windows.c @@ -0,0 +1,173 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include +#include + +#include +#include +#include + +typedef struct { + csp_usart_callback_t rx_callback; + void * user_data; + csp_usart_fd_t fd; + HANDLE rx_thread; + LONG isListening; +} usart_context_t; + +static int openPort(const char * device, csp_usart_fd_t * return_fd) { + + *return_fd = CreateFileA(device, + GENERIC_READ|GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (*return_fd == INVALID_HANDLE_VALUE) { + csp_log_error("Failed to open port: [%s], error: %lu", device, GetLastError()); + return CSP_ERR_INVAL; + } + + return CSP_ERR_NONE; +} + +static int configurePort(csp_usart_fd_t fd, const csp_usart_conf_t * conf) { + + DCB portSettings = {0}; + portSettings.DCBlength = sizeof(portSettings); + if(!GetCommState(fd, &portSettings) ) { + csp_log_error("Could not get default settings for open COM port, error: %lu", GetLastError()); + return CSP_ERR_INVAL; + } + portSettings.BaudRate = conf->baudrate; + portSettings.Parity = conf->paritysetting; + portSettings.StopBits = conf->stopbits; + portSettings.fParity = conf->checkparity; + portSettings.fBinary = TRUE; + portSettings.ByteSize = conf->databits; + if (!SetCommState(fd, &portSettings)) { + csp_log_error("Could not configure COM port, error: %lu", GetLastError()); + return CSP_ERR_INVAL; + } + + return CSP_ERR_NONE; +} + +static int setPortTimeouts(csp_usart_fd_t fd) { + + COMMTIMEOUTS timeouts = {0}; + + if (!GetCommTimeouts(fd, &timeouts)) { + csp_log_error("Error gettings current timeout settings, error: %lu", GetLastError()); + return CSP_ERR_INVAL; + } + + timeouts.ReadIntervalTimeout = 5; + timeouts.ReadTotalTimeoutMultiplier = 1; + timeouts.ReadTotalTimeoutConstant = 5; + timeouts.WriteTotalTimeoutMultiplier = 1; + timeouts.WriteTotalTimeoutConstant = 5; + + if(!SetCommTimeouts(fd, &timeouts)) { + csp_log_error("Error setting timeout settings, error: %lu", GetLastError()); + return CSP_ERR_INVAL; + } + + return CSP_ERR_NONE; +} + +static unsigned WINAPI usart_rx_thread(void* params) { + + usart_context_t * ctx = params; + DWORD eventStatus; + uint8_t cbuf[100]; + DWORD bytesRead; + SetCommMask(ctx->fd, EV_RXCHAR); + + while (ctx->isListening) { + WaitCommEvent(ctx->fd, &eventStatus, NULL); + if (eventStatus & EV_RXCHAR) { + if (ReadFile(ctx->fd, cbuf, sizeof(cbuf), &bytesRead, NULL)) { + ctx->rx_callback(ctx->user_data, cbuf, bytesRead, NULL); + } else { + csp_log_warn("Error receiving data, error: %lu", GetLastError()); + } + } + } + return 0; +} + +int csp_usart_write(csp_usart_fd_t fd, const void * data, size_t data_length) { + + DWORD bytesActual; + if (!WriteFile(fd, data, data_length, &bytesActual, NULL)) { + return CSP_ERR_TX; + } + if( !FlushFileBuffers(fd) ) { + csp_log_warn("Could not flush write buffer. Code: %lu", GetLastError()); + } + return (int) bytesActual; +} + +int csp_usart_open(const csp_usart_conf_t *conf, csp_usart_callback_t rx_callback, void * user_data, csp_usart_fd_t * return_fd) { + + csp_usart_fd_t fd; + int res = openPort(conf->device, &fd); + if (res != CSP_ERR_NONE) { + return res; + } + + res = configurePort(fd, conf); + if (res != CSP_ERR_NONE) { + CloseHandle(fd); + return res; + } + + res = setPortTimeouts(fd); + if (res) { + CloseHandle(fd); + return res; + } + + usart_context_t * ctx = csp_calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + csp_log_error("%s: Error allocating context, device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); + CloseHandle(fd); + return CSP_ERR_NOMEM; + } + ctx->rx_callback = rx_callback; + ctx->user_data = user_data; + ctx->fd = fd; + ctx->isListening = 1; + + res = csp_thread_create(usart_rx_thread, "usart_rx", 0, ctx, 0, &ctx->rx_thread); + if (res) { + CloseHandle(ctx->fd); + csp_free(ctx); + return res; + } + + return CSP_ERR_NONE; +} diff --git a/Program/libcsp/src/interfaces/csp_if_can.c b/Program/libcsp/src/interfaces/csp_if_can.c new file mode 100755 index 0000000..5ef13e7 --- /dev/null +++ b/Program/libcsp/src/interfaces/csp_if_can.c @@ -0,0 +1,275 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include + +#include +#include +#include + +#include "csp_if_can_pbuf.h" + +/* Max number of bytes per CAN frame */ +#define MAX_BYTES_IN_CAN_FRAME 8 +#define CFP_OVERHEAD (sizeof(csp_id_t) + sizeof(uint16_t)) +#define MAX_CAN_DATA_SIZE (((1 << CFP_REMAIN_SIZE) * MAX_BYTES_IN_CAN_FRAME) - CFP_OVERHEAD) + +/* CFP type */ +enum cfp_frame_t { + /* First CFP fragment of a CSP packet */ + CFP_BEGIN = 0, + /* Remaining CFP fragment(s) of a CSP packet */ + CFP_MORE = 1 +}; + +int csp_can_rx(csp_iface_t *iface, uint32_t id, const uint8_t *data, uint8_t dlc, CSP_BASE_TYPE *task_woken) +{ + /* Test: random packet loss */ + if (0) { + int random = rand(); + if (random < RAND_MAX * 0.00005) { + csp_log_warn("Dropping frame"); + return CSP_ERR_DRIVER; + } + } + + /* Bind incoming frame to a packet buffer */ + csp_can_pbuf_element_t * buf = csp_can_pbuf_find(id, CFP_ID_CONN_MASK, task_woken); + if (buf == NULL) { + if (CFP_TYPE(id) == CFP_BEGIN) { + buf = csp_can_pbuf_new(id, task_woken); + if (buf == NULL) { + //csp_log_warn("No available packet buffer for CAN"); + iface->rx_error++; + return CSP_ERR_NOMEM; + } + } else { + //csp_log_warn("Out of order id 0x%X remain %u", CFP_ID(id), CFP_REMAIN(id)); + iface->frame++; + return CSP_ERR_INVAL; + } + } + + /* Reset frame data offset */ + uint8_t offset = 0; + + switch (CFP_TYPE(id)) { + + case CFP_BEGIN: + + /* Discard packet if DLC is less than CSP id + CSP length fields */ + if (dlc < (sizeof(csp_id_t) + sizeof(uint16_t))) { + //csp_log_warn("Short BEGIN frame received"); + iface->frame++; + csp_can_pbuf_free(buf, task_woken); + break; + } + + /* Check for incomplete frame */ + if (buf->packet != NULL) { + /* Reuse the buffer */ + //csp_log_warn("Incomplete frame"); + iface->frame++; + } else { + /* Get free buffer for frame */ + buf->packet = task_woken ? csp_buffer_get_isr(0) : csp_buffer_get(0); // CSP only supports one size + if (buf->packet == NULL) { + //csp_log_error("Failed to get buffer for CSP_BEGIN packet"); + iface->frame++; + csp_can_pbuf_free(buf, task_woken); + break; + } + } + + /* Copy CSP identifier (header) */ + memcpy(&(buf->packet->id), data, sizeof(buf->packet->id)); + buf->packet->id.ext = csp_ntoh32(buf->packet->id.ext); + + /* Copy CSP length (of data) */ + memcpy(&(buf->packet->length), data + sizeof(csp_id_t), sizeof(buf->packet->length)); + buf->packet->length = csp_ntoh16(buf->packet->length); + + /* Check length against max */ + if ((buf->packet->length > MAX_CAN_DATA_SIZE) || (buf->packet->length > csp_buffer_data_size())) { + iface->rx_error++; + csp_can_pbuf_free(buf, task_woken); + break; + } + + /* Reset RX count */ + buf->rx_count = 0; + + /* Set offset to prevent CSP header from being copied to CSP data */ + offset = sizeof(csp_id_t) + sizeof(uint16_t); + + /* Set remain field - increment to include begin packet */ + buf->remain = CFP_REMAIN(id) + 1; + + /* FALLTHROUGH */ + + case CFP_MORE: + + /* Check 'remain' field match */ + if (CFP_REMAIN(id) != buf->remain - 1) { + //csp_log_error("CAN frame lost in CSP packet"); + csp_can_pbuf_free(buf, task_woken); + iface->frame++; + break; + } + + /* Decrement remaining frames */ + buf->remain--; + + /* Check for overflow */ + if ((buf->rx_count + dlc - offset) > buf->packet->length) { + //csp_log_error("RX buffer overflow"); + iface->frame++; + csp_can_pbuf_free(buf, task_woken); + break; + } + + /* Copy dlc bytes into buffer */ + memcpy(&buf->packet->data[buf->rx_count], data + offset, dlc - offset); + buf->rx_count += dlc - offset; + + /* Check if more data is expected */ + if (buf->rx_count != buf->packet->length) + break; + + /* Data is available */ + csp_qfifo_write(buf->packet, iface, task_woken); + + /* Drop packet buffer reference */ + buf->packet = NULL; + + /* Free packet buffer */ + csp_can_pbuf_free(buf, task_woken); + + break; + + default: + //csp_log_warn("Received unknown CFP message type"); + csp_can_pbuf_free(buf, task_woken); + break; + } + + return CSP_ERR_NONE; +} + +int csp_can_tx(const csp_route_t * ifroute, csp_packet_t *packet) +{ + csp_iface_t * iface = ifroute->iface; + csp_can_interface_data_t * ifdata = iface->interface_data; + + /* Get an unique CFP id - this should be locked to prevent access from multiple tasks */ + const uint32_t ident = ifdata->cfp_frame_id++; + + /* Check protocol's max length - limit is 1 (first) frame + as many frames that can be specified in 'remain' */ + if (packet->length > MAX_CAN_DATA_SIZE) { + return CSP_ERR_TX; + } + + /* Insert destination node/via address into the CFP destination field */ + const uint8_t dest = (ifroute->via != CSP_NO_VIA_ADDRESS) ? ifroute->via : packet->id.dst; + + /* Create CAN identifier */ + uint32_t id = (CFP_MAKE_SRC(packet->id.src) | + CFP_MAKE_DST(dest) | + CFP_MAKE_ID(ident) | + CFP_MAKE_TYPE(CFP_BEGIN) | + CFP_MAKE_REMAIN((packet->length + CFP_OVERHEAD - 1) / MAX_BYTES_IN_CAN_FRAME)); + + /* Calculate first frame data bytes */ + const uint8_t avail = MAX_BYTES_IN_CAN_FRAME - CFP_OVERHEAD; + uint8_t bytes = (packet->length <= avail) ? packet->length : avail; + + /* Copy CSP headers and data */ + const uint32_t csp_id_be = csp_hton32(packet->id.ext); + const uint16_t csp_length_be = csp_hton16(packet->length); + + uint8_t frame_buf[MAX_BYTES_IN_CAN_FRAME]; + memcpy(frame_buf, &csp_id_be, sizeof(csp_id_be)); + memcpy(frame_buf + sizeof(csp_id_be), &csp_length_be, sizeof(csp_length_be)); + memcpy(frame_buf + CFP_OVERHEAD, packet->data, bytes); + + /* Increment tx counter */ + uint16_t tx_count = bytes; + + const csp_can_driver_tx_t tx_func = ifdata->tx_func; + + /* Send first frame */ + if ((tx_func)(iface->driver_data, id, frame_buf, CFP_OVERHEAD + bytes) != CSP_ERR_NONE) { + //csp_log_warn("Failed to send CAN frame in csp_tx_can"); + iface->tx_error++; + return CSP_ERR_DRIVER; + } + + /* Send next frames if not complete */ + while (tx_count < packet->length) { + /* Calculate frame data bytes */ + bytes = (packet->length - tx_count >= MAX_BYTES_IN_CAN_FRAME) ? MAX_BYTES_IN_CAN_FRAME : packet->length - tx_count; + + /* Prepare identifier */ + id = (CFP_MAKE_SRC(packet->id.src) | + CFP_MAKE_DST(dest) | + CFP_MAKE_ID(ident) | + CFP_MAKE_TYPE(CFP_MORE) | + CFP_MAKE_REMAIN((packet->length - tx_count - bytes + MAX_BYTES_IN_CAN_FRAME - 1) / MAX_BYTES_IN_CAN_FRAME)); + + /* Increment tx counter */ + tx_count += bytes; + + /* Send frame */ + if ((tx_func)(iface->driver_data, id, packet->data + tx_count - bytes, bytes) != CSP_ERR_NONE) { + //csp_log_warn("Failed to send CAN frame in Tx callback"); + iface->tx_error++; + return CSP_ERR_DRIVER; + } + } + + csp_buffer_free(packet); + + return CSP_ERR_NONE; +} + +int csp_can_add_interface(csp_iface_t * iface) { + + if ((iface == NULL) || (iface->name == NULL) || (iface->interface_data == NULL)) { + return CSP_ERR_INVAL; + } + + csp_can_interface_data_t * ifdata = iface->interface_data; + if (ifdata->tx_func == NULL) { + return CSP_ERR_INVAL; + } + + if ((iface->mtu == 0) || (iface->mtu > MAX_CAN_DATA_SIZE)) { + iface->mtu = MAX_CAN_DATA_SIZE; + } + + ifdata->cfp_frame_id = 0; + + iface->nexthop = csp_can_tx; + + return csp_iflist_add(iface); +} diff --git a/Program/libcsp/src/interfaces/csp_if_can_pbuf.c b/Program/libcsp/src/interfaces/csp_if_can_pbuf.c new file mode 100755 index 0000000..db65170 --- /dev/null +++ b/Program/libcsp/src/interfaces/csp_if_can_pbuf.c @@ -0,0 +1,93 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "csp_if_can_pbuf.h" + +#include +#include +#include + +/* Number of packet buffer elements */ +#define PBUF_ELEMENTS 5 + +/* Buffer element timeout in ms */ +#define PBUF_TIMEOUT_MS 1000 + +static csp_can_pbuf_element_t csp_can_pbuf[PBUF_ELEMENTS] = {}; + +int csp_can_pbuf_free(csp_can_pbuf_element_t *buf, CSP_BASE_TYPE *task_woken) +{ + /* Free CSP packet */ + if (buf->packet != NULL) { + if (task_woken == NULL) { + csp_buffer_free(buf->packet); + } else { + csp_buffer_free_isr(buf->packet); + } + } + + /* Mark buffer element free */ + buf->packet = NULL; + buf->rx_count = 0; + buf->cfpid = 0; + buf->last_used = 0; + buf->remain = 0; + buf->state = BUF_FREE; + + return CSP_ERR_NONE; +} + +csp_can_pbuf_element_t *csp_can_pbuf_new(uint32_t id, CSP_BASE_TYPE *task_woken) +{ + uint32_t now = (task_woken) ? csp_get_ms_isr() : csp_get_ms(); + + for (int i = 0; i < PBUF_ELEMENTS; i++) { + + /* Perform cleanup in used pbufs */ + if (csp_can_pbuf[i].state == BUF_USED) { + if (now - csp_can_pbuf[i].last_used > PBUF_TIMEOUT_MS) + csp_can_pbuf_free(&csp_can_pbuf[i], task_woken); + } + + if (csp_can_pbuf[i].state == BUF_FREE) { + csp_can_pbuf[i].state = BUF_USED; + csp_can_pbuf[i].cfpid = id; + csp_can_pbuf[i].remain = 0; + csp_can_pbuf[i].last_used = now; + return &csp_can_pbuf[i]; + } + + } + + return NULL; + +} + +csp_can_pbuf_element_t *csp_can_pbuf_find(uint32_t id, uint32_t mask, CSP_BASE_TYPE *task_woken) +{ + for (int i = 0; i < PBUF_ELEMENTS; i++) { + if ((csp_can_pbuf[i].state == BUF_USED) && ((csp_can_pbuf[i].cfpid & mask) == (id & mask))) { + csp_can_pbuf[i].last_used = (task_woken) ? csp_get_ms_isr() : csp_get_ms(); + return &csp_can_pbuf[i]; + } + } + return NULL; +} + diff --git a/Program/libcsp/src/interfaces/csp_if_can_pbuf.h b/Program/libcsp/src/interfaces/csp_if_can_pbuf.h new file mode 100755 index 0000000..155ac8b --- /dev/null +++ b/Program/libcsp/src/interfaces/csp_if_can_pbuf.h @@ -0,0 +1,46 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIB_CSP_SRC_INTERFACES_CSP_IF_CAN_PBUF_H_ +#define LIB_CSP_SRC_INTERFACES_CSP_IF_CAN_PBUF_H_ + +#include + +/* Packet buffers */ +typedef enum { + BUF_FREE = 0, /* Buffer element free */ + BUF_USED = 1, /* Buffer element used */ +} csp_can_pbuf_state_t; + +typedef struct { + uint16_t rx_count; /* Received bytes */ + uint32_t remain; /* Remaining packets */ + uint32_t cfpid; /* Connection CFP identification number */ + csp_packet_t *packet; /* Pointer to packet buffer */ + csp_can_pbuf_state_t state; /* Element state */ + uint32_t last_used; /* Timestamp in ms for last use of buffer */ +} csp_can_pbuf_element_t; + +int csp_can_pbuf_free(csp_can_pbuf_element_t *buf, CSP_BASE_TYPE *task_woken); +csp_can_pbuf_element_t *csp_can_pbuf_new(uint32_t id, CSP_BASE_TYPE *task_woken); +csp_can_pbuf_element_t *csp_can_pbuf_find(uint32_t id, uint32_t mask, CSP_BASE_TYPE *task_woken); +void csp_can_pbuf_cleanup(CSP_BASE_TYPE *task_woken); + +#endif diff --git a/Program/libcsp/src/interfaces/csp_if_i2c.c b/Program/libcsp/src/interfaces/csp_if_i2c.c new file mode 100755 index 0000000..d019014 --- /dev/null +++ b/Program/libcsp/src/interfaces/csp_if_i2c.c @@ -0,0 +1,112 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include +#include + +// Ensure certain fields in the csp_i2c_frame_t matches the fields in the csp_packet_t +CSP_STATIC_ASSERT(offsetof(csp_i2c_frame_t, len) == offsetof(csp_packet_t, length), len_field_misaligned); +CSP_STATIC_ASSERT(offsetof(csp_i2c_frame_t, data) == offsetof(csp_packet_t, id), data_field_misaligned); + +int csp_i2c_tx(const csp_route_t * ifroute, csp_packet_t * packet) { + + /* Cast the CSP packet buffer into an i2c frame */ + csp_i2c_frame_t * frame = (csp_i2c_frame_t *) packet; + + /* Insert destination node into the i2c destination field */ + frame->dest = (ifroute->via != CSP_NO_VIA_ADDRESS) ? ifroute->via : packet->id.dst; + + /* Save the outgoing id in the buffer */ + packet->id.ext = csp_hton32(packet->id.ext); + + /* Add the CSP header to the I2C length field */ + frame->len += sizeof(packet->id); + frame->len_rx = 0; + + /* Some I2C drivers support X number of retries + * CSP don't care about this. If it doesn't work the first + * time, don't use time on it. + */ + frame->retries = 0; + + /* send frame */ + csp_i2c_interface_data_t * ifdata = ifroute->iface->interface_data; + return (ifdata->tx_func)(ifroute->iface->driver_data, frame); + +} + +/** + * When a frame is received, cast it to a csp_packet + * and send it directly to the CSP new packet function. + * Context: ISR only + */ +void csp_i2c_rx(csp_iface_t * iface, csp_i2c_frame_t * frame, void * pxTaskWoken) { + + /* Validate input */ + if (frame == NULL) { + return; + } + + if (frame->len < sizeof(csp_id_t)) { + iface->frame++; + (pxTaskWoken != NULL) ? csp_buffer_free_isr(frame) : csp_buffer_free(frame); + return; + } + + /* Strip the CSP header off the length field before converting to CSP packet */ + frame->len -= sizeof(csp_id_t); + + if (frame->len > csp_buffer_data_size()) { // consistency check, should never happen + iface->rx_error++; + (pxTaskWoken != NULL) ? csp_buffer_free_isr(frame) : csp_buffer_free(frame); + return; + } + + /* Convert the packet from network to host order */ + csp_packet_t * packet = (csp_packet_t *) frame; + packet->id.ext = csp_ntoh32(packet->id.ext); + + /* Receive the packet in CSP */ + csp_qfifo_write(packet, iface, pxTaskWoken); + +} + +int csp_i2c_add_interface(csp_iface_t * iface) { + + if ((iface == NULL) || (iface->name == NULL) || (iface->interface_data == NULL)) { + return CSP_ERR_INVAL; + } + + csp_i2c_interface_data_t * ifdata = iface->interface_data; + if (ifdata->tx_func == NULL) { + return CSP_ERR_INVAL; + } + + const unsigned int max_data_size = csp_buffer_data_size(); + if ((iface->mtu == 0) || (iface->mtu > max_data_size)) { + iface->mtu = max_data_size; + } + + iface->nexthop = csp_i2c_tx; + + return csp_iflist_add(iface); +} diff --git a/Program/libcsp/src/interfaces/csp_if_kiss.c b/Program/libcsp/src/interfaces/csp_if_kiss.c new file mode 100755 index 0000000..ea2e7d9 --- /dev/null +++ b/Program/libcsp/src/interfaces/csp_if_kiss.c @@ -0,0 +1,245 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include + +#include +#include + +#define FEND 0xC0 +#define FESC 0xDB +#define TFEND 0xDC +#define TFESC 0xDD +#define TNC_DATA 0x00 + +int csp_kiss_tx(const csp_route_t * ifroute, csp_packet_t * packet) { + + csp_kiss_interface_data_t * ifdata = ifroute->iface->interface_data; + void * driver = ifroute->iface->driver_data; + + /* Add CRC32 checksum - the MTU setting ensures there are space */ + csp_crc32_append(packet, false); + + /* Lock */ + if (csp_mutex_lock(&ifdata->lock, 1000) != CSP_MUTEX_OK) { + return CSP_ERR_TIMEDOUT; + } + + /* Save the outgoing id in the buffer */ + packet->id.ext = csp_hton32(packet->id.ext); + packet->length += sizeof(packet->id.ext); + + /* Transmit data */ + const unsigned char start[] = {FEND, TNC_DATA}; + const unsigned char esc_end[] = {FESC, TFEND}; + const unsigned char esc_esc[] = {FESC, TFESC}; + const unsigned char * data = (unsigned char *) &packet->id.ext; + ifdata->tx_func(driver, start, sizeof(start)); + for (unsigned int i = 0; i < packet->length; i++, ++data) { + if (*data == FEND) { + ifdata->tx_func(driver, esc_end, sizeof(esc_end)); + continue; + } + if (*data == FESC) { + ifdata->tx_func(driver, esc_esc, sizeof(esc_esc)); + continue; + } + ifdata->tx_func(driver, data, 1); + } + const unsigned char stop[] = {FEND}; + ifdata->tx_func(driver, stop, sizeof(stop)); + + /* Free data */ + csp_buffer_free(packet); + + /* Unlock */ + csp_mutex_unlock(&ifdata->lock); + + return CSP_ERR_NONE; +} + +/** + * Decode received data and eventually route the packet. + */ +void csp_kiss_rx(csp_iface_t * iface, const uint8_t * buf, size_t len, void * pxTaskWoken) { + + csp_kiss_interface_data_t * ifdata = iface->interface_data; + + while (len--) { + + /* Input */ + uint8_t inputbyte = *buf++; + + /* If packet was too long */ + if (ifdata->rx_length > ifdata->max_rx_length) { + //csp_log_warn("KISS RX overflow"); + iface->rx_error++; + ifdata->rx_mode = KISS_MODE_NOT_STARTED; + ifdata->rx_length = 0; + } + + switch (ifdata->rx_mode) { + + case KISS_MODE_NOT_STARTED: + + /* Skip any characters until End char detected */ + if (inputbyte != FEND) { + break; + } + + /* Try to allocate new buffer */ + if (ifdata->rx_packet == NULL) { + ifdata->rx_packet = pxTaskWoken ? csp_buffer_get_isr(0) : csp_buffer_get(0); // CSP only supports one size + } + + /* If no more memory, skip frame */ + if (ifdata->rx_packet == NULL) { + ifdata->rx_mode = KISS_MODE_SKIP_FRAME; + break; + } + + /* Start transfer */ + ifdata->rx_length = 0; + ifdata->rx_mode = KISS_MODE_STARTED; + ifdata->rx_first = true; + break; + + case KISS_MODE_STARTED: + + /* Escape char */ + if (inputbyte == FESC) { + ifdata->rx_mode = KISS_MODE_ESCAPED; + break; + } + + /* End Char */ + if (inputbyte == FEND) { + + /* Accept message */ + if (ifdata->rx_length > 0) { + + /* Check for valid length */ + if (ifdata->rx_length < CSP_HEADER_LENGTH + sizeof(uint32_t)) { + //csp_log_warn("KISS short frame skipped, len: %u", ifdata->rx_length); + iface->rx_error++; + ifdata->rx_mode = KISS_MODE_NOT_STARTED; + break; + } + + /* Count received frame */ + iface->frame++; + + /* The CSP packet length is without the header */ + ifdata->rx_packet->length = ifdata->rx_length - CSP_HEADER_LENGTH; + + /* Convert the packet from network to host order */ + ifdata->rx_packet->id.ext = csp_ntoh32(ifdata->rx_packet->id.ext); + + /* Validate CRC */ + if (csp_crc32_verify(ifdata->rx_packet, false) != CSP_ERR_NONE) { + //csp_log_warn("KISS invalid crc frame skipped, len: %u", ifdata->rx_packet->length); + iface->rx_error++; + ifdata->rx_mode = KISS_MODE_NOT_STARTED; + break; + } + + /* Send back into CSP, notice calling from task so last argument must be NULL! */ + csp_qfifo_write(ifdata->rx_packet, iface, pxTaskWoken); + ifdata->rx_packet = NULL; + ifdata->rx_mode = KISS_MODE_NOT_STARTED; + break; + + } + + /* Break after the end char */ + break; + } + + /* Skip the first char after FEND which is TNC_DATA (0x00) */ + if (ifdata->rx_first) { + ifdata->rx_first = false; + break; + } + + /* Valid data char */ + ((char *) &ifdata->rx_packet->id.ext)[ifdata->rx_length++] = inputbyte; + + break; + + case KISS_MODE_ESCAPED: + + /* Escaped escape char */ + if (inputbyte == TFESC) + ((char *) &ifdata->rx_packet->id.ext)[ifdata->rx_length++] = FESC; + + /* Escaped fend char */ + if (inputbyte == TFEND) + ((char *) &ifdata->rx_packet->id.ext)[ifdata->rx_length++] = FEND; + + /* Go back to started mode */ + ifdata->rx_mode = KISS_MODE_STARTED; + break; + + case KISS_MODE_SKIP_FRAME: + + /* Just wait for end char */ + if (inputbyte == FEND) + ifdata->rx_mode = KISS_MODE_NOT_STARTED; + + break; + + } + + } + +} + +int csp_kiss_add_interface(csp_iface_t * iface) { + + if ((iface == NULL) || (iface->name == NULL) || (iface->interface_data == NULL)) { + return CSP_ERR_INVAL; + } + + csp_kiss_interface_data_t * ifdata = iface->interface_data; + if (ifdata->tx_func == NULL) { + return CSP_ERR_INVAL; + } + + if (csp_mutex_create(&ifdata->lock) != CSP_MUTEX_OK) { + return CSP_ERR_NOMEM; + } + + ifdata->max_rx_length = CSP_HEADER_LENGTH + csp_buffer_data_size(); // CSP header + CSP data + ifdata->rx_length = 0; + ifdata->rx_mode = KISS_MODE_NOT_STARTED; + ifdata->rx_first = false; + ifdata->rx_packet = NULL; + + const unsigned int max_data_size = csp_buffer_data_size() - sizeof(uint32_t); // compensate for the added CRC32 + if ((iface->mtu == 0) || (iface->mtu > max_data_size)) { + iface->mtu = max_data_size; + } + + iface->nexthop = csp_kiss_tx; + + return csp_iflist_add(iface); +} diff --git a/Program/libcsp/src/interfaces/csp_if_lo.c b/Program/libcsp/src/interfaces/csp_if_lo.c new file mode 100755 index 0000000..b0f4d5d --- /dev/null +++ b/Program/libcsp/src/interfaces/csp_if_lo.c @@ -0,0 +1,53 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#include "../csp_init.h" + +/** + * Loopback interface transmit function + * @param packet Packet to transmit + * @return 1 if packet was successfully transmitted, 0 on error + */ +static int csp_lo_tx(const csp_route_t * ifroute, csp_packet_t * packet) { + + /* Drop packet silently if not destined for us. This allows + * blackhole routing addresses by setting their nexthop to + * the loopback interface. + */ + if (packet->id.dst != csp_conf.address) { + /* Consume and drop packet */ + csp_buffer_free(packet); + return CSP_ERR_NONE; + } + + /* Send back into CSP, notice calling from task so last argument must be NULL! */ + csp_qfifo_write(packet, &csp_if_lo, NULL); + + return CSP_ERR_NONE; + +} + +/* Interface definition */ +csp_iface_t csp_if_lo = { + .name = CSP_IF_LOOPBACK_NAME, + .nexthop = csp_lo_tx, +}; diff --git a/Program/libcsp/src/interfaces/csp_if_zmqhub.c b/Program/libcsp/src/interfaces/csp_if_zmqhub.c new file mode 100755 index 0000000..1952dd3 --- /dev/null +++ b/Program/libcsp/src/interfaces/csp_if_zmqhub.c @@ -0,0 +1,238 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#if (CSP_HAVE_LIBZMQ) + +#include +#include + +#include +#include +#include +#include +#include + +#define CSP_ZMQ_MTU 1024 // max payload data, see documentation + +/* ZMQ driver & interface */ +typedef struct { + csp_thread_handle_t rx_thread; + void * context; + void * publisher; + void * subscriber; + csp_bin_sem_handle_t tx_wait; + char name[CSP_IFLIST_NAME_MAX + 1]; + csp_iface_t iface; +} zmq_driver_t; + +/** + * Interface transmit function + * @param packet Packet to transmit + * @return 1 if packet was successfully transmitted, 0 on error + */ +int csp_zmqhub_tx(const csp_route_t * route, csp_packet_t * packet) { + + zmq_driver_t * drv = route->iface->driver_data; + + const uint8_t dest = (route->via != CSP_NO_VIA_ADDRESS) ? route->via : packet->id.dst; + + uint16_t length = packet->length; + uint8_t * destptr = ((uint8_t *) &packet->id) - sizeof(dest); + memcpy(destptr, &dest, sizeof(dest)); + csp_bin_sem_wait(&drv->tx_wait, 1000); /* Using ZMQ in thread safe manner*/ + int result = zmq_send(drv->publisher, destptr, length + sizeof(packet->id) + sizeof(dest), 0); + csp_bin_sem_post(&drv->tx_wait); /* Release tx semaphore */ + if (result < 0) { + csp_log_error("ZMQ send error: %u %s\r\n", result, zmq_strerror(zmq_errno())); + } + + csp_buffer_free(packet); + + return CSP_ERR_NONE; + +} + +CSP_DEFINE_TASK(csp_zmqhub_task) { + + zmq_driver_t * drv = param; + csp_packet_t * packet; + const uint32_t HEADER_SIZE = (sizeof(packet->id) + sizeof(uint8_t)); + + //csp_log_info("RX %s started", drv->iface.name); + + while(1) { + zmq_msg_t msg; + assert(zmq_msg_init_size(&msg, CSP_ZMQ_MTU + HEADER_SIZE) == 0); + + // Receive data + if (zmq_msg_recv(&msg, drv->subscriber, 0) < 0) { + csp_log_error("RX %s: %s", drv->iface.name, zmq_strerror(zmq_errno())); + continue; + } + + unsigned int datalen = zmq_msg_size(&msg); + if (datalen < HEADER_SIZE) { + csp_log_warn("RX %s: Too short datalen: %u - expected min %u bytes", drv->iface.name, datalen, HEADER_SIZE); + zmq_msg_close(&msg); + continue; + } + + // Create new csp packet + packet = csp_buffer_get(datalen - HEADER_SIZE); + if (packet == NULL) { + csp_log_warn("RX %s: Failed to get csp_buffer(%u)", drv->iface.name, datalen); + zmq_msg_close(&msg); + continue; + } + + // Copy the data from zmq to csp + const uint8_t * rx_data = zmq_msg_data(&msg); + + // First byte is the "via" address + ++rx_data; + --datalen; + + // Remaining is CSP header and payload + memcpy(&packet->id, rx_data, datalen); + packet->length = (datalen - sizeof(packet->id)); + + // Route packet + csp_qfifo_write(packet, &drv->iface, NULL); + + zmq_msg_close(&msg); + } + + return CSP_TASK_RETURN; + +} + +int csp_zmqhub_make_endpoint(const char * host, uint16_t port, char * buf, size_t buf_size) { + int res = snprintf(buf, buf_size, "tcp://%s:%u", host, port); + if ((res < 0) || (res >= (int)buf_size)) { + buf[0] = 0; + return CSP_ERR_NOMEM; + } + return CSP_ERR_NONE; +} + +int csp_zmqhub_init(uint8_t addr, + const char * host, + uint32_t flags, + csp_iface_t ** return_interface) { + + char pub[100]; + csp_zmqhub_make_endpoint(host, CSP_ZMQPROXY_SUBSCRIBE_PORT, pub, sizeof(pub)); + + char sub[100]; + csp_zmqhub_make_endpoint(host, CSP_ZMQPROXY_PUBLISH_PORT, sub, sizeof(sub)); + + return csp_zmqhub_init_w_endpoints(addr, pub, sub, flags, return_interface); +} + +int csp_zmqhub_init_w_endpoints(uint8_t addr, + const char * publisher_endpoint, + const char * subscriber_endpoint, + uint32_t flags, + csp_iface_t ** return_interface) { + + uint8_t * rxfilter = NULL; + unsigned int rxfilter_count = 0; + + if (addr != CSP_NO_VIA_ADDRESS) { // != 255 + rxfilter = &addr; + rxfilter_count = 1; + } + + return csp_zmqhub_init_w_name_endpoints_rxfilter(NULL, + rxfilter, rxfilter_count, + publisher_endpoint, + subscriber_endpoint, + flags, + return_interface); +} + +int csp_zmqhub_init_w_name_endpoints_rxfilter(const char * ifname, + const uint8_t rxfilter[], unsigned int rxfilter_count, + const char * publish_endpoint, + const char * subscribe_endpoint, + uint32_t flags, + csp_iface_t ** return_interface) { + + zmq_driver_t * drv = csp_calloc(1, sizeof(*drv)); + assert(drv); + + if (ifname == NULL) { + ifname = CSP_ZMQHUB_IF_NAME; + } + + strncpy(drv->name, ifname, sizeof(drv->name) - 1); + drv->iface.name = drv->name; + drv->iface.driver_data = drv; + drv->iface.nexthop = csp_zmqhub_tx; + drv->iface.mtu = CSP_ZMQ_MTU; // there is actually no 'max' MTU on ZMQ, but assuming the other end is based on the same code + + drv->context = zmq_ctx_new(); + assert(drv->context); + + csp_log_info("INIT %s: pub(tx): [%s], sub(rx): [%s], rx filters: %u", + drv->iface.name, publish_endpoint, subscribe_endpoint, rxfilter_count); + + /* Publisher (TX) */ + drv->publisher = zmq_socket(drv->context, ZMQ_PUB); + assert(drv->publisher); + + /* Subscriber (RX) */ + drv->subscriber = zmq_socket(drv->context, ZMQ_SUB); + assert(drv->subscriber); + + if (rxfilter && rxfilter_count) { + // subscribe to all 'rx_filters' -> subscribe to all packets, where the first byte (address/via) matches a rx_filter + for (unsigned int i = 0; i < rxfilter_count; ++i, ++rxfilter) { + assert(zmq_setsockopt(drv->subscriber, ZMQ_SUBSCRIBE, rxfilter, 1) == 0); + } + } else { + // subscribe to all packets - no filter + assert(zmq_setsockopt(drv->subscriber, ZMQ_SUBSCRIBE, NULL, 0) == 0); + } + + /* Connect to server */ + assert(zmq_connect(drv->publisher, publish_endpoint) == 0); + assert(zmq_connect(drv->subscriber, subscribe_endpoint) == 0); + + /* ZMQ isn't thread safe, so we add a binary semaphore to wait on for tx */ + assert(csp_bin_sem_create(&drv->tx_wait) == CSP_SEMAPHORE_OK); + + /* Start RX thread */ + assert(csp_thread_create(csp_zmqhub_task, drv->iface.name, 20000, drv, 0, &drv->rx_thread) == 0); + + /* Register interface */ + csp_iflist_add(&drv->iface); + + if (return_interface) { + *return_interface = &drv->iface; + } + + return CSP_ERR_NONE; + +} + +#endif // CSP_HAVE_LIBZMQ diff --git a/Program/libcsp/src/rtable/csp_rtable.c b/Program/libcsp/src/rtable/csp_rtable.c new file mode 100755 index 0000000..7fcd443 --- /dev/null +++ b/Program/libcsp/src/rtable/csp_rtable.c @@ -0,0 +1,180 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_rtable_internal.h" + +#include + +#include +#include +#include + +#include "../csp_init.h" + +static int csp_rtable_parse(const char * rtable, int dry_run) { + + int valid_entries = 0; + + /* Copy string before running strtok */ + const size_t str_len = strnlen(rtable, 100); + char rtable_copy[str_len + 1]; + strncpy(rtable_copy, rtable, str_len); + rtable_copy[str_len] = 0; + + /* Get first token */ + char * saveptr; + char * str = strtok_r(rtable_copy, ",", &saveptr); + while ((str) && (strlen(str) > 1)) { + unsigned int address, netmask, via; + char name[15]; + if (sscanf(str, "%u/%u %14s %u", &address, &netmask, name, &via) == 4) { + } else if (sscanf(str, "%u/%u %14s", &address, &netmask, name) == 3) { + via = CSP_NO_VIA_ADDRESS; + } else if (sscanf(str, "%u %14s %u", &address, name, &via) == 3) { + netmask = CSP_ID_HOST_SIZE; + } else if (sscanf(str, "%u %14s", &address, name) == 2) { + netmask = CSP_ID_HOST_SIZE; + via = CSP_NO_VIA_ADDRESS; + } else { + // invalid entry + name[0] = 0; + } + name[sizeof(name) - 1] = 0; + + csp_iface_t * ifc = csp_iflist_get_by_name(name); + if ((address > CSP_ID_HOST_MAX) || (netmask > CSP_ID_HOST_SIZE) || (via > UINT8_MAX) || (ifc == NULL)) { + csp_log_error("%s: invalid entry [%s]", __FUNCTION__, str); + return CSP_ERR_INVAL; + } + + if (dry_run == 0) { + int res = csp_rtable_set(address, netmask, ifc, via); + if (res != CSP_ERR_NONE) { + csp_log_error("%s: failed to add [%s], error: %d", __FUNCTION__, str, res); + return res; + } + } + valid_entries++; + str = strtok_r(NULL, ",", &saveptr); + } + + return valid_entries; +} + +int csp_rtable_load(const char * rtable) { + return csp_rtable_parse(rtable, 0); +} + +int csp_rtable_check(const char * rtable) { + return csp_rtable_parse(rtable, 1); +} + +int csp_rtable_set(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via) { + + /* Legacy reference to default route (the old way) */ + if (address == CSP_DEFAULT_ROUTE) { + netmask = 0; + address = 0; + } + + /* Validates options */ + if (((address > CSP_ID_HOST_MAX) && (address != 255)) || (ifc == NULL) || (netmask > CSP_ID_HOST_SIZE)) { + csp_log_error("%s: invalid route: address %u, netmask %u, interface %p (%s), via %u", + __FUNCTION__, address, netmask, ifc, (ifc != NULL) ? ifc->name : "", via); + return CSP_ERR_INVAL; + } + + return csp_rtable_set_internal(address, netmask, ifc, via); +} + +typedef struct { + char * buffer; + size_t len; + size_t maxlen; + int error; +} csp_rtable_save_ctx_t; + +static bool csp_rtable_save_route(void * vctx, uint8_t address, uint8_t mask, const csp_route_t * route) +{ + csp_rtable_save_ctx_t * ctx = vctx; + + // Do not save loop back interface + if (strcasecmp(route->iface->name, CSP_IF_LOOPBACK_NAME) == 0) { + return true; + } + + const char * sep = (ctx->len == 0) ? "" : ","; + + char mask_str[10]; + if (mask != CSP_ID_HOST_SIZE) { + snprintf(mask_str, sizeof(mask_str), "/%u", mask); + } else { + mask_str[0] = 0; + } + char via_str[10]; + if (route->via != CSP_NO_VIA_ADDRESS) { + snprintf(via_str, sizeof(via_str), " %u", route->via); + } else { + via_str[0] = 0; + } + size_t remain_buf_size = ctx->maxlen - ctx->len; + int res = snprintf(ctx->buffer + ctx->len, remain_buf_size, + "%s%u%s %s%s", sep, address, mask_str, route->iface->name, via_str); + if ((res < 0) || (res >= (int)(remain_buf_size))) { + ctx->error = CSP_ERR_NOMEM; + return false; + } + ctx->len += res; + return true; +} + +int csp_rtable_save(char * buffer, size_t maxlen) +{ + csp_rtable_save_ctx_t ctx = {.len = 0, .buffer = buffer, .maxlen = maxlen, .error = CSP_ERR_NONE}; + buffer[0] = 0; + csp_rtable_iterate(csp_rtable_save_route, &ctx); + return ctx.error; +} + +void csp_rtable_clear(void) { + csp_rtable_free(); + + /* Set loopback up again */ + csp_rtable_set(csp_conf.address, CSP_ID_HOST_SIZE, &csp_if_lo, CSP_NO_VIA_ADDRESS); +} + +#if (CSP_DEBUG) + +static bool csp_rtable_print_route(void * ctx, uint8_t address, uint8_t mask, const csp_route_t * route) +{ + if (route->via == CSP_NO_VIA_ADDRESS) { + printf("%u/%u %s\r\n", address, mask, route->iface->name); + } else { + printf("%u/%u %s %u\r\n", address, mask, route->iface->name, route->via); + } + return true; +} + +void csp_rtable_print(void) +{ + csp_rtable_iterate(csp_rtable_print_route, NULL); +} + +#endif diff --git a/Program/libcsp/src/rtable/csp_rtable_cidr.c b/Program/libcsp/src/rtable/csp_rtable_cidr.c new file mode 100755 index 0000000..70a9e51 --- /dev/null +++ b/Program/libcsp/src/rtable/csp_rtable_cidr.c @@ -0,0 +1,147 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_rtable_internal.h" + +#include +#include + +/* Definition of routing table */ +typedef struct csp_rtable_s { + csp_route_t route; + uint8_t address; + uint8_t netmask; + struct csp_rtable_s * next; +} csp_rtable_t; + +/* Routing table (linked list) */ +static csp_rtable_t * rtable = NULL; + +static csp_rtable_t * csp_rtable_find(uint8_t addr, uint8_t netmask, uint8_t exact) { + + /* Remember best result */ + csp_rtable_t * best_result = NULL; + uint8_t best_result_mask = 0; + + /* Start search */ + csp_rtable_t * i = rtable; + while(i) { + + /* Look for exact match */ + if (i->address == addr && i->netmask == netmask) { + best_result = i; + break; + } + + /* Try a CIDR netmask match */ + if (!exact) { + uint8_t hostbits = (1 << (CSP_ID_HOST_SIZE - i->netmask)) - 1; + uint8_t netbits = ~hostbits; + //printf("Netbits %x Hostbits %x\r\n", netbits, hostbits); + + /* Match network addresses */ + uint8_t net_a = i->address & netbits; + uint8_t net_b = addr & netbits; + //printf("A: %hhx, B: %hhx\r\n", net_a, net_b); + + /* We have a match */ + if (net_a == net_b) { + if (i->netmask >= best_result_mask) { + //printf("Match best result %u %u\r\n", best_result_mask, i->netmask); + best_result = i; + best_result_mask = i->netmask; + } + } + + } + + i = i->next; + + } + + if (0 && best_result) { + csp_log_packet("Using routing entry: %u/%u if %s mtu %u", + best_result->address, best_result->netmask, best_result->route.iface->name, best_result->route.via); + } + + return best_result; + +} + +const csp_route_t * csp_rtable_find_route(uint8_t dest_address) +{ + csp_rtable_t * entry = csp_rtable_find(dest_address, CSP_ID_HOST_SIZE, 0); + if (entry) { + return &entry->route; + } + return NULL; +} + +int csp_rtable_set_internal(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via) { + + /* First see if the entry exists */ + csp_rtable_t * entry = csp_rtable_find(address, netmask, 1); + + /* If not, create a new one */ + if (!entry) { + entry = csp_malloc(sizeof(*entry)); + if (entry == NULL) { + return CSP_ERR_NOMEM; + } + + entry->next = NULL; + /* Add entry to linked-list */ + if (rtable == NULL) { + /* This is the first interface to be added */ + rtable = entry; + } else { + /* One or more interfaces were already added */ + csp_rtable_t * i = rtable; + while (i->next) { + i = i->next; + } + i->next = entry; + } + } + + /* Fill in the data */ + entry->address = address; + entry->netmask = netmask; + entry->route.iface = ifc; + entry->route.via = via; + + return CSP_ERR_NONE; +} + +void csp_rtable_free(void) { + for (csp_rtable_t * i = rtable; (i);) { + void * freeme = i; + i = i->next; + csp_free(freeme); + } + rtable = NULL; +} + +void csp_rtable_iterate(csp_rtable_iterator_t iter, void * ctx) +{ + for (csp_rtable_t * route = rtable; + route && iter(ctx, route->address, route->netmask, &route->route); + route = route->next); +} diff --git a/Program/libcsp/src/rtable/csp_rtable_internal.h b/Program/libcsp/src/rtable/csp_rtable_internal.h new file mode 100755 index 0000000..e8a236b --- /dev/null +++ b/Program/libcsp/src/rtable/csp_rtable_internal.h @@ -0,0 +1,24 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +/* Internal set route - after common validation by csp_rtable_set(...) */ +int csp_rtable_set_internal(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via); diff --git a/Program/libcsp/src/rtable/csp_rtable_static.c b/Program/libcsp/src/rtable/csp_rtable_static.c new file mode 100755 index 0000000..c89ee53 --- /dev/null +++ b/Program/libcsp/src/rtable/csp_rtable_static.c @@ -0,0 +1,73 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_rtable_internal.h" + +#include + +/* Routing table (static array) */ +static csp_route_t rtable[CSP_DEFAULT_ROUTE + 1] = {}; + +const csp_route_t * csp_rtable_find_route(uint8_t dest_address) { + + if (rtable[dest_address].iface != NULL) { + return &rtable[dest_address]; + } + if (rtable[CSP_DEFAULT_ROUTE].iface != NULL) { + return &rtable[CSP_DEFAULT_ROUTE]; + } + return NULL; + +} + +int csp_rtable_set_internal(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via) { + + /* Validates options */ + if ((netmask != 0) && (netmask != CSP_ID_HOST_SIZE)) { + csp_log_error("%s: invalid netmask in route: address %u, netmask %u, interface %p, via %u", __FUNCTION__, address, netmask, ifc, via); + return CSP_ERR_INVAL; + } + + /* Set route */ + const unsigned int ri = (netmask == 0) ? CSP_DEFAULT_ROUTE : address; + rtable[ri].iface = ifc; + rtable[ri].via = via; + + return CSP_ERR_NONE; +} + +void csp_rtable_free(void) { + + memset(rtable, 0, sizeof(rtable)); +} + +void csp_rtable_iterate(csp_rtable_iterator_t iter, void * ctx) { + + for (unsigned int i = 0; i < CSP_DEFAULT_ROUTE; ++i) { + if (rtable[i].iface != NULL) { + if (iter(ctx, i, CSP_ID_HOST_SIZE, &rtable[i]) == false) { + return; // stopped by user + } + } + } + if (rtable[CSP_DEFAULT_ROUTE].iface) { + iter(ctx, 0, 0, &rtable[CSP_DEFAULT_ROUTE]); + } +} diff --git a/Program/libcsp/src/transport/csp_rdp.c b/Program/libcsp/src/transport/csp_rdp.c new file mode 100755 index 0000000..bd63f96 --- /dev/null +++ b/Program/libcsp/src/transport/csp_rdp.c @@ -0,0 +1,1157 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + * This is a implementation of the seq/ack handling taken from the Reliable Datagram Protocol (RDP) + * For more information read RFC 908/1151. The implementation has been extended to include support for + * delayed acknowledgments, to improve performance over half-duplex links. + */ + +#include "csp_transport.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../csp_port.h" +#include "../csp_conn.h" +#include "../csp_io.h" +#include "../csp_init.h" + +#define RDP_SYN 0x01 +#define RDP_ACK 0x02 +#define RDP_EAK 0x04 +#define RDP_RST 0x08 + +#if (CSP_USE_RDP) + +static uint32_t csp_rdp_window_size = 4; +static uint32_t csp_rdp_conn_timeout = 10000; +static uint32_t csp_rdp_packet_timeout = 1000; +static uint32_t csp_rdp_delayed_acks = 1; +static uint32_t csp_rdp_ack_timeout = 1000 / 4; +static uint32_t csp_rdp_ack_delay_count = 4 / 2; + +/* Used for queue calls */ +static CSP_BASE_TYPE pdTrue = 1; + +/* RDP header - on top of csp_packet_t */ +typedef struct { + uint32_t quarantine; // EACK quarantine period (-> csp_packet_t.padding) + uint32_t timestamp; // Time the message was sent (-> csp_packet_t.padding) + uint8_t padding[CSP_PADDING_BYTES - (2 * sizeof(uint32_t))]; + uint16_t length; // Overlay length member in csp_packet_t + csp_id_t id; // Overlay id member in csp_packet_t + uint8_t data[]; // Overlay data member in csp_packet_t +} rdp_packet_t; + +// Ensure certain fields in the rdp_packet_t matches the fields in the csp_packet_t +CSP_STATIC_ASSERT(offsetof(rdp_packet_t, length) == offsetof(csp_packet_t, length), length_field_misaligned); +CSP_STATIC_ASSERT(offsetof(rdp_packet_t, id) == offsetof(csp_packet_t, id), id_field_misaligned); +CSP_STATIC_ASSERT(offsetof(rdp_packet_t, data) == offsetof(csp_packet_t, data), data_field_misaligned); + +typedef struct __attribute__((__packed__)) { + union __attribute__((__packed__)) { + uint8_t flags; + struct __attribute__((__packed__)) { +#if (CSP_BIG_ENDIAN) + unsigned int res : 4; + unsigned int syn : 1; + unsigned int ack : 1; + unsigned int eak : 1; + unsigned int rst : 1; +#elif (CSP_LITTLE_ENDIAN) + unsigned int rst : 1; + unsigned int eak : 1; + unsigned int ack : 1; + unsigned int syn : 1; + unsigned int res : 4; +#endif + }; + }; + uint16_t seq_nr; + uint16_t ack_nr; +} rdp_header_t; + +static int csp_rdp_close_internal(csp_conn_t * conn, uint8_t closed_by, bool send_rst); + +/** + * RDP Headers: + * The following functions are helper functions that handles the extra RDP + * information that needs to be appended to all data packets. + */ +static rdp_header_t * csp_rdp_header_add(csp_packet_t * packet) { + rdp_header_t * header; + if ((packet->length + sizeof(*header)) > csp_buffer_data_size()) { + return NULL; + } + header = (rdp_header_t *) &packet->data[packet->length]; + packet->length += sizeof(*header); + memset(header, 0, sizeof(*header)); + return header; +} + +static rdp_header_t * csp_rdp_header_remove(csp_packet_t * packet) { + rdp_header_t * header = (rdp_header_t *) &packet->data[packet->length - sizeof(*header)]; + packet->length -= sizeof(*header); + return header; +} + +static rdp_header_t * csp_rdp_header_ref(csp_packet_t * packet) { + rdp_header_t * header = (rdp_header_t *) &packet->data[packet->length - sizeof(*header)]; + return header; +} + +/* Functions for comparing wrapping sequence numbers and timestamps */ + +/* Return 1 if seq is between start and end (both inclusive) */ +static inline int csp_rdp_seq_between(uint16_t seq, uint16_t start, uint16_t end) { + return (uint16_t)(end - start) >= (uint16_t)(seq - start); +} + +/* Return 1 if seq is before cmp */ +static inline int csp_rdp_seq_before(uint16_t seq, uint16_t cmp) { + return (int16_t)(seq - cmp) < 0; +} + +/* Return 1 if seq is after cmp */ +static inline int csp_rdp_seq_after(uint16_t seq, uint16_t cmp) { + return csp_rdp_seq_before(cmp, seq); +} + +/* Return 1 if time is between start and end (both inclusive) */ +//static inline int csp_rdp_time_between(uint32_t time, uint32_t start, uint32_t end) { +// return (uint32_t)(end - start) >= (uint32_t)(time - start); +//} + +/* Return 1 if time is before cmp */ +static inline int csp_rdp_time_before(uint32_t time, uint32_t cmp) { + return (int32_t)(time - cmp) < 0; +} + +/* Return 1 if time is after cmp */ +static inline int csp_rdp_time_after(uint32_t time, uint32_t cmp) { + return csp_rdp_time_before(cmp, time); +} + +/** + * CONTROL MESSAGES + * The following function is used to send empty messages, + * with ACK, SYN or RST flag. + */ +static int csp_rdp_send_cmp(csp_conn_t * conn, csp_packet_t * packet, int flags, int seq_nr, int ack_nr) { + + /* Generate message */ + if (!packet) { + packet = csp_buffer_get(20); + if (!packet) + return CSP_ERR_NOMEM; + packet->length = 0; + } + + /* Add RDP header */ + rdp_header_t * header = csp_rdp_header_add(packet); + if (header == NULL) { + csp_log_error("RDP %p: No space for RDP header (cmp)", conn); + csp_buffer_free(packet); + return CSP_ERR_NOMEM; + } + header->seq_nr = csp_hton16(seq_nr); + header->ack_nr = csp_hton16(ack_nr); + header->ack = (flags & RDP_ACK) ? 1 : 0; + header->eak = (flags & RDP_EAK) ? 1 : 0; + header->syn = (flags & RDP_SYN) ? 1 : 0; + header->rst = (flags & RDP_RST) ? 1 : 0; + + /* Send copy to tx_queue, before sending packet to IF */ + if (flags & RDP_SYN) { + rdp_packet_t * rdp_packet = csp_buffer_clone(packet); + if (rdp_packet == NULL) return CSP_ERR_NOMEM; + rdp_packet->timestamp = csp_get_ms(); + if (csp_queue_enqueue(conn->rdp.tx_queue, &rdp_packet, 0) != CSP_QUEUE_OK) + csp_buffer_free(rdp_packet); + } + + /* Send control messages with high priority */ + csp_id_t idout = conn->idout; + idout.pri = conn->idout.pri < CSP_PRIO_HIGH ? conn->idout.pri : CSP_PRIO_HIGH; + + csp_log_protocol("RDP %p: Send CMP S %u: syn %u, ack %u, eack %u, rst %u, seq_nr %5u, ack_nr %5u, packet_len %u (%u)", + conn, conn->rdp.state, header->syn, header->ack, header->eak, + header->rst, csp_ntoh16(header->seq_nr), csp_ntoh16(header->ack_nr), + packet->length, (unsigned int)(packet->length - sizeof(rdp_header_t))); + + /* Send packet to IF */ + if (csp_send_direct(idout, packet, csp_rtable_find_route(idout.dst), 0) != CSP_ERR_NONE) { + csp_log_error("RDP %p: INTERFACE ERROR: not possible to send", conn); + csp_buffer_free(packet); + return CSP_ERR_BUSY; + } + + /* Update last ACK time stamp */ + if (flags & RDP_ACK) { + conn->rdp.rcv_lsa = ack_nr; + conn->rdp.ack_timestamp = csp_get_ms(); + } + + return CSP_ERR_NONE; + +} + +/** + * EXTENDED ACKNOWLEDGEMENTS + * The following function sends an extended ACK packet + */ +static int csp_rdp_send_eack(csp_conn_t * conn) { + + /* Allocate message */ + csp_packet_t * packet_eack = csp_buffer_get(100); + if (packet_eack == NULL) return CSP_ERR_NOMEM; + packet_eack->length = 0; + + /* Loop through RX queue */ + int i, count; + csp_packet_t * packet; + count = csp_queue_size(conn->rdp.rx_queue); + for (i = 0; i < count; i++) { + + if (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) { + csp_log_error("RDP %p: Cannot dequeue from rx_queue in queue deliver", conn); + break; + } + + /* Add seq nr to EACK packet */ + rdp_header_t * header = csp_rdp_header_ref(packet); + packet_eack->data16[packet_eack->length/sizeof(uint16_t)] = csp_hton16(header->seq_nr); + packet_eack->length += sizeof(uint16_t); + csp_log_protocol("RDP %p: Added EACK nr %u", conn, header->seq_nr); + + /* Requeue */ + csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); + + } + + return csp_rdp_send_cmp(conn, packet_eack, RDP_ACK | RDP_EAK, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + +} + + +/** + * SYN Packet + * The following function sends a SYN packet + */ +static int csp_rdp_send_syn(csp_conn_t * conn) { + + /* Allocate message */ + csp_packet_t * packet = csp_buffer_get(100); + if (packet == NULL) return CSP_ERR_NOMEM; + + /* Generate contents */ + packet->data32[0] = csp_hton32(csp_rdp_window_size); + packet->data32[1] = csp_hton32(csp_rdp_conn_timeout); + packet->data32[2] = csp_hton32(csp_rdp_packet_timeout); + packet->data32[3] = csp_hton32(csp_rdp_delayed_acks); + packet->data32[4] = csp_hton32(csp_rdp_ack_timeout); + packet->data32[5] = csp_hton32(csp_rdp_ack_delay_count); + packet->length = 6 * sizeof(uint32_t); + + return csp_rdp_send_cmp(conn, packet, RDP_SYN, conn->rdp.snd_iss, 0); + +} + +static inline int csp_rdp_receive_data(csp_conn_t * conn, csp_packet_t * packet) { + + /* Remove RDP header before passing to userspace */ + csp_rdp_header_remove(packet); + + /* Enqueue data */ + if (csp_conn_enqueue_packet(conn, packet) < 0) { + csp_log_warn("RDP %p: Conn RX buffer full", conn); + return CSP_ERR_NOBUFS; + } + + return CSP_ERR_NONE; + +} + +static inline void csp_rdp_rx_queue_flush(csp_conn_t * conn) { + + /* Loop through RX queue */ + int i, count; + csp_packet_t * packet; + +front: + count = csp_queue_size(conn->rdp.rx_queue); + for (i = 0; i < count; i++) { + + if (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) { + csp_log_error("RDP %p: Cannot dequeue from rx_queue in queue deliver", conn); + break; + } + + rdp_header_t * header = csp_rdp_header_ref(packet); + csp_log_protocol("RDP %p: RX Queue deliver matching Element, seq %u", conn, header->seq_nr); + + /* If the matching packet was found: */ + if (header->seq_nr == (uint16_t)(conn->rdp.rcv_cur + 1)) { + csp_log_protocol("RDP %p: Deliver seq %u", conn, header->seq_nr); + csp_rdp_receive_data(conn, packet); + conn->rdp.rcv_cur++; + /* Loop from first element again */ + goto front; + + /* Otherwise, requeue */ + } else { + csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); + } + + } + +} + +static inline bool csp_rdp_seq_in_rx_queue(csp_conn_t * conn, uint16_t seq_nr) { + + /* Loop through RX queue */ + int i, count; + rdp_packet_t * packet; + count = csp_queue_size(conn->rdp.rx_queue); + for (i = 0; i < count; i++) { + + if (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) { + csp_log_error("RDP %p: Cannot dequeue from rx_queue in queue exists", conn); + break; + } + + csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); + + rdp_header_t * header = csp_rdp_header_ref((csp_packet_t *) packet); + csp_log_protocol("RDP %p: RX Queue exists matching Element, seq %u", conn, header->seq_nr); + + /* If the matching packet was found, deliver */ + if (header->seq_nr == seq_nr) { + csp_log_protocol("RDP %p: We have a match", conn); + return true; + } + + } + + return false; + +} + +static inline int csp_rdp_rx_queue_add(csp_conn_t * conn, csp_packet_t * packet, uint16_t seq_nr) { + + if (csp_rdp_seq_in_rx_queue(conn, seq_nr)) + return CSP_QUEUE_ERROR; + return csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); + +} + +static void csp_rdp_flush_eack(csp_conn_t * conn, csp_packet_t * eack_packet) { + + /* Loop through TX queue */ + int i, j, count; + rdp_packet_t * packet; + count = csp_queue_size(conn->rdp.tx_queue); + for (i = 0; i < count; i++) { + + if (csp_queue_dequeue(conn->rdp.tx_queue, &packet, 0) != CSP_QUEUE_OK) { + csp_log_error("RDP %p: Cannot dequeue from tx_queue in flush EACK", conn); + break; + } + + rdp_header_t * header = csp_rdp_header_ref((csp_packet_t *) packet); + csp_log_protocol("RDP %p: EACK compare element, time %"PRIu32", seq %u", conn, packet->timestamp, csp_ntoh16(header->seq_nr)); + + /* Look for this element in EACKs */ + int match = 0; + for (j = 0; j < (int)((eack_packet->length - sizeof(rdp_header_t)) / sizeof(uint16_t)); j++) { + if (csp_ntoh16(eack_packet->data16[j]) == csp_ntoh16(header->seq_nr)) + match = 1; + + /* Enable this if you want EACK's to trigger retransmission */ + if (csp_ntoh16(eack_packet->data16[j]) > csp_ntoh16(header->seq_nr)) { + uint32_t time_now = csp_get_ms(); + if (csp_rdp_time_after(time_now, packet->quarantine)) { + packet->timestamp = time_now - conn->rdp.packet_timeout - 1; + packet->quarantine = time_now + conn->rdp.packet_timeout / 2; + } + } + } + + if (match == 0) { + /* If not found, put back on tx queue */ + csp_queue_enqueue(conn->rdp.tx_queue, &packet, 0); + } else { + /* Found, free */ + csp_log_protocol("RDP %p: TX Element %u freed", conn, csp_ntoh16(header->seq_nr)); + csp_buffer_free(packet); + } + + } + +} + +static inline bool csp_rdp_should_ack(csp_conn_t * conn) { + + /* If delayed ACKs are not used, always ACK */ + if (!conn->rdp.delayed_acks) { + return true; + } + + /* ACK if time since last ACK is greater than ACK timeout */ + uint32_t time_now = csp_get_ms(); + if (csp_rdp_time_after(time_now, conn->rdp.ack_timestamp + conn->rdp.ack_timeout)) + return true; + + /* ACK if number of unacknowledged packets is greater than delay count */ + if (csp_rdp_seq_after(conn->rdp.rcv_cur, conn->rdp.rcv_lsa + conn->rdp.ack_delay_count)) + return true; + + return false; + +} + +void csp_rdp_flush_all(csp_conn_t * conn) { + + if ((conn == NULL) || conn->rdp.tx_queue == NULL) { + csp_log_error("RDP %p: Null pointer passed to rdp flush all", conn); + return; + } + + rdp_packet_t * packet; + + /* Empty TX queue */ + while (csp_queue_dequeue_isr(conn->rdp.tx_queue, &packet, &pdTrue) == CSP_QUEUE_OK) { + if (packet != NULL) { + csp_log_protocol("RDP %p: Flush TX Element, time %"PRIu32", seq %u", conn, packet->timestamp, csp_ntoh16(csp_rdp_header_ref((csp_packet_t *) packet)->seq_nr)); + csp_buffer_free(packet); + } + } + + /* Empty RX queue */ + while (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) == CSP_QUEUE_OK) { + if (packet != NULL) { + csp_log_protocol("RDP %p: Flush RX Element, time %"PRIu32", seq %u", conn, packet->timestamp, csp_ntoh16(csp_rdp_header_ref((csp_packet_t *) packet)->seq_nr)); + csp_buffer_free(packet); + } + } + +} + + +int csp_rdp_check_ack(csp_conn_t * conn) { + + /* Check all RX queues for spare capacity */ + int avail = 1; + for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { + if (csp_conf.conn_queue_length - csp_queue_size(conn->rx_queue[prio]) <= 2 * (int32_t)conn->rdp.window_size) { + avail = 0; + break; + } + } + + /* If more space available, only send after ack timeout or immediately if delay_acks is zero */ + if (avail && csp_rdp_should_ack(conn)) { + csp_rdp_send_cmp(conn, NULL, RDP_ACK, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + } + + return CSP_ERR_NONE; + +} + +static inline bool csp_rdp_is_conn_ready_for_tx(csp_conn_t * conn) +{ + // Check Tx window (messages waiting for acks) + if (csp_rdp_seq_after(conn->rdp.snd_nxt, conn->rdp.snd_una + conn->rdp.window_size - 1)) { + return false; + } + return true; +} + +/** + * This function must be called with regular intervals for the + * RDP protocol to work as expected. This takes care of closing + * stale connections and retransmitting traffic. A good place to + * call this function is from the CSP router task. + */ +void csp_rdp_check_timeouts(csp_conn_t * conn) { + + const uint32_t time_now = csp_get_ms(); + + /** + * CONNECTION TIMEOUT: + * Check that connection has not timed out inside the network stack + */ + if (conn->socket != NULL) { + if (csp_rdp_time_after(time_now, conn->timestamp + conn->rdp.conn_timeout)) { + csp_log_warn("RDP %p: Found a lost connection (now: %"PRIu32", ts: %"PRIu32", to: %"PRIu32"), closing", + conn, time_now, conn->timestamp, conn->rdp.conn_timeout); + csp_conn_close(conn, CSP_RDP_CLOSED_BY_USERSPACE | CSP_RDP_CLOSED_BY_PROTOCOL | CSP_RDP_CLOSED_BY_TIMEOUT); + return; + } + } + + /** + * CLOSE-WAIT TIMEOUT: + * After waiting a while in CLOSE-WAIT, the connection should be closed. + */ + if (conn->rdp.state == RDP_CLOSE_WAIT) { + if (csp_rdp_time_after(time_now, conn->timestamp + conn->rdp.conn_timeout)) { + csp_conn_close(conn, CSP_RDP_CLOSED_BY_PROTOCOL | CSP_RDP_CLOSED_BY_TIMEOUT); + } + return; + } + + /** + * MESSAGE TIMEOUT: + * Check each outgoing message for TX timeout + */ + int count = csp_queue_size(conn->rdp.tx_queue); + for (int i = 0; i < count; i++) { + + rdp_packet_t * packet; + if ((csp_queue_dequeue_isr(conn->rdp.tx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) || packet == NULL) { + csp_log_warn("RDP %p: Cannot dequeue from tx_queue in check timeout", conn); + break; + } + + /* Get header */ + rdp_header_t * header = csp_rdp_header_ref((csp_packet_t *) packet); + + /* If acked, do not retransmit */ + if (csp_rdp_seq_before(csp_ntoh16(header->seq_nr), conn->rdp.snd_una)) { + csp_log_protocol("RDP %p: TX Element Free, time %"PRIu32", seq %u, una %u", conn, packet->timestamp, csp_ntoh16(header->seq_nr), conn->rdp.snd_una); + csp_buffer_free(packet); + continue; + } + + /* Check timestamp and retransmit if needed */ + if (csp_rdp_time_after(time_now, packet->timestamp + conn->rdp.packet_timeout)) { + csp_log_protocol("RDP %p: TX Element timed out, retransmitting seq %u", conn, csp_ntoh16(header->seq_nr)); + + /* Update to latest outgoing ACK */ + header->ack_nr = csp_hton16(conn->rdp.rcv_cur); + + /* Send copy to tx_queue */ + packet->timestamp = csp_get_ms(); + csp_packet_t * new_packet = csp_buffer_clone(packet); + if (csp_send_direct(conn->idout, new_packet, csp_rtable_find_route(conn->idout.dst), 0) != CSP_ERR_NONE) { + csp_log_warn("RDP %p: Retransmission failed", conn); + csp_buffer_free(new_packet); + } + + } + + /* Requeue the TX element */ + csp_queue_enqueue_isr(conn->rdp.tx_queue, &packet, &pdTrue); + + } + + if (conn->rdp.state == RDP_OPEN) { + + /* Check if we have unacknowledged segments */ + if (conn->rdp.delayed_acks) { + csp_rdp_check_ack(conn); + } + + /* Wake user task if additional Tx can be done */ + if (csp_rdp_is_conn_ready_for_tx(conn)) { + csp_log_protocol("RDP %p: Wake Tx task (check timeouts)", conn); + csp_bin_sem_post(&conn->rdp.tx_wait); + } + } +} + +bool csp_rdp_new_packet(csp_conn_t * conn, csp_packet_t * packet) { + + bool close_connection = false; + + /* Get RX header and convert to host byte-order */ + rdp_header_t * rx_header = csp_rdp_header_ref(packet); + rx_header->ack_nr = csp_ntoh16(rx_header->ack_nr); + rx_header->seq_nr = csp_ntoh16(rx_header->seq_nr); + + uint8_t closed_by = CSP_RDP_CLOSED_BY_PROTOCOL; + + csp_log_protocol("RDP %p: Received in S %u: syn %u, ack %u, eack %u, " + "rst %u, seq_nr %5u, ack_nr %5u, packet_len %u (%u)", + conn, conn->rdp.state, rx_header->syn, rx_header->ack, rx_header->eak, + rx_header->rst, rx_header->seq_nr, rx_header->ack_nr, + packet->length, (unsigned int)(packet->length - sizeof(rdp_header_t))); + + /* If a RESET was received. */ + if (rx_header->rst) { + + if (rx_header->ack) { + /* Store current ack'ed sequence number */ + conn->rdp.snd_una = rx_header->ack_nr + 1; + } + + if (conn->rdp.state == RDP_CLOSED) { + csp_log_protocol("RDP %p: RST received in CLOSED - ignored", conn); + close_connection = (conn->socket != NULL); + goto discard_open; + } + + if (conn->rdp.state == RDP_CLOSE_WAIT) { + csp_log_protocol("RDP %p: RST received in CLOSE_WAIT, ack: %d - closing", conn, rx_header->ack); + if (rx_header->ack && CSP_USE_RDP_FAST_CLOSE) { + // skip timeout - the other end has acknowledged the RST + closed_by |= CSP_RDP_CLOSED_BY_TIMEOUT; + } + goto discard_close; + } + + if (rx_header->seq_nr == (conn->rdp.rcv_cur + 1)) { + csp_log_protocol("RDP %p: Received RST in sequence, no more data incoming, reply with RST", conn); + conn->rdp.state = RDP_CLOSE_WAIT; + conn->timestamp = csp_get_ms(); + csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + if (CSP_USE_RDP_FAST_CLOSE) { + closed_by |= CSP_RDP_CLOSED_BY_TIMEOUT; + } + goto discard_close; + } + + csp_log_protocol("RDP %p: RST out of sequence, keep connection open", conn); + goto discard_open; + } + + /* The BIG FAT switch (state-machine) */ + switch(conn->rdp.state) { + + /** + * STATE == CLOSED + */ + case RDP_CLOSED: { + + /* No SYN flag set while in closed. Inform by sending back RST */ + if (!rx_header->syn) { + csp_log_protocol("RDP %p: Not SYN received in CLOSED state. Discarding packet", conn); + csp_rdp_send_cmp(conn, NULL, RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + goto discard_close; + } + + csp_log_protocol("RDP %p: SYN-Received", conn); + + /* Setup TX seq. */ + conn->rdp.snd_iss = (uint16_t)rand(); + conn->rdp.snd_nxt = conn->rdp.snd_iss + 1; + conn->rdp.snd_una = conn->rdp.snd_iss; + + /* Store RX seq. */ + conn->rdp.rcv_cur = rx_header->seq_nr; + conn->rdp.rcv_irs = rx_header->seq_nr; + conn->rdp.rcv_lsa = rx_header->seq_nr; + + /* Store RDP options */ + conn->rdp.window_size = csp_ntoh32(packet->data32[0]); + conn->rdp.conn_timeout = csp_ntoh32(packet->data32[1]); + conn->rdp.packet_timeout = csp_ntoh32(packet->data32[2]); + conn->rdp.delayed_acks = csp_ntoh32(packet->data32[3]); + conn->rdp.ack_timeout = csp_ntoh32(packet->data32[4]); + conn->rdp.ack_delay_count = csp_ntoh32(packet->data32[5]); + csp_log_protocol("RDP %p: window size %"PRIu32", conn timeout %"PRIu32", packet timeout %"PRIu32", delayed acks: %"PRIu32", ack timeout %"PRIu32", ack each %"PRIu32" packet", + conn, conn->rdp.window_size, conn->rdp.conn_timeout, conn->rdp.packet_timeout, + conn->rdp.delayed_acks, conn->rdp.ack_timeout, conn->rdp.ack_delay_count); + + /* Connection accepted */ + conn->rdp.state = RDP_SYN_RCVD; + + /* Send SYN/ACK */ + csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_SYN, conn->rdp.snd_iss, conn->rdp.rcv_irs); + + goto discard_open; + + } + break; + + /** + * STATE == SYN-SENT + */ + case RDP_SYN_SENT: { + + /* First check SYN/ACK */ + if (rx_header->syn && rx_header->ack) { + + conn->rdp.rcv_cur = rx_header->seq_nr; + conn->rdp.rcv_irs = rx_header->seq_nr; + conn->rdp.rcv_lsa = rx_header->seq_nr - 1; + conn->rdp.snd_una = rx_header->ack_nr + 1; + conn->rdp.ack_timestamp = csp_get_ms(); + conn->rdp.state = RDP_OPEN; + + csp_log_protocol("RDP %p: NP: Connection OPEN", conn); + + /* Send ACK */ + csp_rdp_send_cmp(conn, NULL, RDP_ACK, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + + /* Wake TX task */ + csp_log_protocol("RDP %p: Wake Tx task (ack)", conn); + csp_bin_sem_post(&conn->rdp.tx_wait); + + goto discard_open; + } + + /* If there was no SYN in the reply, our SYN message hit an already open connection + * This is handled by sending a RST. + * Normally this would be followed up by a new connection attempt, however + * we don't have a method for signaling this to the user space. + */ + if (rx_header->ack) { + csp_log_error("RDP %p: Half-open connection found, send RST and wake Tx task", conn); + csp_rdp_send_cmp(conn, NULL, RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + csp_bin_sem_post(&conn->rdp.tx_wait); + + goto discard_open; + } + + /* Otherwise we have an invalid command, such as a SYN reply to a SYN command, + * indicating simultaneous connections, which is not possible in the way CSP + * reserves some ports for server and some for clients. + */ + csp_log_error("RDP %p: Invalid reply to SYN request", conn); + goto discard_close; + + } + break; + + /** + * STATE == OPEN + */ + case RDP_SYN_RCVD: + case RDP_OPEN: + { + + /* SYN or !ACK is invalid */ + if (rx_header->syn || !rx_header->ack) { + if (rx_header->seq_nr != conn->rdp.rcv_irs) { + csp_log_error("RDP %p: Invalid SYN or no ACK, resetting!", conn); + goto discard_close; + } else { + csp_log_protocol("RDP %p: Ignoring duplicate SYN packet!", conn); + goto discard_open; + } + } + + /* Check sequence number */ + if (!csp_rdp_seq_between(rx_header->seq_nr, conn->rdp.rcv_cur + 1, conn->rdp.rcv_cur + (conn->rdp.window_size * 2))) { + csp_log_protocol("RDP %p: Invalid sequence number! %u not between %u and %"PRIu32, + conn, rx_header->seq_nr, conn->rdp.rcv_cur + 1U, conn->rdp.rcv_cur + (conn->rdp.window_size * 2U)); + /* If duplicate SYN received, send another SYN/ACK */ + if (conn->rdp.state == RDP_SYN_RCVD) + csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_SYN, conn->rdp.snd_iss, conn->rdp.rcv_irs); + /* If duplicate data packet received, send EACK back */ + if (conn->rdp.state == RDP_OPEN) + csp_rdp_send_eack(conn); + + goto discard_open; + } + + /* Check ACK number */ + if (!csp_rdp_seq_between(rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1)) { + csp_log_error("RDP %p: Invalid ACK number! %u not between %"PRIu32" and %u", + conn, rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1); + goto discard_open; + } + + /* Check SYN_RCVD ACK */ + if (conn->rdp.state == RDP_SYN_RCVD) { + if (rx_header->ack_nr != conn->rdp.snd_iss) { + csp_log_error("RDP %p: SYN-RCVD: Wrong ACK number", conn); + goto discard_close; + } + csp_log_protocol("RDP %p: NC: Connection OPEN", conn); + conn->rdp.state = RDP_OPEN; + + /* If a socket is set, this message is the first in a new connection + * so the connection must be queued to the socket. */ + if (conn->socket != NULL) { + + /* Try queueing */ + if (csp_queue_enqueue(conn->socket, &conn, 0) == CSP_QUEUE_FULL) { + csp_log_error("RDP %p: ERROR socket cannot accept more connections", conn); + goto discard_close; + } + + /* Ensure that this connection will not be posted to this socket again + * and remember that the connection handle has been passed to userspace + * by setting the socket = NULL */ + conn->socket = NULL; + } + + } + + /* Store current ack'ed sequence number */ + conn->rdp.snd_una = rx_header->ack_nr + 1; + + /* We have an EACK */ + if (rx_header->eak) { + if (packet->length > sizeof(rdp_header_t)) + csp_rdp_flush_eack(conn, packet); + goto discard_open; + } + + /* If no data, return here */ + if (packet->length <= sizeof(rdp_header_t)) + goto discard_open; + + /* If message is not in sequence, send EACK and store packet */ + if (rx_header->seq_nr != (uint16_t)(conn->rdp.rcv_cur + 1)) { + if (csp_rdp_rx_queue_add(conn, packet, rx_header->seq_nr) != CSP_QUEUE_OK) { + csp_log_protocol("RDP %p: Duplicate sequence number", conn); + csp_rdp_check_ack(conn); + goto discard_open; + } + csp_rdp_send_eack(conn); + goto accepted_open; + } + + /* Store sequence number before stripping RDP header */ + uint16_t seq_nr = rx_header->seq_nr; + + /* Receive data */ + if (csp_rdp_receive_data(conn, packet) != CSP_ERR_NONE) + goto discard_open; + + /* Update last received packet */ + conn->rdp.rcv_cur = seq_nr; + + /* Only ACK the message if there is room for a full window in the RX buffer. + * Unacknowledged segments are ACKed by csp_rdp_check_timeouts when the buffer is + * no longer full. */ + csp_rdp_check_ack(conn); + + /* Flush RX queue */ + csp_rdp_rx_queue_flush(conn); + + goto accepted_open; + + } + break; + + case RDP_CLOSE_WAIT: + + /* Ignore SYN or !ACK */ + if (rx_header->syn || !rx_header->ack) { + csp_log_protocol("RDP %p: Invalid SYN or no ACK in CLOSE-WAIT", conn); + goto discard_open; + } + + /* Check ACK number */ + if (!csp_rdp_seq_between(rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1)) { + csp_log_error("RDP %p: Invalid ACK number! %u not between %"PRIu32" and %u", + conn, rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1); + goto discard_open; + } + + /* Store current ack'ed sequence number */ + conn->rdp.snd_una = rx_header->ack_nr + 1; + + /* Send back a reset */ + csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + + goto discard_open; + + default: + csp_log_error("RDP %p: ERROR default state!", conn); + goto discard_close; + } + +discard_close: + /* If user-space has received the connection handle, wake it up, + * by sending a NULL pointer, user-space must close connection */ + if (conn->socket == NULL) { + csp_conn_close(conn, closed_by); + csp_conn_enqueue_packet(conn, NULL); + } else { + /* New connection, userspace doesn't know anything about it yet - so it can be completely closed */ + csp_conn_close(conn, closed_by | CSP_RDP_CLOSED_BY_USERSPACE); + } + +discard_open: + csp_buffer_free(packet); +accepted_open: + return close_connection; + +} + +int csp_rdp_connect(csp_conn_t * conn) { + + int retry = 1; + + conn->rdp.window_size = csp_rdp_window_size; + conn->rdp.conn_timeout = csp_rdp_conn_timeout; + conn->rdp.packet_timeout = csp_rdp_packet_timeout; + conn->rdp.delayed_acks = csp_rdp_delayed_acks; + conn->rdp.ack_timeout = csp_rdp_ack_timeout; + conn->rdp.ack_delay_count = csp_rdp_ack_delay_count; + conn->rdp.ack_timestamp = csp_get_ms(); + +retry: + csp_log_protocol("RDP %p: Active connect, conn state %u", conn, conn->rdp.state); + + if (conn->rdp.state == RDP_OPEN) { + csp_log_error("RDP %p: Connection already open", conn); + return CSP_ERR_ALREADY; + } + + /* Randomize ISS */ + conn->rdp.snd_iss = (uint16_t)rand(); + conn->rdp.snd_nxt = conn->rdp.snd_iss + 1; + conn->rdp.snd_una = conn->rdp.snd_iss; + + csp_log_protocol("RDP %p: AC: Sending SYN", conn); + + /* Ensure semaphore is busy, so router task can release it */ + csp_bin_sem_wait(&conn->rdp.tx_wait, 0); + + /* Send SYN message */ + conn->rdp.state = RDP_SYN_SENT; + if (csp_rdp_send_syn(conn) != CSP_ERR_NONE) + goto error; + + /* Wait for router task to release semaphore */ + csp_log_protocol("RDP %p: AC: Waiting for SYN/ACK reply...", conn); + int result = csp_bin_sem_wait(&conn->rdp.tx_wait, conn->rdp.conn_timeout); + + if (result == CSP_SEMAPHORE_OK) { + if (conn->rdp.state == RDP_OPEN) { + csp_log_protocol("RDP %p: AC: Connection OPEN", conn); + return CSP_ERR_NONE; + } + if (conn->rdp.state == RDP_SYN_SENT) { + if (retry) { + csp_log_warn("RDP %p: Half-open connection detected, RST sent, now retrying", conn); + csp_rdp_flush_all(conn); + retry = 0; + goto retry; + } + csp_log_error("RDP %p: Connection stayed half-open, even after RST and retry!", conn); + goto error; + } + } + +error: + csp_log_protocol("RDP %p: AC: Connection Failed", conn); + csp_rdp_close_internal(conn, CSP_RDP_CLOSED_BY_PROTOCOL, false); + return CSP_ERR_TIMEDOUT; + +} + +int csp_rdp_send(csp_conn_t * conn, csp_packet_t * packet) { + + if (conn->rdp.state != RDP_OPEN) { + csp_log_error("RDP %p: ERROR cannot send, connection not open (%d)", conn, conn->rdp.state); + return CSP_ERR_RESET; + } + + while ((conn->rdp.state == RDP_OPEN) && (csp_rdp_is_conn_ready_for_tx(conn) == false)) { + csp_log_protocol("RDP %p: Waiting for window update before sending seq %u", conn, conn->rdp.snd_nxt); + if ((csp_bin_sem_wait(&conn->rdp.tx_wait, conn->rdp.conn_timeout)) != CSP_SEMAPHORE_OK) { + csp_log_error("RDP %p: Timeout during send", conn); + return CSP_ERR_TIMEDOUT; + } + } + + if (conn->rdp.state != RDP_OPEN) { + csp_log_error("RDP %p: ERROR cannot send, connection not open (%d) -> reset", conn, conn->rdp.state); + return CSP_ERR_RESET; + } + + /* Add RDP header */ + rdp_header_t * tx_header = csp_rdp_header_add(packet); + if (tx_header == NULL) { + csp_log_error("RDP %p: No space for RDP header (send)", conn); + return CSP_ERR_NOMEM; + } + tx_header->ack_nr = csp_hton16(conn->rdp.rcv_cur); + tx_header->seq_nr = csp_hton16(conn->rdp.snd_nxt); + tx_header->ack = 1; + + /* Send copy to tx_queue */ + rdp_packet_t * rdp_packet = csp_buffer_clone(packet); + if (rdp_packet == NULL) { + csp_log_error("RDP %p: Failed to allocate packet buffer", conn); + return CSP_ERR_NOMEM; + } + + rdp_packet->timestamp = csp_get_ms(); + rdp_packet->quarantine = 0; + if (csp_queue_enqueue(conn->rdp.tx_queue, &rdp_packet, 0) != CSP_QUEUE_OK) { + csp_log_error("RDP %p: No more space in RDP retransmit queue", conn); + csp_buffer_free(rdp_packet); + return CSP_ERR_NOBUFS; + } + + csp_log_protocol("RDP %p: Sending in S %u: syn %u, ack %u, eack %u, " + "rst %u, seq_nr %5u, ack_nr %5u, packet_len %u (%u)", + conn, conn->rdp.state, tx_header->syn, tx_header->ack, tx_header->eak, + tx_header->rst, csp_ntoh16(tx_header->seq_nr), csp_ntoh16(tx_header->ack_nr), + packet->length, (unsigned int)(packet->length - sizeof(rdp_header_t))); + + conn->rdp.snd_nxt++; + return CSP_ERR_NONE; + +} + +int csp_rdp_init(csp_conn_t * conn) { + + csp_log_protocol("RDP %p: Creating RDP queues", conn); + + /* Set initial state */ + conn->rdp.state = RDP_CLOSED; + conn->rdp.conn_timeout = csp_rdp_conn_timeout; + conn->rdp.packet_timeout = csp_rdp_packet_timeout; + + /* Create a binary semaphore to wait on for tasks */ + if (csp_bin_sem_create(&conn->rdp.tx_wait) != CSP_SEMAPHORE_OK) { + csp_log_error("RDP %p: Failed to initialize semaphore", conn); + return CSP_ERR_NOMEM; + } + + /* Create TX queue */ + conn->rdp.tx_queue = csp_queue_create(csp_conf.rdp_max_window, sizeof(csp_packet_t *)); + if (conn->rdp.tx_queue == NULL) { + csp_log_error("RDP %p: Failed to create TX queue for conn", conn); + csp_bin_sem_remove(&conn->rdp.tx_wait); + return CSP_ERR_NOMEM; + } + + /* Create RX queue */ + conn->rdp.rx_queue = csp_queue_create(csp_conf.rdp_max_window * 2, sizeof(csp_packet_t *)); + if (conn->rdp.rx_queue == NULL) { + csp_log_error("RDP %p: Failed to create RX queue for conn", conn); + csp_bin_sem_remove(&conn->rdp.tx_wait); + csp_queue_remove(conn->rdp.tx_queue); + return CSP_ERR_NOMEM; + } + + return CSP_ERR_NONE; + +} + +void csp_rdp_free_resources(csp_conn_t * conn) { + + csp_bin_sem_remove(&conn->rdp.tx_wait); + csp_queue_remove(conn->rdp.tx_queue); + csp_queue_remove(conn->rdp.rx_queue); +} + +/** + * @note This function may only be called from csp_close, and is therefore + * without any checks for null pointers. + */ +int csp_rdp_close(csp_conn_t * conn, uint8_t closed_by) { + return csp_rdp_close_internal(conn, closed_by, true); +} + +static int csp_rdp_close_internal(csp_conn_t * conn, uint8_t closed_by, bool send_rst) { + + if (conn->rdp.state == RDP_CLOSED) { + return CSP_ERR_NONE; + } + + conn->rdp.closed_by |= closed_by; + + /* If connection is open, send reset */ + if (conn->rdp.state != RDP_CLOSE_WAIT) { + conn->rdp.state = RDP_CLOSE_WAIT; + conn->timestamp = csp_get_ms(); + if (send_rst) { + csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); + } + csp_log_protocol("RDP %p: csp_rdp_close(0x%x)%s -> CLOSE_WAIT", conn, closed_by, send_rst ? ", sent RST" : ""); + csp_bin_sem_post(&conn->rdp.tx_wait); // wake up any pendng Tx + } + + if (conn->rdp.closed_by != CSP_RDP_CLOSED_BY_ALL) { + csp_log_protocol("RDP %p: csp_rdp_close(0x%x), waiting for:%s%s%s", + conn, closed_by, + (conn->rdp.closed_by & CSP_RDP_CLOSED_BY_USERSPACE) ? "" : " userspace", + (conn->rdp.closed_by & CSP_RDP_CLOSED_BY_PROTOCOL) ? "" : " protocol", + (conn->rdp.closed_by & CSP_RDP_CLOSED_BY_TIMEOUT) ? "" : " timeout"); + return CSP_ERR_AGAIN; + } + + csp_log_protocol("RDP %p: csp_rdp_close(0x%x) -> CLOSED", conn, closed_by); + conn->rdp.state = RDP_CLOSED; + conn->rdp.closed_by = 0; + return CSP_ERR_NONE; + +} + +/** + * RDP Set socket options + * Controls important parameters of the RDP protocol. + * These settings will be applied to all new outgoing connections. + * The settings are global, so be sure no other task are conflicting with your settings. + */ +void csp_rdp_set_opt(unsigned int window_size, unsigned int conn_timeout_ms, + unsigned int packet_timeout_ms, unsigned int delayed_acks, + unsigned int ack_timeout, unsigned int ack_delay_count) { + csp_rdp_window_size = window_size; + csp_rdp_conn_timeout = conn_timeout_ms; + csp_rdp_packet_timeout = packet_timeout_ms; + csp_rdp_delayed_acks = delayed_acks; + csp_rdp_ack_timeout = ack_timeout; + csp_rdp_ack_delay_count = ack_delay_count; +} + +void csp_rdp_get_opt(unsigned int * window_size, unsigned int * conn_timeout_ms, + unsigned int * packet_timeout_ms, unsigned int * delayed_acks, + unsigned int * ack_timeout, unsigned int * ack_delay_count) { + + if (window_size) + *window_size = csp_rdp_window_size; + if (conn_timeout_ms) + *conn_timeout_ms = csp_rdp_conn_timeout; + if (packet_timeout_ms) + *packet_timeout_ms = csp_rdp_packet_timeout; + if (delayed_acks) + *delayed_acks = csp_rdp_delayed_acks; + if (ack_timeout) + *ack_timeout = csp_rdp_ack_timeout; + if (ack_delay_count) + *ack_delay_count = csp_rdp_ack_delay_count; +} + +#if (CSP_DEBUG) +void csp_rdp_conn_print(csp_conn_t * conn) { + + if (conn == NULL) + return; + + printf("\tRDP: S:%d (closed by 0x%x), rcv %u, snd %u, win %"PRIu32"\r\n", + conn->rdp.state, conn->rdp.closed_by, conn->rdp.rcv_cur, conn->rdp.snd_una, conn->rdp.window_size); + +} +#endif // CSP_DEBUG + +#endif // CSP_USE_RDP diff --git a/Program/libcsp/src/transport/csp_transport.h b/Program/libcsp/src/transport/csp_transport.h new file mode 100755 index 0000000..431deac --- /dev/null +++ b/Program/libcsp/src/transport/csp_transport.h @@ -0,0 +1,48 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _CSP_TRANSPORT_H_ +#define _CSP_TRANSPORT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** ARRIVING SEGMENT */ +void csp_udp_new_packet(csp_conn_t * conn, csp_packet_t * packet); +bool csp_rdp_new_packet(csp_conn_t * conn, csp_packet_t * packet); + +/** RDP: USER REQUESTS */ +int csp_rdp_connect(csp_conn_t * conn); +int csp_rdp_init(csp_conn_t * conn); +int csp_rdp_close(csp_conn_t * conn, uint8_t closed_by); +void csp_rdp_conn_print(csp_conn_t * conn); +int csp_rdp_send(csp_conn_t * conn, csp_packet_t * packet); +int csp_rdp_check_ack(csp_conn_t * conn); +void csp_rdp_check_timeouts(csp_conn_t * conn); +void csp_rdp_flush_all(csp_conn_t * conn); +void csp_rdp_free_resources(csp_conn_t * conn); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Program/libcsp/src/transport/csp_udp.c b/Program/libcsp/src/transport/csp_udp.c new file mode 100755 index 0000000..c989619 --- /dev/null +++ b/Program/libcsp/src/transport/csp_udp.c @@ -0,0 +1,50 @@ +/* +Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "csp_transport.h" + +#include +#include + +#include "../csp_conn.h" + +void csp_udp_new_packet(csp_conn_t * conn, csp_packet_t * packet) { + + /* Enqueue */ + if (csp_conn_enqueue_packet(conn, packet) < 0) { + csp_log_error("Connection buffer queue full!"); + csp_buffer_free(packet); + return; + } + + /* Try to queue up the new connection pointer */ + if (conn->socket != NULL) { + if (csp_queue_enqueue(conn->socket, &conn, 0) != CSP_QUEUE_OK) { + csp_log_warn("Warning socket connection queue full"); + csp_close(conn); + return; + } + + /* Ensure that this connection will not be posted to this socket again */ + conn->socket = NULL; + } + +} + diff --git a/Program/libcsp/utils/cfpsplit.py b/Program/libcsp/utils/cfpsplit.py new file mode 100755 index 0000000..985c98c --- /dev/null +++ b/Program/libcsp/utils/cfpsplit.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +# Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +# Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +# Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# Split CFP header in protocol fields + +import sys + + +def usage(): + print("usage: cfpsplit.py HEADER") + + +def main(): + if len(sys.argv) != 2: + usage() + sys.exit(-1) + + try: + hdrhex = int(sys.argv[1], 16) + except Exception: + print("HEADER must be in hexadecimal format") + sys.exit(-1) + + if hdrhex > 0x1fffffff: + print("HEADER is not a valid CFP header") + sys.exit(-1) + + print("Source: {0}".format((hdrhex >> 24) & 0x1f)) + print("Destination: {0}".format((hdrhex >> 19) & 0x1f)) + print("Type: {0}".format("MORE" if ((hdrhex >> 18) & 0x01) else "BEGIN")) + print("Remain: {0}".format((hdrhex >> 10) & 0xff)) + print("Identifier: {0}".format((hdrhex >> 0) & 0x3ff)) + + +if __name__ == "__main__": + main() diff --git a/Program/libcsp/utils/cspsplit.py b/Program/libcsp/utils/cspsplit.py new file mode 100755 index 0000000..037871d --- /dev/null +++ b/Program/libcsp/utils/cspsplit.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +# Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +# Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +# Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# Split CSP header in protocol fields + +import sys + + +def usage(): + print("usage: cspsplit.py HEADER") + + +def main(): + if len(sys.argv) != 2: + usage() + sys.exit(-1) + + try: + hdrhex = int(sys.argv[1], 16) + except Exception: + print("HEADER must be in hexadecimal format") + sys.exit(-1) + + print("Priotity: {0}".format((hdrhex >> 30) & 0x03)) + print("Source: {0}".format((hdrhex >> 25) & 0x1f)) + print("Destination: {0}".format((hdrhex >> 20) & 0x1f)) + print("Destination port: {0}".format((hdrhex >> 14) & 0x3f)) + print("Source port: {0}".format((hdrhex >> 8) & 0x3f)) + print("HMAC: {0}".format("Yes" if ((hdrhex >> 3) & 0x01) else "No")) + print("XTEA: {0}".format("Yes" if ((hdrhex >> 2) & 0x01) else "No")) + print("RDP: {0}".format("Yes" if ((hdrhex >> 1) & 0x01) else "No")) + print("CRC32: {0}".format("Yes" if ((hdrhex >> 0) & 0x01) else "No")) + + +if __name__ == "__main__": + main() diff --git a/Program/libcsp/waf b/Program/libcsp/waf new file mode 100755 index 0000000..4df5cdd --- /dev/null +++ b/Program/libcsp/waf @@ -0,0 +1,173 @@ +#!/usr/bin/env python +# encoding: latin-1 +# Thomas Nagy, 2005-2018 +# +""" +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +import os, sys, inspect + +VERSION="2.0.18" +REVISION="96675f149f50dab16c9e2e6aaf5e787b" +GIT="ea17399be6950863390fb7bf25b747b67afe0ce3" +INSTALL='' +C1='#/' +C2='#-' +C3='#)' +cwd = os.getcwd() +join = os.path.join + + +WAF='waf' +def b(x): + return x +if sys.hexversion>0x300000f: + WAF='waf3' + def b(x): + return x.encode() + +def err(m): + print(('\033[91mError: %s\033[0m' % m)) + sys.exit(1) + +def unpack_wafdir(dir, src): + f = open(src,'rb') + c = 'corrupt archive (%d)' + while 1: + line = f.readline() + if not line: err('run waf-light from a folder containing waflib') + if line == b('#==>\n'): + txt = f.readline() + if not txt: err(c % 1) + if f.readline() != b('#<==\n'): err(c % 2) + break + if not txt: err(c % 3) + txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) + + import shutil, tarfile + try: shutil.rmtree(dir) + except OSError: pass + try: + for x in ('Tools', 'extras'): + os.makedirs(join(dir, 'waflib', x)) + except OSError: + err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) + + os.chdir(dir) + tmp = 't.bz2' + t = open(tmp,'wb') + try: t.write(txt) + finally: t.close() + + try: + t = tarfile.open(tmp) + except: + try: + os.system('bunzip2 t.bz2') + t = tarfile.open('t') + tmp = 't' + except: + os.chdir(cwd) + try: shutil.rmtree(dir) + except OSError: pass + err("Waf cannot be unpacked, check that bzip2 support is present") + + try: + for x in t: t.extract(x) + finally: + t.close() + + for x in ('Tools', 'extras'): + os.chmod(join('waflib',x), 493) + + if sys.hexversion<0x300000f: + sys.path = [join(dir, 'waflib')] + sys.path + import fixpy2 + fixpy2.fixdir(dir) + + os.remove(tmp) + os.chdir(cwd) + + try: dir = unicode(dir, 'mbcs') + except: pass + try: + from ctypes import windll + windll.kernel32.SetFileAttributesW(dir, 2) + except: + pass + +def test(dir): + try: + os.stat(join(dir, 'waflib')) + return os.path.abspath(dir) + except OSError: + pass + +def find_lib(): + src = os.path.abspath(inspect.getfile(inspect.getmodule(err))) + base, name = os.path.split(src) + + #devs use $WAFDIR + w=test(os.environ.get('WAFDIR', '')) + if w: return w + + #waf-light + if name.endswith('waf-light'): + w = test(base) + if w: return w + for dir in sys.path: + if test(dir): + return dir + err('waf-light requires waflib -> export WAFDIR=/folder') + + dirname = '%s-%s-%s' % (WAF, VERSION, REVISION) + for i in (INSTALL,'/usr','/usr/local','/opt'): + w = test(i + '/lib/' + dirname) + if w: return w + + #waf-local + dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname) + w = test(dir) + if w: return w + + #unpack + unpack_wafdir(dir, src) + return dir + +wafdir = find_lib() +sys.path.insert(0, wafdir) + +if __name__ == '__main__': + + from waflib import Scripting + Scripting.waf_entry_point(cwd, VERSION, wafdir) + +#==> +#BZh91AY&SY���[����P�����������e�(¬#)0�Z0e#)�b�AG�PvmͰteN�`;6�Ti���Ҋ�#)i��:��G#/�w`N�#/��E=��FA �JQJ ���IJ$�@#)*�����#/R��gy�>�ǵU=W��w�^�n�&gsTTv��%%�����ts�ꏠ�n��w������ ׺��z��t���϶�}�|�����M}�{���;�<��Gp�\�a )귖y�`0=�#-d;`��t�Oy�����w�w:�hP��#0�[2H�����0PIE)@�zz#)͢����Y����jT_w�������{��@�h��[N�jQrƁ�{�3`7޽��tP��m��kwn�b�9В�����M����:Ӡ"���I���������3m�:�{�=�[�n�;�j���=������I9��;��v�[����؎��y[c��T�n���{�=����{g�h�lt�����u�V�<)M���lm�ٯn�{7mZ��6�kn&=��_f������^�<��87m�s�wZo#)�OW�������ޫ�8z�#)TJ�d%-A�������l�;짼�뻔� 3��guُS��p�n�����i����4 ���s]��#)�λH#)(�]�^^��٘�׶eZ�i���w���nh��'iN��}���s}ۏf��3b�M��s�gh�qo/]�]n����zs;mWVǷ����[�y�71ϗ��ϳ#-��w��a�.������w��|�Ӳ`������ћXd��P^�Y4r�/i���`��l����z���fq���uy��g�#)0��US��i�����Ѧh��\���ױ�N�}m��Wn���˧���ke��r ��}Ϫ���h��=d(�o07tׯ:�m��eb�uA8q���]��k�{����a�:W�0{�#)wb&�����>�7���P5����{b�����Oq���ֻ�K��*�o���ix��]���n�wZ�l�)ݶ�}W51�N���c�/@��^�|w���컛 w}!}�2i�}�=�k��#i�ݛ��^�^�[��ɾ���d+���x�}�}��}�#-�_�  �#)�#)��&LF��'�b���C@4d4�56I�~�%4A �����h��<"53P�@#)�#)#)�DAi�6�&��������S�O�x�x���A�ꞣC�#)�2#)#)#)��)" �j`�h���?P�ѵ#)�C@dѠh�#)#-#)#)#)#)I  #)&��MmF�bdɩ2���#)#)$�D#)�44(�&��T�ҟ�=�?J7�mM��DѠ��#)#)>_�G�UV�0�Z檊��]����.�D�3�U�R�Eb�,���k�mU���ɤ?A����m�?N����vq�e31=��LV �2�z� x�U�T�1��E�?�{���#/�G8#@��{ho����"�4r���AT �,y��]�eJ���y�x�S���>"걉&țZ���eλ�?��r����A� 4�R�uv�M�������"��#)�p���'9�YBD��h���b*�PE #)��#)=���aim�Wt[���j�U��V���2J35#-3M�4`�I��D��"X�ԥQM��#/&h �A(�jj5F��m��i�F�h�5�M�4#)m�404ŕ6�I�Z6�(JYiM5�!e�6h& �31�I�F�d�#-)�E ��%a�K-#Jm�l�m6��VѦbK�3!4D�2ɶ�m4�Ԕl����Z�l͙i2L�PTE��E��#/dQ�$m�E�F�I��Q ��b���TD)���B�DIb��$mH���A#-�42H�� fAK+,��Idb)d�M��4L*E�,�$h���&Ĕ�ehɡ�&$%D�4�Y64I"��KH"��lk$3b$�436 ��ڒ�$���X$���%����$���(�E"��(0 �2JaL�2�Rj,͍�F�RD��KJl�!E�؀�Y�R6d�M��؉�")Fl��2��$�YJ#-��d�M461�Y,��D� �M$�R0٦@��BMI,�(1��f��PE4�D֠X L��Idd#JL���e"Th�&m(i1Pl���B@E&c$�h"Y!��L���1F�KbQ2�LB���B��*H��I�M�1���4�L�b�e$)30)def� X��D��jd�2#/CDR4b��jT�%4R#&2dSi#/,��Q���E*�I1$�Sh�j4�4��1�L��L��63Y ��14���" M���(�B�2�l���`2Hi,��j���&��I���bA�e����H�M�R�P(�0Г2�He�dFS�Y�Jcj#- d�DHh�mMmh�2���L�M(���Z#-Jm�K4Y�M#(K,��DZ�X[(Ć)��4�F����#k���a�͢�lVƶ*6L�4�R��44����F�5Y���c(�S*H�D���[%�Q�IKQ���&�D�5���cR#/e��2eI�*�4T�B+d�"�T�T›63��,Y��L��S,��J��JSL�l����)��%�2R�Z���!�գ%AEVMd�j��EH�kD�$m�hŊ�l2ѵ����0�U@i��R �F2�&���ƍ�&��d�i ժ���* ��KY4IR1!M�lY"��Y�1Jm*�R�YaZ�DF��K"e5MM����k,Xl�k+,�l�  ��D��b�4��!��-�T%��KQY&�6L�J,�&��l�#-"+,�E1��J�l�4 AE��$&Fm6�F6��S��cE%bH��#!4L�Q�JdR��P5BT�4�� J��Bj-#/36�)F̤����!Hb�k�i4F5&�a $YP�-4) Ě4Y�ٔ����d�a�,�� jE��5�4ECF�4�#-1R�fQj4  2�A�&ĕ%I�1R�cd���a)ME`�0٤�lf�E���CJ2Zf��hT�2�H�lق!�M#b�5�M������JHH-�a*5�1Xţ2�i0�I�Bɑ��QlQ�%���b�fQ�FCd���2"�6��cTj�4P�eQAb� 5&��0�,#�(j��iM2�QF�"��Z �Qb,FR�ȩEQ�i0DY4E3(Z�R��*lJ"eZ�ՃEL�J��#/b�(�L��kI�J�m�-�chh�$�A���� ���(�4I��m�$5�0A�2`�B�Jl͉����*ed�di#/i&��(���ԕ�e$��b(Ѡ�& ��"4ZYh�j$�Z��e(�Ml�!Tm�IE�E4&E23#1��F#S6I��Ib�5%K*ɭ6� [�(���QL�iV6��cm�[Rf2�BY��KQ�ŚTmDm*TR����f���#-,%F�lkeI���&�I��F�#-1h�ƍ���[V)*Q�`!�F�4�ja���m�lZf���ZJ�ke,�jjm����V&����I(��k5&���eDP!Q&$�)&Ddb2l��f[F/�||��!)���#/r� g�ᬌ�S�R�o~�+�#/���� {>#/������h�l��z����9���z���Sw*��7�ˋ���!��#/����#)�D(0\:8���p�I �m��'�cD���H���8g�?�֏�J���/e�+)#|����[s��*�l=�_���:� eC#����X���;��a�8�"��8��'%�����5'#/�-�����]�&�dƈ6?F�����d�;�&7�]��W�x�,�r��]y�fsW �a�B��M^,�2�ٍ.e�) ILM6 ��Ő�1�gQ�]� �-�#7���D��� ��k{���vXS#)��_?m��,�:.k�דG�X_��Kb1�O��.�{>��G���N�V�QL0�ФY;�d���4D��χ1�1��<�I�J<�r��F�X��ж (D0�V+��n{76\�W(�T�T��v�0����խ��,3ۼ��w���,���m���$�؟mF� i���=�@�Ⅷ�nE2�.E�7.C�M֯�zx#Q�~~� ���� ��y2�Fm���ꠊ�a=WR9r��2#-�!7�0mxNwDFԣ+ousF��k�Wyݍ�:W.d�.����d|���׌� ���<��\�#-�؇�&6�SC<6�]2rjł��)G֓Oܹ6��C�˵3�@�?��tiK�I�P�C��0 ��bV��MX ����_n q��C#-��fL��uB�w*-�dlA쯃#���{�rH�Ȧw�Ԋ�b���=�yn�9:�Y����i�aCG/���5 �y�u혬�?��>��95�ï�~�z_�;wkt��ΡITm S!�YS�7L���0�=��F�&�����K�>�)Z�M�`RtiP;襈�3����,T�Yˈr�$���e�q��&���2�}�4�:�ț�����ȱ��o��"����ETP�1��PX����+W�#c�R�Q4iї�E�U�9h1�R�m+�+_#/�N�2���h���W��&�xڹ�?��j��@�C(W� V?w���}�n�gunm(`�>?��k�YĦ���ݹ]���t�)���9]e)2%9JUS�梶/]���W�)VJ��ܱh�ݖ�����q���3�k�h:UP�SE��#'��cPi-��#|���ӓݾi����DF�q���J�� G~e��kf���L ���J$���:���д���e�u�X�4k��\��c�8��;j�<(��<�J)�"��)۾�do�S�B�#/�rr�Ӻ�5��_;�����W��夔|/ �d�(��F���lZj�ڔ�."��T��\x�[Ebua��X��@���ENHQ�T�}�~t��(O�9�lXtA)��\��s,1P����=��D9z��01�v�9�Ňo�)kG�A�kٯo���b�)3#/3#H3�T�/�dn ���bG�Ӻ����7�w�݆?�H�j�d$51���SZ�j�����}��y�]�\�3~��#/ᤎ������d��"Xܑ��4�,�X}Yn�0�g���g�k�8�.�|b���A��#{�S�<��#/t�����‰ɣ�JU;���x��S#-�L3�����v���+���T,�x���m���J}7�M���b�Z�����͆�y�ai-�j- ���1I�-��7b�e ��R�A�8{�Ɣ���L�|"=`k\K�^��t�6�TႰ��B;�'xo�^���֫��+�#7&�!{�]�\k�����r�C�Ŷ{�Cls��>v�s-u���}�:섒H���T��JS�ၶ,1��4�K���X�2}Ȳ�=9zC}N�ez��|��+J��E1yw�X�5 bw������( Ð��"I����X@�+[q�����f6�q6>�uX�dE���(��i�;�w�[9����u25�^/�Cd5DT�'������[7�Љ*U�!VT���օ�J+9]z�Ѹ���u5�&�]����_�B�R��#/QR>W�K������i��;�RW��W���Kb�"��QV�#AE�T�|����Ϳ��o�G�չV�l�ϩ�\�(/�r�H����c�Ѻ�#/�Ѩj�vYBw������d �E��^`^s������La>����f~�Ua����nq� �!_)���N��j'6ʴO�b\�R�u616�O��0�"A�lg8��@2��I�tӿ;������EEB`f�����H���X��E��':��jҦ�>;�1�.�����7��D�򳹢�2���I �ڔ2Ҹv����齇-�'���mv�#/cϼ����N'\�3 ��w��]!�P��W|T�W�&1QOŔ������ԛ�$v���B�}���������,�_U���c�*Ή���֏M�H���e(+vteFW=u�����/~.�e#gFY7'ǻ�����cMd_�?��2�e���m�&y�Y򯥳L�S~(��v��,��v�Qh�#�y���Ds��3�2L�J\95��kvv=D��/N��u��s-��e�1��g&���n.���1��� ��+Z+g1U 1�!Q ��Y�>�P�*�#-ʢ2,S�\&���N믯�M5^���]�1�T�LC���ׇ���T-�V��˂���¤X�#-��4����$�����~��a��c?�-������JIˎ��4ތ;:b�Ӡic��8E�7W��O�7�•�r�Jd���SB^sƪ�q��f��a��� �y�Z����N�G�^b^�:���3�y��f��)!�ls5S�X����1��ê��޻}$������(��W��7�"�I�IDp]��f���m�=�`�MF0T٧ܠ��1�ȥ>Ol5�Q��ת����F��_?��F^Ah�|Km�5=�-�,p��#-�nu�Uk� 2�(�5�Bʪ8�����X#/�U�a���ˎC�b� ֔^�=�x��P/o�#)>>3�3c�4�D��D���;L�w=P�u�7�V^-Eu�W���{�QSG� ����P��$���?p��U�R��EW�ɶ)օZv�q�[v>v=�_#��G��o2��~��ˌ�e�K�K�|q�+�����wp�Ώ�T\�z�G��<c��/Y������ YMh=ɿ�R)9:sI�Ǫ#� U� ��Kd�{k�#-��;�ݼno%���x9d{�M�xb�Z�� z�������iG�3F,E���6�%UD�l�;�)]q}(�d7r�:�f2�٨ Q#-�rA�fR#DT1�h���ʱAi��$h�Y�z ��ˍ ��w����D�`!gxe�K_<9aّ�ȷ�(�H���j��y%2,�o!#)�Gԏ�-��lu�X~u#-�r>2vcH�������Qp烄ݵ�Ҕ��mXt٬`���Ҍ&�eU WƂ�V"��Ԟ��f��L+��"�?S�mk�@���`O���@c�����-T�S�1��-9��;���Dw��V�o����ƪ�~�G]��d��y�mqK��zvu���d#/���/�x@�;+�[7ڎu�wm���#)Ct����8FP��#+�c*kma�n*���Q��N�L�^ph�&�����'�ӦK<�q֡����'�0�b'xH�1�3d����]�������'��)����M:f9�l� ���1_ t(��:8�c1�f�^r.u��� �"�%L��'mC�ѷ��o��V�������po'� �� G�g_�҉��ct�w~J��5�Z��s�D'K( ���T84�՘�-[���֢Pl�Pm65s��޺�k�]R��5x�ݹ�N�"�W\�u��fƬ&֘�������9O�㏇�����э���Z��ҫ��|v���Y��g���Ů! |� ~�5BB���h�#)#)�`#)�D;�cp�/��5~e�йB�ʴ��������ޣA�е�ȷ���k��d���}F��֯�*z ���#--�E���T�ouDv�Ll�6�'d�ì�ꄆk0yìf#-r��ldiɫW�m��-G� �z��4�]ŷщ!�w|�R貎]�^���6�����n����(E+�dX(�#/��bS1!�,�go�\���S�5�r����`����tS���L�кFe�U@/�=��Nu��ʍ �q�� m�|2d�߱�i����W&x��-SQ�u� �h���c��sد�ʝ/y�k��]*8�b�_�̼�=�\���da����O��Qӹ��j���3��I˸�}��;q�������x��Ҩ��?���q�{�% �h+�W �Hm�x'L�^I��Uo�XkF���t��A/|+�yVM!%���w��mi��%f���w夏ҵ�~�yn��B�'��k��Y?#-��Ɗ��F�H8Ν��I�����N��7��є�V��{�6@�`�ҏ6�����uqvL�ڵ� KJN��Nݛ�{iP%�1!��?`pfp9�}��/wN����a]Y��a���,\���B���R�����/!�rf$�(:?��s��"pc#/7��{`��9v���R�g�" %`��"��∱#/hY��iܖ��f�8L9�7�O��qۋ��I��fjا��6�}���.^lnk�����e�_��['E�Dx�����!�P�嵼P�����z� �~��iӜII�,V�.,�6>�:ה�yA�6��v��`�Ԥ�?j�����:�?O!�Ĕ�h�2{-���� �|��g��DA������A�/�h���;�&9(�}���t�!bՕ0Y��of�<(D>�#-�)#�K�Ž�NvT뎉�!#)�% y �ft�9���Ნ��%^��#D�l��ڃ:�T`�)6�3�V:7LwA�&�訜�`5�H���XʎZ_r D�8tNe�hi%�5�@YG���y��w�_�A=;'^�c��.����i`��ey>˥;zx��X%޽n���t҈�yo����\����1;P��9�ts����.ĵ������,1��X���qs����N�ǤҜ�4�j~�o�u>4� �#�ʢ.�(Y���s���1 �Y�[�e �h��^�$����0vѾ��lvr�yE������8J Ȭr����sk6hP�#)�d�����ƾ(6�͂���B�P�|�-�nwo����B���0��+���&7���d?\�����N�Dg5 �*�G/�?��F�i��m�Ö%��N)�8�����2�C��F��X 8�L��;�P���07X���ǏV�0���#)&�~��������H��=�νT@��rܧ+b��U�T=��$S\�<��(��E���PY�y���"�2n��ק����tz�#-� ��(��J���_�)��4�wE�##)���PR�DJ�^��mN�k[�PDR #)� $��e�~�%���lQ��t�o]҄��������,:OB�#)�����,;�Ǘ�CH��EXQ��6����בj>���ER=S�:�s|4jG���m�fտ.�4����j]����:;��.�>���:�v@0� )���f���۶_P�(>��qQ�+��~7�o��9�$#-Mk�S�#3��^E푻�����Ƌ�0Y��D����;�|Z�s�r����3��~���m�!&L�!BI@�4 -���)R`���a�ȥ�c.�gՋT� 8)������.�:�7B�zϻ���;#�l�� P���C�I�%�{ܥ�*����%�8���C�`�0u��^�J�4ZMI:�rl�Y�����T���T�ho�° �����)@���Ž�-�20��SBkM�>K^����[�g2,��̣K�/r��Pi+$�0�pq ��{ؑ��;��(��c���$�ה����7�#�o.���ۖ���93O~[#8I��8�U�3#)��#-Yz�B�K���̳x=~r�P=�dA��R�5�}j �VI�魳�Lg�1al�����!_�a�IH�tii`�ٞs���3���!�}#�v%6g#{`,d��>o�,�ô�bOr4����>��z崎P��@۩9�X aa���(�%���z�o����ݶt8���J���ݬ����~����i3[�%t��<��}C|W ���a� i鲇�1�@*RGW���0��^f��z�y���l�#-3�i�Hs@��E��#)�/ #)��{e�TV��Ձ�������Sa@�����he5E�Y�� �2�+c%�2��#/���l��/%WEϱ�4FҖX��ީ���nθ~�:�s�E�p���*(~�����s��ꆄ�4�u�y!�#-���l�B��I:��;�˦�849���BÜ�u��J�8�b��W8R�ʁ�� 2z�=��:׭�F7h�R8�c����SPx��#/hF�/x�! �0Y�=��3�1��wL�^܎��F��U�M����Ľ�n$Ǵ�k�@�:���M,���}#-�d�Jۂ��/?�C�\�>�=N�:�}h��復���|k�8ts�58s��ɮW�8���P��#/��(�"��;R���ɷ�tb/]���̻]�֞;#1���Jd����[Gk��:�m �WM�1�Å����c9|����y!� �aL"��D)$CT�V� m�D���n ��`ҡq)E�������rY8���H���eޡ�bIM-���D�$l;^�pjr�pBi����2N��ԯk���`ި���� К���I(\Pb�0�`C�[!������'��ߌ��~� �C�[��.8TT)�h7�xɐ��#/x!���1�q���ߗ� lU��Ã�9':���w|��-eMG�WO��_�ƣ�ʭ��6�Nv���Ͽ��䥧`p�+��O�Bםm���u��q�2��y��#/��c�V���f�DwT�)���Ȏih�o�9*b����a�1G�}"hL��͍��R�P��\�7�t1�z�B�m��Ա�0�����$cFv/�-�0���d@�#)���奉c�6P���aF��=���z��|4��~���ٿA�p����%0X�#�j�ū�W������"�X�2ѷ�J��xѰh,���J���'����.��= 28.9R�Y-��h�R�d��n�9.5�L�6W<<���kS�"dXK-]j�T�a��>�[;q|w�+R~3�}U�{�C�|F�lߒ��BB�|l$�#�Q�a��c�g %(�����g=H-�׫���52�NM��u#M�<42@� 6���Aҷ}m?�ه��_�����M��v]�4-����t5��2�ICq5���.� �i*~�a �����vz���,6��#-�ؙ�*����q��8��G����~�����Tvk��=��O�'�4���J-h�bX�0FKg����� ��Y��������>��:� ; �����P�I��\�)����#�3�����5޶�ܽ1��64�0��X�PII&�w�VDVA�N��L@�2,*�� 6�Jd ::�a#- �u��l#-d�Q��E�$6T�u <��� ���#-�V�#Yk�#-)$դo.؅)ڊ"0ѥb��Q�Ѹ&b�̴�0�V�܌�e2�eCSJ�"� �@���y~�w��s4$�_��xwKw�!(n�r��Z�|����~��cH�\4��zdJX��mu^k�'����T4A�U�L�;���E�Ri�\�Dyb9iȦa�=�4����lצ�!����F7��-+���[#-#\!����.����}|�C1�ٸ�C&ǣ�"<��Q��q��BK�`�v�r�[�y��vb�OS%,,`���"�W��^���ф��>(d�#�,�\E&�!>P�r��m�C�#/6^�t���m��k��T'g�3ppkb8:B�,�\X(h|H�%lŔc �,;[#-�#1��>N#5G+���N��Ɏ��4�$���;>)͙n$"���ص7�S�ըx�:)x��؋F�gA�����g%�9��R��qT�F;D}w��v}��X�t�`n#)�� ���l�U���L�zYf�u��gX�G�#q�Ks8f:�F�!�k���si3[#/��z��62mFnj�K$!Qh�� PV��#-RL`�i��a�dt���#/�#}�E�,� 0�P�k��Iׁt���2�P������޺:�� 5e=� �|ϙ�۲#)��(7�y��տ��e:�=������-�o@}p�!�=^������ �B���e.�:T8i���X14 ������7�z3�� �b�R�QH�W���I۸��%��_�����m�G�Pp��=x��G�1�l���r�VܮR�����냈q��� ����a|��2�>��"j�&��TWdB�����(&es�x�c쇎�n�\��g�X�,�Pb�v�|?_�]�#-çH�ن1����ۭ�լ�ٹYoO5ө�WOK���ϫ�7�06�-�#-��c/�^��������Őo7T0�l=�X z���VA�E�����$yɬn���y���K��w[��f"a*l gкH%�T�s*�`Af ��t�q��A���,7���5��`����+#/���W�8��Sn��*�AjJۖ�~_��� u�����=>6XRi��>-��#)':(@H#/����wE�B�u����yQ��ܝ��ĉ �y�pr#�����#/��g���E3jK&�1�*X�_��bh�b�엣��E�U4T��Z���80�����+��|s���P����8mȥ+���(#/;%��mW�+��������j񠋛u��R�ή�^�����������e`��ѩ����)".������i>��>鮾��/�bъ�ݵ�ͣ_��#-�4��$�(@�̌x�����Q{(�#-oR��m�$���H"�]�TUS!<��u��}�9���cui��b)f@h�H6)��7?�y�[�ϼvC�?�H�0�`ʟ�xi�u�C,��u/���R��4}��J%�]5�� a��I��Խ���~���(_�?�v@E`�������p�r\N$� �9B�%8O��F�x��N�����#-#-���=���$�6p��05aB(a~��T���5AҸ��\�/�#)��*0Q��--���lm�g/V�0��,~2�9���௮����Rb�a�Q��!?Ki#-ݝ(�$*�Rh!0�V��!H#)1I[�d\T(�#/N=>4o��~�Ž�>����|��w��[��C��#�}H���||�*z�<��i���#+`�1�y���z_�.�E�wC��!~#)|B��f�ӗ0^���f�x~9w(�5"��#-���@r �2F׷�t\.�g>6,dy��D��3�D�] �l�~����ܗ�c]�7�)��ߺA���:����߫�;��� �d:�vP4���s�����H�]�h����1�3���H�(#/���� xP��Խ�]�#-[��+�F����#-�-�@=_ީ3'R��A��3Jh$Pᙿ )c���墏��f�� �G=����5���.R�!�#/B����c!nb�l�yC(����Y�p���O� ����6�+�У���������=�#G�t=�W�鞫�+�lA�.* ��˨#�뷗���Hn��VF�G#-�6Ӱ�9��X\���k��f�_�x�����a����ج[x�_9}�6�!�����d�����@�߬}-���;HO䲡�P?�B@p�~ �*̅yPIBv�z>�-�[옶*�ĄǸ�$M���\?�$y�1mHҡ[��?����ʶ_�Cw�u���=���0��mS��H��V~�%�4���� �Cc�������u��K�V�W�[@�*9�ie��č��h`,���ZZ��W��R��j��_��`O��z~=��WԱ\�jy˨�*y��^QL�HNCC�i��=�q�؟،?��,���R�sC���K*�Q�������K�b�)#)��Wݟ�i�i�GH (�"D��2�����7U��?�Ow����OW���}&ݜ��������>�e�3|�M�W~�)u}M����W��G�cAKk���\ڬ�w��e������#���}�?=�;Ov��g�.[���z!�"�Zj����×[T�xϗ�y�I��Ž:�������:ݶ+�V���E���V�����]���y#-���.nYh��{���pm\\,3���_^����V�59���{#-��C������}�� qH#-�߽�E{3���t���/�>w��~/�㊛$%�C�yz1K��6�̶S�t[F<�k�f72tS�?��l�Q�α�@e��\����#-��ә9a���lc#-5m_+ƙ���k٢7Z�#-1����[x[N�s��J�lkB�wt5ze�wNN�6~_�?������T��pP6rz�R��������捃~�g�G�*as�'�x�\�b�lB�2.s�U�?���F�6e�2w?.��,<{����D�,w;�D�^��M���{��;u�hx(a�DY'w��������.~�-R�$8��@��4?���a���Xc�������G�ef�zu?|{O���GR��x��� �e����w�i���DZ�0��3쾓��Á�)�edF�#o�U�W~W����}�ߤ[V�ٳ�k����a��莀����ۥ�t��̾�j���;э1�}p�t�����d幽��G5>����#/(���H�~J�6+��۴���ӣ0����δ�?o�3����t���F1����wR���f=�#-~�$���^�Jj� �ZG���ݔ(>wZ�$W�q#/:��|+�0 5����������ss�����&�K2�5�;��M�s����j��_���#-�~Y�� 슜�K.q�����6��k������V����`�,= �����p���DZn���"������A��/�-#/~�#-?~;x���>��;�������#/>��`:�O�!���{L�!#/� ��DO��BlF�%Aho�N�eg�������x �stm��K�M�؃䳻�����{�2d�I���} ����YBA�<}�Tc��☾�Z��I/���Hl����<���X#)Q��92%|��U%�`��i�A\�2J����ԓ��2t[���?��"�̍H�+�V3���>��y�ߢu���wu���,)�w7\8�ClR�Du0`4>�#��Ԉ�p��M-�78��]�����fp$�:� yG@�%�}i��ߣg�z>oPM�+���������Y4��`�[����xh!�^',���R��+�1�d�ώ��ְV�� Nm\�_6�6�{�浗��"���F��VSaclb^b�V�?�=�7x񮯽E�|��WF�9 ��6?i��E��xS�* ���A'��!G��v�[}γ�LÐ�II�E#/$um|@p�)��,�Ck6�ZT������"�����Ȱ�H��� �,~Mu��7sj~�E��D��x�� dW`n�)W��/�#/�Ea'JN<�s=N��EG�s���ϭ��a�(�Ѡ#/ߦ���-���_��;1���}�*G7c���ӻL�Z'�"d�����Ks6OS��h�|���ɇ�koL8�����?��Sja�<]��;���oC?����6]��=�h@�ԧbI;6>����K�c!�����cɚ�y�[�g�$���>� ���o �%�{t)$�,F:���4���͒�NY�$xz7_�uD�)揓����a�#)Q�{Lk/��1V�ϔ������<쿥d����s#jX݄��jA��aO��Q�j#-U�#�#�5(�D�� #D49�ń����ih,�B��t��!�Y���ՙf�On `�a���-����Aȱ�a�ILA�"hhn�)"�4�[VW�c��'φ����đu`\�j�5���w\Q��s4*��"О�V�6�b/��[��"?�9�gA((>���?��)�Y���Ś��Z�9+����r� �c �F6�,# D�����o�ǹ���~�F��#�#�E4E�#��3Y����ޠ�A�aR�D�!#-Z���m�ZI*UP��P�Y�O�s���q�����r�ӛޙ�����A��F���i|�-'�l�D����j�Uuw��u�_���f���WV�����%�u[?O����c�tC��V��<"��1N�����r����e#�<�"�!�V�u���4����,�eVMq�eo���9#-��C ��ڇ #/0�>�G�I ����]uG�<�~����ק٣O���Z�x�F�#)8g#/5U6�[���>�aL~�Y�w?VP��w�u~uw��\�3ܮ��������k��>�&5)n�|_�{�}^M��\4���}�sY�O���1l�@L/���0A�^u`QH�:�Z.8��v���zs�14fׁ�܅QmZ$V҆A�X�)�%<��#- ��xAVb�ƕi��i�ɲ(�v�k��ж�J��R��"��Pm��b��"��� ��\�YJ�g���0�Uj�4cj2#/Z�j�[*�c86�FH2#-Ӥ����f�k�!(��AS(����2�-�L�õ�sj�S@��:�F1,Șa�aYҨ����q�Բ��3�HZ7��KkA#)ek�ݧ`2�zXUֻ]b�0Q",�&T8T�${�1�TGHM&D��b%��Ů�!h"�9���*�L��:�%#��� W:?�� �|��AI$�9�%!���Ņy- �E�d�c=� ý=1��&h2�_���e�q������x�ܾ�Rv���?2���/V��ꇻ���o1��*c#�������>'������=z9��#-�%�a٭��)��oz�L�юe�������s���+�5�P^��/��<"l���9�k�=T�ެڬ3����&�ͥ�&�~?��r|��P���������s ����v�A#)_��${׫�ԎV�6T>pMh4/��\ˡAU$�̪���(�����4#)�#e���� $#��1�����'�-��J'���{��� �x�|t�j�aҝ �����n�X��De��Fأ,-*�~4��#-8�|��ǻb"5#�\\axqiF4�S��>},Y%ө� Hȑ#u0���M�V��:EA����1�=!�D�����1m@�z��Q�4ޝ#/T��^�Ѭ#-#)i-�Z �A8�:plo1��cs�WJ��T"9m��^Y;5����|�R�(,,�-�H��`~wp��?�����0���q��y���V�vm=�2|؎�_��J��`CT<��2+rn�d��ɠ�rҴ�uF:;H#�+�`� ��˜�PJ(#�CcPq����BF<]i���24>�:ۍ��FRv�t]Y��XH�Q�����LE��U�A��Etn9R��cx��Bq�j�x�d1LYC�8x�j0<�D#-0� ����S*�4�i��)X�C7�2�(����U#-"�QB_�f$��E���X���Ў��7�[m/ ���u�L���A�LF���Kb�V4�� �=�٠�D�n$DN׳&h�HZ1,sI��JY��b�)�op+�X� (G�I�H���_L�����.�m���_��y�[߉����ߎ@5��0.�棾0C��JRs�8e����ϩӑ�'��{��6�A���7n|�P�l}��X�G~�9��w%Ů���kb���w[m���}�cFS�ˑ!�vr��䂪��P-��%�<��E�w���u�O��m�c�.����3Q�&䊕t���=Xڭa�&2 �6ǭW$�s����Xiz����m�E��M��b����4ӓH��J�l�1H,X��ư(:�x�TglB��!�A|�lY�#/A��T��b�×�w�De�6��Tp���R�Y¡�M^�8�-a��#/8�;\;�$3� �#/�|_Ĉ���a�m犁��;����:��l���f�=�<�(��a4! ��D��k@��m�&�#-�X�)��n�V(�<[wŔ��띯;�c�k[��!r�����R���8r���/R�y���o&UAw#-.��)ǎ�*�;����c���`�o�m��0C���n*6���-�d۶�ҹQ|��[�#-��;�tdl��w�iއ]�mGQ�gtAY7��J�p���`���gt��)u��B���,7m�o�ˎ�{�H�X���뫣��NL��S(ij���P;5K�M���1dፑXe� '91�#/�Fo��Nv�J) ssZ+�ݰ,+N���m����O$�Ԛa��69���q����~�V�L�fm������ ���!(eߜ~�t��LRe�uʒ�/�;�[I^U�t�~�嶜�n�� ��� rqB1��7מm[^�J��q�'�ؒ N�|�~���q���)�x��A���e׋���2ɉɿ�޻�H����5���F蛎�JYY1 D1�ʛt�c�ik IœTi#/uo�B������]�Om�R�oNYy�\#/w��Ʒ���`M㛢�?��ۧGt��J�L�L� k�8!�L��m?o�xt����a^���4@��e��n�8¹b��Uֵ�im;'�y�hz7,��+���ɫ�돼�!���M*K*7��:"ԛ ���.{A3�M��VF�Ӳ�o�k$,!�� b�hE����T�oE0��C�5vM3��^B�e,�/3��K����W�]-���ߜ�0�z(��sq��hS#/1p��fn��O=!�;p��#-΍gVs&���R����^Xm���*,U�w���+ͷ��M��Ø�I�����|��kҸ�0�ze�c�Z�z]zt�kh%1� ��B� �����N��[D�ߌv� h� "���{6��Q�x��#)�p�wE�(�l�&�=k �/K<F�C���#��;0s9,��ZK���u����l�"�G#)����Ҟ`�:_���M"B��y��S@#/�u���gx�".DH`�`����<&��K�'�;���$0���a@�M��(���·���ZW(ۋ���u���lvK�3��w��A�~�� kIW�]�^������|�>ߞ�\i_e�<�8I|� �d.���m�,��_�;:��v�b��3c�,�#)�B���� �P O�w�wvO���e�u��� ��<[�#�,j#)���E^�� )l����&.2���u�J �˲������w��'>8����2Ǐ�k�%� <#/O����9�yos&�ǡ8�.�}ƵT���us�E�/K��(����d���i��*KpxM���i�#/R���ј��W�Kc:�����h�p��`v���iq`Jg�^��&b���|�ἳ����vK.˗!B#/6�%X[q�kdŰ�#�-�`�Rb]�8�3��c����O��]�B�$�K��|\�ț|j��g}'�$j��a��T;�_I)T���ee��V#�.�6�®�j'��p�w�{�?��T���=�#/V!}�b�xGk��Έ�<*X�ƌ���A�h�1 �� �j��Dʪ\�9��[����2����� ݌�ne�q��$�ޘ�]�D��d{�>��M{f. t�>Hhp2vB�T�����)@�vl�џY�η~�n��7I?���oR7b����[Ox�8���y4��˰�JF��Q\�C���f��C�Jqi�xi?K\�ADc��H�Jz3r�P�D�P#���N�rc5�q� ݠ�bY#-ôc�mTst:{��fN����M�P�2@��Lj �s���pm<(��nd������Ü�i�m��Ďm�&�a$ǒ��fseXuaz�>x� L:- @~Zགྷ̈�?_צ���"�!4�~ks6��#*g-���M�/\Fd-�vC f�縅 �������d��1�����4 ��Vꗸ���4Q��!��Z��<�L��Q�E-���a H ���0�N�3\JܘrSs t U�R>\}[��������c�r��XZ.�,���#Ώfi?��N7�I�.��k�Sͨ#�z�G��Q��#h, ߛ���є`U���u�@� ����M�s���ϝC����mD��ىGQ�v�hf;C���;N* ��r4��+�f����|��L��1�dE���Dh>VAE�,�DD�[2cof�D��&#��trr�GZ�K0�WK���R#-��V�!�Ӧ#/�gkh���AC�;Z[�뮊V-�V��>Q��T� <ωՒ�'lļ��p�HU���V��o�������ф���r��g��s5;�G�µ9#�����Z��T#ܩ�1�ȱf\l���u�_ľ���Jl,W�a&�J/O�K3b^oB��:^��Y'������&�ն�����s��˙gyb���ϒ��mȎ���3'V߆2��� ��Ħ�j0q+J`�I�\��R���o�gDPрci�%ޔ!�a������N��`Ώrj�荏9�E�`o�db����T��[h|#-���^Ji5xx#��o�~�#)�Y{;���!��W)�����Lk��Y���sZ�I-�>s�x��%���R�"�gɐ5᝭t_�}��V;�.���&�uA�*$"��+A\�|��B�*�9��!��rn��m�G�#-L��Q�i�`Ђ oQ��@�J�*/F��vM,Dz�Gw)�[k��"��Q��zʧ(Xy���}&�r��~��տ�s�n�G?�F�����(��4ID��>_�T�A��3�����q{�Th���碧�G�����!�ueF՛AmRυ[��y@��G��s.|���o�����?�ċ�9�G��K��@��Y �� �����([�u�`��"�%K��'����l7L��<�t��D[߷�}g��1���K#/��u��+;��z��E��ko�.�Z�h���o�1���jۂ:��f\�1m���M�<�w]��7�����+��#/�~J���o�8�FC=��f.�� #)R:�Lq� sD_�+]��n�a��pZ�m��}�H�&Q��|Y)��׬N�J���WD ו�8_$e.n�?B<.��?w/�r��F�~�8\���E]�o�uqP�sphK%!k'0�ݞ��`�V�j���\C|&�r��ҤZ�@�4�jd$�ү�*,�3Z�CQ�d�v���/��������~�W#/1����o{��5dKօP�/�6b�l��M˰d$���� �a���c±^�K��:�]}��5�"�DP�Km��n�\۱���-LV�XF�f��[&��it^����!y���拼EC9H2����tflkA���M1�C,��`�l��ر��k��OIiN�}���#/n�#)���A^��(��l��!�.�o7B�[8fX�H�ڀWz�2��s�X(�� ���p�p�4Y�A��a���󒥃�X8~ =ޡO��ϒ�ӯt�q�8=�����=��-$�� ��Uma+#��1��-!%g���X��'g�1�� �U����Ei��l�G����<8�?^j*�_����n�S%�S(�^x�]c-M�zB��D�C� �k���>�;��k�N$og���$��[$v�.�Ȟ/j�k�n�u�VҨ�9�9�шd�~�4�t����i���&ϛ���/~��/�����[l��:unM�({-:�;�_��Q����cק��n:ǫ�o��ԙ�=C�k� ���M��Q���fS�pr��LK�8'R���#-���ص�Ɨ��˃�(�=�4D������SX��?��dK�1�����u��g����Ԏ��&xt�M(_K՟Ma��h��{/��\w�T�H-/Q4�V��(��-�M��?����|�]I�Y8�;��p�~g6T�##-%MP�p.��gZ��+m�l!���P���o`�Bb�=E�����;����{�H�Q�kz@�}����_�p1���#/����������Ե%�l\�F��i �H儖"��� B�r�ZZ��,Ya�}7�z�I����#/��V�^���8����s17��f;����[�P G�B����6+{N�iC�&:3:���r��/U/��!Yy �4�� R��&�O :��#/B��֠����|�g��:��-r������S1�q��Ȁ�Q#)�8guv���'�� 9%�G�r�Wt��j^��[dۉ�Ry���6�����޵��2��#)U)Q����U7��=f��{�|Gњ��h��C*�s@�y �q�IJ=�29�K?��b�m�4X'?��K����O���amDѨ�d��>v���yX�B���#�L�(훭`6�$�:��ܮ�M�á�d�x&���#/�X+�#-�<��D��U����n#-��qt�ġw@9(��X9��֙�`/���� D$�)���F�62�!*��>9�@u啕j��yF��8{�����'z=��ݳ� q#-k����CX��v�Ny��*�|N�ZY6 ��tӵ�X,#/1�D#-��aI0jl�=� ټ��•�vр�Wc� 9N�D��p�<���a�Z�~��$�#-#-#)"�-�S�+�+�e�PQ['(x��T��'7Z�@�en��Z���T��[-���/�%a^�R0~�#{����,��#/G3���G��B�q�� Pt���� �����!��@��Pv ��wn��)�%w�fsj�;�3�IB:���=.�"��Ie�kI�+�s�g�����Ń%�0(����2%@��h����( 2����� �1#)���I{��x̺��}����%c�K\i����qwUZ�����\�ڛ&�1T%��mϩD絥z����� �4��0��AM�FN ��O����s�;�5 ��9`�KJ � �Ais�>1�C9#-ʊ%,��J8����]$hӜV��ܮ�ٖaT�����d:2'��i��I]]�x�fM9���/�cO�ښ�rE=�|�-̇_V�[��~� Hs��s�c��|a%�s�EMe�=W����w���l�fg�4�ܢ�`�E��3Y(��3�=�nR�jR5�Lߊ���{v��#/��q��ւ�s`�WLÍVh�w�-��W8g{�m���qn��O<�-��9���֍, C��`�N��`[��™�y#/Z=�s'�W��H���.V|�W᪁wU�k>&�����#-���~9"���ֺN;�s4֎�Y#/�fx����}pr��r=q�Ėܾ7�Α�j��72����s��ڹ�V�{��TsA�FŰn�m� ������,����#)��(l�cr�gz��kK��k6w�;ŷK! �t]=�� �� [��������x�J.�����;�t�uY~T+��_:��>Hا��[�< �٧*�.�:'���v"�W���z&��+�G��|덱���*�1�E-��������v��`��#�k�cdۣ�r��Ȓ�R���4��� s6�@Q��m3�N +ߣl��� "XH;"��=Đ��W�#/���0��������c���M{��x|���V�f0R�5ֽ��3��؅3|�hk}���Iv(�"`��Ta��ߦ:b�d�B;o�P��hs��+�!�ϖ2�4j�f3�� (�;��t�i����pV2pv�|�Ӄm��v�K1�Yt���ܿJ������%�@�NWN��ދ��s������C��9_k�z�5���J�mc��v��F*�̆�M��ry$�%TD��R�'�������bfs�m�:���N<�^WH���^������u��@��Cye�N{t�V�zx�7����)� �&w� ݋Aթ��@�x�Z#-��n���P=�N�6 ��k��ؙ��Є�8��i#"�E---i}�'˂�#-;��<M ��;c�ox�#)$�|ʧ��]CI%���&���1�j�>6�����?_�5ݜ�+T�[�<9#/B7�6/ {{�Մ����*�8wV[�fv�0U#��m#/N�Jx��Q�S��D��;��j,0��.�o��j��X�U�X"�;������&0�3gU_|=�?D_zmP]F@��ģ���zGc���[��#-, #qGAI�^��vD�3d֠�E2����Ġ�#)��Ԡ�O����Es�k��q�Vs�L�� AD�������$���S��~��TWƮ��] ����o���C�#/uܶ$����W�tlJE�EaFDRAB�#-=������ץY��_��c�H���1l��g�OއGc�8v��:��Y#"�R(0`k! |��:��/W�S��m�Kv5���3T�Yų�e����2?�0ٰ}�W.YzH �M��#)7��ϻ�#�#/&-@���{�$C�̈~g���C �B���"�����%LC�B�IQ�]잿��r�_۬���*��0�_=Ö��W��y��Ε$NI�e���YU�`��r�,���e�,�r1#/�#/��r��96���U���-�Ѻ ܆������~��#-� T�^� ��ltT��lIh�Jk]�!��g�Tb�XF�+����?�}��/���Ca�8M�W08�'��#/�֢�Ժ�v��01G����:~�F������{�Y���W#/�Uf[�g�~��~����s<�7E�a�VN~fP�����Gն.2�������Z*��dم�2��Q��Jf� ������%��9��^�,�햝��7��C���P��E3�S�5@��؟zԙJ`r�#)���_):��y�� ��J��a�b��\��> �e��:V3B�x��5-J܁�/�Ԉ�� �ܰ�noG��^���q���04@�����<7;�,XO�#)�v�x���x���!/vo��n~tV:��B����C������v��|񙦖\υ���*2.%�H��X��/t<4���;h�ld�p�M]����_�����|L�F�<��k�@�w�t����)�yA~�H���u���,����C*��ri#-���w52x "�"7s���O��#�=�wÙU��:����T��*R�BԬ#/��~��s�f�4E�{QO6����X�{���5T�0��.{x��|`�]V�8�6��2��8���m4��f5�j[�~ �$���1���!blM1>`\�A�#-��.)��;�Y��}������c>��OD�Ƞ(&�]�#)��i�uQ���:v�ٮ��"��HLWQ��[�e�pue�֔U��^9��S���s�"V¶=�@���V��W|�裃 ��{�9������¡�lΏg�V����#/@�qP�,v��4� Xzy&e�s�-�~G�wbQ������3��n�q��  #-A%&N6��?������Č�b��I�G��K���VH(�ju�)9&�Qb/6���q��1�o�G}�.��+��*����`����hN�B���H�ϭןկ.�Mj�\��(�so�)g�� �#-4F̷e�`0��R�qQ����|�;���l� �%������#-������j��'G�����A�>��#-��G��N�W�Y�����w��/�9�D;z@bR���/���H�'�Y�Z�t�#���C,@y�Nr+(k�خ��3zL;,�" 썼B�N3$��>�q6�4Ҙ#-�&�� [$-�S�n�-��\���f�x,Ro�J R*��Op2�c�M' ���#�1�'ة���#-$n�E"#/� x�w� .O��m�~ի֑�B�zbF<%xk5�#�0��_3HW��w��=�����d�.��;��#/*d���"�, i�V��Z0l��@0��B��Q�30�[����Z�Q�v��rI{@�{"ϕr[x߼u� 9&j����7Js�B�� ��Z�l�X�`��a�z'��ﲡ���S�ᆟ,�X��JKDHK�]ܰ�Sɴ?����;���8��e.~x����$ �u��RfX�~�1�o�'�\8�`�-��# ��r���D\C��v�_����X�N�e���:w���Q\���+��(�M�-��c����3P������ڿ�]����d�aQ#����`�t�Ww7�4��|�^�,4�m�C�z‹�qtZC�U���6��у���#-�eLw� !N*R�ωlj� ���θJ�L�-�rj�~Ă=%���gJP2 q�#O��{xt����}�=}޺����lRp�Ln^|��æ��U�̧���#-yv{���G��>����laoa-3�=k{b�h���+�\ �Sa�����������B�pc=[1q%�~^QD�B�y�q�N6#�\��6o���F�:i�:O�#)Yz���L�{y�g�����f�waA�� &�A�7n�$���:T�9��o����ƚ�g88��oe����#-�#)S�v �FT2���@���z�5[{6��wܾ�ߢ�ר$��dW����6��#)��}k�ӛm���}dQ��� ��}@I�4�r���i�O�O�b�x���+i���M1f�tб��>s����W�0�zb��i'1(�ue�0o��n‡ l���1��4��D]@�u��n�Y�M׃\��E��b����R�AP���E� H1�5��4�#)���B�}Hגh�t�+w�n��0�oV�p�pYё��*tw@�#/g*�^|�b� )�C�U+<ߌO�Mf�j���o��HAJ#J��JV�ݿJv�^y�y��0���������|���y%#)k��]q~ʨ,��B�1F!#/�tW�>��Tu��US��!�_��~�G�S�3�x�%������o��F�K1_b�Z�&"��Zr�'�?��p#-����w�lc����z��t��O6u@���#)9�iH�_/V�k��r��Å£�笧HO�% ���d��r��I�5=[��#-qtܷK?>�F;Z9��f��^�"q�����,_ʩ���}��s�ke���r�'P�����F�T�ӏwz��f#[5R�Ȍ,��i��~�4�6���3��e��J�GZ ���<|q6'�P> ����Z���\�����IiD����ݿ�Yh7G�<�4=>4T�����g��Nb�����ʊ���"h(GO��_r���-c]�I>���k@�0��~�߯쳃������7`�*���d#)��!e���@·�ēZ��?�5?pW��8�/�v��,�� [2� �Z���B�#)N�â"a�b�e;"97�؂��#)� �J�� �� 3��#)@�����#ꂶHd�’�DT�K���GE�@��2��. �&c�}��� #a kJl��nx�X̬f �bXp�,�cnJR�bQ��%n}Z"#/��_�B��{O�J����������g�g.�u��Mŕ�T���;�k�������1@�#-A�W� ��3P��\���V5p�EM���`��Q:��s�D�*��23�l�R�N��o�)ϥ����Σ�M!+�E>�T�����s�Κ�?� �#)�`cnh>����+�BGG%om_u�� �M�Q' �wD��w,�Eͺ��J1�V��o��%�g�v���[LC(n��q����K9����6w��:�*��p���️�u��=Ь�+�Y�G�&͊���F!���:8i�5;<�@�FI4�?`Ց;��5F�(z��q�T����z$��۳�=f[������/0K���'N��-����?<�tz��� s?��#-�|lg���@l>�Y�/��w�R��$!�~�Q=����bX�,��d�P�i,��S4�f�̔�"���z��9*����*�g||p�����-pq �6����Hk�{+q�6�C"B^��J���aԐ�HE�{K"���ZSO�8m۾����4�v1������#k�g·MG��#/��}�P�&�7�D�J�ө�6�Ƣ�su���&Ȉ��#-ha����(lUeY�V�H�����aةFvt�G#-�m7[������Ri����rp�N:��7T%�#-a� ����3٨j�� ��vQ� ݉���5E�d�Cz�Nӹ��lJM*�y{:VF,O��&�0񜓹<�t�'�(v��(#/H�[�nkd�cV�:ʲZث\��m�j�U�ڽY�w�y��ֺ�U��t�Rh�^���ee�q2&��+�/7ɛ<Ԓu�����I릥�A3'K�0��G݊��Y�<,mKQ����g�ߓ��x ltH�h<��y�̯�y��|�G�Ru� H{ڿege�޴� &ѭ��V*�Z��l�pCoYlk����jq��0h��2/i��"��k"�b�w&��r�#-V�R�L�H�y�%%��B�$�dq�o�`�'�_}��<�3�͏�氁'�ܶ�lAġ#-��Dj�AdU�����k{�ן˽���V2!D B4�Nv�&�&G�o��n���vNޠw� �Ť*�^��U�ɵO%��!��7��\��3�1�=t:�����ьdP�Q�"��S@,Svu{7q���m�7s�`k�W�IS�.�~LY�bP�ו%� .� h�#),��7c���D<��xo�Q�Ē!���m�#�`{��S��S��^�ϲ�*���IhDJw���Y�&�tB��+0.��w�`�V_?����@�U!�7�yqF�s�ԁ=Gf�f Q�>{��~���y�m�LQ5Uy�ނ��B����,�(D�(�=yy��U�ҒX��nbĴP� Ӿj/�@{�|��9AWgy�~�,s�a���:�lG�io�p>3Bsp4���S�%y��9���|�4J�Ԓ�#)�kDκj�@�"� P�oCw�;�4���������D��p�Ӟ�}VN� 6�t f�L��Ft��+i��7�[���>�n�P�!Fda���/�c�)�9�|ۧ��i����3�Κ�¥k%�G�կ����;(��#/�\����(�Of�9#��������( �5Q����VbX�!ź/|�ll8@��G*��)�����q�pkՕ��8�L��A/�Q1�*P<�߷��9+�k�| �c`=x�|�l�ez9d�.�7#�FH�=o��z�&ԳX���};\RW����E].�Ko7M�^,%�A�|8���6���袐z7��R���{C a=�؉�A��b:*�J��㿆��ybi&z�6�c��H+X��r�H#-��E`�=��4j���#��Y�A�#-c�4~hy�Zn���<(����E7��x�?�MH�g������ ����4N��=֒����%���h�auuz����lF���“��e5ՌX���k������k7=ڙ�h�G~���fm’�Dn�5���X:��&�^Z�Ǿq}��N���GZtm�{�fN�}%��A"LKgD����0�1%S�}���/�2�=+�> ��(�B�Y�C#-��m�Y�Z�yQ2a�0H�'Ĥ�ȯM��z�R���I�3t�<�z ��62 tB�� #"T������*�Z�h~ݔ1!�$H�e�:��n� �����s�M��Cho��|~_糳�Kt�gz��D�GV#/�Dh�svCd�lx��.(P�Q��&³��X�|�����d�wL_�6�4����߈�:7�3`9s| �GW�cKr%�� ]vb�l ��F]J�*o���)Uf[(8?�B����^f��] tJ�M/�B)�����w�E��� �Ce��0��N�Ͼh�9�%@0�� ��ϣ���3��Ŧ,�k�^>R���t��&�:NO��n���P3�:��0�Qv�����J�7p�Zk\+��V���F��=fE�k���Hb䐈#���x�m�I�)���M�C �bph�6�4�R���&�w���� R�q81�sD�v��{�}���Ɇ�P��E6�%֙C�],Q�=�#):�:�WtRG-�M�-�����Ԕl�U~�u7aF*�thb����)�p <'���0k�9���]�dL�f�;�z��q����LIW8� \W�mzpMP�b�wO��ϑI�I����z�����,=H#/�<��S鷗f|�gY'#-� �m(#)@�~~9i�f;ia��b �v���)�D�+XV���������zfTO���xl��y�&Y#)&��� �TZ��@ z�tl;�ZLW�v�R�*zG�#)bt�#�6a��?#/J�3 ?6��>TwH���Y��9|L.�)* ����b��?}-�}�H��%���f�L؀� #-#)��}���kJ�/oەZS1�_�����P$�TRE� L�k�?���~�l�N^;��mYmΉa���t�,)#-��0V�®RS��2ΣӔ@�7���U�<�D���WVg��&{�녔������������g�.~����٧���B_V�� +���Vi�$�|"��{~4��[U�����������O�+#/��0��eߞW8��#) _���c#-�_����Kz����wUuUR�����9!�+15��G� 3/��'�p����}�9φ`�pEO��ߜ��?��pI (��/*�?_������\��r��Aj������ݾ��A����h�1 /1u?���-%+��+�1�~��f2��7I,$�?L���o�\����RpU�C�,d P�?2�LʢE���=[x���&z# �Q9���@�U�Et)��}��H��-4� J��W��H�q������7�]�rL]QN�)��Zf��/=�L�z3),(���K��О����Lb��=��n�u���*�-/�� �-�"�% n�"���@�D���_����_����y�:#-Z���,9���:$�ѩ�)F$�'�d������r�7��� ��?�<"n�P6��ClR�xT�"œV�t�����_cU^-���ʢ%$�H19��aY?�NN�ѯ�]�y�����`2�/ÈDϐ���>��#/m*��H�<\2��^�'��� �����;�v�$�T�+�����#/LL�g�lDa�J�� ���0�Z�@ ���7bd{��S_�wxo�~w#/g��}> |����'�v�4���t�������$��W��!b��s��Gk���o� �!L��}��=� �3/�V����9�y8�9M�\�z����#�`}�%S6a�5;��%�~����w�wh��_��#�~���g��v�s�+�Í<ն>B��b�����9=��b� Q$����DO�a����W��uy�`��̰�������!�"-��I��#-I�v���`w�`��<�Z�����%L�Q�6��_#-Zu�u��;[�$���@PX�i���SYo������6�8q���&#)_��}1a��yZ��r^[�{ޟ��H}k�c�m���%Q#/x�&E�f HV�7>ue��-!t:y�W��'�#/ &sW>NSM��ϓf�vB�y|�m������+�swy����ǂ"4Q�j�ykI���:f�LII�<&Db��U�#)6��΃� S�OP�{G�D9=��i�`M_��z�ҿ�:���8�C�Y���#/���W�s��&9��\�s(KW�6���#/R�_~�*�������ͣ?ǫ�0A�A�3)B�`I~����O�unc8��,��'���g�(���P���<4z�n�/#)#)A#/ �՘�"6�w���w����վ�g g�$d�����<���]���m�� ����m����VDդ���n9��o��J)��o��y�ݴ\����JL��R�W<����>��(B�_?C �)�0jQ^=W�8�<�ze�8k��/��ߩc4��9Fb�j��q� e�' VH��,l�z߷��y�2Yˍ_��f-{񍷣�*�I��8�9�!�Oo��-Ͷ�K��r������^�[�s;��;檫ʟU�?�X��T��i)��4b��ױ�o��Il����.�Ih�z������:+���Y��|o0fU���,&6��C�K��i�X�_Z���!�g1����Ϲ�|�M��b+���ęL��zdn���~4mF�TGm6�{��)@�vp�#)�*��<4 ������ݾ��C��Hcj�uP���xCugX�I��N���|�|���D�M9�`�Q�5�#/�S� /�Qʏ,�!���X� �Fe��g�v�Y�ϬQg�������qE�)ĸ��;t�+:�s�z���Q�VA�����L��!�O��i�֯�k_�,Xl�o[�](�kړ��L�鷦�]�UU��Qu���- �Ju����׭��3\Y��q���X���zl��+�Z�����P_�2�7HO^^jQ�D��URHG��`B�o>_��Sj�Ԥ��t��sP�cV�)�w���c�;��isga1N#�7�_�h➜���i�S��$���S�﹭Rw�Ѿw/k��[3���N�S����u���"}�͕S��-<4?>��W�,��on�Y<�n��ldԘ�s.9���#-a����H!)�_�,}x�=�E�֝a„�Q$��Ix� ��]�6����ywN�_#-x�B��a��[zQ��a))��a�ެȜ�-���aJ��O�j�������FCGz���3Ӳ�t��R�8�t}��˸�x�wY�1ˆ���#/���r@��{�h�a��~�����9��v� ��<7������0���Fpqu&÷��-&�4J���?��-wwow�A̺�i�g��k�;����|�%��4�P�mҤ'b��QbP�P.2��|Q#/�_OP�B���7�v��}pGv��KM.�25����#d��O�B�7k�Fh^Á#\ZnUF�"�qW:'h2,�8����'��ByQ�mk�G�x�CG�̋ ��4�َÅܤ}ޯSX5�HZ����l�#)�Yy)V#/J����%� b��x��7#�"QU֫�/#)�@NTx���Y�[�u�S��#-_g/k�?R���b́� �+�;�+�*󒺃m�����+7�=�#/�b�_wS�<3�zhv9�&�"�k����"���#)A?�9�����z��r�ܾ����jt��Kd��{���ƙ�8�����0m�}�������䀞��y���0$< ~�������I�"�cĤ�� )�y}^�?�<#���"��7���ZU#)�'�O8���s3����Bp~�U��!�5��{�B����?��a�MR��r�#)� ������o������M#)��1R04��)��;4�(4?Y�w�<�T�.d��=1�����^<>�%�H��8v�7H�֮}�����s�`��c�H�� �(߁����Ӧ���k�Mk��m���O��O����"o��Ža���[�@�b�0�>x�#)�O�cDF(���XH����y�9 �3#- }�{Dt>ñ#)3I��H��~���)q,(IO ���=Y�2�����$?T�j�P��]>B ��T�%K-���{��N\kl��^�?t�L��CH@����ρp�s���N�#�� �M`t�xN\���~�g#�$�}�+u�e�qN5s pҨ��� �(g*��Y�9p#/Ps�!���4$INr$&�3Y�i0�A�u*�8꘻���(#)X��˖Ĩ(u����#)Ԥ<��hz��z#/ ܇~�%�����P�=e�("�:� �/�Wؤ�O�^-�mfAaAr�B���&�N�0#/��zY*�Mt� �t���l,tg��g2�j�bO�N@��q7��&�#/SmLzP>:Q8�w76��NU�{j�!�^��;]��yUff#/�,#��tq��+����{�ޖK](ֽ#/���0�Q,+*�J���„e��ro�xnR�3���,��>Ŝ���w�n&��Y\MwRx=نS���q�\%O�����А�r:��я.8��"`i>ˤ:D��^�c'C�&���ˎ8]s����a�p�2.ZB��'>�;�'�"�4�IB8b�M�#-�ۖ�mO������j�hDp�ɓê��Кy�9�Sr�x��-�hv�d�#-Y{y�dž�ڧ��l�~��DNP����Vm�H!|�O��{�.�zOĨ�"R!�J!R��Z�������U#)��&yT!�Ѵ���]쭵���2����P�]ҽ�dRl/U��d�A�r�#/+�`£��ز���8��F��m��R��?�Ɯ�̠�q�)#)6�z���(^Ig{����� hQ����gܹީ��B����=.��lhk�̧q��$^1�e���2ht� �wシm��s��-�Ŕ��3� ���v����y��v��\7N���g#/m�v �9��f$z>W��BG'Pe�o�8f+nV�bk~�<��bdRt#/��z#�æM���e����^--� ��\gx��Ѹۙ [� �a��Vfb {��A. #-X�N��/����43�! 4�ߦ#��Qu���a�g�]ꇲ9t:�������lgi{9k+LA�ע-��4�yj�n�k|�ʻ[ql�:��>��0U����B�M>�ku�!ˁ�:q��o��=�� L�6i������_�FR��`����N�N��:�(����XN��߯�P����T�^p�\S��l6;5�*��xk�,(�Y$��n�!���xJ�c��H����~Ox��pQ\���%��1J��� �}���:]#-�}ꎽEGCf�����]q��[��ȇ+M��ν,�;q�k�ۿU�;#��w`�#)�X���&��"ǀ�~TBø�H=FA^�� #)�#jz���~>֕G��adػ#�פ�K�Pr�Ɩ.,��Y���>�����~�nZ�>i??�k|�9��E#-A���:N��0�����֝�&���S<Ljt�m̏�j�\B-�B�s���:��>�cS>�{�����v?�Bb�z����N�4k�<���V�*� �߄)�hfO5�?U{����~�%�0�#/���p�Mry~�E!X�e���p~�/��6�7�_?��cXl}52GZ,�\��D�JI<�� #)��KGl���߯e�am˞�h!Q�n��p�_���[�4���A���w@y{����- 2�TQ3��5��.�$��@a��� �������d��L'U�����xMr�d0�JD p᩻�%�BHod#-� �f����i�62Ӵ#/�X��fa��b:��:��-'��U���m�~~3j�0��H���\���*�Aȷ#]6,��8Hb�;:#-a��>Z�K���_o/���Mxm�yyfu�`06 �`�v��q�p�l��#-s\]�S��x�H�մw���Q�;� fXA]�@r�<��9 Œ�9��#=2��V�v�����!�m�-ZK�X�9���%d��J%A���LS#)��\TL��P/"r�>��537���m�v�{�?�R�Y��+h:�5K����""��#-��3v�)��a��Sh�0"���09��^%&��#-��<��z���Z��Tm��{Z�_�N�c~,�p.���5��88N����,�Nmoqƨ,��A����`2�\%��NN���ܻW$�r�������� �D�.x7��d�Rvm�O�W_lC_��x�dF�|ÐH��.{�X[YBB#/#-j#-�8��A=�zb��U{��S�5M����(]S#-���:��ƣȖ��_3܊o6��)!�6{����] ���̽9��>uR�#}�3va�g�v��m��ZU�#��q���V�X�*d=��ò��6�PHo7a[��yBE#-o�e_�]�: ��+!҇�#-����7b>�Wq��|<_+��y�[�' lW�}8�YD}�[ 9��PE[tH�!��5�=@Ѧ����p-P��E2D�gEg&�1r"m�xhh�Nf�Cc��&�Z��u��5��j��r"V˥�|���k#-�-�@1#-FDtt��mk^�%a�QOf;4=�Q��@�X>�B�-���})�V�Z ����k�����ӫ����� ����#-CB;�%?�l��[_�� �d���+�O�gJ7����Rg�\.�f�]%k�ْ�t<��#-c���tg��>G@^� Mu^q�`����m���إkNv�yÅ��N`���&�8y��I(������K��<�t��I�*��faHy/�"#y�#��`/�-*w��l��"������gfA�.�Ё�#)��h���ڳ�ۘ���cTq�)i8V�kjG1��x�dE ��u]D�7��f�;}�Q�k�S���Z&��3�LBc���"P�d#-�KCu���w�}%�� ��V��gF��đ��”�w��`�Q#-��߀��bzݟ��sDֺ�FG�}>�}v�o�v��E����Ot��QY�x�t�t4�W}�UAM! !�K�$�V��A�]&[����_R۴�T��Kÿy�����ӯ�������8��t��9~����(��� �K,���>FJتi�x �e��p��#)(tE�#�V�F�lj8�|2-MR�����C�����ků��#)$�?-mO��u�y0���}�W���;��hщ�N�rg��ק��~#���3��K�4?�n�n|-#-යY`�AAb'��A�N`t��@��`V����=��te��0*��o��q�g����Y��T�*�Bu��2�k���W���>v��yo���_�4$��?�(b��(0 3_@##8m��F��#-F��I�?��R�(��د�����x�v�bQ` ���A��G�-`a�ۨ���ķ�{��O�nw�Xm�t��tط�T#/?Xf��9�.}������� �N���2���+�y�LO.�F`�W�0�;.�$������#/���R�#-���Z���:�;��hy5�G�{�ܝ������gH������s�}ߘ�u6C#����+h��b�d_0��w���j�ZGF�s����_4�P�4�6�?{��#)r65#-�Nӯ��nf���/1؃�9" ���e�yw�Z�pN�O,@������V®��q|t�1f� w��}���^��qn.I!�2Uz��Y ����G��d(#)�C:�VW���o�?����#/���A��`����-I#G������`�nX�p&=7�i��\��ݠ�jB��B�1>���~�V�Ζ��#/���Ӵ���� \-���^��F��.4�$7W���;�m�6�Qh�,B��)Ս�p�m#w��#)����ka�(�r)�H�#-��Naj,d$�@Š�t���޲�٬iORy�� �|4�U���0/���?W�N��{S��%�t�m� �h ��M#-��j6�1���ol��� �yX["��K db�#"H� ��a�r���. �ⴥ�@��Kf�@�t�2�y�3#\�)ٮ�Âm0�rN� :��1��#/����d_� �@:O���WM)'����'������#�*��ނиx͉�M�s�5,h��#/�����T=|��� ];��`�$I��Q��++�]�Q�a�C*��hZ{0I�`�����_�M��\��D�Ł��Ř��B�� ��w�p��ڝ:��������m����%��l0hL̒�~y�y�'Q�IJ����=���o��)��������r�?��OD27GFkqU�/��i��]}�:� �PpF�{��q#-�?;��s�#-O�O��F���5���� �#v���b#-��m@���y- �>#I��7�u9D4��UH[�~ )K~��O����J��^���s{���4��eL��;d7�j\�q�_������Ւ�|����O���0���@�83�1n�%������I$�xw�%~~�3[#-�W^��B���8\?�{L�<������d@��A��F���6Pܷ?�tʛv!�ڰ-��EM=��?a�/���s�+�ڋ�rp�$�9�z�߀�Σ��H��Т%�m�.AYu>���nCFSl�]�5�i���ׅW� �x�&N��#/Qm��C#/#-�iMͬ�������#-#-��|�uO��fD��fq�0�hL����R����-�z?<#)܅��?�6WTj��8!IO��1k +'�iaC�QI�)2�۶H�E>��ם%����=�F�vKK�F�2��WYi���U9 �ć4�+dR���#/��܍�er��h�R:�I$�5Q��I��u��--m��5sVZ�\oL���:�P�^������k�h5b��SL�.������Q���Q�D.^�7��w������ٍ@NZ!$@y�_�5($���fVi?��܄�jTm�2sx��0�Bw ��O���ɨ�"$�h�r#/����W�Q��B(�cvU��y��P6� ���'؏�������D-5#-�&�喝D�Uw�,� D@9#/[(��>�2d�?�ۍc94,����I$�;�]���I��))���2��bZ ���m�ӽi��uq�w�oȧ��N���)"��~�]b�����/Kᒛ��o�Y���}�q�uo�0woo�6�F�+0?r�ӌݩM�"�\ܦR����o 33 ;��0��D��w�ǂ�����}4�|�����~���O�߭�[A%��/���={7��8~w�������n:���QRR��"�2m!�\��;��!���7�V�fIJ�x�1)@���)Q2?_��7�Ѯ��һ�?�Nd���3'�; ��d���B�QCF؉淩��DRѐN�(o@d�! K#p�����b`^A���5���p �F����`G� �,�[x�S��C�� #)B����}���y����W9o��������$�_��cX��W�j����װ%�o`�Y��"�D��r'��Q��ȹg����?յ�����_H��l����6�B �A�!��?����8烟t�XƜ������v�HCmS�]�`|�@{��|S�8sO�#/wR�$j��s�ܠ�)�Q�~��E ��:���z���#)����:�+P�<@����¥�?�˰=�ܡ��D<���FE#!�v���,�W���p��m���r|��#-�@f����C�@u���o$�T�`T>�΅�>^��W����/�+��c�a�o����+dh|�ew�-Nϲ ��C��*�ې�؇�L� 1 N#$�Oj�S�>�� �����.�`h�#)}^�_�"�}}��lv�jk�{� O{��J;=M�W��֣;[�mb"_݈��� $˛��$_ �|P+���pGhda\��=�%`p��?�4����.Bv���*�Tg���I>�F��v�����:`��br ��s�7����y� ��v#z۠�dB�V�#J���p2nD�,�pK��U4�pᱬ*蘑�)���Q8��gID�5//�L0 �t��R $�)Ks�w�h��a���-��G�-� %������q�&ޝNdS0��G�-fy�X)"�>�#)� l��V�|�'�<��T�(�/��{ L�S�`Z6KRD��kÀ� ���{Ob'����>����#)��Ì�+��n6wF?�[G�3#)��M�������O�}~��aR�������7Z�'�K{��s���*%1%U~�QG�IB��8��r����i���Y�i�b��mJ���j�fg����=G|������*;T���iO�z��z�+���o�uU[T�P1W0Q�����G���D6��#/��(rX�b���~Q�������h�$���4���5s���N��/͒.a8\㺔�� �zc~�I�W���+��w��e?���cO�9^�K"�/������ޢ��>�#/�z#/��Wr�L���2]�,gXi�=�]9��(�n� ��F�Oc�O���,��z�G���L�V���, �X�#)���v��E:�#-�S��Jw�5S3`Q��,K%'B �F��1���_�Z��ӕ�z�N�a�=>��v�}V�8U�!��RȬ��,JfQ�]���F�U�\7H���l�LAY$I*���6QM���X���'4אz>�Wۤ�� Ӏ�A�}����ռ��PPp_+���`��� k�|���g��6;R9�w��7?V�Sd?`4�lw!ikۻb��k&���׵b� �jC!��#-�)D@��rR��by)y=����o#)4��z2:o;s���G[�Qi^��4�����z~���I9W,����C� ӊC�Ga�۸�wtB��SIϘ;\�'��w[���msu"�2#C� i#/����}l����{{�ga�p'�Ve&$��$��G#-���)�#/(�߽d�������-+^^�C�O_�{.�T�D�m�}A��||���Ԩ~D/�C�6|��V���ޙ0�R��a X����*�$���V�|���ÿf�!@�.*� �˂^B�#-tUO���|�QH}$ �#�G<�:�G<�rB��J�<�#-�T��eBS\ �h>G��g��YRZFo����� ���c��gH���裼$�#�'��!������@����H�S�,�a]c�� J�99�|A�Y�%���!� �$��/?=ѳCq���G�3�#/�������/��#-��K!������,����?��=y���;q �@/b�#/�J�EQ�9�g#/ ���G�~{* ���Ξ��PO<����Ȁ�>��/�8Xc8���H��.ce �E �J�Ip��}n4��0��ǯKe��R��j�"��Y.. O��`��fo�X�A ��@��� �#-��ӫy��<�#)w��^���a��l��}�K�ET‚g����ӫ%:�'ٻѰ{T���/\#-�U:�$d��\U���A¦� luy+*O �X ES�#)0��8��Q %A�P0�Anߍl��/g��*|7*�5�^�w� ݒd0�oe*#�>1d���$�N ���b�Y"�#�f}�>+�x�"r!�#/��IH�����$�bL�Dh�b1"m0�F"^���o~.���-��mn~̨9��F�4c�wp�Πz�U*��dqEtO�QiN�K֡��l���8���k�� t��Xr�����h�#-��5��2{��"��;u�ͳ�;�R(X5I&���hӀ��kK��(L�}��$�ӽ9;Q:��K�gӧ]���n*��ep?�Ķ\A�N�9n#)��=A��6�oU�h�"�5CJ�����Ng�H�Fl!�IXB�F("G �Kr>P���<�;�:�օ��ݐq.�dH%VeU�-�Ëó�˔��m;MQ�]���!�V�U쒓��]�Q��g^�0P>����%'c��zѭ�X(����bbns5���a����Gqi���R��l��[}��4��u'�8�����MR��&7 �o��� ��~}�7�y�/�#���u�[Chfq �X�џ���c��~�j��3������l��+���X�#)s�,Z����ukgl+ �#�G*{�!D�ċh�"�(��#)�4�V]��աA�7@h#-�3#-z$G�d���S:B�l���~e��gY�b p,���C����0U�.��}��#-�,�Ӊ�@���b��v�p��䙃m����^�6xm*n`RHWO�<����<bH���+�?����ڗ��>�x�,x�u�݁��ʥ�"I��_�?~�*� Æ����-i�r~���lnns�,C@k���Ϭ#-�����[M�BA�"!���#-� &�H-�������+�|�j��B�z�^$D~aq���E��<ߣ�8P�Gʎy5nםh��r:��Ǹ��9<>�W��!Ju[��dyy�4�o�8���^巺�eX�U��Gr`����6C�0��z-�.�?NR�_��r=�5�Hi�P΀��t�:�#���3i�O�+~� coÄ��B�aR|r^(�J�i�������T,P@"X �,'eXuʐ��V��0�66��Kw�:�#�r=��[��>߼�#-d0M+�k�ߺV���B�%�TbL���r� B$`W���ҳ#-��{��™&H1O" ������T��}%��ڮ\c�����3?ݡF%~���[�N*Fn}�#/!FZ�o9�L�d��<�v�,�Z5`��*��~&D%���� ���t&c�NH���B��:xjai*f)\a+*y���mO��������� ��(kf:����،�� �DX���&4���2�]pMc=g�s9��B�lb[�5sA���E���V���T�i#/aOG1�A��bS��#�����wx���籵�À Cٕ��߂~�#)W�5:�J��X�$�l�*��d��Ϧr�X/�i���mV���o��v��[�F/��Z�q�|��#-#/KE��ZE�q������������zS��$��#)�#/�f˻��w�� N����J�#)M Ī-����m�*��-�=��@�`G���D#��5��c��~�B���O��{��7��e�8�ҍ,;��;��5�1�~漱y~-�~���#)m�r0�kFSH����� �ِ��V#/~���V��_� �}�ۓ>��OO����}de�ߔ�$#-_2�����]��O�^�0���#-��,�&����~�//�U��!��?��]�>B�7�@>;���~cFn��I�.�=�י6ɼ}O#)d��*6<�� <�=�͸�_��+��`��ޘ��r 7�,���?nj���g�b����S�}`���;��a�p�u;f,���2�P]S|�MBK��^#-�l�9<)d��E�'$^�s*��f��1,h?���+��6���G|EJm�U��w���'��E�(�� ��v�z�����N��^/Nt{� ��w�(�*7�䏄���I��T-C/ٖ����+��Y��t���vzqH~D�?G��y4� I~���C�p�Fb#/��(|��#�����_#)h�G��U�}�j)�'�������"�@��D��#e���;w�+�e�PJm�U#/��a�˲C߀�E!�I0�8 t �"��%U�|�olm��v0U��Ë ?���]j��Eʊ9�I�d�}�~7��X34m�4��v�ٟ���0������o|<�f�s�)p��{�~F�C�'y��H����G��aDP2t���otO�;)%nQ!;�Iߠ�������#/��pk��P��!Ύ���i+ިsT�XYz�%�zs,t�Uꛫ{�#-<%-u�Hi#-�3 �ء�b^�_�v�\1����c��b u�b`Pm���m#/�:�|���;5aCl|�<*:yo>zbM�u'Y��q3���#-�г>��K�x�7�i3Jc�;6S/gl�u��#{ֻ3���\�b#)xiG�g�����yb@3��:-0��W��o?���\=>�Q��fa��o֝��5��)�Y����kʻLӻϞ p���� DN&�6iQ-9z-�b�w��F�-�hȁ�^P)�Q*@KH���&��Dl6�#-cߦp~�j-�Q��G�c����O��zP3�����-�Tw�����������o���Q���<�4m|�z�U챔b��>��x����δ0�}ZQ^(9�#)�]= ��\�P�D�ߣ���$yAR�#))aN^�F#�H@e��U‚�Yӏ*li"4{�� i��z�v���~�<�|�Xm�<�O|Է0����D�E�FQ��O�Q�H�L�|���:c7���v��L���7 �Ƚ�����������=~��M���A限�p�ݤ�Ꙛ��s��� �g11g�>&��Fr IS"#/�Fv�1��8I�՟g#���;�n���Z���h����8�U���Q֫BFeR,#cqauY#ǘF �y��*���H`ص�I�贺�0j��ǟ��g��(�,���;���SP�)#/ �8#)$Q���yM��=\4~?�e��@2�z���N7��#/�ݸM/?�4��t����}�t4:�_��^w¥}�v9iDL�An ��u�v8~_XN#�~?jp��~�#)�$!!�1�oUUU��[�`�Nc#-��#)p��7@H;�A`6��&ۍ�ፁی�����o8F�BJD�P������6^ۤ�6<#/j�&�ث��,��tͤ#)�#/3��#/I-��y���Q�X2]�h�y�eȜ[�u�up*��Jn�*.�����[�Y�����-�Vq�@ƴ�oO��ǝ�aUk�¦��Sq��L�`��,�ݴ���ԏD���q3)(4�*$]��m���i���b�N:�#q� ��'��,�p:���!{��~�0�O9_Ʃ�g�ߩ�^��Y���l��$�/�#)0�<$�t����#-|9ߠ�9|@C���!T��#-=�Cr#-bl���@�!�4H,��!��#��������f��o �9�`�4�۲b)G�V�v�JH>#D��w#/K�ł��E .�e�EEb�,�������AX˸-�#Vy�Z��E�&F���,Y��Kb_Ni���ύa�c�����UM���e������#-dӒC��G)��AkotcC~^d#/2��#)����8I $�g��o�T�T��������pk������^{ IA��#s�_�Б�i�#H$zZDx#/�����o�.#5U��#��O9\��L:W�,y!O! e��=;�Z��w�(�[���,�Y��`']�L���5m��3�f��#�l���[}oM��M�.�j��V�@�#-���[�Yr�Yu0zk�P=�V%O2�(�����J(���Hk�2fd�q��D���y"�.�I5�ױ�]�#-�����0� V��蹼#-9�IE�����aښ��*v;�# �+ �(���T�]�V�d:U�Cϑ�˼�x��H�C�:��#ػ#)�2�Kbm �U��#-���b����#��#kkϲ#-���"+�S��5f#/4L��"��С��iH���Ԋ�Q�*c��O�$g/��u�v��Rb#)�4��Y�]�u��E��Q�� �S$��B!��c��5�H�7���FA��ÑMa!}��bȩ z 5��7#-E#�>bƁ �q�2&X`dF���`r83�keUF�^���Ӧ�u 顉 �7;�I��%�:1��q�� �5����X���T*v�Cr��`ܮ#)�"Ch�l�3��o��JW�������H8�1Y�3U�v�G��]E5�{$��#:��Z p#���{����"��#aCi#-����W��7ҹ��B�A�����\˕$�M�IAd���^��Zzl�,\� Lfx5��O�Z4sx���s˛H��*�"�xx�O+��74�#-X��o(hmIx��/ud��ߏ��]i��D�@��2 g˸5 ���m�7�nl�$�I�����r�A��듌O��(�?�ܦ��C$���M��;�q;#x6�P[�z���1wm�u�������d��lju?�zG�?dQ��黶�t�L�!=�H쾂z:��ӽ���l�[����q�dM�'Xvc=o��X�`���pedt�Ԫ�g��M�x�����؃�Z#/V����{�'e��BOXxشh�Xb���b0F͐�{6��#/F���H@�rq� x(�A���0>__uHՑpWZ�#/G��0s��H������,����:W��j��� AAO�TETd7���kS�T�.�(�f�(����(���y�����m�!��g�"�����~��z��"@��� B��JR&%o~�$��[v���"1)��%\�R矠��uT. V��pd����Z��ج�R�x�!��;�z��uo1^���鿀�u� �D�������;�Q���c�)��D�T#/�j-"��u�h�y�&��c��o��;�N#/��j�k�Tf���OJgH�T5����DA��`�6$-��&�M��c�"���0����pT�?&F2B���;�oT� �7D��_���y{C#)X��A�`��3;XE���!&l����ysM�7V��{ n�� _��ϷJ�8B�o�#�N�s׫hw��Q}!\��#)�V H������6���o�Xڹh�ZK�BG��;��;���TD5�U��m�kkt��Ul�8���!�OORI�;p�Y��e��(�0�ij��I� KVl�U�:�#-a�)�`�c4 �ő�#-� #��?�G���?� 0�k�R�L[�ݼzm��M�nk�(�ݠ����-���ͼ\�1���nY++�F�z% t�ѥ�J �L������|,���ξ�l�@�!$J�gps��̐�i�e#-��s�'����`{ �Of��O�������%������e����ݜ�c��i~i�;Ǟ{�b�]�dH�����vp���`Sۜ�>���8�}j1��P���$M��fZ&���؉�?.�\�۫B��0��J��rF]��1��4�r:��r��ؽC���1-�#)��@_�H��R��?�~���\;���0�[�,.؄�r�7V�%"�3� '�*H��BP†���}*pt0SK#/K���\�cr!�d#-��xrn��YZ�=�~�-������h�O�o������o#-"Bo��#-��Oy���~�������U���{a .��w���-$%�����6:(|���!���ӫ2�z�0ǒ��!;�DK%�����^N�$+f��1&�y��9�m*�`� �y���s�gbQ�L*�O�4��I?7˸��j�);�~����O&�(%�&���kK��z�^��@@�*�!��afj�� H"��9���W�Rt���Is-�P�BNڄ�p5���𽮖�[`�͟���x��6���*������#/�Z}�B��FS�?�-&���ZR�?����!$ kh-�J�[%�V4�eTb�YYmX�m��J�֓Z�ʍ3��)#)V1�S�~G���渖��9��vUuç҇TA�Q �� ���C�#),x#�#)�P}w���a�{���uX �Km~�s!Cᡱ�G5jа�,�X�ڊ�ȥ�b�aX9�;f��ސ����/�] $N �#)�il�6�M"iҾU744�dZ�8ab��_J� �&j��ν�t�#/�����ީJ�h��v3�N{�uqUC&�ݨ$[j]8l��]*�zD`So}����=]T�WUk���Z�?���gj䢖��,$�C��)#/�H�>̵��$���sd�kr���L���5&�6��d�TE�o�}��w��Wߖr����8��#) HAdA�N�U�G��8����^��g����T�G i �8�D��P �'��A�^��N�|.�$�P#-��y��m>�i�w���~���^���h�{�{��(F@��Y%��vx2�PX>��SwZ����U��~k?K����(��*�#u�}�qӧU��X�ʅ:4�x���(��$&߷M.��[��6u�D���~ZP�L}�����Fj${_��<�'g�Aē�Ћ���A#-�Zb ���i�0"$�X�ߘ���۰�:A��5S���2�u#-Ou� *}���9,���*_�^Y���5�6@A4�lK�0���i�|��m�n���ua��_����<��}v~�8Z?�j@�;H�_W����?�G�C���s���.g��r0N���8WN��ҋ}��#)��&ěF���!P��0@�=�2�pU�(�4G�w��?*� �=$6<��#-�o��__�a�j#)�(�{{#)f�\d]Ψ}|���C!�`�:�J f�2��F��<�8�]�F����br!m��lN�8��y��=h�*�k�r��gY��C$3�C�e&S���Wd+\s1�8�;�R� =�}#�#)��D�RTT=��tx�'{�t��)耆�Σ�f+n����xȐ������򆔅�����J5��oC��qH���UB�AdDd!����G#/�f�e� ����Oc��ӻ�TMP�b����7�q�B]��5}-,�F2"��Y�C#-�`�\��>! u��X�A3�d�4�e�7W�:z�Z�5��P9#-�Z�рx����x=�d�1"�w@;�i YY�_A`e��5�@�R�x �K��ߛzu�oj��G��̢|��z/���p��������oyЩV���Q0-�t��i��o��t@sz�G�����t�]�Ou���Üq���1в�f��[d�M� r��>��z�@�7��x��h����DP$S �x7�m��"�[lmp�胁7�l�s��y6��m\9�7�`�WpS�c��Ʀ���S���PV;V�YJE��Yͨ�R�ȵ��A�E A�WDG����St���|�C�CG��͇^�ϯe��O8!�5�o�}�5��&=�ÿ��9���! ��a����P#/!�h{��H��B���`%jBU�J�))B�=��џ'��X%��)W� �����@ua��p�dOľ�::�"lh���o��BB.��g�1m���~pT���F�y#-����C���H��z��E���m�]�=�) v�#����(���l|.�U�w�~����f@9�F�n��f�u��xgsbX��9�Љ`=��6Kٟ$�������Հ8i��}H@�m1�׸�f�ܱ1���P4ls��#��8���F�:�2UT�b B&�.�߿\ 1va��>w��Y�1٦�в���=��Ow���CԊ�z�org" �3�S$��Ξ��?3�ӷN��۴��Lu�zt��`eH�;o��t�x==��C��~��v.Ž���^�cj��Z��8������>*k� �٢�d�ʇ)ZRI֦�t�ԍ����ȏ#]IqB'}�_ *~�t�c�:V@�3c��d�E3T��� ��~"2)�ώ^����:���v{�kf�T���:�s��/#��Ū�&��V�b�F�l��K�);����rX�SKj/���F�!V����Td-6��HQ�#/���J]�.��dG ��Fm.� %�#)m!�@0��V��k��hjk�%Y�H#/�&��N�xPz9maM��Vw���q�_?�}�����~���x�JTA�JIP#-��*�X5�o�B��$���mP�B��:�*�|��|����v���?�]� /��R�Q[�ꫝ��K4�I�#gm����S�P��M�8�٢�� [3���R:M��#/�"����f[+����'�ʑ���Y��Uc��{��^[�=�x$����$��> 4�U������ ��L�#/"�D�R��h����[!)"��HQg�ݤ止��jx�>�g����(Qp�9��ȒH�E���� ��9�u4an��4��kˀ�I ��p�ξ���t�ϊ���Urp:k;d�&��(��`S'\DP ij�J��H���b�W�m)c[bf�UT����RD�#)����߄{���bv�#�:�������cn.��X��#/"�TC��#-�4:kz�L���`���x7H��#-���Y��&o�o�i�g[&4�S$.wy}�3��|ߦ"��m���}]��~��W��E���O�����#-k" �`���H���tc�ή��T�;��N"�}: $ 3Rk-+Yj6@|�D/�B���3W�(߶��* ��B�3�{��'@�/]�k��[��j���Hڍ�����m��@�s9w.p.˥��1�n'��$Ґ\��&qL���7k�S�"���yf��#���s��_#/����R��b���U [��iv#-�^� �<� ���r��2��/`P*#/��gYY�)�,Ѡ�o�yv1RAJ5�0#/!�F"��hi�"a�� �<�-h��-�<��3�ܱ���Аxش��8�X KV�F�Q ����uu��F�����e� ���s�<�s�l������D��#�4�d^M���k #)�o��F/w,���6���գ6�=�O���of����B<;�:����}��$ЋE��z�)�'���/�KY/٘�7鬛����#)I�P���2!D�*�Hm�|��\2,aʲ=�Z�Oor>�r_N���)d����o� S3A�w,~��yD���p��آ�U*�����@d �#-A�U:������s�A�C������N�9�[�#)Σ��7*UUzK"riqJ\Tb"���U`��b��eK�Lsש�w���=�J�QQ,,`��u���ˏ:��_�.�5�;^{:�z���au��lU��hhD4cJԞ��&$���D�#)B����r0*�Zb�#��ts�rׂ��' �وL2n���M��@y�iЪ)Q���#)�W;�Ν* I7�QC�Ƽtl��V|4��AF��#)#)�;�檦‰�SPXF@��.ˊBn�J�U�<�f�5g#H��}N�#-��#ξ��ml6�Qǧ,��2K�Q��&ј�\�*��01��<0�:�(�e'������&O#/!\4c���F�(���$1��������,Rޫ)Y4��Fr9V#-6)�����z5 [E"�QA҇���8�p�����f��r`�ƈ��� f�W�!FN�'1 Mc�djB~���)��Ycd)���Ƒ��x �d��FS��#-cot�,{)ٍ�0X���7#k�ͅt�W&�[˷����k��q����:�¿{ע�b=c���J`�z�BLQq���?����{ץ�ҢK���t�a�i���g��]a����BT�ts��C�y�G�Q�/�G�V�+&�5�6�-�y6 �i"H��#/�A$Ș�!�@�c�j��\U7�.J�Q�j� GR��O�|�ph���H!�T9@6\�f��r#�L�(6�2�b% mZ74I�Т�����MD&�0$ٰvt��#ń;�ô�m��w�G� �8k������QJ�l!�����L�U)hn��8T4-�" X #-#-��ȭ[&fV����.۹���9�ML��5#���#|���[�A����u��_k�A�:�QB3�e��'��8����`�t%�u����"U�JbCd���M�p��i�U#)l�v�5��!�Q =��~������86C�"4(4��5""��Co�@�6#�NQ�i@��> v���h�ca7��9��/�_���=L�[8q�Ú����׋ƺ�;q:X��t3�ۖ�=�ق�WD�-� bP@�-`�ܧ�&�e�Qd�t՟a5v��#-��jg���>q�c�C��9����o�mR��ڷF����3L���u��g)��;Y.E����#�`M�=�^C�?|;$�{'/��~�fY���4 �2#)�#-��o���N�}Mm�ac���@%XV"(���bs�hI��=���c���`͹�{�nP d�ƕ ��H�&�4 ���B���L,��fh#/l�#)��S�`��X g7C1 S�H0`�oa�F@�����M�!�ش���ȸ�2�|�m��B΃��e�����v��5�� ��گ$y��#�d�E�{5R�ɠӿ���̾'��1x? ���Ei�Tל���jJpc�,̸��[��|�����$"������OrZ��R��~e��A`V��E��W6���mEo���m�j��]-.� ��vw�\N�/��Ջ�rw�⫕H�#)��33���Y��4��\.z�ܼ�kZ�ReHВ L���+L�$�&����5�I���0b�i�C%4D�Eic^��C&���J%2�hS&&i�#0(Њ��%(�_uIdP�Jb�RYC#-PL��J�A2�E�2V���R(� ��5R�1�#-3i�i �Ai���rM��mN#�#/�_�)�b|�|X&A�~l�U_SBݘ���3fD~��w�9lY!,��A�׉�i3@���s����9`�� ��g�Ŋ1�%��q�.�G\ή�bv��F�$�F~�%���݋�}��%��<��,媗d/v%ۚ�����#�2�7D���#b! 9uf�T�`��c�������kuݹ���bm�� ��d� �����Z�^�o�_�bc5��#f�V*(��i�`B�Xy�ϗ�}����u�3aDPn� ;~�v{3�= ʩ��� =z�0�RS8H���թ��)��[8͏~�O�~�4�L�+�:�� 1�8��wR>���~��֟N��3�=N��%ڡ9�W2����A���g��ˈ�L��0=m� �p{"�>���N"/��C�)QR #/U$I#)�ܙ1� ���H��Q�~�~Yw�1�R�="(�2�F^#->�p}��1��J��x� nk�w��<���;Y���P4p���}Z�~�tI-��O>�oi����ȸ���*s�.#/mf�8�X�P���†���U����y�k�4₶���0�#)I�B�FM�w��p�$���76��[��j t@�B�Lv�Q��+�1�-��/�YӇ����:��w�hג]�mw3�FW�bT�����rC��s/ )X{N �L�'��&�BbP��{�2vN�#-��"!UE�eH���U����J���ʳK�h�#����Ħa i��F�����EL������Œ��tӃ{��m?���7���1csQ�t�Σ�CL�[l��͌�9�B� XgF�E5(Ԧ.3Z�H��X\o m.t�fں���-�`O6���)A-L����^%�$�t�/�����7���Qæ� ݦ� �2�8�?7\b.��&�e�=Y$�j,�B��9+Ҟ�.o(ާt��]iڃK�T� -������t���x3Fӕ��3��X��$0�7 $��l���lI9+H�IѰ~Z� �����!z/�,�7#/��R[�&*_������������4�To#-�>�02�!�n�6#-�Ω���с�Đ�Lc�:R7f��"7J�ՆB���h`����XD�����12v�2�t�џ���h�F9������ i�5�zY̳�~s��[i���cÓX�t��؂��v�&0#/ �����/#-�r��,�)N��4bц� I��.��s�П��{���Ɯ���$�.6�ވ����Y�����t|T�z�R3��L�N�v����Y��͔#|O�k� � �ݶ!>�3��O���N����X}�kQ���ǖ(#;cC�I4js��pumZ6�cx��b��.9�{���3#-����� P��I��=���s���Xݮ2P��qu=�th�s4��ZgV4BL��1�yRw"$�kfM�(}����%�meӊ�`�ݡ�)C��]��4Ȗ���d�z4��r���= aE�P�X�i�SW(�m���/ް�Ɇ%+a[��*ɾ�U�쌦�!2�(ƪ��cfz�9�Rw\��~9w2W�<��,��Q���!�9n�6�4��� kKc�2��������H���u��pU����rs)����H1��tî�p�\5NK��MzɵQ��4�P���\*[ �Qy��z#/i���u�%Hj����T�H���j&n��Ē޸7����f��g���6v��q�ΰ�tyYzL�k�,�]EƐ<�iQ!���Xlh���p��NV�Nځ]#- ��H.q���:��R�IFȡ�b�<�P���ԙ���)>�4=���#/Y����E�&)�+��a��f��C\ı�5F7w����#/�b��=2"��r\$d!�'tf�m��l�z�U}ؒ�J#/��^��n��%�"eB|�8��N�0j۬�}x7[5[sgWXf&�,.~�x}w8��WaN.ff11%3�9��n!��Mr�ë��\���k({{����lQU#ӨBY��r�㡭7���e���cs,�c/�Q��%���/���58Q��z�E��<�&e����Q��5�Tl� ���ܸ���*#-��O�1��W���� i�#\[eqp������UX6���k�C(WG12p��8�MMՃ�F9#��i��$�#-��ٜ]k��c�-��ޱ�&��#���)�X��Q:QTT�U!�D���)�E� ���H)W�<6��n�i'#-;&��CtH,wU�Ꝍ�yb��vv� ���-U\�)�ٞ�-8�b��;�J|��7o Ժ��|�&���"�P�&�zH�9�/F���P�9�#)�������i�i.�To^Ň&���ml�J�Z�5/Epf�Ǖ�7�Ll��V��[�̸��Gv�wif��b�]��V��j��X�]�&��� �%ސ �L����lM�(��GE�D�,���Y�ӌ��fp�Vmrt1��=D�.�Pa�ţ�#��wb��hTk�!Kႂ�����������`ȳ#�`9>�nqի��I��m�)��⁰��'&x�le,Tm�T� ����E/,-�û#-ұ�p��04@�!�J�Q�&�����\���,fn �&SS4�,����&��)�U).�:�Jp$�B�t�����m$FZ����jl��X����%�[Ja�kd�r&\�*N,��� ���jS�5@с�i��5͜#-8� �v�!>9�eV'���A� ��ء��6ʹt`��N�3�aTB�eq��=Fy�\�mC� D�0كi�t���A�;H�wn�!�l�}�q�o���]�q+���Y�L�F��j��fcO���:[!͎ �@:�4cC#C8-Aon�4>ɫ �Y�U��q��/���gg�'��KD�.��Y��������V��������g��砠�+�Ʉ�&tq�#-)"�[eb �T �r���E�[��= ��B�ԇ"�4�@AC�#/f ��.x�?"�[�R^���(e)#/�#/HZ@���p�[����R��XS8�#�K����4t���2��6�I l�]|/�����X�Z���5H���TX$Ga�Jt�ކ���%ҷ�ir(�CN���ng����7*C(Cb��[8Kb ��9b�dm�U�0&�22G��6�#���a�u���R"C���#)�a3dX]���������8�h��Ǝ�p�UC=�A���D� ����Fz���0F ����n�hg4g.3hn�" '[w: �c�@��sdh�قə<�I)F��P8�&#/f� i���v�2�lCnBd�j�23i��T�p#�&wM��+q*���.�v�#-0� ��lK9�00���#)�5N�tXk��J�Y3FL՚��|��C�7�?�$�B&�"hgx#-*nD�P�D}�H���6rQ��C������Ƕ��U�ѫ`��#)A>5F���d�u"##)DN�s�R~�9Ƥ�@�:@����TC8� � ��8�(� �rO�-�L�(C���$�S�URa�ϥ���V�C��N ~Qdp�q�}�8qispj�)�Ѽd���u�Qv"ì#5������b��ۨXE�0@�C�q�*G\�'I�eK�ZF�̓$��d!��#xF�##��Co�w`d�pC�p�"���o��� #-�H���RC�����F#/A���g�U֠mO�"�#-1#�`�B7 B*�#)BƊ!Cd^>qJʁ�m0��b��g�b4lF����F����-#/���^�!��\������C$&�X���7�^=���<,p?-dȸ|����A�r~����m���>Lr�=ٗ�F��wG*ɽ�f�&�y.U����1�������{|&3pZ5��[&��dB�b�oQ*�4#/:`�Z�0�4�Αs.7� � �ϖFiE�#-%�4x�{1�"�����.\���b��3#/٠�NG��Q�0�J��)5��XѨ��j$Ƣ&I�f���AE�,b�����ַ��>I����J�S�J�S�޿�2 ��t��h�o�@���A�0~��^�6�IfO�m�'��Z��y��@�%9DAʀ�0�O'W������2�����xL��Z�t.@�Iʁ�]ْ��4�U�Hm$�?#-�E��@!ۮ��I�@)��Ŵ���-���4�L�d��p��R�7��Q�zx�^w\�ߵ�^��ʺ@nɁ0ɅE�1 i Ь$�Ŗ]P)�-���j�d��a���e"f�83��T"�s{�F3�:�сYhx��rF������0#/��K{��oRC�f<�� ��(��z��#-s�dd�������2Րi���n��.���d��#��R�UC��uHq�#/D�-�Z�W����$!�F�&� !K���)l���^#)H�x �IJd+�Fk��L[//��H�yA�;��nQvId! D*�, JR��[?hk%��u����#/�^#/�� �`�0H�hsI`�_�#)�=��*��fV�}31�te���q#k'�*(��3��AŽc}"�aV��9+h��&E�ה|=uɟ"�Ӓ)�����9x֐�Ho�*#�|1)�7v��#H���Pފp�(e�\��#-!4��Y��w*\[���$�!��M`vhU#/���i!K�b�g��:�'5��bCJ��Z�ĭ�nj�%�N @��"r���+t﹵��+E�eG��p�0~=l��$�r/3 $P��c#-հ)†�6�eP��%*� �U�eYN�9#/3���l+M�r���j]�0ֹ��h�č('<���;X�B&�[M"���ս1���C!aa�} �Q�dB�c�2�۫��A���K-�n�Ĩ�Q4�I�F�����I8#)Z�H#/�����]y63��Y��� �@A]�x��?Xvה|ʤm�oz����i�"��@��?�[�"�(��O�Ά�|��l!��ֶ���C���7A�L�D>Qu��Jb`FC�+�d�& �I#^#)���vM��Y6Ս[I�j�m�i$� S�h}J��F�J�2�b�yC+Qk�>kyC���0Z�K�⸚�-�J���#-�Օ��U�ڎ[U��ȡ�ogM8k;ĭ�L��V�fFT�qK-fS�e�6�M�M��[��jZ���t�42aS��F�t�^&�5�� D#-�Q�nf�L2�a�$m�n������^�1�>ܑ$�SNDI�e�Rn���.�4A�Ά�p�T".�F�g[S��8�"�n)ʘ��;x\:1�����i��D�����*�n�%�#/�)���7`$��H�fn!��T<Οh��40�+��:IS�&�2l�HYzZ� ����<�]"��&B�����"�ƅN� �ȤHCޕK���6(�kj���4`u����` Ț���T/�|qucX�]�ʥ��f̡&�$�r����8ڥ���ER����.�R#-�]�^qc]nm��v�#-4��z� 9�ХJUr����1����:��G��'�\�A�A�lm!*��\��*���l]�鱀ܐ1�q�+V2�S$n��O'�qK�[��nj�U�Wi5�t���)7��]�L��<�w�W�bcJ�Mn�5F���v��{�4p�J)�lԁ��[E��#*�B�L��X��R)��Z�ZYKL��̩��O��^xME� *f�VЕlғm%�^S��oR��LljE�5����rL��$�(`@P�����AK�(�H��\TA�o��";����=�^x�����z���)a�� B�h=��0�� �bz;M��$$ <��,�E����qaߞ��P31b� �H�m�����\h��7�N�Td��9�Wtn��/Rm1J���"c��J�Q�! �#)��J����L2��#)�Hm-�8q�[ҖQ��,6S# ��E����l�)����р10�o��O��#/CʸZ��dW�r$#/�� �A�Q�6p�������{�<����#=C��h�p���׫��~,d�?L��7��/4^�t"�ˎ7G��+��#-�zb3z�Z"��C&ْU�/HUK�l���x3ݟb����L8]d��Gi��iZ���K�v$#/��&���m��П��K��B���~���"��0T����/���c]��u�[�?����M��2u �n����d������4m��߼��"F�)uQH{-����#/�nX�#/I�׍#)jm�)��ii���[F�F#)!��=�6�&#)j�EEV$�2��DTd�0����5so�u�)U��b�fDd�@!e"�aւ�SaMw��)E��PA�%�Q���Ķ�BQiI�Sm�6�3k&�SE*So�ܡ�e���%���eiI#/46�e)�MI�6f2�PX�4el��&I,� �V-R�AQR�*R�*��RU!�$mJ!��i�d(II�&Ra4�4�R�T��VD�����Rd�f�ԳY2hҒX�`�P�$�AH m��YjCIoymk�͛Z��Y+V�W�W�=�\ֽf��F�K`��j�B#)$(�"'2IF���פ9;C�r�h9�d���#�7����+�#-�\֫㨂��0{'~��,唢jd�C�^��o""y8i��gI*L�0��y�#���OGmKTI}Xq���(�g�Q~Q=w�z��;c� Y�w�E�g���Rk��^S%P�kf�2��Fy.���JQ�IC��K-ZZ��c�;^ݹ����@��+r��ˎ�tOݾ3��Hһ�1FI@Y�mW���##65�J�TAQ���`�v�=�k�#/ ��T�:��TI�[���6�'WPR�v*W��)AqM2S�b�`]/�����b��۫]%����}Aq �֪<�\��v��>�����h�yT �L~���#R�=��)�^ �~w�"HR�v�������G��B�Nн�����(�A�[JB�C<#-��X#V��͐����TF#/߯������C��>7V^ � �1��d�&yi�ؙ����c���,8�g�:16�0��b�`����v!h+�յu��z@Å/�Hv ����������� ��~2�&�¤�id-��,1� H1���@i�II��娊�hnP#/9�d�h�L�6��ڶ����^�خ�4�dX�k�F�Ȳ����z�E���<�QPi�Ӊƒ<�bz��̝:%�hԐ�8d�"L�;!O��D��ד���G��T;NA�x�%U/VTA(��2�3=j�8��J����D#)���� �-�*�8J&�&�M1�@b�@�B%�#-�����{P���g\�=�tY��u �(�4x,y�:I�bB�#-���0��RG����@��/>�>e����p�g��K�)��=��m��!��:D�#-� �5�wn BnC#���ݩ����ZrF�����!N��6�����ar%qu�j&d s��@9*�}(�^����zv�3���V��T.4�;�3sΌ�9�A�D��J��1��,�"�NU^��4>���I�&J��s0�8,"���N2��߸�C�^#)�^f��pT�Y#J��bW� @gU�J�fT(#-�2�p�`8��p��v3�{�rcy�ww��ƙ�1��>��5&7�"��H�*�1hҵ�%$Tҩ�Rl�TƆ���O����$�dM����k��L�p�ے�.y�Znj�#-�/;��]]ܠ@ $#8kX7 D�!�~^��Ҫ(��)��� ��By1g�a�xu�#/�{Wa��Ü��� �EHw�D�|g�{�{������ǟmk��XL��u#]��F�\h���̎NRM�ݢX���bb(z�&�Ɣp�wyzs�����a�������ZW��)�PN�M;����{p��݌�<��1!ON�-����ϡe���#/��SY}������Y����#/F��,0%�q.��F�i�ؒM��C2=9yr��6�[�&e�d��Т�#T(2�/"صk�S���)x�ݸ�&�\�/d��j��y�ۖ��Pc nκ�e�$�tw�}���ᮋ�G��}_f�C�r@F ���!��}�3�c;�.4��bE;Z��b�~�J�f^��5����f�)'�hwJM�0�����V�Y6���?Ґ,��S&Fl7$��&� 6��QkU�2���MJ���LIdlV-�oΫr1b+F���x\�%�PF _��j�VE"H����hb��.p+� ��b�4,�{�ˮ�g2�ZB[%%D(d� ��c:cgTF�G7��0A���ByͶEָH�p��2 M�X�bR�i �5+�?^����婰nXG��%���x����$��ECU�B9l����M�^.V������~N#/J�H���i�&,�&����2���P�5��H�E,�FEF�h�5;[m�Z����~�y���26@��,���2囑�q�8ޣ�#)!tH&A��zm�>O�8< ���`�"�i(� [`,n-g�d���(���?,}����s�M�p.E�.#)$���q���#)�%퉨7�{J�o���߭��w���Q����)#)8�T~ΠM�dL�d6�_#W�����f/��r��� �ΐ4K�^�n�&����Q��2�zi�#/�QV�$��q����9��?�"HC��]f\^ިo�У��x��T,���;:�xCA�x=Ƞu�Bk�)�)���g��G��_���H'����V+k�ʶ��\�ںYVA**TPE��`�^)QY�,�䢴�5����;��̸�j?G���0mM"�n5� [�~���"dw�����^�5?/�p�nV!���i&��'�(�� ��j/+9��A��:����:� C��[!�as%�E IH�^E�_c�|� �R���g����ىu(0�� �Rg�:� �^��z��-5�ʁ�6ٷ��(;�͡���d���T�5e���֟��;Ȩ��"tP#8~aϳ����$Q֐ޤ_�֚?;0�M���uCF� �QT*���qML�)�U$)���;�Vha��ԁ����/o��w�j��V���k���V<`]u#/��,���Ii���%s�t�t�`7l8`F��AFL�+]$�eݵ&B�)��Ɇޡ�L��DqI���lb-���F����̬��F��BjcU��F�%Q��T|Z�j�hŷ�j#-�PU���́�117�)� ]"W����6�m��o&��Ɩ�!��FFs��ؐ�b �ZM��F`L%���Yl��Bdo%���#-�*°�0�&�P��`N�Y%�G]C[�*�1^N�ۚ�\�Fһ��r���r�7�I�z���`��T�2,U�"$�md�6��gI�1�N�,f0�A��Τ]���a�XH�|8�#-j�Ǝ���CH��\��rCX�tj���4�ihre���-���Ԅ��ؗq��-��#-;�P��'Z@�FA@�/��C��Km�z*L\�6'�c�k��wl��f�S2��5��;l�jh�41#CՉ����t��1� ��ו���{��&���������U�g��JJ�!�BI<�5����-�fէtj7/+cR��QeWUҢL��t�lacX�媺��X�m���%���{�e� YPu7V-J� �*?�d�}����Xw"j@QHX�HE����~g��`5?l"R�<~�.V����c�/��h�!���1#)�RER� ���#/�$�#/���7G  'A�uє�e��:o���h��K�����zM5��M�O���7����"�ʫ4!x���,�aa��)Rʮk��6��[�2"�d�bl�Tz�Ŋ�#)،h4L�c2#/&"4F�T-cW���,�’[R`��`���*#)h�Y(UPTQ#�q�jV?>]F��h��ȵ��L���.X�ي4��`O܆�QK�@T�(^�`b8���2e� �bNI,a��"ƚ�#)x7�8#)ME�f����*A.BY�l���i��2՗�zÒؤ�a=��#)� �.>��~4�1�ڋ�L����Ŭ �UI�Ν�ConԈ��GeP�F��aX�#/�\���k���]��**}�"#)m��A�>ި�#-\�{#)�l�z.�;�4!�W��K^9��w�iKJT�cj�׼���U�k)�WQ���5��6�������`#-�w/ "Ѫ���~��R$ a*�h3]���l�)�T��!w�G����j3���sfӾ�֑�a�$9�ӪLM&M�S �M8���ܼ�s���8H�⭾ca�#GN�f��GK:��#���,1v�4" �y�bi����LH��>�#)F9[D$�x��l��C�=� 䞗��#/����}�l�4HD���@�\S���5$J P X��ֵ�n���*0g�)�C�l$qB'h���t�Wӯ���\�-nlQIu/�$#)�E?A����<������3��˺��r�y~���s�{���2&b���|�VG� �����E/i�A#/z|��:�#)����E**������:���#-�~B� ��C'�Il���*��܂%�Kt�D4��By���iS���~\��sþtP�#)E��0*d3�=;i�6BZR�_Ql��Et��̻ �M/Y��>��δH�OQ������zRX&p5p�s��t�o\�q4��Ph� #0�\�l�f�uN AX�%�T �76a�!e?��N�����B'i@��P!r F��RPئ��)a"�%0T$Iɠ����O%��'���K�pM�������vtG����"xUQ# 9�I�2*��<&���<)=��&yw�o#)Ú6�`ޘp�%�|��f;��`�B����*Y��J��;E�koo􍫆��Ed�(�Őb�Pa�Ϳ�g~'�%E ͐� �Rl��YX�"��QX��|�3���R玓yr�) ���}�Iz��y�E"��#-P���E�C��"{ʡH)E�: eݭ�gM� x���ɪDlQ#-#/��(�rQ5���$m�q�IηI2��h�Z^�k#)�T�U!�f���N/��TmĄi��\�J~������o���@N��BX�6m�ZPd-����9Y]�oD�y�P~�; #/�#-;�?J�H�[��b~�f�H#-�&Ⲝ*TNI��Fl�����S�]2����ɜ�Aۗ'G�g֤Hޒ�%?��F�����V�]TS�ĺ�+nj��B���~���9��Br��,��.���Vi�\�o�/�����}�����eȷ�i�k�#/"�1*��`�#)�#) AI#)�IE�[%�€�D�d�*@��������(<��AOq#),�P]�=S��W��n�C�A���L��Z�L���k�7�����lD28t5��T#)#)YD��У���QHi��'!�eV[�Z#)���u_�߅���׹#-wp;�̚���͜M�E�?[�ɞI�T�yJ`z$��B����S�m/;s\�<���]㶺ěi���R$������!ԅH�2��c,��C��zγqE�d?�B��[.�A���!$h1�@��m��ڱ��1�&+Dl� ZӬCa�c@F�"h}3�Z��aM���������i� Ʊ�1 ��#0��2�I��������껬sx� 9@kK-���m�*�E�h`�B��"ZK�ɶ!0Ĉ)��JZ�,#/�5� VP�C�i�%�� ��Fm���H��$l�x0����@�#-��h9�v�QM��#�E ;��Ɉf�l�p##-e�i�}����Jw�������,#/�#�#)eLe�N�>U�����!>�=-.r����O�^�ĺj��~�VʬE�3�L�LJ�w�u������U�-�Э�k̬�YQ���2ѲZM[�5�z���(�#)���ذ�IHR�D>���H/��c�0�������T���[�U����j�T>3P�)N]gW.i��,�#/��>q�l�#/;Z>j��D�b!���ޓ��Q�B�<��m�U�d�b�#-#-�+�K��C�c�Xi)ߖ�؝n6�I6M�A��yL���g^=G�p��s}�a�`3����@ު &�����'Rb��\q�8��ad�dɶ�'ӧ �1c(�Ef�xv완 ��5��j�LC�/��PJۚo��f h�Z%��5��"��]��m�s�6�H_���������G�� j� �"��q�Pcg��/|)��~z���"���k�;.�ݤ�oY���<�6lD}��>�� ��q�������Rw�@�� �!*�#-,!�������f�!���Li�x��ݤ�Κ��'U�.�Mhf����"�(�7��i�����/E �G��/�F��A�����b�<"~Y��P�U�P��&�P��!/js��l�2�,�s��g�|]��/ �B��A�b4�7-��mh��ۚ$������ۺ� �j,�������� ��ݭ��Q�tߪ��*�Y�MA�����_^ d���,s��m "�d�(�QbH$7X6( ؤpR8L��EQ�(7�%>D� ��!�.2��� �q��s8`�:��\�C�֜Ǭ�vjYV_�� ��(��U�X��j�)8!�E��O�i����ՎF���a��zT��k��CN�7t6a�\!yNHRe�L�Һ6y���]I�z i���0#N����$�[|��M���$V�Ւ�佈�އj>F����$ M���� fhv���c�!0�::UH��̪񫭰�Z��ܷWY�4Ք�i۶��؛[f��u[+����˻J�V��YF•*�mUc[W����Ɲ�O�b���JV����5 �9[���\�� ��j,#/I�=w�`e#����5�0u�>V��dd��{�#-�[�r�#- �0���v���#/�%�� �Э�����#�+��43���@��4j�a��w;��bE,����4�#-q�A��o#)��1#)�bL��z����(�ݠ�_�#-�pl�����ɕ������#/�7l!��OAsr>���b2nlj�����+���s#)o�E�~�'��>t�^���5����cEX��j�Ӯ�k@���5���*�f�>��*�5Ut�� (�̊x��;������O�ߺ�-����S�R��$��]'v5Âk�PX��.�KT� �GL���v�,6JB�#)��&���?I���-`����5���z�.�#m��l�AA�[� Z�ip0�];`R��Ö�$C�}��š���X>���(DI��?�X��8"�iѸtSH˥��@~R~Ԩ6(:*�@�U#/��/%���NtM�,�!�2ߍ�7C�k�~P�Y���0ّ��#-4�^)��`��)��`$b6{(4�7 p�p\�D!�k蚯��a��xA��ӥ��gLeXd�b����;`7�xd�5�Run���]3\�k�C�nx��VD&ٙ$����u�G�k��t0xa��JK-��C�0 ܗ�e�Elգ�z�б����}���bXF��9��sS�DUN繙���0���W���h�a�#-u�׼!幻Pmה��aФ�k����!��#/Yt��>{2��b�A�a#)��ꪄ!��s��3<���D�*�5��q�S�@$IjP*)D�-���j�j-���m�[cF�1�Mh�KL��h�VEJ����P���c����]�WJ�%Ȅ�%��PF��p8.U^� ��ZH1|�wN��.�� �&�"#-�8<ab��}{̅ �E&�g�Unq��g��ۻt&ʟ��}�Z�^��j�yC-��m�A�Hh��1��2L���̢�r|�#-&Ӿ5��� $a��Wѻ0���m(�#���\C�)+�oƧ�i��]��֎ )�D'��.͔B �qs��Y0�d��:�b��k�$)�Men*(� ��B��k��m�"Cݛ�H,�ZT�+f�[�׮�`�&#-�I+�P>S� 1�A�n��v3C/m#/|�5]$��(=�|䏟�^� �w2�t��T]"�#-�p�p�R�� "]lP�Wֱ�p�B�1]\�D@O�*EZ#/6�����=68��0-�M�"uA�#8��Č�CfUH&��P�;3�}>�}����é� � �i�f�WS��w]�վ4�FBj��؞���/�.��)�G�=Z��S(w��,9?3[T��K�DL%���C��Xѓ��2Ä�S#n��y�_[4z��J�8���AvKz(�z�$<�X%��1�b����κh7y:�O'huBl@&@��n���(���7Co�iu9���J���c�U%�[�0Ɋ�U��F�#-���FB�#/d�#-����_!��,�� �MI���ߺ뺛#�ݑO�i�]����u�ηLջ�ґ�33X�h�k���zj�Wy�C�qyz���b�$+^��QF���r��m|�4x��4��m��jBQG4ȋ�B�P2ČE��2D�v�h�d�(�#)�#�V+#-#-a%J�+�dEaF�b�7��H�1��J�Ї���D�(����T�&0��D1�~/���a��en�)��ᙐi��3aCwc�<�j[J\Mb0s.#-���֤2E������$�P�GG���G��Mٷ�2�T�n����OV���'�ڙ�4����#-/���#-8�+��skh�� gZF� V4�.#)�cKl���T�M��,A�B"G�k��I���/�=�e��F�%9�i� t��ɏ���=�����MM���%��}畅����e�=�<}��]8�F(������!_F+!�a 4c_1�q��ƌL�i*�l��K��M��jIN'�#- 0뜪�"ѳk#-*�ETrةB9jz1f�F [��=�����Ma�`&(n�YC���B�]�����&��$��,eeU�c�sp>iG�O8a�)� �P4-����[����y��*�6�T� 1��`�HXK�d�b�b��:&�I.%7� �GN'_a����@��noӫ�����/o����z���E��ň~�����F"G0��Ky�h��z�m6>�m����;�M����m�T(�X�bjD����M��d��֌R3=�����L��7����\��ܯ7M^�O7��ɫ��:�)eY��IN�.��C�m�c4���f������33nN�f��3na��wh�A���k�3W��X XA�1�;��T�XM�$+��[�� ޹���s;���"�~z���E��� 7��c@�Q�'DI ��#-����Syx����;:�M�n�Pjia�mW\տ]���0󂞉�7eDL�6�d �����j�+�Z�u�s)�?a:�+�#-�%��͈t��ᩯg D+�M����} ����D��lǩpO��|#)�!0�Ad��p���#/�aDl- u%�>� ���#�P, �&BY�5,�9"����j�����Xͭ�ktڤڻ�E��kιt��ۛwnd9uxڊxe�ŤZF*T��;���X�J�_��䭤� �%rء#/BKI�`��[�|6n��n���a�I}ا5�r�zrU-(�� QB�F�Zb��� � ]�V��o�7�/����填�')0��Đ���.�Y-Bz�[�5���#/��C, (��Jj�E�E6Qk�������jf*65���̬4cL�&�fQ3&%SE�3&����W�����DT���<3$�C@���b+O�j���M�+ R,�#���i�����z<��O������c|�,#��9�uw|�a�E�j:����EZߝ��֒�Z7�s}7��Y�U�k~5kp�^-t��i�n�#m;�:�]�JZۘ������sY��R��k+�n�f��U]�-4}��!��7�g"1&Y�}ERI�J#)�a��A4I& �P1���D��� Ij�#/BM�(��*��7���J��LC@]�ACS��]��1NX�ϼ>���v��v>�Mzf����cd�=���*!sWZ$2�,'�4�>��F·�"��^&m�#-�S3�Ϻ��Ws$�P��cLR+mM7G�a�#�ɷ��e8���x��JG?������! 5��1�<��t2b�t��V����8�U;�"Ǒ�C�}�t�ce�;�7�B��^l2�y�Gf��-��ń%��~s�5�mu�)]p�{eclOQi��=L0놙E�4�o/��f��W���B��O"t`):Cga��³���y\�j�3���Ս��x����Ⴄ91V-���S�V�J�\���4��Bh���h�`�Da�ձZ5Im�����?����\�I�\�"�ri[�=�F�*�6�m\�k�r9�EP ������Fn�ָ�䌿7`@i4 .zU��#?e�<đ�Z�[%��]��-lfmW �l,Bur���C BL�4��pH�S��`�̌ ��$\�m�V�Ж�ْc%[W4�/��J�;��'��v�d�Ye�$qN�`Y$c!` 8�4��2�v����B�m��lթJ q#/��D3Vi�!Q�� 10�RDIU�P�X�b�ix ��4��WeX~z���`Rಠh]������HT�Y���ϡ�o�b��Vdͺhd7np�E3i�9F1��KQ�v������� *��B֪+Z����$J��W��#�")������gȄ�T>���b����?��"�C�،"���� �s4?O�#)����s?����U"U0�U]#��K��e�cNA��@��~�[-]k>n���rgLp��#-x5�����]��r���\��O���N�Ζ �̀�QM2��ohDLJ��M���)��3��q����[��=��#/�x�-QU�14�Y�E#)غ"�P�)Z� 2H�!p���� �.I���0X<�D�_� �����;�����%���;��>ʤk��jl����F썶oV�#)ωT��#8I;ҧ��?�`���<� �� �USE2@� J���db�"a,�}�ƒ�*-@\���|�u�+�Cl���U�W���Y�Z���5�O��/�M��C �v�9d�6�-\4����ؔ��^n+6YI#a6T�6ݦ�4X������h0�6�r�ln��yv㮻e�\���"�x��%Q�6[��[��sY�4;w�T�FG���7-tڲ[F�,Vu�M�d�Ц��������Pt�PO���;Q��R����H�9�x �邲*#)HRAA'���*�}��Hx���u�)������i�j�S��L��Hu�A����q��]ݨ���&Gs؟� B$d��T�~��V����oεl������(_��9 �>̺�X�����Y��(�#-( m��|z�����S��,��z.�c�0k�cc#- ��k} 1�2�%AŶ(E�����39�-oLJ5/��i-4k�[a^��B����׀������d�MX�N3�.7u٥��c"�h�Y�f%2��K�I�U�j 3 &4hȉi <���S�D7�7�(�����z�ق#/�v쒀����;5#/����M$��/0a����J�S��[c�7�幅����a}ݑª�vsFٓwVN��1����nk���Ѥ}�,�jۄ�� {�r=�R�Zh�{��4��#-Ԛo��s���<ޕ��z���˫F��c� y<@0lA��C��-�F6���I�ъ�]��wd2,����%�ɭ�~�t�������PEɴg8�F[fkE(��=�����O4���֓ͳ`�W��W����I�7��`�;��g��ÖZ���m�#/r��xf�o�u�ԁ�mⰒ0�������uW��q`������-M�Cv�\����8�!��il�p��5 ��EE7��#-d�����t���r´B!�@6��R�|�(�:�U4�Fw�X��׈�@���] ���=�>z;�^�`����#)��s#��p���y�#)�Q#-� �b,���+��6��5�r^�>F��#-��)("m ��H�@-�+၎`ŒQL����sԱtY&ah#� �$����Q���襨$D3�2��|�q`���djڲp�9�!BP��Gʩh}l<X+3T#�����j2��J���G��&-@��#-#/1}δ�4�$CiDIi!B[���q��SV�.j��j�W��!=��r�MمKa�iGbg�3��En���_���a0��~����'m&���m�ƀd���N��c]c�02 J�p�l�Tg!A3��4 c$e�M��b��J;&��rߞ�Lΰ�Y7r�=sU��@��3�{�{4���թ�'~3���У��RCi�ƙU�cH��<-ݧBe#-�I��x��(%��Fd� du��kH��#-J�5�A�c� �}[A���=\��q� ׮İ�y��L���æt����y#/���O����8�d!���{d��O��#)���;�vY��oݕ^�P[W����_v����H�����ADI�!dH�(w�/WAک��Ղ�{k����=I����S�&�Ӌ���!ۏ��'t��}'���P��n��pD���}B�>ٸ��P��w�x��E#)��i�W�,����$�rdы>i���(Xt��9C�$Pt�!�'u#/�IL~U��#/�ϙ�� �wR"�tz7J.e �|ٱl��&#Q�1������lw*)��0�B'| B���<�l��V�3�/�ߟG�p }t/~��@)z�RЅ�1�V�9\�־��W��YI����4^�@JF��T-M-R��~��J�4�U :H�@,����i��P� ��'�d��9+cx�P;��4���(���Y�pۧ;_F��<��41��P_�W9���B0���*�h�Jn��?m�8�G[v1P1��K��������������9+\YhRB�����'�9�b�a싲�������dؼv8 �ʼn��h�V��z�U�Dc�CT$>v�/ٺ�!��6��*�#��[?CG�8�s����HH�?��U��9)$s"_f]bS��߰wM�UN80Xx�����u�1��p��3C���_�&��UT7[ .�e�S�&�I҆#�#)��T�d"gCB���y�`���0H���[b@���P��l�ytI:���1*2 �EF��/y馤��0�tI#/`����#/��p�T�5���l�i�Y�H"(gn��{�Z����s\�.^t�;� �2� �Ox�5}߽�޽I�~���#)�FeRDh��(&�D�j"��%��J����HI�d�P��Z�6�O�����R}$]"��H�!��Δl�厳�lK�6;]/i�y��5/s7F@�(�F����-��r1 �8p>hԄ���h��>���\b�C*l>�Kn,�.q2�Q#/�T�G���:��J�|''����G�8M2����= Lm���f7���l��I���C�ꊕ�y��FF��˃`�j��'eR��� ��ƛ#)�4�d�C�9�?b�ʦ���%��� a�k�h˜����&��9�T�/� ���l�G�8|�T�M�h0��$#-�ؕLd�+o3�s��Y�l-�-��^voBAX �# 6��c���wK���vG{^w����ѱ�U�k \��a[f1��F2�0���_@q�R�ĥB�&DC�ۢG�Y j���$�kEcRkL��\#/�p���i %���p|u�W:^ �Zb/��#/a"��iI��5�4���5�q8�$nD�Z�ї1� RE��D_�����Nw��F\M���`7�a.$��C<�'�5R_�|g5#-��#o!��#Ch%m� nT:)Ś�Pq�sN�jjhX��� �6�Z#)�Ą�z#/ju{.�ȄO�۹e]�!z��H�#)������Z$�P� @���9)��Q EA0�lqȚ�,e�ښmM��f1� �4����&�$J �+*�ܖ(5TN�UiҒ��F�]m��Cl"�- �J��Q�#/�Ymӭ���i��6T��J��T-1��X4���t�\��Ja��J�JU�.�*.��TZ%�n�5F,x#-��M=�-�,ȶ��g�B&%m]���*# ظkJE���\�)X*�q��e�$+$�� JdX�5ӃL�����]��*���h1����bȗ# �0mub���XZ�:���#-5M2:Y�"���mE����1�f�ጒ.�kRPn r��nbZ@�<(ӄ}2#-*�^*0R;����ê0���S��i8�Ң� �"�Ȯ�A��&liLUA�<_:/ a�0����A�Qq��kHꚭ��S�Z؊ �F�7i3���%0Uε ��eY2�i�n#/����L#MbAZ$��T�r �,h�������4���lU���!�̚px#�!�lU4M#/�DM����,�)F��H|3�H A���D��f�M�H}�cJ�f���zM�ͅ�A���J���@�!��s(��O+pkt�Cd|E<�km�Q+|�m^Tbl�|�_5 ��f��0�,;53��E�J�czƢ*�"CX�D��˶FlcY�b����dD��� �6.�w��D�KD#bi�L)�" KA�Bb\�c(P�#/$,IQAdT�0��1A�{If�E$C  M�5H�H��a��(�JS�mSJʪ����YC�%���������wN�w��[�_���j-�(Z"�# #��Z�!e��#/S����B�#-:��x�����b�DD$X ��#)�݁S�e�}ת�? R�։ꢍ�T�Y��>rEB@!���T�DޑB�i{9 ��RTC��^�#���� ��,��T"��N�+�`Y�/5Q��AƱ��#)�Ir��� ?�U��qb���ƷWWM���A�nH7A�=T���a����j�\l�$Qr��c > ��b�XC� ����:ha� �΂��$p��u#/.<_��V�#aa��͵61.��X� x�ۗ�f��s�,�`6���Z�9' A+6x��������n��k%�R;���G>�ә��k�W�A+p��#-�_�DdB��9O�׉���e�x(a�('h��N�������#Gy��n{�<"���#/d�hxC �dJ �_w����|�6v���̦7@�ge�ҏ�ve�(xQ��O�ݐ�픒���m�z@4��q̴Zo�űϼ��]��#-#��.�]^K�M�A���@�!�ي<�s�#-EP�@B�_�<�i5�O��y�M!!��;Z�;��T{�`l��v:ة����%AS{}k��Yn��P��)G�s���"�ԁ�l�?��X��:#-'4�U��x��������#i(I��C��G��0'�"�����dl 1#)5Q����ۭhkk��,DN�E��v�EB�!.��QQw�km��6�eMd�U(ȇ�<��B����t#��#)�����=t���Q�T+���L�=TR2��S�{ZPvqP����#);�f_yހ���$�<=F䬛��炾��9��=��l�8Ț�k���W[W�VR���$��A��K$e�I�f�ԔV,l�%$�M�B�[DZ���mEmKJ�-KF�T�Z�lH# K���Z��Q����(�0Zp�R��HW��`ł,EP�(e ����#-�'r ��`\j<� D*i@d�(���HI�7#/���#�+#)�&2KXH��P(�:0X����� 4ECJ�P*�B*Z�0$(�B�"��#/X��>�ݝ����RЁ���ˋD`K�@��r"(b��J�E�)��y�(� CT��|{�.�1�b=�#�٢��أ֩#�0��N)܇��5!D��㼻t���]J�̡}˽V�j6�- P�������8K�·�e�VF#/��Rh��m�H#/�2����g�a,�A�_)�����-�B�Q�����e�.͕)m1���b�c��h���iě������i�J����%�MY��S|��|���#/����oѼ����D�rC�"�l�ª<�ﴺ�{�9ܩ�e��:!�Vj��v��~;/dS���=E�h�&/������רu�r#)vAւX�/���2��犢}=�I�p��~�n��x�B�?�2�d'"N�>�il���YD�뢚���"�sm)����+���voK���SU�+���\&u���f�p�̺ԏ���#)�6A�^#)R&i#-�!5�T��q���ta�p{�Sc��bQz�j�`a # b�4�r��}i4o�~r�.�N;:�8��㢦�n��KX�w���o8#-�{�w�ij$��V/J������g�p\���>קL�wI��O�Q�;`p��Tq]8���R�|�:���C�t42���oߌ�y,�.m��"e7�J���xm�l�2a$3��@��#-xzk}&6+����bm���8��ř�5���I���y�ʪ�΁ �Xt��F���%��M���'Ce�nvгF����ͳ�;T؆ Eh�q!1D�l�0�c#)��~�#/']�Ŵf+2�� ڧ�+^$4R�w[A���i�3�������ĺގ7;BrIy$�^34ѼqM&������jT���&JTcvڧ��kP:���o�<��0{��Z����e��W���yϮb���V��4WK�N �3ĕ۬��ι��8(u�<�a$�������#-��yL~�{�&�%`��V��@J2���0�*�D���)�1b]*�՛�Ec��˻ω�*F��򪋭��lg�u��=���5�����ln�.���b�|��@��el���Y�x���Ƿ���p�ʘD��û�=1ow��+��]�!�;r��.L�ges->����� �#-�������G0�M���S{ )���N�?~H�j��G.P�P�����t1�fJ���eީ�t�vь3z8��Q�>8ğ�f �z3.�{S���P#m"��B������!�?��(E �e��wtl�pl�p�Lx�<��LFosC��Ћ�D��@ع�:���@�iB�74Jk���S 'c�n��#/ f���r�@�<�͌)F��v�ȅm l �P�q�۔�HO�n��=z��X�D���CAK.����#)�oց��U;1��bu���l!�#/42�&!��#/x�@ ��P0kD ��`0���z�a�9����ݹe��)������`rG>27q�:h��lSAC�#)l3X#/"�9{���L��Jњ\D��uV�6�Û�'(Q��Z�# � � ��Dv���bj�/.�q�h�aPcM��`�@�C� ��Ae��PL�">&9�L���~p]�[e�v5Λ\�6�K����x��;G3��?<�tT���<�!���P�*�҈���r7�AE�����l�v [ e����#�ֺ���h0�7''�(��w�T&�s��R�M<����r��z�J���fbZH���g"l�� x�KE���Zy��ނ�k��dv�xwu���JkZ-;h��F��|����i��iU�W�Gb�g���%��#u�Y�D����}��[��t���xl�c_Gk&h�,|E�閌�+�nWf�rï�OLM�3�\m�U�s2.����#-�`��5�.���f�S�o�p.�n[�S��Ѻ�Υ��U��GG<�t,�w��۞%����Ѫ�`�N�q^%��3�Ͷ �ExxԚ;%���ު|�17����x�7��=�Ǔ�x%� y����g��t��j�q��ʋ�;<��#-"5jZ� �R� ��'Tʂ�12������Y���u�SU��G���P;���'���" 1PК�]�/Cr̆��wG�ѓ�w�d������VNx+��S����\Bbp�z��ꉴ6<��P��,!ܽ�t�\�0�w,����w��(aK�2���v�x5����p�nP�jX,Y�c����ǧr�T�U�*�Q�[Og:C�b�u*�l�A]�P�a \�Hi+�A��Yp��t#$�s�B7�������dp�l��9�&����0A'�#)�Y"a���⫮��5;��0��� ���yħWX!��Y�x���ȷ<,GPAv�#/#-�#/�e�ĵ�k#)#ؠE��A r�0����:���+�]���5�U�����b�xtC����-�� ���/-�T�Q;x��+}:���h�Qˏ�N=�ԉ�a�:� ϵ��i�+j�E�Y|�Ti6������iY���kh�TЬ�Es�Ը���#I#/�K�J�1��m�&@�<ƅ�(�`�YF91!��"�T������u�Dma�Z5Xڷ�h���� �f��Ze"Ȋ v�X�k��Q�4��(�TQ��A0:Pc˛���_����!��#)ɀ�M��98) �m^N�AQ3��(_���zoxۑrlkJ�k�-�V�j�ʪ*��7 �D/zN��9�p���SUh�\��EJ�-��AKx�*�1��K+ud��/������i���o �#-h�Hi��ѳ��Q�+��_)�S�����5�1%Y��xk\0 R�k�1��K #/A�� �8�2�"4��q���.�k0��2$fP�14��AZkB�FS"œ ���u����� �h�� ��F�� �-�2��HU����?ڛ��ɺ���0ɬ&i���1۹pb��[�,M�(�cu�e�M2�u㝬�{���(�D$5k�Z֩�nˏ$�a�X�:��5l��ɂ6Ć61Aq�#-�#-�H�i�V,p^,m/"��]l�[l2L�-~[�Z��v�0���;Ĭ��8`�&4!�t�D#-A�j �8Ƙяv�U(dH�)��v�]�60bq׷>�<��a����ݝ ��F_��F��j�-v9�������*����Q��-�m�1���y��6��)51[��v����@�T��,%�w�� �aLQ ¥ ����d[3qe(T½�K�`ϙp�*#���4�F�v]�h�����P�QGJ�5$r�[l��b`�[�P�+#-0H�#)�A��s-IcAX�&@��$�- �,��*#Q�� ��k�oi^Ro4J̅��TZ�AG�<1��gx�PM�+B�A22+#훞4q�M'���i>N&}HNL�ʃ��"@�q"fZ���ҍn“17-q&�}����A�X#-l�Sb9׋��nF)T���E�B�X8�N���&!@0�I�"��8���0��EID��N��Ð).#�o6II$�T9�Qo{��8�#)M4L�)\tn)i�XH#)��l�����+�������=p3��d���Cfuއ��F)�ל|���t������g��#)A��u��:Q 5T:o�`��CH�O"���Y0�Lm�mjf�a�~�!�#)>��N%lh2FNa/j-�/��*�.S���D=}<�&�BB�,A��w$A�u|�=Ԍ���#��ƓS@��:��8ڶ�/@�Q'�Ks�r[���]���[�4�"S����i�*)�i�Q�Dn��-��vW�=V�A���_g���5����K�M��'RuZ�_I�J+� �缐�"Ⱦ'M��f[����]�hz�ro]�mT�d3�+w�K��O�E*�NG�ש?��ا��a�u�H=�β�{�-�_`d��Fz3��#/r�<#/77�V<�@M�Z���1#-݃�RfL~��n��#)9D��`~�)�Ad�UL}#н�J;��}�٭�$�)Nî�t�V.Z��϶d����8. r}#-p~Ll�=��Բ]4X`C$0a����OH�v'F��I�j &�g���>C�����#)p�Jr�`{�7s@�q{� �bQWIq靔�z�J�� I�s�c����Q�Fr�X72-���Y,FH� s���I![�.�y;H����|Y��Jwa�*����'*�ƦxN#/��%�J�"#)Q��d#)a��#)� �f� �_��|˳ ��gmȷz��Ԇ#)UCS+1�j4�t7�F�Gj�Ł1� Ie�s�F��P��y�@���p8�e����Ffǭ��l�&�s-R)UHT+ jg#-�#-����q��,-0�7k^�Y�9$7CɰMyQ�DT6�R"����?a�� �bS"&j�`p�b�H6h"�+�GӍ-h6gJ�-�2�yiQ睬�#/F*^)���`�^��P����n9�ɾL@Em#)@��$'��Ni�f���! �,��2�ox�?*��}��r����/����3p�& #w�0�d&E�ro5:�fbZH��@�� ��ؿ��4����%������)��Ӡ�� /=m�Rc��};�����]'ں%�[/P�A3P6�{.7o� � ��%#-HRA��]�|ըX$Y#-#/��J�VLREFL�R� ���ql�h��'����ˬ3R�7��y�v�h0��WW4w�"#/D�;�K�C���;�U�M#̢�F��#�����o XO��ѱ�[=��.3}�tͧzf4���x�Y�8��:�R�m:L4+eA,�>Y�8��;��f$�L����K1r=I tW:�1����cvL�4f\��zm���FD�$�p��ñ����4�S�4Z��� �'f������ܦ�g0�H6SD�K�;K�.��e�ψ[m0Zyk7���3�ky��L.�[����J�����®:ċu���[[��i���xȇ��-M�]�>����eY��,���9�� "z�M"ֳJ0�k�%L��Mb��]8�\��ᮛ�}qʼ\ɸ�D��&�k��� �CV^��s���mvn,���$�d�QŐ��_j��~E��0Vlh��<��ؘ#/���ˁ�z뜣�WC�]&�&�b�(�n�H�&l����3���yt�ҥ���g`q�����oP�8�����qA�q�HFϹ�ʎ�����[^,�-D$N)6��C c*�K�,��#)s�Հ�E%T`�ޥԭU9kC��#/�^Z��ň���I�A!'WU𣱬�5�K`�ِ���#/�͜�1�1�H��PmQ4,T��\q�4柁�����I���� �d�d�z������so��P���V���h����.��m#�I�o���{l��M��4|5�f��c�L���>"�Ā�&���v��͗�'X�Xx맑65;��v��K:#�r�ȧ=-1L}_.B5����QR�/�6XZA�l��p�h�o�X,.����̓���帰���0Fk#/`��Кփ�\߳},`nʈJHP+H*�4S��&��z��-��4D�6����s�8�� �9/s-�۪�h,�D℔%Ҕ3B�1�Hi�v�Z��7�ph�b)b4�"5� �ݖf|�ŧ0P�����mSM�\ �[_N�#)��!����5zc�+#��vMp�R����3j�2�3���;^PI��X�ga��;���]'� �;۲i�����9C4;���0�k0b����뚷�d���cx��b�4&�!�`�,f�R# 9�g"�Z�,�PjcUK�a�U8i�Eڊ#��2G7�1�A�R������{�l�[����&ɚ��4(� m�-#-�i6��Yb#-�uR%F�@bcá�Z�h�4&��a �BQ(d m�2k!��h�E"+�����\�¦���C]���@�M-4 uK���s��M^�L��D�6D��S*��vB]��4,�6"�vA�����pFÑT�l�i4�Ȃ��@ġ���dd�j��*�m��@��v F r� 126M�P*!�ըУC �\$[+�%0MK�bDfMw��<�׻�> �0!���laE jm)�8a��Y�0�l��5�U�E��$��Ϥ��{X��QEDE�ƽ4xs�7�-�� ��P�Ӵ@ �A�!"0E�*�Qd�x)oN��<�ß�j�P���e��;��EK���D��Ӧ7Y:(4��-*n�0��9O�;`q��jQthھH�Mw��]/��89��I�C5��F��#-�x3b[:�#/*�OwD#)6g��J�e������!���D��BH�UzR����Y�SAEB;4���0��k4A�v�M2p#-*�J�;��2;˕"p�`e"din@�#/Q-���yZE�4ɓ�'k�y��2æ��~Mi]HÀ�'9�������i�]¦�窫[��#��:����=�yY��g-1���ջ�n�c;ؾ��1��"ES�F\x�#�S�՗ *��}vǽ�UK?4@�d7����i��>#/HH�(�T�����#R��Д@�o�r''�QK���*v�Z0b#i`��+|����C"QoS���tCm&6�,I��al�%��#�bB@4��5*�h�#- J4?#/L��1���iHu���TMcwb��KD�a�*vmP�����͑f%Dp4p���������(c���f�i��N�� ���3P��e�'��m��5#)xA��G��؈\hh�J�1 �¼=�#-��G#/ iB#-�<���P��a6 �r��)���x2������g>�h��Q4eU=jbʯ,�_��Y�C\�N|=�Р~���' �ܣ�e�9/958�MH����z��Ѩ�pT��bb>.%����Ɯ.����D�;#)�#):�Ba9Ђ�`��1�n�k�$ D�¹���K������o�g��kLY�~�1��^H`1����-��(��0�(Q�3v^;��2�2�(=�}˲Q�M��Xk_��ݭE%�kZR�7��M�"��*8", �b,��(� �q�MP0@���ႄH "lz@hO~^���)RL��@=�"hm�ʷw��8����ج�A�0�"�!�����|ã�SUV o�3@�����H#)"��������-1S˕5��ݽp�4^3��`�]�bb�N��s�$xj��l�%8Ai!O�0Ѳ��h�L�$�#/�r��D�E��y��ve��ۓx���KA(�����&��@�*b#�iY'%:��C,�� �5*;1����,-"m��f���?2�wr���=\��a� 1V=����3 �7#-o�]&a#/�F^��|�C�sq��`���m���qK��$#)�.k׆��K�R|�>���E��c���:�*'õ�n����mt��v��A�P��EUjwM� �`���D(��'Ş��&;�`-#/�T���C��C��Z񚷙#/3h��F��TT(b- �e��DT�]W�c�C#)����lo�8�oI�a5��_N4&��=i�����|�PD�}�Q9��#)�M4Aj@�{�#-� {�\��N~��OQ��zF+d��#����"Db) F)�MK-1��)AUlZ�6�ؑEMi������+W�t4k6mu���_c�枸��WVF`l�؍���q<:NsW1�#)�>�47z�:�W?@�;\�ua�&�$� .l�H�=xǗ@�ڥ��@ �T��|.���QN�#/,�糤$��u��>^�,�ݾ�>�}�o�~����R��&�M#)�7�ƛh�mNCM�ԥ����ь;;�$i��L��� 57M'M�HƬ�r�K�DM��U��K����Z,pu�$nI22�n���<�vq��p��`@�H)4$�.#-Kl�E����W!$&��F�4�bs�YL#r�Ae��Kh�Yr8hM �#-�ױ�ꊜC�2!�8[�+P|FS+"�9��o�V�0X��Xpm/���Y��c"�hY�������C���;�\,����â��������Y �&G�$��Q���:t��sb]2�*'0�'�@����G5A*����t������ lT�dZa�z��g�)�)��~~�o�(b �#-(��C)@�R�]�>[o��V��F]�Ϻ��GB���nfr��KYL���~s�(���}^��f�"F�of /p�� ��������J���֍�p6�}SP!��Ǿ�͚�롣���5�򊇐7�b�H9�ȠP.�^tl�:�u�� H�$2c2<]F�F�$�����e};�>���U��z�y����Cd�)��(ļ����^E�ch�x��[�c��ż�� fP4�J��;UOڑM�@P�e�o��<��� @I���b�T�Q�7�b {��h��#/������ifJ�ͫ�~��o�����4���MFت6��+k�j��J^��ޛzjQ#)-3�a)ki��\]O"#a�$��H�N��A@�CeQL����-f�Q�l��c+�E�������kT(@�'e(�^#/4{rM���I�Ӽ�����ó"I⯈A6l!FOx�O?�ژ�s*kr���!f!�Ƀxv��,!��8�g:���I��*z3{����{�,E� ����|������4��T#/6�X�R �n�!ǻ��IK�8N�M�?N@4��S�{ը#/ �D(JsMZ#/$H�B *��Z�ړJMR�v��W���歶m&㔀��J��\/*S�R��m��/v�]~ӏuQ>�{<3��#-Y�tj� ��r�fn&ye���F5��и�� ���#)Z?�������v~����/��?�����[���������?壳O���?��������������w�����?����?���������_����ۄz?������ڿ���O���P�*��X��?˙����"��O0�lS ̫���|��yp��\��)��E��X�&�?��{�Ea����T����$�$�Ϧ���V�#-Wu\J#�{�՞�HAvi�C\y����b"6��l��{�e�����rd:n(.k��A�܀{?����e=�8�+�H1 �@Z�wf�xŏ`��G�(JU��h$�SgNt?���؈OU��7����K�=>=�#.��_��ѹhPQ`�X�Be :���v��Θ�ڳr�������ݞ.ɫK�.؍a���ܭ����� {R���o�dkۺ�1��٠��- :�� a����4h�S*�{F���~ZX4�C��k���Fvj��ٻ��VV�M ,��r���͙M�Gj#-[v�ZtGI�mƶ9T�����,���v�I��g�=�ͅ��H0Ha3Z��W�W��Zsx�l��: ��;�n� ��7��!��N�솃/�>�&kM�N˖(W3�$�$b1k��ؼ�@ˍ#)h���B#-�����xe:��սkȠ�]��u�i�64k��)�#/f��<�f����w���`'w�� ��č@���u��,v��j�+�%�'DPR#�$pB����%�)!��*�x��=�ٿ�p� k�ƕݘI3���������?�d���@���HII#)�) T/�w>�|7l3#)9�BFA6nwˆ�14���D�Y"���%�aCD#)�# C.�'�C�5ʊ�g�����LK3�/���\�� ��m�}�߶@X�D D�'V�T7�]o?/�’�ni5m)��q5����ҙ��j6�Tfi"b‚FqJ yЉ�#)����}�!����� x�7E[��)hȼ&�ĻR�"�>@p�sO�D�!�[�w3�R����tC�����Mʪb1E����í'_�8�᭺&��g�����>��8d������Cl�Fgot�g,r.;@}r�����#/�o���p !P�Ayt�韈q~���d�:sL����X@�Þ4��pL�a>�,5�Ez�«绵��pm�44~�/q��{.���m\Ђ�I�M�7e�x�$߁�cb��m���W����W�սM�,��#)�0� R�[�/7`��p �A�Ò܊1!�I#-#-!�@���῕�9I�̝B���za��X$26E�߸�g�f�Nu��##=�-ƒ��z��O�_�#/�h6I@$f��R�������ztz#�_wP�}E�rP�ѱA��,X�nw#���$�J�FP�bQ��!� �X�"\؀���H #/9 ���|�=`�?j�!xt�@�O)G��2˨�m�-�8�@����u`���9b ������b���{�D��>��N� gA�����X��7 ^[ c~�qQ-y[Na ��x�����(�w�.�[�̖)���k��y��l���B�t����W�P��AK#/��#IB��t��u?��zǼ\!�������w$S� #/^��p +#<== +#-----BEGIN PGP SIGNATURE-----\n\niQIzBAABCgAdFiEEivIt5aBoIuNHTzxwSbTGfAUneqoFAl0q7gwACgkQSbTGfAUn\neqqqtQ/8Dcj08eNGla/JnosmW3PPuCVlA7mYOPBCmdyW3qhmB4/HNniLgprucwMm\nVkkqPzGkTbRXGliDAK3HDFlZsgjcse5PU5/E75bmBAkTMw11YMemAb1E+Z3xbgZR\n2AlfGM6GkQJN5Svfr70LX2nV2S0+Ck+3h6DqPMmBb65Poshes5LvTKPKM2D2CXqs\ngZwDFM3w4b5OXgqeum8On4cM3fxwzJxhw5NBX2Po26t/P7tAxEy+soP3exbtMOtT\nEK6QC08nxLshTKNkVPcgsRnt0lDSYKVeGvSAjMnYrHdCIIGpdiucmWaz1rCZL5He\nB/mcGy+eFbaYZhP4OP5RgizvH+tVqrgPZhRhfuJcU6b4WmmHcowfM+kbxYcptedz\nUM3BTh5WmVUJ08WI2fNyMS1PlufCYpbb/ItO49EsVceoaMfWCW1P0+tN+ZnQmojn\n7wQ+9CQOpP7CI1b8GEabygmef7RkeFMfeGKSA5ptLE5oLwtwVm63pronC/ebg5QQ\nUYWRtpUDZ2oSibyN5Mq5We+9/n0NMEajkPfO1raaFVffYf/zd+q7LN/NK/jwrhSE\nDYGmaTauyVpLW1lkUn1dD1cQJm85GaeSGsq+dyGfSsWdDhkjmKafS16S/DdmozUM\nWL1vkFRMgDPRPzGjh8Bze+bepSvrqOJBErz/ZZNnYQ9SwAV46k0=\n=sEkX\n-----END PGP SIGNATURE-----\n diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py new file mode 100755 index 0000000..5270763 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py @@ -0,0 +1,804 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,sys,errno,re,shutil,stat +try: + import cPickle +except ImportError: + import pickle as cPickle +from waflib import Node,Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors +CACHE_DIR='c4che' +CACHE_SUFFIX='_cache.py' +INSTALL=1337 +UNINSTALL=-1337 +SAVED_ATTRS='root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() +CFG_FILES='cfg_files' +POST_AT_ONCE=0 +POST_LAZY=1 +PROTOCOL=-1 +if sys.platform=='cli': + PROTOCOL=0 +class BuildContext(Context.Context): + '''executes the build''' + cmd='build' + variant='' + def __init__(self,**kw): + super(BuildContext,self).__init__(**kw) + self.is_install=0 + self.top_dir=kw.get('top_dir',Context.top_dir) + self.out_dir=kw.get('out_dir',Context.out_dir) + self.run_dir=kw.get('run_dir',Context.run_dir) + self.launch_dir=Context.launch_dir + self.post_mode=POST_LAZY + self.cache_dir=kw.get('cache_dir') + if not self.cache_dir: + self.cache_dir=os.path.join(self.out_dir,CACHE_DIR) + self.all_envs={} + self.node_sigs={} + self.task_sigs={} + self.imp_sigs={} + self.node_deps={} + self.raw_deps={} + self.task_gen_cache_names={} + self.jobs=Options.options.jobs + self.targets=Options.options.targets + self.keep=Options.options.keep + self.progress_bar=Options.options.progress_bar + self.deps_man=Utils.defaultdict(list) + self.current_group=0 + self.groups=[] + self.group_names={} + for v in SAVED_ATTRS: + if not hasattr(self,v): + setattr(self,v,{}) + def get_variant_dir(self): + if not self.variant: + return self.out_dir + return os.path.join(self.out_dir,os.path.normpath(self.variant)) + variant_dir=property(get_variant_dir,None) + def __call__(self,*k,**kw): + kw['bld']=self + ret=TaskGen.task_gen(*k,**kw) + self.task_gen_cache_names={} + self.add_to_group(ret,group=kw.get('group')) + return ret + def __copy__(self): + raise Errors.WafError('build contexts cannot be copied') + def load_envs(self): + node=self.root.find_node(self.cache_dir) + if not node: + raise Errors.WafError('The project was not configured: run "waf configure" first!') + lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True) + if not lst: + raise Errors.WafError('The cache directory is empty: reconfigure the project') + for x in lst: + name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/') + env=ConfigSet.ConfigSet(x.abspath()) + self.all_envs[name]=env + for f in env[CFG_FILES]: + newnode=self.root.find_resource(f) + if not newnode or not newnode.exists(): + raise Errors.WafError('Missing configuration file %r, reconfigure the project!'%f) + def init_dirs(self): + if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)): + raise Errors.WafError('The project was not configured: run "waf configure" first!') + self.path=self.srcnode=self.root.find_dir(self.top_dir) + self.bldnode=self.root.make_node(self.variant_dir) + self.bldnode.mkdir() + def execute(self): + self.restore() + if not self.all_envs: + self.load_envs() + self.execute_build() + def execute_build(self): + Logs.info("Waf: Entering directory `%s'",self.variant_dir) + self.recurse([self.run_dir]) + self.pre_build() + self.timer=Utils.Timer() + try: + self.compile() + finally: + if self.progress_bar==1 and sys.stderr.isatty(): + c=self.producer.processed or 1 + m=self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL) + Logs.info(m,extra={'stream':sys.stderr,'c1':Logs.colors.cursor_off,'c2':Logs.colors.cursor_on}) + Logs.info("Waf: Leaving directory `%s'",self.variant_dir) + try: + self.producer.bld=None + del self.producer + except AttributeError: + pass + self.post_build() + def restore(self): + try: + env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py')) + except EnvironmentError: + pass + else: + if env.version').ljust(cols) + msg=Logs.indicator%(left,bar,right) + return msg + def declare_chain(self,*k,**kw): + return TaskGen.declare_chain(*k,**kw) + def pre_build(self): + for m in getattr(self,'pre_funs',[]): + m(self) + def post_build(self): + for m in getattr(self,'post_funs',[]): + m(self) + def add_pre_fun(self,meth): + try: + self.pre_funs.append(meth) + except AttributeError: + self.pre_funs=[meth] + def add_post_fun(self,meth): + try: + self.post_funs.append(meth) + except AttributeError: + self.post_funs=[meth] + def get_group(self,x): + if not self.groups: + self.add_group() + if x is None: + return self.groups[self.current_group] + if x in self.group_names: + return self.group_names[x] + return self.groups[x] + def add_to_group(self,tgen,group=None): + assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.Task)) + tgen.bld=self + self.get_group(group).append(tgen) + def get_group_name(self,g): + if not isinstance(g,list): + g=self.groups[g] + for x in self.group_names: + if id(self.group_names[x])==id(g): + return x + return'' + def get_group_idx(self,tg): + se=id(tg) + for i,tmp in enumerate(self.groups): + for t in tmp: + if id(t)==se: + return i + return None + def add_group(self,name=None,move=True): + if name and name in self.group_names: + raise Errors.WafError('add_group: name %s already present',name) + g=[] + self.group_names[name]=g + self.groups.append(g) + if move: + self.current_group=len(self.groups)-1 + def set_group(self,idx): + if isinstance(idx,str): + g=self.group_names[idx] + for i,tmp in enumerate(self.groups): + if id(g)==id(tmp): + self.current_group=i + break + else: + self.current_group=idx + def total(self): + total=0 + for group in self.groups: + for tg in group: + try: + total+=len(tg.tasks) + except AttributeError: + total+=1 + return total + def get_targets(self): + to_post=[] + min_grp=0 + for name in self.targets.split(','): + tg=self.get_tgen_by_name(name) + m=self.get_group_idx(tg) + if m>min_grp: + min_grp=m + to_post=[tg] + elif m==min_grp: + to_post.append(tg) + return(min_grp,to_post) + def get_all_task_gen(self): + lst=[] + for g in self.groups: + lst.extend(g) + return lst + def post_group(self): + def tgpost(tg): + try: + f=tg.post + except AttributeError: + pass + else: + f() + if self.targets=='*': + for tg in self.groups[self.current_group]: + tgpost(tg) + elif self.targets: + if self.current_groupself.current_group: + for tg in g: + if is_post(tg,ln): + return True + if self.post_mode==POST_LAZY and ln!=self.srcnode: + if is_post_group(): + ln=self.srcnode + for tg in self.groups[self.current_group]: + if is_post(tg,ln): + tgpost(tg) + def get_tasks_group(self,idx): + tasks=[] + for tg in self.groups[idx]: + try: + tasks.extend(tg.tasks) + except AttributeError: + tasks.append(tg) + return tasks + def get_build_iterator(self): + if self.targets and self.targets!='*': + (self._min_grp,self._exact_tg)=self.get_targets() + if self.post_mode!=POST_LAZY: + for self.current_group,_ in enumerate(self.groups): + self.post_group() + for self.current_group,_ in enumerate(self.groups): + if self.post_mode!=POST_AT_ONCE: + self.post_group() + tasks=self.get_tasks_group(self.current_group) + Task.set_file_constraints(tasks) + Task.set_precedence_constraints(tasks) + self.cur_tasks=tasks + if tasks: + yield tasks + while 1: + yield[] + def install_files(self,dest,files,**kw): + assert(dest) + tg=self(features='install_task',install_to=dest,install_from=files,**kw) + tg.dest=tg.install_to + tg.type='install_files' + if not kw.get('postpone',True): + tg.post() + return tg + def install_as(self,dest,srcfile,**kw): + assert(dest) + tg=self(features='install_task',install_to=dest,install_from=srcfile,**kw) + tg.dest=tg.install_to + tg.type='install_as' + if not kw.get('postpone',True): + tg.post() + return tg + def symlink_as(self,dest,src,**kw): + assert(dest) + tg=self(features='install_task',install_to=dest,install_from=src,**kw) + tg.dest=tg.install_to + tg.type='symlink_as' + tg.link=src + if not kw.get('postpone',True): + tg.post() + return tg +@TaskGen.feature('install_task') +@TaskGen.before_method('process_rule','process_source') +def process_install_task(self): + self.add_install_task(**self.__dict__) +@TaskGen.taskgen_method +def add_install_task(self,**kw): + if not self.bld.is_install: + return + if not kw['install_to']: + return + if kw['type']=='symlink_as'and Utils.is_win32: + if kw.get('win32_install'): + kw['type']='install_as' + else: + return + tsk=self.install_task=self.create_task('inst') + tsk.chmod=kw.get('chmod',Utils.O644) + tsk.link=kw.get('link','')or kw.get('install_from','') + tsk.relative_trick=kw.get('relative_trick',False) + tsk.type=kw['type'] + tsk.install_to=tsk.dest=kw['install_to'] + tsk.install_from=kw['install_from'] + tsk.relative_base=kw.get('cwd')or kw.get('relative_base',self.path) + tsk.install_user=kw.get('install_user') + tsk.install_group=kw.get('install_group') + tsk.init_files() + if not kw.get('postpone',True): + tsk.run_now() + return tsk +@TaskGen.taskgen_method +def add_install_files(self,**kw): + kw['type']='install_files' + return self.add_install_task(**kw) +@TaskGen.taskgen_method +def add_install_as(self,**kw): + kw['type']='install_as' + return self.add_install_task(**kw) +@TaskGen.taskgen_method +def add_symlink_as(self,**kw): + kw['type']='symlink_as' + return self.add_install_task(**kw) +class inst(Task.Task): + def __str__(self): + return'' + def uid(self): + lst=self.inputs+self.outputs+[self.link,self.generator.path.abspath()] + return Utils.h_list(lst) + def init_files(self): + if self.type=='symlink_as': + inputs=[] + else: + inputs=self.generator.to_nodes(self.install_from) + if self.type=='install_as': + assert len(inputs)==1 + self.set_inputs(inputs) + dest=self.get_install_path() + outputs=[] + if self.type=='symlink_as': + if self.relative_trick: + self.link=os.path.relpath(self.link,os.path.dirname(dest)) + outputs.append(self.generator.bld.root.make_node(dest)) + elif self.type=='install_as': + outputs.append(self.generator.bld.root.make_node(dest)) + else: + for y in inputs: + if self.relative_trick: + destfile=os.path.join(dest,y.path_from(self.relative_base)) + else: + destfile=os.path.join(dest,y.name) + outputs.append(self.generator.bld.root.make_node(destfile)) + self.set_outputs(outputs) + def runnable_status(self): + ret=super(inst,self).runnable_status() + if ret==Task.SKIP_ME and self.generator.bld.is_install: + return Task.RUN_ME + return ret + def post_run(self): + pass + def get_install_path(self,destdir=True): + if isinstance(self.install_to,Node.Node): + dest=self.install_to.abspath() + else: + dest=os.path.normpath(Utils.subst_vars(self.install_to,self.env)) + if not os.path.isabs(dest): + dest=os.path.join(self.env.PREFIX,dest) + if destdir and Options.options.destdir: + dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep)) + return dest + def copy_fun(self,src,tgt): + if Utils.is_win32 and len(tgt)>259 and not tgt.startswith('\\\\?\\'): + tgt='\\\\?\\'+tgt + shutil.copy2(src,tgt) + self.fix_perms(tgt) + def rm_empty_dirs(self,tgt): + while tgt: + tgt=os.path.dirname(tgt) + try: + os.rmdir(tgt) + except OSError: + break + def run(self): + is_install=self.generator.bld.is_install + if not is_install: + return + for x in self.outputs: + if is_install==INSTALL: + x.parent.mkdir() + if self.type=='symlink_as': + fun=is_install==INSTALL and self.do_link or self.do_unlink + fun(self.link,self.outputs[0].abspath()) + else: + fun=is_install==INSTALL and self.do_install or self.do_uninstall + launch_node=self.generator.bld.launch_node() + for x,y in zip(self.inputs,self.outputs): + fun(x.abspath(),y.abspath(),x.path_from(launch_node)) + def run_now(self): + status=self.runnable_status() + if status not in(Task.RUN_ME,Task.SKIP_ME): + raise Errors.TaskNotReady('Could not process %r: status %r'%(self,status)) + self.run() + self.hasrun=Task.SUCCESS + def do_install(self,src,tgt,lbl,**kw): + if not Options.options.force: + try: + st1=os.stat(tgt) + st2=os.stat(src) + except OSError: + pass + else: + if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size: + if not self.generator.bld.progress_bar: + c1=Logs.colors.NORMAL + c2=Logs.colors.BLUE + Logs.info('%s- install %s%s%s (from %s)',c1,c2,tgt,c1,lbl) + return False + if not self.generator.bld.progress_bar: + c1=Logs.colors.NORMAL + c2=Logs.colors.BLUE + Logs.info('%s+ install %s%s%s (from %s)',c1,c2,tgt,c1,lbl) + try: + os.chmod(tgt,Utils.O644|stat.S_IMODE(os.stat(tgt).st_mode)) + except EnvironmentError: + pass + try: + os.remove(tgt) + except OSError: + pass + try: + self.copy_fun(src,tgt) + except EnvironmentError as e: + if not os.path.exists(src): + Logs.error('File %r does not exist',src) + elif not os.path.isfile(src): + Logs.error('Input %r is not a file',src) + raise Errors.WafError('Could not install the file %r'%tgt,e) + def fix_perms(self,tgt): + if not Utils.is_win32: + user=getattr(self,'install_user',None)or getattr(self.generator,'install_user',None) + group=getattr(self,'install_group',None)or getattr(self.generator,'install_group',None) + if user or group: + Utils.lchown(tgt,user or-1,group or-1) + if not os.path.islink(tgt): + os.chmod(tgt,self.chmod) + def do_link(self,src,tgt,**kw): + if os.path.islink(tgt)and os.readlink(tgt)==src: + if not self.generator.bld.progress_bar: + c1=Logs.colors.NORMAL + c2=Logs.colors.BLUE + Logs.info('%s- symlink %s%s%s (to %s)',c1,c2,tgt,c1,src) + else: + try: + os.remove(tgt) + except OSError: + pass + if not self.generator.bld.progress_bar: + c1=Logs.colors.NORMAL + c2=Logs.colors.BLUE + Logs.info('%s+ symlink %s%s%s (to %s)',c1,c2,tgt,c1,src) + os.symlink(src,tgt) + self.fix_perms(tgt) + def do_uninstall(self,src,tgt,lbl,**kw): + if not self.generator.bld.progress_bar: + c1=Logs.colors.NORMAL + c2=Logs.colors.BLUE + Logs.info('%s- remove %s%s%s',c1,c2,tgt,c1) + try: + os.remove(tgt) + except OSError as e: + if e.errno!=errno.ENOENT: + if not getattr(self,'uninstall_error',None): + self.uninstall_error=True + Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') + if Logs.verbose>1: + Logs.warn('Could not remove %s (error code %r)',e.filename,e.errno) + self.rm_empty_dirs(tgt) + def do_unlink(self,src,tgt,**kw): + try: + if not self.generator.bld.progress_bar: + c1=Logs.colors.NORMAL + c2=Logs.colors.BLUE + Logs.info('%s- remove %s%s%s',c1,c2,tgt,c1) + os.remove(tgt) + except OSError: + pass + self.rm_empty_dirs(tgt) +class InstallContext(BuildContext): + '''installs the targets on the system''' + cmd='install' + def __init__(self,**kw): + super(InstallContext,self).__init__(**kw) + self.is_install=INSTALL +class UninstallContext(InstallContext): + '''removes the targets installed''' + cmd='uninstall' + def __init__(self,**kw): + super(UninstallContext,self).__init__(**kw) + self.is_install=UNINSTALL +class CleanContext(BuildContext): + '''cleans the project''' + cmd='clean' + def execute(self): + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + try: + self.clean() + finally: + self.store() + def clean(self): + Logs.debug('build: clean called') + if hasattr(self,'clean_files'): + for n in self.clean_files: + n.delete() + elif self.bldnode!=self.srcnode: + lst=[] + for env in self.all_envs.values(): + lst.extend(self.root.find_or_declare(f)for f in env[CFG_FILES]) + excluded_dirs='.lock* *conf_check_*/** config.log %s/*'%CACHE_DIR + for n in self.bldnode.ant_glob('**/*',excl=excluded_dirs,quiet=True): + if n in lst: + continue + n.delete() + self.root.children={} + for v in SAVED_ATTRS: + if v=='root': + continue + setattr(self,v,{}) +class ListContext(BuildContext): + '''lists the targets to execute''' + cmd='list' + def execute(self): + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + self.pre_build() + self.timer=Utils.Timer() + for g in self.groups: + for tg in g: + try: + f=tg.post + except AttributeError: + pass + else: + f() + try: + self.get_tgen_by_name('') + except Errors.WafError: + pass + targets=sorted(self.task_gen_cache_names) + line_just=max(len(t)for t in targets)if targets else 0 + for target in targets: + tgen=self.task_gen_cache_names[target] + descript=getattr(tgen,'description','') + if descript: + target=target.ljust(line_just) + descript=': %s'%descript + Logs.pprint('GREEN',target,label=descript) +class StepContext(BuildContext): + '''executes tasks in a step-by-step fashion, for debugging''' + cmd='step' + def __init__(self,**kw): + super(StepContext,self).__init__(**kw) + self.files=Options.options.files + def compile(self): + if not self.files: + Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') + BuildContext.compile(self) + return + targets=[] + if self.targets and self.targets!='*': + targets=self.targets.split(',') + for g in self.groups: + for tg in g: + if targets and tg.name not in targets: + continue + try: + f=tg.post + except AttributeError: + pass + else: + f() + for pat in self.files.split(','): + matcher=self.get_matcher(pat) + for tg in g: + if isinstance(tg,Task.Task): + lst=[tg] + else: + lst=tg.tasks + for tsk in lst: + do_exec=False + for node in tsk.inputs: + if matcher(node,output=False): + do_exec=True + break + for node in tsk.outputs: + if matcher(node,output=True): + do_exec=True + break + if do_exec: + ret=tsk.run() + Logs.info('%s -> exit %r',tsk,ret) + def get_matcher(self,pat): + inn=True + out=True + if pat.startswith('in:'): + out=False + pat=pat.replace('in:','') + elif pat.startswith('out:'): + inn=False + pat=pat.replace('out:','') + anode=self.root.find_node(pat) + pattern=None + if not anode: + if not pat.startswith('^'): + pat='^.+?%s'%pat + if not pat.endswith('$'): + pat='%s$'%pat + pattern=re.compile(pat) + def match(node,output): + if output and not out: + return False + if not output and not inn: + return False + if anode: + return anode==node + else: + return pattern.match(node.abspath()) + return match +class EnvContext(BuildContext): + fun=cmd=None + def execute(self): + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py new file mode 100755 index 0000000..be01a40 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py @@ -0,0 +1,165 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import copy,re,os +from waflib import Logs,Utils +re_imp=re.compile(r'^(#)*?([^#=]*?)\ =\ (.*?)$',re.M) +class ConfigSet(object): + __slots__=('table','parent') + def __init__(self,filename=None): + self.table={} + if filename: + self.load(filename) + def __contains__(self,key): + if key in self.table: + return True + try: + return self.parent.__contains__(key) + except AttributeError: + return False + def keys(self): + keys=set() + cur=self + while cur: + keys.update(cur.table.keys()) + cur=getattr(cur,'parent',None) + keys=list(keys) + keys.sort() + return keys + def __iter__(self): + return iter(self.keys()) + def __str__(self): + return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in self.keys()]) + def __getitem__(self,key): + try: + while 1: + x=self.table.get(key) + if not x is None: + return x + self=self.parent + except AttributeError: + return[] + def __setitem__(self,key,value): + self.table[key]=value + def __delitem__(self,key): + self[key]=[] + def __getattr__(self,name): + if name in self.__slots__: + return object.__getattribute__(self,name) + else: + return self[name] + def __setattr__(self,name,value): + if name in self.__slots__: + object.__setattr__(self,name,value) + else: + self[name]=value + def __delattr__(self,name): + if name in self.__slots__: + object.__delattr__(self,name) + else: + del self[name] + def derive(self): + newenv=ConfigSet() + newenv.parent=self + return newenv + def detach(self): + tbl=self.get_merged_dict() + try: + delattr(self,'parent') + except AttributeError: + pass + else: + keys=tbl.keys() + for x in keys: + tbl[x]=copy.deepcopy(tbl[x]) + self.table=tbl + return self + def get_flat(self,key): + s=self[key] + if isinstance(s,str): + return s + return' '.join(s) + def _get_list_value_for_modification(self,key): + try: + value=self.table[key] + except KeyError: + try: + value=self.parent[key] + except AttributeError: + value=[] + else: + if isinstance(value,list): + value=value[:] + else: + value=[value] + self.table[key]=value + else: + if not isinstance(value,list): + self.table[key]=value=[value] + return value + def append_value(self,var,val): + if isinstance(val,str): + val=[val] + current_value=self._get_list_value_for_modification(var) + current_value.extend(val) + def prepend_value(self,var,val): + if isinstance(val,str): + val=[val] + self.table[var]=val+self._get_list_value_for_modification(var) + def append_unique(self,var,val): + if isinstance(val,str): + val=[val] + current_value=self._get_list_value_for_modification(var) + for x in val: + if x not in current_value: + current_value.append(x) + def get_merged_dict(self): + table_list=[] + env=self + while 1: + table_list.insert(0,env.table) + try: + env=env.parent + except AttributeError: + break + merged_table={} + for table in table_list: + merged_table.update(table) + return merged_table + def store(self,filename): + try: + os.makedirs(os.path.split(filename)[0]) + except OSError: + pass + buf=[] + merged_table=self.get_merged_dict() + keys=list(merged_table.keys()) + keys.sort() + try: + fun=ascii + except NameError: + fun=repr + for k in keys: + if k!='undo_stack': + buf.append('%s = %s\n'%(k,fun(merged_table[k]))) + Utils.writef(filename,''.join(buf)) + def load(self,filename): + tbl=self.table + code=Utils.readf(filename,m='r') + for m in re_imp.finditer(code): + g=m.group + tbl[g(2)]=eval(g(3)) + Logs.debug('env: %s',self.table) + def update(self,d): + self.table.update(d) + def stash(self): + orig=self.table + tbl=self.table=self.table.copy() + for x in tbl.keys(): + tbl[x]=copy.deepcopy(tbl[x]) + self.undo_stack=self.undo_stack+[orig] + def commit(self): + self.undo_stack.pop(-1) + def revert(self): + self.table=self.undo_stack.pop(-1) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py new file mode 100755 index 0000000..7c0afe1 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py @@ -0,0 +1,377 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re,shlex,shutil,sys,time,traceback +from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors +WAF_CONFIG_LOG='config.log' +autoconfig=False +conf_template='''# project %(app)s configured on %(now)s by +# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) +# using %(args)s +#''' +class ConfigurationContext(Context.Context): + '''configures the project''' + cmd='configure' + error_handlers=[] + def __init__(self,**kw): + super(ConfigurationContext,self).__init__(**kw) + self.environ=dict(os.environ) + self.all_envs={} + self.top_dir=None + self.out_dir=None + self.tools=[] + self.hash=0 + self.files=[] + self.tool_cache=[] + self.setenv('') + def setenv(self,name,env=None): + if name not in self.all_envs or env: + if not env: + env=ConfigSet.ConfigSet() + self.prepare_env(env) + else: + env=env.derive() + self.all_envs[name]=env + self.variant=name + def get_env(self): + return self.all_envs[self.variant] + def set_env(self,val): + self.all_envs[self.variant]=val + env=property(get_env,set_env) + def init_dirs(self): + top=self.top_dir + if not top: + top=Options.options.top + if not top: + top=getattr(Context.g_module,Context.TOP,None) + if not top: + top=self.path.abspath() + top=os.path.abspath(top) + self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top) + assert(self.srcnode) + out=self.out_dir + if not out: + out=Options.options.out + if not out: + out=getattr(Context.g_module,Context.OUT,None) + if not out: + out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','') + out=os.path.realpath(out) + self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out) + self.bldnode.mkdir() + if not os.path.isdir(self.bldnode.abspath()): + self.fatal('Could not create the build directory %s'%self.bldnode.abspath()) + def execute(self): + self.init_dirs() + self.cachedir=self.bldnode.make_node(Build.CACHE_DIR) + self.cachedir.mkdir() + path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG) + self.logger=Logs.make_logger(path,'cfg') + app=getattr(Context.g_module,'APPNAME','') + if app: + ver=getattr(Context.g_module,'VERSION','') + if ver: + app="%s (%s)"%(app,ver) + params={'now':time.ctime(),'pyver':sys.hexversion,'systype':sys.platform,'args':" ".join(sys.argv),'wafver':Context.WAFVERSION,'abi':Context.ABI,'app':app} + self.to_log(conf_template%params) + self.msg('Setting top to',self.srcnode.abspath()) + self.msg('Setting out to',self.bldnode.abspath()) + if id(self.srcnode)==id(self.bldnode): + Logs.warn('Setting top == out') + elif id(self.path)!=id(self.srcnode): + if self.srcnode.is_child_of(self.path): + Logs.warn('Are you certain that you do not want to set top="." ?') + super(ConfigurationContext,self).execute() + self.store() + Context.top_dir=self.srcnode.abspath() + Context.out_dir=self.bldnode.abspath() + env=ConfigSet.ConfigSet() + env.argv=sys.argv + env.options=Options.options.__dict__ + env.config_cmd=self.cmd + env.run_dir=Context.run_dir + env.top_dir=Context.top_dir + env.out_dir=Context.out_dir + env.hash=self.hash + env.files=self.files + env.environ=dict(self.environ) + env.launch_dir=Context.launch_dir + if not(self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN')or getattr(Options.options,'no_lock_in_run')): + env.store(os.path.join(Context.run_dir,Options.lockfile)) + if not(self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP')or getattr(Options.options,'no_lock_in_top')): + env.store(os.path.join(Context.top_dir,Options.lockfile)) + if not(self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT')or getattr(Options.options,'no_lock_in_out')): + env.store(os.path.join(Context.out_dir,Options.lockfile)) + def prepare_env(self,env): + if not env.PREFIX: + if Options.options.prefix or Utils.is_win32: + env.PREFIX=Options.options.prefix + else: + env.PREFIX='/' + if not env.BINDIR: + if Options.options.bindir: + env.BINDIR=Options.options.bindir + else: + env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env) + if not env.LIBDIR: + if Options.options.libdir: + env.LIBDIR=Options.options.libdir + else: + env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env) + def store(self): + n=self.cachedir.make_node('build.config.py') + n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools)) + if not self.all_envs: + self.fatal('nothing to store in the configuration context!') + for key in self.all_envs: + tmpenv=self.all_envs[key] + tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX)) + def load(self,tool_list,tooldir=None,funs=None,with_sys_path=True,cache=False): + tools=Utils.to_list(tool_list) + if tooldir: + tooldir=Utils.to_list(tooldir) + for tool in tools: + if cache: + mag=(tool,id(self.env),tooldir,funs) + if mag in self.tool_cache: + self.to_log('(tool %s is already loaded, skipping)'%tool) + continue + self.tool_cache.append(mag) + module=None + try: + module=Context.load_tool(tool,tooldir,ctx=self,with_sys_path=with_sys_path) + except ImportError as e: + self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,getattr(e,'waf_sys_path',sys.path),e)) + except Exception as e: + self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs)) + self.to_log(traceback.format_exc()) + raise + if funs is not None: + self.eval_rules(funs) + else: + func=getattr(module,'configure',None) + if func: + if type(func)is type(Utils.readf): + func(self) + else: + self.eval_rules(func) + self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs}) + def post_recurse(self,node): + super(ConfigurationContext,self).post_recurse(node) + self.hash=Utils.h_list((self.hash,node.read('rb'))) + self.files.append(node.abspath()) + def eval_rules(self,rules): + self.rules=Utils.to_list(rules) + for x in self.rules: + f=getattr(self,x) + if not f: + self.fatal('No such configuration function %r'%x) + f() +def conf(f): + def fun(*k,**kw): + mandatory=kw.pop('mandatory',True) + try: + return f(*k,**kw) + except Errors.ConfigurationError: + if mandatory: + raise + fun.__name__=f.__name__ + setattr(ConfigurationContext,f.__name__,fun) + setattr(Build.BuildContext,f.__name__,fun) + return f +@conf +def add_os_flags(self,var,dest=None,dup=False): + try: + flags=shlex.split(self.environ[var]) + except KeyError: + return + if dup or''.join(flags)not in''.join(Utils.to_list(self.env[dest or var])): + self.env.append_value(dest or var,flags) +@conf +def cmd_to_list(self,cmd): + if isinstance(cmd,str): + if os.path.isfile(cmd): + return[cmd] + if os.sep=='/': + return shlex.split(cmd) + else: + try: + return shlex.split(cmd,posix=False) + except TypeError: + return shlex.split(cmd) + return cmd +@conf +def check_waf_version(self,mini='1.9.99',maxi='2.1.0',**kw): + self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)),**kw) + ver=Context.HEXVERSION + if Utils.num2ver(mini)>ver: + self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver)) + if Utils.num2ver(maxi) %r'%(filename,path_list,var,ret)) + if not ret: + self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename) + interpreter=kw.get('interpreter') + if interpreter is None: + if not Utils.check_exe(ret[0],env=environ): + self.fatal('Program %r is not executable'%ret) + self.env[var]=ret + else: + self.env[var]=self.env[interpreter]+ret + return ret +@conf +def find_binary(self,filenames,exts,paths): + for f in filenames: + for ext in exts: + exe_name=f+ext + if os.path.isabs(exe_name): + if os.path.isfile(exe_name): + return exe_name + else: + for path in paths: + x=os.path.expanduser(os.path.join(path,exe_name)) + if os.path.isfile(x): + return x + return None +@conf +def run_build(self,*k,**kw): + buf=[] + for key in sorted(kw.keys()): + v=kw[key] + if hasattr(v,'__call__'): + buf.append(Utils.h_fun(v)) + else: + buf.append(str(v)) + h=Utils.h_list(buf) + dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h) + cachemode=kw.get('confcache',getattr(Options.options,'confcache',None)) + if not cachemode and os.path.exists(dir): + shutil.rmtree(dir) + try: + os.makedirs(dir) + except OSError: + pass + try: + os.stat(dir) + except OSError: + self.fatal('cannot use the configuration test folder %r'%dir) + if cachemode==1: + try: + proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build')) + except EnvironmentError: + pass + else: + ret=proj['cache_run_build'] + if isinstance(ret,str)and ret.startswith('Test does not build'): + self.fatal(ret) + return ret + bdir=os.path.join(dir,'testbuild') + if not os.path.exists(bdir): + os.makedirs(bdir) + cls_name=kw.get('run_build_cls')or getattr(self,'run_build_cls','build') + self.test_bld=bld=Context.create_context(cls_name,top_dir=dir,out_dir=bdir) + bld.init_dirs() + bld.progress_bar=0 + bld.targets='*' + bld.logger=self.logger + bld.all_envs.update(self.all_envs) + bld.env=kw['env'] + bld.kw=kw + bld.conf=self + kw['build_fun'](bld) + ret=-1 + try: + try: + bld.compile() + except Errors.WafError: + ret='Test does not build: %s'%traceback.format_exc() + self.fatal(ret) + else: + ret=getattr(bld,'retval',0) + finally: + if cachemode: + proj=ConfigSet.ConfigSet() + proj['cache_run_build']=ret + proj.store(os.path.join(dir,'cache_run_build')) + else: + shutil.rmtree(dir) + return ret +@conf +def ret_msg(self,msg,args): + if isinstance(msg,str): + return msg + return msg(args) +@conf +def test(self,*k,**kw): + if not'env'in kw: + kw['env']=self.env.derive() + if kw.get('validate'): + kw['validate'](kw) + self.start_msg(kw['msg'],**kw) + ret=None + try: + ret=self.run_build(*k,**kw) + except self.errors.ConfigurationError: + self.end_msg(kw['errmsg'],'YELLOW',**kw) + if Logs.verbose>1: + raise + else: + self.fatal('The configuration failed') + else: + kw['success']=ret + if kw.get('post_check'): + ret=kw['post_check'](kw) + if ret: + self.end_msg(kw['errmsg'],'YELLOW',**kw) + self.fatal('The configuration failed %r'%ret) + else: + self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) + return ret diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py new file mode 100755 index 0000000..9324fbe --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py @@ -0,0 +1,406 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re,imp,sys +from waflib import Utils,Errors,Logs +import waflib.Node +HEXVERSION=0x2001200 +WAFVERSION="2.0.18" +WAFREVISION="314689b8994259a84f0de0aaef74d7ce91f541ad" +ABI=20 +DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI) +APPNAME='APPNAME' +VERSION='VERSION' +TOP='top' +OUT='out' +WSCRIPT_FILE='wscript' +launch_dir='' +run_dir='' +top_dir='' +out_dir='' +waf_dir='' +default_encoding=Utils.console_encoding() +g_module=None +STDOUT=1 +STDERR=-1 +BOTH=0 +classes=[] +def create_context(cmd_name,*k,**kw): + for x in classes: + if x.cmd==cmd_name: + return x(*k,**kw) + ctx=Context(*k,**kw) + ctx.fun=cmd_name + return ctx +class store_context(type): + def __init__(cls,name,bases,dct): + super(store_context,cls).__init__(name,bases,dct) + name=cls.__name__ + if name in('ctx','Context'): + return + try: + cls.cmd + except AttributeError: + raise Errors.WafError('Missing command for the context class %r (cmd)'%name) + if not getattr(cls,'fun',None): + cls.fun=cls.cmd + classes.insert(0,cls) +ctx=store_context('ctx',(object,),{}) +class Context(ctx): + errors=Errors + tools={} + def __init__(self,**kw): + try: + rd=kw['run_dir'] + except KeyError: + rd=run_dir + self.node_class=type('Nod3',(waflib.Node.Node,),{}) + self.node_class.__module__='waflib.Node' + self.node_class.ctx=self + self.root=self.node_class('',None) + self.cur_script=None + self.path=self.root.find_dir(rd) + self.stack_path=[] + self.exec_dict={'ctx':self,'conf':self,'bld':self,'opt':self} + self.logger=None + def finalize(self): + try: + logger=self.logger + except AttributeError: + pass + else: + Logs.free_logger(logger) + delattr(self,'logger') + def load(self,tool_list,*k,**kw): + tools=Utils.to_list(tool_list) + path=Utils.to_list(kw.get('tooldir','')) + with_sys_path=kw.get('with_sys_path',True) + for t in tools: + module=load_tool(t,path,with_sys_path=with_sys_path) + fun=getattr(module,kw.get('name',self.fun),None) + if fun: + fun(self) + def execute(self): + self.recurse([os.path.dirname(g_module.root_path)]) + def pre_recurse(self,node): + self.stack_path.append(self.cur_script) + self.cur_script=node + self.path=node.parent + def post_recurse(self,node): + self.cur_script=self.stack_path.pop() + if self.cur_script: + self.path=self.cur_script.parent + def recurse(self,dirs,name=None,mandatory=True,once=True,encoding=None): + try: + cache=self.recurse_cache + except AttributeError: + cache=self.recurse_cache={} + for d in Utils.to_list(dirs): + if not os.path.isabs(d): + d=os.path.join(self.path.abspath(),d) + WSCRIPT=os.path.join(d,WSCRIPT_FILE) + WSCRIPT_FUN=WSCRIPT+'_'+(name or self.fun) + node=self.root.find_node(WSCRIPT_FUN) + if node and(not once or node not in cache): + cache[node]=True + self.pre_recurse(node) + try: + function_code=node.read('r',encoding) + exec(compile(function_code,node.abspath(),'exec'),self.exec_dict) + finally: + self.post_recurse(node) + elif not node: + node=self.root.find_node(WSCRIPT) + tup=(node,name or self.fun) + if node and(not once or tup not in cache): + cache[tup]=True + self.pre_recurse(node) + try: + wscript_module=load_module(node.abspath(),encoding=encoding) + user_function=getattr(wscript_module,(name or self.fun),None) + if not user_function: + if not mandatory: + continue + raise Errors.WafError('No function %r defined in %s'%(name or self.fun,node.abspath())) + user_function(self) + finally: + self.post_recurse(node) + elif not node: + if not mandatory: + continue + try: + os.listdir(d) + except OSError: + raise Errors.WafError('Cannot read the folder %r'%d) + raise Errors.WafError('No wscript file in directory %s'%d) + def log_command(self,cmd,kw): + if Logs.verbose: + fmt=os.environ.get('WAF_CMD_FORMAT') + if fmt=='string': + if not isinstance(cmd,str): + cmd=Utils.shell_escape(cmd) + Logs.debug('runner: %r',cmd) + Logs.debug('runner_env: kw=%s',kw) + def exec_command(self,cmd,**kw): + subprocess=Utils.subprocess + kw['shell']=isinstance(cmd,str) + self.log_command(cmd,kw) + if self.logger: + self.logger.info(cmd) + if'stdout'not in kw: + kw['stdout']=subprocess.PIPE + if'stderr'not in kw: + kw['stderr']=subprocess.PIPE + if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]): + raise Errors.WafError('Program %s not found!'%cmd[0]) + cargs={} + if'timeout'in kw: + if sys.hexversion>=0x3030000: + cargs['timeout']=kw['timeout'] + if not'start_new_session'in kw: + kw['start_new_session']=True + del kw['timeout'] + if'input'in kw: + if kw['input']: + cargs['input']=kw['input'] + kw['stdin']=subprocess.PIPE + del kw['input'] + if'cwd'in kw: + if not isinstance(kw['cwd'],str): + kw['cwd']=kw['cwd'].abspath() + encoding=kw.pop('decode_as',default_encoding) + try: + ret,out,err=Utils.run_process(cmd,kw,cargs) + except Exception as e: + raise Errors.WafError('Execution failure: %s'%str(e),ex=e) + if out: + if not isinstance(out,str): + out=out.decode(encoding,errors='replace') + if self.logger: + self.logger.debug('out: %s',out) + else: + Logs.info(out,extra={'stream':sys.stdout,'c1':''}) + if err: + if not isinstance(err,str): + err=err.decode(encoding,errors='replace') + if self.logger: + self.logger.error('err: %s'%err) + else: + Logs.info(err,extra={'stream':sys.stderr,'c1':''}) + return ret + def cmd_and_log(self,cmd,**kw): + subprocess=Utils.subprocess + kw['shell']=isinstance(cmd,str) + self.log_command(cmd,kw) + quiet=kw.pop('quiet',None) + to_ret=kw.pop('output',STDOUT) + if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]): + raise Errors.WafError('Program %r not found!'%cmd[0]) + kw['stdout']=kw['stderr']=subprocess.PIPE + if quiet is None: + self.to_log(cmd) + cargs={} + if'timeout'in kw: + if sys.hexversion>=0x3030000: + cargs['timeout']=kw['timeout'] + if not'start_new_session'in kw: + kw['start_new_session']=True + del kw['timeout'] + if'input'in kw: + if kw['input']: + cargs['input']=kw['input'] + kw['stdin']=subprocess.PIPE + del kw['input'] + if'cwd'in kw: + if not isinstance(kw['cwd'],str): + kw['cwd']=kw['cwd'].abspath() + encoding=kw.pop('decode_as',default_encoding) + try: + ret,out,err=Utils.run_process(cmd,kw,cargs) + except Exception as e: + raise Errors.WafError('Execution failure: %s'%str(e),ex=e) + if not isinstance(out,str): + out=out.decode(encoding,errors='replace') + if not isinstance(err,str): + err=err.decode(encoding,errors='replace') + if out and quiet!=STDOUT and quiet!=BOTH: + self.to_log('out: %s'%out) + if err and quiet!=STDERR and quiet!=BOTH: + self.to_log('err: %s'%err) + if ret: + e=Errors.WafError('Command %r returned %r'%(cmd,ret)) + e.returncode=ret + e.stderr=err + e.stdout=out + raise e + if to_ret==BOTH: + return(out,err) + elif to_ret==STDERR: + return err + return out + def fatal(self,msg,ex=None): + if self.logger: + self.logger.info('from %s: %s'%(self.path.abspath(),msg)) + try: + logfile=self.logger.handlers[0].baseFilename + except AttributeError: + pass + else: + if os.environ.get('WAF_PRINT_FAILURE_LOG'): + msg='Log from (%s):\n%s\n'%(logfile,Utils.readf(logfile)) + else: + msg='%s\n(complete log in %s)'%(msg,logfile) + raise self.errors.ConfigurationError(msg,ex=ex) + def to_log(self,msg): + if not msg: + return + if self.logger: + self.logger.info(msg) + else: + sys.stderr.write(str(msg)) + sys.stderr.flush() + def msg(self,*k,**kw): + try: + msg=kw['msg'] + except KeyError: + msg=k[0] + self.start_msg(msg,**kw) + try: + result=kw['result'] + except KeyError: + result=k[1] + color=kw.get('color') + if not isinstance(color,str): + color=result and'GREEN'or'YELLOW' + self.end_msg(result,color,**kw) + def start_msg(self,*k,**kw): + if kw.get('quiet'): + return + msg=kw.get('msg')or k[0] + try: + if self.in_msg: + self.in_msg+=1 + return + except AttributeError: + self.in_msg=0 + self.in_msg+=1 + try: + self.line_just=max(self.line_just,len(msg)) + except AttributeError: + self.line_just=max(40,len(msg)) + for x in(self.line_just*'-',msg): + self.to_log(x) + Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='') + def end_msg(self,*k,**kw): + if kw.get('quiet'): + return + self.in_msg-=1 + if self.in_msg: + return + result=kw.get('result')or k[0] + defcolor='GREEN' + if result is True: + msg='ok' + elif not result: + msg='not found' + defcolor='YELLOW' + else: + msg=str(result) + self.to_log(msg) + try: + color=kw['color'] + except KeyError: + if len(k)>1 and k[1]in Logs.colors_lst: + color=k[1] + else: + color=defcolor + Logs.pprint(color,msg) + def load_special_tools(self,var,ban=[]): + if os.path.isdir(waf_dir): + lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var) + for x in lst: + if not x.name in ban: + load_tool(x.name.replace('.py','')) + else: + from zipfile import PyZipFile + waflibs=PyZipFile(waf_dir) + lst=waflibs.namelist() + for x in lst: + if not re.match('waflib/extras/%s'%var.replace('*','.*'),var): + continue + f=os.path.basename(x) + doban=False + for b in ban: + r=b.replace('*','.*') + if re.match(r,f): + doban=True + if not doban: + f=f.replace('.py','') + load_tool(f) +cache_modules={} +def load_module(path,encoding=None): + try: + return cache_modules[path] + except KeyError: + pass + module=imp.new_module(WSCRIPT_FILE) + try: + code=Utils.readf(path,m='r',encoding=encoding) + except EnvironmentError: + raise Errors.WafError('Could not read the file %r'%path) + module_dir=os.path.dirname(path) + sys.path.insert(0,module_dir) + try: + exec(compile(code,path,'exec'),module.__dict__) + finally: + sys.path.remove(module_dir) + cache_modules[path]=module + return module +def load_tool(tool,tooldir=None,ctx=None,with_sys_path=True): + if tool=='java': + tool='javaw' + else: + tool=tool.replace('++','xx') + if not with_sys_path: + back_path=sys.path + sys.path=[] + try: + if tooldir: + assert isinstance(tooldir,list) + sys.path=tooldir+sys.path + try: + __import__(tool) + except ImportError as e: + e.waf_sys_path=list(sys.path) + raise + finally: + for d in tooldir: + sys.path.remove(d) + ret=sys.modules[tool] + Context.tools[tool]=ret + return ret + else: + if not with_sys_path: + sys.path.insert(0,waf_dir) + try: + for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'): + try: + __import__(x%tool) + break + except ImportError: + x=None + else: + __import__(tool) + except ImportError as e: + e.waf_sys_path=list(sys.path) + raise + finally: + if not with_sys_path: + sys.path.remove(waf_dir) + ret=sys.modules[x%tool] + Context.tools[tool]=ret + return ret + finally: + if not with_sys_path: + sys.path+=back_path diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py new file mode 100755 index 0000000..3ef76fc --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py @@ -0,0 +1,39 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import traceback,sys +class WafError(Exception): + def __init__(self,msg='',ex=None): + Exception.__init__(self) + self.msg=msg + assert not isinstance(msg,Exception) + self.stack=[] + if ex: + if not msg: + self.msg=str(ex) + if isinstance(ex,WafError): + self.stack=ex.stack + else: + self.stack=traceback.extract_tb(sys.exc_info()[2]) + self.stack+=traceback.extract_stack()[:-1] + self.verbose_msg=''.join(traceback.format_list(self.stack)) + def __str__(self): + return str(self.msg) +class BuildError(WafError): + def __init__(self,error_tasks=[]): + self.tasks=error_tasks + WafError.__init__(self,self.format_error()) + def format_error(self): + lst=['Build failed'] + for tsk in self.tasks: + txt=tsk.format_error() + if txt: + lst.append(txt) + return'\n'.join(lst) +class ConfigurationError(WafError): + pass +class TaskRescan(WafError): + pass +class TaskNotReady(WafError): + pass diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py new file mode 100755 index 0000000..e23c4de --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py @@ -0,0 +1,206 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re,traceback,sys +from waflib import Utils,ansiterm +if not os.environ.get('NOSYNC',False): + if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__): + sys.stdout=ansiterm.AnsiTerm(sys.stdout) + if sys.stderr.isatty()and id(sys.stderr)==id(sys.__stderr__): + sys.stderr=ansiterm.AnsiTerm(sys.stderr) +import logging +LOG_FORMAT=os.environ.get('WAF_LOG_FORMAT','%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s') +HOUR_FORMAT=os.environ.get('WAF_HOUR_FORMAT','%H:%M:%S') +zones=[] +verbose=0 +colors_lst={'USE':True,'BOLD':'\x1b[01;1m','RED':'\x1b[01;31m','GREEN':'\x1b[32m','YELLOW':'\x1b[33m','PINK':'\x1b[35m','BLUE':'\x1b[01;34m','CYAN':'\x1b[36m','GREY':'\x1b[37m','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',} +indicator='\r\x1b[K%s%s%s' +try: + unicode +except NameError: + unicode=None +def enable_colors(use): + if use==1: + if not(sys.stderr.isatty()or sys.stdout.isatty()): + use=0 + if Utils.is_win32 and os.name!='java': + term=os.environ.get('TERM','') + else: + term=os.environ.get('TERM','dumb') + if term in('dumb','emacs'): + use=0 + if use>=1: + os.environ['TERM']='vt100' + colors_lst['USE']=use +try: + get_term_cols=ansiterm.get_term_cols +except AttributeError: + def get_term_cols(): + return 80 +get_term_cols.__doc__=""" + Returns the console width in characters. + + :return: the number of characters per line + :rtype: int + """ +def get_color(cl): + if colors_lst['USE']: + return colors_lst.get(cl,'') + return'' +class color_dict(object): + def __getattr__(self,a): + return get_color(a) + def __call__(self,a): + return get_color(a) +colors=color_dict() +re_log=re.compile(r'(\w+): (.*)',re.M) +class log_filter(logging.Filter): + def __init__(self,name=''): + logging.Filter.__init__(self,name) + def filter(self,rec): + rec.zone=rec.module + if rec.levelno>=logging.INFO: + return True + m=re_log.match(rec.msg) + if m: + rec.zone=m.group(1) + rec.msg=m.group(2) + if zones: + return getattr(rec,'zone','')in zones or'*'in zones + elif not verbose>2: + return False + return True +class log_handler(logging.StreamHandler): + def emit(self,record): + try: + try: + self.stream=record.stream + except AttributeError: + if record.levelno>=logging.WARNING: + record.stream=self.stream=sys.stderr + else: + record.stream=self.stream=sys.stdout + self.emit_override(record) + self.flush() + except(KeyboardInterrupt,SystemExit): + raise + except: + self.handleError(record) + def emit_override(self,record,**kw): + self.terminator=getattr(record,'terminator','\n') + stream=self.stream + if unicode: + msg=self.formatter.format(record) + fs='%s'+self.terminator + try: + if(isinstance(msg,unicode)and getattr(stream,'encoding',None)): + fs=fs.decode(stream.encoding) + try: + stream.write(fs%msg) + except UnicodeEncodeError: + stream.write((fs%msg).encode(stream.encoding)) + else: + stream.write(fs%msg) + except UnicodeError: + stream.write((fs%msg).encode('utf-8')) + else: + logging.StreamHandler.emit(self,record) +class formatter(logging.Formatter): + def __init__(self): + logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT) + def format(self,rec): + try: + msg=rec.msg.decode('utf-8') + except Exception: + msg=rec.msg + use=colors_lst['USE'] + if(use==1 and rec.stream.isatty())or use==2: + c1=getattr(rec,'c1',None) + if c1 is None: + c1='' + if rec.levelno>=logging.ERROR: + c1=colors.RED + elif rec.levelno>=logging.WARNING: + c1=colors.YELLOW + elif rec.levelno>=logging.INFO: + c1=colors.GREEN + c2=getattr(rec,'c2',colors.NORMAL) + msg='%s%s%s'%(c1,msg,c2) + else: + msg=re.sub(r'\r(?!\n)|\x1B\[(K|.*?(m|h|l))','',msg) + if rec.levelno>=logging.INFO: + if rec.args: + try: + return msg%rec.args + except UnicodeDecodeError: + return msg.encode('utf-8')%rec.args + return msg + rec.msg=msg + rec.c1=colors.PINK + rec.c2=colors.NORMAL + return logging.Formatter.format(self,rec) +log=None +def debug(*k,**kw): + if verbose: + k=list(k) + k[0]=k[0].replace('\n',' ') + log.debug(*k,**kw) +def error(*k,**kw): + log.error(*k,**kw) + if verbose>2: + st=traceback.extract_stack() + if st: + st=st[:-1] + buf=[] + for filename,lineno,name,line in st: + buf.append(' File %r, line %d, in %s'%(filename,lineno,name)) + if line: + buf.append(' %s'%line.strip()) + if buf: + log.error('\n'.join(buf)) +def warn(*k,**kw): + log.warning(*k,**kw) +def info(*k,**kw): + log.info(*k,**kw) +def init_log(): + global log + log=logging.getLogger('waflib') + log.handlers=[] + log.filters=[] + hdlr=log_handler() + hdlr.setFormatter(formatter()) + log.addHandler(hdlr) + log.addFilter(log_filter()) + log.setLevel(logging.DEBUG) +def make_logger(path,name): + logger=logging.getLogger(name) + if sys.hexversion>0x3000000: + encoding=sys.stdout.encoding + else: + encoding=None + hdlr=logging.FileHandler(path,'w',encoding=encoding) + formatter=logging.Formatter('%(message)s') + hdlr.setFormatter(formatter) + logger.addHandler(hdlr) + logger.setLevel(logging.DEBUG) + return logger +def make_mem_logger(name,to_log,size=8192): + from logging.handlers import MemoryHandler + logger=logging.getLogger(name) + hdlr=MemoryHandler(size,target=to_log) + formatter=logging.Formatter('%(message)s') + hdlr.setFormatter(formatter) + logger.addHandler(hdlr) + logger.memhandler=hdlr + logger.setLevel(logging.DEBUG) + return logger +def free_logger(logger): + try: + for x in logger.handlers: + x.close() + logger.removeHandler(x) + except Exception: + pass +def pprint(col,msg,label='',sep='\n'): + info('%s%s%s %s',colors(col),msg,colors.NORMAL,label,extra={'terminator':sep}) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py new file mode 100755 index 0000000..4bdc7ec --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py @@ -0,0 +1,477 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re,sys,shutil +from waflib import Utils,Errors +exclude_regs=''' +**/*~ +**/#*# +**/.#* +**/%*% +**/._* +**/*.swp +**/CVS +**/CVS/** +**/.cvsignore +**/SCCS +**/SCCS/** +**/vssver.scc +**/.svn +**/.svn/** +**/BitKeeper +**/.git +**/.git/** +**/.gitignore +**/.bzr +**/.bzrignore +**/.bzr/** +**/.hg +**/.hg/** +**/_MTN +**/_MTN/** +**/.arch-ids +**/{arch} +**/_darcs +**/_darcs/** +**/.intlcache +**/.DS_Store''' +def ant_matcher(s,ignorecase): + reflags=re.I if ignorecase else 0 + ret=[] + for x in Utils.to_list(s): + x=x.replace('\\','/').replace('//','/') + if x.endswith('/'): + x+='**' + accu=[] + for k in x.split('/'): + if k=='**': + accu.append(k) + else: + k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+') + k='^%s$'%k + try: + exp=re.compile(k,flags=reflags) + except Exception as e: + raise Errors.WafError('Invalid pattern: %s'%k,e) + else: + accu.append(exp) + ret.append(accu) + return ret +def ant_sub_filter(name,nn): + ret=[] + for lst in nn: + if not lst: + pass + elif lst[0]=='**': + ret.append(lst) + if len(lst)>1: + if lst[1].match(name): + ret.append(lst[2:]) + else: + ret.append([]) + elif lst[0].match(name): + ret.append(lst[1:]) + return ret +def ant_sub_matcher(name,pats): + nacc=ant_sub_filter(name,pats[0]) + nrej=ant_sub_filter(name,pats[1]) + if[]in nrej: + nacc=[] + return[nacc,nrej] +class Node(object): + dict_class=dict + __slots__=('name','parent','children','cache_abspath','cache_isdir') + def __init__(self,name,parent): + self.name=name + self.parent=parent + if parent: + if name in parent.children: + raise Errors.WafError('node %s exists in the parent files %r already'%(name,parent)) + parent.children[name]=self + def __setstate__(self,data): + self.name=data[0] + self.parent=data[1] + if data[2]is not None: + self.children=self.dict_class(data[2]) + def __getstate__(self): + return(self.name,self.parent,getattr(self,'children',None)) + def __str__(self): + return self.abspath() + def __repr__(self): + return self.abspath() + def __copy__(self): + raise Errors.WafError('nodes are not supposed to be copied') + def read(self,flags='r',encoding='latin-1'): + return Utils.readf(self.abspath(),flags,encoding) + def write(self,data,flags='w',encoding='latin-1'): + Utils.writef(self.abspath(),data,flags,encoding) + def read_json(self,convert=True,encoding='utf-8'): + import json + object_pairs_hook=None + if convert and sys.hexversion<0x3000000: + try: + _type=unicode + except NameError: + _type=str + def convert(value): + if isinstance(value,list): + return[convert(element)for element in value] + elif isinstance(value,_type): + return str(value) + else: + return value + def object_pairs(pairs): + return dict((str(pair[0]),convert(pair[1]))for pair in pairs) + object_pairs_hook=object_pairs + return json.loads(self.read(encoding=encoding),object_pairs_hook=object_pairs_hook) + def write_json(self,data,pretty=True): + import json + indent=2 + separators=(',',': ') + sort_keys=pretty + newline=os.linesep + if not pretty: + indent=None + separators=(',',':') + newline='' + output=json.dumps(data,indent=indent,separators=separators,sort_keys=sort_keys)+newline + self.write(output,encoding='utf-8') + def exists(self): + return os.path.exists(self.abspath()) + def isdir(self): + return os.path.isdir(self.abspath()) + def chmod(self,val): + os.chmod(self.abspath(),val) + def delete(self,evict=True): + try: + try: + if os.path.isdir(self.abspath()): + shutil.rmtree(self.abspath()) + else: + os.remove(self.abspath()) + except OSError: + if os.path.exists(self.abspath()): + raise + finally: + if evict: + self.evict() + def evict(self): + del self.parent.children[self.name] + def suffix(self): + k=max(0,self.name.rfind('.')) + return self.name[k:] + def height(self): + d=self + val=-1 + while d: + d=d.parent + val+=1 + return val + def listdir(self): + lst=Utils.listdir(self.abspath()) + lst.sort() + return lst + def mkdir(self): + if self.isdir(): + return + try: + self.parent.mkdir() + except OSError: + pass + if self.name: + try: + os.makedirs(self.abspath()) + except OSError: + pass + if not self.isdir(): + raise Errors.WafError('Could not create the directory %r'%self) + try: + self.children + except AttributeError: + self.children=self.dict_class() + def find_node(self,lst): + if isinstance(lst,str): + lst=[x for x in Utils.split_path(lst)if x and x!='.'] + if lst and lst[0].startswith('\\\\')and not self.parent: + node=self.ctx.root.make_node(lst[0]) + node.cache_isdir=True + return node.find_node(lst[1:]) + cur=self + for x in lst: + if x=='..': + cur=cur.parent or cur + continue + try: + ch=cur.children + except AttributeError: + cur.children=self.dict_class() + else: + try: + cur=ch[x] + continue + except KeyError: + pass + cur=self.__class__(x,cur) + if not cur.exists(): + cur.evict() + return None + if not cur.exists(): + cur.evict() + return None + return cur + def make_node(self,lst): + if isinstance(lst,str): + lst=[x for x in Utils.split_path(lst)if x and x!='.'] + cur=self + for x in lst: + if x=='..': + cur=cur.parent or cur + continue + try: + cur=cur.children[x] + except AttributeError: + cur.children=self.dict_class() + except KeyError: + pass + else: + continue + cur=self.__class__(x,cur) + return cur + def search_node(self,lst): + if isinstance(lst,str): + lst=[x for x in Utils.split_path(lst)if x and x!='.'] + cur=self + for x in lst: + if x=='..': + cur=cur.parent or cur + else: + try: + cur=cur.children[x] + except(AttributeError,KeyError): + return None + return cur + def path_from(self,node): + c1=self + c2=node + c1h=c1.height() + c2h=c2.height() + lst=[] + up=0 + while c1h>c2h: + lst.append(c1.name) + c1=c1.parent + c1h-=1 + while c2h>c1h: + up+=1 + c2=c2.parent + c2h-=1 + while not c1 is c2: + lst.append(c1.name) + up+=1 + c1=c1.parent + c2=c2.parent + if c1.parent: + lst.extend(['..']*up) + lst.reverse() + return os.sep.join(lst)or'.' + else: + return self.abspath() + def abspath(self): + try: + return self.cache_abspath + except AttributeError: + pass + if not self.parent: + val=os.sep + elif not self.parent.name: + val=os.sep+self.name + else: + val=self.parent.abspath()+os.sep+self.name + self.cache_abspath=val + return val + if Utils.is_win32: + def abspath(self): + try: + return self.cache_abspath + except AttributeError: + pass + if not self.parent: + val='' + elif not self.parent.name: + val=self.name+os.sep + else: + val=self.parent.abspath().rstrip(os.sep)+os.sep+self.name + self.cache_abspath=val + return val + def is_child_of(self,node): + p=self + diff=self.height()-node.height() + while diff>0: + diff-=1 + p=p.parent + return p is node + def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False): + dircont=self.listdir() + try: + lst=set(self.children.keys()) + except AttributeError: + self.children=self.dict_class() + else: + if remove: + for x in lst-set(dircont): + self.children[x].evict() + for name in dircont: + npats=accept(name,pats) + if npats and npats[0]: + accepted=[]in npats[0] + node=self.make_node([name]) + isdir=node.isdir() + if accepted: + if isdir: + if dir: + yield node + elif src: + yield node + if isdir: + node.cache_isdir=True + if maxdepth: + for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove,quiet=quiet): + yield k + def ant_glob(self,*k,**kw): + src=kw.get('src',True) + dir=kw.get('dir') + excl=kw.get('excl',exclude_regs) + incl=k and k[0]or kw.get('incl','**') + remove=kw.get('remove',True) + maxdepth=kw.get('maxdepth',25) + ignorecase=kw.get('ignorecase',False) + quiet=kw.get('quiet',False) + pats=(ant_matcher(incl,ignorecase),ant_matcher(excl,ignorecase)) + if kw.get('generator'): + return Utils.lazy_generator(self.ant_iter,(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet)) + it=self.ant_iter(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet) + if kw.get('flat'): + return' '.join(x.path_from(self)for x in it) + return list(it) + def is_src(self): + cur=self + x=self.ctx.srcnode + y=self.ctx.bldnode + while cur.parent: + if cur is y: + return False + if cur is x: + return True + cur=cur.parent + return False + def is_bld(self): + cur=self + y=self.ctx.bldnode + while cur.parent: + if cur is y: + return True + cur=cur.parent + return False + def get_src(self): + cur=self + x=self.ctx.srcnode + y=self.ctx.bldnode + lst=[] + while cur.parent: + if cur is y: + lst.reverse() + return x.make_node(lst) + if cur is x: + return self + lst.append(cur.name) + cur=cur.parent + return self + def get_bld(self): + cur=self + x=self.ctx.srcnode + y=self.ctx.bldnode + lst=[] + while cur.parent: + if cur is y: + return self + if cur is x: + lst.reverse() + return self.ctx.bldnode.make_node(lst) + lst.append(cur.name) + cur=cur.parent + lst.reverse() + if lst and Utils.is_win32 and len(lst[0])==2 and lst[0].endswith(':'): + lst[0]=lst[0][0] + return self.ctx.bldnode.make_node(['__root__']+lst) + def find_resource(self,lst): + if isinstance(lst,str): + lst=[x for x in Utils.split_path(lst)if x and x!='.'] + node=self.get_bld().search_node(lst) + if not node: + node=self.get_src().find_node(lst) + if node and node.isdir(): + return None + return node + def find_or_declare(self,lst): + if isinstance(lst,str)and os.path.isabs(lst): + node=self.ctx.root.make_node(lst) + else: + node=self.get_bld().make_node(lst) + node.parent.mkdir() + return node + def find_dir(self,lst): + if isinstance(lst,str): + lst=[x for x in Utils.split_path(lst)if x and x!='.'] + node=self.find_node(lst) + if node and not node.isdir(): + return None + return node + def change_ext(self,ext,ext_in=None): + name=self.name + if ext_in is None: + k=name.rfind('.') + if k>=0: + name=name[:k]+ext + else: + name=name+ext + else: + name=name[:-len(ext_in)]+ext + return self.parent.find_or_declare([name]) + def bldpath(self): + return self.path_from(self.ctx.bldnode) + def srcpath(self): + return self.path_from(self.ctx.srcnode) + def relpath(self): + cur=self + x=self.ctx.bldnode + while cur.parent: + if cur is x: + return self.bldpath() + cur=cur.parent + return self.srcpath() + def bld_dir(self): + return self.parent.bldpath() + def h_file(self): + return Utils.h_file(self.abspath()) + def get_bld_sig(self): + try: + cache=self.ctx.cache_sig + except AttributeError: + cache=self.ctx.cache_sig={} + try: + ret=cache[self] + except KeyError: + p=self.abspath() + try: + ret=cache[self]=self.h_file() + except EnvironmentError: + if self.isdir(): + st=os.stat(p) + ret=cache[self]=Utils.h_list([p,st.st_ino,st.st_mode]) + return ret + raise + return ret +pickle_lock=Utils.threading.Lock() +class Nod3(Node): + pass diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py new file mode 100755 index 0000000..b61c60a --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py @@ -0,0 +1,200 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,tempfile,optparse,sys,re +from waflib import Logs,Utils,Context,Errors +options=optparse.Values() +commands=[] +envvars=[] +lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform) +class opt_parser(optparse.OptionParser): + def __init__(self,ctx,allow_unknown=False): + optparse.OptionParser.__init__(self,conflict_handler='resolve',add_help_option=False,version='waf %s (%s)'%(Context.WAFVERSION,Context.WAFREVISION)) + self.formatter.width=Logs.get_term_cols() + self.ctx=ctx + self.allow_unknown=allow_unknown + def _process_args(self,largs,rargs,values): + while rargs: + try: + optparse.OptionParser._process_args(self,largs,rargs,values) + except(optparse.BadOptionError,optparse.AmbiguousOptionError)as e: + if self.allow_unknown: + largs.append(e.opt_str) + else: + self.error(str(e)) + def print_usage(self,file=None): + return self.print_help(file) + def get_usage(self): + cmds_str={} + for cls in Context.classes: + if not cls.cmd or cls.cmd=='options'or cls.cmd.startswith('_'): + continue + s=cls.__doc__ or'' + cmds_str[cls.cmd]=s + if Context.g_module: + for(k,v)in Context.g_module.__dict__.items(): + if k in('options','init','shutdown'): + continue + if type(v)is type(Context.create_context): + if v.__doc__ and not k.startswith('_'): + cmds_str[k]=v.__doc__ + just=0 + for k in cmds_str: + just=max(just,len(k)) + lst=[' %s: %s'%(k.ljust(just),v)for(k,v)in cmds_str.items()] + lst.sort() + ret='\n'.join(lst) + return'''waf [commands] [options] + +Main commands (example: ./waf build -j4) +%s +'''%ret +class OptionsContext(Context.Context): + cmd='options' + fun='options' + def __init__(self,**kw): + super(OptionsContext,self).__init__(**kw) + self.parser=opt_parser(self) + self.option_groups={} + jobs=self.jobs() + p=self.add_option + color=os.environ.get('NOCOLOR','')and'no'or'auto' + if os.environ.get('CLICOLOR','')=='0': + color='no' + elif os.environ.get('CLICOLOR_FORCE','')=='1': + color='yes' + p('-c','--color',dest='colors',default=color,action='store',help='whether to use colors (yes/no/auto) [default: auto]',choices=('yes','no','auto')) + p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs) + p('-k','--keep',dest='keep',default=0,action='count',help='continue despite errors (-kk to try harder)') + p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]') + p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)') + p('--profile',dest='profile',default=0,action='store_true',help=optparse.SUPPRESS_HELP) + p('--pdb',dest='pdb',default=0,action='store_true',help=optparse.SUPPRESS_HELP) + p('-h','--help',dest='whelp',default=0,action='store_true',help="show this help message and exit") + gr=self.add_option_group('Configuration options') + self.option_groups['configure options']=gr + gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out') + gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top') + gr.add_option('--no-lock-in-run',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_run') + gr.add_option('--no-lock-in-out',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_out') + gr.add_option('--no-lock-in-top',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_top') + default_prefix=getattr(Context.g_module,'default_prefix',os.environ.get('PREFIX')) + if not default_prefix: + if Utils.unversioned_sys_platform()=='win32': + d=tempfile.gettempdir() + default_prefix=d[0].upper()+d[1:] + else: + default_prefix='/usr/local/' + gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix) + gr.add_option('--bindir',dest='bindir',help='bindir') + gr.add_option('--libdir',dest='libdir',help='libdir') + gr=self.add_option_group('Build and installation options') + self.option_groups['build and install options']=gr + gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output') + gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"') + gr=self.add_option_group('Step options') + self.option_groups['step options']=gr + gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"') + default_destdir=os.environ.get('DESTDIR','') + gr=self.add_option_group('Installation and uninstallation options') + self.option_groups['install/uninstall options']=gr + gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir') + gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation') + gr.add_option('--distcheck-args',metavar='ARGS',help='arguments to pass to distcheck',default=None,action='store') + def jobs(self): + count=int(os.environ.get('JOBS',0)) + if count<1: + if'NUMBER_OF_PROCESSORS'in os.environ: + count=int(os.environ.get('NUMBER_OF_PROCESSORS',1)) + else: + if hasattr(os,'sysconf_names'): + if'SC_NPROCESSORS_ONLN'in os.sysconf_names: + count=int(os.sysconf('SC_NPROCESSORS_ONLN')) + elif'SC_NPROCESSORS_CONF'in os.sysconf_names: + count=int(os.sysconf('SC_NPROCESSORS_CONF')) + if not count and os.name not in('nt','java'): + try: + tmp=self.cmd_and_log(['sysctl','-n','hw.ncpu'],quiet=0) + except Errors.WafError: + pass + else: + if re.match('^[0-9]+$',tmp): + count=int(tmp) + if count<1: + count=1 + elif count>1024: + count=1024 + return count + def add_option(self,*k,**kw): + return self.parser.add_option(*k,**kw) + def add_option_group(self,*k,**kw): + try: + gr=self.option_groups[k[0]] + except KeyError: + gr=self.parser.add_option_group(*k,**kw) + self.option_groups[k[0]]=gr + return gr + def get_option_group(self,opt_str): + try: + return self.option_groups[opt_str] + except KeyError: + for group in self.parser.option_groups: + if group.title==opt_str: + return group + return None + def sanitize_path(self,path,cwd=None): + if not cwd: + cwd=Context.launch_dir + p=os.path.expanduser(path) + p=os.path.join(cwd,p) + p=os.path.normpath(p) + p=os.path.abspath(p) + return p + def parse_cmd_args(self,_args=None,cwd=None,allow_unknown=False): + self.parser.allow_unknown=allow_unknown + (options,leftover_args)=self.parser.parse_args(args=_args) + envvars=[] + commands=[] + for arg in leftover_args: + if'='in arg: + envvars.append(arg) + elif arg!='options': + commands.append(arg) + for name in'top out destdir prefix bindir libdir'.split(): + if getattr(options,name,None): + path=self.sanitize_path(getattr(options,name),cwd) + setattr(options,name,path) + return options,commands,envvars + def init_module_vars(self,arg_options,arg_commands,arg_envvars): + options.__dict__.clear() + del commands[:] + del envvars[:] + options.__dict__.update(arg_options.__dict__) + commands.extend(arg_commands) + envvars.extend(arg_envvars) + for var in envvars: + (name,value)=var.split('=',1) + os.environ[name.strip()]=value + def init_logs(self,options,commands,envvars): + Logs.verbose=options.verbose + if options.verbose>=1: + self.load('errcheck') + colors={'yes':2,'auto':1,'no':0}[options.colors] + Logs.enable_colors(colors) + if options.zones: + Logs.zones=options.zones.split(',') + if not Logs.verbose: + Logs.verbose=1 + elif Logs.verbose>0: + Logs.zones=['runner'] + if Logs.verbose>2: + Logs.zones=['*'] + def parse_args(self,_args=None): + options,commands,envvars=self.parse_cmd_args() + self.init_logs(options,commands,envvars) + self.init_module_vars(options,commands,envvars) + def execute(self): + super(OptionsContext,self).execute() + self.parse_args() + Utils.alloc_process_pool(options.jobs) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py new file mode 100755 index 0000000..bb0a64c --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py @@ -0,0 +1,375 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import heapq,traceback +try: + from queue import Queue,PriorityQueue +except ImportError: + from Queue import Queue + try: + from Queue import PriorityQueue + except ImportError: + class PriorityQueue(Queue): + def _init(self,maxsize): + self.maxsize=maxsize + self.queue=[] + def _put(self,item): + heapq.heappush(self.queue,item) + def _get(self): + return heapq.heappop(self.queue) +from waflib import Utils,Task,Errors,Logs +GAP=5 +class PriorityTasks(object): + def __init__(self): + self.lst=[] + def __len__(self): + return len(self.lst) + def __iter__(self): + return iter(self.lst) + def __str__(self): + return'PriorityTasks: [%s]'%'\n '.join(str(x)for x in self.lst) + def clear(self): + self.lst=[] + def append(self,task): + heapq.heappush(self.lst,task) + def appendleft(self,task): + heapq.heappush(self.lst,task) + def pop(self): + return heapq.heappop(self.lst) + def extend(self,lst): + if self.lst: + for x in lst: + self.append(x) + else: + if isinstance(lst,list): + self.lst=lst + heapq.heapify(lst) + else: + self.lst=lst.lst +class Consumer(Utils.threading.Thread): + def __init__(self,spawner,task): + Utils.threading.Thread.__init__(self) + self.task=task + self.spawner=spawner + self.setDaemon(1) + self.start() + def run(self): + try: + if not self.spawner.master.stop: + self.spawner.master.process_task(self.task) + finally: + self.spawner.sem.release() + self.spawner.master.out.put(self.task) + self.task=None + self.spawner=None +class Spawner(Utils.threading.Thread): + def __init__(self,master): + Utils.threading.Thread.__init__(self) + self.master=master + self.sem=Utils.threading.Semaphore(master.numjobs) + self.setDaemon(1) + self.start() + def run(self): + try: + self.loop() + except Exception: + pass + def loop(self): + master=self.master + while 1: + task=master.ready.get() + self.sem.acquire() + if not master.stop: + task.log_display(task.generator.bld) + Consumer(self,task) +class Parallel(object): + def __init__(self,bld,j=2): + self.numjobs=j + self.bld=bld + self.outstanding=PriorityTasks() + self.postponed=PriorityTasks() + self.incomplete=set() + self.ready=PriorityQueue(0) + self.out=Queue(0) + self.count=0 + self.processed=0 + self.stop=False + self.error=[] + self.biter=None + self.dirty=False + self.revdeps=Utils.defaultdict(set) + self.spawner=None + if self.numjobs>1: + self.spawner=Spawner(self) + def get_next_task(self): + if not self.outstanding: + return None + return self.outstanding.pop() + def postpone(self,tsk): + self.postponed.append(tsk) + def refill_task_list(self): + while self.count>self.numjobs*GAP: + self.get_out() + while not self.outstanding: + if self.count: + self.get_out() + if self.outstanding: + break + elif self.postponed: + try: + cond=self.deadlock==self.processed + except AttributeError: + pass + else: + if cond: + lst=[] + for tsk in self.postponed: + deps=[id(x)for x in tsk.run_after if not x.hasrun] + lst.append('%s\t-> %r'%(repr(tsk),deps)) + if not deps: + lst.append('\n task %r dependencies are done, check its *runnable_status*?'%id(tsk)) + raise Errors.WafError('Deadlock detected: check the task build order%s'%''.join(lst)) + self.deadlock=self.processed + if self.postponed: + self.outstanding.extend(self.postponed) + self.postponed.clear() + elif not self.count: + if self.incomplete: + for x in self.incomplete: + for k in x.run_after: + if not k.hasrun: + break + else: + self.incomplete.remove(x) + self.outstanding.append(x) + break + else: + if self.stop or self.error: + break + raise Errors.WafError('Broken revdeps detected on %r'%self.incomplete) + else: + tasks=next(self.biter) + ready,waiting=self.prio_and_split(tasks) + self.outstanding.extend(ready) + self.incomplete.update(waiting) + self.total=self.bld.total() + break + def add_more_tasks(self,tsk): + if getattr(tsk,'more_tasks',None): + more=set(tsk.more_tasks) + groups_done=set() + def iteri(a,b): + for x in a: + yield x + for x in b: + yield x + for x in iteri(self.outstanding,self.incomplete): + for k in x.run_after: + if isinstance(k,Task.TaskGroup): + if k not in groups_done: + groups_done.add(k) + for j in k.prev&more: + self.revdeps[j].add(k) + elif k in more: + self.revdeps[k].add(x) + ready,waiting=self.prio_and_split(tsk.more_tasks) + self.outstanding.extend(ready) + self.incomplete.update(waiting) + self.total+=len(tsk.more_tasks) + def mark_finished(self,tsk): + def try_unfreeze(x): + if x in self.incomplete: + for k in x.run_after: + if not k.hasrun: + break + else: + self.incomplete.remove(x) + self.outstanding.append(x) + if tsk in self.revdeps: + for x in self.revdeps[tsk]: + if isinstance(x,Task.TaskGroup): + x.prev.remove(tsk) + if not x.prev: + for k in x.next: + k.run_after.remove(x) + try_unfreeze(k) + x.next=[] + else: + try_unfreeze(x) + del self.revdeps[tsk] + if hasattr(tsk,'semaphore'): + sem=tsk.semaphore + try: + sem.release(tsk) + except KeyError: + pass + else: + while sem.waiting and not sem.is_locked(): + x=sem.waiting.pop() + self._add_task(x) + def get_out(self): + tsk=self.out.get() + if not self.stop: + self.add_more_tasks(tsk) + self.mark_finished(tsk) + self.count-=1 + self.dirty=True + return tsk + def add_task(self,tsk): + self.ready.put(tsk) + def _add_task(self,tsk): + if hasattr(tsk,'semaphore'): + sem=tsk.semaphore + try: + sem.acquire(tsk) + except IndexError: + sem.waiting.add(tsk) + return + self.count+=1 + self.processed+=1 + if self.numjobs==1: + tsk.log_display(tsk.generator.bld) + try: + self.process_task(tsk) + finally: + self.out.put(tsk) + else: + self.add_task(tsk) + def process_task(self,tsk): + tsk.process() + if tsk.hasrun!=Task.SUCCESS: + self.error_handler(tsk) + def skip(self,tsk): + tsk.hasrun=Task.SKIPPED + self.mark_finished(tsk) + def cancel(self,tsk): + tsk.hasrun=Task.CANCELED + self.mark_finished(tsk) + def error_handler(self,tsk): + if not self.bld.keep: + self.stop=True + self.error.append(tsk) + def task_status(self,tsk): + try: + return tsk.runnable_status() + except Exception: + self.processed+=1 + tsk.err_msg=traceback.format_exc() + if not self.stop and self.bld.keep: + self.skip(tsk) + if self.bld.keep==1: + if Logs.verbose>1 or not self.error: + self.error.append(tsk) + self.stop=True + else: + if Logs.verbose>1: + self.error.append(tsk) + return Task.EXCEPTION + tsk.hasrun=Task.EXCEPTION + self.error_handler(tsk) + return Task.EXCEPTION + def start(self): + self.total=self.bld.total() + while not self.stop: + self.refill_task_list() + tsk=self.get_next_task() + if not tsk: + if self.count: + continue + else: + break + if tsk.hasrun: + self.processed+=1 + continue + if self.stop: + break + st=self.task_status(tsk) + if st==Task.RUN_ME: + self._add_task(tsk) + elif st==Task.ASK_LATER: + self.postpone(tsk) + elif st==Task.SKIP_ME: + self.processed+=1 + self.skip(tsk) + self.add_more_tasks(tsk) + elif st==Task.CANCEL_ME: + if Logs.verbose>1: + self.error.append(tsk) + self.processed+=1 + self.cancel(tsk) + while self.error and self.count: + self.get_out() + self.ready.put(None) + if not self.stop: + assert not self.count + assert not self.postponed + assert not self.incomplete + def prio_and_split(self,tasks): + for x in tasks: + x.visited=0 + reverse=self.revdeps + groups_done=set() + for x in tasks: + for k in x.run_after: + if isinstance(k,Task.TaskGroup): + if k not in groups_done: + groups_done.add(k) + for j in k.prev: + reverse[j].add(k) + else: + reverse[k].add(x) + def visit(n): + if isinstance(n,Task.TaskGroup): + return sum(visit(k)for k in n.next) + if n.visited==0: + n.visited=1 + if n in reverse: + rev=reverse[n] + n.prio_order=n.tree_weight+len(rev)+sum(visit(k)for k in rev) + else: + n.prio_order=n.tree_weight + n.visited=2 + elif n.visited==1: + raise Errors.WafError('Dependency cycle found!') + return n.prio_order + for x in tasks: + if x.visited!=0: + continue + try: + visit(x) + except Errors.WafError: + self.debug_cycles(tasks,reverse) + ready=[] + waiting=[] + for x in tasks: + for k in x.run_after: + if not k.hasrun: + waiting.append(x) + break + else: + ready.append(x) + return(ready,waiting) + def debug_cycles(self,tasks,reverse): + tmp={} + for x in tasks: + tmp[x]=0 + def visit(n,acc): + if isinstance(n,Task.TaskGroup): + for k in n.next: + visit(k,acc) + return + if tmp[n]==0: + tmp[n]=1 + for k in reverse.get(n,[]): + visit(k,[n]+acc) + tmp[n]=2 + elif tmp[n]==1: + lst=[] + for tsk in acc: + lst.append(repr(tsk)) + if tsk is n: + break + raise Errors.WafError('Task dependency cycle in "run_after" constraints: %s'%''.join(lst)) + for x in tasks: + visit(x,[]) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py new file mode 100755 index 0000000..dde677b --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py @@ -0,0 +1,415 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from __future__ import with_statement +import os,shlex,shutil,traceback,errno,sys,stat +from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node +build_dir_override=None +no_climb_commands=['configure'] +default_cmd="build" +def waf_entry_point(current_directory,version,wafdir): + Logs.init_log() + if Context.WAFVERSION!=version: + Logs.error('Waf script %r and library %r do not match (directory %r)',version,Context.WAFVERSION,wafdir) + sys.exit(1) + Context.waf_dir=wafdir + Context.run_dir=Context.launch_dir=current_directory + start_dir=current_directory + no_climb=os.environ.get('NOCLIMB') + if len(sys.argv)>1: + potential_wscript=os.path.join(current_directory,sys.argv[1]) + if os.path.basename(potential_wscript)==Context.WSCRIPT_FILE and os.path.isfile(potential_wscript): + path=os.path.normpath(os.path.dirname(potential_wscript)) + start_dir=os.path.abspath(path) + no_climb=True + sys.argv.pop(1) + ctx=Context.create_context('options') + (options,commands,env)=ctx.parse_cmd_args(allow_unknown=True) + if options.top: + start_dir=Context.run_dir=Context.top_dir=options.top + no_climb=True + if options.out: + Context.out_dir=options.out + if not no_climb: + for k in no_climb_commands: + for y in commands: + if y.startswith(k): + no_climb=True + break + cur=start_dir + while cur: + try: + lst=os.listdir(cur) + except OSError: + lst=[] + Logs.error('Directory %r is unreadable!',cur) + if Options.lockfile in lst: + env=ConfigSet.ConfigSet() + try: + env.load(os.path.join(cur,Options.lockfile)) + ino=os.stat(cur)[stat.ST_INO] + except EnvironmentError: + pass + else: + for x in(env.run_dir,env.top_dir,env.out_dir): + if not x: + continue + if Utils.is_win32: + if cur==x: + load=True + break + else: + try: + ino2=os.stat(x)[stat.ST_INO] + except OSError: + pass + else: + if ino==ino2: + load=True + break + else: + Logs.warn('invalid lock file in %s',cur) + load=False + if load: + Context.run_dir=env.run_dir + Context.top_dir=env.top_dir + Context.out_dir=env.out_dir + break + if not Context.run_dir: + if Context.WSCRIPT_FILE in lst: + Context.run_dir=cur + next=os.path.dirname(cur) + if next==cur: + break + cur=next + if no_climb: + break + wscript=os.path.normpath(os.path.join(Context.run_dir,Context.WSCRIPT_FILE)) + if not os.path.exists(wscript): + if options.whelp: + Logs.warn('These are the generic options (no wscript/project found)') + ctx.parser.print_help() + sys.exit(0) + Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)',Context.WSCRIPT_FILE) + sys.exit(1) + try: + os.chdir(Context.run_dir) + except OSError: + Logs.error('Waf: The folder %r is unreadable',Context.run_dir) + sys.exit(1) + try: + set_main_module(wscript) + except Errors.WafError as e: + Logs.pprint('RED',e.verbose_msg) + Logs.error(str(e)) + sys.exit(1) + except Exception as e: + Logs.error('Waf: The wscript in %r is unreadable',Context.run_dir) + traceback.print_exc(file=sys.stdout) + sys.exit(2) + if options.profile: + import cProfile,pstats + cProfile.runctx('from waflib import Scripting; Scripting.run_commands()',{},{},'profi.txt') + p=pstats.Stats('profi.txt') + p.sort_stats('time').print_stats(75) + else: + try: + try: + run_commands() + except: + if options.pdb: + import pdb + type,value,tb=sys.exc_info() + traceback.print_exc() + pdb.post_mortem(tb) + else: + raise + except Errors.WafError as e: + if Logs.verbose>1: + Logs.pprint('RED',e.verbose_msg) + Logs.error(e.msg) + sys.exit(1) + except SystemExit: + raise + except Exception as e: + traceback.print_exc(file=sys.stdout) + sys.exit(2) + except KeyboardInterrupt: + Logs.pprint('RED','Interrupted') + sys.exit(68) +def set_main_module(file_path): + Context.g_module=Context.load_module(file_path) + Context.g_module.root_path=file_path + def set_def(obj): + name=obj.__name__ + if not name in Context.g_module.__dict__: + setattr(Context.g_module,name,obj) + for k in(dist,distclean,distcheck): + set_def(k) + if not'init'in Context.g_module.__dict__: + Context.g_module.init=Utils.nada + if not'shutdown'in Context.g_module.__dict__: + Context.g_module.shutdown=Utils.nada + if not'options'in Context.g_module.__dict__: + Context.g_module.options=Utils.nada +def parse_options(): + ctx=Context.create_context('options') + ctx.execute() + if not Options.commands: + if isinstance(default_cmd,list): + Options.commands.extend(default_cmd) + else: + Options.commands.append(default_cmd) + if Options.options.whelp: + ctx.parser.print_help() + sys.exit(0) +def run_command(cmd_name): + ctx=Context.create_context(cmd_name) + ctx.log_timer=Utils.Timer() + ctx.options=Options.options + ctx.cmd=cmd_name + try: + ctx.execute() + finally: + ctx.finalize() + return ctx +def run_commands(): + parse_options() + run_command('init') + while Options.commands: + cmd_name=Options.commands.pop(0) + ctx=run_command(cmd_name) + Logs.info('%r finished successfully (%s)',cmd_name,ctx.log_timer) + run_command('shutdown') +def distclean_dir(dirname): + for(root,dirs,files)in os.walk(dirname): + for f in files: + if f.endswith(('.o','.moc','.exe')): + fname=os.path.join(root,f) + try: + os.remove(fname) + except OSError: + Logs.warn('Could not remove %r',fname) + for x in(Context.DBFILE,'config.log'): + try: + os.remove(x) + except OSError: + pass + try: + shutil.rmtree(Build.CACHE_DIR) + except OSError: + pass +def distclean(ctx): + '''removes build folders and data''' + def remove_and_log(k,fun): + try: + fun(k) + except EnvironmentError as e: + if e.errno!=errno.ENOENT: + Logs.warn('Could not remove %r',k) + if not Options.commands: + for k in os.listdir('.'): + for x in'.waf-2 waf-2 .waf3-2 waf3-2'.split(): + if k.startswith(x): + remove_and_log(k,shutil.rmtree) + cur='.' + if ctx.options.no_lock_in_top: + cur=ctx.options.out + try: + lst=os.listdir(cur) + except OSError: + Logs.warn('Could not read %r',cur) + return + if Options.lockfile in lst: + f=os.path.join(cur,Options.lockfile) + try: + env=ConfigSet.ConfigSet(f) + except EnvironmentError: + Logs.warn('Could not read %r',f) + return + if not env.out_dir or not env.top_dir: + Logs.warn('Invalid lock file %r',f) + return + if env.out_dir==env.top_dir: + distclean_dir(env.out_dir) + else: + remove_and_log(env.out_dir,shutil.rmtree) + env_dirs=[env.out_dir] + if not ctx.options.no_lock_in_top: + env_dirs.append(env.top_dir) + if not ctx.options.no_lock_in_run: + env_dirs.append(env.run_dir) + for k in env_dirs: + p=os.path.join(k,Options.lockfile) + remove_and_log(p,os.remove) +class Dist(Context.Context): + '''creates an archive containing the project source code''' + cmd='dist' + fun='dist' + algo='tar.bz2' + ext_algo={} + def execute(self): + self.recurse([os.path.dirname(Context.g_module.root_path)]) + self.archive() + def archive(self): + import tarfile + arch_name=self.get_arch_name() + try: + self.base_path + except AttributeError: + self.base_path=self.path + node=self.base_path.make_node(arch_name) + try: + node.delete() + except OSError: + pass + files=self.get_files() + if self.algo.startswith('tar.'): + tar=tarfile.open(node.abspath(),'w:'+self.algo.replace('tar.','')) + for x in files: + self.add_tar_file(x,tar) + tar.close() + elif self.algo=='zip': + import zipfile + zip=zipfile.ZipFile(node.abspath(),'w',compression=zipfile.ZIP_DEFLATED) + for x in files: + archive_name=self.get_base_name()+'/'+x.path_from(self.base_path) + zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED) + zip.close() + else: + self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip') + try: + from hashlib import sha256 + except ImportError: + digest='' + else: + digest=' (sha256=%r)'%sha256(node.read(flags='rb')).hexdigest() + Logs.info('New archive created: %s%s',self.arch_name,digest) + def get_tar_path(self,node): + return node.abspath() + def add_tar_file(self,x,tar): + p=self.get_tar_path(x) + tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path)) + tinfo.uid=0 + tinfo.gid=0 + tinfo.uname='root' + tinfo.gname='root' + if os.path.isfile(p): + with open(p,'rb')as f: + tar.addfile(tinfo,fileobj=f) + else: + tar.addfile(tinfo) + def get_tar_prefix(self): + try: + return self.tar_prefix + except AttributeError: + return self.get_base_name() + def get_arch_name(self): + try: + self.arch_name + except AttributeError: + self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo) + return self.arch_name + def get_base_name(self): + try: + self.base_name + except AttributeError: + appname=getattr(Context.g_module,Context.APPNAME,'noname') + version=getattr(Context.g_module,Context.VERSION,'1.0') + self.base_name=appname+'-'+version + return self.base_name + def get_excl(self): + try: + return self.excl + except AttributeError: + self.excl=Node.exclude_regs+' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' + if Context.out_dir: + nd=self.root.find_node(Context.out_dir) + if nd: + self.excl+=' '+nd.path_from(self.base_path) + return self.excl + def get_files(self): + try: + files=self.files + except AttributeError: + files=self.base_path.ant_glob('**/*',excl=self.get_excl()) + return files +def dist(ctx): + '''makes a tarball for redistributing the sources''' + pass +class DistCheck(Dist): + fun='distcheck' + cmd='distcheck' + def execute(self): + self.recurse([os.path.dirname(Context.g_module.root_path)]) + self.archive() + self.check() + def make_distcheck_cmd(self,tmpdir): + cfg=[] + if Options.options.distcheck_args: + cfg=shlex.split(Options.options.distcheck_args) + else: + cfg=[x for x in sys.argv if x.startswith('-')] + cmd=[sys.executable,sys.argv[0],'configure','build','install','uninstall','--destdir='+tmpdir]+cfg + return cmd + def check(self): + import tempfile,tarfile + with tarfile.open(self.get_arch_name())as t: + for x in t: + t.extract(x) + instdir=tempfile.mkdtemp('.inst',self.get_base_name()) + cmd=self.make_distcheck_cmd(instdir) + ret=Utils.subprocess.Popen(cmd,cwd=self.get_base_name()).wait() + if ret: + raise Errors.WafError('distcheck failed with code %r'%ret) + if os.path.exists(instdir): + raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir) + shutil.rmtree(self.get_base_name()) +def distcheck(ctx): + '''checks if the project compiles (tarball from 'dist')''' + pass +def autoconfigure(execute_method): + def execute(self): + if not Configure.autoconfig: + return execute_method(self) + env=ConfigSet.ConfigSet() + do_config=False + try: + env.load(os.path.join(Context.top_dir,Options.lockfile)) + except EnvironmentError: + Logs.warn('Configuring the project') + do_config=True + else: + if env.run_dir!=Context.run_dir: + do_config=True + else: + h=0 + for f in env.files: + try: + h=Utils.h_list((h,Utils.readf(f,'rb'))) + except EnvironmentError: + do_config=True + break + else: + do_config=h!=env.hash + if do_config: + cmd=env.config_cmd or'configure' + if Configure.autoconfig=='clobber': + tmp=Options.options.__dict__ + launch_dir_tmp=Context.launch_dir + if env.options: + Options.options.__dict__=env.options + Context.launch_dir=env.launch_dir + try: + run_command(cmd) + finally: + Options.options.__dict__=tmp + Context.launch_dir=launch_dir_tmp + else: + run_command(cmd) + run_command(self.cmd) + else: + return execute_method(self) + return execute +Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py new file mode 100755 index 0000000..845a24a --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py @@ -0,0 +1,792 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re,sys,tempfile,traceback +from waflib import Utils,Logs,Errors +NOT_RUN=0 +MISSING=1 +CRASHED=2 +EXCEPTION=3 +CANCELED=4 +SKIPPED=8 +SUCCESS=9 +ASK_LATER=-1 +SKIP_ME=-2 +RUN_ME=-3 +CANCEL_ME=-4 +COMPILE_TEMPLATE_SHELL=''' +def f(tsk): + env = tsk.env + gen = tsk.generator + bld = gen.bld + cwdx = tsk.get_cwd() + p = env.get_flat + def to_list(xx): + if isinstance(xx, str): return [xx] + return xx + tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s + return tsk.exec_command(cmd, cwd=cwdx, env=env.env or None) +''' +COMPILE_TEMPLATE_NOSHELL=''' +def f(tsk): + env = tsk.env + gen = tsk.generator + bld = gen.bld + cwdx = tsk.get_cwd() + def to_list(xx): + if isinstance(xx, str): return [xx] + return xx + def merge(lst1, lst2): + if lst1 and lst2: + return lst1[:-1] + [lst1[-1] + lst2[0]] + lst2[1:] + return lst1 + lst2 + lst = [] + %s + if '' in lst: + lst = [x for x in lst if x] + tsk.last_cmd = lst + return tsk.exec_command(lst, cwd=cwdx, env=env.env or None) +''' +COMPILE_TEMPLATE_SIG_VARS=''' +def f(tsk): + sig = tsk.generator.bld.hash_env_vars(tsk.env, tsk.vars) + tsk.m.update(sig) + env = tsk.env + gen = tsk.generator + bld = gen.bld + cwdx = tsk.get_cwd() + p = env.get_flat + buf = [] + %s + tsk.m.update(repr(buf).encode()) +''' +classes={} +class store_task_type(type): + def __init__(cls,name,bases,dict): + super(store_task_type,cls).__init__(name,bases,dict) + name=cls.__name__ + if name!='evil'and name!='Task': + if getattr(cls,'run_str',None): + (f,dvars)=compile_fun(cls.run_str,cls.shell) + cls.hcode=Utils.h_cmd(cls.run_str) + cls.orig_run_str=cls.run_str + cls.run_str=None + cls.run=f + cls.vars=list(set(cls.vars+dvars)) + cls.vars.sort() + if cls.vars: + fun=compile_sig_vars(cls.vars) + if fun: + cls.sig_vars=fun + elif getattr(cls,'run',None)and not'hcode'in cls.__dict__: + cls.hcode=Utils.h_cmd(cls.run) + getattr(cls,'register',classes)[name]=cls +evil=store_task_type('evil',(object,),{}) +class Task(evil): + vars=[] + always_run=False + shell=False + color='GREEN' + ext_in=[] + ext_out=[] + before=[] + after=[] + hcode=Utils.SIG_NIL + keep_last_cmd=False + weight=0 + tree_weight=0 + prio_order=0 + __slots__=('hasrun','generator','env','inputs','outputs','dep_nodes','run_after') + def __init__(self,*k,**kw): + self.hasrun=NOT_RUN + try: + self.generator=kw['generator'] + except KeyError: + self.generator=self + self.env=kw['env'] + self.inputs=[] + self.outputs=[] + self.dep_nodes=[] + self.run_after=set() + def __lt__(self,other): + return self.priority()>other.priority() + def __le__(self,other): + return self.priority()>=other.priority() + def __gt__(self,other): + return self.priority()8192 + else: + too_long=len(cmd)>200000 + if too_long and getattr(self,'allow_argsfile',True): + cmd,args=self.split_argfile(cmd) + try: + (fd,tmp)=tempfile.mkstemp() + os.write(fd,'\r\n'.join(args).encode()) + os.close(fd) + if Logs.verbose: + Logs.debug('argfile: @%r -> %r',tmp,args) + return self.generator.bld.exec_command(cmd+['@'+tmp],**kw) + finally: + try: + os.remove(tmp) + except OSError: + pass + return self.generator.bld.exec_command(cmd,**kw) + def process(self): + try: + del self.generator.bld.task_sigs[self.uid()] + except KeyError: + pass + try: + ret=self.run() + except Exception: + self.err_msg=traceback.format_exc() + self.hasrun=EXCEPTION + else: + if ret: + self.err_code=ret + self.hasrun=CRASHED + else: + try: + self.post_run() + except Errors.WafError: + pass + except Exception: + self.err_msg=traceback.format_exc() + self.hasrun=EXCEPTION + else: + self.hasrun=SUCCESS + if self.hasrun!=SUCCESS and self.scan: + try: + del self.generator.bld.imp_sigs[self.uid()] + except KeyError: + pass + def log_display(self,bld): + if self.generator.bld.progress_bar==3: + return + s=self.display() + if s: + if bld.logger: + logger=bld.logger + else: + logger=Logs + if self.generator.bld.progress_bar==1: + c1=Logs.colors.cursor_off + c2=Logs.colors.cursor_on + logger.info(s,extra={'stream':sys.stderr,'terminator':'','c1':c1,'c2':c2}) + else: + logger.info(s,extra={'terminator':'','c1':'','c2':''}) + def display(self): + col1=Logs.colors(self.color) + col2=Logs.colors.NORMAL + master=self.generator.bld.producer + def cur(): + return master.processed-master.ready.qsize() + if self.generator.bld.progress_bar==1: + return self.generator.bld.progress_line(cur(),master.total,col1,col2) + if self.generator.bld.progress_bar==2: + ela=str(self.generator.bld.timer) + try: + ins=','.join([n.name for n in self.inputs]) + except AttributeError: + ins='' + try: + outs=','.join([n.name for n in self.outputs]) + except AttributeError: + outs='' + return'|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n'%(master.total,cur(),ins,outs,ela) + s=str(self) + if not s: + return None + total=master.total + n=len(str(total)) + fs='[%%%dd/%%%dd] %%s%%s%%s%%s\n'%(n,n) + kw=self.keyword() + if kw: + kw+=' ' + return fs%(cur(),total,kw,col1,s,col2) + def hash_constraints(self): + return(tuple(self.before),tuple(self.after),tuple(self.ext_in),tuple(self.ext_out),self.__class__.__name__,self.hcode) + def format_error(self): + if Logs.verbose: + msg=': %r\n%r'%(self,getattr(self,'last_cmd','')) + else: + msg=' (run with -v to display more information)' + name=getattr(self.generator,'name','') + if getattr(self,"err_msg",None): + return self.err_msg + elif not self.hasrun: + return'task in %r was not executed for some reason: %r'%(name,self) + elif self.hasrun==CRASHED: + try: + return' -> task in %r failed with exit status %r%s'%(name,self.err_code,msg) + except AttributeError: + return' -> task in %r failed%s'%(name,msg) + elif self.hasrun==MISSING: + return' -> missing files in %r%s'%(name,msg) + elif self.hasrun==CANCELED: + return' -> %r canceled because of missing dependencies'%name + else: + return'invalid status for task in %r: %r'%(name,self.hasrun) + def colon(self,var1,var2): + tmp=self.env[var1] + if not tmp: + return[] + if isinstance(var2,str): + it=self.env[var2] + else: + it=var2 + if isinstance(tmp,str): + return[tmp%x for x in it] + else: + lst=[] + for y in it: + lst.extend(tmp) + lst.append(y) + return lst + def __str__(self): + name=self.__class__.__name__ + if self.outputs: + if name.endswith(('lib','program'))or not self.inputs: + node=self.outputs[0] + return node.path_from(node.ctx.launch_node()) + if not(self.inputs or self.outputs): + return self.__class__.__name__ + if len(self.inputs)==1: + node=self.inputs[0] + return node.path_from(node.ctx.launch_node()) + src_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.inputs]) + tgt_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.outputs]) + if self.outputs: + sep=' -> ' + else: + sep='' + return'%s: %s%s%s'%(self.__class__.__name__,src_str,sep,tgt_str) + def keyword(self): + name=self.__class__.__name__ + if name.endswith(('lib','program')): + return'Linking' + if len(self.inputs)==1 and len(self.outputs)==1: + return'Compiling' + if not self.inputs: + if self.outputs: + return'Creating' + else: + return'Running' + return'Processing' + def __repr__(self): + try: + ins=",".join([x.name for x in self.inputs]) + outs=",".join([x.name for x in self.outputs]) + except AttributeError: + ins=",".join([str(x)for x in self.inputs]) + outs=",".join([str(x)for x in self.outputs]) + return"".join(['\n\t{task %r: '%id(self),self.__class__.__name__," ",ins," -> ",outs,'}']) + def uid(self): + try: + return self.uid_ + except AttributeError: + m=Utils.md5(self.__class__.__name__) + up=m.update + for x in self.inputs+self.outputs: + up(x.abspath()) + self.uid_=m.digest() + return self.uid_ + def set_inputs(self,inp): + if isinstance(inp,list): + self.inputs+=inp + else: + self.inputs.append(inp) + def set_outputs(self,out): + if isinstance(out,list): + self.outputs+=out + else: + self.outputs.append(out) + def set_run_after(self,task): + assert isinstance(task,Task) + self.run_after.add(task) + def signature(self): + try: + return self.cache_sig + except AttributeError: + pass + self.m=Utils.md5(self.hcode) + self.sig_explicit_deps() + self.sig_vars() + if self.scan: + try: + self.sig_implicit_deps() + except Errors.TaskRescan: + return self.signature() + ret=self.cache_sig=self.m.digest() + return ret + def runnable_status(self): + bld=self.generator.bld + if bld.is_install<0: + return SKIP_ME + for t in self.run_after: + if not t.hasrun: + return ASK_LATER + elif t.hasrun0x3000000: + def uid(self): + try: + return self.uid_ + except AttributeError: + m=Utils.md5(self.__class__.__name__.encode('latin-1','xmlcharrefreplace')) + up=m.update + for x in self.inputs+self.outputs: + up(x.abspath().encode('latin-1','xmlcharrefreplace')) + self.uid_=m.digest() + return self.uid_ + uid.__doc__=Task.uid.__doc__ + Task.uid=uid +def is_before(t1,t2): + to_list=Utils.to_list + for k in to_list(t2.ext_in): + if k in to_list(t1.ext_out): + return 1 + if t1.__class__.__name__ in to_list(t2.after): + return 1 + if t2.__class__.__name__ in to_list(t1.before): + return 1 + return 0 +def set_file_constraints(tasks): + ins=Utils.defaultdict(set) + outs=Utils.defaultdict(set) + for x in tasks: + for a in x.inputs: + ins[a].add(x) + for a in x.dep_nodes: + ins[a].add(x) + for a in x.outputs: + outs[a].add(x) + links=set(ins.keys()).intersection(outs.keys()) + for k in links: + for a in ins[k]: + a.run_after.update(outs[k]) +class TaskGroup(object): + def __init__(self,prev,next): + self.prev=prev + self.next=next + self.done=False + def get_hasrun(self): + for k in self.prev: + if not k.hasrun: + return NOT_RUN + return SUCCESS + hasrun=property(get_hasrun,None) +def set_precedence_constraints(tasks): + cstr_groups=Utils.defaultdict(list) + for x in tasks: + h=x.hash_constraints() + cstr_groups[h].append(x) + keys=list(cstr_groups.keys()) + maxi=len(keys) + for i in range(maxi): + t1=cstr_groups[keys[i]][0] + for j in range(i+1,maxi): + t2=cstr_groups[keys[j]][0] + if is_before(t1,t2): + a=i + b=j + elif is_before(t2,t1): + a=j + b=i + else: + continue + a=cstr_groups[keys[a]] + b=cstr_groups[keys[b]] + if len(a)<2 or len(b)<2: + for x in b: + x.run_after.update(a) + else: + group=TaskGroup(set(a),set(b)) + for x in b: + x.run_after.add(group) +def funex(c): + dc={} + exec(c,dc) + return dc['f'] +re_cond=re.compile(r'(?P\w+)|(?P\|)|(?P&)') +re_novar=re.compile(r'^(SRC|TGT)\W+.*?$') +reg_act=re.compile(r'(?P\\)|(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})',re.M) +def compile_fun_shell(line): + extr=[] + def repl(match): + g=match.group + if g('dollar'): + return"$" + elif g('backslash'): + return'\\\\' + elif g('subst'): + extr.append((g('var'),g('code'))) + return"%s" + return None + line=reg_act.sub(repl,line)or line + dvars=[] + def add_dvar(x): + if x not in dvars: + dvars.append(x) + def replc(m): + if m.group('and'): + return' and ' + elif m.group('or'): + return' or ' + else: + x=m.group('var') + add_dvar(x) + return'env[%r]'%x + parm=[] + app=parm.append + for(var,meth)in extr: + if var=='SRC': + if meth: + app('tsk.inputs%s'%meth) + else: + app('" ".join([a.path_from(cwdx) for a in tsk.inputs])') + elif var=='TGT': + if meth: + app('tsk.outputs%s'%meth) + else: + app('" ".join([a.path_from(cwdx) for a in tsk.outputs])') + elif meth: + if meth.startswith(':'): + add_dvar(var) + m=meth[1:] + if m=='SRC': + m='[a.path_from(cwdx) for a in tsk.inputs]' + elif m=='TGT': + m='[a.path_from(cwdx) for a in tsk.outputs]' + elif re_novar.match(m): + m='[tsk.inputs%s]'%m[3:] + elif re_novar.match(m): + m='[tsk.outputs%s]'%m[3:] + else: + add_dvar(m) + if m[:3]not in('tsk','gen','bld'): + m='%r'%m + app('" ".join(tsk.colon(%r, %s))'%(var,m)) + elif meth.startswith('?'): + expr=re_cond.sub(replc,meth[1:]) + app('p(%r) if (%s) else ""'%(var,expr)) + else: + call='%s%s'%(var,meth) + add_dvar(call) + app(call) + else: + add_dvar(var) + app("p('%s')"%var) + if parm: + parm="%% (%s) "%(',\n\t\t'.join(parm)) + else: + parm='' + c=COMPILE_TEMPLATE_SHELL%(line,parm) + Logs.debug('action: %s',c.strip().splitlines()) + return(funex(c),dvars) +reg_act_noshell=re.compile(r"(?P\s+)|(?P\$\{(?P\w+)(?P.*?)\})|(?P([^$ \t\n\r\f\v]|\$\$)+)",re.M) +def compile_fun_noshell(line): + buf=[] + dvars=[] + merge=False + app=buf.append + def add_dvar(x): + if x not in dvars: + dvars.append(x) + def replc(m): + if m.group('and'): + return' and ' + elif m.group('or'): + return' or ' + else: + x=m.group('var') + add_dvar(x) + return'env[%r]'%x + for m in reg_act_noshell.finditer(line): + if m.group('space'): + merge=False + continue + elif m.group('text'): + app('[%r]'%m.group('text').replace('$$','$')) + elif m.group('subst'): + var=m.group('var') + code=m.group('code') + if var=='SRC': + if code: + app('[tsk.inputs%s]'%code) + else: + app('[a.path_from(cwdx) for a in tsk.inputs]') + elif var=='TGT': + if code: + app('[tsk.outputs%s]'%code) + else: + app('[a.path_from(cwdx) for a in tsk.outputs]') + elif code: + if code.startswith(':'): + add_dvar(var) + m=code[1:] + if m=='SRC': + m='[a.path_from(cwdx) for a in tsk.inputs]' + elif m=='TGT': + m='[a.path_from(cwdx) for a in tsk.outputs]' + elif re_novar.match(m): + m='[tsk.inputs%s]'%m[3:] + elif re_novar.match(m): + m='[tsk.outputs%s]'%m[3:] + else: + add_dvar(m) + if m[:3]not in('tsk','gen','bld'): + m='%r'%m + app('tsk.colon(%r, %s)'%(var,m)) + elif code.startswith('?'): + expr=re_cond.sub(replc,code[1:]) + app('to_list(env[%r] if (%s) else [])'%(var,expr)) + else: + call='%s%s'%(var,code) + add_dvar(call) + app('to_list(%s)'%call) + else: + app('to_list(env[%r])'%var) + add_dvar(var) + if merge: + tmp='merge(%s, %s)'%(buf[-2],buf[-1]) + del buf[-1] + buf[-1]=tmp + merge=True + buf=['lst.extend(%s)'%x for x in buf] + fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf) + Logs.debug('action: %s',fun.strip().splitlines()) + return(funex(fun),dvars) +def compile_fun(line,shell=False): + if isinstance(line,str): + if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0: + shell=True + else: + dvars_lst=[] + funs_lst=[] + for x in line: + if isinstance(x,str): + fun,dvars=compile_fun(x,shell) + dvars_lst+=dvars + funs_lst.append(fun) + else: + funs_lst.append(x) + def composed_fun(task): + for x in funs_lst: + ret=x(task) + if ret: + return ret + return None + return composed_fun,dvars_lst + if shell: + return compile_fun_shell(line) + else: + return compile_fun_noshell(line) +def compile_sig_vars(vars): + buf=[] + for x in sorted(vars): + if x[:3]in('tsk','gen','bld'): + buf.append('buf.append(%s)'%x) + if buf: + return funex(COMPILE_TEMPLATE_SIG_VARS%'\n\t'.join(buf)) + return None +def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None): + params={'vars':vars or[],'color':color,'name':name,'shell':shell,'scan':scan,} + if isinstance(func,str)or isinstance(func,tuple): + params['run_str']=func + else: + params['run']=func + cls=type(Task)(name,(Task,),params) + classes[name]=cls + if ext_in: + cls.ext_in=Utils.to_list(ext_in) + if ext_out: + cls.ext_out=Utils.to_list(ext_out) + if before: + cls.before=Utils.to_list(before) + if after: + cls.after=Utils.to_list(after) + return cls +def deep_inputs(cls): + def sig_explicit_deps(self): + Task.sig_explicit_deps(self) + Task.sig_deep_inputs(self) + cls.sig_explicit_deps=sig_explicit_deps + return cls +TaskBase=Task +class TaskSemaphore(object): + def __init__(self,num): + self.num=num + self.locking=set() + self.waiting=set() + def is_locked(self): + return len(self.locking)>=self.num + def acquire(self,tsk): + if self.is_locked(): + raise IndexError('Cannot lock more %r'%self.locking) + self.locking.add(tsk) + def release(self,tsk): + self.locking.remove(tsk) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py new file mode 100755 index 0000000..c5cf6d7 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py @@ -0,0 +1,471 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import copy,re,os,functools +from waflib import Task,Utils,Logs,Errors,ConfigSet,Node +feats=Utils.defaultdict(set) +HEADER_EXTS=['.h','.hpp','.hxx','.hh'] +class task_gen(object): + mappings=Utils.ordered_iter_dict() + prec=Utils.defaultdict(set) + def __init__(self,*k,**kw): + self.source=[] + self.target='' + self.meths=[] + self.features=[] + self.tasks=[] + if not'bld'in kw: + self.env=ConfigSet.ConfigSet() + self.idx=0 + self.path=None + else: + self.bld=kw['bld'] + self.env=self.bld.env.derive() + self.path=kw.get('path',self.bld.path) + path=self.path.abspath() + try: + self.idx=self.bld.idx[path]=self.bld.idx.get(path,0)+1 + except AttributeError: + self.bld.idx={} + self.idx=self.bld.idx[path]=1 + try: + self.tg_idx_count=self.bld.tg_idx_count=self.bld.tg_idx_count+1 + except AttributeError: + self.tg_idx_count=self.bld.tg_idx_count=1 + for key,val in kw.items(): + setattr(self,key,val) + def __str__(self): + return""%(self.name,self.path.abspath()) + def __repr__(self): + lst=[] + for x in self.__dict__: + if x not in('env','bld','compiled_tasks','tasks'): + lst.append("%s=%s"%(x,repr(getattr(self,x)))) + return"bld(%s) in %s"%(", ".join(lst),self.path.abspath()) + def get_cwd(self): + return self.bld.bldnode + def get_name(self): + try: + return self._name + except AttributeError: + if isinstance(self.target,list): + lst=[str(x)for x in self.target] + name=self._name=','.join(lst) + else: + name=self._name=str(self.target) + return name + def set_name(self,name): + self._name=name + name=property(get_name,set_name) + def to_list(self,val): + if isinstance(val,str): + return val.split() + else: + return val + def post(self): + if getattr(self,'posted',None): + return False + self.posted=True + keys=set(self.meths) + keys.update(feats['*']) + self.features=Utils.to_list(self.features) + for x in self.features: + st=feats[x] + if st: + keys.update(st) + elif not x in Task.classes: + Logs.warn('feature %r does not exist - bind at least one method to it?',x) + prec={} + prec_tbl=self.prec + for x in prec_tbl: + if x in keys: + prec[x]=prec_tbl[x] + tmp=[] + for a in keys: + for x in prec.values(): + if a in x: + break + else: + tmp.append(a) + tmp.sort(reverse=True) + out=[] + while tmp: + e=tmp.pop() + if e in keys: + out.append(e) + try: + nlst=prec[e] + except KeyError: + pass + else: + del prec[e] + for x in nlst: + for y in prec: + if x in prec[y]: + break + else: + tmp.append(x) + tmp.sort(reverse=True) + if prec: + buf=['Cycle detected in the method execution:'] + for k,v in prec.items(): + buf.append('- %s after %s'%(k,[x for x in v if x in prec])) + raise Errors.WafError('\n'.join(buf)) + self.meths=out + Logs.debug('task_gen: posting %s %d',self,id(self)) + for x in out: + try: + v=getattr(self,x) + except AttributeError: + raise Errors.WafError('%r is not a valid task generator method'%x) + Logs.debug('task_gen: -> %s (%d)',x,id(self)) + v() + Logs.debug('task_gen: posted %s',self.name) + return True + def get_hook(self,node): + name=node.name + for k in self.mappings: + try: + if name.endswith(k): + return self.mappings[k] + except TypeError: + if k.match(name): + return self.mappings[k] + keys=list(self.mappings.keys()) + raise Errors.WafError("File %r has no mapping in %r (load a waf tool?)"%(node,keys)) + def create_task(self,name,src=None,tgt=None,**kw): + task=Task.classes[name](env=self.env.derive(),generator=self) + if src: + task.set_inputs(src) + if tgt: + task.set_outputs(tgt) + task.__dict__.update(kw) + self.tasks.append(task) + return task + def clone(self,env): + newobj=self.bld() + for x in self.__dict__: + if x in('env','bld'): + continue + elif x in('path','features'): + setattr(newobj,x,getattr(self,x)) + else: + setattr(newobj,x,copy.copy(getattr(self,x))) + newobj.posted=False + if isinstance(env,str): + newobj.env=self.bld.all_envs[env].derive() + else: + newobj.env=env.derive() + return newobj +def declare_chain(name='',rule=None,reentrant=None,color='BLUE',ext_in=[],ext_out=[],before=[],after=[],decider=None,scan=None,install_path=None,shell=False): + ext_in=Utils.to_list(ext_in) + ext_out=Utils.to_list(ext_out) + if not name: + name=rule + cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell) + def x_file(self,node): + if ext_in: + _ext_in=ext_in[0] + tsk=self.create_task(name,node) + cnt=0 + ext=decider(self,node)if decider else cls.ext_out + for x in ext: + k=node.change_ext(x,ext_in=_ext_in) + tsk.outputs.append(k) + if reentrant!=None: + if cnt1: + self.to_log('Command failure: %s'%e) + self.fatal('The configuration failed') + else: + if not ret: + ret=True + kw['success']=ret + if'okmsg'in kw: + self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) + return ret +def build_fun(bld): + if bld.kw['compile_filename']: + node=bld.srcnode.make_node(bld.kw['compile_filename']) + node.write(bld.kw['code']) + o=bld(features=bld.kw['features'],source=bld.kw['compile_filename'],target='testprog') + for k,v in bld.kw.items(): + setattr(o,k,v) + if not bld.kw.get('quiet'): + bld.conf.to_log("==>\n%s\n<=="%bld.kw['code']) +@conf +def validate_c(self,kw): + for x in('type_name','field_name','function_name'): + if x in kw: + Logs.warn('Invalid argument %r in test'%x) + if not'build_fun'in kw: + kw['build_fun']=build_fun + if not'env'in kw: + kw['env']=self.env.derive() + env=kw['env'] + if not'compiler'in kw and not'features'in kw: + kw['compiler']='c' + if env.CXX_NAME and Task.classes.get('cxx'): + kw['compiler']='cxx' + if not self.env.CXX: + self.fatal('a c++ compiler is required') + else: + if not self.env.CC: + self.fatal('a c compiler is required') + if not'compile_mode'in kw: + kw['compile_mode']='c' + if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler')=='cxx': + kw['compile_mode']='cxx' + if not'type'in kw: + kw['type']='cprogram' + if not'features'in kw: + if not'header_name'in kw or kw.get('link_header_test',True): + kw['features']=[kw['compile_mode'],kw['type']] + else: + kw['features']=[kw['compile_mode']] + else: + kw['features']=Utils.to_list(kw['features']) + if not'compile_filename'in kw: + kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'') + def to_header(dct): + if'header_name'in dct: + dct=Utils.to_list(dct['header_name']) + return''.join(['#include <%s>\n'%x for x in dct]) + return'' + if'framework_name'in kw: + fwkname=kw['framework_name'] + if not'uselib_store'in kw: + kw['uselib_store']=fwkname.upper() + if not kw.get('no_header'): + fwk='%s/%s.h'%(fwkname,fwkname) + if kw.get('remove_dot_h'): + fwk=fwk[:-2] + val=kw.get('header_name',[]) + kw['header_name']=Utils.to_list(val)+[fwk] + kw['msg']='Checking for framework %s'%fwkname + kw['framework']=fwkname + elif'header_name'in kw: + if not'msg'in kw: + kw['msg']='Checking for header %s'%kw['header_name'] + l=Utils.to_list(kw['header_name']) + assert len(l),'list of headers in header_name is empty' + kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM + if not'uselib_store'in kw: + kw['uselib_store']=l[0].upper() + if not'define_name'in kw: + kw['define_name']=self.have_define(l[0]) + if'lib'in kw: + if not'msg'in kw: + kw['msg']='Checking for library %s'%kw['lib'] + if not'uselib_store'in kw: + kw['uselib_store']=kw['lib'].upper() + if'stlib'in kw: + if not'msg'in kw: + kw['msg']='Checking for static library %s'%kw['stlib'] + if not'uselib_store'in kw: + kw['uselib_store']=kw['stlib'].upper() + if'fragment'in kw: + kw['code']=kw['fragment'] + if not'msg'in kw: + kw['msg']='Checking for code snippet' + if not'errmsg'in kw: + kw['errmsg']='no' + for(flagsname,flagstype)in(('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')): + if flagsname in kw: + if not'msg'in kw: + kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname]) + if not'errmsg'in kw: + kw['errmsg']='no' + if not'execute'in kw: + kw['execute']=False + if kw['execute']: + kw['features'].append('test_exec') + kw['chmod']=Utils.O755 + if not'errmsg'in kw: + kw['errmsg']='not found' + if not'okmsg'in kw: + kw['okmsg']='yes' + if not'code'in kw: + kw['code']=SNIP_EMPTY_PROGRAM + if self.env[INCKEYS]: + kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code'] + if kw.get('merge_config_header')or env.merge_config_header: + kw['code']='%s\n\n%s'%(self.get_config_header(),kw['code']) + env.DEFINES=[] + if not kw.get('success'): + kw['success']=None + if'define_name'in kw: + self.undefine(kw['define_name']) + if not'msg'in kw: + self.fatal('missing "msg" in conf.check(...)') +@conf +def post_check(self,*k,**kw): + is_success=0 + if kw['execute']: + if kw['success']is not None: + if kw.get('define_ret'): + is_success=kw['success'] + else: + is_success=(kw['success']==0) + else: + is_success=(kw['success']==0) + if kw.get('define_name'): + comment=kw.get('comment','') + define_name=kw['define_name'] + if kw['execute']and kw.get('define_ret')and isinstance(is_success,str): + if kw.get('global_define',1): + self.define(define_name,is_success,quote=kw.get('quote',1),comment=comment) + else: + if kw.get('quote',1): + succ='"%s"'%is_success + else: + succ=int(is_success) + val='%s=%s'%(define_name,succ) + var='DEFINES_%s'%kw['uselib_store'] + self.env.append_value(var,val) + else: + if kw.get('global_define',1): + self.define_cond(define_name,is_success,comment=comment) + else: + var='DEFINES_%s'%kw['uselib_store'] + self.env.append_value(var,'%s=%s'%(define_name,int(is_success))) + if kw.get('add_have_to_env',1): + if kw.get('uselib_store'): + self.env[self.have_define(kw['uselib_store'])]=1 + elif kw['execute']and kw.get('define_ret'): + self.env[define_name]=is_success + else: + self.env[define_name]=int(is_success) + if'header_name'in kw: + if kw.get('auto_add_header_name'): + self.env.append_value(INCKEYS,Utils.to_list(kw['header_name'])) + if is_success and'uselib_store'in kw: + from waflib.Tools import ccroot + _vars=set() + for x in kw['features']: + if x in ccroot.USELIB_VARS: + _vars|=ccroot.USELIB_VARS[x] + for k in _vars: + x=k.lower() + if x in kw: + self.env.append_value(k+'_'+kw['uselib_store'],kw[x]) + return is_success +@conf +def check(self,*k,**kw): + self.validate_c(kw) + self.start_msg(kw['msg'],**kw) + ret=None + try: + ret=self.run_build(*k,**kw) + except self.errors.ConfigurationError: + self.end_msg(kw['errmsg'],'YELLOW',**kw) + if Logs.verbose>1: + raise + else: + self.fatal('The configuration failed') + else: + kw['success']=ret + ret=self.post_check(*k,**kw) + if not ret: + self.end_msg(kw['errmsg'],'YELLOW',**kw) + self.fatal('The configuration failed %r'%ret) + else: + self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) + return ret +class test_exec(Task.Task): + color='PINK' + def run(self): + cmd=[self.inputs[0].abspath()]+getattr(self.generator,'test_args',[]) + if getattr(self.generator,'rpath',None): + if getattr(self.generator,'define_ret',False): + self.generator.bld.retval=self.generator.bld.cmd_and_log(cmd) + else: + self.generator.bld.retval=self.generator.bld.exec_command(cmd) + else: + env=self.env.env or{} + env.update(dict(os.environ)) + for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'): + env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'') + if getattr(self.generator,'define_ret',False): + self.generator.bld.retval=self.generator.bld.cmd_and_log(cmd,env=env) + else: + self.generator.bld.retval=self.generator.bld.exec_command(cmd,env=env) +@feature('test_exec') +@after_method('apply_link') +def test_exec_fun(self): + self.create_task('test_exec',self.link_task.outputs[0]) +@conf +def check_cxx(self,*k,**kw): + kw['compiler']='cxx' + return self.check(*k,**kw) +@conf +def check_cc(self,*k,**kw): + kw['compiler']='c' + return self.check(*k,**kw) +@conf +def set_define_comment(self,key,comment): + coms=self.env.DEFINE_COMMENTS + if not coms: + coms=self.env.DEFINE_COMMENTS={} + coms[key]=comment or'' +@conf +def get_define_comment(self,key): + coms=self.env.DEFINE_COMMENTS or{} + return coms.get(key,'') +@conf +def define(self,key,val,quote=True,comment=''): + assert isinstance(key,str) + if not key: + return + if val is True: + val=1 + elif val in(False,None): + val=0 + if isinstance(val,int)or isinstance(val,float): + s='%s=%s' + else: + s=quote and'%s="%s"'or'%s=%s' + app=s%(key,str(val)) + ban=key+'=' + lst=self.env.DEFINES + for x in lst: + if x.startswith(ban): + lst[lst.index(x)]=app + break + else: + self.env.append_value('DEFINES',app) + self.env.append_unique(DEFKEYS,key) + self.set_define_comment(key,comment) +@conf +def undefine(self,key,comment=''): + assert isinstance(key,str) + if not key: + return + ban=key+'=' + lst=[x for x in self.env.DEFINES if not x.startswith(ban)] + self.env.DEFINES=lst + self.env.append_unique(DEFKEYS,key) + self.set_define_comment(key,comment) +@conf +def define_cond(self,key,val,comment=''): + assert isinstance(key,str) + if not key: + return + if val: + self.define(key,1,comment=comment) + else: + self.undefine(key,comment=comment) +@conf +def is_defined(self,key): + assert key and isinstance(key,str) + ban=key+'=' + for x in self.env.DEFINES: + if x.startswith(ban): + return True + return False +@conf +def get_define(self,key): + assert key and isinstance(key,str) + ban=key+'=' + for x in self.env.DEFINES: + if x.startswith(ban): + return x[len(ban):] + return None +@conf +def have_define(self,key): + return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key) +@conf +def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''): + if not configfile: + configfile=WAF_CONFIG_H + waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile) + node=top and self.bldnode or self.path.get_bld() + node=node.make_node(configfile) + node.parent.mkdir() + lst=['/* WARNING! All changes made to this file will be lost! */\n'] + lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard)) + lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix)) + lst.append('\n#endif /* %s */\n'%waf_guard) + node.write('\n'.join(lst)) + self.env.append_unique(Build.CFG_FILES,[node.abspath()]) + if remove: + for key in self.env[DEFKEYS]: + self.undefine(key) + self.env[DEFKEYS]=[] +@conf +def get_config_header(self,defines=True,headers=False,define_prefix=''): + lst=[] + if self.env.WAF_CONFIG_H_PRELUDE: + lst.append(self.env.WAF_CONFIG_H_PRELUDE) + if headers: + for x in self.env[INCKEYS]: + lst.append('#include <%s>'%x) + if defines: + tbl={} + for k in self.env.DEFINES: + a,_,b=k.partition('=') + tbl[a]=b + for k in self.env[DEFKEYS]: + caption=self.get_define_comment(k) + if caption: + caption=' /* %s */'%caption + try: + txt='#define %s%s %s%s'%(define_prefix,k,tbl[k],caption) + except KeyError: + txt='/* #undef %s%s */%s'%(define_prefix,k,caption) + lst.append(txt) + return"\n".join(lst) +@conf +def cc_add_flags(conf): + conf.add_os_flags('CPPFLAGS',dup=False) + conf.add_os_flags('CFLAGS',dup=False) +@conf +def cxx_add_flags(conf): + conf.add_os_flags('CPPFLAGS',dup=False) + conf.add_os_flags('CXXFLAGS',dup=False) +@conf +def link_add_flags(conf): + conf.add_os_flags('LINKFLAGS',dup=False) + conf.add_os_flags('LDFLAGS',dup=False) +@conf +def cc_load_tools(conf): + if not conf.env.DEST_OS: + conf.env.DEST_OS=Utils.unversioned_sys_platform() + conf.load('c') +@conf +def cxx_load_tools(conf): + if not conf.env.DEST_OS: + conf.env.DEST_OS=Utils.unversioned_sys_platform() + conf.load('cxx') +@conf +def get_cc_version(conf,cc,gcc=False,icc=False,clang=False): + cmd=cc+['-dM','-E','-'] + env=conf.env.env or None + try: + out,err=conf.cmd_and_log(cmd,output=0,input='\n'.encode(),env=env) + except Errors.WafError: + conf.fatal('Could not determine the compiler version %r'%cmd) + if gcc: + if out.find('__INTEL_COMPILER')>=0: + conf.fatal('The intel compiler pretends to be gcc') + if out.find('__GNUC__')<0 and out.find('__clang__')<0: + conf.fatal('Could not determine the compiler type') + if icc and out.find('__INTEL_COMPILER')<0: + conf.fatal('Not icc/icpc') + if clang and out.find('__clang__')<0: + conf.fatal('Not clang/clang++') + if not clang and out.find('__clang__')>=0: + conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') + k={} + if icc or gcc or clang: + out=out.splitlines() + for line in out: + lst=shlex.split(line) + if len(lst)>2: + key=lst[1] + val=lst[2] + k[key]=val + def isD(var): + return var in k + if not conf.env.DEST_OS: + conf.env.DEST_OS='' + for i in MACRO_TO_DESTOS: + if isD(i): + conf.env.DEST_OS=MACRO_TO_DESTOS[i] + break + else: + if isD('__APPLE__')and isD('__MACH__'): + conf.env.DEST_OS='darwin' + elif isD('__unix__'): + conf.env.DEST_OS='generic' + if isD('__ELF__'): + conf.env.DEST_BINFMT='elf' + elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'): + conf.env.DEST_BINFMT='pe' + if not conf.env.IMPLIBDIR: + conf.env.IMPLIBDIR=conf.env.LIBDIR + conf.env.LIBDIR=conf.env.BINDIR + elif isD('__APPLE__'): + conf.env.DEST_BINFMT='mac-o' + if not conf.env.DEST_BINFMT: + conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS) + for i in MACRO_TO_DEST_CPU: + if isD(i): + conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i] + break + Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')])) + if icc: + ver=k['__INTEL_COMPILER'] + conf.env.CC_VERSION=(ver[:-2],ver[-2],ver[-1]) + else: + if isD('__clang__')and isD('__clang_major__'): + conf.env.CC_VERSION=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__']) + else: + conf.env.CC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k.get('__GNUC_PATCHLEVEL__','0')) + return k +@conf +def get_xlc_version(conf,cc): + cmd=cc+['-qversion'] + try: + out,err=conf.cmd_and_log(cmd,output=0) + except Errors.WafError: + conf.fatal('Could not find xlc %r'%cmd) + for v in(r"IBM XL C/C\+\+.* V(?P\d*)\.(?P\d*)",): + version_re=re.compile(v,re.I).search + match=version_re(out or err) + if match: + k=match.groupdict() + conf.env.CC_VERSION=(k['major'],k['minor']) + break + else: + conf.fatal('Could not determine the XLC version.') +@conf +def get_suncc_version(conf,cc): + cmd=cc+['-V'] + try: + out,err=conf.cmd_and_log(cmd,output=0) + except Errors.WafError as e: + if not(hasattr(e,'returncode')and hasattr(e,'stdout')and hasattr(e,'stderr')): + conf.fatal('Could not find suncc %r'%cmd) + out=e.stdout + err=e.stderr + version=(out or err) + version=version.splitlines()[0] + version_re=re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P\d*)\.(?P\d*)',re.I).search + match=version_re(version) + if match: + k=match.groupdict() + conf.env.CC_VERSION=(k['major'],k['minor']) + else: + conf.fatal('Could not determine the suncc version.') +@conf +def add_as_needed(self): + if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME): + self.env.append_unique('LINKFLAGS','-Wl,--as-needed') +class cfgtask(Task.Task): + def __init__(self,*k,**kw): + Task.Task.__init__(self,*k,**kw) + self.run_after=set() + def display(self): + return'' + def runnable_status(self): + for x in self.run_after: + if not x.hasrun: + return Task.ASK_LATER + return Task.RUN_ME + def uid(self): + return Utils.SIG_NIL + def signature(self): + return Utils.SIG_NIL + def run(self): + conf=self.conf + bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath()) + bld.env=conf.env + bld.init_dirs() + bld.in_msg=1 + bld.logger=self.logger + bld.multicheck_task=self + args=self.args + try: + if'func'in args: + bld.test(build_fun=args['func'],msg=args.get('msg',''),okmsg=args.get('okmsg',''),errmsg=args.get('errmsg',''),) + else: + args['multicheck_mandatory']=args.get('mandatory',True) + args['mandatory']=True + try: + bld.check(**args) + finally: + args['mandatory']=args['multicheck_mandatory'] + except Exception: + return 1 + def process(self): + Task.Task.process(self) + if'msg'in self.args: + with self.generator.bld.multicheck_lock: + self.conf.start_msg(self.args['msg']) + if self.hasrun==Task.NOT_RUN: + self.conf.end_msg('test cancelled','YELLOW') + elif self.hasrun!=Task.SUCCESS: + self.conf.end_msg(self.args.get('errmsg','no'),'YELLOW') + else: + self.conf.end_msg(self.args.get('okmsg','yes'),'GREEN') +@conf +def multicheck(self,*k,**kw): + self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw) + for var in('DEFINES',DEFKEYS): + self.env.append_value(var,[]) + self.env.DEFINE_COMMENTS=self.env.DEFINE_COMMENTS or{} + class par(object): + def __init__(self): + self.keep=False + self.task_sigs={} + self.progress_bar=0 + def total(self): + return len(tasks) + def to_log(self,*k,**kw): + return + bld=par() + bld.keep=kw.get('run_all_tests',True) + bld.imp_sigs={} + tasks=[] + id_to_task={} + for dct in k: + x=Task.classes['cfgtask'](bld=bld,env=None) + tasks.append(x) + x.args=dct + x.bld=bld + x.conf=self + x.args=dct + x.logger=Logs.make_mem_logger(str(id(x)),self.logger) + if'id'in dct: + id_to_task[dct['id']]=x + for x in tasks: + for key in Utils.to_list(x.args.get('before_tests',[])): + tsk=id_to_task[key] + if not tsk: + raise ValueError('No test named %r'%key) + tsk.run_after.add(x) + for key in Utils.to_list(x.args.get('after_tests',[])): + tsk=id_to_task[key] + if not tsk: + raise ValueError('No test named %r'%key) + x.run_after.add(tsk) + def it(): + yield tasks + while 1: + yield[] + bld.producer=p=Runner.Parallel(bld,Options.options.jobs) + bld.multicheck_lock=Utils.threading.Lock() + p.biter=it() + self.end_msg('started') + p.start() + for x in tasks: + x.logger.memhandler.flush() + self.start_msg('-> processing test results') + if p.error: + for x in p.error: + if getattr(x,'err_msg',None): + self.to_log(x.err_msg) + self.end_msg('fail',color='RED') + raise Errors.WafError('There is an error in the library, read config.log for more information') + failure_count=0 + for x in tasks: + if x.hasrun not in(Task.SUCCESS,Task.NOT_RUN): + failure_count+=1 + if failure_count: + self.end_msg(kw.get('errmsg','%s test failed'%failure_count),color='YELLOW',**kw) + else: + self.end_msg('all ok',**kw) + for x in tasks: + if x.hasrun!=Task.SUCCESS: + if x.args.get('mandatory',True): + self.fatal(kw.get('fatalmsg')or'One of the tests has failed, read config.log for more information') +@conf +def check_gcc_o_space(self,mode='c'): + if int(self.env.CC_VERSION[0])>4: + return + self.env.stash() + if mode=='c': + self.env.CCLNK_TGT_F=['-o',''] + elif mode=='cxx': + self.env.CXXLNK_TGT_F=['-o',''] + features='%s %sshlib'%(mode,mode) + try: + self.check(msg='Checking if the -o link must be split from arguments',fragment=SNIP_EMPTY_PROGRAM,features=features) + except self.errors.ConfigurationError: + self.env.revert() + else: + self.env.commit() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py new file mode 100755 index 0000000..847b433 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py @@ -0,0 +1,121 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,shutil,platform +from waflib import Task,Utils +from waflib.TaskGen import taskgen_method,feature,after_method,before_method +app_info=''' + + + + + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Waf + CFBundleSignature + ???? + NOTE + THIS IS A GENERATED FILE, DO NOT MODIFY + CFBundleExecutable + {app_name} + + +''' +@feature('c','cxx') +def set_macosx_deployment_target(self): + if self.env.MACOSX_DEPLOYMENT_TARGET: + os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env.MACOSX_DEPLOYMENT_TARGET + elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ: + if Utils.unversioned_sys_platform()=='darwin': + os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2]) +@taskgen_method +def create_bundle_dirs(self,name,out): + dir=out.parent.find_or_declare(name) + dir.mkdir() + macos=dir.find_or_declare(['Contents','MacOS']) + macos.mkdir() + return dir +def bundle_name_for_output(out): + name=out.name + k=name.rfind('.') + if k>=0: + name=name[:k]+'.app' + else: + name=name+'.app' + return name +@feature('cprogram','cxxprogram') +@after_method('apply_link') +def create_task_macapp(self): + if self.env.MACAPP or getattr(self,'mac_app',False): + out=self.link_task.outputs[0] + name=bundle_name_for_output(out) + dir=self.create_bundle_dirs(name,out) + n1=dir.find_or_declare(['Contents','MacOS',out.name]) + self.apptask=self.create_task('macapp',self.link_task.outputs,n1) + inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name + self.add_install_files(install_to=inst_to,install_from=n1,chmod=Utils.O755) + if getattr(self,'mac_files',None): + mac_files_root=getattr(self,'mac_files_root',None) + if isinstance(mac_files_root,str): + mac_files_root=self.path.find_node(mac_files_root) + if not mac_files_root: + self.bld.fatal('Invalid mac_files_root %r'%self.mac_files_root) + res_dir=n1.parent.parent.make_node('Resources') + inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name + for node in self.to_nodes(self.mac_files): + relpath=node.path_from(mac_files_root or node.parent) + self.create_task('macapp',node,res_dir.make_node(relpath)) + self.add_install_as(install_to=os.path.join(inst_to,relpath),install_from=node) + if getattr(self.bld,'is_install',None): + self.install_task.hasrun=Task.SKIP_ME +@feature('cprogram','cxxprogram') +@after_method('apply_link') +def create_task_macplist(self): + if self.env.MACAPP or getattr(self,'mac_app',False): + out=self.link_task.outputs[0] + name=bundle_name_for_output(out) + dir=self.create_bundle_dirs(name,out) + n1=dir.find_or_declare(['Contents','Info.plist']) + self.plisttask=plisttask=self.create_task('macplist',[],n1) + plisttask.context={'app_name':self.link_task.outputs[0].name,'env':self.env} + plist_ctx=getattr(self,'plist_context',None) + if(plist_ctx): + plisttask.context.update(plist_ctx) + if getattr(self,'mac_plist',False): + node=self.path.find_resource(self.mac_plist) + if node: + plisttask.inputs.append(node) + else: + plisttask.code=self.mac_plist + else: + plisttask.code=app_info + inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name + self.add_install_files(install_to=inst_to,install_from=n1) +@feature('cshlib','cxxshlib') +@before_method('apply_link','propagate_uselib_vars') +def apply_bundle(self): + if self.env.MACBUNDLE or getattr(self,'mac_bundle',False): + self.env.LINKFLAGS_cshlib=self.env.LINKFLAGS_cxxshlib=[] + self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN + use=self.use=self.to_list(getattr(self,'use',[])) + if not'MACBUNDLE'in use: + use.append('MACBUNDLE') +app_dirs=['Contents','Contents/MacOS','Contents/Resources'] +class macapp(Task.Task): + color='PINK' + def run(self): + self.outputs[0].parent.mkdir() + shutil.copy2(self.inputs[0].srcpath(),self.outputs[0].abspath()) +class macplist(Task.Task): + color='PINK' + ext_in=['.bin'] + def run(self): + if getattr(self,'code',None): + txt=self.code + else: + txt=self.inputs[0].read() + context=getattr(self,'context',{}) + txt=txt.format(**context) + self.outputs[0].write(txt) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py new file mode 100755 index 0000000..a183c66 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py @@ -0,0 +1,672 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re,string,traceback +from waflib import Logs,Utils,Errors +class PreprocError(Errors.WafError): + pass +FILE_CACHE_SIZE=100000 +LINE_CACHE_SIZE=100000 +POPFILE='-' +recursion_limit=150 +go_absolute=False +standard_includes=['/usr/local/include','/usr/include'] +if Utils.is_win32: + standard_includes=[] +use_trigraphs=0 +strict_quotes=0 +g_optrans={'not':'!','not_eq':'!','and':'&&','and_eq':'&=','or':'||','or_eq':'|=','xor':'^','xor_eq':'^=','bitand':'&','bitor':'|','compl':'~',} +re_lines=re.compile('^[ \t]*(?:#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE) +re_mac=re.compile(r"^[a-zA-Z_]\w*") +re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]') +re_pragma_once=re.compile(r'^\s*once\s*',re.IGNORECASE) +re_nl=re.compile('\\\\\r*\n',re.MULTILINE) +re_cpp=re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL|re.MULTILINE) +trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')] +chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39} +NUM='i' +OP='O' +IDENT='T' +STR='s' +CHAR='c' +tok_types=[NUM,STR,IDENT,OP] +exp_types=[r"""0[xX](?P[a-fA-F0-9]+)(?P[uUlL]*)|L*?'(?P(\\.|[^\\'])+)'|(?P\d+)[Ee](?P[+-]*?\d+)(?P[fFlL]*)|(?P\d*\.\d+)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P\d+\.\d*)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P0*)(?P\d+)(?P[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',] +re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M) +accepted='a' +ignored='i' +undefined='u' +skipped='s' +def repl(m): + s=m.group() + if s[0]=='/': + return' ' + return s +prec={} +ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',','] +for x,syms in enumerate(ops): + for u in syms.split(): + prec[u]=x +def reduce_nums(val_1,val_2,val_op): + try: + a=0+val_1 + except TypeError: + a=int(val_1) + try: + b=0+val_2 + except TypeError: + b=int(val_2) + d=val_op + if d=='%': + c=a%b + elif d=='+': + c=a+b + elif d=='-': + c=a-b + elif d=='*': + c=a*b + elif d=='/': + c=a/b + elif d=='^': + c=a^b + elif d=='==': + c=int(a==b) + elif d=='|'or d=='bitor': + c=a|b + elif d=='||'or d=='or': + c=int(a or b) + elif d=='&'or d=='bitand': + c=a&b + elif d=='&&'or d=='and': + c=int(a and b) + elif d=='!='or d=='not_eq': + c=int(a!=b) + elif d=='^'or d=='xor': + c=int(a^b) + elif d=='<=': + c=int(a<=b) + elif d=='<': + c=int(a': + c=int(a>b) + elif d=='>=': + c=int(a>=b) + elif d=='<<': + c=a<>': + c=a>>b + else: + c=0 + return c +def get_num(lst): + if not lst: + raise PreprocError('empty list for get_num') + (p,v)=lst[0] + if p==OP: + if v=='(': + count_par=1 + i=1 + while i=prec[v]: + num2=reduce_nums(num,num2,v) + return get_term([(NUM,num2)]+lst) + else: + num3,lst=get_num(lst[1:]) + num3=reduce_nums(num2,num3,v2) + return get_term([(NUM,num),(p,v),(NUM,num3)]+lst) + raise PreprocError('cannot reduce %r'%lst) +def reduce_eval(lst): + num,lst=get_term(lst) + return(NUM,num) +def stringize(lst): + lst=[str(v2)for(p2,v2)in lst] + return"".join(lst) +def paste_tokens(t1,t2): + p1=None + if t1[0]==OP and t2[0]==OP: + p1=OP + elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM): + p1=IDENT + elif t1[0]==NUM and t2[0]==NUM: + p1=NUM + if not p1: + raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2)) + return(p1,t1[1]+t2[1]) +def reduce_tokens(lst,defs,ban=[]): + i=0 + while i=len(lst): + raise PreprocError('expected ( after %r (got nothing)'%v) + (p2,v2)=lst[i] + if p2!=OP or v2!='(': + raise PreprocError('expected ( after %r'%v) + del lst[i] + one_param=[] + count_paren=0 + while i1: + (p3,v3)=accu[-1] + (p4,v4)=accu[-2] + if v3=='##': + accu.pop() + if v4==','and pt1: + return(v,[[],t[1:]]) + else: + return(v,[[],[('T','')]]) +re_include=re.compile(r'^\s*(<(?:.*)>|"(?:.*)")') +def extract_include(txt,defs): + m=re_include.search(txt) + if m: + txt=m.group(1) + return txt[0],txt[1:-1] + toks=tokenize(txt) + reduce_tokens(toks,defs,['waf_include']) + if not toks: + raise PreprocError('could not parse include %r'%txt) + if len(toks)==1: + if toks[0][0]==STR: + return'"',toks[0][1] + else: + if toks[0][1]=='<'and toks[-1][1]=='>': + ret='<',stringize(toks).lstrip('<').rstrip('>') + return ret + raise PreprocError('could not parse include %r'%txt) +def parse_char(txt): + if not txt: + raise PreprocError('attempted to parse a null char') + if txt[0]!='\\': + return ord(txt) + c=txt[1] + if c=='x': + if len(txt)==4 and txt[3]in string.hexdigits: + return int(txt[2:],16) + return int(txt[2:],16) + elif c.isdigit(): + if c=='0'and len(txt)==2: + return 0 + for i in 3,2,1: + if len(txt)>i and txt[1:1+i].isdigit(): + return(1+i,int(txt[1:1+i],8)) + else: + try: + return chr_esc[c] + except KeyError: + raise PreprocError('could not parse char literal %r'%txt) +def tokenize(s): + return tokenize_private(s)[:] +def tokenize_private(s): + ret=[] + for match in re_clexer.finditer(s): + m=match.group + for name in tok_types: + v=m(name) + if v: + if name==IDENT: + if v in g_optrans: + name=OP + elif v.lower()=="true": + v=1 + name=NUM + elif v.lower()=="false": + v=0 + name=NUM + elif name==NUM: + if m('oct'): + v=int(v,8) + elif m('hex'): + v=int(m('hex'),16) + elif m('n0'): + v=m('n0') + else: + v=m('char') + if v: + v=parse_char(v) + else: + v=m('n2')or m('n4') + elif name==OP: + if v=='%:': + v='#' + elif v=='%:%:': + v='##' + elif name==STR: + v=v[1:-1] + ret.append((name,v)) + break + return ret +def format_defines(lst): + ret=[] + for y in lst: + if y: + pos=y.find('=') + if pos==-1: + ret.append(y) + elif pos>0: + ret.append('%s %s'%(y[:pos],y[pos+1:])) + else: + raise ValueError('Invalid define expression %r'%y) + return ret +class c_parser(object): + def __init__(self,nodepaths=None,defines=None): + self.lines=[] + if defines is None: + self.defs={} + else: + self.defs=dict(defines) + self.state=[] + self.count_files=0 + self.currentnode_stack=[] + self.nodepaths=nodepaths or[] + self.nodes=[] + self.names=[] + self.curfile='' + self.ban_includes=set() + self.listed=set() + def cached_find_resource(self,node,filename): + try: + cache=node.ctx.preproc_cache_node + except AttributeError: + cache=node.ctx.preproc_cache_node=Utils.lru_cache(FILE_CACHE_SIZE) + key=(node,filename) + try: + return cache[key] + except KeyError: + ret=node.find_resource(filename) + if ret: + if getattr(ret,'children',None): + ret=None + elif ret.is_child_of(node.ctx.bldnode): + tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode)) + if tmp and getattr(tmp,'children',None): + ret=None + cache[key]=ret + return ret + def tryfind(self,filename,kind='"',env=None): + if filename.endswith('.moc'): + self.names.append(filename) + return None + self.curfile=filename + found=None + if kind=='"': + if env.MSVC_VERSION: + for n in reversed(self.currentnode_stack): + found=self.cached_find_resource(n,filename) + if found: + break + else: + found=self.cached_find_resource(self.currentnode_stack[-1],filename) + if not found: + for n in self.nodepaths: + found=self.cached_find_resource(n,filename) + if found: + break + listed=self.listed + if found and not found in self.ban_includes: + if found not in listed: + listed.add(found) + self.nodes.append(found) + self.addlines(found) + else: + if filename not in listed: + listed.add(filename) + self.names.append(filename) + return found + def filter_comments(self,node): + code=node.read() + if use_trigraphs: + for(a,b)in trig_def: + code=code.split(a).join(b) + code=re_nl.sub('',code) + code=re_cpp.sub(repl,code) + return re_lines.findall(code) + def parse_lines(self,node): + try: + cache=node.ctx.preproc_cache_lines + except AttributeError: + cache=node.ctx.preproc_cache_lines=Utils.lru_cache(LINE_CACHE_SIZE) + try: + return cache[node] + except KeyError: + cache[node]=lines=self.filter_comments(node) + lines.append((POPFILE,'')) + lines.reverse() + return lines + def addlines(self,node): + self.currentnode_stack.append(node.parent) + self.count_files+=1 + if self.count_files>recursion_limit: + raise PreprocError('recursion limit exceeded') + if Logs.verbose: + Logs.debug('preproc: reading file %r',node) + try: + lines=self.parse_lines(node) + except EnvironmentError: + raise PreprocError('could not read the file %r'%node) + except Exception: + if Logs.verbose>0: + Logs.error('parsing %r failed %s',node,traceback.format_exc()) + else: + self.lines.extend(lines) + def start(self,node,env): + Logs.debug('preproc: scanning %s (in %s)',node.name,node.parent.name) + self.current_file=node + self.addlines(node) + if env.DEFINES: + lst=format_defines(env.DEFINES) + lst.reverse() + self.lines.extend([('define',x)for x in lst]) + while self.lines: + (token,line)=self.lines.pop() + if token==POPFILE: + self.count_files-=1 + self.currentnode_stack.pop() + continue + try: + state=self.state + if token[:2]=='if': + state.append(undefined) + elif token=='endif': + state.pop() + if token[0]!='e': + if skipped in self.state or ignored in self.state: + continue + if token=='if': + ret=eval_macro(tokenize(line),self.defs) + if ret: + state[-1]=accepted + else: + state[-1]=ignored + elif token=='ifdef': + m=re_mac.match(line) + if m and m.group()in self.defs: + state[-1]=accepted + else: + state[-1]=ignored + elif token=='ifndef': + m=re_mac.match(line) + if m and m.group()in self.defs: + state[-1]=ignored + else: + state[-1]=accepted + elif token=='include'or token=='import': + (kind,inc)=extract_include(line,self.defs) + self.current_file=self.tryfind(inc,kind,env) + if token=='import': + self.ban_includes.add(self.current_file) + elif token=='elif': + if state[-1]==accepted: + state[-1]=skipped + elif state[-1]==ignored: + if eval_macro(tokenize(line),self.defs): + state[-1]=accepted + elif token=='else': + if state[-1]==accepted: + state[-1]=skipped + elif state[-1]==ignored: + state[-1]=accepted + elif token=='define': + try: + self.defs[self.define_name(line)]=line + except AttributeError: + raise PreprocError('Invalid define line %r'%line) + elif token=='undef': + m=re_mac.match(line) + if m and m.group()in self.defs: + self.defs.__delitem__(m.group()) + elif token=='pragma': + if re_pragma_once.match(line.lower()): + self.ban_includes.add(self.current_file) + except Exception as e: + if Logs.verbose: + Logs.debug('preproc: line parsing failed (%s): %s %s',e,line,traceback.format_exc()) + def define_name(self,line): + return re_mac.match(line).group() +def scan(task): + try: + incn=task.generator.includes_nodes + except AttributeError: + raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator) + if go_absolute: + nodepaths=incn+[task.generator.bld.root.find_dir(x)for x in standard_includes] + else: + nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)] + tmp=c_parser(nodepaths) + tmp.start(task.inputs[0],task.env) + return(tmp.nodes,tmp.names) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py new file mode 100755 index 0000000..e295753 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py @@ -0,0 +1,152 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Task +from waflib.Configure import conf +from waflib.TaskGen import feature,before_method,after_method +LIB_CODE=''' +#ifdef _MSC_VER +#define testEXPORT __declspec(dllexport) +#else +#define testEXPORT +#endif +testEXPORT int lib_func(void) { return 9; } +''' +MAIN_CODE=''' +#ifdef _MSC_VER +#define testEXPORT __declspec(dllimport) +#else +#define testEXPORT +#endif +testEXPORT int lib_func(void); +int main(int argc, char **argv) { + (void)argc; (void)argv; + return !(lib_func() == 9); +} +''' +@feature('link_lib_test') +@before_method('process_source') +def link_lib_test_fun(self): + def write_test_file(task): + task.outputs[0].write(task.generator.code) + rpath=[] + if getattr(self,'add_rpath',False): + rpath=[self.bld.path.get_bld().abspath()] + mode=self.mode + m='%s %s'%(mode,mode) + ex=self.test_exec and'test_exec'or'' + bld=self.bld + bld(rule=write_test_file,target='test.'+mode,code=LIB_CODE) + bld(rule=write_test_file,target='main.'+mode,code=MAIN_CODE) + bld(features='%sshlib'%m,source='test.'+mode,target='test') + bld(features='%sprogram %s'%(m,ex),source='main.'+mode,target='app',use='test',rpath=rpath) +@conf +def check_library(self,mode=None,test_exec=True): + if not mode: + mode='c' + if self.env.CXX: + mode='cxx' + self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec) +INLINE_CODE=''' +typedef int foo_t; +static %s foo_t static_foo () {return 0; } +%s foo_t foo () { + return 0; +} +''' +INLINE_VALUES=['inline','__inline__','__inline'] +@conf +def check_inline(self,**kw): + self.start_msg('Checking for inline') + if not'define_name'in kw: + kw['define_name']='INLINE_MACRO' + if not'features'in kw: + if self.env.CXX: + kw['features']=['cxx'] + else: + kw['features']=['c'] + for x in INLINE_VALUES: + kw['fragment']=INLINE_CODE%(x,x) + try: + self.check(**kw) + except self.errors.ConfigurationError: + continue + else: + self.end_msg(x) + if x!='inline': + self.define('inline',x,quote=False) + return x + self.fatal('could not use inline functions') +LARGE_FRAGMENT='''#include +int main(int argc, char **argv) { + (void)argc; (void)argv; + return !(sizeof(off_t) >= 8); +} +''' +@conf +def check_large_file(self,**kw): + if not'define_name'in kw: + kw['define_name']='HAVE_LARGEFILE' + if not'execute'in kw: + kw['execute']=True + if not'features'in kw: + if self.env.CXX: + kw['features']=['cxx','cxxprogram'] + else: + kw['features']=['c','cprogram'] + kw['fragment']=LARGE_FRAGMENT + kw['msg']='Checking for large file support' + ret=True + try: + if self.env.DEST_BINFMT!='pe': + ret=self.check(**kw) + except self.errors.ConfigurationError: + pass + else: + if ret: + return True + kw['msg']='Checking for -D_FILE_OFFSET_BITS=64' + kw['defines']=['_FILE_OFFSET_BITS=64'] + try: + ret=self.check(**kw) + except self.errors.ConfigurationError: + pass + else: + self.define('_FILE_OFFSET_BITS',64) + return ret + self.fatal('There is no support for large files') +ENDIAN_FRAGMENT=''' +short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; +} +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; +} +extern int foo; +''' +class grep_for_endianness(Task.Task): + color='PINK' + def run(self): + txt=self.inputs[0].read(flags='rb').decode('latin-1') + if txt.find('LiTTleEnDian')>-1: + self.generator.tmp.append('little') + elif txt.find('BIGenDianSyS')>-1: + self.generator.tmp.append('big') + else: + return-1 +@feature('grep_for_endianness') +@after_method('process_source') +def grep_for_endianness_fun(self): + self.create_task('grep_for_endianness',self.compiled_tasks[0].outputs[0]) +@conf +def check_endianness(self): + tmp=[] + def check_msg(self): + return tmp[0] + self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg='Checking for endianness',define='ENDIANNESS',tmp=tmp,okmsg=check_msg,confcache=None) + return tmp[0] diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py new file mode 100755 index 0000000..9d865bf --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py @@ -0,0 +1,486 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re +from waflib import Task,Utils,Node,Errors,Logs +from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension +from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests +from waflib.Configure import conf +SYSTEM_LIB_PATHS=['/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib'] +USELIB_VARS=Utils.defaultdict(set) +USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH']) +USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH']) +USELIB_VARS['d']=set(['INCLUDES','DFLAGS']) +USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH']) +USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS']) +USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS']) +USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS']) +USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) +USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) +USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS']) +USELIB_VARS['asm']=set(['ASFLAGS']) +@taskgen_method +def create_compiled_task(self,name,node): + out='%s.%d.o'%(node.name,self.idx) + task=self.create_task(name,node,node.parent.find_or_declare(out)) + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks=[task] + return task +@taskgen_method +def to_incnodes(self,inlst): + lst=[] + seen=set() + for x in self.to_list(inlst): + if x in seen or not x: + continue + seen.add(x) + if isinstance(x,Node.Node): + lst.append(x) + else: + if os.path.isabs(x): + lst.append(self.bld.root.make_node(x)or x) + else: + if x[0]=='#': + p=self.bld.bldnode.make_node(x[1:]) + v=self.bld.srcnode.make_node(x[1:]) + else: + p=self.path.get_bld().make_node(x) + v=self.path.make_node(x) + if p.is_child_of(self.bld.bldnode): + p.mkdir() + lst.append(p) + lst.append(v) + return lst +@feature('c','cxx','d','asm','fc','includes') +@after_method('propagate_uselib_vars','process_source') +def apply_incpaths(self): + lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env.INCLUDES) + self.includes_nodes=lst + cwd=self.get_cwd() + self.env.INCPATHS=[x.path_from(cwd)for x in lst] +class link_task(Task.Task): + color='YELLOW' + weight=3 + inst_to=None + chmod=Utils.O755 + def add_target(self,target): + if isinstance(target,str): + base=self.generator.path + if target.startswith('#'): + target=target[1:] + base=self.generator.bld.bldnode + pattern=self.env[self.__class__.__name__+'_PATTERN'] + if not pattern: + pattern='%s' + folder,name=os.path.split(target) + if self.__class__.__name__.find('shlib')>0 and getattr(self.generator,'vnum',None): + nums=self.generator.vnum.split('.') + if self.env.DEST_BINFMT=='pe': + name=name+'-'+nums[0] + elif self.env.DEST_OS=='openbsd': + pattern='%s.%s'%(pattern,nums[0]) + if len(nums)>=2: + pattern+='.%s'%nums[1] + if folder: + tmp=folder+os.sep+pattern%name + else: + tmp=pattern%name + target=base.find_or_declare(tmp) + self.set_outputs(target) + def exec_command(self,*k,**kw): + ret=super(link_task,self).exec_command(*k,**kw) + if not ret and self.env.DO_MANIFEST: + ret=self.exec_mf() + return ret + def exec_mf(self): + if not self.env.MT: + return 0 + manifest=None + for out_node in self.outputs: + if out_node.name.endswith('.manifest'): + manifest=out_node.abspath() + break + else: + return 0 + mode='' + for x in Utils.to_list(self.generator.features): + if x in('cprogram','cxxprogram','fcprogram','fcprogram_test'): + mode=1 + elif x in('cshlib','cxxshlib','fcshlib'): + mode=2 + Logs.debug('msvc: embedding manifest in mode %r',mode) + lst=[]+self.env.MT + lst.extend(Utils.to_list(self.env.MTFLAGS)) + lst.extend(['-manifest',manifest]) + lst.append('-outputresource:%s;%s'%(self.outputs[0].abspath(),mode)) + return super(link_task,self).exec_command(lst) +class stlink_task(link_task): + run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}' + chmod=Utils.O644 +def rm_tgt(cls): + old=cls.run + def wrap(self): + try: + os.remove(self.outputs[0].abspath()) + except OSError: + pass + return old(self) + setattr(cls,'run',wrap) +rm_tgt(stlink_task) +@feature('skip_stlib_link_deps') +@before_method('process_use') +def apply_skip_stlib_link_deps(self): + self.env.SKIP_STLIB_LINK_DEPS=True +@feature('c','cxx','d','fc','asm') +@after_method('process_source') +def apply_link(self): + for x in self.features: + if x=='cprogram'and'cxx'in self.features: + x='cxxprogram' + elif x=='cshlib'and'cxx'in self.features: + x='cxxshlib' + if x in Task.classes: + if issubclass(Task.classes[x],link_task): + link=x + break + else: + return + objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])] + self.link_task=self.create_task(link,objs) + self.link_task.add_target(self.target) + try: + inst_to=self.install_path + except AttributeError: + inst_to=self.link_task.inst_to + if inst_to: + self.install_task=self.add_install_files(install_to=inst_to,install_from=self.link_task.outputs[:],chmod=self.link_task.chmod,task=self.link_task) +@taskgen_method +def use_rec(self,name,**kw): + if name in self.tmp_use_not or name in self.tmp_use_seen: + return + try: + y=self.bld.get_tgen_by_name(name) + except Errors.WafError: + self.uselib.append(name) + self.tmp_use_not.add(name) + return + self.tmp_use_seen.append(name) + y.post() + y.tmp_use_objects=objects=kw.get('objects',True) + y.tmp_use_stlib=stlib=kw.get('stlib',True) + try: + link_task=y.link_task + except AttributeError: + y.tmp_use_var='' + else: + objects=False + if not isinstance(link_task,stlink_task): + stlib=False + y.tmp_use_var='LIB' + else: + y.tmp_use_var='STLIB' + p=self.tmp_use_prec + for x in self.to_list(getattr(y,'use',[])): + if self.env["STLIB_"+x]: + continue + try: + p[x].append(name) + except KeyError: + p[x]=[name] + self.use_rec(x,objects=objects,stlib=stlib) +@feature('c','cxx','d','use','fc') +@before_method('apply_incpaths','propagate_uselib_vars') +@after_method('apply_link','process_source') +def process_use(self): + use_not=self.tmp_use_not=set() + self.tmp_use_seen=[] + use_prec=self.tmp_use_prec={} + self.uselib=self.to_list(getattr(self,'uselib',[])) + self.includes=self.to_list(getattr(self,'includes',[])) + names=self.to_list(getattr(self,'use',[])) + for x in names: + self.use_rec(x) + for x in use_not: + if x in use_prec: + del use_prec[x] + out=self.tmp_use_sorted=[] + tmp=[] + for x in self.tmp_use_seen: + for k in use_prec.values(): + if x in k: + break + else: + tmp.append(x) + while tmp: + e=tmp.pop() + out.append(e) + try: + nlst=use_prec[e] + except KeyError: + pass + else: + del use_prec[e] + for x in nlst: + for y in use_prec: + if x in use_prec[y]: + break + else: + tmp.append(x) + if use_prec: + raise Errors.WafError('Cycle detected in the use processing %r'%use_prec) + out.reverse() + link_task=getattr(self,'link_task',None) + for x in out: + y=self.bld.get_tgen_by_name(x) + var=y.tmp_use_var + if var and link_task: + if self.env.SKIP_STLIB_LINK_DEPS and isinstance(link_task,stlink_task): + pass + elif var=='LIB'or y.tmp_use_stlib or x in names: + self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]]) + self.link_task.dep_nodes.extend(y.link_task.outputs) + tmp_path=y.link_task.outputs[0].parent.path_from(self.get_cwd()) + self.env.append_unique(var+'PATH',[tmp_path]) + else: + if y.tmp_use_objects: + self.add_objects_from_tgen(y) + if getattr(y,'export_includes',None): + self.includes=self.includes+y.to_incnodes(y.export_includes) + if getattr(y,'export_defines',None): + self.env.append_value('DEFINES',self.to_list(y.export_defines)) + for x in names: + try: + y=self.bld.get_tgen_by_name(x) + except Errors.WafError: + if not self.env['STLIB_'+x]and not x in self.uselib: + self.uselib.append(x) + else: + for k in self.to_list(getattr(y,'use',[])): + if not self.env['STLIB_'+k]and not k in self.uselib: + self.uselib.append(k) +@taskgen_method +def accept_node_to_link(self,node): + return not node.name.endswith('.pdb') +@taskgen_method +def add_objects_from_tgen(self,tg): + try: + link_task=self.link_task + except AttributeError: + pass + else: + for tsk in getattr(tg,'compiled_tasks',[]): + for x in tsk.outputs: + if self.accept_node_to_link(x): + link_task.inputs.append(x) +@taskgen_method +def get_uselib_vars(self): + _vars=set() + for x in self.features: + if x in USELIB_VARS: + _vars|=USELIB_VARS[x] + return _vars +@feature('c','cxx','d','fc','javac','cs','uselib','asm') +@after_method('process_use') +def propagate_uselib_vars(self): + _vars=self.get_uselib_vars() + env=self.env + app=env.append_value + feature_uselib=self.features+self.to_list(getattr(self,'uselib',[])) + for var in _vars: + y=var.lower() + val=getattr(self,y,[]) + if val: + app(var,self.to_list(val)) + for x in feature_uselib: + val=env['%s_%s'%(var,x)] + if val: + app(var,val) +@feature('cshlib','cxxshlib','fcshlib') +@after_method('apply_link') +def apply_implib(self): + if not self.env.DEST_BINFMT=='pe': + return + dll=self.link_task.outputs[0] + if isinstance(self.target,Node.Node): + name=self.target.name + else: + name=os.path.split(self.target)[1] + implib=self.env.implib_PATTERN%name + implib=dll.parent.find_or_declare(implib) + self.env.append_value('LINKFLAGS',self.env.IMPLIB_ST%implib.bldpath()) + self.link_task.outputs.append(implib) + if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe': + node=self.path.find_resource(self.defs) + if not node: + raise Errors.WafError('invalid def file %r'%self.defs) + if self.env.def_PATTERN: + self.env.append_value('LINKFLAGS',self.env.def_PATTERN%node.path_from(self.get_cwd())) + self.link_task.dep_nodes.append(node) + else: + self.link_task.inputs.append(node) + if getattr(self,'install_task',None): + try: + inst_to=self.install_path_implib + except AttributeError: + try: + inst_to=self.install_path + except AttributeError: + inst_to='${IMPLIBDIR}' + self.install_task.install_to='${BINDIR}' + if not self.env.IMPLIBDIR: + self.env.IMPLIBDIR=self.env.LIBDIR + self.implib_install_task=self.add_install_files(install_to=inst_to,install_from=implib,chmod=self.link_task.chmod,task=self.link_task) +re_vnum=re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$') +@feature('cshlib','cxxshlib','dshlib','fcshlib','vnum') +@after_method('apply_link','propagate_uselib_vars') +def apply_vnum(self): + if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'): + return + link=self.link_task + if not re_vnum.match(self.vnum): + raise Errors.WafError('Invalid vnum %r for target %r'%(self.vnum,getattr(self,'name',self))) + nums=self.vnum.split('.') + node=link.outputs[0] + cnum=getattr(self,'cnum',str(nums[0])) + cnums=cnum.split('.') + if len(cnums)>len(nums)or nums[0:len(cnums)]!=cnums: + raise Errors.WafError('invalid compatibility version %s'%cnum) + libname=node.name + if libname.endswith('.dylib'): + name3=libname.replace('.dylib','.%s.dylib'%self.vnum) + name2=libname.replace('.dylib','.%s.dylib'%cnum) + else: + name3=libname+'.'+self.vnum + name2=libname+'.'+cnum + if self.env.SONAME_ST: + v=self.env.SONAME_ST%name2 + self.env.append_value('LINKFLAGS',v.split()) + if self.env.DEST_OS!='openbsd': + outs=[node.parent.make_node(name3)] + if name2!=name3: + outs.append(node.parent.make_node(name2)) + self.create_task('vnum',node,outs) + if getattr(self,'install_task',None): + self.install_task.hasrun=Task.SKIPPED + self.install_task.no_errcheck_out=True + path=self.install_task.install_to + if self.env.DEST_OS=='openbsd': + libname=self.link_task.outputs[0].name + t1=self.add_install_as(install_to='%s/%s'%(path,libname),install_from=node,chmod=self.link_task.chmod) + self.vnum_install_task=(t1,) + else: + t1=self.add_install_as(install_to=path+os.sep+name3,install_from=node,chmod=self.link_task.chmod) + t3=self.add_symlink_as(install_to=path+os.sep+libname,install_from=name3) + if name2!=name3: + t2=self.add_symlink_as(install_to=path+os.sep+name2,install_from=name3) + self.vnum_install_task=(t1,t2,t3) + else: + self.vnum_install_task=(t1,t3) + if'-dynamiclib'in self.env.LINKFLAGS: + try: + inst_to=self.install_path + except AttributeError: + inst_to=self.link_task.inst_to + if inst_to: + p=Utils.subst_vars(inst_to,self.env) + path=os.path.join(p,name2) + self.env.append_value('LINKFLAGS',['-install_name',path]) + self.env.append_value('LINKFLAGS','-Wl,-compatibility_version,%s'%cnum) + self.env.append_value('LINKFLAGS','-Wl,-current_version,%s'%self.vnum) +class vnum(Task.Task): + color='CYAN' + ext_in=['.bin'] + def keyword(self): + return'Symlinking' + def run(self): + for x in self.outputs: + path=x.abspath() + try: + os.remove(path) + except OSError: + pass + try: + os.symlink(self.inputs[0].name,path) + except OSError: + return 1 +class fake_shlib(link_task): + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + return Task.SKIP_ME +class fake_stlib(stlink_task): + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + return Task.SKIP_ME +@conf +def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]): + return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib',export_includes=export_includes,export_defines=export_defines) +@conf +def read_stlib(self,name,paths=[],export_includes=[],export_defines=[]): + return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib',export_includes=export_includes,export_defines=export_defines) +lib_patterns={'shlib':['lib%s.so','%s.so','lib%s.dylib','lib%s.dll','%s.dll'],'stlib':['lib%s.a','%s.a','lib%s.dll','%s.dll','lib%s.lib','%s.lib'],} +@feature('fake_lib') +def process_lib(self): + node=None + names=[x%self.name for x in lib_patterns[self.lib_type]] + for x in self.lib_paths+[self.path]+SYSTEM_LIB_PATHS: + if not isinstance(x,Node.Node): + x=self.bld.root.find_node(x)or self.path.find_node(x) + if not x: + continue + for y in names: + node=x.find_node(y) + if node: + try: + Utils.h_file(node.abspath()) + except EnvironmentError: + raise ValueError('Could not read %r'%y) + break + else: + continue + break + else: + raise Errors.WafError('could not find library %r'%self.name) + self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node]) + self.target=self.name +class fake_o(Task.Task): + def runnable_status(self): + return Task.SKIP_ME +@extension('.o','.obj') +def add_those_o_files(self,node): + tsk=self.create_task('fake_o',[],node) + try: + self.compiled_tasks.append(tsk) + except AttributeError: + self.compiled_tasks=[tsk] +@feature('fake_obj') +@before_method('process_source') +def process_objs(self): + for node in self.to_nodes(self.source): + self.add_those_o_files(node) + self.source=[] +@conf +def read_object(self,obj): + if not isinstance(obj,self.path.__class__): + obj=self.path.find_resource(obj) + return self(features='fake_obj',source=obj,name=obj.name) +@feature('cxxprogram','cprogram') +@after_method('apply_link','process_use') +def set_full_paths_hpux(self): + if self.env.DEST_OS!='hp-ux': + return + base=self.bld.bldnode.abspath() + for var in['LIBPATH','STLIBPATH']: + lst=[] + for x in self.env[var]: + if x.startswith('/'): + lst.append(x) + else: + lst.append(os.path.normpath(os.path.join(base,x))) + self.env[var]=lst diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py new file mode 100755 index 0000000..9379f5a --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py @@ -0,0 +1,20 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.Tools import ccroot,ar,gcc +from waflib.Configure import conf +@conf +def find_clang(conf): + cc=conf.find_program('clang',var='CC') + conf.get_cc_version(cc,clang=True) + conf.env.CC_NAME='clang' +def configure(conf): + conf.find_clang() + conf.find_program(['llvm-ar','ar'],var='AR') + conf.find_ar() + conf.gcc_common_flags() + conf.gcc_modifier_platform() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py new file mode 100755 index 0000000..fc97135 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py @@ -0,0 +1,20 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.Tools import ccroot,ar,gxx +from waflib.Configure import conf +@conf +def find_clangxx(conf): + cxx=conf.find_program('clang++',var='CXX') + conf.get_cc_version(cxx,clang=True) + conf.env.CXX_NAME='clang' +def configure(conf): + conf.find_clangxx() + conf.find_program(['llvm-ar','ar'],var='AR') + conf.find_ar() + conf.gxx_common_flags() + conf.gxx_modifier_platform() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py new file mode 100755 index 0000000..ee607be --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py @@ -0,0 +1,44 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib.Tools import ccroot +from waflib import Utils +from waflib.Logs import debug +c_compiler={'win32':['msvc','gcc','clang'],'cygwin':['gcc'],'darwin':['clang','gcc'],'aix':['xlc','gcc','clang'],'linux':['gcc','clang','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'osf1V':['gcc'],'gnu':['gcc','clang'],'java':['gcc','msvc','clang','icc'],'default':['clang','gcc'],} +def default_compilers(): + build_platform=Utils.unversioned_sys_platform() + possible_compiler_list=c_compiler.get(build_platform,c_compiler['default']) + return' '.join(possible_compiler_list) +def configure(conf): + try: + test_for_compiler=conf.options.check_c_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_c')") + for compiler in re.split('[ ,]+',test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (C compiler)'%compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + debug('compiler_c: %r',e) + else: + if conf.env.CC: + conf.end_msg(conf.env.get_flat('CC')) + conf.env.COMPILER_CC=compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a C compiler!') +def options(opt): + test_for_compiler=default_compilers() + opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py']) + cc_compiler_opts=opt.add_option_group('Configuration options') + cc_compiler_opts.add_option('--check-c-compiler',default=None,help='list of C compilers to try [%s]'%test_for_compiler,dest="check_c_compiler") + for x in test_for_compiler.split(): + opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py new file mode 100755 index 0000000..cbd267f --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py @@ -0,0 +1,44 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib.Tools import ccroot +from waflib import Utils +from waflib.Logs import debug +cxx_compiler={'win32':['msvc','g++','clang++'],'cygwin':['g++'],'darwin':['clang++','g++'],'aix':['xlc++','g++','clang++'],'linux':['g++','clang++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'osf1V':['g++'],'gnu':['g++','clang++'],'java':['g++','msvc','clang++','icpc'],'default':['clang++','g++']} +def default_compilers(): + build_platform=Utils.unversioned_sys_platform() + possible_compiler_list=cxx_compiler.get(build_platform,cxx_compiler['default']) + return' '.join(possible_compiler_list) +def configure(conf): + try: + test_for_compiler=conf.options.check_cxx_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_cxx')") + for compiler in re.split('[ ,]+',test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (C++ compiler)'%compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + debug('compiler_cxx: %r',e) + else: + if conf.env.CXX: + conf.end_msg(conf.env.get_flat('CXX')) + conf.env.COMPILER_CXX=compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a C++ compiler!') +def options(opt): + test_for_compiler=default_compilers() + opt.load_special_tools('cxx_*.py') + cxx_compiler_opts=opt.add_option_group('Configuration options') + cxx_compiler_opts.add_option('--check-cxx-compiler',default=None,help='list of C++ compilers to try [%s]'%test_for_compiler,dest="check_cxx_compiler") + for x in test_for_compiler.split(): + opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py new file mode 100755 index 0000000..2ca7e26 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py @@ -0,0 +1,41 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib import Utils,Logs +d_compiler={'default':['gdc','dmd','ldc2']} +def default_compilers(): + build_platform=Utils.unversioned_sys_platform() + possible_compiler_list=d_compiler.get(build_platform,d_compiler['default']) + return' '.join(possible_compiler_list) +def configure(conf): + try: + test_for_compiler=conf.options.check_d_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_d')") + for compiler in re.split('[ ,]+',test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (D compiler)'%compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + Logs.debug('compiler_d: %r',e) + else: + if conf.env.D: + conf.end_msg(conf.env.get_flat('D')) + conf.env.COMPILER_D=compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a D compiler!') +def options(opt): + test_for_compiler=default_compilers() + d_compiler_opts=opt.add_option_group('Configuration options') + d_compiler_opts.add_option('--check-d-compiler',default=None,help='list of D compilers to try [%s]'%test_for_compiler,dest='check_d_compiler') + for x in test_for_compiler.split(): + opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py new file mode 100755 index 0000000..8b23a2b --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py @@ -0,0 +1,43 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib import Utils,Logs +from waflib.Tools import fc +fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']} +def default_compilers(): + build_platform=Utils.unversioned_sys_platform() + possible_compiler_list=fc_compiler.get(build_platform,fc_compiler['default']) + return' '.join(possible_compiler_list) +def configure(conf): + try: + test_for_compiler=conf.options.check_fortran_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_fc')") + for compiler in re.split('[ ,]+',test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (Fortran compiler)'%compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + Logs.debug('compiler_fortran: %r',e) + else: + if conf.env.FC: + conf.end_msg(conf.env.get_flat('FC')) + conf.env.COMPILER_FORTRAN=compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a Fortran compiler!') +def options(opt): + test_for_compiler=default_compilers() + opt.load_special_tools('fc_*.py') + fortran_compiler_opts=opt.add_option_group('Configuration options') + fortran_compiler_opts.add_option('--check-fortran-compiler',default=None,help='list of Fortran compiler to try [%s]'%test_for_compiler,dest="check_fortran_compiler") + for x in test_for_compiler.split(): + opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py new file mode 100755 index 0000000..df73c94 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py @@ -0,0 +1,113 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Utils,Task,Options,Errors +from waflib.TaskGen import before_method,after_method,feature +from waflib.Tools import ccroot +from waflib.Configure import conf +ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES']) +ccroot.lib_patterns['csshlib']=['%s'] +@feature('cs') +@before_method('process_source') +def apply_cs(self): + cs_nodes=[] + no_nodes=[] + for x in self.to_nodes(self.source): + if x.name.endswith('.cs'): + cs_nodes.append(x) + else: + no_nodes.append(x) + self.source=no_nodes + bintype=getattr(self,'bintype',self.gen.endswith('.dll')and'library'or'exe') + self.cs_task=tsk=self.create_task('mcs',cs_nodes,self.path.find_or_declare(self.gen)) + tsk.env.CSTYPE='/target:%s'%bintype + tsk.env.OUT='/out:%s'%tsk.outputs[0].abspath() + self.env.append_value('CSFLAGS','/platform:%s'%getattr(self,'platform','anycpu')) + inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}') + if inst_to: + mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644) + self.install_task=self.add_install_files(install_to=inst_to,install_from=self.cs_task.outputs[:],chmod=mod) +@feature('cs') +@after_method('apply_cs') +def use_cs(self): + names=self.to_list(getattr(self,'use',[])) + get=self.bld.get_tgen_by_name + for x in names: + try: + y=get(x) + except Errors.WafError: + self.env.append_value('CSFLAGS','/reference:%s'%x) + continue + y.post() + tsk=getattr(y,'cs_task',None)or getattr(y,'link_task',None) + if not tsk: + self.bld.fatal('cs task has no link task for use %r'%self) + self.cs_task.dep_nodes.extend(tsk.outputs) + self.cs_task.set_run_after(tsk) + self.env.append_value('CSFLAGS','/reference:%s'%tsk.outputs[0].abspath()) +@feature('cs') +@after_method('apply_cs','use_cs') +def debug_cs(self): + csdebug=getattr(self,'csdebug',self.env.CSDEBUG) + if not csdebug: + return + node=self.cs_task.outputs[0] + if self.env.CS_NAME=='mono': + out=node.parent.find_or_declare(node.name+'.mdb') + else: + out=node.change_ext('.pdb') + self.cs_task.outputs.append(out) + if getattr(self,'install_task',None): + self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out) + if csdebug=='pdbonly': + val=['/debug+','/debug:pdbonly'] + elif csdebug=='full': + val=['/debug+','/debug:full'] + else: + val=['/debug-'] + self.env.append_value('CSFLAGS',val) +@feature('cs') +@after_method('debug_cs') +def doc_cs(self): + csdoc=getattr(self,'csdoc',self.env.CSDOC) + if not csdoc: + return + node=self.cs_task.outputs[0] + out=node.change_ext('.xml') + self.cs_task.outputs.append(out) + if getattr(self,'install_task',None): + self.doc_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out) + self.env.append_value('CSFLAGS','/doc:%s'%out.abspath()) +class mcs(Task.Task): + color='YELLOW' + run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' + def split_argfile(self,cmd): + inline=[cmd[0]] + infile=[] + for x in cmd[1:]: + if x.lower()=='/noconfig': + inline.append(x) + else: + infile.append(self.quote_flag(x)) + return(inline,infile) +def configure(conf): + csc=getattr(Options.options,'cscbinary',None) + if csc: + conf.env.MCS=csc + conf.find_program(['csc','mcs','gmcs'],var='MCS') + conf.env.ASS_ST='/r:%s' + conf.env.RES_ST='/resource:%s' + conf.env.CS_NAME='csc' + if str(conf.env.MCS).lower().find('mcs')>-1: + conf.env.CS_NAME='mono' +def options(opt): + opt.add_option('--with-csc-binary',type='string',dest='cscbinary') +class fake_csshlib(Task.Task): + color='YELLOW' + inst_to=None + def runnable_status(self): + return Task.SKIP_ME +@conf +def read_csshlib(self,name,paths=[]): + return self(name=name,features='fake_lib',lib_paths=paths,lib_type='csshlib') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py new file mode 100755 index 0000000..e63ad8b --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py @@ -0,0 +1,26 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import TaskGen,Task +from waflib.Tools import c_preproc +from waflib.Tools.ccroot import link_task,stlink_task +@TaskGen.extension('.cpp','.cc','.cxx','.C','.c++') +def cxx_hook(self,node): + return self.create_compiled_task('cxx',node) +if not'.c'in TaskGen.task_gen.mappings: + TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp'] +class cxx(Task.Task): + run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' + vars=['CXXDEPS'] + ext_in=['.h'] + scan=c_preproc.scan +class cxxprogram(link_task): + run_str='${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' + vars=['LINKDEPS'] + ext_out=['.bin'] + inst_to='${BINDIR}' +class cxxshlib(cxxprogram): + inst_to='${LIBDIR}' +class cxxstlib(stlink_task): + pass diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py new file mode 100755 index 0000000..6d1c3c6 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Utils,Task,Errors +from waflib.TaskGen import taskgen_method,feature,extension +from waflib.Tools import d_scan,d_config +from waflib.Tools.ccroot import link_task,stlink_task +class d(Task.Task): + color='GREEN' + run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}' + scan=d_scan.scan +class d_with_header(d): + run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}' +class d_header(Task.Task): + color='BLUE' + run_str='${D} ${D_HEADER} ${SRC}' +class dprogram(link_task): + run_str='${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}' + inst_to='${BINDIR}' +class dshlib(dprogram): + inst_to='${LIBDIR}' +class dstlib(stlink_task): + pass +@extension('.d','.di','.D') +def d_hook(self,node): + ext=Utils.destos_to_binfmt(self.env.DEST_OS)=='pe'and'obj'or'o' + out='%s.%d.%s'%(node.name,self.idx,ext) + def create_compiled_task(self,name,node): + task=self.create_task(name,node,node.parent.find_or_declare(out)) + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks=[task] + return task + if getattr(self,'generate_headers',None): + tsk=create_compiled_task(self,'d_with_header',node) + tsk.outputs.append(node.change_ext(self.env.DHEADER_ext)) + else: + tsk=create_compiled_task(self,'d',node) + return tsk +@taskgen_method +def generate_header(self,filename): + try: + self.header_lst.append([filename,self.install_path]) + except AttributeError: + self.header_lst=[[filename,self.install_path]] +@feature('d') +def process_header(self): + for i in getattr(self,'header_lst',[]): + node=self.path.find_resource(i[0]) + if not node: + raise Errors.WafError('file %r not found on d obj'%i[0]) + self.create_task('d_header',node,node.change_ext('.di')) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py new file mode 100755 index 0000000..3b4bdf0 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Utils +from waflib.Configure import conf +@conf +def d_platform_flags(self): + v=self.env + if not v.DEST_OS: + v.DEST_OS=Utils.unversioned_sys_platform() + binfmt=Utils.destos_to_binfmt(self.env.DEST_OS) + if binfmt=='pe': + v.dprogram_PATTERN='%s.exe' + v.dshlib_PATTERN='lib%s.dll' + v.dstlib_PATTERN='lib%s.a' + elif binfmt=='mac-o': + v.dprogram_PATTERN='%s' + v.dshlib_PATTERN='lib%s.dylib' + v.dstlib_PATTERN='lib%s.a' + else: + v.dprogram_PATTERN='%s' + v.dshlib_PATTERN='lib%s.so' + v.dstlib_PATTERN='lib%s.a' +DLIB=''' +version(D_Version2) { + import std.stdio; + int main() { + writefln("phobos2"); + return 0; + } +} else { + version(Tango) { + import tango.stdc.stdio; + int main() { + printf("tango"); + return 0; + } + } else { + import std.stdio; + int main() { + writefln("phobos1"); + return 0; + } + } +} +''' +@conf +def check_dlibrary(self,execute=True): + ret=self.check_cc(features='d dprogram',fragment=DLIB,compile_filename='test.d',execute=execute,define_ret=True) + if execute: + self.env.DLIBRARY=ret.strip() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py new file mode 100755 index 0000000..6926671 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py @@ -0,0 +1,136 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib import Utils +def filter_comments(filename): + txt=Utils.readf(filename) + i=0 + buf=[] + max=len(txt) + begin=0 + while i-1: + conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead') + conf.load('ar') + conf.load('d') + conf.common_flags_dmd() + conf.d_platform_flags() + if str(conf.env.D).find('ldc')>-1: + conf.common_flags_ldc() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py new file mode 100755 index 0000000..f993e58 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py @@ -0,0 +1,175 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy','uses':'use',} +meths_typos=['__call__','program','shlib','stlib','objects'] +import sys +from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils +from waflib.Tools import ccroot +def check_same_targets(self): + mp=Utils.defaultdict(list) + uids={} + def check_task(tsk): + if not isinstance(tsk,Task.Task): + return + if hasattr(tsk,'no_errcheck_out'): + return + for node in tsk.outputs: + mp[node].append(tsk) + try: + uids[tsk.uid()].append(tsk) + except KeyError: + uids[tsk.uid()]=[tsk] + for g in self.groups: + for tg in g: + try: + for tsk in tg.tasks: + check_task(tsk) + except AttributeError: + check_task(tg) + dupe=False + for(k,v)in mp.items(): + if len(v)>1: + dupe=True + msg='* Node %r is created more than once%s. The task generators are:'%(k,Logs.verbose==1 and" (full message on 'waf -v -v')"or"") + Logs.error(msg) + for x in v: + if Logs.verbose>1: + Logs.error(' %d. %r',1+v.index(x),x.generator) + else: + Logs.error(' %d. %r in %r',1+v.index(x),x.generator.name,getattr(x.generator,'path',None)) + Logs.error('If you think that this is an error, set no_errcheck_out on the task instance') + if not dupe: + for(k,v)in uids.items(): + if len(v)>1: + Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid') + tg_details=tsk.generator.name + if Logs.verbose>2: + tg_details=tsk.generator + for tsk in v: + Logs.error(' - object %r (%r) defined in %r',tsk.__class__.__name__,tsk,tg_details) +def check_invalid_constraints(self): + feat=set() + for x in list(TaskGen.feats.values()): + feat.union(set(x)) + for(x,y)in TaskGen.task_gen.prec.items(): + feat.add(x) + feat.union(set(y)) + ext=set() + for x in TaskGen.task_gen.mappings.values(): + ext.add(x.__name__) + invalid=ext&feat + if invalid: + Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method',list(invalid)) + for cls in list(Task.classes.values()): + if sys.hexversion>0x3000000 and issubclass(cls,Task.Task)and isinstance(cls.hcode,str): + raise Errors.WafError('Class %r has hcode value %r of type , expecting (use Utils.h_cmd() ?)'%(cls,cls.hcode)) + for x in('before','after'): + for y in Utils.to_list(getattr(cls,x,[])): + if not Task.classes.get(y): + Logs.error('Erroneous order constraint %r=%r on task class %r',x,y,cls.__name__) + if getattr(cls,'rule',None): + Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")',cls.__name__) +def replace(m): + oldcall=getattr(Build.BuildContext,m) + def call(self,*k,**kw): + ret=oldcall(self,*k,**kw) + for x in typos: + if x in kw: + if x=='iscopy'and'subst'in getattr(self,'features',''): + continue + Logs.error('Fix the typo %r -> %r on %r',x,typos[x],ret) + return ret + setattr(Build.BuildContext,m,call) +def enhance_lib(): + for m in meths_typos: + replace(m) + def ant_glob(self,*k,**kw): + if k: + lst=Utils.to_list(k[0]) + for pat in lst: + sp=pat.split('/') + if'..'in sp: + Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'",k[0]) + if'.'in sp: + Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'",k[0]) + return self.old_ant_glob(*k,**kw) + Node.Node.old_ant_glob=Node.Node.ant_glob + Node.Node.ant_glob=ant_glob + def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False): + if remove: + try: + if self.is_child_of(self.ctx.bldnode)and not quiet: + quiet=True + Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False',self) + except AttributeError: + pass + return self.old_ant_iter(accept,maxdepth,pats,dir,src,remove,quiet) + Node.Node.old_ant_iter=Node.Node.ant_iter + Node.Node.ant_iter=ant_iter + old=Task.is_before + def is_before(t1,t2): + ret=old(t1,t2) + if ret and old(t2,t1): + Logs.error('Contradictory order constraints in classes %r %r',t1,t2) + return ret + Task.is_before=is_before + def check_err_features(self): + lst=self.to_list(self.features) + if'shlib'in lst: + Logs.error('feature shlib -> cshlib, dshlib or cxxshlib') + for x in('c','cxx','d','fc'): + if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]: + Logs.error('%r features is probably missing %r',self,x) + TaskGen.feature('*')(check_err_features) + def check_err_order(self): + if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features): + for x in('before','after','ext_in','ext_out'): + if hasattr(self,x): + Logs.warn('Erroneous order constraint %r on non-rule based task generator %r',x,self) + else: + for x in('before','after'): + for y in self.to_list(getattr(self,x,[])): + if not Task.classes.get(y): + Logs.error('Erroneous order constraint %s=%r on %r (no such class)',x,y,self) + TaskGen.feature('*')(check_err_order) + def check_compile(self): + check_invalid_constraints(self) + try: + ret=self.orig_compile() + finally: + check_same_targets(self) + return ret + Build.BuildContext.orig_compile=Build.BuildContext.compile + Build.BuildContext.compile=check_compile + def use_rec(self,name,**kw): + try: + y=self.bld.get_tgen_by_name(name) + except Errors.WafError: + pass + else: + idx=self.bld.get_group_idx(self) + odx=self.bld.get_group_idx(y) + if odx>idx: + msg="Invalid 'use' across build groups:" + if Logs.verbose>1: + msg+='\n target %r\n uses:\n %r'%(self,y) + else: + msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name) + raise Errors.WafError(msg) + self.orig_use_rec(name,**kw) + TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec + TaskGen.task_gen.use_rec=use_rec + def _getattr(self,name,default=None): + if name=='append'or name=='add': + raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique') + elif name=='prepend': + raise Errors.WafError('env.prepend does not exist: use env.prepend_value') + if name in self.__slots__: + return super(ConfigSet.ConfigSet,self).__getattr__(name,default) + else: + return self[name] + ConfigSet.ConfigSet.__getattr__=_getattr +def options(opt): + enhance_lib() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py new file mode 100755 index 0000000..64c479d --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py @@ -0,0 +1,118 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Utils,Task,Errors +from waflib.Tools import ccroot,fc_config,fc_scan +from waflib.TaskGen import extension +from waflib.Configure import conf +ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES','FCPPFLAGS']) +ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) +ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) +ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS']) +@extension('.f','.F','.f90','.F90','.for','.FOR','.f95','.F95','.f03','.F03','.f08','.F08') +def fc_hook(self,node): + return self.create_compiled_task('fc',node) +@conf +def modfile(conf,name): + if name.find(':')>=0: + separator=conf.env.FC_SUBMOD_SEPARATOR or'@' + modpath=name.split(':') + modname=modpath[0]+separator+modpath[-1] + suffix=conf.env.FC_SUBMOD_SUFFIX or'.smod' + else: + modname=name + suffix='.mod' + return{'lower':modname.lower()+suffix.lower(),'lower.MOD':modname.lower()+suffix.upper(),'UPPER.mod':modname.upper()+suffix.lower(),'UPPER':modname.upper()+suffix.upper()}[conf.env.FC_MOD_CAPITALIZATION or'lower'] +def get_fortran_tasks(tsk): + bld=tsk.generator.bld + tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator)) + return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)] +class fc(Task.Task): + color='GREEN' + run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()} ${FCPPFLAGS}' + vars=["FORTRANMODPATHFLAG"] + def scan(self): + tmp=fc_scan.fortran_parser(self.generator.includes_nodes) + tmp.task=self + tmp.start(self.inputs[0]) + return(tmp.nodes,tmp.names) + def runnable_status(self): + if getattr(self,'mod_fortran_done',None): + return super(fc,self).runnable_status() + bld=self.generator.bld + lst=get_fortran_tasks(self) + for tsk in lst: + tsk.mod_fortran_done=True + for tsk in lst: + ret=tsk.runnable_status() + if ret==Task.ASK_LATER: + for x in lst: + x.mod_fortran_done=None + return Task.ASK_LATER + ins=Utils.defaultdict(set) + outs=Utils.defaultdict(set) + for tsk in lst: + key=tsk.uid() + for x in bld.raw_deps[key]: + if x.startswith('MOD@'): + name=bld.modfile(x.replace('MOD@','')) + node=bld.srcnode.find_or_declare(name) + tsk.set_outputs(node) + outs[node].add(tsk) + for tsk in lst: + key=tsk.uid() + for x in bld.raw_deps[key]: + if x.startswith('USE@'): + name=bld.modfile(x.replace('USE@','')) + node=bld.srcnode.find_resource(name) + if node and node not in tsk.outputs: + if not node in bld.node_deps[key]: + bld.node_deps[key].append(node) + ins[node].add(tsk) + for k in ins.keys(): + for a in ins[k]: + a.run_after.update(outs[k]) + for x in outs[k]: + self.generator.bld.producer.revdeps[x].add(a) + tmp=[] + for t in outs[k]: + tmp.extend(t.outputs) + a.dep_nodes.extend(tmp) + a.dep_nodes.sort(key=lambda x:x.abspath()) + for tsk in lst: + try: + delattr(tsk,'cache_sig') + except AttributeError: + pass + return super(fc,self).runnable_status() +class fcprogram(ccroot.link_task): + color='YELLOW' + run_str='${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB} ${LDFLAGS}' + inst_to='${BINDIR}' +class fcshlib(fcprogram): + inst_to='${LIBDIR}' +class fcstlib(ccroot.stlink_task): + pass +class fcprogram_test(fcprogram): + def runnable_status(self): + ret=super(fcprogram_test,self).runnable_status() + if ret==Task.SKIP_ME: + ret=Task.RUN_ME + return ret + def exec_command(self,cmd,**kw): + bld=self.generator.bld + kw['shell']=isinstance(cmd,str) + kw['stdout']=kw['stderr']=Utils.subprocess.PIPE + kw['cwd']=self.get_cwd() + bld.out=bld.err='' + bld.to_log('command: %s\n'%cmd) + kw['output']=0 + try: + (bld.out,bld.err)=bld.cmd_and_log(cmd,**kw) + except Errors.WafError: + return-1 + if bld.out: + bld.to_log('out: %s\n'%bld.out) + if bld.err: + bld.to_log('err: %s\n'%bld.err) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py new file mode 100755 index 0000000..8714276 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py @@ -0,0 +1,299 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re,os,sys,shlex +from waflib.Configure import conf +from waflib.TaskGen import feature,before_method +FC_FRAGMENT=' program main\n end program main\n' +FC_FRAGMENT2=' PROGRAM MAIN\n END\n' +@conf +def fc_flags(conf): + v=conf.env + v.FC_SRC_F=[] + v.FC_TGT_F=['-c','-o'] + v.FCINCPATH_ST='-I%s' + v.FCDEFINES_ST='-D%s' + if not v.LINK_FC: + v.LINK_FC=v.FC + v.FCLNK_SRC_F=[] + v.FCLNK_TGT_F=['-o'] + v.FCFLAGS_fcshlib=['-fpic'] + v.LINKFLAGS_fcshlib=['-shared'] + v.fcshlib_PATTERN='lib%s.so' + v.fcstlib_PATTERN='lib%s.a' + v.FCLIB_ST='-l%s' + v.FCLIBPATH_ST='-L%s' + v.FCSTLIB_ST='-l%s' + v.FCSTLIBPATH_ST='-L%s' + v.FCSTLIB_MARKER='-Wl,-Bstatic' + v.FCSHLIB_MARKER='-Wl,-Bdynamic' + v.SONAME_ST='-Wl,-h,%s' +@conf +def fc_add_flags(conf): + conf.add_os_flags('FCPPFLAGS',dup=False) + conf.add_os_flags('FCFLAGS',dup=False) + conf.add_os_flags('LINKFLAGS',dup=False) + conf.add_os_flags('LDFLAGS',dup=False) +@conf +def check_fortran(self,*k,**kw): + self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app') +@conf +def check_fc(self,*k,**kw): + kw['compiler']='fc' + if not'compile_mode'in kw: + kw['compile_mode']='fc' + if not'type'in kw: + kw['type']='fcprogram' + if not'compile_filename'in kw: + kw['compile_filename']='test.f90' + if not'code'in kw: + kw['code']=FC_FRAGMENT + return self.check(*k,**kw) +@conf +def fortran_modifier_darwin(conf): + v=conf.env + v.FCFLAGS_fcshlib=['-fPIC'] + v.LINKFLAGS_fcshlib=['-dynamiclib'] + v.fcshlib_PATTERN='lib%s.dylib' + v.FRAMEWORKPATH_ST='-F%s' + v.FRAMEWORK_ST=['-framework'] + v.LINKFLAGS_fcstlib=[] + v.FCSHLIB_MARKER='' + v.FCSTLIB_MARKER='' + v.SONAME_ST='' +@conf +def fortran_modifier_win32(conf): + v=conf.env + v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe' + v.fcshlib_PATTERN='%s.dll' + v.implib_PATTERN='%s.dll.a' + v.IMPLIB_ST='-Wl,--out-implib,%s' + v.FCFLAGS_fcshlib=[] + v.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) +@conf +def fortran_modifier_cygwin(conf): + fortran_modifier_win32(conf) + v=conf.env + v.fcshlib_PATTERN='cyg%s.dll' + v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base']) + v.FCFLAGS_fcshlib=[] +@conf +def check_fortran_dummy_main(self,*k,**kw): + if not self.env.CC: + self.fatal('A c compiler is required for check_fortran_dummy_main') + lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN'] + lst.extend([m.lower()for m in lst]) + lst.append('') + self.start_msg('Detecting whether we need a dummy main') + for main in lst: + kw['fortran_main']=main + try: + self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True) + if not main: + self.env.FC_MAIN=-1 + self.end_msg('no') + else: + self.env.FC_MAIN=main + self.end_msg('yes %s'%main) + break + except self.errors.ConfigurationError: + pass + else: + self.end_msg('not found') + self.fatal('could not detect whether fortran requires a dummy main, see the config.log') +GCC_DRIVER_LINE=re.compile('^Driving:') +POSIX_STATIC_EXT=re.compile(r'\S+\.a') +POSIX_LIB_FLAGS=re.compile(r'-l\S+') +@conf +def is_link_verbose(self,txt): + assert isinstance(txt,str) + for line in txt.splitlines(): + if not GCC_DRIVER_LINE.search(line): + if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line): + return True + return False +@conf +def check_fortran_verbose_flag(self,*k,**kw): + self.start_msg('fortran link verbose flag') + for x in('-v','--verbose','-verbose','-V'): + try: + self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True) + except self.errors.ConfigurationError: + pass + else: + if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out): + self.end_msg(x) + break + else: + self.end_msg('failure') + self.fatal('Could not obtain the fortran link verbose flag (see config.log)') + self.env.FC_VERBOSE_FLAG=x + return x +LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*'] +if os.name=='nt': + LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname']) +else: + LINKFLAGS_IGNORED.append(r'-lgcc*') +RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED] +def _match_ignore(line): + for i in RLINKFLAGS_IGNORED: + if i.match(line): + return True + return False +def parse_fortran_link(lines): + final_flags=[] + for line in lines: + if not GCC_DRIVER_LINE.match(line): + _parse_flink_line(line,final_flags) + return final_flags +SPACE_OPTS=re.compile('^-[LRuYz]$') +NOSPACE_OPTS=re.compile('^-[RL]') +def _parse_flink_token(lexer,token,tmp_flags): + if _match_ignore(token): + pass + elif token.startswith('-lkernel32')and sys.platform=='cygwin': + tmp_flags.append(token) + elif SPACE_OPTS.match(token): + t=lexer.get_token() + if t.startswith('P,'): + t=t[2:] + for opt in t.split(os.pathsep): + tmp_flags.append('-L%s'%opt) + elif NOSPACE_OPTS.match(token): + tmp_flags.append(token) + elif POSIX_LIB_FLAGS.match(token): + tmp_flags.append(token) + else: + pass + t=lexer.get_token() + return t +def _parse_flink_line(line,final_flags): + lexer=shlex.shlex(line,posix=True) + lexer.whitespace_split=True + t=lexer.get_token() + tmp_flags=[] + while t: + t=_parse_flink_token(lexer,t,tmp_flags) + final_flags.extend(tmp_flags) + return final_flags +@conf +def check_fortran_clib(self,autoadd=True,*k,**kw): + if not self.env.FC_VERBOSE_FLAG: + self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?') + self.start_msg('Getting fortran runtime link flags') + try: + self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG]) + except Exception: + self.end_msg(False) + if kw.get('mandatory',True): + conf.fatal('Could not find the c library flags') + else: + out=self.test_bld.err + flags=parse_fortran_link(out.splitlines()) + self.end_msg('ok (%s)'%' '.join(flags)) + self.env.LINKFLAGS_CLIB=flags + return flags + return[] +def getoutput(conf,cmd,stdin=False): + from waflib import Errors + if conf.env.env: + env=conf.env.env + else: + env=dict(os.environ) + env['LANG']='C' + input=stdin and'\n'.encode()or None + try: + out,err=conf.cmd_and_log(cmd,env=env,output=0,input=input) + except Errors.WafError as e: + if not(hasattr(e,'stderr')and hasattr(e,'stdout')): + raise e + else: + out=e.stdout + err=e.stderr + except Exception: + conf.fatal('could not determine the compiler version %r'%cmd) + return(out,err) +ROUTINES_CODE="""\ + subroutine foobar() + return + end + subroutine foo_bar() + return + end +""" +MAIN_CODE=""" +void %(dummy_func_nounder)s(void); +void %(dummy_func_under)s(void); +int %(main_func_name)s() { + %(dummy_func_nounder)s(); + %(dummy_func_under)s(); + return 0; +} +""" +@feature('link_main_routines_func') +@before_method('process_source') +def link_main_routines_tg_method(self): + def write_test_file(task): + task.outputs[0].write(task.generator.code) + bld=self.bld + bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__) + bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE) + bld(features='fc fcstlib',source='test.f',target='test') + bld(features='c fcprogram',source='main.c',target='app',use='test') +def mangling_schemes(): + for u in('_',''): + for du in('','_'): + for c in("lower","upper"): + yield(u,du,c) +def mangle_name(u,du,c,name): + return getattr(name,c)()+u+(name.find('_')!=-1 and du or'') +@conf +def check_fortran_mangling(self,*k,**kw): + if not self.env.CC: + self.fatal('A c compiler is required for link_main_routines') + if not self.env.FC: + self.fatal('A fortran compiler is required for link_main_routines') + if not self.env.FC_MAIN: + self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)') + self.start_msg('Getting fortran mangling scheme') + for(u,du,c)in mangling_schemes(): + try: + self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',dummy_func_nounder=mangle_name(u,du,c,'foobar'),dummy_func_under=mangle_name(u,du,c,'foo_bar'),main_func_name=self.env.FC_MAIN) + except self.errors.ConfigurationError: + pass + else: + self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c)) + self.env.FORTRAN_MANGLING=(u,du,c) + break + else: + self.end_msg(False) + self.fatal('mangler not found') + return(u,du,c) +@feature('pyext') +@before_method('propagate_uselib_vars','apply_link') +def set_lib_pat(self): + self.env.fcshlib_PATTERN=self.env.pyext_PATTERN +@conf +def detect_openmp(self): + for x in('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'): + try: + self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP') + except self.errors.ConfigurationError: + pass + else: + break + else: + self.fatal('Could not find OpenMP') +@conf +def check_gfortran_o_space(self): + if self.env.FC_NAME!='GFORTRAN'or int(self.env.FC_VERSION[0])>4: + return + self.env.stash() + self.env.FCLNK_TGT_F=['-o',''] + try: + self.check_fc(msg='Checking if the -o link must be split from arguments',fragment=FC_FRAGMENT,features='fc fcshlib') + except self.errors.ConfigurationError: + self.env.revert() + else: + self.env.commit() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py new file mode 100755 index 0000000..76921fc --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py @@ -0,0 +1,70 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +INC_REGEX=r"""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])""" +USE_REGEX=r"""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)""" +MOD_REGEX=r"""(?:^|;)\s*MODULE(?!\s+(?:PROCEDURE|SUBROUTINE|FUNCTION))\s+(\w+)""" +SMD_REGEX=r"""(?:^|;)\s*SUBMODULE\s*\(([\w:]+)\)\s*(\w+)""" +re_inc=re.compile(INC_REGEX,re.I) +re_use=re.compile(USE_REGEX,re.I) +re_mod=re.compile(MOD_REGEX,re.I) +re_smd=re.compile(SMD_REGEX,re.I) +class fortran_parser(object): + def __init__(self,incpaths): + self.seen=[] + self.nodes=[] + self.names=[] + self.incpaths=incpaths + def find_deps(self,node): + txt=node.read() + incs=[] + uses=[] + mods=[] + for line in txt.splitlines(): + m=re_inc.search(line) + if m: + incs.append(m.group(1)) + m=re_use.search(line) + if m: + uses.append(m.group(1)) + m=re_mod.search(line) + if m: + mods.append(m.group(1)) + m=re_smd.search(line) + if m: + uses.append(m.group(1)) + mods.append('{0}:{1}'.format(m.group(1),m.group(2))) + return(incs,uses,mods) + def start(self,node): + self.waiting=[node] + while self.waiting: + nd=self.waiting.pop(0) + self.iter(nd) + def iter(self,node): + incs,uses,mods=self.find_deps(node) + for x in incs: + if x in self.seen: + continue + self.seen.append(x) + self.tryfind_header(x) + for x in uses: + name="USE@%s"%x + if not name in self.names: + self.names.append(name) + for x in mods: + name="MOD@%s"%x + if not name in self.names: + self.names.append(name) + def tryfind_header(self,filename): + found=None + for n in self.incpaths: + found=n.find_resource(filename) + if found: + self.nodes.append(found) + self.waiting.append(found) + break + if not found: + if not filename in self.names: + self.names.append(filename) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py new file mode 100755 index 0000000..1f1620e --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py @@ -0,0 +1,38 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re +from waflib import Task,TaskGen +from waflib.Tools import ccroot +def decide_ext(self,node): + if'cxx'in self.features: + return['.lex.cc'] + return['.lex.c'] +def flexfun(tsk): + env=tsk.env + bld=tsk.generator.bld + wd=bld.variant_dir + def to_list(xx): + if isinstance(xx,str): + return[xx] + return xx + tsk.last_cmd=lst=[] + lst.extend(to_list(env.FLEX)) + lst.extend(to_list(env.FLEXFLAGS)) + inputs=[a.path_from(tsk.get_cwd())for a in tsk.inputs] + if env.FLEX_MSYS: + inputs=[x.replace(os.sep,'/')for x in inputs] + lst.extend(inputs) + lst=[x for x in lst if x] + txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0) + tsk.outputs[0].write(txt.replace('\r\n','\n').replace('\r','\n')) +TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,) +Task.classes['flex'].vars=['FLEXFLAGS','FLEX'] +ccroot.USELIB_VARS['c'].add('FLEXFLAGS') +ccroot.USELIB_VARS['cxx'].add('FLEXFLAGS') +def configure(conf): + conf.find_program('flex',var='FLEX') + conf.env.FLEXFLAGS=['-t'] + if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX[0]): + conf.env.FLEX_MSYS=True diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py new file mode 100755 index 0000000..b62adcd --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib import Utils +from waflib.Tools import fc,fc_config,fc_scan,ar +from waflib.Configure import conf +@conf +def find_g95(conf): + fc=conf.find_program('g95',var='FC') + conf.get_g95_version(fc) + conf.env.FC_NAME='G95' +@conf +def g95_flags(conf): + v=conf.env + v.FCFLAGS_fcshlib=['-fPIC'] + v.FORTRANMODFLAG=['-fmod=',''] + v.FCFLAGS_DEBUG=['-Werror'] +@conf +def g95_modifier_win32(conf): + fc_config.fortran_modifier_win32(conf) +@conf +def g95_modifier_cygwin(conf): + fc_config.fortran_modifier_cygwin(conf) +@conf +def g95_modifier_darwin(conf): + fc_config.fortran_modifier_darwin(conf) +@conf +def g95_modifier_platform(conf): + dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform() + g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None) + if g95_modifier_func: + g95_modifier_func() +@conf +def get_g95_version(conf,fc): + version_re=re.compile(r"g95\s*(?P\d*)\.(?P\d*)").search + cmd=fc+['--version'] + out,err=fc_config.getoutput(conf,cmd,stdin=False) + if out: + match=version_re(out) + else: + match=version_re(err) + if not match: + conf.fatal('cannot determine g95 version') + k=match.groupdict() + conf.env.FC_VERSION=(k['major'],k['minor']) +def configure(conf): + conf.find_g95() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.g95_flags() + conf.g95_modifier_platform() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py new file mode 100755 index 0000000..654d37f --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py @@ -0,0 +1,13 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import waflib.Tools.asm +from waflib.Tools import ar +def configure(conf): + conf.find_program(['gas','gcc'],var='AS') + conf.env.AS_TGT_F=['-c','-o'] + conf.env.ASLNK_TGT_F=['-o'] + conf.find_ar() + conf.load('asm') + conf.env.ASM_NAME='gas' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py new file mode 100755 index 0000000..12afcc6 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py @@ -0,0 +1,104 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.Tools import ccroot,ar +from waflib.Configure import conf +@conf +def find_gcc(conf): + cc=conf.find_program(['gcc','cc'],var='CC') + conf.get_cc_version(cc,gcc=True) + conf.env.CC_NAME='gcc' +@conf +def gcc_common_flags(conf): + v=conf.env + v.CC_SRC_F=[] + v.CC_TGT_F=['-c','-o'] + if not v.LINK_CC: + v.LINK_CC=v.CC + v.CCLNK_SRC_F=[] + v.CCLNK_TGT_F=['-o'] + v.CPPPATH_ST='-I%s' + v.DEFINES_ST='-D%s' + v.LIB_ST='-l%s' + v.LIBPATH_ST='-L%s' + v.STLIB_ST='-l%s' + v.STLIBPATH_ST='-L%s' + v.RPATH_ST='-Wl,-rpath,%s' + v.SONAME_ST='-Wl,-h,%s' + v.SHLIB_MARKER='-Wl,-Bdynamic' + v.STLIB_MARKER='-Wl,-Bstatic' + v.cprogram_PATTERN='%s' + v.CFLAGS_cshlib=['-fPIC'] + v.LINKFLAGS_cshlib=['-shared'] + v.cshlib_PATTERN='lib%s.so' + v.LINKFLAGS_cstlib=['-Wl,-Bstatic'] + v.cstlib_PATTERN='lib%s.a' + v.LINKFLAGS_MACBUNDLE=['-bundle','-undefined','dynamic_lookup'] + v.CFLAGS_MACBUNDLE=['-fPIC'] + v.macbundle_PATTERN='%s.bundle' +@conf +def gcc_modifier_win32(conf): + v=conf.env + v.cprogram_PATTERN='%s.exe' + v.cshlib_PATTERN='%s.dll' + v.implib_PATTERN='%s.dll.a' + v.IMPLIB_ST='-Wl,--out-implib,%s' + v.CFLAGS_cshlib=[] + v.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) +@conf +def gcc_modifier_cygwin(conf): + gcc_modifier_win32(conf) + v=conf.env + v.cshlib_PATTERN='cyg%s.dll' + v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base']) + v.CFLAGS_cshlib=[] +@conf +def gcc_modifier_darwin(conf): + v=conf.env + v.CFLAGS_cshlib=['-fPIC'] + v.LINKFLAGS_cshlib=['-dynamiclib'] + v.cshlib_PATTERN='lib%s.dylib' + v.FRAMEWORKPATH_ST='-F%s' + v.FRAMEWORK_ST=['-framework'] + v.ARCH_ST=['-arch'] + v.LINKFLAGS_cstlib=[] + v.SHLIB_MARKER=[] + v.STLIB_MARKER=[] + v.SONAME_ST=[] +@conf +def gcc_modifier_aix(conf): + v=conf.env + v.LINKFLAGS_cprogram=['-Wl,-brtl'] + v.LINKFLAGS_cshlib=['-shared','-Wl,-brtl,-bexpfull'] + v.SHLIB_MARKER=[] +@conf +def gcc_modifier_hpux(conf): + v=conf.env + v.SHLIB_MARKER=[] + v.STLIB_MARKER=[] + v.CFLAGS_cshlib=['-fPIC','-DPIC'] + v.cshlib_PATTERN='lib%s.sl' +@conf +def gcc_modifier_openbsd(conf): + conf.env.SONAME_ST=[] +@conf +def gcc_modifier_osf1V(conf): + v=conf.env + v.SHLIB_MARKER=[] + v.STLIB_MARKER=[] + v.SONAME_ST=[] +@conf +def gcc_modifier_platform(conf): + gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None) + if gcc_modifier_func: + gcc_modifier_func() +def configure(conf): + conf.find_gcc() + conf.find_ar() + conf.gcc_common_flags() + conf.gcc_modifier_platform() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + conf.check_gcc_o_space() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py new file mode 100755 index 0000000..c809930 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py @@ -0,0 +1,35 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.Tools import ar,d +from waflib.Configure import conf +@conf +def find_gdc(conf): + conf.find_program('gdc',var='D') + out=conf.cmd_and_log(conf.env.D+['--version']) + if out.find("gdc")==-1: + conf.fatal("detected compiler is not gdc") +@conf +def common_flags_gdc(conf): + v=conf.env + v.DFLAGS=[] + v.D_SRC_F=['-c'] + v.D_TGT_F='-o%s' + v.D_LINKER=v.D + v.DLNK_SRC_F='' + v.DLNK_TGT_F='-o%s' + v.DINC_ST='-I%s' + v.DSHLIB_MARKER=v.DSTLIB_MARKER='' + v.DSTLIB_ST=v.DSHLIB_ST='-l%s' + v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L%s' + v.LINKFLAGS_dshlib=['-shared'] + v.DHEADER_ext='.di' + v.DFLAGS_d_with_header='-fintfc' + v.D_HDR_F='-fintfc-file=%s' +def configure(conf): + conf.find_gdc() + conf.load('ar') + conf.load('d') + conf.common_flags_gdc() + conf.d_platform_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py new file mode 100755 index 0000000..47d005a --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py @@ -0,0 +1,71 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib import Utils +from waflib.Tools import fc,fc_config,fc_scan,ar +from waflib.Configure import conf +@conf +def find_gfortran(conf): + fc=conf.find_program(['gfortran','g77'],var='FC') + conf.get_gfortran_version(fc) + conf.env.FC_NAME='GFORTRAN' +@conf +def gfortran_flags(conf): + v=conf.env + v.FCFLAGS_fcshlib=['-fPIC'] + v.FORTRANMODFLAG=['-J',''] + v.FCFLAGS_DEBUG=['-Werror'] +@conf +def gfortran_modifier_win32(conf): + fc_config.fortran_modifier_win32(conf) +@conf +def gfortran_modifier_cygwin(conf): + fc_config.fortran_modifier_cygwin(conf) +@conf +def gfortran_modifier_darwin(conf): + fc_config.fortran_modifier_darwin(conf) +@conf +def gfortran_modifier_platform(conf): + dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform() + gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None) + if gfortran_modifier_func: + gfortran_modifier_func() +@conf +def get_gfortran_version(conf,fc): + version_re=re.compile(r"GNU\s*Fortran",re.I).search + cmd=fc+['--version'] + out,err=fc_config.getoutput(conf,cmd,stdin=False) + if out: + match=version_re(out) + else: + match=version_re(err) + if not match: + conf.fatal('Could not determine the compiler type') + cmd=fc+['-dM','-E','-'] + out,err=fc_config.getoutput(conf,cmd,stdin=True) + if out.find('__GNUC__')<0: + conf.fatal('Could not determine the compiler type') + k={} + out=out.splitlines() + import shlex + for line in out: + lst=shlex.split(line) + if len(lst)>2: + key=lst[1] + val=lst[2] + k[key]=val + def isD(var): + return var in k + def isT(var): + return var in k and k[var]!='0' + conf.env.FC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__']) +def configure(conf): + conf.find_gfortran() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.gfortran_flags() + conf.gfortran_modifier_platform() + conf.check_gfortran_o_space() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py new file mode 100755 index 0000000..ba5a71e --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py @@ -0,0 +1,242 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os +import functools +from waflib import Context,Task,Utils,Options,Errors,Logs +from waflib.TaskGen import taskgen_method,before_method,feature,extension +from waflib.Configure import conf +@taskgen_method +def add_marshal_file(self,filename,prefix): + if not hasattr(self,'marshal_list'): + self.marshal_list=[] + self.meths.append('process_marshal') + self.marshal_list.append((filename,prefix)) +@before_method('process_source') +def process_marshal(self): + for f,prefix in getattr(self,'marshal_list',[]): + node=self.path.find_resource(f) + if not node: + raise Errors.WafError('file not found %r'%f) + h_node=node.change_ext('.h') + c_node=node.change_ext('.c') + task=self.create_task('glib_genmarshal',node,[h_node,c_node]) + task.env.GLIB_GENMARSHAL_PREFIX=prefix + self.source=self.to_nodes(getattr(self,'source',[])) + self.source.append(c_node) +class glib_genmarshal(Task.Task): + vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL'] + color='BLUE' + ext_out=['.h'] + def run(self): + bld=self.generator.bld + get=self.env.get_flat + cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath()) + ret=bld.exec_command(cmd1) + if ret: + return ret + c='''#include "%s"\n'''%self.outputs[0].name + self.outputs[1].write(c) + cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath()) + return bld.exec_command(cmd2) +@taskgen_method +def add_enums_from_template(self,source='',target='',template='',comments=''): + if not hasattr(self,'enums_list'): + self.enums_list=[] + self.meths.append('process_enums') + self.enums_list.append({'source':source,'target':target,'template':template,'file-head':'','file-prod':'','file-tail':'','enum-prod':'','value-head':'','value-prod':'','value-tail':'','comments':comments}) +@taskgen_method +def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''): + if not hasattr(self,'enums_list'): + self.enums_list=[] + self.meths.append('process_enums') + self.enums_list.append({'source':source,'template':'','target':target,'file-head':file_head,'file-prod':file_prod,'file-tail':file_tail,'enum-prod':enum_prod,'value-head':value_head,'value-prod':value_prod,'value-tail':value_tail,'comments':comments}) +@before_method('process_source') +def process_enums(self): + for enum in getattr(self,'enums_list',[]): + task=self.create_task('glib_mkenums') + env=task.env + inputs=[] + source_list=self.to_list(enum['source']) + if not source_list: + raise Errors.WafError('missing source '+str(enum)) + source_list=[self.path.find_resource(k)for k in source_list] + inputs+=source_list + env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list] + if not enum['target']: + raise Errors.WafError('missing target '+str(enum)) + tgt_node=self.path.find_or_declare(enum['target']) + if tgt_node.name.endswith('.c'): + self.source.append(tgt_node) + env.GLIB_MKENUMS_TARGET=tgt_node.abspath() + options=[] + if enum['template']: + template_node=self.path.find_resource(enum['template']) + options.append('--template %s'%(template_node.abspath())) + inputs.append(template_node) + params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'} + for param,option in params.items(): + if enum[param]: + options.append('%s %r'%(option,enum[param])) + env.GLIB_MKENUMS_OPTIONS=' '.join(options) + task.set_inputs(inputs) + task.set_outputs(tgt_node) +class glib_mkenums(Task.Task): + run_str='${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}' + color='PINK' + ext_out=['.h'] +@taskgen_method +def add_settings_schemas(self,filename_list): + if not hasattr(self,'settings_schema_files'): + self.settings_schema_files=[] + if not isinstance(filename_list,list): + filename_list=[filename_list] + self.settings_schema_files.extend(filename_list) +@taskgen_method +def add_settings_enums(self,namespace,filename_list): + if hasattr(self,'settings_enum_namespace'): + raise Errors.WafError("Tried to add gsettings enums to %r more than once"%self.name) + self.settings_enum_namespace=namespace + if not isinstance(filename_list,list): + filename_list=[filename_list] + self.settings_enum_files=filename_list +@feature('glib2') +def process_settings(self): + enums_tgt_node=[] + install_files=[] + settings_schema_files=getattr(self,'settings_schema_files',[]) + if settings_schema_files and not self.env.GLIB_COMPILE_SCHEMAS: + raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure") + if hasattr(self,'settings_enum_files'): + enums_task=self.create_task('glib_mkenums') + source_list=self.settings_enum_files + source_list=[self.path.find_resource(k)for k in source_list] + enums_task.set_inputs(source_list) + enums_task.env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list] + target=self.settings_enum_namespace+'.enums.xml' + tgt_node=self.path.find_or_declare(target) + enums_task.set_outputs(tgt_node) + enums_task.env.GLIB_MKENUMS_TARGET=tgt_node.abspath() + enums_tgt_node=[tgt_node] + install_files.append(tgt_node) + options='--comments "" --fhead "" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " " --vtail " " --ftail "" '%(self.settings_enum_namespace) + enums_task.env.GLIB_MKENUMS_OPTIONS=options + for schema in settings_schema_files: + schema_task=self.create_task('glib_validate_schema') + schema_node=self.path.find_resource(schema) + if not schema_node: + raise Errors.WafError("Cannot find the schema file %r"%schema) + install_files.append(schema_node) + source_list=enums_tgt_node+[schema_node] + schema_task.set_inputs(source_list) + schema_task.env.GLIB_COMPILE_SCHEMAS_OPTIONS=[("--schema-file="+k.abspath())for k in source_list] + target_node=schema_node.change_ext('.xml.valid') + schema_task.set_outputs(target_node) + schema_task.env.GLIB_VALIDATE_SCHEMA_OUTPUT=target_node.abspath() + def compile_schemas_callback(bld): + if not bld.is_install: + return + compile_schemas=Utils.to_list(bld.env.GLIB_COMPILE_SCHEMAS) + destdir=Options.options.destdir + paths=bld._compile_schemas_registered + if destdir: + paths=(os.path.join(destdir,path.lstrip(os.sep))for path in paths) + for path in paths: + Logs.pprint('YELLOW','Updating GSettings schema cache %r'%path) + if self.bld.exec_command(compile_schemas+[path]): + Logs.warn('Could not update GSettings schema cache %r'%path) + if self.bld.is_install: + schemadir=self.env.GSETTINGSSCHEMADIR + if not schemadir: + raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)') + if install_files: + self.add_install_files(install_to=schemadir,install_from=install_files) + registered_schemas=getattr(self.bld,'_compile_schemas_registered',None) + if not registered_schemas: + registered_schemas=self.bld._compile_schemas_registered=set() + self.bld.add_post_fun(compile_schemas_callback) + registered_schemas.add(schemadir) +class glib_validate_schema(Task.Task): + run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}' + color='PINK' +@extension('.gresource.xml') +def process_gresource_source(self,node): + if not self.env.GLIB_COMPILE_RESOURCES: + raise Errors.WafError("Unable to process GResource file - glib-compile-resources was not found during configure") + if'gresource'in self.features: + return + h_node=node.change_ext('_xml.h') + c_node=node.change_ext('_xml.c') + self.create_task('glib_gresource_source',node,[h_node,c_node]) + self.source.append(c_node) +@feature('gresource') +def process_gresource_bundle(self): + for i in self.to_list(self.source): + node=self.path.find_resource(i) + task=self.create_task('glib_gresource_bundle',node,node.change_ext('')) + inst_to=getattr(self,'install_path',None) + if inst_to: + self.add_install_files(install_to=inst_to,install_from=task.outputs) +class glib_gresource_base(Task.Task): + color='BLUE' + base_cmd='${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}' + def scan(self): + bld=self.generator.bld + kw={} + kw['cwd']=self.get_cwd() + kw['quiet']=Context.BOTH + cmd=Utils.subst_vars('${GLIB_COMPILE_RESOURCES} --sourcedir=%s --sourcedir=%s --generate-dependencies %s'%(self.inputs[0].parent.srcpath(),self.inputs[0].bld_dir(),self.inputs[0].bldpath()),self.env) + output=bld.cmd_and_log(cmd,**kw) + nodes=[] + names=[] + for dep in output.splitlines(): + if dep: + node=bld.bldnode.find_node(dep) + if node: + nodes.append(node) + else: + names.append(dep) + return(nodes,names) +class glib_gresource_source(glib_gresource_base): + vars=['GLIB_COMPILE_RESOURCES'] + fun_h=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[0].abspath()} --generate-header ${SRC}') + fun_c=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[1].abspath()} --generate-source ${SRC}') + ext_out=['.h'] + def run(self): + return self.fun_h[0](self)or self.fun_c[0](self) +class glib_gresource_bundle(glib_gresource_base): + run_str=glib_gresource_base.base_cmd+' --target=${TGT} ${SRC}' + shell=True +@conf +def find_glib_genmarshal(conf): + conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL') +@conf +def find_glib_mkenums(conf): + if not conf.env.PERL: + conf.find_program('perl',var='PERL') + conf.find_program('glib-mkenums',interpreter='PERL',var='GLIB_MKENUMS') +@conf +def find_glib_compile_schemas(conf): + conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS') + def getstr(varname): + return getattr(Options.options,varname,getattr(conf.env,varname,'')) + gsettingsschemadir=getstr('GSETTINGSSCHEMADIR') + if not gsettingsschemadir: + datadir=getstr('DATADIR') + if not datadir: + prefix=conf.env.PREFIX + datadir=os.path.join(prefix,'share') + gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas') + conf.env.GSETTINGSSCHEMADIR=gsettingsschemadir +@conf +def find_glib_compile_resources(conf): + conf.find_program('glib-compile-resources',var='GLIB_COMPILE_RESOURCES') +def configure(conf): + conf.find_glib_genmarshal() + conf.find_glib_mkenums() + conf.find_glib_compile_schemas(mandatory=False) + conf.find_glib_compile_resources(mandatory=False) +def options(opt): + gr=opt.add_option_group('Installation directories') + gr.add_option('--gsettingsschemadir',help='GSettings schema location [DATADIR/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py new file mode 100755 index 0000000..21a6288 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py @@ -0,0 +1,66 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re +from waflib import Utils,Options,Context +gnuopts=''' +bindir, user commands, ${EXEC_PREFIX}/bin +sbindir, system binaries, ${EXEC_PREFIX}/sbin +libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec +sysconfdir, host-specific configuration, ${PREFIX}/etc +sharedstatedir, architecture-independent variable data, ${PREFIX}/com +localstatedir, variable data, ${PREFIX}/var +libdir, object code libraries, ${EXEC_PREFIX}/lib%s +includedir, header files, ${PREFIX}/include +oldincludedir, header files for non-GCC compilers, /usr/include +datarootdir, architecture-independent data root, ${PREFIX}/share +datadir, architecture-independent data, ${DATAROOTDIR} +infodir, GNU "info" documentation, ${DATAROOTDIR}/info +localedir, locale-dependent data, ${DATAROOTDIR}/locale +mandir, manual pages, ${DATAROOTDIR}/man +docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE} +htmldir, HTML documentation, ${DOCDIR} +dvidir, DVI documentation, ${DOCDIR} +pdfdir, PDF documentation, ${DOCDIR} +psdir, PostScript documentation, ${DOCDIR} +'''%Utils.lib64() +_options=[x.split(', ')for x in gnuopts.splitlines()if x] +def configure(conf): + def get_param(varname,default): + return getattr(Options.options,varname,'')or default + env=conf.env + env.LIBDIR=env.BINDIR=[] + env.EXEC_PREFIX=get_param('EXEC_PREFIX',env.PREFIX) + env.PACKAGE=getattr(Context.g_module,'APPNAME',None)or env.PACKAGE + complete=False + iter=0 + while not complete and iter\d*)\.(?P\d*)",re.I).search + if Utils.is_win32: + cmd=fc + else: + cmd=fc+['-logo'] + out,err=fc_config.getoutput(conf,cmd,stdin=False) + match=version_re(out)or version_re(err) + if not match: + conf.fatal('cannot determine ifort version.') + k=match.groupdict() + conf.env.FC_VERSION=(k['major'],k['minor']) +def configure(conf): + if Utils.is_win32: + compiler,version,path,includes,libdirs,arch=conf.detect_ifort() + v=conf.env + v.DEST_CPU=arch + v.PATH=path + v.INCLUDES=includes + v.LIBPATH=libdirs + v.MSVC_COMPILER=compiler + try: + v.MSVC_VERSION=float(version) + except ValueError: + v.MSVC_VERSION=float(version[:-3]) + conf.find_ifort_win32() + conf.ifort_modifier_win32() + else: + conf.find_ifort() + conf.find_program('xiar',var='AR') + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.ifort_modifier_platform() +all_ifort_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')] +@conf +def gather_ifort_versions(conf,versions): + version_pattern=re.compile(r'^...?.?\....?.?') + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran') + except OSError: + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\Fortran') + except OSError: + return + index=0 + while 1: + try: + version=Utils.winreg.EnumKey(all_versions,index) + except OSError: + break + index+=1 + if not version_pattern.match(version): + continue + targets={} + for target,arch in all_ifort_platforms: + if target=='intel64': + targetDir='EM64T_NATIVE' + else: + targetDir=target + try: + Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) + icl_version=Utils.winreg.OpenKey(all_versions,version) + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + pass + else: + batch_file=os.path.join(path,'bin','ifortvars.bat') + if os.path.isfile(batch_file): + targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) + for target,arch in all_ifort_platforms: + try: + icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target) + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + continue + else: + batch_file=os.path.join(path,'bin','ifortvars.bat') + if os.path.isfile(batch_file): + targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) + major=version[0:2] + versions['intel '+major]=targets +@conf +def setup_ifort(conf,versiondict): + platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_ifort_platforms] + desired_versions=conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys()))) + for version in desired_versions: + try: + targets=versiondict[version] + except KeyError: + continue + for arch in platforms: + try: + cfg=targets[arch] + except KeyError: + continue + cfg.evaluate() + if cfg.is_valid: + compiler,revision=version.rsplit(' ',1) + return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu + conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys()))) +@conf +def get_ifort_version_win32(conf,compiler,version,target,vcvars): + try: + conf.msvc_cnt+=1 + except AttributeError: + conf.msvc_cnt=1 + batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt) + batfile.write("""@echo off +set INCLUDE= +set LIB= +call "%s" %s +echo PATH=%%PATH%% +echo INCLUDE=%%INCLUDE%% +echo LIB=%%LIB%%;%%LIBPATH%% +"""%(vcvars,target)) + sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()]) + batfile.delete() + lines=sout.splitlines() + if not lines[0]: + lines.pop(0) + MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None + for line in lines: + if line.startswith('PATH='): + path=line[5:] + MSVC_PATH=path.split(';') + elif line.startswith('INCLUDE='): + MSVC_INCDIR=[i for i in line[8:].split(';')if i] + elif line.startswith('LIB='): + MSVC_LIBDIR=[i for i in line[4:].split(';')if i] + if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR): + conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)') + env=dict(os.environ) + env.update(PATH=path) + compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) + fc=conf.find_program(compiler_name,path_list=MSVC_PATH) + if'CL'in env: + del(env['CL']) + try: + conf.cmd_and_log(fc+['/help'],env=env) + except UnicodeError: + st=traceback.format_exc() + if conf.logger: + conf.logger.error(st) + conf.fatal('ifort: Unicode error - check the code page?') + except Exception as e: + Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s',compiler,version,target,str(e)) + conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)') + else: + Logs.debug('ifort: get_ifort_version: %r %r %r -> OK',compiler,version,target) + finally: + conf.env[compiler_name]='' + return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR) +class target_compiler(object): + def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None): + self.conf=ctx + self.name=None + self.is_valid=False + self.is_done=False + self.compiler=compiler + self.cpu=cpu + self.version=version + self.bat_target=bat_target + self.bat=bat + self.callback=callback + def evaluate(self): + if self.is_done: + return + self.is_done=True + try: + vs=self.conf.get_ifort_version_win32(self.compiler,self.version,self.bat_target,self.bat) + except Errors.ConfigurationError: + self.is_valid=False + return + if self.callback: + vs=self.callback(self,vs) + self.is_valid=True + (self.bindirs,self.incdirs,self.libdirs)=vs + def __str__(self): + return str((self.bindirs,self.incdirs,self.libdirs)) + def __repr__(self): + return repr((self.bindirs,self.incdirs,self.libdirs)) +@conf +def detect_ifort(self): + return self.setup_ifort(self.get_ifort_versions(False)) +@conf +def get_ifort_versions(self,eval_and_save=True): + dct={} + self.gather_ifort_versions(dct) + return dct +def _get_prog_names(self,compiler): + if compiler=='intel': + compiler_name='ifort' + linker_name='XILINK' + lib_name='XILIB' + else: + compiler_name='CL' + linker_name='LINK' + lib_name='LIB' + return compiler_name,linker_name,lib_name +@conf +def find_ifort_win32(conf): + v=conf.env + path=v.PATH + compiler=v.MSVC_COMPILER + version=v.MSVC_VERSION + compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) + v.IFORT_MANIFEST=(compiler=='intel'and version>=11) + fc=conf.find_program(compiler_name,var='FC',path_list=path) + env=dict(conf.environ) + if path: + env.update(PATH=';'.join(path)) + if not conf.cmd_and_log(fc+['/nologo','/help'],env=env): + conf.fatal('not intel fortran compiler could not be identified') + v.FC_NAME='IFORT' + if not v.LINK_FC: + conf.find_program(linker_name,var='LINK_FC',path_list=path,mandatory=True) + if not v.AR: + conf.find_program(lib_name,path_list=path,var='AR',mandatory=True) + v.ARFLAGS=['/nologo'] + if v.IFORT_MANIFEST: + conf.find_program('MT',path_list=path,var='MT') + v.MTFLAGS=['/nologo'] + try: + conf.load('winres') + except Errors.WafError: + Logs.warn('Resource compiler not found. Compiling resource file is disabled') +@after_method('apply_link') +@feature('fc') +def apply_flags_ifort(self): + if not self.env.IFORT_WIN32 or not getattr(self,'link_task',None): + return + is_static=isinstance(self.link_task,ccroot.stlink_task) + subsystem=getattr(self,'subsystem','') + if subsystem: + subsystem='/subsystem:%s'%subsystem + flags=is_static and'ARFLAGS'or'LINKFLAGS' + self.env.append_value(flags,subsystem) + if not is_static: + for f in self.env.LINKFLAGS: + d=f.lower() + if d[1:]=='debug': + pdbnode=self.link_task.outputs[0].change_ext('.pdb') + self.link_task.outputs.append(pdbnode) + if getattr(self,'install_task',None): + self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode) + break +@feature('fcprogram','fcshlib','fcprogram_test') +@after_method('apply_link') +def apply_manifest_ifort(self): + if self.env.IFORT_WIN32 and getattr(self,'link_task',None): + self.link_task.env.FC=self.env.LINK_FC + if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self,'link_task',None): + out_node=self.link_task.outputs[0] + man_node=out_node.parent.find_or_declare(out_node.name+'.manifest') + self.link_task.outputs.append(man_node) + self.env.DO_MANIFEST=True diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py new file mode 100755 index 0000000..d799402 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py @@ -0,0 +1,101 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from __future__ import with_statement +import os,re +from waflib import Context,Task,Utils,Logs +import waflib.Tools.ccroot +from waflib.TaskGen import feature,before_method,taskgen_method +from waflib.Logs import error +from waflib.Configure import conf +_style_flags={'ba':'-b','desktop':'-d','keys':'-k','quoted':'--quoted-style','quotedxml':'--quotedxml-style','rfc822deb':'-r','schemas':'-s','xml':'-x',} +@taskgen_method +def ensure_localedir(self): + if not self.env.LOCALEDIR: + if self.env.DATAROOTDIR: + self.env.LOCALEDIR=os.path.join(self.env.DATAROOTDIR,'locale') + else: + self.env.LOCALEDIR=os.path.join(self.env.PREFIX,'share','locale') +@before_method('process_source') +@feature('intltool_in') +def apply_intltool_in_f(self): + try: + self.meths.remove('process_source') + except ValueError: + pass + self.ensure_localedir() + podir=getattr(self,'podir','.') + podirnode=self.path.find_dir(podir) + if not podirnode: + error("could not find the podir %r"%podir) + return + cache=getattr(self,'intlcache','.intlcache') + self.env.INTLCACHE=[os.path.join(str(self.path.get_bld()),podir,cache)] + self.env.INTLPODIR=podirnode.bldpath() + self.env.append_value('INTLFLAGS',getattr(self,'flags',self.env.INTLFLAGS_DEFAULT)) + if'-c'in self.env.INTLFLAGS: + self.bld.fatal('Redundant -c flag in intltool task %r'%self) + style=getattr(self,'style',None) + if style: + try: + style_flag=_style_flags[style] + except KeyError: + self.bld.fatal('intltool_in style "%s" is not valid'%style) + self.env.append_unique('INTLFLAGS',[style_flag]) + for i in self.to_list(self.source): + node=self.path.find_resource(i) + task=self.create_task('intltool',node,node.change_ext('')) + inst=getattr(self,'install_path',None) + if inst: + self.add_install_files(install_to=inst,install_from=task.outputs) +@feature('intltool_po') +def apply_intltool_po(self): + try: + self.meths.remove('process_source') + except ValueError: + pass + self.ensure_localedir() + appname=getattr(self,'appname',getattr(Context.g_module,Context.APPNAME,'set_your_app_name')) + podir=getattr(self,'podir','.') + inst=getattr(self,'install_path','${LOCALEDIR}') + linguas=self.path.find_node(os.path.join(podir,'LINGUAS')) + if linguas: + with open(linguas.abspath())as f: + langs=[] + for line in f.readlines(): + if not line.startswith('#'): + langs+=line.split() + re_linguas=re.compile('[-a-zA-Z_@.]+') + for lang in langs: + if re_linguas.match(lang): + node=self.path.find_resource(os.path.join(podir,re_linguas.match(lang).group()+'.po')) + task=self.create_task('po',node,node.change_ext('.mo')) + if inst: + filename=task.outputs[0].name + (langname,ext)=os.path.splitext(filename) + inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo' + self.add_install_as(install_to=inst_file,install_from=task.outputs[0],chmod=getattr(self,'chmod',Utils.O644)) + else: + Logs.pprint('RED',"Error no LINGUAS file found in po directory") +class po(Task.Task): + run_str='${MSGFMT} -o ${TGT} ${SRC}' + color='BLUE' +class intltool(Task.Task): + run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}' + color='BLUE' +@conf +def find_msgfmt(conf): + conf.find_program('msgfmt',var='MSGFMT') +@conf +def find_intltool_merge(conf): + if not conf.env.PERL: + conf.find_program('perl',var='PERL') + conf.env.INTLCACHE_ST='--cache=%s' + conf.env.INTLFLAGS_DEFAULT=['-q','-u'] + conf.find_program('intltool-merge',interpreter='PERL',var='INTLTOOL') +def configure(conf): + conf.find_msgfmt() + conf.find_intltool_merge() + if conf.env.CC or conf.env.CXX: + conf.check(header_name='locale.h') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py new file mode 100755 index 0000000..06099ff --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py @@ -0,0 +1,51 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Errors +from waflib.Tools import ccroot,ar +from waflib.Configure import conf +@conf +def find_irixcc(conf): + v=conf.env + cc=None + if v.CC: + cc=v.CC + elif'CC'in conf.environ: + cc=conf.environ['CC'] + if not cc: + cc=conf.find_program('cc',var='CC') + if not cc: + conf.fatal('irixcc was not found') + try: + conf.cmd_and_log(cc+['-version']) + except Errors.WafError: + conf.fatal('%r -version could not be executed'%cc) + v.CC=cc + v.CC_NAME='irix' +@conf +def irixcc_common_flags(conf): + v=conf.env + v.CC_SRC_F='' + v.CC_TGT_F=['-c','-o'] + v.CPPPATH_ST='-I%s' + v.DEFINES_ST='-D%s' + if not v.LINK_CC: + v.LINK_CC=v.CC + v.CCLNK_SRC_F='' + v.CCLNK_TGT_F=['-o'] + v.LIB_ST='-l%s' + v.LIBPATH_ST='-L%s' + v.STLIB_ST='-l%s' + v.STLIBPATH_ST='-L%s' + v.cprogram_PATTERN='%s' + v.cshlib_PATTERN='lib%s.so' + v.cstlib_PATTERN='lib%s.a' +def configure(conf): + conf.find_irixcc() + conf.find_cpp() + conf.find_ar() + conf.irixcc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py new file mode 100755 index 0000000..7f97c97 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py @@ -0,0 +1,330 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,shutil +from waflib import Task,Utils,Errors,Node +from waflib.Configure import conf +from waflib.TaskGen import feature,before_method,after_method,taskgen_method +from waflib.Tools import ccroot +ccroot.USELIB_VARS['javac']=set(['CLASSPATH','JAVACFLAGS']) +SOURCE_RE='**/*.java' +JAR_RE='**/*' +class_check_source=''' +public class Test { + public static void main(String[] argv) { + Class lib; + if (argv.length < 1) { + System.err.println("Missing argument"); + System.exit(77); + } + try { + lib = Class.forName(argv[0]); + } catch (ClassNotFoundException e) { + System.err.println("ClassNotFoundException"); + System.exit(1); + } + lib = null; + System.exit(0); + } +} +''' +@feature('javac') +@before_method('process_source') +def apply_java(self): + Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[]) + outdir=getattr(self,'outdir',None) + if outdir: + if not isinstance(outdir,Node.Node): + outdir=self.path.get_bld().make_node(self.outdir) + else: + outdir=self.path.get_bld() + outdir.mkdir() + self.outdir=outdir + self.env.OUTDIR=outdir.abspath() + self.javac_task=tsk=self.create_task('javac') + tmp=[] + srcdir=getattr(self,'srcdir','') + if isinstance(srcdir,Node.Node): + srcdir=[srcdir] + for x in Utils.to_list(srcdir): + if isinstance(x,Node.Node): + y=x + else: + y=self.path.find_dir(x) + if not y: + self.bld.fatal('Could not find the folder %s from %s'%(x,self.path)) + tmp.append(y) + tsk.srcdir=tmp + if getattr(self,'compat',None): + tsk.env.append_value('JAVACFLAGS',['-source',str(self.compat)]) + if hasattr(self,'sourcepath'): + fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)] + names=os.pathsep.join([x.srcpath()for x in fold]) + else: + names=[x.srcpath()for x in tsk.srcdir] + if names: + tsk.env.append_value('JAVACFLAGS',['-sourcepath',names]) +@taskgen_method +def java_use_rec(self,name,**kw): + if name in self.tmp_use_seen: + return + self.tmp_use_seen.append(name) + try: + y=self.bld.get_tgen_by_name(name) + except Errors.WafError: + self.uselib.append(name) + return + else: + y.post() + if hasattr(y,'jar_task'): + self.use_lst.append(y.jar_task.outputs[0].abspath()) + else: + if hasattr(y,'outdir'): + self.use_lst.append(y.outdir.abspath()) + else: + self.use_lst.append(y.path.get_bld().abspath()) + for x in self.to_list(getattr(y,'use',[])): + self.java_use_rec(x) +@feature('javac') +@before_method('propagate_uselib_vars') +@after_method('apply_java') +def use_javac_files(self): + self.use_lst=[] + self.tmp_use_seen=[] + self.uselib=self.to_list(getattr(self,'uselib',[])) + names=self.to_list(getattr(self,'use',[])) + get=self.bld.get_tgen_by_name + for x in names: + try: + tg=get(x) + except Errors.WafError: + self.uselib.append(x) + else: + tg.post() + if hasattr(tg,'jar_task'): + self.use_lst.append(tg.jar_task.outputs[0].abspath()) + self.javac_task.set_run_after(tg.jar_task) + self.javac_task.dep_nodes.extend(tg.jar_task.outputs) + else: + if hasattr(tg,'outdir'): + base_node=tg.outdir + else: + base_node=tg.path.get_bld() + self.use_lst.append(base_node.abspath()) + self.javac_task.dep_nodes.extend([x for x in base_node.ant_glob(JAR_RE,remove=False,quiet=True)]) + for tsk in tg.tasks: + self.javac_task.set_run_after(tsk) + if getattr(self,'recurse_use',False)or self.bld.env.RECURSE_JAVA: + self.java_use_rec(x) + self.env.append_value('CLASSPATH',self.use_lst) +@feature('javac') +@after_method('apply_java','propagate_uselib_vars','use_javac_files') +def set_classpath(self): + if getattr(self,'classpath',None): + self.env.append_unique('CLASSPATH',getattr(self,'classpath',[])) + for x in self.tasks: + x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep +@feature('jar') +@after_method('apply_java','use_javac_files') +@before_method('process_source') +def jar_files(self): + destfile=getattr(self,'destfile','test.jar') + jaropts=getattr(self,'jaropts',[]) + manifest=getattr(self,'manifest',None) + basedir=getattr(self,'basedir',None) + if basedir: + if not isinstance(self.basedir,Node.Node): + basedir=self.path.get_bld().make_node(basedir) + else: + basedir=self.path.get_bld() + if not basedir: + self.bld.fatal('Could not find the basedir %r for %r'%(self.basedir,self)) + self.jar_task=tsk=self.create_task('jar_create') + if manifest: + jarcreate=getattr(self,'jarcreate','cfm') + if not isinstance(manifest,Node.Node): + node=self.path.find_resource(manifest) + else: + node=manifest + if not node: + self.bld.fatal('invalid manifest file %r for %r'%(manifest,self)) + tsk.dep_nodes.append(node) + jaropts.insert(0,node.abspath()) + else: + jarcreate=getattr(self,'jarcreate','cf') + if not isinstance(destfile,Node.Node): + destfile=self.path.find_or_declare(destfile) + if not destfile: + self.bld.fatal('invalid destfile %r for %r'%(destfile,self)) + tsk.set_outputs(destfile) + tsk.basedir=basedir + jaropts.append('-C') + jaropts.append(basedir.bldpath()) + jaropts.append('.') + tsk.env.JAROPTS=jaropts + tsk.env.JARCREATE=jarcreate + if getattr(self,'javac_task',None): + tsk.set_run_after(self.javac_task) +@feature('jar') +@after_method('jar_files') +def use_jar_files(self): + self.uselib=self.to_list(getattr(self,'uselib',[])) + names=self.to_list(getattr(self,'use',[])) + get=self.bld.get_tgen_by_name + for x in names: + try: + y=get(x) + except Errors.WafError: + self.uselib.append(x) + else: + y.post() + self.jar_task.run_after.update(y.tasks) +class JTask(Task.Task): + def split_argfile(self,cmd): + inline=[cmd[0]] + infile=[] + for x in cmd[1:]: + if x.startswith('-J'): + inline.append(x) + else: + infile.append(self.quote_flag(x)) + return(inline,infile) +class jar_create(JTask): + color='GREEN' + run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}' + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + if not self.inputs: + try: + self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False,quiet=True)if id(x)!=id(self.outputs[0])] + except Exception: + raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self)) + return super(jar_create,self).runnable_status() +class javac(JTask): + color='BLUE' + run_str='${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}' + vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR'] + def uid(self): + lst=[self.__class__.__name__,self.generator.outdir.abspath()] + for x in self.srcdir: + lst.append(x.abspath()) + return Utils.h_list(lst) + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + if not self.inputs: + self.inputs=[] + for x in self.srcdir: + if x.exists(): + self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False,quiet=True)) + return super(javac,self).runnable_status() + def post_run(self): + for node in self.generator.outdir.ant_glob('**/*.class',quiet=True): + self.generator.bld.node_sigs[node]=self.uid() + self.generator.bld.task_sigs[self.uid()]=self.cache_sig +@feature('javadoc') +@after_method('process_rule') +def create_javadoc(self): + tsk=self.create_task('javadoc') + tsk.classpath=getattr(self,'classpath',[]) + self.javadoc_package=Utils.to_list(self.javadoc_package) + if not isinstance(self.javadoc_output,Node.Node): + self.javadoc_output=self.bld.path.find_or_declare(self.javadoc_output) +class javadoc(Task.Task): + color='BLUE' + def __str__(self): + return'%s: %s -> %s\n'%(self.__class__.__name__,self.generator.srcdir,self.generator.javadoc_output) + def run(self): + env=self.env + bld=self.generator.bld + wd=bld.bldnode + srcpath=self.generator.path.abspath()+os.sep+self.generator.srcdir + srcpath+=os.pathsep + srcpath+=self.generator.path.get_bld().abspath()+os.sep+self.generator.srcdir + classpath=env.CLASSPATH + classpath+=os.pathsep + classpath+=os.pathsep.join(self.classpath) + classpath="".join(classpath) + self.last_cmd=lst=[] + lst.extend(Utils.to_list(env.JAVADOC)) + lst.extend(['-d',self.generator.javadoc_output.abspath()]) + lst.extend(['-sourcepath',srcpath]) + lst.extend(['-classpath',classpath]) + lst.extend(['-subpackages']) + lst.extend(self.generator.javadoc_package) + lst=[x for x in lst if x] + self.generator.bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0) + def post_run(self): + nodes=self.generator.javadoc_output.ant_glob('**',quiet=True) + for node in nodes: + self.generator.bld.node_sigs[node]=self.uid() + self.generator.bld.task_sigs[self.uid()]=self.cache_sig +def configure(self): + java_path=self.environ['PATH'].split(os.pathsep) + v=self.env + if'JAVA_HOME'in self.environ: + java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path + self.env.JAVA_HOME=[self.environ['JAVA_HOME']] + for x in'javac java jar javadoc'.split(): + self.find_program(x,var=x.upper(),path_list=java_path,mandatory=(x not in('javadoc'))) + if'CLASSPATH'in self.environ: + v.CLASSPATH=self.environ['CLASSPATH'] + if not v.JAR: + self.fatal('jar is required for making java packages') + if not v.JAVAC: + self.fatal('javac is required for compiling java classes') + v.JARCREATE='cf' + v.JAVACFLAGS=[] +@conf +def check_java_class(self,classname,with_classpath=None): + javatestdir='.waf-javatest' + classpath=javatestdir + if self.env.CLASSPATH: + classpath+=os.pathsep+self.env.CLASSPATH + if isinstance(with_classpath,str): + classpath+=os.pathsep+with_classpath + shutil.rmtree(javatestdir,True) + os.mkdir(javatestdir) + Utils.writef(os.path.join(javatestdir,'Test.java'),class_check_source) + self.exec_command(self.env.JAVAC+[os.path.join(javatestdir,'Test.java')],shell=False) + cmd=self.env.JAVA+['-cp',classpath,'Test',classname] + self.to_log("%s\n"%str(cmd)) + found=self.exec_command(cmd,shell=False) + self.msg('Checking for java class %s'%classname,not found) + shutil.rmtree(javatestdir,True) + return found +@conf +def check_jni_headers(conf): + if not conf.env.CC_NAME and not conf.env.CXX_NAME: + conf.fatal('load a compiler first (gcc, g++, ..)') + if not conf.env.JAVA_HOME: + conf.fatal('set JAVA_HOME in the system environment') + javaHome=conf.env.JAVA_HOME[0] + dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include') + if dir is None: + dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/../Headers') + if dir is None: + conf.fatal('JAVA_HOME does not seem to be set properly') + f=dir.ant_glob('**/(jni|jni_md).h') + incDirs=[x.parent.abspath()for x in f] + dir=conf.root.find_dir(conf.env.JAVA_HOME[0]) + f=dir.ant_glob('**/*jvm.(so|dll|dylib)') + libDirs=[x.parent.abspath()for x in f]or[javaHome] + f=dir.ant_glob('**/*jvm.(lib)') + if f: + libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f] + if conf.env.DEST_OS=='freebsd': + conf.env.append_unique('LINKFLAGS_JAVA','-pthread') + for d in libDirs: + try: + conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA') + except Exception: + pass + else: + break + else: + conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py new file mode 100755 index 0000000..40d435e --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py @@ -0,0 +1,36 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.Tools import ar,d +from waflib.Configure import conf +@conf +def find_ldc2(conf): + conf.find_program(['ldc2'],var='D') + out=conf.cmd_and_log(conf.env.D+['-version']) + if out.find("based on DMD v2.")==-1: + conf.fatal("detected compiler is not ldc2") +@conf +def common_flags_ldc2(conf): + v=conf.env + v.D_SRC_F=['-c'] + v.D_TGT_F='-of%s' + v.D_LINKER=v.D + v.DLNK_SRC_F='' + v.DLNK_TGT_F='-of%s' + v.DINC_ST='-I%s' + v.DSHLIB_MARKER=v.DSTLIB_MARKER='' + v.DSTLIB_ST=v.DSHLIB_ST='-L-l%s' + v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L-L%s' + v.LINKFLAGS_dshlib=['-L-shared'] + v.DHEADER_ext='.di' + v.DFLAGS_d_with_header=['-H','-Hf'] + v.D_HDR_F='%s' + v.LINKFLAGS=[] + v.DFLAGS_dshlib=['-relocation-model=pic'] +def configure(conf): + conf.find_ldc2() + conf.load('ar') + conf.load('d') + conf.common_flags_ldc2() + conf.d_platform_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py new file mode 100755 index 0000000..7c6a682 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py @@ -0,0 +1,18 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.TaskGen import extension +from waflib import Task +@extension('.lua') +def add_lua(self,node): + tsk=self.create_task('luac',node,node.change_ext('.luac')) + inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None) + if inst_to: + self.add_install_files(install_to=inst_to,install_from=tsk.outputs) + return tsk +class luac(Task.Task): + run_str='${LUAC} -s -o ${TGT} ${SRC}' + color='PINK' +def configure(conf): + conf.find_program('luac',var='LUAC') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py new file mode 100755 index 0000000..0d0faa0 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py @@ -0,0 +1,24 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,stat +from waflib import Utils,Build,Node +STRONGEST=True +Build.SAVED_ATTRS.append('hashes_md5_tstamp') +def h_file(self): + filename=self.abspath() + st=os.stat(filename) + cache=self.ctx.hashes_md5_tstamp + if filename in cache and cache[filename][0]==st.st_mtime: + return cache[filename][1] + if STRONGEST: + ret=Utils.h_file(filename) + else: + if stat.S_ISDIR(st[stat.ST_MODE]): + raise IOError('Not a file') + ret=Utils.md5(str((st.st_mtime,st.st_size)).encode()).digest() + cache[filename]=(st.st_mtime,ret) + return ret +h_file.__doc__=Node.Node.h_file.__doc__ +Node.Node.h_file=h_file diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py new file mode 100755 index 0000000..36839d2 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py @@ -0,0 +1,704 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,sys,re,traceback +from waflib import Utils,Logs,Options,Errors +from waflib.TaskGen import after_method,feature +from waflib.Configure import conf +from waflib.Tools import ccroot,c,cxx,ar +g_msvc_systemlibs=''' +aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet +cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs +credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d +ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp +faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid +gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop +kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi +mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree +msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm +netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp +odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32 +osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu +ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm +rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32 +shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32 +traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg +version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm +wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp +'''.split() +all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm'),('x86_arm64','arm64'),('amd64_x86','x86'),('amd64_arm','arm'),('amd64_arm64','arm64')] +all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')] +all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')] +def options(opt): + opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='') + opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='') + opt.add_option('--no-msvc-lazy',action='store_false',help='lazily check msvc target environments',default=True,dest='msvc_lazy') +@conf +def setup_msvc(conf,versiondict): + platforms=getattr(Options.options,'msvc_targets','').split(',') + if platforms==['']: + platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms] + desired_versions=getattr(Options.options,'msvc_version','').split(',') + if desired_versions==['']: + desired_versions=conf.env.MSVC_VERSIONS or list(reversed(sorted(versiondict.keys()))) + lazy_detect=getattr(Options.options,'msvc_lazy',True) + if conf.env.MSVC_LAZY_AUTODETECT is False: + lazy_detect=False + if not lazy_detect: + for val in versiondict.values(): + for arch in list(val.keys()): + cfg=val[arch] + cfg.evaluate() + if not cfg.is_valid: + del val[arch] + conf.env.MSVC_INSTALLED_VERSIONS=versiondict + for version in desired_versions: + Logs.debug('msvc: detecting %r - %r',version,desired_versions) + try: + targets=versiondict[version] + except KeyError: + continue + seen=set() + for arch in platforms: + if arch in seen: + continue + else: + seen.add(arch) + try: + cfg=targets[arch] + except KeyError: + continue + cfg.evaluate() + if cfg.is_valid: + compiler,revision=version.rsplit(' ',1) + return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu + conf.fatal('msvc: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys()))) +@conf +def get_msvc_version(conf,compiler,version,target,vcvars): + Logs.debug('msvc: get_msvc_version: %r %r %r',compiler,version,target) + try: + conf.msvc_cnt+=1 + except AttributeError: + conf.msvc_cnt=1 + batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt) + batfile.write("""@echo off +set INCLUDE= +set LIB= +call "%s" %s +echo PATH=%%PATH%% +echo INCLUDE=%%INCLUDE%% +echo LIB=%%LIB%%;%%LIBPATH%% +"""%(vcvars,target)) + sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()]) + lines=sout.splitlines() + if not lines[0]: + lines.pop(0) + MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None + for line in lines: + if line.startswith('PATH='): + path=line[5:] + MSVC_PATH=path.split(';') + elif line.startswith('INCLUDE='): + MSVC_INCDIR=[i for i in line[8:].split(';')if i] + elif line.startswith('LIB='): + MSVC_LIBDIR=[i for i in line[4:].split(';')if i] + if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR): + conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)') + env=dict(os.environ) + env.update(PATH=path) + compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) + cxx=conf.find_program(compiler_name,path_list=MSVC_PATH) + if'CL'in env: + del(env['CL']) + try: + conf.cmd_and_log(cxx+['/help'],env=env) + except UnicodeError: + st=traceback.format_exc() + if conf.logger: + conf.logger.error(st) + conf.fatal('msvc: Unicode error - check the code page?') + except Exception as e: + Logs.debug('msvc: get_msvc_version: %r %r %r -> failure %s',compiler,version,target,str(e)) + conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)') + else: + Logs.debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target) + finally: + conf.env[compiler_name]='' + return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR) +def gather_wince_supported_platforms(): + supported_wince_platforms=[] + try: + ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs') + except OSError: + try: + ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs') + except OSError: + ce_sdk='' + if not ce_sdk: + return supported_wince_platforms + index=0 + while 1: + try: + sdk_device=Utils.winreg.EnumKey(ce_sdk,index) + sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device) + except OSError: + break + index+=1 + try: + path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir') + except OSError: + try: + path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation') + except OSError: + continue + path,xml=os.path.split(path) + path=str(path) + path,device=os.path.split(path) + if not device: + path,device=os.path.split(path) + platforms=[] + for arch,compiler in all_wince_platforms: + if os.path.isdir(os.path.join(path,device,'Lib',arch)): + platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch))) + if platforms: + supported_wince_platforms.append((device,platforms)) + return supported_wince_platforms +def gather_msvc_detected_versions(): + version_pattern=re.compile(r'^(\d\d?\.\d\d?)(Exp)?$') + detected_versions=[] + for vcver,vcvar in(('VCExpress','Exp'),('VisualStudio','')): + prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix) + except OSError: + prefix='SOFTWARE\\Microsoft\\'+vcver + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix) + except OSError: + continue + index=0 + while 1: + try: + version=Utils.winreg.EnumKey(all_versions,index) + except OSError: + break + index+=1 + match=version_pattern.match(version) + if match: + versionnumber=float(match.group(1)) + else: + continue + detected_versions.append((versionnumber,version+vcvar,prefix+'\\'+version)) + def fun(tup): + return tup[0] + detected_versions.sort(key=fun) + return detected_versions +class target_compiler(object): + def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None): + self.conf=ctx + self.name=None + self.is_valid=False + self.is_done=False + self.compiler=compiler + self.cpu=cpu + self.version=version + self.bat_target=bat_target + self.bat=bat + self.callback=callback + def evaluate(self): + if self.is_done: + return + self.is_done=True + try: + vs=self.conf.get_msvc_version(self.compiler,self.version,self.bat_target,self.bat) + except Errors.ConfigurationError: + self.is_valid=False + return + if self.callback: + vs=self.callback(self,vs) + self.is_valid=True + (self.bindirs,self.incdirs,self.libdirs)=vs + def __str__(self): + return str((self.compiler,self.cpu,self.version,self.bat_target,self.bat)) + def __repr__(self): + return repr((self.compiler,self.cpu,self.version,self.bat_target,self.bat)) +@conf +def gather_wsdk_versions(conf,versions): + version_pattern=re.compile(r'^v..?.?\...?.?') + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows') + except OSError: + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows') + except OSError: + return + index=0 + while 1: + try: + version=Utils.winreg.EnumKey(all_versions,index) + except OSError: + break + index+=1 + if not version_pattern.match(version): + continue + try: + msvc_version=Utils.winreg.OpenKey(all_versions,version) + path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder') + except OSError: + continue + if path and os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')): + targets={} + for target,arch in all_msvc_platforms: + targets[target]=target_compiler(conf,'wsdk',arch,version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')) + versions['wsdk '+version[1:]]=targets +@conf +def gather_msvc_targets(conf,versions,version,vc_path): + targets={} + if os.path.isfile(os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat')): + for target,realtarget in all_msvc_platforms[::-1]: + targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat')) + elif os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')): + for target,realtarget in all_msvc_platforms[::-1]: + targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'vcvarsall.bat')) + elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')): + targets['x86']=target_compiler(conf,'msvc','x86',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')) + elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')): + targets['x86']=target_compiler(conf,'msvc','x86',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')) + if targets: + versions['msvc %s'%version]=targets +@conf +def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms): + for device,platforms in supported_platforms: + targets={} + for platform,compiler,include,lib in platforms: + winCEpath=os.path.join(vc_path,'ce') + if not os.path.isdir(winCEpath): + continue + if os.path.isdir(os.path.join(winCEpath,'lib',platform)): + bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)] + incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include] + libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib] + def combine_common(obj,compiler_env): + (common_bindirs,_1,_2)=compiler_env + return(bindirs+common_bindirs,incdirs,libdirs) + targets[platform]=target_compiler(conf,'msvc',platform,version,'x86',vsvars,combine_common) + if targets: + versions[device+' '+version]=targets +@conf +def gather_winphone_targets(conf,versions,version,vc_path,vsvars): + targets={} + for target,realtarget in all_msvc_platforms[::-1]: + targets[target]=target_compiler(conf,'winphone',realtarget,version,target,vsvars) + if targets: + versions['winphone '+version]=targets +@conf +def gather_vswhere_versions(conf,versions): + try: + import json + except ImportError: + Logs.error('Visual Studio 2017 detection requires Python 2.6') + return + prg_path=os.environ.get('ProgramFiles(x86)',os.environ.get('ProgramFiles','C:\\Program Files (x86)')) + vswhere=os.path.join(prg_path,'Microsoft Visual Studio','Installer','vswhere.exe') + args=[vswhere,'-products','*','-legacy','-format','json'] + try: + txt=conf.cmd_and_log(args) + except Errors.WafError as e: + Logs.debug('msvc: vswhere.exe failed %s',e) + return + if sys.version_info[0]<3: + txt=txt.decode(Utils.console_encoding()) + arr=json.loads(txt) + arr.sort(key=lambda x:x['installationVersion']) + for entry in arr: + ver=entry['installationVersion'] + ver=str('.'.join(ver.split('.')[:2])) + path=str(os.path.abspath(entry['installationPath'])) + if os.path.exists(path)and('msvc %s'%ver)not in versions: + conf.gather_msvc_targets(versions,ver,path) +@conf +def gather_msvc_versions(conf,versions): + vc_paths=[] + for(v,version,reg)in gather_msvc_detected_versions(): + try: + try: + msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC") + except OSError: + msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++") + path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir') + except OSError: + try: + msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Wow6432node\\Microsoft\\VisualStudio\\SxS\\VS7") + path,type=Utils.winreg.QueryValueEx(msvc_version,version) + except OSError: + continue + else: + vc_paths.append((version,os.path.abspath(str(path)))) + continue + else: + vc_paths.append((version,os.path.abspath(str(path)))) + wince_supported_platforms=gather_wince_supported_platforms() + for version,vc_path in vc_paths: + vs_path=os.path.dirname(vc_path) + vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat') + if wince_supported_platforms and os.path.isfile(vsvars): + conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms) + for version,vc_path in vc_paths: + vs_path=os.path.dirname(vc_path) + vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat') + if os.path.isfile(vsvars): + conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars) + break + for version,vc_path in vc_paths: + vs_path=os.path.dirname(vc_path) + conf.gather_msvc_targets(versions,version,vc_path) +@conf +def gather_icl_versions(conf,versions): + version_pattern=re.compile(r'^...?.?\....?.?') + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++') + except OSError: + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++') + except OSError: + return + index=0 + while 1: + try: + version=Utils.winreg.EnumKey(all_versions,index) + except OSError: + break + index+=1 + if not version_pattern.match(version): + continue + targets={} + for target,arch in all_icl_platforms: + if target=='intel64': + targetDir='EM64T_NATIVE' + else: + targetDir=target + try: + Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) + icl_version=Utils.winreg.OpenKey(all_versions,version) + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + pass + else: + batch_file=os.path.join(path,'bin','iclvars.bat') + if os.path.isfile(batch_file): + targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) + for target,arch in all_icl_platforms: + try: + icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target) + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + continue + else: + batch_file=os.path.join(path,'bin','iclvars.bat') + if os.path.isfile(batch_file): + targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) + major=version[0:2] + versions['intel '+major]=targets +@conf +def gather_intel_composer_versions(conf,versions): + version_pattern=re.compile(r'^...?.?\...?.?.?') + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites') + except OSError: + try: + all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites') + except OSError: + return + index=0 + while 1: + try: + version=Utils.winreg.EnumKey(all_versions,index) + except OSError: + break + index+=1 + if not version_pattern.match(version): + continue + targets={} + for target,arch in all_icl_platforms: + if target=='intel64': + targetDir='EM64T_NATIVE' + else: + targetDir=target + try: + try: + defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir) + except OSError: + if targetDir=='EM64T_NATIVE': + defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T') + else: + raise + uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey') + Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir) + icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++') + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + pass + else: + batch_file=os.path.join(path,'bin','iclvars.bat') + if os.path.isfile(batch_file): + targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) + compilervars_warning_attr='_compilervars_warning_key' + if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True): + setattr(conf,compilervars_warning_attr,False) + patch_url='http://software.intel.com/en-us/forums/topic/328487' + compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat') + for vscomntool in('VS110COMNTOOLS','VS100COMNTOOLS'): + if vscomntool in os.environ: + vs_express_path=os.environ[vscomntool]+r'..\IDE\VSWinExpress.exe' + dev_env_path=os.environ[vscomntool]+r'..\IDE\devenv.exe' + if(r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"'in Utils.readf(compilervars_arch)and not os.path.exists(vs_express_path)and not os.path.exists(dev_env_path)): + Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ''(VSWinExpress.exe) but it does not seem to be installed at %r. ''The intel command line set up will fail to configure unless the file %r''is patched. See: %s')%(vs_express_path,compilervars_arch,patch_url)) + major=version[0:2] + versions['intel '+major]=targets +@conf +def detect_msvc(self): + return self.setup_msvc(self.get_msvc_versions()) +@conf +def get_msvc_versions(self): + dct=Utils.ordered_iter_dict() + self.gather_icl_versions(dct) + self.gather_intel_composer_versions(dct) + self.gather_wsdk_versions(dct) + self.gather_msvc_versions(dct) + self.gather_vswhere_versions(dct) + Logs.debug('msvc: detected versions %r',list(dct.keys())) + return dct +@conf +def find_lt_names_msvc(self,libname,is_static=False): + lt_names=['lib%s.la'%libname,'%s.la'%libname,] + for path in self.env.LIBPATH: + for la in lt_names: + laf=os.path.join(path,la) + dll=None + if os.path.exists(laf): + ltdict=Utils.read_la_file(laf) + lt_libdir=None + if ltdict.get('libdir',''): + lt_libdir=ltdict['libdir'] + if not is_static and ltdict.get('library_names',''): + dllnames=ltdict['library_names'].split() + dll=dllnames[0].lower() + dll=re.sub(r'\.dll$','',dll) + return(lt_libdir,dll,False) + elif ltdict.get('old_library',''): + olib=ltdict['old_library'] + if os.path.exists(os.path.join(path,olib)): + return(path,olib,True) + elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)): + return(lt_libdir,olib,True) + else: + return(None,olib,True) + else: + raise self.errors.WafError('invalid libtool object file: %s'%laf) + return(None,None,None) +@conf +def libname_msvc(self,libname,is_static=False): + lib=libname.lower() + lib=re.sub(r'\.lib$','',lib) + if lib in g_msvc_systemlibs: + return lib + lib=re.sub('^lib','',lib) + if lib=='m': + return None + (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static) + if lt_path!=None and lt_libname!=None: + if lt_static: + return os.path.join(lt_path,lt_libname) + if lt_path!=None: + _libpaths=[lt_path]+self.env.LIBPATH + else: + _libpaths=self.env.LIBPATH + static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,] + dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,] + libnames=static_libs + if not is_static: + libnames=dynamic_libs+static_libs + for path in _libpaths: + for libn in libnames: + if os.path.exists(os.path.join(path,libn)): + Logs.debug('msvc: lib found: %s',os.path.join(path,libn)) + return re.sub(r'\.lib$','',libn) + self.fatal('The library %r could not be found'%libname) + return re.sub(r'\.lib$','',libname) +@conf +def check_lib_msvc(self,libname,is_static=False,uselib_store=None): + libn=self.libname_msvc(libname,is_static) + if not uselib_store: + uselib_store=libname.upper() + if False and is_static: + self.env['STLIB_'+uselib_store]=[libn] + else: + self.env['LIB_'+uselib_store]=[libn] +@conf +def check_libs_msvc(self,libnames,is_static=False): + for libname in Utils.to_list(libnames): + self.check_lib_msvc(libname,is_static) +def configure(conf): + conf.autodetect(True) + conf.find_msvc() + conf.msvc_common_flags() + conf.cc_load_tools() + conf.cxx_load_tools() + conf.cc_add_flags() + conf.cxx_add_flags() + conf.link_add_flags() + conf.visual_studio_add_flags() +@conf +def no_autodetect(conf): + conf.env.NO_MSVC_DETECT=1 + configure(conf) +@conf +def autodetect(conf,arch=False): + v=conf.env + if v.NO_MSVC_DETECT: + return + compiler,version,path,includes,libdirs,cpu=conf.detect_msvc() + if arch: + v.DEST_CPU=cpu + v.PATH=path + v.INCLUDES=includes + v.LIBPATH=libdirs + v.MSVC_COMPILER=compiler + try: + v.MSVC_VERSION=float(version) + except ValueError: + v.MSVC_VERSION=float(version[:-3]) +def _get_prog_names(conf,compiler): + if compiler=='intel': + compiler_name='ICL' + linker_name='XILINK' + lib_name='XILIB' + else: + compiler_name='CL' + linker_name='LINK' + lib_name='LIB' + return compiler_name,linker_name,lib_name +@conf +def find_msvc(conf): + if sys.platform=='cygwin': + conf.fatal('MSVC module does not work under cygwin Python!') + v=conf.env + path=v.PATH + compiler=v.MSVC_COMPILER + version=v.MSVC_VERSION + compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) + v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11) + cxx=conf.find_program(compiler_name,var='CXX',path_list=path) + env=dict(conf.environ) + if path: + env.update(PATH=';'.join(path)) + if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env): + conf.fatal('the msvc compiler could not be identified') + v.CC=v.CXX=cxx + v.CC_NAME=v.CXX_NAME='msvc' + if not v.LINK_CXX: + conf.find_program(linker_name,path_list=path,errmsg='%s was not found (linker)'%linker_name,var='LINK_CXX') + if not v.LINK_CC: + v.LINK_CC=v.LINK_CXX + if not v.AR: + stliblink=conf.find_program(lib_name,path_list=path,var='AR') + if not stliblink: + return + v.ARFLAGS=['/nologo'] + if v.MSVC_MANIFEST: + conf.find_program('MT',path_list=path,var='MT') + v.MTFLAGS=['/nologo'] + try: + conf.load('winres') + except Errors.ConfigurationError: + Logs.warn('Resource compiler not found. Compiling resource file is disabled') +@conf +def visual_studio_add_flags(self): + v=self.env + if self.environ.get('INCLUDE'): + v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x]) + if self.environ.get('LIB'): + v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x]) +@conf +def msvc_common_flags(conf): + v=conf.env + v.DEST_BINFMT='pe' + v.append_value('CFLAGS',['/nologo']) + v.append_value('CXXFLAGS',['/nologo']) + v.append_value('LINKFLAGS',['/nologo']) + v.DEFINES_ST='/D%s' + v.CC_SRC_F='' + v.CC_TGT_F=['/c','/Fo'] + v.CXX_SRC_F='' + v.CXX_TGT_F=['/c','/Fo'] + if(v.MSVC_COMPILER=='msvc'and v.MSVC_VERSION>=8)or(v.MSVC_COMPILER=='wsdk'and v.MSVC_VERSION>=6): + v.CC_TGT_F=['/FC']+v.CC_TGT_F + v.CXX_TGT_F=['/FC']+v.CXX_TGT_F + v.CPPPATH_ST='/I%s' + v.AR_TGT_F=v.CCLNK_TGT_F=v.CXXLNK_TGT_F='/OUT:' + v.CFLAGS_CRT_MULTITHREADED=v.CXXFLAGS_CRT_MULTITHREADED=['/MT'] + v.CFLAGS_CRT_MULTITHREADED_DLL=v.CXXFLAGS_CRT_MULTITHREADED_DLL=['/MD'] + v.CFLAGS_CRT_MULTITHREADED_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DBG=['/MTd'] + v.CFLAGS_CRT_MULTITHREADED_DLL_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG=['/MDd'] + v.LIB_ST='%s.lib' + v.LIBPATH_ST='/LIBPATH:%s' + v.STLIB_ST='%s.lib' + v.STLIBPATH_ST='/LIBPATH:%s' + if v.MSVC_MANIFEST: + v.append_value('LINKFLAGS',['/MANIFEST']) + v.CFLAGS_cshlib=[] + v.CXXFLAGS_cxxshlib=[] + v.LINKFLAGS_cshlib=v.LINKFLAGS_cxxshlib=['/DLL'] + v.cshlib_PATTERN=v.cxxshlib_PATTERN='%s.dll' + v.implib_PATTERN='%s.lib' + v.IMPLIB_ST='/IMPLIB:%s' + v.LINKFLAGS_cstlib=[] + v.cstlib_PATTERN=v.cxxstlib_PATTERN='%s.lib' + v.cprogram_PATTERN=v.cxxprogram_PATTERN='%s.exe' + v.def_PATTERN='/def:%s' +@after_method('apply_link') +@feature('c','cxx') +def apply_flags_msvc(self): + if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None): + return + is_static=isinstance(self.link_task,ccroot.stlink_task) + subsystem=getattr(self,'subsystem','') + if subsystem: + subsystem='/subsystem:%s'%subsystem + flags=is_static and'ARFLAGS'or'LINKFLAGS' + self.env.append_value(flags,subsystem) + if not is_static: + for f in self.env.LINKFLAGS: + d=f.lower() + if d[1:]in('debug','debug:full','debug:fastlink'): + pdbnode=self.link_task.outputs[0].change_ext('.pdb') + self.link_task.outputs.append(pdbnode) + if getattr(self,'install_task',None): + self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode) + break +@feature('cprogram','cshlib','cxxprogram','cxxshlib') +@after_method('apply_link') +def apply_manifest(self): + if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None): + out_node=self.link_task.outputs[0] + man_node=out_node.parent.find_or_declare(out_node.name+'.manifest') + self.link_task.outputs.append(man_node) + self.env.DO_MANIFEST=True +def make_winapp(self,family): + append=self.env.append_unique + append('DEFINES','WINAPI_FAMILY=%s'%family) + append('CXXFLAGS',['/ZW','/TP']) + for lib_path in self.env.LIBPATH: + append('CXXFLAGS','/AI%s'%lib_path) +@feature('winphoneapp') +@after_method('process_use') +@after_method('propagate_uselib_vars') +def make_winphone_app(self): + make_winapp(self,'WINAPI_FAMILY_PHONE_APP') + self.env.append_unique('LINKFLAGS',['/NODEFAULTLIB:ole32.lib','PhoneAppModelHost.lib']) +@feature('winapp') +@after_method('process_use') +@after_method('propagate_uselib_vars') +def make_windows_app(self): + make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py new file mode 100755 index 0000000..59067ed --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py @@ -0,0 +1,21 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os +import waflib.Tools.asm +from waflib.TaskGen import feature +@feature('asm') +def apply_nasm_vars(self): + self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[]))) +def configure(conf): + conf.find_program(['nasm','yasm'],var='AS') + conf.env.AS_TGT_F=['-o'] + conf.env.ASLNK_TGT_F=['-o'] + conf.load('asm') + conf.env.ASMPATH_ST='-I%s'+os.sep + txt=conf.cmd_and_log(conf.env.AS+['--version']) + if'yasm'in txt.lower(): + conf.env.ASM_NAME='yasm' + else: + conf.env.ASM_NAME='nasm' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py new file mode 100755 index 0000000..beb2217 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py @@ -0,0 +1,11 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Task +def build(bld): + def run(self): + for x in self.outputs: + x.write('') + for(name,cls)in Task.classes.items(): + cls.run=run diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py new file mode 100755 index 0000000..ee86113 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os +from waflib import Task,Options,Utils,Errors +from waflib.Configure import conf +from waflib.TaskGen import extension,feature,before_method +@before_method('apply_incpaths','apply_link','propagate_uselib_vars') +@feature('perlext') +def init_perlext(self): + self.uselib=self.to_list(getattr(self,'uselib',[])) + if not'PERLEXT'in self.uselib: + self.uselib.append('PERLEXT') + self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.perlext_PATTERN +@extension('.xs') +def xsubpp_file(self,node): + outnode=node.change_ext('.c') + self.create_task('xsubpp',node,outnode) + self.source.append(outnode) +class xsubpp(Task.Task): + run_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}' + color='BLUE' + ext_out=['.h'] +@conf +def check_perl_version(self,minver=None): + res=True + if minver: + cver='.'.join(map(str,minver)) + else: + cver='' + self.start_msg('Checking for minimum perl version %s'%cver) + perl=self.find_program('perl',var='PERL',value=getattr(Options.options,'perlbinary',None)) + version=self.cmd_and_log(perl+["-e",'printf \"%vd\", $^V']) + if not version: + res=False + version="Unknown" + elif not minver is None: + ver=tuple(map(int,version.split("."))) + if ver +#ifdef __cplusplus +extern "C" { +#endif + void Py_Initialize(void); + void Py_Finalize(void); +#ifdef __cplusplus +} +#endif +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + Py_Initialize(); + Py_Finalize(); + return 0; +} +''' +INST=''' +import sys, py_compile +py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True) +''' +DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib'] +@before_method('process_source') +@feature('py') +def feature_py(self): + self.install_path=getattr(self,'install_path','${PYTHONDIR}') + install_from=getattr(self,'install_from',None) + if install_from and not isinstance(install_from,Node.Node): + install_from=self.path.find_dir(install_from) + self.install_from=install_from + ver=self.env.PYTHON_VERSION + if not ver: + self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version') + if int(ver.replace('.',''))>31: + self.install_32=True +@extension('.py') +def process_py(self,node): + assert(hasattr(self,'install_path')),'add features="py" for target "%s" in "%s/wscript".'%(self.target,self.path.nice_path()) + self.install_from=getattr(self,'install_from',None) + relative_trick=getattr(self,'relative_trick',True) + if self.install_from: + assert isinstance(self.install_from,Node.Node),'add features="py" for target "%s" in "%s/wscript" (%s).'%(self.target,self.path.nice_path(),type(self.install_from)) + if self.install_path: + if self.install_from: + self.add_install_files(install_to=self.install_path,install_from=node,cwd=self.install_from,relative_trick=relative_trick) + else: + self.add_install_files(install_to=self.install_path,install_from=node,relative_trick=relative_trick) + lst=[] + if self.env.PYC: + lst.append('pyc') + if self.env.PYO: + lst.append('pyo') + if self.install_path: + if self.install_from: + target_dir=node.path_from(self.install_from)if relative_trick else node.name + pyd=Utils.subst_vars("%s/%s"%(self.install_path,target_dir),self.env) + else: + target_dir=node.path_from(self.path)if relative_trick else node.name + pyd=Utils.subst_vars("%s/%s"%(self.install_path,target_dir),self.env) + else: + pyd=node.abspath() + for ext in lst: + if self.env.PYTAG and not self.env.NOPYCACHE: + name=node.name[:-3] + pyobj=node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s"%(name,self.env.PYTAG,ext)) + pyobj.parent.mkdir() + else: + pyobj=node.change_ext(".%s"%ext) + tsk=self.create_task(ext,node,pyobj) + tsk.pyd=pyd + if self.install_path: + self.add_install_files(install_to=os.path.dirname(pyd),install_from=pyobj,cwd=node.parent.get_bld(),relative_trick=relative_trick) +class pyc(Task.Task): + color='PINK' + def __str__(self): + node=self.outputs[0] + return node.path_from(node.ctx.launch_node()) + def run(self): + cmd=[Utils.subst_vars('${PYTHON}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd] + ret=self.generator.bld.exec_command(cmd) + return ret +class pyo(Task.Task): + color='PINK' + def __str__(self): + node=self.outputs[0] + return node.path_from(node.ctx.launch_node()) + def run(self): + cmd=[Utils.subst_vars('${PYTHON}',self.env),Utils.subst_vars('${PYFLAGS_OPT}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd] + ret=self.generator.bld.exec_command(cmd) + return ret +@feature('pyext') +@before_method('propagate_uselib_vars','apply_link') +@after_method('apply_bundle') +def init_pyext(self): + self.uselib=self.to_list(getattr(self,'uselib',[])) + if not'PYEXT'in self.uselib: + self.uselib.append('PYEXT') + self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN + self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN + try: + if not self.install_path: + return + except AttributeError: + self.install_path='${PYTHONARCHDIR}' +@feature('pyext') +@before_method('apply_link','apply_bundle') +def set_bundle(self): + if Utils.unversioned_sys_platform()=='darwin': + self.mac_bundle=True +@before_method('propagate_uselib_vars') +@feature('pyembed') +def init_pyembed(self): + self.uselib=self.to_list(getattr(self,'uselib',[])) + if not'PYEMBED'in self.uselib: + self.uselib.append('PYEMBED') +@conf +def get_python_variables(self,variables,imports=None): + if not imports: + try: + imports=self.python_imports + except AttributeError: + imports=DISTUTILS_IMP + program=list(imports) + program.append('') + for v in variables: + program.append("print(repr(%s))"%v) + os_env=dict(os.environ) + try: + del os_env['MACOSX_DEPLOYMENT_TARGET'] + except KeyError: + pass + try: + out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env) + except Errors.WafError: + self.fatal('The distutils module is unusable: install "python-devel"?') + self.to_log(out) + return_values=[] + for s in out.splitlines(): + s=s.strip() + if not s: + continue + if s=='None': + return_values.append(None) + elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'): + return_values.append(eval(s)) + elif s[0].isdigit(): + return_values.append(int(s)) + else:break + return return_values +@conf +def test_pyembed(self,mode,msg='Testing pyembed configuration'): + self.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg=msg,fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(mode,mode)) +@conf +def test_pyext(self,mode,msg='Testing pyext configuration'): + self.check(header_name='Python.h',define_name='HAVE_PYEXT',msg=msg,fragment=FRAG,errmsg='Could not build python extensions',features='%s %sshlib pyext'%(mode,mode)) +@conf +def python_cross_compile(self,features='pyembed pyext'): + features=Utils.to_list(features) + if not('PYTHON_LDFLAGS'in self.environ or'PYTHON_PYEXT_LDFLAGS'in self.environ or'PYTHON_PYEMBED_LDFLAGS'in self.environ): + return False + for x in'PYTHON_VERSION PYTAG pyext_PATTERN'.split(): + if not x in self.environ: + self.fatal('Please set %s in the os environment'%x) + else: + self.env[x]=self.environ[x] + xx=self.env.CXX_NAME and'cxx'or'c' + if'pyext'in features: + flags=self.environ.get('PYTHON_PYEXT_LDFLAGS',self.environ.get('PYTHON_LDFLAGS')) + if flags is None: + self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required') + else: + self.parse_flags(flags,'PYEXT') + self.test_pyext(xx) + if'pyembed'in features: + flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS')) + if flags is None: + self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required') + else: + self.parse_flags(flags,'PYEMBED') + self.test_pyembed(xx) + return True +@conf +def check_python_headers(conf,features='pyembed pyext'): + features=Utils.to_list(features) + assert('pyembed'in features)or('pyext'in features),"check_python_headers features must include 'pyembed' and/or 'pyext'" + env=conf.env + if not env.CC_NAME and not env.CXX_NAME: + conf.fatal('load a compiler first (gcc, g++, ..)') + if conf.python_cross_compile(features): + return + if not env.PYTHON_VERSION: + conf.check_python_version() + pybin=env.PYTHON + if not pybin: + conf.fatal('Could not find the python executable') + v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split() + try: + lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v]) + except RuntimeError: + conf.fatal("Python development headers not found (-v for details).") + vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)] + conf.to_log("Configuration returned from %r:\n%s\n"%(pybin,'\n'.join(vals))) + dct=dict(zip(v,lst)) + x='MACOSX_DEPLOYMENT_TARGET' + if dct[x]: + env[x]=conf.environ[x]=dct[x] + env.pyext_PATTERN='%s'+dct['SO'] + num='.'.join(env.PYTHON_VERSION.split('.')[:2]) + conf.find_program([''.join(pybin)+'-config','python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',msg="python-config",mandatory=False) + if env.PYTHON_CONFIG: + if conf.env.HAVE_PYTHON_H: + return + all_flags=[['--cflags','--libs','--ldflags']] + if sys.hexversion<0x2070000: + all_flags=[[k]for k in all_flags[0]] + xx=env.CXX_NAME and'cxx'or'c' + if'pyembed'in features: + for flags in all_flags: + embedflags=flags+['--embed'] + try: + conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(embedflags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=embedflags) + except conf.errors.ConfigurationError: + conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=flags) + try: + conf.test_pyembed(xx) + except conf.errors.ConfigurationError: + if dct['Py_ENABLE_SHARED']and dct['LIBDIR']: + env.append_unique('LIBPATH_PYEMBED',[dct['LIBDIR']]) + conf.test_pyembed(xx) + else: + raise + if'pyext'in features: + for flags in all_flags: + conf.check_cfg(msg='Asking python-config for pyext %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=flags) + try: + conf.test_pyext(xx) + except conf.errors.ConfigurationError: + if dct['Py_ENABLE_SHARED']and dct['LIBDIR']: + env.append_unique('LIBPATH_PYEXT',[dct['LIBDIR']]) + conf.test_pyext(xx) + else: + raise + conf.define('HAVE_PYTHON_H',1) + return + all_flags=dct['LDFLAGS']+' '+dct['CFLAGS'] + conf.parse_flags(all_flags,'PYEMBED') + all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS'] + conf.parse_flags(all_flags,'PYEXT') + result=None + if not dct["LDVERSION"]: + dct["LDVERSION"]=env.PYTHON_VERSION + for name in('python'+dct['LDVERSION'],'python'+env.PYTHON_VERSION+'m','python'+env.PYTHON_VERSION.replace('.','')): + if not result and env.LIBPATH_PYEMBED: + path=env.LIBPATH_PYEMBED + conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path) + result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name) + if not result and dct['LIBDIR']: + path=[dct['LIBDIR']] + conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path) + result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name) + if not result and dct['LIBPL']: + path=[dct['LIBPL']] + conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n") + result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name) + if not result: + path=[os.path.join(dct['prefix'],"libs")] + conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n") + result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name) + if result: + break + if result: + env.LIBPATH_PYEMBED=path + env.append_value('LIB_PYEMBED',[name]) + else: + conf.to_log("\n\n### LIB NOT FOUND\n") + if Utils.is_win32 or dct['Py_ENABLE_SHARED']: + env.LIBPATH_PYEXT=env.LIBPATH_PYEMBED + env.LIB_PYEXT=env.LIB_PYEMBED + conf.to_log("Include path for Python extensions (found via distutils module): %r\n"%(dct['INCLUDEPY'],)) + env.INCLUDES_PYEXT=[dct['INCLUDEPY']] + env.INCLUDES_PYEMBED=[dct['INCLUDEPY']] + if env.CC_NAME=='gcc': + env.append_unique('CFLAGS_PYEMBED',['-fno-strict-aliasing']) + env.append_unique('CFLAGS_PYEXT',['-fno-strict-aliasing']) + if env.CXX_NAME=='gcc': + env.append_unique('CXXFLAGS_PYEMBED',['-fno-strict-aliasing']) + env.append_unique('CXXFLAGS_PYEXT',['-fno-strict-aliasing']) + if env.CC_NAME=="msvc": + from distutils.msvccompiler import MSVCCompiler + dist_compiler=MSVCCompiler() + dist_compiler.initialize() + env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options) + env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options) + env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared) + conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg='Distutils not installed? Broken python installation? Get python-config now!') +@conf +def check_python_version(conf,minver=None): + assert minver is None or isinstance(minver,tuple) + pybin=conf.env.PYTHON + if not pybin: + conf.fatal('could not find the python executable') + cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))'] + Logs.debug('python: Running python command %r',cmd) + lines=conf.cmd_and_log(cmd).split() + assert len(lines)==5,"found %r lines, expected 5: %r"%(len(lines),lines) + pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4])) + result=(minver is None)or(pyver_tuple>=minver) + if result: + pyver='.'.join([str(x)for x in pyver_tuple[:2]]) + conf.env.PYTHON_VERSION=pyver + if'PYTHONDIR'in conf.env: + pydir=conf.env.PYTHONDIR + elif'PYTHONDIR'in conf.environ: + pydir=conf.environ['PYTHONDIR'] + else: + if Utils.is_win32: + (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"]) + else: + python_LIBDEST=None + (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX]) + if python_LIBDEST is None: + if conf.env.LIBDIR: + python_LIBDEST=os.path.join(conf.env.LIBDIR,'python'+pyver) + else: + python_LIBDEST=os.path.join(conf.env.PREFIX,'lib','python'+pyver) + if'PYTHONARCHDIR'in conf.env: + pyarchdir=conf.env.PYTHONARCHDIR + elif'PYTHONARCHDIR'in conf.environ: + pyarchdir=conf.environ['PYTHONARCHDIR'] + else: + (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX]) + if not pyarchdir: + pyarchdir=pydir + if hasattr(conf,'define'): + conf.define('PYTHONDIR',pydir) + conf.define('PYTHONARCHDIR',pyarchdir) + conf.env.PYTHONDIR=pydir + conf.env.PYTHONARCHDIR=pyarchdir + pyver_full='.'.join(map(str,pyver_tuple[:3])) + if minver is None: + conf.msg('Checking for python version',pyver_full) + else: + minver_str='.'.join(map(str,minver)) + conf.msg('Checking for python version >= %s'%(minver_str,),pyver_full,color=result and'GREEN'or'YELLOW') + if not result: + conf.fatal('The python version is too old, expecting %r'%(minver,)) +PYTHON_MODULE_TEMPLATE=''' +import %s as current_module +version = getattr(current_module, '__version__', None) +if version is not None: + print(str(version)) +else: + print('unknown version') +''' +@conf +def check_python_module(conf,module_name,condition=''): + msg="Checking for python module %r"%module_name + if condition: + msg='%s (%s)'%(msg,condition) + conf.start_msg(msg) + try: + ret=conf.cmd_and_log(conf.env.PYTHON+['-c',PYTHON_MODULE_TEMPLATE%module_name]) + except Errors.WafError: + conf.end_msg(False) + conf.fatal('Could not find the python module %r'%module_name) + ret=ret.strip() + if condition: + conf.end_msg(ret) + if ret=='unknown version': + conf.fatal('Could not check the %s version'%module_name) + from distutils.version import LooseVersion + def num(*k): + if isinstance(k[0],int): + return LooseVersion('.'.join([str(x)for x in k])) + else: + return LooseVersion(k[0]) + d={'num':num,'ver':LooseVersion(ret)} + ev=eval(condition,{},d) + if not ev: + conf.fatal('The %s version does not satisfy the requirements'%module_name) + else: + if ret=='unknown version': + conf.end_msg(True) + else: + conf.end_msg(ret) +def configure(conf): + v=conf.env + if getattr(Options.options,'pythondir',None): + v.PYTHONDIR=Options.options.pythondir + if getattr(Options.options,'pythonarchdir',None): + v.PYTHONARCHDIR=Options.options.pythonarchdir + if getattr(Options.options,'nopycache',None): + v.NOPYCACHE=Options.options.nopycache + if not v.PYTHON: + v.PYTHON=[getattr(Options.options,'python',None)or sys.executable] + v.PYTHON=Utils.to_list(v.PYTHON) + conf.find_program('python',var='PYTHON') + v.PYFLAGS='' + v.PYFLAGS_OPT='-O' + v.PYC=getattr(Options.options,'pyc',1) + v.PYO=getattr(Options.options,'pyo',1) + try: + v.PYTAG=conf.cmd_and_log(conf.env.PYTHON+['-c',"import imp;print(imp.get_tag())"]).strip() + except Errors.WafError: + pass +def options(opt): + pyopt=opt.add_option_group("Python Options") + pyopt.add_option('--nopyc',dest='pyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]') + pyopt.add_option('--nopyo',dest='pyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]') + pyopt.add_option('--nopycache',dest='nopycache',action='store_true',help='Do not use __pycache__ directory to install objects [Default:auto]') + pyopt.add_option('--python',dest="python",help='python binary to be used [Default: %s]'%sys.executable) + pyopt.add_option('--pythondir',dest='pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)') + pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py new file mode 100755 index 0000000..ea97019 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py @@ -0,0 +1,499 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from __future__ import with_statement +try: + from xml.sax import make_parser + from xml.sax.handler import ContentHandler +except ImportError: + has_xml=False + ContentHandler=object +else: + has_xml=True +import os,sys,re +from waflib.Tools import cxx +from waflib import Build,Task,Utils,Options,Errors,Context +from waflib.TaskGen import feature,after_method,extension,before_method +from waflib.Configure import conf +from waflib import Logs +MOC_H=['.h','.hpp','.hxx','.hh'] +EXT_RCC=['.qrc'] +EXT_UI=['.ui'] +EXT_QT5=['.cpp','.cc','.cxx','.C'] +class qxx(Task.classes['cxx']): + def __init__(self,*k,**kw): + Task.Task.__init__(self,*k,**kw) + self.moc_done=0 + def runnable_status(self): + if self.moc_done: + return Task.Task.runnable_status(self) + else: + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + self.add_moc_tasks() + return Task.Task.runnable_status(self) + def create_moc_task(self,h_node,m_node): + try: + moc_cache=self.generator.bld.moc_cache + except AttributeError: + moc_cache=self.generator.bld.moc_cache={} + try: + return moc_cache[h_node] + except KeyError: + tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator) + tsk.set_inputs(h_node) + tsk.set_outputs(m_node) + tsk.env.append_unique('MOC_FLAGS','-i') + if self.generator: + self.generator.tasks.append(tsk) + gen=self.generator.bld.producer + gen.outstanding.append(tsk) + gen.total+=1 + return tsk + else: + delattr(self,'cache_sig') + def add_moc_tasks(self): + node=self.inputs[0] + bld=self.generator.bld + if bld.is_install==Build.UNINSTALL: + return + try: + self.signature() + except KeyError: + pass + else: + delattr(self,'cache_sig') + include_nodes=[node.parent]+self.generator.includes_nodes + moctasks=[] + mocfiles=set() + for d in bld.raw_deps.get(self.uid(),[]): + if not d.endswith('.moc'): + continue + if d in mocfiles: + continue + mocfiles.add(d) + h_node=None + base2=d[:-4] + prefix=node.name[:node.name.rfind('.')] + if base2==prefix: + h_node=node + else: + for x in include_nodes: + for e in MOC_H: + h_node=x.find_node(base2+e) + if h_node: + break + else: + continue + break + if h_node: + m_node=h_node.change_ext('.moc') + else: + raise Errors.WafError('No source found for %r which is a moc file'%d) + task=self.create_moc_task(h_node,m_node) + moctasks.append(task) + self.run_after.update(set(moctasks)) + self.moc_done=1 +class trans_update(Task.Task): + run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}' + color='BLUE' +class XMLHandler(ContentHandler): + def __init__(self): + ContentHandler.__init__(self) + self.buf=[] + self.files=[] + def startElement(self,name,attrs): + if name=='file': + self.buf=[] + def endElement(self,name): + if name=='file': + self.files.append(str(''.join(self.buf))) + def characters(self,cars): + self.buf.append(cars) +@extension(*EXT_RCC) +def create_rcc_task(self,node): + rcnode=node.change_ext('_rc.%d.cpp'%self.idx) + self.create_task('rcc',node,rcnode) + cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o')) + try: + self.compiled_tasks.append(cpptask) + except AttributeError: + self.compiled_tasks=[cpptask] + return cpptask +@extension(*EXT_UI) +def create_uic_task(self,node): + try: + uic_cache=self.bld.uic_cache + except AttributeError: + uic_cache=self.bld.uic_cache={} + if node not in uic_cache: + uictask=uic_cache[node]=self.create_task('ui5',node) + uictask.outputs=[node.parent.find_or_declare(self.env.ui_PATTERN%node.name[:-3])] +@extension('.ts') +def add_lang(self,node): + self.lang=self.to_list(getattr(self,'lang',[]))+[node] +@feature('qt5') +@before_method('process_source') +def process_mocs(self): + lst=self.to_nodes(getattr(self,'moc',[])) + self.source=self.to_list(getattr(self,'source',[])) + for x in lst: + prefix=x.name[:x.name.rfind('.')] + moc_target='moc_%s.%d.cpp'%(prefix,self.idx) + moc_node=x.parent.find_or_declare(moc_target) + self.source.append(moc_node) + self.create_task('moc',x,moc_node) +@feature('qt5') +@after_method('apply_link') +def apply_qt5(self): + if getattr(self,'lang',None): + qmtasks=[] + for x in self.to_list(self.lang): + if isinstance(x,str): + x=self.path.find_resource(x+'.ts') + qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.%d.qm'%self.idx))) + if getattr(self,'update',None)and Options.options.trans_qt5: + cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if a.inputs and a.inputs[0].name.endswith('.ui')] + for x in qmtasks: + self.create_task('trans_update',cxxnodes,x.inputs) + if getattr(self,'langname',None): + qmnodes=[x.outputs[0]for x in qmtasks] + rcnode=self.langname + if isinstance(rcnode,str): + rcnode=self.path.find_or_declare(rcnode+('.%d.qrc'%self.idx)) + t=self.create_task('qm2rcc',qmnodes,rcnode) + k=create_rcc_task(self,t.outputs[0]) + self.link_task.inputs.append(k.outputs[0]) + lst=[] + for flag in self.to_list(self.env.CXXFLAGS): + if len(flag)<2: + continue + f=flag[0:2] + if f in('-D','-I','/D','/I'): + if(f[0]=='/'): + lst.append('-'+flag[1:]) + else: + lst.append(flag) + self.env.append_value('MOC_FLAGS',lst) +@extension(*EXT_QT5) +def cxx_hook(self,node): + return self.create_compiled_task('qxx',node) +class rcc(Task.Task): + color='BLUE' + run_str='${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' + ext_out=['.h'] + def rcname(self): + return os.path.splitext(self.inputs[0].name)[0] + def scan(self): + if not has_xml: + Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') + return([],[]) + parser=make_parser() + curHandler=XMLHandler() + parser.setContentHandler(curHandler) + with open(self.inputs[0].abspath(),'r')as f: + parser.parse(f) + nodes=[] + names=[] + root=self.inputs[0].parent + for x in curHandler.files: + nd=root.find_resource(x) + if nd: + nodes.append(nd) + else: + names.append(x) + return(nodes,names) + def quote_flag(self,x): + return x +class moc(Task.Task): + color='BLUE' + run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' + def quote_flag(self,x): + return x +class ui5(Task.Task): + color='BLUE' + run_str='${QT_UIC} ${SRC} -o ${TGT}' + ext_out=['.h'] +class ts2qm(Task.Task): + color='BLUE' + run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' +class qm2rcc(Task.Task): + color='BLUE' + after='ts2qm' + def run(self): + txt='\n'.join(['%s'%k.path_from(self.outputs[0].parent)for k in self.inputs]) + code='\n\n%s\n\n'%txt + self.outputs[0].write(code) +def configure(self): + self.find_qt5_binaries() + self.set_qt5_libs_dir() + self.set_qt5_libs_to_check() + self.set_qt5_defines() + self.find_qt5_libraries() + self.add_qt5_rpath() + self.simplify_qt5_libs() + if not has_xml: + Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') + if'COMPILER_CXX'not in self.env: + self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?') + frag='#include \nint main(int argc, char **argv) {return 0;}\n' + uses='QT5CORE QT5WIDGETS QT5GUI' + for flag in[[],'-fPIE','-fPIC','-std=c++11',['-std=c++11','-fPIE'],['-std=c++11','-fPIC']]: + msg='See if Qt files compile ' + if flag: + msg+='with %s'%flag + try: + self.check(features='qt5 cxx',use=uses,uselib_store='qt5',cxxflags=flag,fragment=frag,msg=msg) + except self.errors.ConfigurationError: + pass + else: + break + else: + self.fatal('Could not build a simple Qt application') + if Utils.unversioned_sys_platform()=='freebsd': + frag='#include \nint main(int argc, char **argv) { QApplication app(argc, argv); return NULL != (void*) (&app);}\n' + try: + self.check(features='qt5 cxx cxxprogram',use=uses,fragment=frag,msg='Can we link Qt programs on FreeBSD directly?') + except self.errors.ConfigurationError: + self.check(features='qt5 cxx cxxprogram',use=uses,uselib_store='qt5',libpath='/usr/local/lib',fragment=frag,msg='Is /usr/local/lib required?') +@conf +def find_qt5_binaries(self): + env=self.env + opt=Options.options + qtdir=getattr(opt,'qtdir','') + qtbin=getattr(opt,'qtbin','') + paths=[] + if qtdir: + qtbin=os.path.join(qtdir,'bin') + if not qtdir: + qtdir=self.environ.get('QT5_ROOT','') + qtbin=self.environ.get('QT5_BIN')or os.path.join(qtdir,'bin') + if qtbin: + paths=[qtbin] + if not qtdir: + paths=self.environ.get('PATH','').split(os.pathsep) + paths.extend(['/usr/share/qt5/bin','/usr/local/lib/qt5/bin']) + try: + lst=Utils.listdir('/usr/local/Trolltech/') + except OSError: + pass + else: + if lst: + lst.sort() + lst.reverse() + qtdir='/usr/local/Trolltech/%s/'%lst[0] + qtbin=os.path.join(qtdir,'bin') + paths.append(qtbin) + cand=None + prev_ver=['5','0','0'] + for qmk in('qmake-qt5','qmake5','qmake'): + try: + qmake=self.find_program(qmk,path_list=paths) + except self.errors.ConfigurationError: + pass + else: + try: + version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip() + except self.errors.WafError: + pass + else: + if version: + new_ver=version.split('.') + if new_ver>prev_ver: + cand=qmake + prev_ver=new_ver + if not cand: + try: + self.find_program('qtchooser') + except self.errors.ConfigurationError: + pass + else: + cmd=self.env.QTCHOOSER+['-qt=5','-run-tool=qmake'] + try: + version=self.cmd_and_log(cmd+['-query','QT_VERSION']) + except self.errors.WafError: + pass + else: + cand=cmd + if cand: + self.env.QMAKE=cand + else: + self.fatal('Could not find qmake for qt5') + self.env.QT_HOST_BINS=qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_HOST_BINS']).strip() + paths.insert(0,qtbin) + def find_bin(lst,var): + if var in env: + return + for f in lst: + try: + ret=self.find_program(f,path_list=paths) + except self.errors.ConfigurationError: + pass + else: + env[var]=ret + break + find_bin(['uic-qt5','uic'],'QT_UIC') + if not env.QT_UIC: + self.fatal('cannot find the uic compiler for qt5') + self.start_msg('Checking for uic version') + uicver=self.cmd_and_log(env.QT_UIC+['-version'],output=Context.BOTH) + uicver=''.join(uicver).strip() + uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','') + self.end_msg(uicver) + if uicver.find(' 3.')!=-1 or uicver.find(' 4.')!=-1: + self.fatal('this uic compiler is for qt3 or qt4, add uic for qt5 to your path') + find_bin(['moc-qt5','moc'],'QT_MOC') + find_bin(['rcc-qt5','rcc'],'QT_RCC') + find_bin(['lrelease-qt5','lrelease'],'QT_LRELEASE') + find_bin(['lupdate-qt5','lupdate'],'QT_LUPDATE') + env.UIC_ST='%s -o %s' + env.MOC_ST='-o' + env.ui_PATTERN='ui_%s.h' + env.QT_LRELEASE_FLAGS=['-silent'] + env.MOCCPPPATH_ST='-I%s' + env.MOCDEFINES_ST='-D%s' +@conf +def set_qt5_libs_dir(self): + env=self.env + qtlibs=getattr(Options.options,'qtlibs',None)or self.environ.get('QT5_LIBDIR') + if not qtlibs: + try: + qtlibs=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_LIBS']).strip() + except Errors.WafError: + qtdir=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip() + qtlibs=os.path.join(qtdir,'lib') + self.msg('Found the Qt5 libraries in',qtlibs) + env.QTLIBS=qtlibs +@conf +def find_single_qt5_lib(self,name,uselib,qtlibs,qtincludes,force_static): + env=self.env + if force_static: + exts=('.a','.lib') + prefix='STLIB' + else: + exts=('.so','.lib') + prefix='LIB' + def lib_names(): + for x in exts: + for k in('','5')if Utils.is_win32 else['']: + for p in('lib',''): + yield(p,name,k,x) + for tup in lib_names(): + k=''.join(tup) + path=os.path.join(qtlibs,k) + if os.path.exists(path): + if env.DEST_OS=='win32': + libval=''.join(tup[:-1]) + else: + libval=name + env.append_unique(prefix+'_'+uselib,libval) + env.append_unique('%sPATH_%s'%(prefix,uselib),qtlibs) + env.append_unique('INCLUDES_'+uselib,qtincludes) + env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,name.replace('Qt5','Qt'))) + return k + return False +@conf +def find_qt5_libraries(self): + env=self.env + qtincludes=self.environ.get('QT5_INCLUDES')or self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip() + force_static=self.environ.get('QT5_FORCE_STATIC') + try: + if self.environ.get('QT5_XCOMPILE'): + self.fatal('QT5_XCOMPILE Disables pkg-config detection') + self.check_cfg(atleast_pkgconfig_version='0.1') + except self.errors.ConfigurationError: + for i in self.qt5_vars: + uselib=i.upper() + if Utils.unversioned_sys_platform()=='darwin': + fwk=i.replace('Qt5','Qt') + frameworkName=fwk+'.framework' + qtDynamicLib=os.path.join(env.QTLIBS,frameworkName,fwk) + if os.path.exists(qtDynamicLib): + env.append_unique('FRAMEWORK_'+uselib,fwk) + env.append_unique('FRAMEWORKPATH_'+uselib,env.QTLIBS) + self.msg('Checking for %s'%i,qtDynamicLib,'GREEN') + else: + self.msg('Checking for %s'%i,False,'YELLOW') + env.append_unique('INCLUDES_'+uselib,os.path.join(env.QTLIBS,frameworkName,'Headers')) + else: + ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,force_static) + if not force_static and not ret: + ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,True) + self.msg('Checking for %s'%i,ret,'GREEN'if ret else'YELLOW') + else: + path='%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(self.environ.get('PKG_CONFIG_PATH',''),env.QTLIBS,env.QTLIBS) + for i in self.qt5_vars: + self.check_cfg(package=i,args='--cflags --libs',mandatory=False,force_static=force_static,pkg_config_path=path) +@conf +def simplify_qt5_libs(self): + env=self.env + def process_lib(vars_,coreval): + for d in vars_: + var=d.upper() + if var=='QTCORE': + continue + value=env['LIBPATH_'+var] + if value: + core=env[coreval] + accu=[] + for lib in value: + if lib in core: + continue + accu.append(lib) + env['LIBPATH_'+var]=accu + process_lib(self.qt5_vars,'LIBPATH_QTCORE') +@conf +def add_qt5_rpath(self): + env=self.env + if getattr(Options.options,'want_rpath',False): + def process_rpath(vars_,coreval): + for d in vars_: + var=d.upper() + value=env['LIBPATH_'+var] + if value: + core=env[coreval] + accu=[] + for lib in value: + if var!='QTCORE': + if lib in core: + continue + accu.append('-Wl,--rpath='+lib) + env['RPATH_'+var]=accu + process_rpath(self.qt5_vars,'LIBPATH_QTCORE') +@conf +def set_qt5_libs_to_check(self): + self.qt5_vars=Utils.to_list(getattr(self,'qt5_vars',[])) + if not self.qt5_vars: + dirlst=Utils.listdir(self.env.QTLIBS) + pat=self.env.cxxshlib_PATTERN + if Utils.is_win32: + pat=pat.replace('.dll','.lib') + if self.environ.get('QT5_FORCE_STATIC'): + pat=self.env.cxxstlib_PATTERN + if Utils.unversioned_sys_platform()=='darwin': + pat=r"%s\.framework" + re_qt=re.compile(pat%'Qt5?(?P.*)'+'$') + for x in dirlst: + m=re_qt.match(x) + if m: + self.qt5_vars.append("Qt5%s"%m.group('name')) + if not self.qt5_vars: + self.fatal('cannot find any Qt5 library (%r)'%self.env.QTLIBS) + qtextralibs=getattr(Options.options,'qtextralibs',None) + if qtextralibs: + self.qt5_vars.extend(qtextralibs.split(',')) +@conf +def set_qt5_defines(self): + if sys.platform!='win32': + return + for x in self.qt5_vars: + y=x.replace('Qt5','Qt')[2:].upper() + self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y) +def options(opt): + opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries') + for i in'qtdir qtbin qtlibs'.split(): + opt.add_option('--'+i,type='string',default='',dest=i) + opt.add_option('--translate',action='store_true',help='collect translation strings',dest='trans_qt5',default=False) + opt.add_option('--qtextralibs',type='string',default='',dest='qtextralibs',help='additional qt libraries on the system to add to default ones, comma separated') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py new file mode 100755 index 0000000..887234f --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py @@ -0,0 +1,97 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os +from waflib import Errors,Options,Task,Utils +from waflib.TaskGen import before_method,feature,extension +from waflib.Configure import conf +@feature('rubyext') +@before_method('apply_incpaths','process_source','apply_bundle','apply_link') +def init_rubyext(self): + self.install_path='${ARCHDIR_RUBY}' + self.uselib=self.to_list(getattr(self,'uselib','')) + if not'RUBY'in self.uselib: + self.uselib.append('RUBY') + if not'RUBYEXT'in self.uselib: + self.uselib.append('RUBYEXT') +@feature('rubyext') +@before_method('apply_link','propagate_uselib_vars') +def apply_ruby_so_name(self): + self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.rubyext_PATTERN +@conf +def check_ruby_version(self,minver=()): + ruby=self.find_program('ruby',var='RUBY',value=Options.options.rubybinary) + try: + version=self.cmd_and_log(ruby+['-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip() + except Errors.WafError: + self.fatal('could not determine ruby version') + self.env.RUBY_VERSION=version + try: + ver=tuple(map(int,version.split('.'))) + except Errors.WafError: + self.fatal('unsupported ruby version %r'%version) + cver='' + if minver: + cver='> '+'.'.join(str(x)for x in minver) + if ver=(1,9,0): + ruby_hdrdir=read_config('rubyhdrdir') + cpppath+=ruby_hdrdir + if version>=(2,0,0): + cpppath+=read_config('rubyarchhdrdir') + cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])] + self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file',link_header_test=False) + self.env.LIBPATH_RUBYEXT=read_config('libdir') + self.env.LIBPATH_RUBYEXT+=archdir + self.env.INCLUDES_RUBYEXT=cpppath + self.env.CFLAGS_RUBYEXT=read_config('CCDLFLAGS') + self.env.rubyext_PATTERN='%s.'+read_config('DLEXT')[0] + flags=read_config('LDSHARED') + while flags and flags[0][0]!='-': + flags=flags[1:] + if len(flags)>1 and flags[1]=="ppc": + flags=flags[2:] + self.env.LINKFLAGS_RUBYEXT=flags + self.env.LINKFLAGS_RUBYEXT+=read_config('LIBS') + self.env.LINKFLAGS_RUBYEXT+=read_config('LIBRUBYARG_SHARED') + if Options.options.rubyarchdir: + self.env.ARCHDIR_RUBY=Options.options.rubyarchdir + else: + self.env.ARCHDIR_RUBY=read_config('sitearchdir')[0] + if Options.options.rubylibdir: + self.env.LIBDIR_RUBY=Options.options.rubylibdir + else: + self.env.LIBDIR_RUBY=read_config('sitelibdir')[0] +@conf +def check_ruby_module(self,module_name): + self.start_msg('Ruby module %s'%module_name) + try: + self.cmd_and_log(self.env.RUBY+['-e','require \'%s\';puts 1'%module_name]) + except Errors.WafError: + self.end_msg(False) + self.fatal('Could not find the ruby module %r'%module_name) + self.end_msg(True) +@extension('.rb') +def process(self,node): + return self.create_task('run_ruby',node) +class run_ruby(Task.Task): + run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}' +def options(opt): + opt.add_option('--with-ruby-archdir',type='string',dest='rubyarchdir',help='Specify directory where to install arch specific files') + opt.add_option('--with-ruby-libdir',type='string',dest='rubylibdir',help='Specify alternate ruby library path') + opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py new file mode 100755 index 0000000..676c884 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py @@ -0,0 +1,48 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Errors +from waflib.Tools import ccroot,ar +from waflib.Configure import conf +@conf +def find_scc(conf): + v=conf.env + cc=conf.find_program('cc',var='CC') + try: + conf.cmd_and_log(cc+['-flags']) + except Errors.WafError: + conf.fatal('%r is not a Sun compiler'%cc) + v.CC_NAME='sun' + conf.get_suncc_version(cc) +@conf +def scc_common_flags(conf): + v=conf.env + v.CC_SRC_F=[] + v.CC_TGT_F=['-c','-o',''] + if not v.LINK_CC: + v.LINK_CC=v.CC + v.CCLNK_SRC_F='' + v.CCLNK_TGT_F=['-o',''] + v.CPPPATH_ST='-I%s' + v.DEFINES_ST='-D%s' + v.LIB_ST='-l%s' + v.LIBPATH_ST='-L%s' + v.STLIB_ST='-l%s' + v.STLIBPATH_ST='-L%s' + v.SONAME_ST='-Wl,-h,%s' + v.SHLIB_MARKER='-Bdynamic' + v.STLIB_MARKER='-Bstatic' + v.cprogram_PATTERN='%s' + v.CFLAGS_cshlib=['-xcode=pic32','-DPIC'] + v.LINKFLAGS_cshlib=['-G'] + v.cshlib_PATTERN='lib%s.so' + v.LINKFLAGS_cstlib=['-Bstatic'] + v.cstlib_PATTERN='lib%s.a' +def configure(conf): + conf.find_scc() + conf.find_ar() + conf.scc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py new file mode 100755 index 0000000..0047098 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py @@ -0,0 +1,48 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib import Errors +from waflib.Tools import ccroot,ar +from waflib.Configure import conf +@conf +def find_sxx(conf): + v=conf.env + cc=conf.find_program(['CC','c++'],var='CXX') + try: + conf.cmd_and_log(cc+['-flags']) + except Errors.WafError: + conf.fatal('%r is not a Sun compiler'%cc) + v.CXX_NAME='sun' + conf.get_suncc_version(cc) +@conf +def sxx_common_flags(conf): + v=conf.env + v.CXX_SRC_F=[] + v.CXX_TGT_F=['-c','-o',''] + if not v.LINK_CXX: + v.LINK_CXX=v.CXX + v.CXXLNK_SRC_F=[] + v.CXXLNK_TGT_F=['-o',''] + v.CPPPATH_ST='-I%s' + v.DEFINES_ST='-D%s' + v.LIB_ST='-l%s' + v.LIBPATH_ST='-L%s' + v.STLIB_ST='-l%s' + v.STLIBPATH_ST='-L%s' + v.SONAME_ST='-Wl,-h,%s' + v.SHLIB_MARKER='-Bdynamic' + v.STLIB_MARKER='-Bstatic' + v.cxxprogram_PATTERN='%s' + v.CXXFLAGS_cxxshlib=['-xcode=pic32','-DPIC'] + v.LINKFLAGS_cxxshlib=['-G'] + v.cxxshlib_PATTERN='lib%s.so' + v.LINKFLAGS_cxxstlib=['-Bstatic'] + v.cxxstlib_PATTERN='lib%s.a' +def configure(conf): + conf.find_sxx() + conf.find_ar() + conf.sxx_common_flags() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py new file mode 100755 index 0000000..3a208d8 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py @@ -0,0 +1,327 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re +from waflib import Utils,Task,Errors,Logs,Node +from waflib.TaskGen import feature,before_method +re_bibunit=re.compile(r'\\(?Pputbib)\[(?P[^\[\]]*)\]',re.M) +def bibunitscan(self): + node=self.inputs[0] + nodes=[] + if not node: + return nodes + code=node.read() + for match in re_bibunit.finditer(code): + path=match.group('file') + if path: + found=None + for k in('','.bib'): + Logs.debug('tex: trying %s%s',path,k) + fi=node.parent.find_resource(path+k) + if fi: + found=True + nodes.append(fi) + if not found: + Logs.debug('tex: could not find %s',path) + Logs.debug('tex: found the following bibunit files: %s',nodes) + return nodes +exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps','.sty'] +exts_tex=['.ltx','.tex'] +re_tex=re.compile(r'\\(?Pusepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P[^{}]*)}',re.M) +g_bibtex_re=re.compile('bibdata',re.M) +g_glossaries_re=re.compile('\\@newglossary',re.M) +class tex(Task.Task): + bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False) + bibtex_fun.__doc__=""" + Execute the program **bibtex** + """ + makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False) + makeindex_fun.__doc__=""" + Execute the program **makeindex** + """ + makeglossaries_fun,_=Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}',shell=False) + makeglossaries_fun.__doc__=""" + Execute the program **makeglossaries** + """ + def exec_command(self,cmd,**kw): + if self.env.PROMPT_LATEX: + kw['stdout']=kw['stderr']=None + return super(tex,self).exec_command(cmd,**kw) + def scan_aux(self,node): + nodes=[node] + re_aux=re.compile(r'\\@input{(?P[^{}]*)}',re.M) + def parse_node(node): + code=node.read() + for match in re_aux.finditer(code): + path=match.group('file') + found=node.parent.find_or_declare(path) + if found and found not in nodes: + Logs.debug('tex: found aux node %r',found) + nodes.append(found) + parse_node(found) + parse_node(node) + return nodes + def scan(self): + node=self.inputs[0] + nodes=[] + names=[] + seen=[] + if not node: + return(nodes,names) + def parse_node(node): + if node in seen: + return + seen.append(node) + code=node.read() + for match in re_tex.finditer(code): + multibib=match.group('type') + if multibib and multibib.startswith('bibliography'): + multibib=multibib[len('bibliography'):] + if multibib.startswith('style'): + continue + else: + multibib=None + for path in match.group('file').split(','): + if path: + add_name=True + found=None + for k in exts_deps_tex: + for up in self.texinputs_nodes: + Logs.debug('tex: trying %s%s',path,k) + found=up.find_resource(path+k) + if found: + break + for tsk in self.generator.tasks: + if not found or found in tsk.outputs: + break + else: + nodes.append(found) + add_name=False + for ext in exts_tex: + if found.name.endswith(ext): + parse_node(found) + break + if found and multibib and found.name.endswith('.bib'): + try: + self.multibibs.append(found) + except AttributeError: + self.multibibs=[found] + if add_name: + names.append(path) + parse_node(node) + for x in nodes: + x.parent.get_bld().mkdir() + Logs.debug("tex: found the following : %s and names %s",nodes,names) + return(nodes,names) + def check_status(self,msg,retcode): + if retcode!=0: + raise Errors.WafError('%r command exit status %r'%(msg,retcode)) + def info(self,*k,**kw): + try: + info=self.generator.bld.conf.logger.info + except AttributeError: + info=Logs.info + info(*k,**kw) + def bibfile(self): + for aux_node in self.aux_nodes: + try: + ct=aux_node.read() + except EnvironmentError: + Logs.error('Error reading %s: %r',aux_node.abspath()) + continue + if g_bibtex_re.findall(ct): + self.info('calling bibtex') + self.env.env={} + self.env.env.update(os.environ) + self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}) + self.env.SRCFILE=aux_node.name[:-4] + self.check_status('error when calling bibtex',self.bibtex_fun()) + for node in getattr(self,'multibibs',[]): + self.env.env={} + self.env.env.update(os.environ) + self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}) + self.env.SRCFILE=node.name[:-4] + self.check_status('error when calling bibtex',self.bibtex_fun()) + def bibunits(self): + try: + bibunits=bibunitscan(self) + except OSError: + Logs.error('error bibunitscan') + else: + if bibunits: + fn=['bu'+str(i)for i in range(1,len(bibunits)+1)] + if fn: + self.info('calling bibtex on bibunits') + for f in fn: + self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()} + self.env.SRCFILE=f + self.check_status('error when calling bibtex',self.bibtex_fun()) + def makeindex(self): + self.idx_node=self.inputs[0].change_ext('.idx') + try: + idx_path=self.idx_node.abspath() + os.stat(idx_path) + except OSError: + self.info('index file %s absent, not calling makeindex',idx_path) + else: + self.info('calling makeindex') + self.env.SRCFILE=self.idx_node.name + self.env.env={} + self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun()) + def bibtopic(self): + p=self.inputs[0].parent.get_bld() + if os.path.exists(os.path.join(p.abspath(),'btaux.aux')): + self.aux_nodes+=p.ant_glob('*[0-9].aux') + def makeglossaries(self): + src_file=self.inputs[0].abspath() + base_file=os.path.basename(src_file) + base,_=os.path.splitext(base_file) + for aux_node in self.aux_nodes: + try: + ct=aux_node.read() + except EnvironmentError: + Logs.error('Error reading %s: %r',aux_node.abspath()) + continue + if g_glossaries_re.findall(ct): + if not self.env.MAKEGLOSSARIES: + raise Errors.WafError("The program 'makeglossaries' is missing!") + Logs.warn('calling makeglossaries') + self.env.SRCFILE=base + self.check_status('error when calling makeglossaries %s'%base,self.makeglossaries_fun()) + return + def texinputs(self): + return os.pathsep.join([k.abspath()for k in self.texinputs_nodes])+os.pathsep + def run(self): + env=self.env + if not env.PROMPT_LATEX: + env.append_value('LATEXFLAGS','-interaction=batchmode') + env.append_value('PDFLATEXFLAGS','-interaction=batchmode') + env.append_value('XELATEXFLAGS','-interaction=batchmode') + self.cwd=self.inputs[0].parent.get_bld() + self.info('first pass on %s',self.__class__.__name__) + cur_hash=self.hash_aux_nodes() + self.call_latex() + self.hash_aux_nodes() + self.bibtopic() + self.bibfile() + self.bibunits() + self.makeindex() + self.makeglossaries() + for i in range(10): + prev_hash=cur_hash + cur_hash=self.hash_aux_nodes() + if not cur_hash: + Logs.error('No aux.h to process') + if cur_hash and cur_hash==prev_hash: + break + self.info('calling %s',self.__class__.__name__) + self.call_latex() + def hash_aux_nodes(self): + try: + self.aux_nodes + except AttributeError: + try: + self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux')) + except IOError: + return None + return Utils.h_list([Utils.h_file(x.abspath())for x in self.aux_nodes]) + def call_latex(self): + self.env.env={} + self.env.env.update(os.environ) + self.env.env.update({'TEXINPUTS':self.texinputs()}) + self.env.SRCFILE=self.inputs[0].abspath() + self.check_status('error when calling latex',self.texfun()) +class latex(tex): + texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False) +class pdflatex(tex): + texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False) +class xelatex(tex): + texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False) +class dvips(Task.Task): + run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}' + color='BLUE' + after=['latex','pdflatex','xelatex'] +class dvipdf(Task.Task): + run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}' + color='BLUE' + after=['latex','pdflatex','xelatex'] +class pdf2ps(Task.Task): + run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}' + color='BLUE' + after=['latex','pdflatex','xelatex'] +@feature('tex') +@before_method('process_source') +def apply_tex(self): + if not getattr(self,'type',None)in('latex','pdflatex','xelatex'): + self.type='pdflatex' + outs=Utils.to_list(getattr(self,'outs',[])) + try: + self.generator.bld.conf + except AttributeError: + default_prompt=False + else: + default_prompt=True + self.env.PROMPT_LATEX=getattr(self,'prompt',default_prompt) + deps_lst=[] + if getattr(self,'deps',None): + deps=self.to_list(self.deps) + for dep in deps: + if isinstance(dep,str): + n=self.path.find_resource(dep) + if not n: + self.bld.fatal('Could not find %r for %r'%(dep,self)) + if not n in deps_lst: + deps_lst.append(n) + elif isinstance(dep,Node.Node): + deps_lst.append(dep) + for node in self.to_nodes(self.source): + if self.type=='latex': + task=self.create_task('latex',node,node.change_ext('.dvi')) + elif self.type=='pdflatex': + task=self.create_task('pdflatex',node,node.change_ext('.pdf')) + elif self.type=='xelatex': + task=self.create_task('xelatex',node,node.change_ext('.pdf')) + task.env=self.env + if deps_lst: + for n in deps_lst: + if not n in task.dep_nodes: + task.dep_nodes.append(n) + if hasattr(self,'texinputs_nodes'): + task.texinputs_nodes=self.texinputs_nodes + else: + task.texinputs_nodes=[node.parent,node.parent.get_bld(),self.path,self.path.get_bld()] + lst=os.environ.get('TEXINPUTS','') + if self.env.TEXINPUTS: + lst+=os.pathsep+self.env.TEXINPUTS + if lst: + lst=lst.split(os.pathsep) + for x in lst: + if x: + if os.path.isabs(x): + p=self.bld.root.find_node(x) + if p: + task.texinputs_nodes.append(p) + else: + Logs.error('Invalid TEXINPUTS folder %s',x) + else: + Logs.error('Cannot resolve relative paths in TEXINPUTS %s',x) + if self.type=='latex': + if'ps'in outs: + tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps')) + tsk.env.env=dict(os.environ) + if'pdf'in outs: + tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf')) + tsk.env.env=dict(os.environ) + elif self.type=='pdflatex': + if'ps'in outs: + self.create_task('pdf2ps',task.outputs,node.change_ext('.ps')) + self.source=[] +def configure(self): + v=self.env + for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split(): + try: + self.find_program(p,var=p.upper()) + except self.errors.ConfigurationError: + pass + v.DVIPSFLAGS='-Ppdf' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py new file mode 100755 index 0000000..2f5a30d --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py @@ -0,0 +1,218 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib import Build,Context,Errors,Logs,Node,Options,Task,Utils +from waflib.TaskGen import extension,taskgen_method +from waflib.Configure import conf +class valac(Task.Task): + vars=["VALAC","VALAC_VERSION","VALAFLAGS"] + ext_out=['.h'] + def run(self): + cmd=self.env.VALAC+self.env.VALAFLAGS + resources=getattr(self,'vala_exclude',[]) + cmd.extend([a.abspath()for a in self.inputs if a not in resources]) + ret=self.exec_command(cmd,cwd=self.vala_dir_node.abspath()) + if ret: + return ret + if self.generator.dump_deps_node: + self.generator.dump_deps_node.write('\n'.join(self.generator.packages)) + return ret +@taskgen_method +def init_vala_task(self): + self.profile=getattr(self,'profile','gobject') + self.packages=packages=Utils.to_list(getattr(self,'packages',[])) + self.use=Utils.to_list(getattr(self,'use',[])) + if packages and not self.use: + self.use=packages[:] + if self.profile=='gobject': + if not'GOBJECT'in self.use: + self.use.append('GOBJECT') + def addflags(flags): + self.env.append_value('VALAFLAGS',flags) + if self.profile: + addflags('--profile=%s'%self.profile) + valatask=self.valatask + if hasattr(self,'vala_dir'): + if isinstance(self.vala_dir,str): + valatask.vala_dir_node=self.path.get_bld().make_node(self.vala_dir) + try: + valatask.vala_dir_node.mkdir() + except OSError: + raise self.bld.fatal('Cannot create the vala dir %r'%valatask.vala_dir_node) + else: + valatask.vala_dir_node=self.vala_dir + else: + valatask.vala_dir_node=self.path.get_bld() + addflags('--directory=%s'%valatask.vala_dir_node.abspath()) + if hasattr(self,'thread'): + if self.profile=='gobject': + if not'GTHREAD'in self.use: + self.use.append('GTHREAD') + else: + Logs.warn('Profile %s means no threading support',self.profile) + self.thread=False + if self.thread: + addflags('--thread') + self.is_lib='cprogram'not in self.features + if self.is_lib: + addflags('--library=%s'%self.target) + h_node=valatask.vala_dir_node.find_or_declare('%s.h'%self.target) + valatask.outputs.append(h_node) + addflags('--header=%s'%h_node.name) + valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi'%self.target)) + if getattr(self,'gir',None): + gir_node=valatask.vala_dir_node.find_or_declare('%s.gir'%self.gir) + addflags('--gir=%s'%gir_node.name) + valatask.outputs.append(gir_node) + self.vala_target_glib=getattr(self,'vala_target_glib',getattr(Options.options,'vala_target_glib',None)) + if self.vala_target_glib: + addflags('--target-glib=%s'%self.vala_target_glib) + addflags(['--define=%s'%x for x in Utils.to_list(getattr(self,'vala_defines',[]))]) + packages_private=Utils.to_list(getattr(self,'packages_private',[])) + addflags(['--pkg=%s'%x for x in packages_private]) + def _get_api_version(): + api_version='1.0' + if hasattr(Context.g_module,'API_VERSION'): + version=Context.g_module.API_VERSION.split(".") + if version[0]=="0": + api_version="0."+version[1] + else: + api_version=version[0]+".0" + return api_version + self.includes=Utils.to_list(getattr(self,'includes',[])) + valatask.install_path=getattr(self,'install_path','') + valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi') + valatask.pkg_name=getattr(self,'pkg_name',self.env.PACKAGE) + valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version())) + valatask.install_binding=getattr(self,'install_binding',True) + self.vapi_dirs=vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[])) + if hasattr(self,'use'): + local_packages=Utils.to_list(self.use)[:] + seen=[] + while len(local_packages)>0: + package=local_packages.pop() + if package in seen: + continue + seen.append(package) + try: + package_obj=self.bld.get_tgen_by_name(package) + except Errors.WafError: + continue + package_obj.post() + package_name=package_obj.target + task=getattr(package_obj,'valatask',None) + if task: + for output in task.outputs: + if output.name==package_name+".vapi": + valatask.set_run_after(task) + if package_name not in packages: + packages.append(package_name) + if output.parent not in vapi_dirs: + vapi_dirs.append(output.parent) + if output.parent not in self.includes: + self.includes.append(output.parent) + if hasattr(package_obj,'use'): + lst=self.to_list(package_obj.use) + lst.reverse() + local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages + addflags(['--pkg=%s'%p for p in packages]) + for vapi_dir in vapi_dirs: + if isinstance(vapi_dir,Node.Node): + v_node=vapi_dir + else: + v_node=self.path.find_dir(vapi_dir) + if not v_node: + Logs.warn('Unable to locate Vala API directory: %r',vapi_dir) + else: + addflags('--vapidir=%s'%v_node.abspath()) + self.dump_deps_node=None + if self.is_lib and self.packages: + self.dump_deps_node=valatask.vala_dir_node.find_or_declare('%s.deps'%self.target) + valatask.outputs.append(self.dump_deps_node) + if self.is_lib and valatask.install_binding: + headers_list=[o for o in valatask.outputs if o.suffix()==".h"] + if headers_list: + self.install_vheader=self.add_install_files(install_to=valatask.header_path,install_from=headers_list) + vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))] + if vapi_list: + self.install_vapi=self.add_install_files(install_to=valatask.vapi_path,install_from=vapi_list) + gir_list=[o for o in valatask.outputs if o.suffix()=='.gir'] + if gir_list: + self.install_gir=self.add_install_files(install_to=getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),install_from=gir_list) + if hasattr(self,'vala_resources'): + nodes=self.to_nodes(self.vala_resources) + valatask.vala_exclude=getattr(valatask,'vala_exclude',[])+nodes + valatask.inputs.extend(nodes) + for x in nodes: + addflags(['--gresources',x.abspath()]) +@extension('.vala','.gs') +def vala_file(self,node): + try: + valatask=self.valatask + except AttributeError: + valatask=self.valatask=self.create_task('valac') + self.init_vala_task() + valatask.inputs.append(node) + name=node.name[:node.name.rfind('.')]+'.c' + c_node=valatask.vala_dir_node.find_or_declare(name) + valatask.outputs.append(c_node) + self.source.append(c_node) +@extension('.vapi') +def vapi_file(self,node): + try: + valatask=self.valatask + except AttributeError: + valatask=self.valatask=self.create_task('valac') + self.init_vala_task() + valatask.inputs.append(node) +@conf +def find_valac(self,valac_name,min_version): + valac=self.find_program(valac_name,var='VALAC') + try: + output=self.cmd_and_log(valac+['--version']) + except Errors.WafError: + valac_version=None + else: + ver=re.search(r'\d+.\d+.\d+',output).group().split('.') + valac_version=tuple([int(x)for x in ver]) + self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version) + if valac and valac_version= %r"%(valac_name,valac_version,min_version)) + self.env.VALAC_VERSION=valac_version + return valac +@conf +def check_vala(self,min_version=(0,8,0),branch=None): + if self.env.VALA_MINVER: + min_version=self.env.VALA_MINVER + if self.env.VALA_MINVER_BRANCH: + branch=self.env.VALA_MINVER_BRANCH + if not branch: + branch=min_version[:2] + try: + find_valac(self,'valac-%d.%d'%(branch[0],branch[1]),min_version) + except self.errors.ConfigurationError: + find_valac(self,'valac',min_version) +@conf +def check_vala_deps(self): + if not self.env.HAVE_GOBJECT: + pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'} + if getattr(Options.options,'vala_target_glib',None): + pkg_args['atleast_version']=Options.options.vala_target_glib + self.check_cfg(**pkg_args) + if not self.env.HAVE_GTHREAD: + pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'} + if getattr(Options.options,'vala_target_glib',None): + pkg_args['atleast_version']=Options.options.vala_target_glib + self.check_cfg(**pkg_args) +def configure(self): + self.load('gnu_dirs') + self.check_vala_deps() + self.check_vala() + self.add_os_flags('VALAFLAGS') + self.env.append_unique('VALAFLAGS',['-C']) +def options(opt): + opt.load('gnu_dirs') + valaopts=opt.add_option_group('Vala Compiler Options') + valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py new file mode 100755 index 0000000..fa58d9d --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py @@ -0,0 +1,172 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,shlex,sys +from waflib.TaskGen import feature,after_method,taskgen_method +from waflib import Utils,Task,Logs,Options +from waflib.Tools import ccroot +testlock=Utils.threading.Lock() +SCRIPT_TEMPLATE="""#! %(python)s +import subprocess, sys +cmd = %(cmd)r +# if you want to debug with gdb: +#cmd = ['gdb', '-args'] + cmd +env = %(env)r +status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str)) +sys.exit(status) +""" +@taskgen_method +def handle_ut_cwd(self,key): + cwd=getattr(self,key,None) + if cwd: + if isinstance(cwd,str): + if os.path.isabs(cwd): + self.ut_cwd=self.bld.root.make_node(cwd) + else: + self.ut_cwd=self.path.make_node(cwd) +@feature('test_scripts') +def make_interpreted_test(self): + for x in['test_scripts_source','test_scripts_template']: + if not hasattr(self,x): + Logs.warn('a test_scripts taskgen i missing %s'%x) + return + self.ut_run,lst=Task.compile_fun(self.test_scripts_template,shell=getattr(self,'test_scripts_shell',False)) + script_nodes=self.to_nodes(self.test_scripts_source) + for script_node in script_nodes: + tsk=self.create_task('utest',[script_node]) + tsk.vars=lst+tsk.vars + tsk.env['SCRIPT']=script_node.path_from(tsk.get_cwd()) + self.handle_ut_cwd('test_scripts_cwd') + env=getattr(self,'test_scripts_env',None) + if env: + self.ut_env=env + else: + self.ut_env=dict(os.environ) + paths=getattr(self,'test_scripts_paths',{}) + for(k,v)in paths.items(): + p=self.ut_env.get(k,'').split(os.pathsep) + if isinstance(v,str): + v=v.split(os.pathsep) + self.ut_env[k]=os.pathsep.join(p+v) +@feature('test') +@after_method('apply_link','process_use') +def make_test(self): + if not getattr(self,'link_task',None): + return + tsk=self.create_task('utest',self.link_task.outputs) + if getattr(self,'ut_str',None): + self.ut_run,lst=Task.compile_fun(self.ut_str,shell=getattr(self,'ut_shell',False)) + tsk.vars=lst+tsk.vars + self.handle_ut_cwd('ut_cwd') + if not hasattr(self,'ut_paths'): + paths=[] + for x in self.tmp_use_sorted: + try: + y=self.bld.get_tgen_by_name(x).link_task + except AttributeError: + pass + else: + if not isinstance(y,ccroot.stlink_task): + paths.append(y.outputs[0].parent.abspath()) + self.ut_paths=os.pathsep.join(paths)+os.pathsep + if not hasattr(self,'ut_env'): + self.ut_env=dct=dict(os.environ) + def add_path(var): + dct[var]=self.ut_paths+dct.get(var,'') + if Utils.is_win32: + add_path('PATH') + elif Utils.unversioned_sys_platform()=='darwin': + add_path('DYLD_LIBRARY_PATH') + add_path('LD_LIBRARY_PATH') + else: + add_path('LD_LIBRARY_PATH') + if not hasattr(self,'ut_cmd'): + self.ut_cmd=getattr(Options.options,'testcmd',False) +@taskgen_method +def add_test_results(self,tup): + Logs.debug("ut: %r",tup) + try: + self.utest_results.append(tup) + except AttributeError: + self.utest_results=[tup] + try: + self.bld.utest_results.append(tup) + except AttributeError: + self.bld.utest_results=[tup] +@Task.deep_inputs +class utest(Task.Task): + color='PINK' + after=['vnum','inst'] + vars=[] + def runnable_status(self): + if getattr(Options.options,'no_tests',False): + return Task.SKIP_ME + ret=super(utest,self).runnable_status() + if ret==Task.SKIP_ME: + if getattr(Options.options,'all_tests',False): + return Task.RUN_ME + return ret + def get_test_env(self): + return self.generator.ut_env + def post_run(self): + super(utest,self).post_run() + if getattr(Options.options,'clear_failed_tests',False)and self.waf_unit_test_results[1]: + self.generator.bld.task_sigs[self.uid()]=None + def run(self): + if hasattr(self.generator,'ut_run'): + return self.generator.ut_run(self) + self.ut_exec=getattr(self.generator,'ut_exec',[self.inputs[0].abspath()]) + ut_cmd=getattr(self.generator,'ut_cmd',False) + if ut_cmd: + self.ut_exec=shlex.split(ut_cmd%' '.join(self.ut_exec)) + return self.exec_command(self.ut_exec) + def exec_command(self,cmd,**kw): + self.generator.bld.log_command(cmd,kw) + if getattr(Options.options,'dump_test_scripts',False): + script_code=SCRIPT_TEMPLATE%{'python':sys.executable,'env':self.get_test_env(),'cwd':self.get_cwd().abspath(),'cmd':cmd} + script_file=self.inputs[0].abspath()+'_run.py' + Utils.writef(script_file,script_code,encoding='utf-8') + os.chmod(script_file,Utils.O755) + if Logs.verbose>1: + Logs.info('Test debug file written as %r'%script_file) + proc=Utils.subprocess.Popen(cmd,cwd=self.get_cwd().abspath(),env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,shell=isinstance(cmd,str)) + (stdout,stderr)=proc.communicate() + self.waf_unit_test_results=tup=(self.inputs[0].abspath(),proc.returncode,stdout,stderr) + testlock.acquire() + try: + return self.generator.add_test_results(tup) + finally: + testlock.release() + def get_cwd(self): + return getattr(self.generator,'ut_cwd',self.inputs[0].parent) +def summary(bld): + lst=getattr(bld,'utest_results',[]) + if lst: + Logs.pprint('CYAN','execution summary') + total=len(lst) + tfail=len([x for x in lst if x[1]]) + Logs.pprint('GREEN',' tests that pass %d/%d'%(total-tfail,total)) + for(f,code,out,err)in lst: + if not code: + Logs.pprint('GREEN',' %s'%f) + Logs.pprint('GREEN'if tfail==0 else'RED',' tests that fail %d/%d'%(tfail,total)) + for(f,code,out,err)in lst: + if code: + Logs.pprint('RED',' %s'%f) +def set_exit_code(bld): + lst=getattr(bld,'utest_results',[]) + for(f,code,out,err)in lst: + if code: + msg=[] + if out: + msg.append('stdout:%s%s'%(os.linesep,out.decode('utf-8'))) + if err: + msg.append('stderr:%s%s'%(os.linesep,err.decode('utf-8'))) + bld.fatal(os.linesep.join(msg)) +def options(opt): + opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests') + opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests') + opt.add_option('--clear-failed',action='store_true',default=False,help='Force failed unit tests to run again next time',dest='clear_failed_tests') + opt.add_option('--testcmd',action='store',default=False,dest='testcmd',help='Run the unit tests using the test-cmd string example "--testcmd="valgrind --error-exitcode=1 %s" to run under valgrind') + opt.add_option('--dump-test-scripts',action='store_true',default=False,help='Create python scripts to help debug tests',dest='dump_test_scripts') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py new file mode 100755 index 0000000..39d1f39 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import re +from waflib import Task +from waflib.TaskGen import extension +from waflib.Tools import c_preproc +@extension('.rc') +def rc_file(self,node): + obj_ext='.rc.o' + if self.env.WINRC_TGT_F=='/fo': + obj_ext='.res' + rctask=self.create_task('winrc',node,node.change_ext(obj_ext)) + try: + self.compiled_tasks.append(rctask) + except AttributeError: + self.compiled_tasks=[rctask] +re_lines=re.compile(r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',re.IGNORECASE|re.MULTILINE) +class rc_parser(c_preproc.c_parser): + def filter_comments(self,node): + code=node.read() + if c_preproc.use_trigraphs: + for(a,b)in c_preproc.trig_def: + code=code.split(a).join(b) + code=c_preproc.re_nl.sub('',code) + code=c_preproc.re_cpp.sub(c_preproc.repl,code) + ret=[] + for m in re.finditer(re_lines,code): + if m.group(2): + ret.append((m.group(2),m.group(3))) + else: + ret.append(('include',m.group(5))) + return ret +class winrc(Task.Task): + run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}' + color='BLUE' + def scan(self): + tmp=rc_parser(self.generator.includes_nodes) + tmp.start(self.inputs[0],self.env) + return(tmp.nodes,tmp.names) +def configure(conf): + v=conf.env + if not v.WINRC: + if v.CC_NAME=='msvc': + conf.find_program('RC',var='WINRC',path_list=v.PATH) + v.WINRC_TGT_F='/fo' + v.WINRC_SRC_F='' + else: + conf.find_program('windres',var='WINRC',path_list=v.PATH) + v.WINRC_TGT_F='-o' + v.WINRC_SRC_F='-i' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py new file mode 100755 index 0000000..a86010d --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py @@ -0,0 +1,44 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.Tools import ccroot,ar +from waflib.Configure import conf +@conf +def find_xlc(conf): + cc=conf.find_program(['xlc_r','xlc'],var='CC') + conf.get_xlc_version(cc) + conf.env.CC_NAME='xlc' +@conf +def xlc_common_flags(conf): + v=conf.env + v.CC_SRC_F=[] + v.CC_TGT_F=['-c','-o'] + if not v.LINK_CC: + v.LINK_CC=v.CC + v.CCLNK_SRC_F=[] + v.CCLNK_TGT_F=['-o'] + v.CPPPATH_ST='-I%s' + v.DEFINES_ST='-D%s' + v.LIB_ST='-l%s' + v.LIBPATH_ST='-L%s' + v.STLIB_ST='-l%s' + v.STLIBPATH_ST='-L%s' + v.RPATH_ST='-Wl,-rpath,%s' + v.SONAME_ST=[] + v.SHLIB_MARKER=[] + v.STLIB_MARKER=[] + v.LINKFLAGS_cprogram=['-Wl,-brtl'] + v.cprogram_PATTERN='%s' + v.CFLAGS_cshlib=['-fPIC'] + v.LINKFLAGS_cshlib=['-G','-Wl,-brtl,-bexpfull'] + v.cshlib_PATTERN='lib%s.so' + v.LINKFLAGS_cstlib=[] + v.cstlib_PATTERN='lib%s.a' +def configure(conf): + conf.find_xlc() + conf.find_ar() + conf.xlc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py new file mode 100755 index 0000000..8a081b6 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py @@ -0,0 +1,44 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from waflib.Tools import ccroot,ar +from waflib.Configure import conf +@conf +def find_xlcxx(conf): + cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX') + conf.get_xlc_version(cxx) + conf.env.CXX_NAME='xlc++' +@conf +def xlcxx_common_flags(conf): + v=conf.env + v.CXX_SRC_F=[] + v.CXX_TGT_F=['-c','-o'] + if not v.LINK_CXX: + v.LINK_CXX=v.CXX + v.CXXLNK_SRC_F=[] + v.CXXLNK_TGT_F=['-o'] + v.CPPPATH_ST='-I%s' + v.DEFINES_ST='-D%s' + v.LIB_ST='-l%s' + v.LIBPATH_ST='-L%s' + v.STLIB_ST='-l%s' + v.STLIBPATH_ST='-L%s' + v.RPATH_ST='-Wl,-rpath,%s' + v.SONAME_ST=[] + v.SHLIB_MARKER=[] + v.STLIB_MARKER=[] + v.LINKFLAGS_cxxprogram=['-Wl,-brtl'] + v.cxxprogram_PATTERN='%s' + v.CXXFLAGS_cxxshlib=['-fPIC'] + v.LINKFLAGS_cxxshlib=['-G','-Wl,-brtl,-bexpfull'] + v.cxxshlib_PATTERN='lib%s.so' + v.LINKFLAGS_cxxstlib=[] + v.cxxstlib_PATTERN='lib%s.a' +def configure(conf): + conf.find_xlcxx() + conf.find_ar() + conf.xlcxx_common_flags() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py new file mode 100755 index 0000000..79b38f3 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py @@ -0,0 +1,625 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from __future__ import with_statement +import atexit,os,sys,errno,inspect,re,datetime,platform,base64,signal,functools,time +try: + import cPickle +except ImportError: + import pickle as cPickle +if os.name=='posix'and sys.version_info[0]<3: + try: + import subprocess32 as subprocess + except ImportError: + import subprocess +else: + import subprocess +try: + TimeoutExpired=subprocess.TimeoutExpired +except AttributeError: + class TimeoutExpired(Exception): + pass +from collections import deque,defaultdict +try: + import _winreg as winreg +except ImportError: + try: + import winreg + except ImportError: + winreg=None +from waflib import Errors +try: + from hashlib import md5 +except ImportError: + try: + from hashlib import sha1 as md5 + except ImportError: + pass +else: + try: + md5().digest() + except ValueError: + from hashlib import sha1 as md5 +try: + import threading +except ImportError: + if not'JOBS'in os.environ: + os.environ['JOBS']='1' + class threading(object): + pass + class Lock(object): + def acquire(self): + pass + def release(self): + pass + threading.Lock=threading.Thread=Lock +SIG_NIL='SIG_NIL_SIG_NIL_'.encode() +O644=420 +O755=493 +rot_chr=['\\','|','/','-'] +rot_idx=0 +class ordered_iter_dict(dict): + def __init__(self,*k,**kw): + self.lst=deque() + dict.__init__(self,*k,**kw) + def clear(self): + dict.clear(self) + self.lst=deque() + def __setitem__(self,key,value): + if key in dict.keys(self): + self.lst.remove(key) + dict.__setitem__(self,key,value) + self.lst.append(key) + def __delitem__(self,key): + dict.__delitem__(self,key) + try: + self.lst.remove(key) + except ValueError: + pass + def __iter__(self): + return reversed(self.lst) + def keys(self): + return reversed(self.lst) +class lru_node(object): + __slots__=('next','prev','key','val') + def __init__(self): + self.next=self + self.prev=self + self.key=None + self.val=None +class lru_cache(object): + __slots__=('maxlen','table','head') + def __init__(self,maxlen=100): + self.maxlen=maxlen + self.table={} + self.head=lru_node() + self.head.next=self.head + self.head.prev=self.head + def __getitem__(self,key): + node=self.table[key] + if node is self.head: + return node.val + node.prev.next=node.next + node.next.prev=node.prev + node.next=self.head.next + node.prev=self.head + self.head=node.next.prev=node.prev.next=node + return node.val + def __setitem__(self,key,val): + if key in self.table: + node=self.table[key] + node.val=val + self.__getitem__(key) + else: + if len(self.table)0x3000000 and not'b'in m: + m+='b' + with open(fname,m)as f: + txt=f.read() + if encoding: + txt=txt.decode(encoding) + else: + txt=txt.decode() + else: + with open(fname,m)as f: + txt=f.read() + return txt +def writef(fname,data,m='w',encoding='latin-1'): + if sys.hexversion>0x3000000 and not'b'in m: + data=data.encode(encoding) + m+='b' + with open(fname,m)as f: + f.write(data) +def h_file(fname): + m=md5() + with open(fname,'rb')as f: + while fname: + fname=f.read(200000) + m.update(fname) + return m.digest() +def readf_win32(f,m='r',encoding='latin-1'): + flags=os.O_NOINHERIT|os.O_RDONLY + if'b'in m: + flags|=os.O_BINARY + if'+'in m: + flags|=os.O_RDWR + try: + fd=os.open(f,flags) + except OSError: + raise IOError('Cannot read from %r'%f) + if sys.hexversion>0x3000000 and not'b'in m: + m+='b' + with os.fdopen(fd,m)as f: + txt=f.read() + if encoding: + txt=txt.decode(encoding) + else: + txt=txt.decode() + else: + with os.fdopen(fd,m)as f: + txt=f.read() + return txt +def writef_win32(f,data,m='w',encoding='latin-1'): + if sys.hexversion>0x3000000 and not'b'in m: + data=data.encode(encoding) + m+='b' + flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT + if'b'in m: + flags|=os.O_BINARY + if'+'in m: + flags|=os.O_RDWR + try: + fd=os.open(f,flags) + except OSError: + raise OSError('Cannot write to %r'%f) + with os.fdopen(fd,m)as f: + f.write(data) +def h_file_win32(fname): + try: + fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT) + except OSError: + raise OSError('Cannot read from %r'%fname) + m=md5() + with os.fdopen(fd,'rb')as f: + while fname: + fname=f.read(200000) + m.update(fname) + return m.digest() +readf_unix=readf +writef_unix=writef +h_file_unix=h_file +if hasattr(os,'O_NOINHERIT')and sys.hexversion<0x3040000: + readf=readf_win32 + writef=writef_win32 + h_file=h_file_win32 +try: + x=''.encode('hex') +except LookupError: + import binascii + def to_hex(s): + ret=binascii.hexlify(s) + if not isinstance(ret,str): + ret=ret.decode('utf-8') + return ret +else: + def to_hex(s): + return s.encode('hex') +to_hex.__doc__=""" +Return the hexadecimal representation of a string + +:param s: string to convert +:type s: string +""" +def listdir_win32(s): + if not s: + try: + import ctypes + except ImportError: + return[x+':\\'for x in'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] + else: + dlen=4 + maxdrives=26 + buf=ctypes.create_string_buffer(maxdrives*dlen) + ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf)) + return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))] + if len(s)==2 and s[1]==":": + s+=os.sep + if not os.path.isdir(s): + e=OSError('%s is not a directory'%s) + e.errno=errno.ENOENT + raise e + return os.listdir(s) +listdir=os.listdir +if is_win32: + listdir=listdir_win32 +def num2ver(ver): + if isinstance(ver,str): + ver=tuple(ver.split('.')) + if isinstance(ver,tuple): + ret=0 + for i in range(4): + if i0x3000000: + ret=ret.encode('latin-1','xmlcharrefreplace') + return ret +reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") +def subst_vars(expr,params): + def repl_var(m): + if m.group(1): + return'\\' + if m.group(2): + return'$' + try: + return params.get_flat(m.group(3)) + except AttributeError: + return params[m.group(3)] + return reg_subst.sub(repl_var,expr) +def destos_to_binfmt(key): + if key=='darwin': + return'mac-o' + elif key in('win32','cygwin','uwin','msys'): + return'pe' + return'elf' +def unversioned_sys_platform(): + s=sys.platform + if s.startswith('java'): + from java.lang import System + s=System.getProperty('os.name') + if s=='Mac OS X': + return'darwin' + elif s.startswith('Windows '): + return'win32' + elif s=='OS/2': + return'os2' + elif s=='HP-UX': + return'hp-ux' + elif s in('SunOS','Solaris'): + return'sunos' + else:s=s.lower() + if s=='powerpc': + return'darwin' + if s=='win32'or s=='os2': + return s + if s=='cli'and os.name=='nt': + return'win32' + return re.split(r'\d+$',s)[0] +def nada(*k,**kw): + pass +class Timer(object): + def __init__(self): + self.start_time=self.now() + def __str__(self): + delta=self.now()-self.start_time + if not isinstance(delta,datetime.timedelta): + delta=datetime.timedelta(seconds=delta) + days=delta.days + hours,rem=divmod(delta.seconds,3600) + minutes,seconds=divmod(rem,60) + seconds+=delta.microseconds*1e-6 + result='' + if days: + result+='%dd'%days + if days or hours: + result+='%dh'%hours + if days or hours or minutes: + result+='%dm'%minutes + return'%s%.3fs'%(result,seconds) + def now(self): + return datetime.datetime.utcnow() + if hasattr(time,'perf_counter'): + def now(self): + return time.perf_counter() +def read_la_file(path): + sp=re.compile(r'^([^=]+)=\'(.*)\'$') + dc={} + for line in readf(path).splitlines(): + try: + _,left,right,_=sp.split(line.strip()) + dc[left]=right + except ValueError: + pass + return dc +def run_once(fun): + cache={} + def wrap(*k): + try: + return cache[k] + except KeyError: + ret=fun(*k) + cache[k]=ret + return ret + wrap.__cache__=cache + wrap.__name__=fun.__name__ + return wrap +def get_registry_app_path(key,filename): + if not winreg: + return None + try: + result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0]) + except OSError: + pass + else: + if os.path.isfile(result): + return result +def lib64(): + if os.sep=='/': + if platform.architecture()[0]=='64bit': + if os.path.exists('/usr/lib64')and not os.path.exists('/usr/lib32'): + return'64' + return'' +def sane_path(p): + return os.path.abspath(os.path.expanduser(p)) +process_pool=[] +def get_process(): + try: + return process_pool.pop() + except IndexError: + filepath=os.path.dirname(os.path.abspath(__file__))+os.sep+'processor.py' + cmd=[sys.executable,'-c',readf(filepath)] + return subprocess.Popen(cmd,stdout=subprocess.PIPE,stdin=subprocess.PIPE,bufsize=0,close_fds=not is_win32) +def run_prefork_process(cmd,kwargs,cargs): + if not'env'in kwargs: + kwargs['env']=dict(os.environ) + try: + obj=base64.b64encode(cPickle.dumps([cmd,kwargs,cargs])) + except(TypeError,AttributeError): + return run_regular_process(cmd,kwargs,cargs) + proc=get_process() + if not proc: + return run_regular_process(cmd,kwargs,cargs) + proc.stdin.write(obj) + proc.stdin.write('\n'.encode()) + proc.stdin.flush() + obj=proc.stdout.readline() + if not obj: + raise OSError('Preforked sub-process %r died'%proc.pid) + process_pool.append(proc) + lst=cPickle.loads(base64.b64decode(obj)) + assert len(lst)==5 + ret,out,err,ex,trace=lst + if ex: + if ex=='OSError': + raise OSError(trace) + elif ex=='ValueError': + raise ValueError(trace) + elif ex=='TimeoutExpired': + exc=TimeoutExpired(cmd,timeout=cargs['timeout'],output=out) + exc.stderr=err + raise exc + else: + raise Exception(trace) + return ret,out,err +def lchown(path,user=-1,group=-1): + if isinstance(user,str): + import pwd + entry=pwd.getpwnam(user) + if not entry: + raise OSError('Unknown user %r'%user) + user=entry[2] + if isinstance(group,str): + import grp + entry=grp.getgrnam(group) + if not entry: + raise OSError('Unknown group %r'%group) + group=entry[2] + return os.lchown(path,user,group) +def run_regular_process(cmd,kwargs,cargs={}): + proc=subprocess.Popen(cmd,**kwargs) + if kwargs.get('stdout')or kwargs.get('stderr'): + try: + out,err=proc.communicate(**cargs) + except TimeoutExpired: + if kwargs.get('start_new_session')and hasattr(os,'killpg'): + os.killpg(proc.pid,signal.SIGKILL) + else: + proc.kill() + out,err=proc.communicate() + exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out) + exc.stderr=err + raise exc + status=proc.returncode + else: + out,err=(None,None) + try: + status=proc.wait(**cargs) + except TimeoutExpired as e: + if kwargs.get('start_new_session')and hasattr(os,'killpg'): + os.killpg(proc.pid,signal.SIGKILL) + else: + proc.kill() + proc.wait() + raise e + return status,out,err +def run_process(cmd,kwargs,cargs={}): + if kwargs.get('stdout')and kwargs.get('stderr'): + return run_prefork_process(cmd,kwargs,cargs) + else: + return run_regular_process(cmd,kwargs,cargs) +def alloc_process_pool(n,force=False): + global run_process,get_process,alloc_process_pool + if not force: + n=max(n-len(process_pool),0) + try: + lst=[get_process()for x in range(n)] + except OSError: + run_process=run_regular_process + get_process=alloc_process_pool=nada + else: + for x in lst: + process_pool.append(x) +def atexit_pool(): + for k in process_pool: + try: + os.kill(k.pid,9) + except OSError: + pass + else: + k.wait() +if(sys.hexversion<0x207000f and not is_win32)or sys.hexversion>=0x306000f: + atexit.register(atexit_pool) +if os.environ.get('WAF_NO_PREFORK')or sys.platform=='cli'or not sys.executable: + run_process=run_regular_process + get_process=alloc_process_pool=nada diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py new file mode 100755 index 0000000..55e850d --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py @@ -0,0 +1,4 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py new file mode 100755 index 0000000..1ab9c5c --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py @@ -0,0 +1,238 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,re,sys +from waflib import Utils +wlock=Utils.threading.Lock() +try: + from ctypes import Structure,windll,c_short,c_ushort,c_ulong,c_int,byref,c_wchar,POINTER,c_long +except ImportError: + class AnsiTerm(object): + def __init__(self,stream): + self.stream=stream + try: + self.errors=self.stream.errors + except AttributeError: + pass + self.encoding=self.stream.encoding + def write(self,txt): + try: + wlock.acquire() + self.stream.write(txt) + self.stream.flush() + finally: + wlock.release() + def fileno(self): + return self.stream.fileno() + def flush(self): + self.stream.flush() + def isatty(self): + return self.stream.isatty() +else: + class COORD(Structure): + _fields_=[("X",c_short),("Y",c_short)] + class SMALL_RECT(Structure): + _fields_=[("Left",c_short),("Top",c_short),("Right",c_short),("Bottom",c_short)] + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + _fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_ushort),("Window",SMALL_RECT),("MaximumWindowSize",COORD)] + class CONSOLE_CURSOR_INFO(Structure): + _fields_=[('dwSize',c_ulong),('bVisible',c_int)] + try: + _type=unicode + except NameError: + _type=str + to_int=lambda number,default:number and int(number)or default + STD_OUTPUT_HANDLE=-11 + STD_ERROR_HANDLE=-12 + windll.kernel32.GetStdHandle.argtypes=[c_ulong] + windll.kernel32.GetStdHandle.restype=c_ulong + windll.kernel32.GetConsoleScreenBufferInfo.argtypes=[c_ulong,POINTER(CONSOLE_SCREEN_BUFFER_INFO)] + windll.kernel32.GetConsoleScreenBufferInfo.restype=c_long + windll.kernel32.SetConsoleTextAttribute.argtypes=[c_ulong,c_ushort] + windll.kernel32.SetConsoleTextAttribute.restype=c_long + windll.kernel32.FillConsoleOutputCharacterW.argtypes=[c_ulong,c_wchar,c_ulong,POINTER(COORD),POINTER(c_ulong)] + windll.kernel32.FillConsoleOutputCharacterW.restype=c_long + windll.kernel32.FillConsoleOutputAttribute.argtypes=[c_ulong,c_ushort,c_ulong,POINTER(COORD),POINTER(c_ulong)] + windll.kernel32.FillConsoleOutputAttribute.restype=c_long + windll.kernel32.SetConsoleCursorPosition.argtypes=[c_ulong,POINTER(COORD)] + windll.kernel32.SetConsoleCursorPosition.restype=c_long + windll.kernel32.SetConsoleCursorInfo.argtypes=[c_ulong,POINTER(CONSOLE_CURSOR_INFO)] + windll.kernel32.SetConsoleCursorInfo.restype=c_long + class AnsiTerm(object): + def __init__(self,s): + self.stream=s + try: + self.errors=s.errors + except AttributeError: + pass + self.encoding=s.encoding + self.cursor_history=[] + handle=(s.fileno()==2)and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE + self.hconsole=windll.kernel32.GetStdHandle(handle) + self._sbinfo=CONSOLE_SCREEN_BUFFER_INFO() + self._csinfo=CONSOLE_CURSOR_INFO() + windll.kernel32.GetConsoleCursorInfo(self.hconsole,byref(self._csinfo)) + self._orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO() + r=windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._orig_sbinfo)) + self._isatty=r==1 + def screen_buffer_info(self): + windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._sbinfo)) + return self._sbinfo + def clear_line(self,param): + mode=param and int(param)or 0 + sbinfo=self.screen_buffer_info() + if mode==1: + line_start=COORD(0,sbinfo.CursorPosition.Y) + line_length=sbinfo.Size.X + elif mode==2: + line_start=COORD(sbinfo.CursorPosition.X,sbinfo.CursorPosition.Y) + line_length=sbinfo.Size.X-sbinfo.CursorPosition.X + else: + line_start=sbinfo.CursorPosition + line_length=sbinfo.Size.X-sbinfo.CursorPosition.X + chars_written=c_ulong() + windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),line_length,line_start,byref(chars_written)) + windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,line_length,line_start,byref(chars_written)) + def clear_screen(self,param): + mode=to_int(param,0) + sbinfo=self.screen_buffer_info() + if mode==1: + clear_start=COORD(0,0) + clear_length=sbinfo.CursorPosition.X*sbinfo.CursorPosition.Y + elif mode==2: + clear_start=COORD(0,0) + clear_length=sbinfo.Size.X*sbinfo.Size.Y + windll.kernel32.SetConsoleCursorPosition(self.hconsole,clear_start) + else: + clear_start=sbinfo.CursorPosition + clear_length=((sbinfo.Size.X-sbinfo.CursorPosition.X)+sbinfo.Size.X*(sbinfo.Size.Y-sbinfo.CursorPosition.Y)) + chars_written=c_ulong() + windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),clear_length,clear_start,byref(chars_written)) + windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,clear_length,clear_start,byref(chars_written)) + def push_cursor(self,param): + sbinfo=self.screen_buffer_info() + self.cursor_history.append(sbinfo.CursorPosition) + def pop_cursor(self,param): + if self.cursor_history: + old_pos=self.cursor_history.pop() + windll.kernel32.SetConsoleCursorPosition(self.hconsole,old_pos) + def set_cursor(self,param): + y,sep,x=param.partition(';') + x=to_int(x,1)-1 + y=to_int(y,1)-1 + sbinfo=self.screen_buffer_info() + new_pos=COORD(min(max(0,x),sbinfo.Size.X),min(max(0,y),sbinfo.Size.Y)) + windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos) + def set_column(self,param): + x=to_int(param,1)-1 + sbinfo=self.screen_buffer_info() + new_pos=COORD(min(max(0,x),sbinfo.Size.X),sbinfo.CursorPosition.Y) + windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos) + def move_cursor(self,x_offset=0,y_offset=0): + sbinfo=self.screen_buffer_info() + new_pos=COORD(min(max(0,sbinfo.CursorPosition.X+x_offset),sbinfo.Size.X),min(max(0,sbinfo.CursorPosition.Y+y_offset),sbinfo.Size.Y)) + windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos) + def move_up(self,param): + self.move_cursor(y_offset=-to_int(param,1)) + def move_down(self,param): + self.move_cursor(y_offset=to_int(param,1)) + def move_left(self,param): + self.move_cursor(x_offset=-to_int(param,1)) + def move_right(self,param): + self.move_cursor(x_offset=to_int(param,1)) + def next_line(self,param): + sbinfo=self.screen_buffer_info() + self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=to_int(param,1)) + def prev_line(self,param): + sbinfo=self.screen_buffer_info() + self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=-to_int(param,1)) + def rgb2bgr(self,c): + return((c&1)<<2)|(c&2)|((c&4)>>2) + def set_color(self,param): + cols=param.split(';') + sbinfo=self.screen_buffer_info() + attr=sbinfo.Attributes + for c in cols: + c=to_int(c,0) + if 29>4)|((attr&0x07)<<4) + windll.kernel32.SetConsoleTextAttribute(self.hconsole,attr) + def show_cursor(self,param): + self._csinfo.bVisible=1 + windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo)) + def hide_cursor(self,param): + self._csinfo.bVisible=0 + windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo)) + ansi_command_table={'A':move_up,'B':move_down,'C':move_right,'D':move_left,'E':next_line,'F':prev_line,'G':set_column,'H':set_cursor,'f':set_cursor,'J':clear_screen,'K':clear_line,'h':show_cursor,'l':hide_cursor,'m':set_color,'s':push_cursor,'u':pop_cursor,} + ansi_tokens=re.compile(r'(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))') + def write(self,text): + try: + wlock.acquire() + if self._isatty: + for param,cmd,txt in self.ansi_tokens.findall(text): + if cmd: + cmd_func=self.ansi_command_table.get(cmd) + if cmd_func: + cmd_func(self,param) + else: + self.writeconsole(txt) + else: + self.stream.write(text) + finally: + wlock.release() + def writeconsole(self,txt): + chars_written=c_ulong() + writeconsole=windll.kernel32.WriteConsoleA + if isinstance(txt,_type): + writeconsole=windll.kernel32.WriteConsoleW + done=0 + todo=len(txt) + chunk=32<<10 + while todo!=0: + doing=min(chunk,todo) + buf=txt[done:done+doing] + r=writeconsole(self.hconsole,buf,doing,byref(chars_written),None) + if r==0: + chunk>>=1 + continue + done+=doing + todo-=doing + def fileno(self): + return self.stream.fileno() + def flush(self): + pass + def isatty(self): + return self._isatty + if sys.stdout.isatty()or sys.stderr.isatty(): + handle=sys.stdout.isatty()and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE + console=windll.kernel32.GetStdHandle(handle) + sbinfo=CONSOLE_SCREEN_BUFFER_INFO() + def get_term_cols(): + windll.kernel32.GetConsoleScreenBufferInfo(console,byref(sbinfo)) + return sbinfo.Size.X-1 +try: + import struct,fcntl,termios +except ImportError: + pass +else: + if(sys.stdout.isatty()or sys.stderr.isatty())and os.environ.get('TERM','')not in('dumb','emacs'): + FD=sys.stdout.isatty()and sys.stdout.fileno()or sys.stderr.fileno() + def fun(): + return struct.unpack("HHHH",fcntl.ioctl(FD,termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[1] + try: + fun() + except Exception as e: + pass + else: + get_term_cols=fun diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py new file mode 100755 index 0000000..55e850d --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py @@ -0,0 +1,4 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py new file mode 100755 index 0000000..fb4e578 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py @@ -0,0 +1,305 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import sys +from waflib import ConfigSet,Logs,Options,Scripting,Task,Build,Configure,Node,Runner,TaskGen,Utils,Errors,Context +sys.modules['Environment']=ConfigSet +ConfigSet.Environment=ConfigSet.ConfigSet +sys.modules['Logs']=Logs +sys.modules['Options']=Options +sys.modules['Scripting']=Scripting +sys.modules['Task']=Task +sys.modules['Build']=Build +sys.modules['Configure']=Configure +sys.modules['Node']=Node +sys.modules['Runner']=Runner +sys.modules['TaskGen']=TaskGen +sys.modules['Utils']=Utils +sys.modules['Constants']=Context +Context.SRCDIR='' +Context.BLDDIR='' +from waflib.Tools import c_preproc +sys.modules['preproc']=c_preproc +from waflib.Tools import c_config +sys.modules['config_c']=c_config +ConfigSet.ConfigSet.copy=ConfigSet.ConfigSet.derive +ConfigSet.ConfigSet.set_variant=Utils.nada +Utils.pproc=Utils.subprocess +Build.BuildContext.add_subdirs=Build.BuildContext.recurse +Build.BuildContext.new_task_gen=Build.BuildContext.__call__ +Build.BuildContext.is_install=0 +Node.Node.relpath_gen=Node.Node.path_from +Utils.pproc=Utils.subprocess +Utils.get_term_cols=Logs.get_term_cols +def cmd_output(cmd,**kw): + silent=False + if'silent'in kw: + silent=kw['silent'] + del(kw['silent']) + if'e'in kw: + tmp=kw['e'] + del(kw['e']) + kw['env']=tmp + kw['shell']=isinstance(cmd,str) + kw['stdout']=Utils.subprocess.PIPE + if silent: + kw['stderr']=Utils.subprocess.PIPE + try: + p=Utils.subprocess.Popen(cmd,**kw) + output=p.communicate()[0] + except OSError as e: + raise ValueError(str(e)) + if p.returncode: + if not silent: + msg="command execution failed: %s -> %r"%(cmd,str(output)) + raise ValueError(msg) + output='' + return output +Utils.cmd_output=cmd_output +def name_to_obj(self,s,env=None): + if Logs.verbose: + Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"') + return self.get_tgen_by_name(s) +Build.BuildContext.name_to_obj=name_to_obj +def env_of_name(self,name): + try: + return self.all_envs[name] + except KeyError: + Logs.error('no such environment: '+name) + return None +Build.BuildContext.env_of_name=env_of_name +def set_env_name(self,name,env): + self.all_envs[name]=env + return env +Configure.ConfigurationContext.set_env_name=set_env_name +def retrieve(self,name,fromenv=None): + try: + env=self.all_envs[name] + except KeyError: + env=ConfigSet.ConfigSet() + self.prepare_env(env) + self.all_envs[name]=env + else: + if fromenv: + Logs.warn('The environment %s may have been configured already',name) + return env +Configure.ConfigurationContext.retrieve=retrieve +Configure.ConfigurationContext.sub_config=Configure.ConfigurationContext.recurse +Configure.ConfigurationContext.check_tool=Configure.ConfigurationContext.load +Configure.conftest=Configure.conf +Configure.ConfigurationError=Errors.ConfigurationError +Utils.WafError=Errors.WafError +Options.OptionsContext.sub_options=Options.OptionsContext.recurse +Options.OptionsContext.tool_options=Context.Context.load +Options.Handler=Options.OptionsContext +Task.simple_task_type=Task.task_type_from_func=Task.task_factory +Task.Task.classes=Task.classes +def setitem(self,key,value): + if key.startswith('CCFLAGS'): + key=key[1:] + self.table[key]=value +ConfigSet.ConfigSet.__setitem__=setitem +@TaskGen.feature('d') +@TaskGen.before('apply_incpaths') +def old_importpaths(self): + if getattr(self,'importpaths',[]): + self.includes=self.importpaths +from waflib import Context +eld=Context.load_tool +def load_tool(*k,**kw): + ret=eld(*k,**kw) + if'set_options'in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "set_options" to options') + ret.options=ret.set_options + if'detect'in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "detect" to "configure"') + ret.configure=ret.detect + return ret +Context.load_tool=load_tool +def get_curdir(self): + return self.path.abspath() +Context.Context.curdir=property(get_curdir,Utils.nada) +def get_srcdir(self): + return self.srcnode.abspath() +Configure.ConfigurationContext.srcdir=property(get_srcdir,Utils.nada) +def get_blddir(self): + return self.bldnode.abspath() +Configure.ConfigurationContext.blddir=property(get_blddir,Utils.nada) +Configure.ConfigurationContext.check_message_1=Configure.ConfigurationContext.start_msg +Configure.ConfigurationContext.check_message_2=Configure.ConfigurationContext.end_msg +rev=Context.load_module +def load_module(path,encoding=None): + ret=rev(path,encoding) + if'set_options'in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "set_options" to "options" (%r)',path) + ret.options=ret.set_options + if'srcdir'in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "srcdir" to "top" (%r)',path) + ret.top=ret.srcdir + if'blddir'in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "blddir" to "out" (%r)',path) + ret.out=ret.blddir + Utils.g_module=Context.g_module + Options.launch_dir=Context.launch_dir + return ret +Context.load_module=load_module +old_post=TaskGen.task_gen.post +def post(self): + self.features=self.to_list(self.features) + if'cc'in self.features: + if Logs.verbose: + Logs.warn('compat: the feature cc does not exist anymore (use "c")') + self.features.remove('cc') + self.features.append('c') + if'cstaticlib'in self.features: + if Logs.verbose: + Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")') + self.features.remove('cstaticlib') + self.features.append(('cxx'in self.features)and'cxxstlib'or'cstlib') + if getattr(self,'ccflags',None): + if Logs.verbose: + Logs.warn('compat: "ccflags" was renamed to "cflags"') + self.cflags=self.ccflags + return old_post(self) +TaskGen.task_gen.post=post +def waf_version(*k,**kw): + Logs.warn('wrong version (waf_version was removed in waf 1.6)') +Utils.waf_version=waf_version +import os +@TaskGen.feature('c','cxx','d') +@TaskGen.before('apply_incpaths','propagate_uselib_vars') +@TaskGen.after('apply_link','process_source') +def apply_uselib_local(self): + env=self.env + from waflib.Tools.ccroot import stlink_task + self.uselib=self.to_list(getattr(self,'uselib',[])) + self.includes=self.to_list(getattr(self,'includes',[])) + names=self.to_list(getattr(self,'uselib_local',[])) + get=self.bld.get_tgen_by_name + seen=set() + seen_uselib=set() + tmp=Utils.deque(names) + if tmp: + if Logs.verbose: + Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') + while tmp: + lib_name=tmp.popleft() + if lib_name in seen: + continue + y=get(lib_name) + y.post() + seen.add(lib_name) + if getattr(y,'uselib_local',None): + for x in self.to_list(getattr(y,'uselib_local',[])): + obj=get(x) + obj.post() + if getattr(obj,'link_task',None): + if not isinstance(obj.link_task,stlink_task): + tmp.append(x) + if getattr(y,'link_task',None): + link_name=y.target[y.target.rfind(os.sep)+1:] + if isinstance(y.link_task,stlink_task): + env.append_value('STLIB',[link_name]) + else: + env.append_value('LIB',[link_name]) + self.link_task.set_run_after(y.link_task) + self.link_task.dep_nodes+=y.link_task.outputs + tmp_path=y.link_task.outputs[0].parent.bldpath() + if not tmp_path in env['LIBPATH']: + env.prepend_value('LIBPATH',[tmp_path]) + for v in self.to_list(getattr(y,'uselib',[])): + if v not in seen_uselib: + seen_uselib.add(v) + if not env['STLIB_'+v]: + if not v in self.uselib: + self.uselib.insert(0,v) + if getattr(y,'export_includes',None): + self.includes.extend(y.to_incnodes(y.export_includes)) +@TaskGen.feature('cprogram','cxxprogram','cstlib','cxxstlib','cshlib','cxxshlib','dprogram','dstlib','dshlib') +@TaskGen.after('apply_link') +def apply_objdeps(self): + names=getattr(self,'add_objects',[]) + if not names: + return + names=self.to_list(names) + get=self.bld.get_tgen_by_name + seen=[] + while names: + x=names[0] + if x in seen: + names=names[1:] + continue + y=get(x) + if getattr(y,'add_objects',None): + added=0 + lst=y.to_list(y.add_objects) + lst.reverse() + for u in lst: + if u in seen: + continue + added=1 + names=[u]+names + if added: + continue + y.post() + seen.append(x) + for t in getattr(y,'compiled_tasks',[]): + self.link_task.inputs.extend(t.outputs) +@TaskGen.after('apply_link') +def process_obj_files(self): + if not hasattr(self,'obj_files'): + return + for x in self.obj_files: + node=self.path.find_resource(x) + self.link_task.inputs.append(node) +@TaskGen.taskgen_method +def add_obj_file(self,file): + if not hasattr(self,'obj_files'): + self.obj_files=[] + if not'process_obj_files'in self.meths: + self.meths.append('process_obj_files') + self.obj_files.append(file) +old_define=Configure.ConfigurationContext.__dict__['define'] +@Configure.conf +def define(self,key,val,quote=True,comment=''): + old_define(self,key,val,quote,comment) + if key.startswith('HAVE_'): + self.env[key]=1 +old_undefine=Configure.ConfigurationContext.__dict__['undefine'] +@Configure.conf +def undefine(self,key,comment=''): + old_undefine(self,key,comment) + if key.startswith('HAVE_'): + self.env[key]=0 +def set_incdirs(self,val): + Logs.warn('compat: change "export_incdirs" by "export_includes"') + self.export_includes=val +TaskGen.task_gen.export_incdirs=property(None,set_incdirs) +def install_dir(self,path): + if not path: + return[] + destpath=Utils.subst_vars(path,self.env) + if self.is_install>0: + Logs.info('* creating %s',destpath) + Utils.check_dir(destpath) + elif self.is_install<0: + Logs.info('* removing %s',destpath) + try: + os.remove(destpath) + except OSError: + pass +Build.BuildContext.install_dir=install_dir +repl={'apply_core':'process_source','apply_lib_vars':'process_source','apply_obj_vars':'propagate_uselib_vars','exec_rule':'process_rule'} +def after(*k): + k=[repl.get(key,key)for key in k] + return TaskGen.after_method(*k) +def before(*k): + k=[repl.get(key,key)for key in k] + return TaskGen.before_method(*k) +TaskGen.before=before diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py new file mode 100755 index 0000000..9aa8418 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py @@ -0,0 +1,47 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +from __future__ import with_statement +import os +all_modifs={} +def fixdir(dir): + for k in all_modifs: + for v in all_modifs[k]: + modif(os.path.join(dir,'waflib'),k,v) +def modif(dir,name,fun): + if name=='*': + lst=[] + for y in'. Tools extras'.split(): + for x in os.listdir(os.path.join(dir,y)): + if x.endswith('.py'): + lst.append(y+os.sep+x) + for x in lst: + modif(dir,x,fun) + return + filename=os.path.join(dir,name) + with open(filename,'r')as f: + txt=f.read() + txt=fun(txt) + with open(filename,'w')as f: + f.write(txt) +def subst(*k): + def do_subst(fun): + for x in k: + try: + all_modifs[x].append(fun) + except KeyError: + all_modifs[x]=[fun] + return fun + return do_subst +@subst('*') +def r1(code): + code=code.replace('as e:',',e:') + code=code.replace(".decode(sys.stdout.encoding or'latin-1',errors='replace')",'') + return code.replace('.encode()','') +@subst('Runner.py') +def r4(code): + return code.replace('next(self.biter)','self.biter.next()') +@subst('Context.py') +def r5(code): + return code.replace("('Execution failure: %s'%str(e),ex=e)","('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]") diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py new file mode 100755 index 0000000..f7033d4 --- /dev/null +++ b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py @@ -0,0 +1,57 @@ +#! /usr/bin/env python +# encoding: utf-8 +# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file + +import os,sys,traceback,base64,signal +try: + import cPickle +except ImportError: + import pickle as cPickle +try: + import subprocess32 as subprocess +except ImportError: + import subprocess +try: + TimeoutExpired=subprocess.TimeoutExpired +except AttributeError: + class TimeoutExpired(Exception): + pass +def run(): + txt=sys.stdin.readline().strip() + if not txt: + sys.exit(1) + [cmd,kwargs,cargs]=cPickle.loads(base64.b64decode(txt)) + cargs=cargs or{} + if not'close_fds'in kwargs: + kwargs['close_fds']=False + ret=1 + out,err,ex,trace=(None,None,None,None) + try: + proc=subprocess.Popen(cmd,**kwargs) + try: + out,err=proc.communicate(**cargs) + except TimeoutExpired: + if kwargs.get('start_new_session')and hasattr(os,'killpg'): + os.killpg(proc.pid,signal.SIGKILL) + else: + proc.kill() + out,err=proc.communicate() + exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out) + exc.stderr=err + raise exc + ret=proc.returncode + except Exception as e: + exc_type,exc_value,tb=sys.exc_info() + exc_lines=traceback.format_exception(exc_type,exc_value,tb) + trace=str(cmd)+'\n'+''.join(exc_lines) + ex=e.__class__.__name__ + tmp=[ret,out,err,ex,trace] + obj=base64.b64encode(cPickle.dumps(tmp)) + sys.stdout.write(obj.decode()) + sys.stdout.write('\n') + sys.stdout.flush() +while 1: + try: + run() + except KeyboardInterrupt: + break diff --git a/Program/libcsp/wscript b/Program/libcsp/wscript new file mode 100755 index 0000000..6421f08 --- /dev/null +++ b/Program/libcsp/wscript @@ -0,0 +1,245 @@ +#!/usr/bin/env python +# encoding: utf-8 + +# Cubesat Space Protocol - A small network-layer protocol designed for Cubesats +# Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) +# Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +import os + +APPNAME = 'libcsp' +VERSION = '1.6' + +valid_os = ['posix', 'windows', 'freertos', 'macosx'] +valid_loglevel = ['error', 'warn', 'info', 'debug'] + + +def options(ctx): + # Load compiler + ctx.load('compiler_c') + + ctx.add_option('--toolchain', default=None, help='Set toolchain prefix') + + # Set libcsp options + gr = ctx.add_option_group('libcsp options') + gr.add_option('--includes', default='', help='Add additional include paths, separate with comma') + gr.add_option('--install-csp', action='store_true', help='Installs CSP headers and lib') + + gr.add_option('--disable-output', action='store_true', help='Disable CSP output') + gr.add_option('--disable-stlib', action='store_true', help='Build objects only') + gr.add_option('--enable-shlib', action='store_true', help='Build shared library') + gr.add_option('--enable-rdp', action='store_true', help='Enable RDP support') + gr.add_option('--enable-rdp-fast-close', action='store_true', help='Enable fast close of RDP connections') + gr.add_option('--enable-qos', action='store_true', help='Enable Quality of Service support') + gr.add_option('--enable-promisc', action='store_true', help='Enable promiscuous support') + gr.add_option('--enable-crc32', action='store_true', help='Enable CRC32 support') + gr.add_option('--enable-hmac', action='store_true', help='Enable HMAC-SHA1 support') + gr.add_option('--enable-xtea', action='store_true', help='Enable XTEA support') + gr.add_option('--enable-python3-bindings', action='store_true', help='Enable Python3 bindings') + gr.add_option('--enable-examples', action='store_true', help='Enable examples') + gr.add_option('--enable-dedup', action='store_true', help='Enable packet deduplicator') + gr.add_option('--enable-external-debug', action='store_true', help='Enable external debug API') + gr.add_option('--enable-debug-timestamp', action='store_true', help='Enable timestamps on debug/log') + + # Drivers and interfaces (requires external dependencies) + gr.add_option('--enable-if-zmqhub', action='store_true', help='Enable ZMQ interface') + gr.add_option('--enable-can-socketcan', action='store_true', help='Enable Linux socketcan driver') + gr.add_option('--with-driver-usart', default=None, metavar='DRIVER', + help='Build USART driver. [windows, linux, None]') + + # OS + gr.add_option('--with-os', metavar='OS', default='posix', + help='Set operating system. Must be one of: ' + str(valid_os)) + + # Options + gr.add_option('--with-loglevel', metavar='LEVEL', default='debug', + help='Set minimum compile time log level. Must be one of: ' + str(valid_loglevel)) + gr.add_option('--with-rtable', metavar='TABLE', default='static', + help='Set routing table type: \'static\' or \'cidr\'') + + +def configure(ctx): + # Validate options + if ctx.options.with_os not in valid_os: + ctx.fatal('--with-os must be either: ' + str(valid_os)) + + if ctx.options.with_loglevel not in valid_loglevel: + ctx.fatal('--with-loglevel must be either: ' + str(valid_loglevel)) + + # Setup and validate toolchain + if (len(ctx.stack_path) <= 1) and ctx.options.toolchain: + ctx.env.CC = ctx.options.toolchain + 'gcc' + ctx.env.AR = ctx.options.toolchain + 'ar' + + ctx.load('compiler_c') + + # Set git revision define + git_rev = os.popen('git describe --long --always 2> /dev/null || echo unknown').read().strip() + ctx.define('GIT_REV', git_rev) + + # Set build output format + ctx.env.FEATURES = ['c'] + if not ctx.options.disable_stlib: + ctx.env.FEATURES += ['cstlib'] + + ctx.env.LIBCSP_SHLIB = ctx.options.enable_shlib + + # Setup CFLAGS + if (len(ctx.stack_path) <= 1) and (len(ctx.env.CFLAGS) == 0): + ctx.env.prepend_value('CFLAGS', ["-std=gnu99", "-g", "-Os", "-Wall", "-Wextra", "-Wshadow", "-Wcast-align", + "-Wwrite-strings", "-Wno-unused-parameter"]) + + # Setup default include path and any extra defined + ctx.env.append_unique('INCLUDES_CSP', ['include'] + ctx.options.includes.split(',')) + + # Store OS as env variable + ctx.env.append_unique('OS', ctx.options.with_os) + + # Platform/OS specifics + if ctx.options.with_os == 'posix': + ctx.env.append_unique('LIBS', ['rt', 'pthread', 'util']) + elif ctx.options.with_os == 'macosx': + ctx.env.append_unique('LIBS', ['pthread']) + elif ctx.options.with_os == 'windows': + ctx.env.append_unique('CFLAGS', ['-D_WIN32_WINNT=0x0600']) + + ctx.define_cond('CSP_FREERTOS', ctx.options.with_os == 'freertos') + ctx.define_cond('CSP_POSIX', ctx.options.with_os == 'posix') + ctx.define_cond('CSP_WINDOWS', ctx.options.with_os == 'windows') + ctx.define_cond('CSP_MACOSX', ctx.options.with_os == 'macosx') + + # Add files + ctx.env.append_unique('FILES_CSP', ['src/*.c', + 'src/external/**/*.c', + 'src/transport/**/*.c', + 'src/crypto/**/*.c', + 'src/interfaces/**/*.c', + 'src/arch/*.c', + 'src/arch/{0}/**/*.c'.format(ctx.options.with_os), + 'src/rtable/csp_rtable.c', + 'src/rtable/csp_rtable_{0}.c'.format(ctx.options.with_rtable)]) + + # Add socketcan + if ctx.options.enable_can_socketcan: + ctx.env.append_unique('FILES_CSP', 'src/drivers/can/can_socketcan.c') + ctx.check_cfg(package='libsocketcan', args='--cflags --libs', define_name='CSP_HAVE_LIBSOCKETCAN') + ctx.env.append_unique('LIBS', ctx.env.LIB_LIBSOCKETCAN) + + # Add USART driver + if ctx.options.with_driver_usart: + ctx.env.append_unique('FILES_CSP', ['src/drivers/usart/usart_kiss.c', + 'src/drivers/usart/usart_{0}.c'.format(ctx.options.with_driver_usart)]) + + # Add ZMQ + if ctx.options.enable_if_zmqhub: + ctx.check_cfg(package='libzmq', args='--cflags --libs', define_name='CSP_HAVE_LIBZMQ') + ctx.env.append_unique('LIBS', ctx.env.LIB_LIBZMQ) + + # Store configuration options + ctx.env.ENABLE_EXAMPLES = ctx.options.enable_examples + + # Add Python bindings + if ctx.options.enable_python3_bindings: + ctx.env.LIBCSP_PYTHON3 = ctx.check_cfg(package='python3', args='--cflags --libs', atleast_version='3.5', + mandatory=True) + + # Set defines for enabling features + ctx.define('CSP_DEBUG', not ctx.options.disable_output) + ctx.define('CSP_DEBUG_TIMESTAMP', ctx.options.enable_debug_timestamp) + ctx.define('CSP_USE_RDP', ctx.options.enable_rdp) + ctx.define('CSP_USE_RDP_FAST_CLOSE', ctx.options.enable_rdp and ctx.options.enable_rdp_fast_close) + ctx.define('CSP_USE_CRC32', ctx.options.enable_crc32) + ctx.define('CSP_USE_HMAC', ctx.options.enable_hmac) + ctx.define('CSP_USE_XTEA', ctx.options.enable_xtea) + ctx.define('CSP_USE_PROMISC', ctx.options.enable_promisc) + ctx.define('CSP_USE_QOS', ctx.options.enable_qos) + ctx.define('CSP_USE_DEDUP', ctx.options.enable_dedup) + ctx.define('CSP_USE_EXTERNAL_DEBUG', ctx.options.enable_external_debug) + + # Set logging level + ctx.define('CSP_LOG_LEVEL_DEBUG', ctx.options.with_loglevel in ('debug')) + ctx.define('CSP_LOG_LEVEL_INFO', ctx.options.with_loglevel in ('debug', 'info')) + ctx.define('CSP_LOG_LEVEL_WARN', ctx.options.with_loglevel in ('debug', 'info', 'warn')) + ctx.define('CSP_LOG_LEVEL_ERROR', ctx.options.with_loglevel in ('debug', 'info', 'warn', 'error')) + + # Check compiler endianness + endianness = ctx.check_endianness() + ctx.define_cond('CSP_LITTLE_ENDIAN', endianness == 'little') + ctx.define_cond('CSP_BIG_ENDIAN', endianness == 'big') + + ctx.define('LIBCSP_VERSION', VERSION) + + ctx.write_config_header('include/csp/csp_autoconfig.h') + + +def build(ctx): + + # Set install path for header files + install_path = None + if ctx.options.install_csp: + install_path = '${PREFIX}/lib' + ctx.install_files('${PREFIX}/include/csp', + ctx.path.ant_glob('include/csp/**'), + cwd=ctx.path.find_dir('include/csp'), + relative_trick=True) + ctx.install_files('${PREFIX}/include/csp', 'include/csp/csp_autoconfig.h', cwd=ctx.bldnode) + + ctx(export_includes=ctx.env.INCLUDES_CSP, name='csp_h') + + ctx(features=ctx.env.FEATURES, + source=ctx.path.ant_glob(ctx.env.FILES_CSP), + target='csp', + use=['csp_h', 'freertos_h', 'util'], + install_path=install_path) + + # Build shared library + if ctx.env.LIBCSP_SHLIB or ctx.env.LIBCSP_PYTHON3: + ctx.shlib(source=ctx.path.ant_glob(ctx.env.FILES_CSP), + name='csp_shlib', + target='csp', + use=['csp_h', 'util_shlib'], + lib=ctx.env.LIBS) + + # Build Python bindings + if ctx.env.LIBCSP_PYTHON3: + ctx.shlib(source=ctx.path.ant_glob('src/bindings/python/**/*.c'), + target='csp_py3', + includes=ctx.env.INCLUDES_PYTHON3, + use=['csp_shlib'], + lib=ctx.env.LIBS, + pytest_path=[ctx.path.get_bld()]) + + if ctx.env.ENABLE_EXAMPLES: + ctx.program(source='examples/csp_server_client.c', + target='csp_server_client', + lib=ctx.env.LIBS, + use='csp') + + ctx.program(source='examples/csp_arch.c', + target='csp_arch', + lib=ctx.env.LIBS, + use='csp') + + if ctx.env.CSP_HAVE_LIBZMQ: + ctx.program(source='examples/zmqproxy.c', + target='zmqproxy', + lib=ctx.env.LIBS, + use='csp') + + +def dist(ctx): + ctx.excl = 'build/* **/.* **/*.pyc **/*.o **/*~ *.tar.gz' From a2b5b9a708a267a123bba44f251149e5e8592379 Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 15 Jun 2021 17:04:43 -0600 Subject: [PATCH 359/400] add ramdom sequence number start --- Program/src/file_delivery_app.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 6f3d7b8..4d18042 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -8,6 +8,7 @@ Author: Evan Giese #include "port.h" #include "file_delivery_app.h" #include "app_control.h" +#include "stdlib.h" int create_ssp_server_drivers(FTP *app) { @@ -178,7 +179,7 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { app->packet_len = remote_entity.mtu; app->buff = ssp_alloc(1, app->packet_len); - app->transaction_sequence_number = 0; + app->transaction_sequence_number = rand(); if (app->buff == NULL) { ssp_free(app); From f22602abd5fb020dc39f769f3a828b8dde9c8117 Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 15 Jun 2021 17:14:16 -0600 Subject: [PATCH 360/400] mod 255 for transaction number start --- Program/src/file_delivery_app.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 4d18042..6a23597 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -179,7 +179,7 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { app->packet_len = remote_entity.mtu; app->buff = ssp_alloc(1, app->packet_len); - app->transaction_sequence_number = rand(); + app->transaction_sequence_number = rand() % 255; if (app->buff == NULL) { ssp_free(app); From 1d760c476a40c52da6021e26c2425f93243abf11 Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 23 Jun 2021 20:04:47 -0600 Subject: [PATCH 361/400] add tests and truncate --- Program/src/file_delivery_app.c | 4 +-- Program/test/mock.c | 12 +++------ Program/test/protocol_handler_tests.c | 38 +++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 6a23597..ab21834 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -128,7 +128,7 @@ static void make_default_data(){ \"one_way_light_time\" : 123\n\ }"; - int fd = ssp_open("mib/peer_1.json", SSP_O_CREAT | SSP_O_RDWR); + int fd = ssp_open("mib/peer_1.json", SSP_O_CREAT | SSP_O_RDWR | SSP_O_TRUNC); if (fd < 0) { if (fd == SSP_EEXIST) { ssp_error("file exists\n"); @@ -142,7 +142,7 @@ static void make_default_data(){ } } - fd = ssp_open("mib/peer_10.json", SSP_O_CREAT | SSP_O_RDWR); + fd = ssp_open("mib/peer_10.json", SSP_O_CREAT | SSP_O_RDWR | SSP_O_TRUNC); if (fd < 0) { if (fd == SSP_EEXIST) { ssp_error("file exists\n"); diff --git a/Program/test/mock.c b/Program/test/mock.c index 2f391ec..9346a50 100755 --- a/Program/test/mock.c +++ b/Program/test/mock.c @@ -13,7 +13,6 @@ #include #include -//char buff[1500]; void mock_mock_remote_entity(Remote_entity *remote_entity, uint32_t cfdp_id) { @@ -71,7 +70,7 @@ Client *mock_client() { } -Response *mock_response(char *buffer) { +Response *mock_response() { Response *res = calloc(1, sizeof(Response)); int addr = 16; res->addr = &addr; @@ -80,7 +79,8 @@ Response *mock_response(char *buffer) { res->size_of_addr = 16; res->type_of_network = posix_connectionless; res->transmission_mode = UN_ACKNOWLEDGED_MODE; - res->msg = buffer; + res->packet_len = 255; + res->type_of_network = test; return res; } @@ -101,12 +101,6 @@ Request *mock_request() { req->dest_cfdp_id = id; req->file = create_file("test_files/dest_received.jpg", true); - int error = add_first_offset(req->file, req->file->total_size); - if (error < 0) { - ssp_free_file(req->file); - return NULL; - } - ssp_memcpy (req->source_file_name, dest, strnlen(dest, 255)); ssp_memcpy (req->destination_file_name, src, strnlen(src, 255)); diff --git a/Program/test/protocol_handler_tests.c b/Program/test/protocol_handler_tests.c index beb5ea5..866b88e 100755 --- a/Program/test/protocol_handler_tests.c +++ b/Program/test/protocol_handler_tests.c @@ -223,18 +223,52 @@ int test_process_nak() { } -void test_send_data_from_nak_array(){ +int test_user_request_handler_send_nak_data(){ + DECLARE_NEW_TEST("user request (client side) initiation starts"); + Client client; + mock_client(&client); + char buff[2000]; + + Response *res = mock_response(); + Request *req = mock_request(); + + ssp_printf("file size %d\n", req->file_size); + + int error = add_first_offset(req->file, 100000); + if (error < 0) { + ssp_free_file(req->file); + return NULL; + } + + receive_offset(req->file, 3000, 5000); + receive_offset(req->file, 10000, 40000); + + ssp_printf("offset count %d\n", req->file->missing_offsets->count); + + req->paused = false; + req->procedure = sending_nak_data; + res->type_of_network = test; + res->msg = req->buff; + + user_request_handler(*res, req, &client); + + ssp_cleanup_req(req); + return 0; } + + int protocol_handler_test() { int error = 0; + //error = test_process_pdu_header(); //error = test_process_pdu_eof(); //error = test_on_server_time_out(); //error = test_process_data_packet(); - error = test_process_nak(); + //error = test_process_nak(); + error = test_user_request_handler_send_nak_data(); return error; } \ No newline at end of file From 47511a3ffc67d96320abbdaacaba1cf976294ab4 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 24 Jun 2021 16:00:31 -0600 Subject: [PATCH 362/400] start request on get request --- Program/src/protocol_handler.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index b5a0f4e..f750cf2 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -323,9 +323,9 @@ void process_messages(Request *req, FTP *app) { (char *)p_put->destination_file_name.value, p_put->destination_id); - put_request(p_put->destination_id, + start_request(put_request(p_put->destination_id, (char *)p_put->source_file_name.value, - (char *)p_put->destination_file_name.value, req->remote_entity.default_transmission_mode, app); + (char *)p_put->destination_file_name.value, req->remote_entity.default_transmission_mode, app)); break; @@ -782,7 +782,7 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, if (req->file_size != 0) process_file_request_metadata(req); else { - printf("just receiving messages, closing request\n"); + ssp_printf("just receiving messages, closing request\n"); req->local_entity.EOF_recv_indication = true; req->procedure = none; req->paused = true; From 3aeebb36095feafcc36c1e76815cbf74fcab1de8 Mon Sep 17 00:00:00 2001 From: Dustin Wagner <60157752+wagnerd97@users.noreply.github.com> Date: Fri, 25 Jun 2021 08:57:06 -0600 Subject: [PATCH 363/400] update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 07c1777..9a5167d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ settings.json SpaceProjects.odt Program/src/incomplete_requests Program/src/obj +Program/test/incomplete_requests +Program/test/temp *.o *.a From a6f68a089d29520ad5c4b69897668eabe3b0235c Mon Sep 17 00:00:00 2001 From: evangee Date: Mon, 5 Jul 2021 11:59:00 -0600 Subject: [PATCH 364/400] remove libcsp --- Program/libcsp/CHANGELOG | 163 --- Program/libcsp/CI.rst | 6 - Program/libcsp/COPYING | 503 ------- Program/libcsp/INSTALL.rst | 29 - Program/libcsp/README.rst | 41 - Program/libcsp/build/.lock-waf_linux_build | 10 - .../libcsp/build/.wafpickle-linux-50727408-20 | Bin 30138 -> 0 bytes Program/libcsp/build/c4che/_cache.py | 59 - Program/libcsp/build/c4che/build.config.py | 2 - Program/libcsp/build/config.log | 409 ------ Program/libcsp/build/csp_arch | Bin 93424 -> 0 bytes Program/libcsp/build/csp_server_client | Bin 339352 -> 0 bytes Program/libcsp/build/examples/csp_arch.c.6.o | Bin 99912 -> 0 bytes .../build/examples/csp_server_client.c.5.o | Bin 35520 -> 0 bytes Program/libcsp/build/examples/zmqproxy.c.7.o | Bin 24472 -> 0 bytes .../libcsp/build/include/csp/csp_autoconfig.h | 33 - Program/libcsp/build/libcsp.a | Bin 782614 -> 0 bytes Program/libcsp/build/libcsp.so | Bin 370272 -> 0 bytes Program/libcsp/build/libcsp_py3.so | Bin 103352 -> 0 bytes .../libcsp/build/src/arch/csp_system.c.2.o | Bin 8832 -> 0 bytes .../libcsp/build/src/arch/csp_system.c.3.o | Bin 8856 -> 0 bytes Program/libcsp/build/src/arch/csp_time.c.2.o | Bin 3976 -> 0 bytes Program/libcsp/build/src/arch/csp_time.c.3.o | Bin 3984 -> 0 bytes .../build/src/arch/posix/csp_clock.c.2.o | Bin 5696 -> 0 bytes .../build/src/arch/posix/csp_clock.c.3.o | Bin 5704 -> 0 bytes .../build/src/arch/posix/csp_malloc.c.2.o | Bin 4872 -> 0 bytes .../build/src/arch/posix/csp_malloc.c.3.o | Bin 4872 -> 0 bytes .../build/src/arch/posix/csp_queue.c.2.o | Bin 9368 -> 0 bytes .../build/src/arch/posix/csp_queue.c.3.o | Bin 8784 -> 0 bytes .../build/src/arch/posix/csp_semaphore.c.2.o | Bin 17592 -> 0 bytes .../build/src/arch/posix/csp_semaphore.c.3.o | Bin 17648 -> 0 bytes .../build/src/arch/posix/csp_system.c.2.o | Bin 16888 -> 0 bytes .../build/src/arch/posix/csp_system.c.3.o | Bin 16864 -> 0 bytes .../build/src/arch/posix/csp_thread.c.2.o | Bin 9248 -> 0 bytes .../build/src/arch/posix/csp_thread.c.3.o | Bin 9256 -> 0 bytes .../build/src/arch/posix/csp_time.c.2.o | Bin 5568 -> 0 bytes .../build/src/arch/posix/csp_time.c.3.o | Bin 5632 -> 0 bytes .../build/src/arch/posix/pthread_queue.c.2.o | Bin 19096 -> 0 bytes .../build/src/arch/posix/pthread_queue.c.3.o | Bin 19104 -> 0 bytes .../build/src/bindings/python/pycsp.c.4.o | Bin 157552 -> 0 bytes .../libcsp/build/src/crypto/csp_hmac.c.2.o | Bin 15840 -> 0 bytes .../libcsp/build/src/crypto/csp_hmac.c.3.o | Bin 15848 -> 0 bytes .../libcsp/build/src/crypto/csp_sha1.c.2.o | Bin 11832 -> 0 bytes .../libcsp/build/src/crypto/csp_sha1.c.3.o | Bin 11872 -> 0 bytes .../libcsp/build/src/crypto/csp_xtea.c.2.o | Bin 13304 -> 0 bytes .../libcsp/build/src/crypto/csp_xtea.c.3.o | Bin 12968 -> 0 bytes Program/libcsp/build/src/csp_bridge.c.2.o | Bin 13336 -> 0 bytes Program/libcsp/build/src/csp_bridge.c.3.o | Bin 13352 -> 0 bytes Program/libcsp/build/src/csp_buffer.c.2.o | Bin 19776 -> 0 bytes Program/libcsp/build/src/csp_buffer.c.3.o | Bin 19608 -> 0 bytes Program/libcsp/build/src/csp_conn.c.2.o | Bin 37800 -> 0 bytes Program/libcsp/build/src/csp_conn.c.3.o | Bin 37872 -> 0 bytes Program/libcsp/build/src/csp_crc32.c.2.o | Bin 11960 -> 0 bytes Program/libcsp/build/src/csp_crc32.c.3.o | Bin 11968 -> 0 bytes Program/libcsp/build/src/csp_debug.c.2.o | Bin 13752 -> 0 bytes Program/libcsp/build/src/csp_debug.c.3.o | Bin 13768 -> 0 bytes Program/libcsp/build/src/csp_dedup.c.2.o | Bin 8848 -> 0 bytes Program/libcsp/build/src/csp_dedup.c.3.o | Bin 8856 -> 0 bytes Program/libcsp/build/src/csp_endian.c.2.o | Bin 9144 -> 0 bytes Program/libcsp/build/src/csp_endian.c.3.o | Bin 9064 -> 0 bytes Program/libcsp/build/src/csp_hex_dump.c.2.o | Bin 10880 -> 0 bytes Program/libcsp/build/src/csp_hex_dump.c.3.o | Bin 10880 -> 0 bytes Program/libcsp/build/src/csp_iflist.c.2.o | Bin 14224 -> 0 bytes Program/libcsp/build/src/csp_iflist.c.3.o | Bin 14232 -> 0 bytes Program/libcsp/build/src/csp_init.c.2.o | Bin 14856 -> 0 bytes Program/libcsp/build/src/csp_init.c.3.o | Bin 15048 -> 0 bytes Program/libcsp/build/src/csp_io.c.2.o | Bin 33800 -> 0 bytes Program/libcsp/build/src/csp_io.c.3.o | Bin 33752 -> 0 bytes Program/libcsp/build/src/csp_port.c.2.o | Bin 14704 -> 0 bytes Program/libcsp/build/src/csp_port.c.3.o | Bin 14664 -> 0 bytes Program/libcsp/build/src/csp_promisc.c.2.o | Bin 5080 -> 0 bytes Program/libcsp/build/src/csp_promisc.c.3.o | Bin 5080 -> 0 bytes Program/libcsp/build/src/csp_qfifo.c.2.o | Bin 15288 -> 0 bytes Program/libcsp/build/src/csp_qfifo.c.3.o | Bin 15320 -> 0 bytes Program/libcsp/build/src/csp_route.c.2.o | Bin 22768 -> 0 bytes Program/libcsp/build/src/csp_route.c.3.o | Bin 22712 -> 0 bytes .../build/src/csp_service_handler.c.2.o | Bin 27968 -> 0 bytes .../build/src/csp_service_handler.c.3.o | Bin 27808 -> 0 bytes Program/libcsp/build/src/csp_services.c.2.o | Bin 33304 -> 0 bytes Program/libcsp/build/src/csp_services.c.3.o | Bin 33312 -> 0 bytes Program/libcsp/build/src/csp_sfp.c.2.o | Bin 21392 -> 0 bytes Program/libcsp/build/src/csp_sfp.c.3.o | Bin 21440 -> 0 bytes .../build/src/drivers/can/can_socketcan.c.2.o | Bin 33072 -> 0 bytes .../build/src/drivers/can/can_socketcan.c.3.o | Bin 32976 -> 0 bytes .../build/src/drivers/usart/usart_kiss.c.2.o | Bin 16160 -> 0 bytes .../build/src/drivers/usart/usart_kiss.c.3.o | Bin 16168 -> 0 bytes .../build/src/drivers/usart/usart_linux.c.2.o | Bin 20896 -> 0 bytes .../build/src/drivers/usart/usart_linux.c.3.o | Bin 20936 -> 0 bytes .../build/src/interfaces/csp_if_can.c.2.o | Bin 19856 -> 0 bytes .../build/src/interfaces/csp_if_can.c.3.o | Bin 19856 -> 0 bytes .../src/interfaces/csp_if_can_pbuf.c.2.o | Bin 8808 -> 0 bytes .../src/interfaces/csp_if_can_pbuf.c.3.o | Bin 8808 -> 0 bytes .../build/src/interfaces/csp_if_i2c.c.2.o | Bin 13000 -> 0 bytes .../build/src/interfaces/csp_if_i2c.c.3.o | Bin 13008 -> 0 bytes .../build/src/interfaces/csp_if_kiss.c.2.o | Bin 17240 -> 0 bytes .../build/src/interfaces/csp_if_kiss.c.3.o | Bin 17248 -> 0 bytes .../build/src/interfaces/csp_if_lo.c.2.o | Bin 10560 -> 0 bytes .../build/src/interfaces/csp_if_lo.c.3.o | Bin 10568 -> 0 bytes .../build/src/interfaces/csp_if_zmqhub.c.2.o | Bin 29712 -> 0 bytes .../build/src/interfaces/csp_if_zmqhub.c.3.o | Bin 29744 -> 0 bytes .../libcsp/build/src/rtable/csp_rtable.c.2.o | Bin 26704 -> 0 bytes .../libcsp/build/src/rtable/csp_rtable.c.3.o | Bin 26736 -> 0 bytes .../build/src/rtable/csp_rtable_static.c.2.o | Bin 13192 -> 0 bytes .../build/src/rtable/csp_rtable_static.c.3.o | Bin 13200 -> 0 bytes .../libcsp/build/src/transport/csp_rdp.c.2.o | Bin 82592 -> 0 bytes .../libcsp/build/src/transport/csp_rdp.c.3.o | Bin 81376 -> 0 bytes .../libcsp/build/src/transport/csp_udp.c.2.o | Bin 11968 -> 0 bytes .../libcsp/build/src/transport/csp_udp.c.3.o | Bin 11984 -> 0 bytes Program/libcsp/build/zmqproxy | Bin 38720 -> 0 bytes Program/libcsp/doc/basic.rst | 153 --- Program/libcsp/doc/example.rst | 61 - Program/libcsp/doc/history.rst | 21 - Program/libcsp/doc/libcsp.rst | 21 - Program/libcsp/doc/memory.rst | 16 - Program/libcsp/doc/mtu.rst | 19 - Program/libcsp/doc/protocolstack.rst | 61 - Program/libcsp/doc/structure.rst | 29 - Program/libcsp/doc/topology.rst | 27 - Program/libcsp/examples/buildall.py | 52 - Program/libcsp/examples/csp_arch.c | 159 --- Program/libcsp/examples/csp_server_client.c | 316 ----- .../python_bindings_example_client.py | 63 - .../python_bindings_example_server.py | 74 -- Program/libcsp/examples/zmqproxy.c | 115 -- Program/libcsp/include/csp/arch/csp_clock.h | 70 - Program/libcsp/include/csp/arch/csp_malloc.h | 60 - Program/libcsp/include/csp/arch/csp_queue.h | 126 -- .../libcsp/include/csp/arch/csp_semaphore.h | 206 --- Program/libcsp/include/csp/arch/csp_system.h | 135 -- Program/libcsp/include/csp/arch/csp_thread.h | 133 -- Program/libcsp/include/csp/arch/csp_time.h | 73 -- .../include/csp/arch/posix/csp_system.h | 59 - .../include/csp/arch/posix/pthread_queue.h | 114 -- Program/libcsp/include/csp/crypto/csp_hmac.h | 82 -- Program/libcsp/include/csp/crypto/csp_sha1.h | 89 -- Program/libcsp/include/csp/crypto/csp_xtea.h | 78 -- Program/libcsp/include/csp/csp.h | 491 ------- Program/libcsp/include/csp/csp_buffer.h | 94 -- Program/libcsp/include/csp/csp_cmp.h | 214 --- Program/libcsp/include/csp/csp_crc32.h | 62 - Program/libcsp/include/csp/csp_debug.h | 226 ---- Program/libcsp/include/csp/csp_endian.h | 148 --- Program/libcsp/include/csp/csp_error.h | 60 - Program/libcsp/include/csp/csp_iflist.h | 76 -- Program/libcsp/include/csp/csp_interface.h | 95 -- Program/libcsp/include/csp/csp_platform.h | 70 - Program/libcsp/include/csp/csp_promisc.h | 64 - Program/libcsp/include/csp/csp_rtable.h | 172 --- Program/libcsp/include/csp/csp_sfp.h | 111 -- Program/libcsp/include/csp/csp_types.h | 292 ----- .../include/csp/drivers/can_socketcan.h | 73 -- Program/libcsp/include/csp/drivers/usart.h | 121 -- .../include/csp/interfaces/csp_if_can.h | 178 --- .../include/csp/interfaces/csp_if_i2c.h | 118 -- .../include/csp/interfaces/csp_if_kiss.h | 116 -- .../libcsp/include/csp/interfaces/csp_if_lo.h | 49 - .../include/csp/interfaces/csp_if_zmqhub.h | 118 -- Program/libcsp/src/arch/csp_system.c | 58 - Program/libcsp/src/arch/csp_time.c | 32 - Program/libcsp/src/arch/freertos/csp_clock.c | 32 - Program/libcsp/src/arch/freertos/csp_malloc.c | 42 - Program/libcsp/src/arch/freertos/csp_queue.c | 60 - .../libcsp/src/arch/freertos/csp_semaphore.c | 84 -- Program/libcsp/src/arch/freertos/csp_system.c | 88 -- Program/libcsp/src/arch/freertos/csp_thread.c | 48 - Program/libcsp/src/arch/freertos/csp_time.c | 40 - Program/libcsp/src/arch/macosx/csp_clock.c | 22 - Program/libcsp/src/arch/macosx/csp_malloc.c | 22 - Program/libcsp/src/arch/macosx/csp_queue.c | 22 - .../libcsp/src/arch/macosx/csp_semaphore.c | 85 -- Program/libcsp/src/arch/macosx/csp_system.c | 87 -- Program/libcsp/src/arch/macosx/csp_thread.c | 55 - Program/libcsp/src/arch/macosx/csp_time.c | 22 - .../libcsp/src/arch/macosx/pthread_queue.c | 178 --- Program/libcsp/src/arch/posix/csp_clock.c | 45 - Program/libcsp/src/arch/posix/csp_malloc.c | 36 - Program/libcsp/src/arch/posix/csp_queue.c | 60 - Program/libcsp/src/arch/posix/csp_semaphore.c | 155 --- Program/libcsp/src/arch/posix/csp_system.c | 135 -- Program/libcsp/src/arch/posix/csp_thread.c | 72 - Program/libcsp/src/arch/posix/csp_time.c | 57 - Program/libcsp/src/arch/posix/pthread_queue.c | 239 ---- Program/libcsp/src/arch/windows/README | 18 - Program/libcsp/src/arch/windows/csp_clock.c | 42 - Program/libcsp/src/arch/windows/csp_malloc.c | 35 - Program/libcsp/src/arch/windows/csp_queue.c | 59 - .../libcsp/src/arch/windows/csp_semaphore.c | 100 -- Program/libcsp/src/arch/windows/csp_system.c | 54 - Program/libcsp/src/arch/windows/csp_thread.c | 46 - Program/libcsp/src/arch/windows/csp_time.c | 44 - .../libcsp/src/arch/windows/windows_queue.c | 127 -- .../libcsp/src/arch/windows/windows_queue.h | 46 - Program/libcsp/src/bindings/python/pycsp.c | 1121 ---------------- Program/libcsp/src/crypto/csp_hmac.c | 194 --- Program/libcsp/src/crypto/csp_sha1.c | 211 --- Program/libcsp/src/crypto/csp_xtea.c | 181 --- Program/libcsp/src/csp_bridge.c | 96 -- Program/libcsp/src/csp_buffer.c | 224 ---- Program/libcsp/src/csp_conn.c | 527 -------- Program/libcsp/src/csp_conn.h | 119 -- Program/libcsp/src/csp_crc32.c | 130 -- Program/libcsp/src/csp_debug.c | 138 -- Program/libcsp/src/csp_dedup.c | 62 - Program/libcsp/src/csp_dedup.h | 33 - Program/libcsp/src/csp_endian.c | 200 --- Program/libcsp/src/csp_hex_dump.c | 76 -- Program/libcsp/src/csp_iflist.c | 106 -- Program/libcsp/src/csp_init.c | 95 -- Program/libcsp/src/csp_init.h | 38 - Program/libcsp/src/csp_io.c | 408 ------ Program/libcsp/src/csp_io.h | 44 - Program/libcsp/src/csp_port.c | 115 -- Program/libcsp/src/csp_port.h | 57 - Program/libcsp/src/csp_promisc.c | 84 -- Program/libcsp/src/csp_promisc.h | 39 - Program/libcsp/src/csp_qfifo.c | 168 --- Program/libcsp/src/csp_qfifo.h | 58 - Program/libcsp/src/csp_route.c | 337 ----- Program/libcsp/src/csp_service_handler.c | 338 ----- Program/libcsp/src/csp_services.c | 254 ---- Program/libcsp/src/csp_sfp.c | 229 ---- .../libcsp/src/drivers/can/can_socketcan.c | 237 ---- Program/libcsp/src/drivers/usart/usart_kiss.c | 86 -- .../libcsp/src/drivers/usart/usart_linux.c | 271 ---- .../libcsp/src/drivers/usart/usart_windows.c | 173 --- Program/libcsp/src/interfaces/csp_if_can.c | 275 ---- .../libcsp/src/interfaces/csp_if_can_pbuf.c | 93 -- .../libcsp/src/interfaces/csp_if_can_pbuf.h | 46 - Program/libcsp/src/interfaces/csp_if_i2c.c | 112 -- Program/libcsp/src/interfaces/csp_if_kiss.c | 245 ---- Program/libcsp/src/interfaces/csp_if_lo.c | 53 - Program/libcsp/src/interfaces/csp_if_zmqhub.c | 238 ---- Program/libcsp/src/rtable/csp_rtable.c | 180 --- Program/libcsp/src/rtable/csp_rtable_cidr.c | 147 --- .../libcsp/src/rtable/csp_rtable_internal.h | 24 - Program/libcsp/src/rtable/csp_rtable_static.c | 73 -- Program/libcsp/src/transport/csp_rdp.c | 1157 ----------------- Program/libcsp/src/transport/csp_transport.h | 48 - Program/libcsp/src/transport/csp_udp.c | 50 - Program/libcsp/utils/cfpsplit.py | 53 - Program/libcsp/utils/cspsplit.py | 53 - Program/libcsp/waf | 173 --- .../waflib/Build.py | 804 ------------ .../waflib/ConfigSet.py | 165 --- .../waflib/Configure.py | 377 ------ .../waflib/Context.py | 406 ------ .../waflib/Errors.py | 39 - .../waflib/Logs.py | 206 --- .../waflib/Node.py | 477 ------- .../waflib/Options.py | 200 --- .../waflib/Runner.py | 375 ------ .../waflib/Scripting.py | 415 ------ .../waflib/Task.py | 792 ----------- .../waflib/TaskGen.py | 471 ------- .../waflib/Tools/__init__.py | 4 - .../waflib/Tools/ar.py | 13 - .../waflib/Tools/asm.py | 50 - .../waflib/Tools/bison.py | 28 - .../waflib/Tools/c.py | 26 - .../waflib/Tools/c_aliases.py | 62 - .../waflib/Tools/c_config.py | 805 ------------ .../waflib/Tools/c_osx.py | 121 -- .../waflib/Tools/c_preproc.py | 672 ---------- .../waflib/Tools/c_tests.py | 152 --- .../waflib/Tools/ccroot.py | 486 ------- .../waflib/Tools/clang.py | 20 - .../waflib/Tools/clangxx.py | 20 - .../waflib/Tools/compiler_c.py | 44 - .../waflib/Tools/compiler_cxx.py | 44 - .../waflib/Tools/compiler_d.py | 41 - .../waflib/Tools/compiler_fc.py | 43 - .../waflib/Tools/cs.py | 113 -- .../waflib/Tools/cxx.py | 26 - .../waflib/Tools/d.py | 54 - .../waflib/Tools/d_config.py | 52 - .../waflib/Tools/d_scan.py | 136 -- .../waflib/Tools/dbus.py | 29 - .../waflib/Tools/dmd.py | 51 - .../waflib/Tools/errcheck.py | 175 --- .../waflib/Tools/fc.py | 118 -- .../waflib/Tools/fc_config.py | 299 ----- .../waflib/Tools/fc_scan.py | 70 - .../waflib/Tools/flex.py | 38 - .../waflib/Tools/g95.py | 54 - .../waflib/Tools/gas.py | 13 - .../waflib/Tools/gcc.py | 104 -- .../waflib/Tools/gdc.py | 35 - .../waflib/Tools/gfortran.py | 71 - .../waflib/Tools/glib2.py | 242 ---- .../waflib/Tools/gnu_dirs.py | 66 - .../waflib/Tools/gxx.py | 104 -- .../waflib/Tools/icc.py | 20 - .../waflib/Tools/icpc.py | 20 - .../waflib/Tools/ifort.py | 303 ----- .../waflib/Tools/intltool.py | 101 -- .../waflib/Tools/irixcc.py | 51 - .../waflib/Tools/javaw.py | 330 ----- .../waflib/Tools/ldc2.py | 36 - .../waflib/Tools/lua.py | 18 - .../waflib/Tools/md5_tstamp.py | 24 - .../waflib/Tools/msvc.py | 704 ---------- .../waflib/Tools/nasm.py | 21 - .../waflib/Tools/nobuild.py | 11 - .../waflib/Tools/perl.py | 85 -- .../waflib/Tools/python.py | 422 ------ .../waflib/Tools/qt5.py | 499 ------- .../waflib/Tools/ruby.py | 97 -- .../waflib/Tools/suncc.py | 48 - .../waflib/Tools/suncxx.py | 48 - .../waflib/Tools/tex.py | 327 ----- .../waflib/Tools/vala.py | 218 ---- .../waflib/Tools/waf_unit_test.py | 172 --- .../waflib/Tools/winres.py | 52 - .../waflib/Tools/xlc.py | 44 - .../waflib/Tools/xlcxx.py | 44 - .../waflib/Utils.py | 625 --------- .../waflib/__init__.py | 4 - .../waflib/ansiterm.py | 238 ---- .../waflib/extras/__init__.py | 4 - .../waflib/extras/compat15.py | 305 ----- .../waflib/fixpy2.py | 47 - .../waflib/processor.py | 57 - Program/libcsp/wscript | 245 ---- 323 files changed, 32859 deletions(-) delete mode 100755 Program/libcsp/CHANGELOG delete mode 100755 Program/libcsp/CI.rst delete mode 100755 Program/libcsp/COPYING delete mode 100755 Program/libcsp/INSTALL.rst delete mode 100755 Program/libcsp/README.rst delete mode 100755 Program/libcsp/build/.lock-waf_linux_build delete mode 100755 Program/libcsp/build/.wafpickle-linux-50727408-20 delete mode 100755 Program/libcsp/build/c4che/_cache.py delete mode 100755 Program/libcsp/build/c4che/build.config.py delete mode 100755 Program/libcsp/build/config.log delete mode 100755 Program/libcsp/build/csp_arch delete mode 100755 Program/libcsp/build/csp_server_client delete mode 100755 Program/libcsp/build/examples/csp_arch.c.6.o delete mode 100755 Program/libcsp/build/examples/csp_server_client.c.5.o delete mode 100755 Program/libcsp/build/examples/zmqproxy.c.7.o delete mode 100755 Program/libcsp/build/include/csp/csp_autoconfig.h delete mode 100755 Program/libcsp/build/libcsp.a delete mode 100755 Program/libcsp/build/libcsp.so delete mode 100755 Program/libcsp/build/libcsp_py3.so delete mode 100755 Program/libcsp/build/src/arch/csp_system.c.2.o delete mode 100755 Program/libcsp/build/src/arch/csp_system.c.3.o delete mode 100755 Program/libcsp/build/src/arch/csp_time.c.2.o delete mode 100755 Program/libcsp/build/src/arch/csp_time.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_clock.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_clock.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_malloc.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_malloc.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_queue.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_queue.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_semaphore.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_semaphore.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_system.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_system.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_thread.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_thread.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_time.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/csp_time.c.3.o delete mode 100755 Program/libcsp/build/src/arch/posix/pthread_queue.c.2.o delete mode 100755 Program/libcsp/build/src/arch/posix/pthread_queue.c.3.o delete mode 100755 Program/libcsp/build/src/bindings/python/pycsp.c.4.o delete mode 100755 Program/libcsp/build/src/crypto/csp_hmac.c.2.o delete mode 100755 Program/libcsp/build/src/crypto/csp_hmac.c.3.o delete mode 100755 Program/libcsp/build/src/crypto/csp_sha1.c.2.o delete mode 100755 Program/libcsp/build/src/crypto/csp_sha1.c.3.o delete mode 100755 Program/libcsp/build/src/crypto/csp_xtea.c.2.o delete mode 100755 Program/libcsp/build/src/crypto/csp_xtea.c.3.o delete mode 100755 Program/libcsp/build/src/csp_bridge.c.2.o delete mode 100755 Program/libcsp/build/src/csp_bridge.c.3.o delete mode 100755 Program/libcsp/build/src/csp_buffer.c.2.o delete mode 100755 Program/libcsp/build/src/csp_buffer.c.3.o delete mode 100755 Program/libcsp/build/src/csp_conn.c.2.o delete mode 100755 Program/libcsp/build/src/csp_conn.c.3.o delete mode 100755 Program/libcsp/build/src/csp_crc32.c.2.o delete mode 100755 Program/libcsp/build/src/csp_crc32.c.3.o delete mode 100755 Program/libcsp/build/src/csp_debug.c.2.o delete mode 100755 Program/libcsp/build/src/csp_debug.c.3.o delete mode 100755 Program/libcsp/build/src/csp_dedup.c.2.o delete mode 100755 Program/libcsp/build/src/csp_dedup.c.3.o delete mode 100755 Program/libcsp/build/src/csp_endian.c.2.o delete mode 100755 Program/libcsp/build/src/csp_endian.c.3.o delete mode 100755 Program/libcsp/build/src/csp_hex_dump.c.2.o delete mode 100755 Program/libcsp/build/src/csp_hex_dump.c.3.o delete mode 100755 Program/libcsp/build/src/csp_iflist.c.2.o delete mode 100755 Program/libcsp/build/src/csp_iflist.c.3.o delete mode 100755 Program/libcsp/build/src/csp_init.c.2.o delete mode 100755 Program/libcsp/build/src/csp_init.c.3.o delete mode 100755 Program/libcsp/build/src/csp_io.c.2.o delete mode 100755 Program/libcsp/build/src/csp_io.c.3.o delete mode 100755 Program/libcsp/build/src/csp_port.c.2.o delete mode 100755 Program/libcsp/build/src/csp_port.c.3.o delete mode 100755 Program/libcsp/build/src/csp_promisc.c.2.o delete mode 100755 Program/libcsp/build/src/csp_promisc.c.3.o delete mode 100755 Program/libcsp/build/src/csp_qfifo.c.2.o delete mode 100755 Program/libcsp/build/src/csp_qfifo.c.3.o delete mode 100755 Program/libcsp/build/src/csp_route.c.2.o delete mode 100755 Program/libcsp/build/src/csp_route.c.3.o delete mode 100755 Program/libcsp/build/src/csp_service_handler.c.2.o delete mode 100755 Program/libcsp/build/src/csp_service_handler.c.3.o delete mode 100755 Program/libcsp/build/src/csp_services.c.2.o delete mode 100755 Program/libcsp/build/src/csp_services.c.3.o delete mode 100755 Program/libcsp/build/src/csp_sfp.c.2.o delete mode 100755 Program/libcsp/build/src/csp_sfp.c.3.o delete mode 100755 Program/libcsp/build/src/drivers/can/can_socketcan.c.2.o delete mode 100755 Program/libcsp/build/src/drivers/can/can_socketcan.c.3.o delete mode 100755 Program/libcsp/build/src/drivers/usart/usart_kiss.c.2.o delete mode 100755 Program/libcsp/build/src/drivers/usart/usart_kiss.c.3.o delete mode 100755 Program/libcsp/build/src/drivers/usart/usart_linux.c.2.o delete mode 100755 Program/libcsp/build/src/drivers/usart/usart_linux.c.3.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_can.c.2.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_can.c.3.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.2.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.3.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_i2c.c.2.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_i2c.c.3.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_kiss.c.2.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_kiss.c.3.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_lo.c.2.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_lo.c.3.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.2.o delete mode 100755 Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.3.o delete mode 100755 Program/libcsp/build/src/rtable/csp_rtable.c.2.o delete mode 100755 Program/libcsp/build/src/rtable/csp_rtable.c.3.o delete mode 100755 Program/libcsp/build/src/rtable/csp_rtable_static.c.2.o delete mode 100755 Program/libcsp/build/src/rtable/csp_rtable_static.c.3.o delete mode 100755 Program/libcsp/build/src/transport/csp_rdp.c.2.o delete mode 100755 Program/libcsp/build/src/transport/csp_rdp.c.3.o delete mode 100755 Program/libcsp/build/src/transport/csp_udp.c.2.o delete mode 100755 Program/libcsp/build/src/transport/csp_udp.c.3.o delete mode 100755 Program/libcsp/build/zmqproxy delete mode 100755 Program/libcsp/doc/basic.rst delete mode 100755 Program/libcsp/doc/example.rst delete mode 100755 Program/libcsp/doc/history.rst delete mode 100755 Program/libcsp/doc/libcsp.rst delete mode 100755 Program/libcsp/doc/memory.rst delete mode 100755 Program/libcsp/doc/mtu.rst delete mode 100755 Program/libcsp/doc/protocolstack.rst delete mode 100755 Program/libcsp/doc/structure.rst delete mode 100755 Program/libcsp/doc/topology.rst delete mode 100755 Program/libcsp/examples/buildall.py delete mode 100755 Program/libcsp/examples/csp_arch.c delete mode 100755 Program/libcsp/examples/csp_server_client.c delete mode 100755 Program/libcsp/examples/python_bindings_example_client.py delete mode 100755 Program/libcsp/examples/python_bindings_example_server.py delete mode 100755 Program/libcsp/examples/zmqproxy.c delete mode 100755 Program/libcsp/include/csp/arch/csp_clock.h delete mode 100755 Program/libcsp/include/csp/arch/csp_malloc.h delete mode 100755 Program/libcsp/include/csp/arch/csp_queue.h delete mode 100755 Program/libcsp/include/csp/arch/csp_semaphore.h delete mode 100755 Program/libcsp/include/csp/arch/csp_system.h delete mode 100755 Program/libcsp/include/csp/arch/csp_thread.h delete mode 100755 Program/libcsp/include/csp/arch/csp_time.h delete mode 100755 Program/libcsp/include/csp/arch/posix/csp_system.h delete mode 100755 Program/libcsp/include/csp/arch/posix/pthread_queue.h delete mode 100755 Program/libcsp/include/csp/crypto/csp_hmac.h delete mode 100755 Program/libcsp/include/csp/crypto/csp_sha1.h delete mode 100755 Program/libcsp/include/csp/crypto/csp_xtea.h delete mode 100755 Program/libcsp/include/csp/csp.h delete mode 100755 Program/libcsp/include/csp/csp_buffer.h delete mode 100755 Program/libcsp/include/csp/csp_cmp.h delete mode 100755 Program/libcsp/include/csp/csp_crc32.h delete mode 100755 Program/libcsp/include/csp/csp_debug.h delete mode 100755 Program/libcsp/include/csp/csp_endian.h delete mode 100755 Program/libcsp/include/csp/csp_error.h delete mode 100755 Program/libcsp/include/csp/csp_iflist.h delete mode 100755 Program/libcsp/include/csp/csp_interface.h delete mode 100755 Program/libcsp/include/csp/csp_platform.h delete mode 100755 Program/libcsp/include/csp/csp_promisc.h delete mode 100755 Program/libcsp/include/csp/csp_rtable.h delete mode 100755 Program/libcsp/include/csp/csp_sfp.h delete mode 100755 Program/libcsp/include/csp/csp_types.h delete mode 100755 Program/libcsp/include/csp/drivers/can_socketcan.h delete mode 100755 Program/libcsp/include/csp/drivers/usart.h delete mode 100755 Program/libcsp/include/csp/interfaces/csp_if_can.h delete mode 100755 Program/libcsp/include/csp/interfaces/csp_if_i2c.h delete mode 100755 Program/libcsp/include/csp/interfaces/csp_if_kiss.h delete mode 100755 Program/libcsp/include/csp/interfaces/csp_if_lo.h delete mode 100755 Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h delete mode 100755 Program/libcsp/src/arch/csp_system.c delete mode 100755 Program/libcsp/src/arch/csp_time.c delete mode 100755 Program/libcsp/src/arch/freertos/csp_clock.c delete mode 100755 Program/libcsp/src/arch/freertos/csp_malloc.c delete mode 100755 Program/libcsp/src/arch/freertos/csp_queue.c delete mode 100755 Program/libcsp/src/arch/freertos/csp_semaphore.c delete mode 100755 Program/libcsp/src/arch/freertos/csp_system.c delete mode 100755 Program/libcsp/src/arch/freertos/csp_thread.c delete mode 100755 Program/libcsp/src/arch/freertos/csp_time.c delete mode 100755 Program/libcsp/src/arch/macosx/csp_clock.c delete mode 100755 Program/libcsp/src/arch/macosx/csp_malloc.c delete mode 100755 Program/libcsp/src/arch/macosx/csp_queue.c delete mode 100755 Program/libcsp/src/arch/macosx/csp_semaphore.c delete mode 100755 Program/libcsp/src/arch/macosx/csp_system.c delete mode 100755 Program/libcsp/src/arch/macosx/csp_thread.c delete mode 100755 Program/libcsp/src/arch/macosx/csp_time.c delete mode 100755 Program/libcsp/src/arch/macosx/pthread_queue.c delete mode 100755 Program/libcsp/src/arch/posix/csp_clock.c delete mode 100755 Program/libcsp/src/arch/posix/csp_malloc.c delete mode 100755 Program/libcsp/src/arch/posix/csp_queue.c delete mode 100755 Program/libcsp/src/arch/posix/csp_semaphore.c delete mode 100755 Program/libcsp/src/arch/posix/csp_system.c delete mode 100755 Program/libcsp/src/arch/posix/csp_thread.c delete mode 100755 Program/libcsp/src/arch/posix/csp_time.c delete mode 100755 Program/libcsp/src/arch/posix/pthread_queue.c delete mode 100755 Program/libcsp/src/arch/windows/README delete mode 100755 Program/libcsp/src/arch/windows/csp_clock.c delete mode 100755 Program/libcsp/src/arch/windows/csp_malloc.c delete mode 100755 Program/libcsp/src/arch/windows/csp_queue.c delete mode 100755 Program/libcsp/src/arch/windows/csp_semaphore.c delete mode 100755 Program/libcsp/src/arch/windows/csp_system.c delete mode 100755 Program/libcsp/src/arch/windows/csp_thread.c delete mode 100755 Program/libcsp/src/arch/windows/csp_time.c delete mode 100755 Program/libcsp/src/arch/windows/windows_queue.c delete mode 100755 Program/libcsp/src/arch/windows/windows_queue.h delete mode 100755 Program/libcsp/src/bindings/python/pycsp.c delete mode 100755 Program/libcsp/src/crypto/csp_hmac.c delete mode 100755 Program/libcsp/src/crypto/csp_sha1.c delete mode 100755 Program/libcsp/src/crypto/csp_xtea.c delete mode 100755 Program/libcsp/src/csp_bridge.c delete mode 100755 Program/libcsp/src/csp_buffer.c delete mode 100755 Program/libcsp/src/csp_conn.c delete mode 100755 Program/libcsp/src/csp_conn.h delete mode 100755 Program/libcsp/src/csp_crc32.c delete mode 100755 Program/libcsp/src/csp_debug.c delete mode 100755 Program/libcsp/src/csp_dedup.c delete mode 100755 Program/libcsp/src/csp_dedup.h delete mode 100755 Program/libcsp/src/csp_endian.c delete mode 100755 Program/libcsp/src/csp_hex_dump.c delete mode 100755 Program/libcsp/src/csp_iflist.c delete mode 100755 Program/libcsp/src/csp_init.c delete mode 100755 Program/libcsp/src/csp_init.h delete mode 100755 Program/libcsp/src/csp_io.c delete mode 100755 Program/libcsp/src/csp_io.h delete mode 100755 Program/libcsp/src/csp_port.c delete mode 100755 Program/libcsp/src/csp_port.h delete mode 100755 Program/libcsp/src/csp_promisc.c delete mode 100755 Program/libcsp/src/csp_promisc.h delete mode 100755 Program/libcsp/src/csp_qfifo.c delete mode 100755 Program/libcsp/src/csp_qfifo.h delete mode 100755 Program/libcsp/src/csp_route.c delete mode 100755 Program/libcsp/src/csp_service_handler.c delete mode 100755 Program/libcsp/src/csp_services.c delete mode 100755 Program/libcsp/src/csp_sfp.c delete mode 100755 Program/libcsp/src/drivers/can/can_socketcan.c delete mode 100755 Program/libcsp/src/drivers/usart/usart_kiss.c delete mode 100755 Program/libcsp/src/drivers/usart/usart_linux.c delete mode 100755 Program/libcsp/src/drivers/usart/usart_windows.c delete mode 100755 Program/libcsp/src/interfaces/csp_if_can.c delete mode 100755 Program/libcsp/src/interfaces/csp_if_can_pbuf.c delete mode 100755 Program/libcsp/src/interfaces/csp_if_can_pbuf.h delete mode 100755 Program/libcsp/src/interfaces/csp_if_i2c.c delete mode 100755 Program/libcsp/src/interfaces/csp_if_kiss.c delete mode 100755 Program/libcsp/src/interfaces/csp_if_lo.c delete mode 100755 Program/libcsp/src/interfaces/csp_if_zmqhub.c delete mode 100755 Program/libcsp/src/rtable/csp_rtable.c delete mode 100755 Program/libcsp/src/rtable/csp_rtable_cidr.c delete mode 100755 Program/libcsp/src/rtable/csp_rtable_internal.h delete mode 100755 Program/libcsp/src/rtable/csp_rtable_static.c delete mode 100755 Program/libcsp/src/transport/csp_rdp.c delete mode 100755 Program/libcsp/src/transport/csp_transport.h delete mode 100755 Program/libcsp/src/transport/csp_udp.c delete mode 100755 Program/libcsp/utils/cfpsplit.py delete mode 100755 Program/libcsp/utils/cspsplit.py delete mode 100755 Program/libcsp/waf delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/__init__.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ar.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/asm.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/bison.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_aliases.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_config.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/dbus.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/dmd.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gxx.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/icc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/icpc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ifort.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/python.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py delete mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py delete mode 100755 Program/libcsp/wscript diff --git a/Program/libcsp/CHANGELOG b/Program/libcsp/CHANGELOG deleted file mode 100755 index bde5e6e..0000000 --- a/Program/libcsp/CHANGELOG +++ /dev/null @@ -1,163 +0,0 @@ -libcsp 1.6, 16-04-2020 ----------------------- -- Updated documentation. -- Updated Python bindings, removed Python2 support. -- Removed timeout for send (internally only) and interface tx functions - the timeout was only used on I2C interface. -- Updated example code to a single csp_server_client.c implementation. -- Renamed (scoped) clock_set_time()/clock_get_time() to csp_clock_set_time()/csp_clock_get_time() -- Changed csp_sys_reboot()/csp_sys_shutdown() to use callbacks, default POSIX impl. in csp/arch/posix/csp_system.h. -- Added support for timestamps in logs by setting CSP_DEBUG_TIMESTAMP (uses csp_clock_get_time()). -- Renamed mac to via (structs, functions, examples and documentation) -- RDP: Ensure connection is kept in CLOSE_WAIT for period of time. In some cases, the connection would switch to CLOSED immediately. -- RDP: Fixed connection leak, if a RST segment was received on a closed connecton. -- RDP: Ensure connection is closed from both userspace and protocol, before closing completely (preventing undetermined behaviour). -- RDP: Added support for fast close of a connection (skipping the CLOSE_WAIT period), but only if both ends agree on close. -- RDP: Fixed issue "Possible bug in RDP TX timeout" (#109), see issue on github for further details. -- Added Travis-CI support on Github, build: Linux, Mac and Windows. -- Changed #ifdef/ifndef to single #if in order to support forced disabling and alignment with log macro's. -- Updated thread API, documentation, aligned implementation -- Refactored all CSP interfaces. - - Accept csp_route_t, instead of csp_iface_t. - - No static members -> multiple interfaces of all types. - - Added csp_iface_t.interface_data for interface data. - - Added csp_iface_t.driver_data for driver data (unknown to interface level). - - Check for buffer overrun - - Set MTU if not already set, and it make sense on the respective interface. - - Driver Tx function is now a callback, must be set by the application (in the interface data). -- csp_packet_t (and other structs) are no longer packed (increases performance), padding is increased from 8->10 bytes for alignment. -- Refactored rtable CIDR/static implementation: - - Use same format for storing table (text). - - Added csp_route_t to hold route entry, e.g. interface and via. - - Replaced csp_rtable_find_iface()/csp_rtable_find_mac() with csp_rtable_find_route() -- Added csp_get_memfree()/csp_get_buf_free()/csp_get_uptime(), which returns an error code. -- Improved logging, check level before doing the actual call. Added support for external log macros. -- Removed unused defines/functions: csp_conn_lock, csp_conn_unlock, CSP_PROMISC -- Replaced CSP_MAX_DELAY and CSP_INFINITY with CSP_MAX_TIMEOUT (same value). -- Added csp_calloc(), csp/arch/csp_malloc.h -- Added csp_buffer_data_size(), csp/csp_buffer.h -- Updated header documentation (doxygen). -- Restructured header includes. -- api: Added const for read-only pointers. -- api: Changed a number of uint8_t pointers to void to avoid cast. - -libcsp 1.5-internal, 21-08-2018 -------------------------------- -- Internal release. -- New python bindings with examples and python3 support. -- Introduced csp_conf_t, which replaces a number of compile options. This has broken csp_init(). -- Refactored CAN interface. -- Bug fixes. - -libcsp 1.4, 07-05-2015 ----------------------- -- new: General rtable interface with support for STATIC or CIDR format -- new: CIDR (classless interdomain routing) route table format with netmasks -- new: Bridge capability -- new: Added routing table (de)serialization functions for load/save -- new: Automatic packet deduplication using CRC32 (compile time option) -- new: Autogenerated python bindings using ctypesgen -- new: Task-less operation with router invocation from external scheduler function -- api: Refactor route_if_add to csp_iflist_add -- api: Refactor route_set and friends to rtable_set -- api: Refactor csp_fifo_qos to csp_qfifo -- api: Added defined to be backwards compatible with 1.x -- interfaces: Drop packets on LOOP interface not for own address (blackhole) -- interfaces: New ZMQHUB interface (using zeroMQ over TCP) -- other: Increase stack size from 250 to 1100 for csp_can_rx_task -- other: Cleanup in csp_route.c -- other: Show incoming interface name in debug message -- other: Remove newlines from debug calls -- improvement: Reduce debug hook function complexity with valist passing -- fix: csp_sleep_ms did not work - -libcsp 1.3, 07-05-2015 ----------------------- -- new: Split long process lists into multiple packets -- new: Added posix csp_clock.h -- new: cmp clock functions (requires that you provide csp_clock.h implementation) -- new: Added SFP (Small fragmentation protocol) for larger data chunks -- fix: csp_if_fifo example -- fix: NULL char at the end of rps -- doc: Updated mtu documentation -- other: Tested with FreeRTOS 8.0 -- other: Added disable-stlib option to build only object files - -libcsp 1.2, 25-10-2013 ----------------------- -- Feature release -- New: CMP service for peek and poke of memory -- New: CMP interface statistics struct is now packed -- New: Faster O(1) buffer system with reference counting and automatic alignment -- New: Thread safe KISS driver with support for multiple interfaces -- New: CSP interface struct now holds an opaque pointer to driver handle -- New: removed TXBUF from KISS driver entirely to minimize stack usage, added TX lock instead -- New: Pre-calculated CRC table .romem or PROGMEM on __avr__ -- New: Added buffer overflow protection to KISS interface -- New: Allow posting null pointers on conn RX queues -- New: Lower memory usage on AVR8 -- New: csp_route_save and csp_route_load functions -- New: option --disable-verbose to disable filenames and linenumber on debug -- Protocol: KISS uses csp_crc32 instead of it own embedded crc32 -- Improvement: Use buffer clone function to copy promisc packets -- Bugfix: Fix pointer size (32/16bit) in cmp_peek/poke -- Bugfix: Issue with double free in KISS fixed -- Bugfix: Change rdp_send timeout from packet to connection timeout to make sending task block longer -- Bugfix: Fix conn pool leak when using security check and discarding new packets -- Bugfix: Add packet too short check for CRC32 -- Bugfix: Accept CRC32 responses from nodes without CRC support -- Bugfix: Ensure csp_ping works for packets > 256 bytes -- Bugfix: Cleanup printf inside ISR functions -- Bugfix: Do not add forwarded packets to promisc queue twice -- Bugfix: Fix return value bug of csp_buffer_get when out of buffers -- Bugfix: Always post null pointer with lowest priority, not highest -- Bugfix: Add check on debug level before calling do_csp_debug, fixes #35 -- Other: Export csp/arch include files -- Other: Remove the use of bool type from csp_debug -- Other: Moved csp debug functions to csp_debug.h instead of csp.h -- Other: Ensure assignment of id happens using the uint32_t .ext value of the union, quenches warning - -libcsp 1.1, 24-08-2012 ----------------------- -- Feature release -- Defacto stable since Feb 2012 -- New: I2C interface -- New: KISS interface -- New: USART drivers for Linux, Mac and Windows -- New: Windows/MinGW support -- New: MacOSX support -- New: Interface register function -- New: Interface search function -- New: CMP service for remote route updating -- New: CMP service for interface statistics -- Improvement: Better QoS support -- Improvement: Send RDP control messages with high priority -- Improvement: WAF distcheck now works -- Improvement: Automatic endian discovery -- Improvement: Accept packets with CRC32 checksum if compiled without CRC32 support -- Improvement: Do not wake the router task if RDP is not enabled -- Improvement: Save 102 bytes of RAM by packing route entries -- Cleanup: Simplify CAN configuration -- Cleanup: Move architecture specific code to src/arch -- Bugfix: CSP_MEMFREE gives wrong answer on freertos AVR due to truncation -- Bugfix: Fixed wrong 64-bit size_t in csp_service_handler -- Bugfix: Fixed problem in csp_if_kiss when out of buffers -- Bigfix: Handle bus-off CAN IRQ for AT90CAN128 - -libcsp 1.0.1, 30-10-2011 ------------------------- -- Hotfix release -- Bugfix: missing extern in csp_if_lo.h - -libcsp 1.0, 24-10-2011 ----------------------- -- First official release -- New: CSP 32-bit header 1.0 -- Features: Network Router with promiscous mode, broadcast and QoS -- Features: Connection-oriented transport protocol w. flow-control -- Features: Connection-less "UDP" like transport -- Features: Encryption, Authentication and message check -- Features: Loopback interface -- Features: Python Bindings -- Features: CAN interface w. drivers for several chips -- Features: CSP-services (ping, reboot, uptime, memfree, buffree, ident) - diff --git a/Program/libcsp/CI.rst b/Program/libcsp/CI.rst deleted file mode 100755 index ce27736..0000000 --- a/Program/libcsp/CI.rst +++ /dev/null @@ -1,6 +0,0 @@ -Continous Integration -===================== - -libcsp uses Travis-CI App for continous integration: https://github.com/marketplace/travis-ci. - -libcsp on Travis: https://travis-ci.com/libcsp/libcsp/branches diff --git a/Program/libcsp/COPYING b/Program/libcsp/COPYING deleted file mode 100755 index 54c619a..0000000 --- a/Program/libcsp/COPYING +++ /dev/null @@ -1,503 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - diff --git a/Program/libcsp/INSTALL.rst b/Program/libcsp/INSTALL.rst deleted file mode 100755 index 35ed8ab..0000000 --- a/Program/libcsp/INSTALL.rst +++ /dev/null @@ -1,29 +0,0 @@ -How to install LibCSP -===================== - -CSP uses the `waf` build system (http://code.google.com/p/waf/). In order to -compile CSP, you first need to configure the toolchain, what operating system -to compile for, the location of required libraries and whether to enable -certain optional features. - -To configure CSP to build with the AVR32 toolchain for FreeRTOS and output -the compiled libcsp.a and header files to the install directory, issue: - -.. code-block:: bash - - ./waf configure --toolchain=avr32- --with-os=freertos --prefix=install - -When compiling for FreeRTOS, the path to the FreeRTOS header files must be -specified with `--includes=PATH`. - -A number of optional features can be enabled by from the configure script. -Support for XTEA encryption can e.g. be enabled with `--enable-xtea`. Run -`./waf configure --help` to list the available configure options. - -The CAN driver (based on socketcan) can be enabled by appending the configure option `--enable-can-socketcan`. - -To build and copy the library to the location specified with --prefix, use: - -.. code-block:: bash - - ./waf build install diff --git a/Program/libcsp/README.rst b/Program/libcsp/README.rst deleted file mode 100755 index 76a27bf..0000000 --- a/Program/libcsp/README.rst +++ /dev/null @@ -1,41 +0,0 @@ -The Cubesat Space Protocol -========================== - -Cubesat Space Protocol (CSP) is a small protocol stack written in C. CSP is designed to ease communication between distributed embedded systems in smaller networks, such as Cubesats. The design follows the TCP/IP model and includes a transport protocol, a routing protocol and several MAC-layer interfaces. The core of `libcsp` includes a router, a connection oriented socket API and message/connection pools. - -The protocol is based on a 32-bit header containing both transport and network-layer information. Its implementation is designed for, but not limited to, embedded systems such as the 8-bit AVR microprocessor and the 32-bit ARM and AVR from Atmel. The implementation is written in GNU C and is currently ported to run on FreeRTOS, Linux (POSIX), MacOS and Windows. The primiary platforms being used are FreeRTOS and Linux. - -The idea is to give sub-system developers of cubesats the same features of a TCP/IP stack, but without adding the huge overhead of the IP header. The small footprint and simple implementation allows a small 8-bit system to be fully connected on the network. This allows all subsystems to provide their services on the same network level, without any master node required. Using a service oriented architecture has several advantages compared to the traditional mater/slave topology used on many cubesats. - - * Standardised network protocol: All subsystems can communicate with eachother - * Service loose coupling: Services maintain a relationship that minimizes dependencies between subsystems - * Service abstraction: Beyond descriptions in the service contract, services hide logic from the outside world - * Service reusability: Logic is divided into services with the intention of promoting reuse. - * Service autonomy: Services have control over the logic they encapsulate. - * Service Redundancy: Easily add redundant services to the bus - * Reduces single point of failure: The complexity is moved from a single master node to several well defined services on the network - -The implementation of `libcsp` is written with simplicity in mind, but it's compile time configuration allows it to have some rather advanced features as well: - -Features --------- - - * Thread safe Socket API - * Router task with Quality of Services - * Connection-oriented operation (RFC 908 and 1151). - * Connection-less operation (similar to UDP) - * ICMP-like requests such as ping and buffer status. - * Loopback interface - * Very Small Footprint in regards to code and memory required - * Zero-copy buffer and queue system - * Modular network interface system - * OS abstraction, currently ported to: FreeRTOS, Linux (POSIX), MacOS and Windows - * Broadcast traffic - * Promiscuous mode - * Encrypted packets with XTEA in CTR mode - * Truncated HMAC-SHA1 Authentication (RFC 2104) - -LGPL Software license ---------------------- -The source code is available under an LGPL 2.1 license. See COPYING for the license text. - diff --git a/Program/libcsp/build/.lock-waf_linux_build b/Program/libcsp/build/.lock-waf_linux_build deleted file mode 100755 index b06201e..0000000 --- a/Program/libcsp/build/.lock-waf_linux_build +++ /dev/null @@ -1,10 +0,0 @@ -argv = ['waf', 'configure', '--with-os=posix', '--enable-can-socketcan', '--enable-rdp', '--enable-hmac', '--enable-xtea', '--with-loglevel=debug', '--enable-debug-timestamp', '--enable-python3-bindings', '--with-driver-usart=linux', '--enable-if-zmqhub', '--enable-examples'] -config_cmd = 'configure' -environ = {'CLUTTER_IM_MODULE': 'xim', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'ANDROID_HOME': '/media/evan/NewVolume/Android/Sdk', 'XDG_MENU_PREFIX': 'gnome-', 'LANG': 'en_CA.UTF-8', 'MANAGERPID': '2687', 'DISPLAY': ':0', 'INVOCATION_ID': '40736d50dbe74043b723449b3313ccde', 'GNOME_SHELL_SESSION_MODE': 'ubuntu', 'GTK2_MODULES': 'overlay-scrollbar', 'COLORTERM': 'truecolor', 'GEM_HOME': '/home/evan/.gem', 'ZEITGEIST_DATA_PATH': '/home/evan/.local/share/zeitgeist', 'USERNAME': 'evan', 'JAVA_HOME': '/home/evan/jdk1.8.0_181', 'XDG_VTNR': '2', 'SSH_AUTH_SOCK': '/run/user/1000/keyring/ssh', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path', 'S_COLORS': 'auto', 'XDG_SESSION_ID': '2', 'USER': 'evan', 'DESKTOP_SESSION': 'ubuntu', 'RBENV_SHELL': 'bash', 'QT4_IM_MODULE': 'xim', 'GOPATH': '/home/evan/Desktop/GO', 'TEXTDOMAINDIR': '/usr/share/locale/', 'GNOME_TERMINAL_SCREEN': '/org/gnome/Terminal/screen/00188ceb_b3cc_4ac6_9aa1_7e7bd14bf55b', 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu.default.path', 'PWD': '/media/evan/NewVolume/ground_station/libcsp', 'HOME': '/home/evan', 'JOURNAL_STREAM': '9:39688', 'ANDROID_NDK_HOME': '/home/evan/ndk-web3/android-ndk-r17b', 'TEXTDOMAIN': 'im-config', 'SSH_AGENT_PID': '3322', 'QT_ACCESSIBILITY': '1', 'DPDK_BUILD': '/usr/src/dpdk-stable-17.05.2/x86_64-native-linuxapp-gcc', 'LIBVIRT_DEFAULT_URI': 'qemu:///system', 'XDG_SESSION_TYPE': 'x11', 'XDG_DATA_DIRS': '/home/evan/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share/:/usr/share/ubuntu:/home/evan/.local/share/flatpak/exports/share/:/var/lib/flatpak/exports/share/:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop:/var/lib/snapd/desktop', 'XDG_SESSION_DESKTOP': 'ubuntu', 'GEM_PATH': '/home/evan/.gem', 'DBUS_STARTER_ADDRESS': 'unix:path=/run/user/1000/bus,guid=5366896dc62962572a54bde85fe78121', 'DPDK_DIR': '/usr/src/dpdk-stable-17.05.2', 'GTK_MODULES': 'gail:atk-bridge', 'WINDOWPATH': '2', 'TERM': 'vt100', 'VTE_VERSION': '5202', 'SHELL': '/bin/bash', 'QT_IM_MODULE': 'ibus', 'XMODIFIERS': '@im=ibus', 'IM_CONFIG_PHASE': '2', 'DBUS_STARTER_BUS_TYPE': 'session', 'XDG_CURRENT_DESKTOP': 'ubuntu:GNOME', 'GPG_AGENT_INFO': '/run/user/1000/gnupg/S.gpg-agent:0:1', 'GNOME_TERMINAL_SERVICE': ':1.87', 'SHLVL': '1', 'XDG_SEAT': 'seat0', 'LANGUAGE': 'en_CA:en', 'DPDK_TARGET': 'x86_64-native-linuxapp-gcc', 'GDMSESSION': 'ubuntu', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'LOGNAME': 'evan', 'DBUS_SESSION_BUS_ADDRESS': 'unix:path=/run/user/1000/bus,guid=5366896dc62962572a54bde85fe78121', 'XDG_RUNTIME_DIR': '/run/user/1000', 'XAUTHORITY': '/run/user/1000/gdm/Xauthority', 'GOBIN': '/home/evan/Desktop/GO/bin', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/etc/xdg', 'PATH': '/home/evan/.rbenv/shims:/home/evan/.rbenv/shims:/home/evan/.rbenv/bin:/home/evan/.rbenv/shims:/home/evan/.rbenv/shims:/home/evan/.rbenv/bin:/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin:/home/evan/.npm-global/bin:/home/evan/.cargo/bin:/home/evan/bin:/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/evan/VSCode-linux-x64/bin:/home/evan/node-v8.7.0-linux-x64/bin:/home/evan/Python-3.6.4/python:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/tools/bin:/media/evan/NewVolume/Android/Sdk/platform-tools:/media/evan/NewVolume/Android/Sdk/emulator:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/platform-tools:/home/evan/BlockChain/go-ethereum/build/bin:/home/evan/Desktop/GO/bin:/home/evan/AllGethTools:/home/evan/.gem/gems/ceedling-0.28.3/bin:/home/evan/VSCode-linux-x64/bin:/home/evan/node-v8.7.0-linux-x64/bin:/home/evan/Python-3.6.4/python:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/tools/bin:/media/evan/NewVolume/Android/Sdk/platform-tools:/media/evan/NewVolume/Android/Sdk/emulator:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/platform-tools:/home/evan/BlockChain/go-ethereum/build/bin:/home/evan/Desktop/GO/bin:/home/evan/AllGethTools:/home/evan/.gem/gems/ceedling-0.28.3/bin', 'SESSION_MANAGER': 'local/evan-Aspire-E5-575G:@/tmp/.ICE-unix/3192,unix/evan-Aspire-E5-575G:/tmp/.ICE-unix/3192', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'GTK_IM_MODULE': 'ibus', '_': '/usr/bin/python3', 'OLDPWD': '/media/evan/NewVolume/ground_station'} -files = ['/media/evan/NewVolume/ground_station/libcsp/wscript'] -hash = b'\xbb\xfe\xcd\xa3\x17\xbd(\x1e\xcaR\xa8\x08z\x8c\x90\xc0' -launch_dir = '/media/evan/NewVolume/ground_station/libcsp' -options = {'colors': 'auto', 'jobs': 4, 'keep': 0, 'verbose': 0, 'zones': '', 'profile': 0, 'pdb': 0, 'whelp': 0, 'out': '', 'top': '', 'no_lock_in_run': '', 'no_lock_in_out': '', 'no_lock_in_top': '', 'prefix': '/usr/local', 'bindir': None, 'libdir': None, 'progress_bar': 0, 'targets': '', 'files': '', 'destdir': '', 'force': False, 'distcheck_args': None, 'check_c_compiler': None, 'toolchain': None, 'includes': '', 'install_csp': None, 'disable_output': None, 'disable_stlib': None, 'enable_shlib': None, 'enable_rdp': True, 'enable_rdp_fast_close': None, 'enable_qos': None, 'enable_promisc': None, 'enable_crc32': None, 'enable_hmac': True, 'enable_xtea': True, 'enable_python3_bindings': True, 'enable_examples': True, 'enable_dedup': None, 'enable_external_debug': None, 'enable_debug_timestamp': True, 'enable_if_zmqhub': True, 'enable_can_socketcan': True, 'with_driver_usart': 'linux', 'with_os': 'posix', 'with_loglevel': 'debug', 'with_rtable': 'static'} -out_dir = '/media/evan/NewVolume/ground_station/libcsp/build' -run_dir = '/media/evan/NewVolume/ground_station/libcsp' -top_dir = '/media/evan/NewVolume/ground_station/libcsp' diff --git a/Program/libcsp/build/.wafpickle-linux-50727408-20 b/Program/libcsp/build/.wafpickle-linux-50727408-20 deleted file mode 100755 index b9aef2db67751cec86c6033e0f3796cda02e9d2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30138 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 ['/usr/bin/gcc'] -['/usr/bin/gcc', '-dM', '-E', '-'] -out: #define __SSP_STRONG__ 3 -#define __DBL_MIN_EXP__ (-1021) -#define __FLT32X_MAX_EXP__ 1024 -#define __UINT_LEAST16_MAX__ 0xffff -#define __ATOMIC_ACQUIRE 2 -#define __FLT128_MAX_10_EXP__ 4932 -#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F -#define __GCC_IEC_559_COMPLEX 2 -#define __UINT_LEAST8_TYPE__ unsigned char -#define __SIZEOF_FLOAT80__ 16 -#define __INTMAX_C(c) c ## L -#define __CHAR_BIT__ 8 -#define __UINT8_MAX__ 0xff -#define __WINT_MAX__ 0xffffffffU -#define __FLT32_MIN_EXP__ (-125) -#define __ORDER_LITTLE_ENDIAN__ 1234 -#define __SIZE_MAX__ 0xffffffffffffffffUL -#define __WCHAR_MAX__ 0x7fffffff -#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 -#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 -#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 -#define __DBL_DENORM_MIN__ ((double)4.94065645841246544176568792868221372e-324L) -#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 -#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 -#define __GCC_IEC_559 2 -#define __FLT32X_DECIMAL_DIG__ 17 -#define __FLT_EVAL_METHOD__ 0 -#define __unix__ 1 -#define __FLT64_DECIMAL_DIG__ 17 -#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 -#define __x86_64 1 -#define __UINT_FAST64_MAX__ 0xffffffffffffffffUL -#define __SIG_ATOMIC_TYPE__ int -#define __DBL_MIN_10_EXP__ (-307) -#define __FINITE_MATH_ONLY__ 0 -#define __GNUC_PATCHLEVEL__ 0 -#define __FLT32_HAS_DENORM__ 1 -#define __UINT_FAST8_MAX__ 0xff -#define __has_include(STR) __has_include__(STR) -#define __DEC64_MAX_EXP__ 385 -#define __INT8_C(c) c -#define __INT_LEAST8_WIDTH__ 8 -#define __UINT_LEAST64_MAX__ 0xffffffffffffffffUL -#define __SHRT_MAX__ 0x7fff -#define __LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L -#define __FLT64X_MAX_10_EXP__ 4932 -#define __UINT_LEAST8_MAX__ 0xff -#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 -#define __FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128 -#define __UINTMAX_TYPE__ long unsigned int -#define __linux 1 -#define __DEC32_EPSILON__ 1E-6DF -#define __FLT_EVAL_METHOD_TS_18661_3__ 0 -#define __unix 1 -#define __UINT32_MAX__ 0xffffffffU -#define __LDBL_MAX_EXP__ 16384 -#define __FLT128_MIN_EXP__ (-16381) -#define __WINT_MIN__ 0U -#define __linux__ 1 -#define __FLT128_MIN_10_EXP__ (-4931) -#define __INT_LEAST16_WIDTH__ 16 -#define __SCHAR_MAX__ 0x7f -#define __FLT128_MANT_DIG__ 113 -#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) -#define __INT64_C(c) c ## L -#define __DBL_DIG__ 15 -#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 -#define __FLT64X_MANT_DIG__ 64 -#define __SIZEOF_INT__ 4 -#define __SIZEOF_POINTER__ 8 -#define __USER_LABEL_PREFIX__ -#define __FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x -#define __STDC_HOSTED__ 1 -#define __LDBL_HAS_INFINITY__ 1 -#define __FLT32_DIG__ 6 -#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F -#define __SHRT_WIDTH__ 16 -#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L -#define __STDC_UTF_16__ 1 -#define __DEC32_MAX__ 9.999999E96DF -#define __FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x -#define __FLT32X_HAS_INFINITY__ 1 -#define __INT32_MAX__ 0x7fffffff -#define __INT_WIDTH__ 32 -#define __SIZEOF_LONG__ 8 -#define __STDC_IEC_559__ 1 -#define __STDC_ISO_10646__ 201706L -#define __UINT16_C(c) c -#define __PTRDIFF_WIDTH__ 64 -#define __DECIMAL_DIG__ 21 -#define __FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64 -#define __gnu_linux__ 1 -#define __INTMAX_WIDTH__ 64 -#define __has_include_next(STR) __has_include_next__(STR) -#define __FLT64X_MIN_10_EXP__ (-4931) -#define __LDBL_HAS_QUIET_NAN__ 1 -#define __FLT64_MANT_DIG__ 53 -#define __GNUC__ 7 -#define __pie__ 2 -#define __MMX__ 1 -#define __FLT_HAS_DENORM__ 1 -#define __SIZEOF_LONG_DOUBLE__ 16 -#define __BIGGEST_ALIGNMENT__ 16 -#define __FLT64_MAX_10_EXP__ 308 -#define __DBL_MAX__ ((double)1.79769313486231570814527423731704357e+308L) -#define __INT_FAST32_MAX__ 0x7fffffffffffffffL -#define __DBL_HAS_INFINITY__ 1 -#define __DEC32_MIN_EXP__ (-94) -#define __INTPTR_WIDTH__ 64 -#define __FLT32X_HAS_DENORM__ 1 -#define __INT_FAST16_TYPE__ long int -#define __LDBL_HAS_DENORM__ 1 -#define __FLT128_HAS_INFINITY__ 1 -#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL -#define __INT_LEAST32_MAX__ 0x7fffffff -#define __DEC32_MIN__ 1E-95DF -#define __DBL_MAX_EXP__ 1024 -#define __WCHAR_WIDTH__ 32 -#define __FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32 -#define __DEC128_EPSILON__ 1E-33DL -#define __SSE2_MATH__ 1 -#define __ATOMIC_HLE_RELEASE 131072 -#define __PTRDIFF_MAX__ 0x7fffffffffffffffL -#define __amd64 1 -#define __STDC_NO_THREADS__ 1 -#define __ATOMIC_HLE_ACQUIRE 65536 -#define __FLT32_HAS_QUIET_NAN__ 1 -#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL -#define __SIZEOF_SIZE_T__ 8 -#define __FLT64X_MIN_EXP__ (-16381) -#define __SIZEOF_WINT_T__ 4 -#define __LONG_LONG_WIDTH__ 64 -#define __FLT32_MAX_EXP__ 128 -#define __GCC_HAVE_DWARF2_CFI_ASM 1 -#define __GXX_ABI_VERSION 1011 -#define __FLT_MIN_EXP__ (-125) -#define __FLT64X_HAS_QUIET_NAN__ 1 -#define __INT_FAST64_TYPE__ long int -#define __FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64 -#define __DBL_MIN__ ((double)2.22507385850720138309023271733240406e-308L) -#define __PIE__ 2 -#define __LP64__ 1 -#define __FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x -#define __DECIMAL_BID_FORMAT__ 1 -#define __FLT64_MIN_EXP__ (-1021) -#define __FLT64_MIN_10_EXP__ (-307) -#define __FLT64X_DECIMAL_DIG__ 21 -#define __DEC128_MIN__ 1E-6143DL -#define __REGISTER_PREFIX__ -#define __UINT16_MAX__ 0xffff -#define __DBL_HAS_DENORM__ 1 -#define __FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32 -#define __UINT8_TYPE__ unsigned char -#define __NO_INLINE__ 1 -#define __FLT_MANT_DIG__ 24 -#define __LDBL_DECIMAL_DIG__ 21 -#define __VERSION__ "7.5.0" -#define __UINT64_C(c) c ## UL -#define _STDC_PREDEF_H 1 -#define __GCC_ATOMIC_INT_LOCK_FREE 2 -#define __FLT128_MAX_EXP__ 16384 -#define __FLT32_MANT_DIG__ 24 -#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ -#define __STDC_IEC_559_COMPLEX__ 1 -#define __FLT128_HAS_DENORM__ 1 -#define __FLT128_DIG__ 33 -#define __SCHAR_WIDTH__ 8 -#define __INT32_C(c) c -#define __DEC64_EPSILON__ 1E-15DD -#define __ORDER_PDP_ENDIAN__ 3412 -#define __DEC128_MIN_EXP__ (-6142) -#define __FLT32_MAX_10_EXP__ 38 -#define __INT_FAST32_TYPE__ long int -#define __UINT_LEAST16_TYPE__ short unsigned int -#define __FLT64X_HAS_INFINITY__ 1 -#define unix 1 -#define __INT16_MAX__ 0x7fff -#define __SIZE_TYPE__ long unsigned int -#define __UINT64_MAX__ 0xffffffffffffffffUL -#define __FLT64X_DIG__ 18 -#define __INT8_TYPE__ signed char -#define __ELF__ 1 -#define __GCC_ASM_FLAG_OUTPUTS__ 1 -#define __FLT_RADIX__ 2 -#define __INT_LEAST16_TYPE__ short int -#define __LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L -#define __UINTMAX_C(c) c ## UL -#define __SSE_MATH__ 1 -#define __k8 1 -#define __SIG_ATOMIC_MAX__ 0x7fffffff -#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 -#define __SIZEOF_PTRDIFF_T__ 8 -#define __FLT32X_MANT_DIG__ 53 -#define __x86_64__ 1 -#define __FLT32X_MIN_EXP__ (-1021) -#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF -#define __INT_FAST16_MAX__ 0x7fffffffffffffffL -#define __FLT64_DIG__ 15 -#define __UINT_FAST32_MAX__ 0xffffffffffffffffUL -#define __UINT_LEAST64_TYPE__ long unsigned int -#define __FLT_HAS_QUIET_NAN__ 1 -#define __FLT_MAX_10_EXP__ 38 -#define __LONG_MAX__ 0x7fffffffffffffffL -#define __FLT64X_HAS_DENORM__ 1 -#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL -#define __FLT_HAS_INFINITY__ 1 -#define __UINT_FAST16_TYPE__ long unsigned int -#define __DEC64_MAX__ 9.999999999999999E384DD -#define __INT_FAST32_WIDTH__ 64 -#define __CHAR16_TYPE__ short unsigned int -#define __PRAGMA_REDEFINE_EXTNAME 1 -#define __SIZE_WIDTH__ 64 -#define __SEG_FS 1 -#define __INT_LEAST16_MAX__ 0x7fff -#define __DEC64_MANT_DIG__ 16 -#define __INT64_MAX__ 0x7fffffffffffffffL -#define __UINT_LEAST32_MAX__ 0xffffffffU -#define __SEG_GS 1 -#define __FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32 -#define __GCC_ATOMIC_LONG_LOCK_FREE 2 -#define __SIG_ATOMIC_WIDTH__ 32 -#define __INT_LEAST64_TYPE__ long int -#define __INT16_TYPE__ short int -#define __INT_LEAST8_TYPE__ signed char -#define __STDC_VERSION__ 201112L -#define __DEC32_MAX_EXP__ 97 -#define __INT_FAST8_MAX__ 0x7f -#define __FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128 -#define __INTPTR_MAX__ 0x7fffffffffffffffL -#define linux 1 -#define __FLT64_HAS_QUIET_NAN__ 1 -#define __FLT32_MIN_10_EXP__ (-37) -#define __SSE2__ 1 -#define __FLT32X_DIG__ 15 -#define __LDBL_MANT_DIG__ 64 -#define __DBL_HAS_QUIET_NAN__ 1 -#define __FLT64_HAS_INFINITY__ 1 -#define __FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x -#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) -#define __code_model_small__ 1 -#define __k8__ 1 -#define __INTPTR_TYPE__ long int -#define __UINT16_TYPE__ short unsigned int -#define __WCHAR_TYPE__ int -#define __SIZEOF_FLOAT__ 4 -#define __pic__ 2 -#define __UINTPTR_MAX__ 0xffffffffffffffffUL -#define __INT_FAST64_WIDTH__ 64 -#define __DEC64_MIN_EXP__ (-382) -#define __FLT32_DECIMAL_DIG__ 9 -#define __INT_FAST64_MAX__ 0x7fffffffffffffffL -#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 -#define __FLT_DIG__ 6 -#define __FLT32_HAS_INFINITY__ 1 -#define __FLT64X_MAX_EXP__ 16384 -#define __UINT_FAST64_TYPE__ long unsigned int -#define __INT_MAX__ 0x7fffffff -#define __amd64__ 1 -#define __INT64_TYPE__ long int -#define __FLT_MAX_EXP__ 128 -#define __ORDER_BIG_ENDIAN__ 4321 -#define __DBL_MANT_DIG__ 53 -#define __SIZEOF_FLOAT128__ 16 -#define __INT_LEAST64_MAX__ 0x7fffffffffffffffL -#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 -#define __DEC64_MIN__ 1E-383DD -#define __WINT_TYPE__ unsigned int -#define __UINT_LEAST32_TYPE__ unsigned int -#define __SIZEOF_SHORT__ 2 -#define __SSE__ 1 -#define __LDBL_MIN_EXP__ (-16381) -#define __FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64 -#define __WINT_WIDTH__ 32 -#define __INT_LEAST8_MAX__ 0x7f -#define __FLT32X_MAX_10_EXP__ 308 -#define __SIZEOF_INT128__ 16 -#define __LDBL_MAX_10_EXP__ 4932 -#define __ATOMIC_RELAXED 0 -#define __DBL_EPSILON__ ((double)2.22044604925031308084726333618164062e-16L) -#define __FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128 -#define _LP64 1 -#define __UINT8_C(c) c -#define __FLT64_MAX_EXP__ 1024 -#define __INT_LEAST32_TYPE__ int -#define __SIZEOF_WCHAR_T__ 4 -#define __UINT64_TYPE__ long unsigned int -#define __FLT128_HAS_QUIET_NAN__ 1 -#define __INT_FAST8_TYPE__ signed char -#define __FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x -#define __GNUC_STDC_INLINE__ 1 -#define __FLT64_HAS_DENORM__ 1 -#define __FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32 -#define __DBL_DECIMAL_DIG__ 17 -#define __STDC_UTF_32__ 1 -#define __INT_FAST8_WIDTH__ 8 -#define __FXSR__ 1 -#define __DEC_EVAL_METHOD__ 2 -#define __FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x -#define __UINT32_C(c) c ## U -#define __INTMAX_MAX__ 0x7fffffffffffffffL -#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ -#define __FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F -#define __INT8_MAX__ 0x7f -#define __LONG_WIDTH__ 64 -#define __PIC__ 2 -#define __UINT_FAST32_TYPE__ long unsigned int -#define __CHAR32_TYPE__ unsigned int -#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F -#define __INT32_TYPE__ int -#define __SIZEOF_DOUBLE__ 8 -#define __FLT_MIN_10_EXP__ (-37) -#define __FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64 -#define __INT_LEAST32_WIDTH__ 32 -#define __INTMAX_TYPE__ long int -#define __DEC128_MAX_EXP__ 6145 -#define __FLT32X_HAS_QUIET_NAN__ 1 -#define __ATOMIC_CONSUME 1 -#define __GNUC_MINOR__ 5 -#define __INT_FAST16_WIDTH__ 64 -#define __UINTMAX_MAX__ 0xffffffffffffffffUL -#define __DEC32_MANT_DIG__ 7 -#define __FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x -#define __DBL_MAX_10_EXP__ 308 -#define __LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L -#define __INT16_C(c) c -#define __STDC__ 1 -#define __PTRDIFF_TYPE__ long int -#define __ATOMIC_SEQ_CST 5 -#define __UINT32_TYPE__ unsigned int -#define __FLT32X_MIN_10_EXP__ (-307) -#define __UINTPTR_TYPE__ long unsigned int -#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD -#define __DEC128_MANT_DIG__ 34 -#define __LDBL_MIN_10_EXP__ (-4931) -#define __FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128 -#define __SIZEOF_LONG_LONG__ 8 -#define __FLT128_DECIMAL_DIG__ 36 -#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 -#define __FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x -#define __LDBL_DIG__ 18 -#define __FLT_DECIMAL_DIG__ 9 -#define __UINT_FAST16_MAX__ 0xffffffffffffffffUL -#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 -#define __INT_LEAST64_WIDTH__ 64 -#define __UINT_FAST8_TYPE__ unsigned char -#define __ATOMIC_ACQ_REL 4 -#define __ATOMIC_RELEASE 3 - -find program=['ar'] paths=['/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/home/evan/.npm-global/bin', '/home/evan/.cargo/bin', '/home/evan/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games', '/snap/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin'] var='AR' -> ['/usr/bin/ar'] -/usr/bin/gcc ----------------------------------------- -Checking for program 'pkg-config' -/usr/bin/pkg-config -find program=['pkg-config'] paths=['/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/home/evan/.npm-global/bin', '/home/evan/.cargo/bin', '/home/evan/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games', '/snap/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin'] var='PKGCONFIG' -> ['/usr/bin/pkg-config'] ----------------------------------------- -Checking for 'libsocketcan' -['/usr/bin/pkg-config', '--cflags', '--libs', 'libsocketcan'] -out: -lsocketcan - -yes ----------------------------------------- -Checking for 'libzmq' -['/usr/bin/pkg-config', '--cflags', '--libs', 'libzmq'] -out: -I/usr/local/include -L/usr/local/lib -lzmq - -yes ----------------------------------------- -Checking for 'python3' -['/usr/bin/pkg-config', '--cflags', '--libs', 'python3'] -out: -I/usr/include/python3.6m -I/usr/include/x86_64-linux-gnu/python3.6m -lpython3.6m - -yes ----------------------------------------- -Checking for endianness -==> - -short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; -short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; -int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; -} -short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; -short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; -int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; -} -extern int foo; - -<== -[1/2] Compiling build/.conf_check_7497c5620f03feadb3d79f4705d343d2/test.c - -['/usr/bin/gcc', '-std=gnu99', '-g', '-Os', '-Wall', '-Wextra', '-Wshadow', '-Wcast-align', '-Wwrite-strings', '-Wno-unused-parameter', '-DGIT_REV="v1.6-9-gbf96d6f"', '-DCSP_POSIX=1', '-DCSP_HAVE_LIBSOCKETCAN=1', '-DCSP_HAVE_LIBZMQ=1', '-DHAVE_PYTHON3=1', '-DCSP_DEBUG=1', '-DCSP_DEBUG_TIMESTAMP=1', '-DCSP_USE_RDP=1', '-DCSP_USE_RDP_FAST_CLOSE=0', '-DCSP_USE_CRC32=0', '-DCSP_USE_HMAC=1', '-DCSP_USE_XTEA=1', '-DCSP_USE_PROMISC=0', '-DCSP_USE_QOS=0', '-DCSP_USE_DEDUP=0', '-DCSP_USE_EXTERNAL_DEBUG=0', '-DCSP_LOG_LEVEL_DEBUG=1', '-DCSP_LOG_LEVEL_INFO=1', '-DCSP_LOG_LEVEL_WARN=1', '-DCSP_LOG_LEVEL_ERROR=1', '../test.c', '-c', '-o/media/evan/NewVolume/ground_station/libcsp/build/.conf_check_7497c5620f03feadb3d79f4705d343d2/testbuild/test.c.1.o'] -[2/2] Processing build/.conf_check_7497c5620f03feadb3d79f4705d343d2/testbuild/test.c.1.o - -little diff --git a/Program/libcsp/build/csp_arch b/Program/libcsp/build/csp_arch deleted file mode 100755 index 481f40a02897e518549d2ca8dea4e8abe1c903e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93424 zcmeFad3;pW{XTy0%p{r2nw_v_0tqApvapFDOIT!3P*y=f1CjvI5MnX`R0K3ajev?< z75OM?wN|ZKw<6k#1rfK_s%@#ZYOB?WXp1{;MN+3&gcPS#GGaOk&JK`PRlOQ zJ*1;qt{b*IoH!Y8xP#J>ZV#n4EZ0h%Zjuf=n)A>&rL|nc2#JF6nAf>eM1&g>kL5ni z4B>c1yH-4AkMWl3cuRFW%T3eyw_J-Kx$&H(!xP;J2;*V7wB<4FACYSM|8k;;N4mNo z{-Rwg-gLxcK7Z(urVVH4^g1h-dvtkNu1?k{tE)YC*pRZi>Vb8&_06jWt{OgU;IJX3 zP0LFM32)-lcG79HB_+b>qLA<`$kZ{scinF@SCyQ%_JjR%XPkfQRnM2cxwjYNS|_|e z_;?qIWE{nMKERHq_jRTRM(8Lw3p>HTwG*7?PV8^)ME^F@JX$_4>cswmPV`rIf|J{c z{ozjRM|WcX`%d&Nos`41o!EcViG30B6T+EzTmr?>%BOcH_7D3LfIfsX z@z~f2{{WTvWGw(fL(PHIYc|vKm84OSFWv8X`*@ zYZg{B!E!?jRg0F_S69{6*G6KRWzCVARme+Iq;dI$MpMnQDqyTwSl3(=Ghw8Kkw_!c zl4N2bDsl%rNnzzeTM9L+AP|`Otd^jvs+z{e`sGz%urN})yk3GEmNzA4iwt9l3342R zh*q{^^uRb0&$!B-MCpJeWF*%FIWqg_HZEUSy=b8=I~IM^%A)g|YA=eXAt6WP!z!^@ zA{|OZ<*T_~GF88@etA<}O-)0LsFhfC4N_Z*ByE&pbzvomnqI^@9%i5h7d2dn_S4W< zTOV0mwP-2It~t^KjbxjOs>KUy>x{;lbC)lV7>gFxAqNOvVT-X$DVr`t!(4{2MXMH8 zEv~I!SVz)L7uGMrrKz@l@p6PQZQW3pEv&6K7B|+^7?Y+<9yh*fQ0bu3p)vp9(!nOl#Gr5}IUGOJieoxjq>KV$D>mlXiHN|j4a>ANdhA3NxScr^e%0H|} zp$*||?pB*>z$S`*%)^AuGPn#Mi?gXK!`;T`2&b-5WUP{q0m>@AvqStj+7`h^R&A}H zD?XpLk4XF^Bd0@rM=ZXzezewoX?=)d7z^||(bB)tTj|}?LgKOXmc0LTrMK48%GxmA zvFVwA>xkO)TuWKUL7TqVQo=oC(+{-iuQ@Fw5=$LJVC=ZbrbqF_j_o!*iX?X2W7FH$ z=MUNR_Vwuwo1SS~$1a=RDkFyNv*}U6vEvn+-V@Ur#(taLYtz4D)B9}ts7;Rs5IYXq z^nsWbn?Gm|>GP{1;Ln5C?nYW>B+eJQ?GKYY+YeYVaGP{1; zI+15kX7^}o5cw3!?CNa`L>@<(UA%3Y$RjATYqyORc@SlG>9%r_`%`9DZVQRrn=-p_ zTbjt-CYsqZ5R3Pl-Xt5t`YeS%IvCb>qLH)GP`J7gUByXX4h<6Ao6c0vrD#36L}|PcEz@_ zB0o%-U9hcO`HCBL~f+aF4Xpr$mdaJ*J;}>^0}1RW!kP0`7FxpDsAgTon}?1E>55k?+ADTNQ&E2FMuj9O7eOZ@XeZ-7%?k{oDDZWojF`bV8nDqn z%?k{k6N7h73IUu5V`#u$AR9+8xLXW%#SBK#fZgJ0USP0Z47SG%M$&-&|{uED}dLHnl>_o>gc|4NrtXNBh7s`eR%soEU8)=@vO(|jNc2U_XNoU}l;|B&7|)?hqrZb!_vNh$yh(vije{>% z;D7sCXb(}~bp&Tfv>xEhY-=29v4Sd6P>wj%5(Ramf@;Hn1NOrS#gJ$pLT#=q@L{-V zeLLLx&uDHObbtbVO(OY!4o8#c>H_V%Qh{EtKo29)oeYWo7FE7;AAG=LKA%M*nzBzp zu2Ya_#UX1I4 zhD1wjco@mJX>3H3f!n@MTGML^cfZ8*KMY4xuT!`uE8LqE?p?%XNc1(Vb8OTJ&A}^r zAJWs%_bBK~6!e@pbiIN;@Rbz7Xa#){p&1fg1!$`Xh${_iZXEYAgWmFhkXsbw`EkhA3bOrkAv{AtCKHk&(M^D4#vGEdkU}|Cp%lhZE>S2? zC={PU`4k;sCqtqq1I4P2=)`!g-jpsf^jlOr7C(Q0qlvCjc(n@eDG49-bK)^1`X$zN z%$4dRFDaDA6w1|cl(h<_k3w0YP;Mm(L!u7>g=6jJ`2}O6S0Rh+e7oW5GFz)~&sMl6 z#BncIxG#PtW!6jKPA4uyqH}>;@g>1_#lbkdU=@|7z&^w}K~r6?z}6_R-y;AmqnKa} ziFyI{>wWMMuK{>1hg4k*P=HTM1pm!(z*Yq~Pywz}fQQj5cQPc(l{2vp$Mfb>P!R=n zS{!Plg8KWXLUgEtdW%pDi7p3JEN`zPqq^Y!CL_Vn0)=-tBgS=;!n;=C{R08u%0X=> zL!x;)Ym4GpyFfwxSxo(p#Gy7Ts7VTHtAZL&D27B|$DmA>CGlJ}DX6Oy6z@BA4P2$5 zzWYR2p01!K5{ebEVPM(GkmyI4)R?cjc#)+jsJj)^x;WJJ3MxxMEm2T^ zCKN-Ww*yM$>y|j!yE2juJyU@Vj)UE(z@9rOh1N}hJw`BwMEOuY)-=9Az3Qg1SK*~9 zym!-LJhv*ml?v|#1fXf$L_CH>U3R>?fM<1sI~Cv#iQvCB4tR?K?5hATRDjI{WJvT8 zEHqefC&%;Fs-TuBs7Z0CZ3^nme+k!81vQUQ42g0}r(#za_ex8v!-IWtA00`GuKp*? zTlTD)cXs9c%CmQ0Q}OZS*598KZvA_><-LQ`W=+|gv@<}K{_*0BszXlOv+o`lGCmLH zO%VRShcG+5Iq7-0;S&#qTmKR1imj)MC}Jk_pWXh>;?iK=<;aC$oV}a7PH`FKw}pnA zhh8Z##fK3;{LEozxb$kmQh{ko6Y?A z!W&0*gB1NAluk4Z3VV~fLN=M5b;y?S*=|6B56#bRTMP^CpsgGA@c>{%GLgT%xCyat zEuX;T|8!bE!`Pej8Vtb~tjeW`6nO_V)F=n$yD@Clt6_opjP#$GZ-sgrDPr&Y&U}^{Mtn zP@ngIB=s4Zw;P~EiFg}RBpL3XxHnF6A!Yc|q9-6HsHvnK+#m|`RvM65Ruef>K^E<9 zD?@JDc0z1>_5d#LV`ONnM>lM{9GCF=S0l;Kp$DLyz1r4D^%6{?9o4g;X`70rNLv_} zb)&8=2^j_pA(Dd<+t0CBiVCrf=uDWXzP=X;w;VFN?rPcP5N7V^yU2m1I%_vJiNdYl z&usmSMVZKY-KY{K6UmWkxlAP@n<~+R$WP0+?aiKW>%XE6NaaB7l+D!z?uzy)t?x%q z2UV0y$_}zRFz1OV2gO%g_kZ#nd9Wf*RKM#{4GH)F>I4XV<@quQU}I&zIW+>W3r z1@0$|7q*TJ-we3$S6?HQaO*6T_|`I5 z!c?Y@4L7vR52v)Yg_K!l<`ZjjELd^Qd%@0gn|6U|jMwH2|t^)S=aIC+#Mlpyi zVU(6V)6}F;d5$!~iuPz8&|44bZt&G7Gm-ytl&xyG;nqk&5!xO2M7ntj1EjA6la*dO>abA?eWKA!yrR>(@Z8qZ|lJo-p^CvYpC z$5@HE2kHHq9kLd+!#*3nIsDaO^O=q#TkAeBy+pwm?LM#_WQvY~Kc4un0^f!5!lRWb z(r48?+WHEh2F0KrLnTjc{f@;0-t!AwiS3UyH4}KTYWos#0qsS7O=*WdrGB zf*mVp@B30JX{?~#v(e1I$H>=uSY@9B#tj14x_8x>gh6W}8aoE2iH0>~O?2xKD@8`E zsfHe~WVD*?KCAWMyt6sHR)Wye_nvP^o!I^Ui4i!_~7@^w=A7Aa%y<< z#i5EXC$uhdx1R3{KQ|tW5p0`{#|j?9`qz@Th$p;pWb_e4I?w~=;plUid{72$5LQKZ ziV*P~cmw57@n&=*!CUtW-|+hONVatCjboyX67crCwpw_0ODALDe=gxinG0IJX^(WD zf-Nj}>mR3J%zs)X&Ef!6UV1DpE7m*$C0!t ztsi1rX-ex?(K}EF2T)@o6#j#mkGvjz={;%Hkrx0+fWIK1vgJFo`BvfeGJ+43h8Lac z+c-W8b3)})99e=7J`=tv?8KVqxzB!rfcEie?YnON>SA~6%&Y@XbZl!ATHirqdloq8 z7NJ-Vt(>E{gF4#-hduNo+w&5vCK9>t#^yRQ4enpIanT>+e(@@1eIW==*w~bYv8TDb z1NrvoU7)4Ow?~VR8Q{DY{oT8Y{PPD&ND)oBQaAD61|Mw74KMmK>>Nynx$URM80Ipq z#{f~;a@Y*6U(O{6+ru3IOQe1f)L)>!Wlxbsy|RiuU~^Rny#TB+^1U6s8`;~qEREiI zKt8KAibfo69aY*VWJrJcEPUxlQBb}d1J$g8v7D*HQ!q|Vn*!h5$cSL^gn|XZ;wc3U z!Q$%+*1dmhII=t}S76U;8^da1(AE$lt*!#sp+S2F?i^L2T&XuwZZf zv*Z=I{{{{JK(BS9(j-PVgn!8ey~Du5X;<_w3{84c*1|1&(lF}m)(C7~(Qn?tM6m0u z-8-sbz8mf63b;~s9jbm6ke&urlx0Kk!3ijN6doR7#@E#*vv}zqMn?jpwj&FYz}HBi zbuTm_l;+&FY<({hy_Ds;WMUsP`eWdV#aoCox9u}z73PaAfE^aVZ4&%CgPHTO1n6V_ z>*eSf7QoqJ@h~h}4^=$h@=maQU(2DCm0mQ~K?n*y?sHuF0qas8hPJeaBE467WL??P zo^~LkrM+Apf<}DusI#SgY{Y>rw9P}`cI!4%v8!z|l8xQ3ah#gm`X@ftowB*`kKN_g zaUk89m95`TZvApf@js*&Kl8madcxbtIY!-3#hcds-jvpFrnF*a`B!Co)?dOcyUp;4 ze{KE{tqSDgR;sK$$niVy5FsY7(u3Xqy-)SIUyesN7 z^xWpfi)%VZZos>XHIYtZH#9DfEMK&|u2TcPu6RVCddt)(EiJ2AwQyNOT}@LNc`j^R zw6t^)-ZX3qjT#jiKXY2u#2GWHPCNayiAMK%6(a{%EUUB%E7Y&Bsb7dMCe~DkYU@>T zb)Q$h3`M5UL;0gZ<2ZUo=R7*lf236Nc z%%Tehg!;-$yaPhz5}!3NefGrJ6IleR!$3_ zK4YTA)-vTw zvQ#WnKZg4`&Tnx#AY;b1CZx#nkRGB3gc@ri&5iXKt7Qh~tUZ9<`sMT*jAV`G#;k=+ z=hxxmj!^ybNNC{-Om6(RBec9eH0|`6ljmBm;4fWR7r}&B*gUeZc^MWJwxd^GD8F}~ zf38`J>3v5Dhl(%q$HP^G#MqsL>)2*@=g9q7 zf{y@B)*sv33$Va_bbovM6u5ifZh|`m+Yo$HX*9NWsv%zpcNN?_;l2d-FkC*qnTEY1 z7w$o3!_9?z7Tf`FtKd$6TMc(E+*-JGaO>f&gS!sy^>Ek2rZf}!Tl62A6tEd z=TY~=ZNsCy&*28~;F24yUEr3({R!IOe7L`a+W_|^xR=9y8}2r^r=Wd41@|1dufwf| z8-;rxTzsxzyZ|>B?niL>%7K^f48R=-cLCh%;YQ%P@G8YqaCvjc!@OvQVXjIuyZchy z*O)1Max34=4#&-ViCC!1(d`XjD0uc2H}&qg5aq+OG{yzeHao@z zayL0E1ECGB%0N*|(#e7CrgMHUPy|(FAQvX%0y?oCh_VOg?|?ZEu2C6CYjI2tlsirj zq*Vso%-?%BJ=n0B!SD$Pni_C3f8SAr9@Q%cb!lkxLv1?7FMzJEO-Ezeo&iq5DIE-J{UGmSDFJx;-`>x77G8@MF-O zzy!i9mwG8Sayo>tR}jXX0@lrG2pIq`zgK<{`ZuUYL2q)Pz&AK21VSyYlLKQN`=ka? z$fyD0jD>wO_}X!p_FU*2plAK6w3}jSM-X;RLL8>eac3j+KO}9|`%|zVig9W+(~x?f z6bLyQWA*+Qgl|DO%ho!^!ozQXTA}|HmEd?4+uLU6#6V~h+uMdDw2_wNQv&Nu$F@K@ zG-!6Ph&4On4aeBzz!>Ny2Fj25nF8I{z`c;VDJ<^^D6u86{BZo6fjH+dobB*T)ebL* z{wC;=Ejd`OH$k@ny2;egc7n2f2>M^zY*}u5pt}pYdfFz`8Ka(KtFr=_d=C3}VZVs> zD7Ou);}++16yB+U-0_m%A_Vnt8AdORyPIj3fa|y{kgHmOVX(eACa;BUciNsz?x*i& zg|q&v5w-?l-!Lp*-s3u!_oToy$J<8~_XI@w3E~gOc>leQe>LmtDktJ^c8v=ZZDM_G zNUjVFZ%LUHSm1aoFuYQ5U=XXe0>u3YI3EM2FLC0$PYr}-S+u1eW}%}VfSom-u`G(9 zdmFmV=r^{wXe18j8dJ&wqmAmvoL|Ob-jO~5bG8?L`7j1Lyj&y)>v(m79Rt{ou7`dk zY|p1c+Vx~q&Dnvp@v6@~itr5xCx&rqAT5l9nFi;p%b>?JBnQLafi42wBx)uFt})jt zj6=}h2|Zud~&zL`7c&{i8>*9}E4H3HHp(TNAx>gk73qhnDsa{Ft+h%)hImqfN?Bvto}l{{~rG>f&Z4ke@o!MCGg)8 z_-_gPw*>xM0{{Ok0qb`VtlvH0a+*h?Yi*xddj1vz51(?3{oE_S;a86FUb*t%9e+8j z-(QgX5ooNnd^a6#{SE`y+dQoBFAldar+kx656fgZLfDhxfu*M$@|qWXcoZu~Z`@Py zko!Tn@=6O_YrW4f9@@-Uby`SdYYn?!2gsTpAv!q&uS2Ut6SwqZbwXCYcWE;`oRz~$ zzn7LRJA7s*{7|lZJG|@8vg&7WBqF9o}t~v+FhaD4cfg?yLW5%aqaHa?jN=LzIMOVZZcj6l=QXRSG&Wsd$M-V z(C%XGuF&oV?cS)}yS4kccK2%ckJ^1-yI*QIS#K2OXt%F+hiR8@VDdOayNk8ELc1HZ ztE_(b)%qP0{ZoLG#*ZHnDw=(6bA6;abVBLS((-|Wn?d`Pj<%6-3T+p6Vt z>!Z??dp~%$>-@-`-%+x|eGP{(ZHUz~*XsB`KZ-3?%KoZhmi++U@Z$(7=ZLGa?={@A zAF1uf9bu^y%KimxXDB|GXnXE~AMH@~pW?P#+1K_{R+ZL(mJmtVFPmc7-&>>%?n|(< zL}mY{(=7Yh#VX`RtK(XR+Ew-+pJmw}paRD$$IQ>e=UVnpmMZ)EJF%aFnsSMW+q@he zA3uY68>8m}6)$#mnC_oJ?QoW!GrO*PQC_>q!xGrdXfWcQUcGLs)hj1>A^Pr&Eu2G&N(jg-TvuB82= z;Z1gLq4pQJxOquE9j5z}zo>+T=QSF9ITKgI^G7I>zr7q@x91FGEBQP6(>x2P|DOI_ zPd0Lue3<@_=l8%#Zl}MJ zCk)9k%OR}u{*{S#F(*Q}%*$yiIoDhdoEGoJjMKxs0m2pDNfZjrl`y!*%iYK1f#zip zZu0(;La7Mby}zbVCc-`5XDO76@R0W<3WLnM5od>Y8#6js^0v$S0<$yJyal>FhL5>Q z-kSOwNV&<|Nz%g~cT2vVUc>Vu^Kl31x;?xm-%Yk@C=k|ZviliGe%3j&9bgSp%i0v} zeU>)U2zmjPR={kHF{w|hq<^gPKg3K`ia(txr~HVir7uH8q+B81W+11uikGj)xw|nV z{$Jwa1x^O0ZaC?Dz~=5wO=gOVjW@MoCWNeya51vD#b;){0k0#g6qe4c<o}U50dp-4Oo@DyB zPJutm!v~MbpX2EceD5tEBQ%%8#O(-jaqZ*l&N|L6@{PY8=s8^h>zjB8W;y?Z7`~H5 zyMf+GWT#reFJLMK*3WQNF-CYLG#FL}BcimE*DQ-X!*w;4rFGD_x*=Kr;LCv1#U1G9 zK~&F4xCDwhsu-TJD55}#j4+1lTS5$IW3)?Q6Fia8vO{SFV<1WH()#X3Xby9i)~|*L zu6|IY6|rz!r$L>55{+FK(L0X0&V2(HGoQ^N)!B7gh>?u0lM!x~vj7w4Q*+z36^7A` zk6M%g?Yj*mNI64JgqX{3JqnzRtioc~;LUAfZ7FCZ5ilq|hGCpLs=Q6`=nJsBZ{q>(=(-0C6pFyVn}#VCHf*?DJmG3yFh+F!-9Y z9ZhRP<}4E_<^LrUHaNy8M}AzW$43y%%3t962x9lxf$S*pZHfocvdl_i*MfZS*MMoE z==mGLCt?lW=UoI{1)Dti%?CvIR;6!NAo)~hF(e)#b9$;XJ0{FXb$VjLT!*_70NwSH zKTiSJ%>fiQpDyP4eYCm7YBb7Hu^LBKeC<-P67hYC!fG5@HK3}6m4y;xH7*DoVRZv+ z@=npI9D~*D7?DI);{b4OBCEK0A}g5ZuTEf?$fvWlB0vVwVjuD<)T>gvN7t7&Al4|!6oMEsnh zu$o3zYtYn%m4y;xHSI~@NL}3to4hePm1ES^9i6h827oylAl3ro=83Feo-aRQg$!D( zcH!1g)zx&e`W^D5Sc&*8MPW6atk$P!Ru)Q()$}dE5mxuYChzLwv)a`utLXsvX(Fq* zc_J&A=Rd5?Emk*TC{V0skQIN8K(P|h!Coh9nn_mIK@?UNN{rRaQNR&a zJ7AO7CkNIzj?n_Y>y#Bz${VQxVl6Okp2!O3`BSyIRafJ%3#9654q3fN8p2A%G`3G+ zHHWOWLKIdON{rQ&Io88&%6y1*L8F+CEM)r>Rtw4ML5RZ2LW!|jcmr^R)$6dyYdk)y z@=jST1i+Pvtm5X0tYDshPXep0X%?%+WM#1Ggq4T`CyuIKt{p z*yR20_^c*(%4#tHK1gI0H&0{*^Zd^eST&?utd@{f3ad_7i8z>|uv$V^zk(>NER-0l zC6&MtR)2?0UN^ntdW;shpi@>$05C`c#9Cn7JdqX5^TXQQYJuDUR4s5RSp`^i!b-#u z6ou7Nvf2YtSXn4BR!h48M_9GNCU5!iSzX*ItEB+=Q6j6jc_J&A=iidRsz;{9s+O#> zQRIr1h^zs{s+O$y!z04VLW!}e{n%o45H@+gIX3nj*??q=W!tHZF# zJMZ|cdJbVWjy4O|0f4`M#UsWlZl1^r=J~fKu(}m1D8;IttooCruoCeMio&X%tlohr ztSpomtNP`@5mrg?<1dg!s!IRgs8?130qXn+*lvM)&hH8LVUB%54S;0JioHn;w;3*jC z6{`!#YB)&>D-o+H3abmq>YosWm4y;xbwPLF2&+tZ@@kLI>hVrlT>yYf6IsR06IsDL z|EdI5A&ef1RU=uAAxU8+;`tPXRU=t_0Z~|4C^1%zpCCwBajMFD?D(u+?vzy{0A5aH z6*o_01@rv(6Igv2V-+E*lPL--5gREAs|Z zQ&tfG6l#E23yhm5vVwVjr8c)(;7iDas;d=bHI<^U67fQc!fFLsIZ-6S%0h{;TJb-y z6juBx&OG^9XGAy#tL{S)j^oHXkre<~m&ht^p2!O3`8Ox9x&xU|tX7c~fAmqY5^)_x zVI^C?9z+&a7D|lOD*i;NuquO1-Y%WWF<4FOl+`K#?AHLXx{8}8vVwX3C)(Vqt5uK{ ztBc5L9!04u5r0HcSjon9dJoOYLW!}uXfiB?)iBuP<>JEQ7_6@Bl+{H5DAxcnR&n!0 zRxr;$L7Q8wPJ^siT})Q|OF zJ7sk-09I^}E>A}g5ZU#ZP4Rt3m}VzrvAYAH%xiFgA=VYQm9^6=7wv_K0b#%lE! z7OM%c$@|6eSv}h+tJMH_UIWBf#my60!94#JZEmspCdTR#vT8t{6e|(8Q505}kX7G2 z&B{WFvAX0%;7DDa3Y)yIbSlTFtFJm`bqN51fa4Kk6*o_01@runHn&*4!hC;(_~sh2 zT8TUQCO`ZtAQcS%0h{;T5~&agw+h#r)Kvg2ExOpNg znCCA}V0Ab1Ev(j()tZpSO2m693ahnbH6&lNvQT2I*0MN+)tRu#+kAXhCw9teEdcIH zWED40WCip5Unj6y&3p^1%gJgz@}%lY#9vSpR+p32$ljWjg%V?R`BdNts|B#h`^WKF zP3V->#q)@@z_@uLE12hd(NcJfQI0W#`4(2|$!Zhwq*#f#gQBonPgdjlXjT?V zjMe%+z!6qUV3Wt+%;#~87FgRUtMvdlMFYfG#my60!90I{0;?kCTUfP{)pf{|VkP3! z6opkQSxqj`tSpomtJbeAR`sySYdJovt2<@Y3V>S@S;fs0S;0L2rwObM$5?G7tF6eB zVkP2Uio$9mSxqa{tSpomtBt<{j?`5%Z1R44d{#RX7Wj6jtTq8)m_11CFrT0-HQn2-Y}`(E&WU?$dh6vVjD$absbqX_1CN{lo+e)zPDK21e?6+I+bIvn$sz(>i|%z0b>0s zZl1^r=K0Oq++yWmZ3wID$!ZVsq*#e~kfN}XS7k0L(X1?#7^~}FgIDV6HrV8CJ3gzH zPFYXdDsG<03g-D4+T5zE2iV4>uC|iZtH_gLCE{U;^v90V4lAyfz{<~W5VhdvidXf zq*#fVRBExhg{-cIC?mUt5@U7CY~Tp1M`4q9-?v&Lw0DPRt zDsG<03g!hLX0U+pM&Mw)oQa&^Ehn>F-ZJW4p+fMM5nk#n@MbEJhWBej^*Yj6n_-1f zFu-Q`2W>b=5YM(54l)X++6)hC!@**BvCVL>QBZF)?1w(UJPr}Vtv16UM#0rK!)e-Z zs2DzBGaPCZJY+MxP#X>t!#8Y(!;FIc+Aw`EzC>1rsZQ&4bBXYkEdmN|21{=)FK6<# zH>03AOO;y>AiS;+_{N)2@U{+MfgaL%Q0268kcwgyzNc;a!KUytEexW-KMcWR6a`1N z62cG)0$P{}VIsO3O3UeaCB-Pr)BysvNDBh?fEEPokQM}tTkt&20oXMP%tS$N)#_TP z?@?+;6Vm>f)<>Y(@emNXKC_V4R=muqzRkh7Kn0;31uV zY5fh*7uoa^a#b4Jp+7aI2bg08;z~RIvCU-pktPoJKBM3RZF3)Bu07I*-C+#&P!{>Y?w)S=vVV(NZdW zSev{AlY*UE_!ES}n7vVuqHmM_4*j^8o-GNbIL8*az#b@BxKoFIjHs((p+>=HwpcgD z^ehB6lhJxr%vcY^LXCn}tv>|)UYq{UTJIcU7;oA1eM71`0?>aO)9Z|1paZ)iFcV{q zRsFx#`U2?7V|pDapeF$$o@Nh}e4k?rtve$0UL9J7xR=L5jY1dhfq9I89|pK zjIRHagzdPZw_JEV7k89AMk>cJw{aoV?M^2RE`#y|w1I*V+KMCJrz!(}O>LkT+Wgj7K)0G!egV4+rr3SRq&?$YE~dE4JM}f?)Rf1+MrdMWdTc z(IVDSl;u>PnF!qhu^(g1)hQ6fEO;6knVwxpDX&?FbzDk05yS&SjPo;dHf8}hvoH_9 znT}X%kIZusUvP2AyDd(>U0i%QI5-wR1(g0q34hFmXX^7MRd9GZ=9K)(#7zm#)Tc`L zD>FR(k&>Sx3eUi>k}c5i%otR%47I^CV|Yn=GT!sXnK8QL1;pl=F`*;~JD&b^CHoMY zXJ&E9%h2%5JOLB3Ix;ItSe-nBl_g&yD?EdZCF23lGk9T%8<;$U=ay8#j%V=vk}u)# z3{ETA0*7bt%#s{L;TfD%@-9;1nSNObzc%2ReqG4~0P#$}rQ~!3@=U+7q!^8iXZlY| zk`S9``i>IzD4yxNN`4MIp6Sn*Oo4`H`hx>LgdNX;XL<~SXVzkeF#={TgI|5>?}-Md zsPBoaiuySs^H_~y``>+2F^*2fpL_T4-FE^zNWH$-Rjt>Wd=zn8?}f9B7i= zu6|F$P2ooXuHx(9HB$HyfUAUlm--06HQ-hVZW^YZ1Xi*znL z(=oDcnQLV9(}BeZL^-{HYvxaJF}qqdG*87wO1ZF6DRrf{)=H_nmC~I$bAu4-!Py}t z?xpe2DX}=SK1HqbOnxidYCc(o;L0=kP5C7)mvI>yt8P8D(7%ns8lZC>6hy+n$G;A|FNM*TDN23dC)Ffp|Vj zIu%1HMky2qBbYsDRB;4KAuPR%z`*QT4}*UK#d{kHMTz||WVx-RSH?k8%~>4!fXxBL z>`H8_SmHTkE)-Z-VlN<=m4lWz7~0_P!I7t9u*2tqDNjdFhwml0JRRK~#ywEFj4`P5dkS_!~^k#kwxC(Gb_FVY_&?R-1?7jsiDK37blXN1xqq`B8 zU*b$GN0E;urjgTD0^jDrGHM&p}NQEB+)XxNj{s}O_tu!)q> z(2J=${XKZ_*p)C-Ig+6gX2|ymGgGn_UL&vt7qfsdPC0_tG!@N9)AYrZyJ+bJ(UXGSw5jG~C97=@S} zpJXM(tSCkyVbq1QrrBexhK_fq{;1vH9i-la(O+W*CTgoI;~7Aia85FFX=L?{ILZd1 zd`*;GX394d;uRuZ32`FCEGub##nZ92@U)*LWThHMeFvygENcKD1@%jMSZ)UiY1Pe9 z3ra1Ya@nS=0*xb&KqjOi6%T`lP3v5G*wSu+C(CNhM{QafnH|Myf^lTV$Q*>A*NL;L z0Q7NekCVol_ga(;&y=NIdtq4NnX;(sU!dWca!%Jr;P6a2v+F)MJX4lo8--)l9Y{-$ zRa^8}mH5f`8uVW4`{j-wH6QP5W=An@qGKx$e$DLI#OYeTW_D~AZ+tzH zLk!|WpD#Z2x#fG(lo|YTHkIF#rp%((NagpWDYNNk4#IHdd(xCM=yl8Yq$w*7z@N(R zNmEv_sT-;Mo;2k`mYXY;-;<_XM7=vTM4Q#r`%?KmY0CA~r={|H(v+>!;Ll3sSf>0r zsr;Ta<(4LBV&9Yci`?URe-hwFr0$7p5EkG^r0$bN%g;33lUON+hXpzf1P-?+4ViPd6?`V1nnA%SO<-5<+B1Vw!K0PPVSibx8jAKG>`7GW0 zMF5mjUqkBNFI9Q`5rN)sWr3N>&(gi$(Vv#Ofco$0&rRiL>E6Tihf?`jy0@MFqTo(k zy@pAlJjl<|y`~7mgXrUm&~x;I&bxxsfC$8DaBOe_fU zvvjY=oC0BKke{V{eI_&95aeg+-ZT*+L4KC*%`iD5tP1k8bZ?Hyk#Aj)pQU@dn3Ew~ z7R<)gn`_PhT1$|hrF(mr=R&w5$j{Qfh33UDxF*QY(!B#sPA4}7`B}QRRD|upUsEU( z;hrErOZS$G@KBJSrF#dNPa@8a;5KG-u;gu5ke{V{hnh=~&K@JJoLSiFme10?+etE& zpQU?mr`Jg3XX)NMNY|apPr|)-OY=j+&W0}8eHC=lCYWt$HPo^;MZ3zOw-3+<@NJfGmQAC{R$ z%FB$fpF!QJ$x3mt*90oqgRhOey?E=N?;W@bmhIExq+H9`%#Vds~oIr z_^S`yB=!cz_Mdt$6_Ndj7MnM5c;&kOrr&&#}v#-J;8y@DiKcfs4WHlkz z5>l2U)ej;3Er>nwo8X4In9)ZK$CPoJ#*n@WWeX7Uc#pJfFC@p7a8LYQ2*Ye-{3b*Q zjVGffimyY=KU>GY66^S-h})ZYP`z;ng`({9OC5Lv0ug}yPaR_9kI_N=Rh~z5ykQ7U zb*=&|kKX2Vi7>;_gmk88d;Wd!7nMCijRHQB=kYl7Mpxc%oAXKTU?DCzGL?g}$;0HQ z%4R;x#(5$#__em;*Ko+7x+CezJA88{Q6AOdC&f^1ilNLT%1J=U|C6>NmkSZjGEiJL z*|>m3pZB%p3o1P@17()ibZ#Maoq$$mp2~!8*M{-zzXjm#YcNrpr_y^1vwyF)`hz|D z$?g`mymjbWW-+mzD^R(QHxnb(!YU@#>%daYq?q+Oc!bqVWT|^C#9kRXC99d-i;PG! z8MGHMV$I|P#@~kss+kO@$UTVsd>x<7P6x|wj(NG(&Xb<+u; z%fsBZGlr5&lr1cS?HYw#_$QCz&7?M=neZ(X9!XfJ!OChTxcTQm@K@dBIau*9x3N_F zPDRi`q|=YTdEnSmT}0b~{gh3*a*QFC<>_eB#fhQ)-$J(f47K9KQb*+c46SAE&%qhb z{cRm{pP#2Kdm#R5WvLh-Q%1o|9V#_Z65r7%`2f|$Gk8*Lk1_C6iQk2h5od5{Y!|I$ z2&{Mp`C=6c6v|tzp^vsiU{S^xwXxxAs`nGWZ;%9$N-e zKsUzKS_adv7QD{XN8y(RuhUxtuUhareY~^ha`Q^KDYWrif(!Sb>Tv$jqU@DUQq^9Txhq3r}t&hrQL`^Hqv^)$TZ{!N|H-+p_d;hNgmvQ zK-YelB%gREw8`$D;hMe~7w)NNFxbc(i13u&jy+<)QtkcMR20FF<3i=2m#u_8JB#@m!|XPq2jw)@T!7!pxEdnHKuA~$XlZVj zW{tpQ(tO0tMNi%m&c)n_si5l`9U4Mt*Pm#i1cH%u8q*ljSL@KW9ouH zI&cvJ+f*Pkr79p-Ru@=!J1znKL2X(OQxm7g@7mQ~FUfAU&pZx(JYBElJ%Ft9Of3vq zd$f6+TX}ju%jaOr)3eIVe;O*Do{*V;2rf_005h)+E>F*g`DWC%WP{T| z@_56e%_qmqUxr11>*9g8LWk!A!GYR_ztO`#ub76;Sdpfl9i*S819`8Cdl)vWLgvG* z_3?as$9!1nQ80XbdS-T~xmDZez|X_n#?&MqJ*|AatXl*_CgJRm52rmJ8P;r@^k$~j zUX2VNTiU}YLEX|;VZdQav&zQ$y}dd~uN-^Mt{+~5&|V{Y(p zp4S^ZGUe+H9{Sxzin|9~y}?7TwZX$i@qclHXA3TEqP(w3_mi`}j+DY0M9P_6uHj>U8K+o)&fLA85ae{@he2_0JGHlzJQWzoEY% z^+oD;)27JqP{p6G(-rDr<9O1NokqarE`9@IP`0v4Xc?5PtO1;H4A)PA>mJAm0qlPT zF$DzG{?`nahuZ%Vt$qKCY2?9F(v0nY{evLo?o(&QK&DD*2*_!o6_C@bVPHr`=@XDL zYn|iz9A)R8#+`E6(oB^nttswJP$XZ9OS-!P^zZRh@*Y3+CS>0;o;}1!*!HVb& z9cd{Lm%yfrn!|Jdq4g2ywGLf}L^HXCZ9YSUeI+WX?_((zgSblZ8K$@xNpzKGEzhuE z9)_6pi9}z4ycdkc0zx)8b`z~T$Ll?J!ROp^&)Oah6rUyF2H5p1gC|dC>L6^)*Vkdx z>vam$KSOx0G4Q+uPaXq9vmpHoQqD*nWgU3TLVicDmJ>N)ZLOPB|F zqL5>;VikO-gRxhVvr(tQDsX@gvrhf3T7M_>+&qTf*|ZP$e2?pZ2bt3p_g%R5e#VC^ z-p}H7E`V(xX$|+YZVFhw_p^Le9mw=;Wb&zm+5-D+f5gJ^jdIYQQV^zUcLNcA3U*oY z+-U>5!)Fwwb~mtge>u)Vz9Lq;t;~~i%MM+;S2Fdk<58+a?o*-?x(1GU^EqfHy?R4k zjqqMw;Q0|ec?=8o0EmrGjtlf8P`X;Ss?efW* z)b1hF?vpw|YPWYW>-7Su*WoNXsn-i)^?E_PUYlrS6!H<1S^Y?V3TQXV0l)Q#-4%C5 z)r{K=M)`c(pT`d5pzq5zfmxB405bWI%ACv?eRcR|6$gNkR5Sy5CMW~l2Y}4t7-&x3 z3Y)vo=*(N{`98#TLN7N*ycg`)tvTeqR8@lm)A`%Hk^s zJj`t)Jm7bh7|^?q{A5g%r|MZJV`kjS(2<<_99w4PTvDu}z5(r@RhqnO%DGbO--n)m z<(uWugez~3a&Fdv{B1110L6I`l9?2k1~h=I_*cJs@!M=pBWP+DvnDD3ehj zpRJ|O$!t>j?7C_|=);DCEm-U)7gJj-d&&LjHTqWp#*xQC-T4Gy`s_qxM;=B~qfdqe z{Rn1#mWY=1Zj`Wp?A94tL=6se8@olXX$WdSN%cAlp5MU}s)48bB(Q0KXTZg{3}pPj z>G+sO zP~LAHW!$IY=}mT)T?9*>-Zp31D*)o@eal&H-CX(#%N|9pczXZntgsgD<$Uvor~icV zeMp(7zqriW)$;z+Q8pc@JiVVd%YtxudOfbP#em}JecoA?3zw(&3un1?dw|!Ao=M@_ zafTo34Yl>f)j#hF5`R_u^E6ab$J>D){Dapck!5QaO#R?>Ej0QEuj%DWE?3b=KMbZ{ z|KK(6i1cq=V_Gnh-8bNx@(?a=UR-I&Z*tL#@TOLS#q02R-ou5btje%@dKfmjDMr4D zl1qnCih5<#e<$?H@ABU(`VENX_Ma+x`qK@9EF=^8u#&F#RF_?@_+)cKV9~J8^XzCWZ0e zm;pY(bn6G00Y1QV>j#(tKEQP6;B9!rSQp>}Ot*f3DKGlFbIpUmX$kNFCU1vea7BO* zFx~nAW`GYc-2=@H0Jtf@2bk_s5w-`oZ{sc#;hq2=V7kjicqqUJnC?O5U5K+Izz3La z{Qxt-2bk`mCZB-sF@oh}x78;PFx}fp($5E&?%U}#{4X*ecaW~z&j*<9*aJ-dKyI>o z07}Yp6)c%;-8PcltWDA8SlUedb~K>U`2f>B#-u)-4=~+hm7fnV-Ie0c-~-ImA2H1g zKEO=9LcDx{nc6B|KEU*-2bhmT%P|lSFgc)R>}ODSYVZJ)eZ*VAGWs_jV7j90=_hVL zEYIt>@Qgjn%;08+cl7hnxmKWcd;jnWyvgpbaLw_dnRa1nUD%7dP(%O|lZ&i70{xtrafHS5MY9p)&yqMUXFHoDqKN}$E26wM{nA?09 zc2zRN8S_=d>~SWuB~Q|ZOvZXObTYFoYk_r;^MB6ZksQOY0lTKROXucn1!=s8M%jl8 z^J-Qe_CMDY%ts<2Z8nV=S=<9gg>_I*I0Xx^kvfczGW&4~>&M5k_voiQ7@US8z%okH z>6qu&5@Z^J8URu_5uWRa#xG!a@J|9;Xjo(Pll@nKF*lYCYD*4t+0U#TJx+`{8skQV zk?QMur>3!txRrXISjyih=bV-@hb@}ygxeveV{86^JLX^KH#*$7;C`Y$W{DPr^V4I5;w z5R4N%?3eH0O<+BV_d;!P5>Nb77eB?zmjAm++|}U?b57!}_)*`{uvZR+;h zr*6M}>h`ZklGfDiw@=-E`_%2XPu>1^8OLpMvA@8tr|x$kEcM%`Zohr%_S>g!zkTZV z+ox_nhc`^!?*pyHucz)WAzb0NPu+g|)a|!V-F}Wy*3|8{Pu+e!b>E8=cKGd6w_i`) z-yxkn*ivH_wtDr{O_Dw}b<=D3)YMJ7ZePc#`)AN4yZP#5kd2GkP8$agwX99i`j9`- z+TT6G)J?s-dxWW5{Ceu9KiSRc%smv|6kambRL(qPs;OMOYAP3Rd@2u)M1<8ivkdnI zjH{+{YV@N{{RB0GPbj^;9d{!n+0BlT$tRS)0`c+*rB9wvX7UN8Pi_=5`GnFZPbgix zFqrsrxfpXzL0k5B=PJSVGQ5FcExkc{g}L_}^!bLMdk02;Ul;g;ssBWxhVLr+Jyg4W z&GdV}hCbx`E20K{^cVRSQ}3t0+_#ka0R6*#74!$`AM4}q0teIR5Bn~sKb?Q*Yg%^0 z!fGR!LH`WjDB@(&X0Gq|$a^r0{sq1&+GoED|I+NL#YQk^AF@-27l5ImR~R@{UH%Dj zj?}OoA<`;>7|J{!!PfA|Yh9i<;B|Q9wJwjm*5#4cx;%VSBH0LbgFVkI3`6o-S0be&k%!MrUE~i2?K|_fnAa--0&Sq(x zOhH5NhVB_qdz>Tit__dddMwcZcVM7PCCEw)8|3(Y)tNgG-GRf(8UiQ?#RvSGmraLeLK_7=em9Pg8SIWPq z;bvmJ-XQ52%*{Rxn-|N?Q!udQW}VJW{(f!w1#+`pWgyi#REHWpELyQVSP_xjw?QN) z+u3((kU04v$g?Cj0iIOnc8mOj+EU2#V^AI>kGnjQO!6(6h=;2^ECR7~Ed58fM`_+7EJ}Bk|+! z{DnG_iGk$=n4^H?qwvsL9pFQN(f1z&kr&BEXgw-Y4s%3RZE$G*mXyXQr@4D19Sf6&}`Z{gJR^ zE^(dgZ)&?}?p2W0cG29i92ZKs)N;z(j?O%qaYg1_%&-B*Ko-5V6gnT)Jn+3H?25Uu zdM5Hx{2Dw@z*9=&Kb0z@0_7MF)07rTQ+1q?@Pz(inIZrEzt%#TBBQ(cOL_s@6CZ1C zS(@Av?;$h+w0{>(-Lf7e#LXD-*z(Xhr@R5x$*6XP|pvc9(QBtqV%K!0>uULxmF5 zUR0PX$8ZKlct?6CW2j3C!URJt9m*+v4La@<#7WIGodK_x#wN5Le=O#3M8e&e03}V% zq=;YJRk)bmOmlK3W8j10$(dyc3}zzmq^{_sLt>G}bfqF)E0DZW$j_2wy3EmDX30uB zs|fM=9sQZ(XZ>|%ycs&Wo+(`$8}{UF~P)4 zQEJ^0)2+(K0kMY-2qJ!{ITi}sUS4x{7lP!qUS^^SD&P%WiMLK1xm(5|Jl_jtMhY!@ z_e3a#x!yCSIQt|S6`4$;z=}(=LJ0WQkU)LyneLF~e#DxAq%Eu>yXoZ2kavhs!+Wt7 zH8fS^$0#W^Sj_bSrAM!dE3m^F7f=G2NA1muIrw*)6&q5ry-rf%wZ#VGR&6b@ky&lW zYqcF;yarSY@pmNKp=1Ja#w^-k$LdP6mvp+Vo-*R4o@qz#fSuK$bl4W-ihrx9RHsX_ zI*b%lr>UlZk*z(t6@?qdb!8JtwQ;~Qs?#=(Z7{1LuvmQYjQ{8L+;R9oy;?PxYSo}8 zu?F!iggvWl_r7=zF@SUo4@rLsbX0bz8Y~Fy{L(s>S-QRJVVq^h<5-eu^}wtSg_>_TT(v>?*d&i3J zq584z9rnQ*tsa9lD~)OAbsQH$@dnE7k*}IVh0I~SZLOh?6`%%fJx&)MQTctXhShHf z$9N39MPA)Nn0m3w2!><^|34j+|L?RU`zoPhTS{yaX;za+&o(&|vpCQn*`zZQ8x{Tv zWqg$A(B1Ht`Rv_2r(~%TH*PQ!QHP)OZO%GCQNJ^LP-Rz@?#mN z*~&OQUd9<6SaZCMEB@p0P~|_xTDZFZnI<0Ttkw|IqgT(qKg*lcZsWY5IqVlQia z%H#SKOI8`C^vI`2wce#z{Bs@5ZmLFXtXQq)j{z{A9jsdI?WjXn?W+jrR@Bc9+QAN= z%UjqSFN@^ji&?cgKeob*p|gxpX!9=9Tcd)in!uGZl6}eOt_=s zWXcYFlo`5X3--sSWHv2pRMnGmFg_`#S(CDLCl#BNtywyDYjwO?nnN=CGiGMyG1uND z@Iz8o{fz0#8bbSa|C_&9K$>>{yi@OwlT>B#4=ZlPxo*WBas;2<{!9 z(fc68YVrsvNNnGBg zv{q{a0BzN3+_9F*MWt=^6dyDPAQ`q)wHFb)UBM`+G;G&LHqv-gR6}QnkYB1u!-rK38#1u2 zw!V4Qz$Nv~W#`u7Ik=eA)t+0nWYMA{O-`_4cYrdGhK0JQsUbluTiCd0sbL_XioR03 z-G)!4Bh|Ib2bC^Gu8qir4K+>5OLcu@U^6cDF->*NV)(HoiEPy_kEz9rz1pS=o2qIW z8|!MDA}Wk2Ro9%`yaXaPRU);^YT$!qWNBl~!s>xdOBXiQR1dTz+n_>h8e%9VqM~pq zFREL<==`{NL32$rff0(2)E71^UEW9$glKG6>G(P$T3WWS4tP3#q#E4dM<%h$;ON$e zF7^@onWq{Kmm~R_WOw>!`1{^cmD! z4P}|t9y0CPIyaiWG?Og5`h3ec+paw?)*^E3>RQXVi)hErny>4=dZ)(jVK-m&N3HEi z?J8|s~rFP)cV!(s!5L09P2HVwBEaV~7u5|Rqpwkt@xx@Gf!`0E|o~Fh{G69q| zEN`k^)nVE=a(a;&sN-a!W{=}fTxBwNcfhxg+A`_b#`hy98v6*3xuz-7*t{rG#WB07 zp@!o$ClEE2aHk$a?OJP;&NZi&Or8D3mgem%-P=$3ylhU(z%#Eq%h3%5vK^KV<1$?T z&BFP?6S2%TdNQ%5RyCPmCIZda?8z(-C_qkdICIU+dHCl@LcT^x1qQiTILhMT-><+Q zx`a4hMIUV)p_`GARuk~?Yt~)}tYvHB?ogq62@ng!EX@M5eu2%2$4)G;d6{P}bb2B& zSEk*wQPK`$_y6+({NMG8qZNBcUE&Jn-z(zd^qhZV5oTXQ9er7KlocU5=P_4=cp7cT zg}JVJbaCCWFR^+FD!mE60Km0UX|nswJ6g(5o!?Tvk1Hx!lbviC_Syf}+PA>TQB`@@OlM&T5JCvg5Ew%MMKXDZAO!N7 zkb%iOYm$tFR5~*~4>Hp|boWdWKzYg{g02$Tby;?J?5C_Ej}O-615|viAc*?;Dd>kE z?zal;!u}Q!!F3V#oO{pz-0G^jA?(u1)Twj-=W)+H_tvedP9JDJ`|wGw%bkmeblKiEZm;qnu8Y7Vv1-((n{3+h7x`v@X0aPUI^kJ6d@>(tnVUrysh;0Ge130l@6}g7(J=pv`5)fU zyQhBc%+{R?Z`l0%p7FbRGqGR8jQu7bsh>sBJ>Eq6HIjV~*TQ!l>Ag>EN^d(uO)S$< zPv1iAbsTChYF~W6i5yiXt=n+(@4nn{O~c(Y7ctdFM14Jl#&bWE7y?BbgsP&nAp;KHe4Kx21@1X@W60^^N}J@yO+?5?0dNQrEZ05eKR+nF7s)+ zU`7zhmpQ$`q!o`R1^y*n?zFo5y5G3!d*|JATkiaZUyWaJ-iJ?Ju;`wDxbWefKg-P= znAmvMhd*@I{D;q2u_S-qimN6*%`@Z{vo<}p-@mMw7hOGbWBXMrkIfxB(9rnry$$oP zS()4V>eaok-Sc$rgfp)m%I&<1?n|$syVJVdFM~64#|)TLy6?-qNxv4gB6rYTxg+aO ztZO(^g+D{Wx#M3Y+!G(AyT;tjbt3k}N9o=p_xE*8XRNsK>RUfsfAY))>nE;SaSi?B z+`77Z%v9xHjPy*^n$2K##_aPhD?TF=`;x?IY+bYuAtZ_Z3(q@f@ynO_DF&^ZXKo)K z9;wb7F48|K|F1p?iEnY`DFm%0)xs#5ko^w6#GhMKH*^e^|JxyP>Oh zf&4Ew+LSwL^EG1)KVQCO{;fMFr_|p)rS8Eg^$T)`JeIrY)hTt4-rn%c%--+KIr4+O zPs|~rzK(|J7PE95L4Q3%_AYM~-m{%%e0b;QE2HxU3&lctxUV*a%%ifzaMvPI*HT@p zCD40WQE0T^{Ub3RQXNCO`t9R}NUyB4R-~@1`~+@fWZ4p%73RJz!g5DxLgt2x1AOVF zg@x_oSsQ)Ztz6h%D)D1D`r;q;$KHpK4JShlv3068t9g~e_YHHW*WJpgciw(KH5phx z_i(cYQ6{dxAQxRpi^cLfS{&B%Q?TW{YHZltdc@GK@b%ssbJH3gnptjr=D01by$uVF z+Y+Y_&mGZl<%QwI#%psIZ(f$$wK;d-<|(;cp{f2bN=h?B%!4^>Dxzu-Rp`-Pm48%$ zo3{@a`QctfaiOM`_K2Sf5{lc*oki3~PZ_I)8ZiCvRcXSqET+F;kHeKR2Z}-xtm*EE zTHDv0XOxn)s8H;WX)P3;gmKf@rNJ}zs77dKdAM3oF}wZ;(ZEQ4uwt~gw5@9o=(+y1ty38K0?pe34xhsf_7Z;a`wv(gd)xxf5 zyvROM8?IcGS%q>jKN9i7TJAT0`;|LmQYacJOcX}Q|NQomLci%zB|l+16w%IayjTrJ zO2xrO^JlzR86GSa`Ws1UFfcq)2>MHr>M~k6IF-nR*gYe*;m!B$7^kt!R|@1_f!yIZ zP?knC?aLH1(pM}QC6$pvfi9*Mb7Er_4djPMqI{nT9tWYLt37OA)7~0XC!!+%`|Zl` z#RbU;8wyDP&KG_LEtXf8N+SU+@g%@k`+$>*{23Uf%py;A+2C+D$bK|h>Su5J^Seie z2ZwB1JR40<*@7Kmx_TNEvf zjLT7MM0gsBdV8am0>$g*s@)KIWXs9QIXQ8_E~^M>wWq z`Eq`gT-z~B(}O(B_b;@EMfR}R9+ud{Qlrv5xeua=DrZ(y8Wq7`x9$j&JBb)osY zNQP8h;(0Kdr|HZCj38-u=(Ypzix4gMgViCATShf?rdF$5kojp6 zUB7sm?N)@1u3Y~hW|=0fn zS-<$qEN^B-rC`vshCpE#smWLA&UZVl78OiAGqGq1FVRM0H;rwfI5AAC3vK(%j=<)) z$7h>&6h)eC)nVEvz?KY|=;-5%+$is{cpbAj&=IchYF@QAT0?)s=IGq^mbO)^X;mQy z_#qIl9A@gOO7`4FfSwuAGHn+(^Y%C5<%9B(8u&_22fmKL7b8fMp}#=Zhj>M>DZcvri#ZEOMDKb1DJ1O6M zai(!K6K|xnQw{W$Xn`|>9YuqD>CTsVDcf10pJzqi4TiY{paC9~)h42OT7xk$f_D(M zv(F`vJvZ8D!!tnZ40#aH)bAT}v&2|5iJD#xY7|p{*s4(y6-LJ>`Hbwq_{d0&Z_)O0 zDc|3hHw!iQV32m3W+NlxV8kkX&qH%IPd6x(i0lC^s1zZ)vW=FCrD~~2cYkn#8<83Y z6L2hfL99mk3EB+uzCz-;co7yAPMVYk(_Olj(8}e8f@I=Av+&xv8AU_1*9&L?AE2!P zjhG2$9BlmJK=Y7Tzs%|x_e;i-cBt)LQ5WSbUv1)hZo9{^oN8%skakISLpC^uYq=8{ zDwSwr@(#-A+qAwVY&IHs|4e+oIF;yr#S8GdKb3nIKSzWz+o{-II;WrQeMm zUGI1*S4&lzU^~TEHo%u=*(r@vUPsZop0+h%OM6=s@%*QK30+!jKJ!MN{j&bj9)Xnw zv~}&X8_W!U?E?nQHhY@r3w7Ceq~44391EC?dukUt1gJ)(m>Z|71nrK}tCR@wBeXv2 zeoe4PN|c+luGniEo`TSRk-vb%u2gmxMK10bg~{BvjnG#K4k2*_#b)JLwrG^P7> z5%_}>1i4jyPNpu{0`ef$b!mpKKSGBJcGL;^x60ZG@-+S`9({7b#APYB4iLQg%?AQe ze?b0LRds_r?+BxbR8`Wd&{z@>sRDVAvbsV3SXmt)C+Qo9{HY7NE#dy6=?;Z-fc)}o z3nM9z_bIE#sjw6h;X9gC-5?)VRu9PU3Cr{sCkR=Fo6kz(%#s0`O21~b$Qn*X9@yWA z3}L4N3tl}2I_Ls9)u~oEc*iI_1R3*0;mMf56JT@nYgJx%bI$$;;BHdk34+<~us!dD zUGA{zD0nT>Ru^=E?970JmsfZQGUkbDeL_@(OB;m&ao|24KJI zu<9sy&qy1E0pu?;;NZQY@DOCo6V;v!13Uqi!qAlp13*7>_Pt?vQ!r=9WsoMto4zmr zd#J;zqu|Za%V`(LQ!?P-eMsRU$e1UpJsAdg0xX50I~4|iPH^_UVb~y;>mBx(#nx&{ zFRz}lYH3# z>{N$UN5Pw=yTvY$CuG3ETdeR9WXu!Qo(uy#0hYqBB^3sMj&=6EVK`4P*E#G0Ul@Sh z=CJB0co#_joX4&L($4?)H}QSHevz!P983aJ=^6?Bfct2Bk2r}l0YEOm%o&ZZ>7*2%&pl>?+-Y~o*m{aJdo%lnO;-7qB z05)(~=cw=wl_P}##+sr@ zahWd+z#izZ>L_@}N*jd%f{b~h+LK{`C%{q|#!_JbXtuNO4Z~`|T;Z@^ z@r41{O%AJ$f;S{>6b6uE8F26}S9l0A=80-gh5?=cOJTSu6$XHYoqcZ@J}H>*JM8y; zVF30HhgC!b6ZTPgHv{4DbY43PU*+27vy~+4qLwdBL1GODDyP zzAym$A5O123f@7Yhr$4Ircht5M;~~)t(FkJOP%%kbY4Q&<)PMHw<4B%pVd$e1UpJsAdg0xX5$>QpuW^lN9|8-@dqvnI}! zBdra?zAymW=&2$?a45}6JRL}*H8LD$2t4nFsv5L z6%Omo24FWitU3zbkhD=4K#pa=!Mj}HA;_2~sy*35cmgbi;f6^cXxQ2JhT#UmJn69e zpJo-N^a6Xk!>Xg;-7jqv29OVDz`=V$;UUPFC#pT!LwEu#h2fKvKF|ZszBdfN5X`ZS zRtrsvQ+;6o_Eo1>9R)8ZdMFGa4|J*(4&E${<^hMj$`=M;uX9*+6ug_Ijlux(jtn?>_bWUE8S_N72Z;|n0hYqBClv;O{>s_+ zhT)s=<9*f=O^UmGVF31Nr&k>X??vbfx@m?0dstYL1ZpPG|f%Ul@Qr*2Q_c~|a8-}|D^REtjmM;vze#>FiQSkncv{4v9KAQmt?`4IDAY-1W_GB2~39uA~ zzeq>vK61v7k7cHE*g`TN$z6{mna-=|l{IamJJ1>p)r%>pG z1kJCa5cy$gqwl(dgqdtzRLshJ=!d1vhjf9YqEhCQEl59>VLk`Qkpw|P=e`PtS%T?t z5<~X4XX%72nxD}k63%2>JV_*F>1IKYGJi>D);~;13x-*OX;&dAUvVIdogm{D)A=L0 z62J^y0YSzE(-zZ$``AZ}a-#%^f&)?(15a?$f?<|m+Eob3vrP^T$hgIHaE=idVTOVO zGA@|5m=@f}J|eG>p!=NU;_183)wE!kmE`F@V$xyulB*yQ@a!Z{3x-*O`(m*(OE5i- z7_1Yev*apBOq^_2(}H1^VA|ERU}u(K+Eq-tGo7m-R|qTH)o1H%^GkB1K7xE%Soa zAZmZ4>N`FpI?h&Isej$~lAvFg2#~f`sM0tKY4Y|)pvu8t4}A@jiUCms=nhb zA#xDRu|5$bU=__tpUnO>aauwLy&R7bQ(hg(6nI!`H1S;3No%M zeL+j>>VhsLc3p4*$hfYqNysLTP(XJ{Amf6Y_d&21f)8qkwt$T5>P_iF?5|P54v?Qy z*2bjE>xHpJAz>0Smb0A8F3;uer`i|JH`#V@L^PLMFe zu69o143;S8LB=hl6C9`(b?t)W$bL_Z=iUvZJE`S)(ek2prQ^3k{)b~Fr4AFD$IJ16 zpd2(b&TVKsDV5nt=!~Fp)SfBj;5dt~1pCc-M;XeFqzAiYW&ENX2?BD5`rQo@1D2gY z(Den?6@t89SzACpEG*U)PU7rq3JgK+uYPO+*(fY4i?am|2y%t8LXh!3q*D@oxLf_` z1PK>yO5zM&Qc8l1TS%wm&7v7`s1FvTde1y)Ytt^IQuirQg|N_CogCjZB$c}VELyO; zrDXoOL7`vD010V+wx9Sw3J^;8neUYFTgBfC)$bmV*b>u* z2INkM0=Y|AHoq_VG zOQPfVs;dKJr|RkkiMxx84#LS3R1uzP2BXT_0<%uK)-@{F(IVsq#{yYU)<%#} zpK&Eb(??XQ2PEzoD9J$nP*EE}BKp~`L;Wrl3_<=tS=}Jxy3%8Foe0EkL_k6?V?JCj zQcpN@Lg^t5No{oi`EwCU+?;@YiyG+w3A+giH7*1U#Nm6no%yOHBkuSq13~^!nz9Gv zPHBBav$+Q(bY=^FRs?WqB8woQGh47hdU%Ah2=ZuQSwWo5azKzUzIO}HY4k&oH>$2~ zka1nUe=_FuDbmy-M|yv9=W>fq?R9|Jrs`6;pN6Eag^(T*E&BzpUb@{{ ztohp}?W1a~2jpGC${ylDY5kH4cGW1RlRuZH&&iQD1E8H)XHx7oVPK3|4D`38jbe;p zeA2O!nsx}|Vukd8yi8cxorB;df}-)7Cb!M0@d6f_X&Qorc(xJI9W)9-f*@B4t3LSj z5NN#cqWu|2nBG_YA@ui&e%eETjO$8I!ed1M3S#dl@Zf-S2}loVDeWPoxQB`tV)F@> zz^l&zImg?_B>wX=Eay%+;>WdqAm>RuUiIRgCw{06Kj)UjC%2xb$c_nhU1s?+?bc<$^35wXu6qU$p9 z;{|Vt=E_`In&GF{C4L4}7o^vX*~Fhg@%*K% zZ**!t^9)~3Vh4V|%J`LYE%Q≪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 F{|V)%Kvn<% diff --git a/Program/libcsp/build/csp_server_client b/Program/libcsp/build/csp_server_client deleted file mode 100755 index 45f96799621a694293e9ac4deec4bb086fb9da3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339352 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 Tc5>3Ef6y4Ke?mebaTxr6827!V diff --git a/Program/libcsp/build/examples/csp_arch.c.6.o b/Program/libcsp/build/examples/csp_arch.c.6.o deleted file mode 100755 index cbf77017dbe9257791506ada0a3b05fc87696f75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99912 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 diff --git a/Program/libcsp/build/examples/csp_server_client.c.5.o b/Program/libcsp/build/examples/csp_server_client.c.5.o deleted file mode 100755 index 86acc85168711f49d8f6906eeb6bb085b3daeb50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35520 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 Cx~8H4 diff --git a/Program/libcsp/build/examples/zmqproxy.c.7.o b/Program/libcsp/build/examples/zmqproxy.c.7.o deleted file mode 100755 index 69fe3211ab7a9fd90aa71976c76064da16a92749..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24472 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 diff --git a/Program/libcsp/build/include/csp/csp_autoconfig.h b/Program/libcsp/build/include/csp/csp_autoconfig.h deleted file mode 100755 index 538232e..0000000 --- a/Program/libcsp/build/include/csp/csp_autoconfig.h +++ /dev/null @@ -1,33 +0,0 @@ -/* WARNING! All changes made to this file will be lost! */ - -#ifndef W_INCLUDE_CSP_CSP_AUTOCONFIG_H_WAF -#define W_INCLUDE_CSP_CSP_AUTOCONFIG_H_WAF - -#define GIT_REV "v1.6-9-gbf96d6f" -/* #undef CSP_FREERTOS */ -#define CSP_POSIX 1 -/* #undef CSP_WINDOWS */ -/* #undef CSP_MACOSX */ -#define CSP_HAVE_LIBSOCKETCAN 1 -#define CSP_HAVE_LIBZMQ 1 -#define HAVE_PYTHON3 1 -#define CSP_DEBUG 1 -#define CSP_DEBUG_TIMESTAMP 1 -#define CSP_USE_RDP 1 -#define CSP_USE_RDP_FAST_CLOSE 0 -#define CSP_USE_CRC32 0 -#define CSP_USE_HMAC 1 -#define CSP_USE_XTEA 1 -#define CSP_USE_PROMISC 0 -#define CSP_USE_QOS 0 -#define CSP_USE_DEDUP 0 -#define CSP_USE_EXTERNAL_DEBUG 0 -#define CSP_LOG_LEVEL_DEBUG 1 -#define CSP_LOG_LEVEL_INFO 1 -#define CSP_LOG_LEVEL_WARN 1 -#define CSP_LOG_LEVEL_ERROR 1 -#define CSP_LITTLE_ENDIAN 1 -/* #undef CSP_BIG_ENDIAN */ -#define LIBCSP_VERSION "1.6" - -#endif /* W_INCLUDE_CSP_CSP_AUTOCONFIG_H_WAF */ diff --git a/Program/libcsp/build/libcsp.a b/Program/libcsp/build/libcsp.a deleted file mode 100755 index 09dc115fc4dbe6cdb57405ac8d549618ebf4a867..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 782614 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

    8WiVlHEzQj>Vor0SFl1zS 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

    dnMIB+EiaNqR6?KGtD(XnKTTIg0b>uj=f+9P0 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 X7-rg!ud({7{{`v)x)Nhw&HDcjbL@iw literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/drivers/usart/usart_kiss.c.2.o b/Program/libcsp/build/src/drivers/usart/usart_kiss.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..375b6df1414ec0e660a9458a8c14a4ddfddbd154 GIT binary patch literal 16160 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 JrXo!JzXH53vl{>a literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/drivers/usart/usart_kiss.c.3.o b/Program/libcsp/build/src/drivers/usart/usart_kiss.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..16224a9eb4b2cbdb3ca171845f9f6b10c0a2e6c2 GIT binary patch literal 16168 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 GssBI8RJ3&f literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/drivers/usart/usart_linux.c.2.o b/Program/libcsp/build/src/drivers/usart/usart_linux.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..3356081b82eeb436431ffc9341030d888bc2ae1c GIT binary patch literal 20896 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/drivers/usart/usart_linux.c.3.o b/Program/libcsp/build/src/drivers/usart/usart_linux.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..88c3a47058fa1f24df379a228bb7a208c1bdf591 GIT binary patch literal 20936 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 Vkbqg8;c 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 P|9$fR6=B9X>h=Ez@n5!p literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/interfaces/csp_if_can.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_can.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..7d157060e4578793fe647d5066bf97ce86dae0cc GIT binary patch literal 19856 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.3.o b/Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..5e74a03b2f82865cb4722f282707527a0a5f0be1 GIT binary patch literal 8808 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/interfaces/csp_if_i2c.c.3.o b/Program/libcsp/build/src/interfaces/csp_if_i2c.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..2d659301aa962fc06645f2b34b1167053f3dd286 GIT binary patch literal 13008 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 E4>TbWcmMzZ literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/interfaces/csp_if_kiss.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_kiss.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..416d8b7f4ab04add4190a90a83e3ee11e1071c41 GIT binary patch literal 17240 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 N{QtgCV_wzv{|jDr_o)B? literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/interfaces/csp_if_lo.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_lo.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..9f44b99d898b5e159f5c17d06e51719fa81119b4 GIT binary patch literal 10560 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..b7c8b66b60a7fa0c0df5230bfc1bc7355aeb3c78 GIT binary patch literal 29712 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 SFb*aEDcS#~Qe$6D`Tqs2cPAhK literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.3.o b/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..fccc13b31c8648d70b51be46da7eed3d99b41aae GIT binary patch literal 29744 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/rtable/csp_rtable.c.2.o b/Program/libcsp/build/src/rtable/csp_rtable.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..df517306993c9281af206aab75dc41266751ec50 GIT binary patch literal 26704 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 YlpEcVd%H%HFY_yT-hZWPBXjM40bWP~c>n+a literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/rtable/csp_rtable.c.3.o b/Program/libcsp/build/src/rtable/csp_rtable.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..3f84441633da04320e984cedf4296109deb282be GIT binary patch literal 26736 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/rtable/csp_rtable_static.c.2.o b/Program/libcsp/build/src/rtable/csp_rtable_static.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..8dafae52df3bbdad6861206b70e5208835db5379 GIT binary patch literal 13192 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/rtable/csp_rtable_static.c.3.o b/Program/libcsp/build/src/rtable/csp_rtable_static.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..b331b10f991fb422a6042850cc2235532afe7384 GIT binary patch literal 13200 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 HShwGQdekFY literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/transport/csp_udp.c.2.o b/Program/libcsp/build/src/transport/csp_udp.c.2.o new file mode 100755 index 0000000000000000000000000000000000000000..0fdff41c8321c8a3623246fe36cf68ce8e68eb34 GIT binary patch literal 11968 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 BrTqW^ literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/src/transport/csp_udp.c.3.o b/Program/libcsp/build/src/transport/csp_udp.c.3.o new file mode 100755 index 0000000000000000000000000000000000000000..11591156184a1ab078dacf1dd1b6c77b44a1215b GIT binary patch literal 11984 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 af4+!JRpI`l&V~A)Ap5^n)fY+L|9=5K*{-nw literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/zmqproxy b/Program/libcsp/build/zmqproxy new file mode 100755 index 0000000000000000000000000000000000000000..c06b40dcf643963ed1d79dae959c935fa31a4feb GIT binary patch literal 38720 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 J2_&K7{{tHUg-ZYc literal 0 HcmV?d00001 diff --git a/Program/libcsp/doc/basic.rst b/Program/libcsp/doc/basic.rst new file mode 100755 index 0000000..70ad741 --- /dev/null +++ b/Program/libcsp/doc/basic.rst @@ -0,0 +1,153 @@ +The basics of CSP +================= + +The following diagram shows a conceptual overview of the different blocks in CSP. The shown inferface is CAN (src/interfaces/csp_if_can.c, driver: src/drivers/can/can_socketcan.c). + +.. code-block:: none + + buffer connection send read/accept + ^ | | ^ + | | v | + | +-----------------+ | +----------------+ +-------------------+ + | | connection pool | | | CSP Core | | csp_task_router() | + | | csp_conn.c |<--+---->| * routing |<---| csp_route.c | + | +-----------------+ | * crypt | +-------------------+ + | | * UDP/RDP | ^ + | csp_route_t | * CRC32 | | + v +------------>| | +----------------+ + +--------------+ | | | | incoming queue | + | buffer pool | | | | | qfifo.c | + | csp_buffer.c | +-------------+ +----------------+ +----------------+ + +--------------+ |routing table| | ^ + ^ | rtable.c | v | + | +-------------+ +------------------------------------+ + | | (next_hop) | + | | CAN interface (csp_if_can.c) | + +------------------------------>| csp_can_rx() | + +------------------------------------+ + | CAN frame (8 bytes) ^ + v | + csp_can_tx_frame() socketcan_rx_thread() + (drivers/can/can_socketcan.c) + + +Buffer +------ + +All buffers are allocated once during initialization of CSP, after this the buffer system is entirely self-contained. All allocated elements are of the same size, so the buffer size must be chosen to be able to handle the maximum possible packet length. The buffer pool uses a queue to store pointers to free buffer elements. First of all, this gives a very quick method to get the next free element since the dequeue is an O(1) operation. Furthermore, since the queue is a protected operating system primitive, it can be accessed from both task-context and interrupt-context. The `csp_buffer_get()` version is for task-context and `csp_buffer_get_isr()` is for interrupt-context. Using fixed size buffer elements that are preallocated is again a question of speed and safety. + +Definition of a buffer element `csp_packet_t`: + +.. literalinclude:: ../include/csp/csp_types.h + :language: c + :start-after: //doc-begin:csp_packet_t + :end-before: //doc-end:csp_packet_t + +A basic concept in the buffer system is called Zero-Copy. This means that from userspace to the kernel-driver, the buffer is never copied from one buffer to another. This is a big deal for a small microprocessor, where a call to `memcpy()` can be very expensive. +This is achieved by a number of `padding` bytes in the buffer, allowing for a header to be prepended at the lower layers without copying the actual payload. This also means that there is a strict contract between the layers, which data can be modified and where. + +The padding bytes are used by the I2C interface, where the `csp_packet_t` will be casted to a `csp_i2c_frame_t`, when the interface calls the driver Tx function `csp_i2c_driver_tx_t`: + +.. literalinclude:: ../include/csp/interfaces/csp_if_i2c.h + :language: c + :start-after: //doc-begin:csp_i2c_frame_t + :end-before: //doc-end:csp_i2c_frame_t + + +Connection +---------- + +CSP supports both connection-less and connection-oriented connections. See more about protocols in :ref:`layer4`. + +During initialization libcsp allocates the configured number of connections. The required number of connections depends on the application. Here is a list functions, that will allocate a connection from the connection pool: + + - client connection, call to `csp_connect()` + - server socket for listening `csp_socket()` + - server accepting an incmoing connection `csp_accept()` + +An applications receive queue is located on the connection and is also allocated once during initialization. The length of the queue is the same for all queues, and specified in the configuration. + + +Send +---- + +The data flow from the application to the driver, can basically be broken down into following steps: + + 1. if using connection-oriented communication, establish a connection> `csp_connect()`, `csp_accept()` + 2. get packet from the buffer pool: `csp_buffer_get()` + 3. add payload data to the packet + 4. send packet, e.g. `csp_send()`, `csp_sendto()` + 5. CSP looks up the destination route, using the routing table, and calls `nexthop()` on the resolved interface. + 6. The interface (in this case the CAN interface), splits the packet into a number of CAN frames (8 bytes) and forwards them to the driver. + + +Receive +------- + +The data flow from the driver to the application, can basically be broken down into following steps: + + 1. the driver layer forwards the raw data frames to the interface, in this case CAN frames + 2. the interface will aquire a free buffer (e.g. `csp_buffer_get_isr()`) for assembling the CAN frames into a complete packet + 3. once the interface has successfully assembled a packet, the packet is queued for routing - primarily to decouple the interface, e.g. if the interfacec/drivers uses interrupt (ISR). + 4. the router picks up the packet from the incoming queue and routes it on - this can either to a local destination, or another interface. + 5. the application waits for new packets at its Rx queue, by calling `csp_read()` or `csp_accept` in case it is a server socket. + 6. the application can now process the packet, and either send it using e.g. `csp_send()`, or free the packet using `csp_buffer_free()`. + + +Routing table +------------- + +When a packet is routed, the destination address is looked up in the routing table, which results in a `csp_route_t` record. The record contains the inteface (`csp_iface_t`) the packet is to be send on, and an optional `via` address. The `via` address is used, when the sender cannot direcly reach the receiver on one of its connected networks, e.g. sending a packet from the satellite to the ground - the radio will be the `via` address. + +CSP comes with 2 routing table implementations (selected at compile time). + + - static: supports a one-to-one mapping, meaning routes must be configured per destination address or a single `default` address. The `default` address is used, in case there are no routes set for the specific destination address. + The `static` routing table has the fastest lookup, but requires more setup. + + - cidr (Classless Inter-Domain Routing): supports a one-to-many mapping, meaning routes can be configued for a range of destianation addresses. + The `cidr` is a bit slower for lookup, but simple to setup. + +Routes can be configured using text strings in the format: + +

  3. kXt-fWJ|?Myb&HcRtxc&s?X;;eLR?x3*K{?*0OoUrhCp6^LVSTk9h+?e`=QC5?>3w0*|e-5Mk-ahFGDX(-0&bSiJHZ3 zN~9|z7OBfN$G(lP1hvOjH=;$dATS5#D)fz&Ca1TId+t|_eYkXm^`p_w&Uc%fuY)tT zRe5HeVBY+Ycr4xAJH!RK9A;|A%2&n`|6{`gsu9P^)}+tf2NxE^#yx+t#{=wEhxL?R z<}!=5=k3_%+Jad7Eghd`y_Du3Yy70zh*LHfB(a^XhO~D z$Rw-p-dAKQiwnydjRk+D1ygd~j5;!+X6>EnaQyTxv#=K%PnaCXYmOB5A11qfu=5u7 zA|kVuWs?{v<9bTobP%qu*!eMAQW}j#jX!p{#P;26vX82J7z!i9OyWmzluUV!Fq61H zAc!XA2EwEvA8$WecTvBwz0P| z=85nX>BD=KkZ$p(_r8kSe`Y{>Ii#2A_85^6Q?%MQJ;oiBQujp;_qD1o!Wq-|MVeQh z{efy=kBb93BjwI*78`83zgPnH14R|pU)S=IrMSM0qw8-7FIsr=M7z}bUJhm$xvzjl zqbk~U($ezq4EHZd3x4;wB8uwESQPy>r1s11oGyuCitVIh;TN(^Hlub&=$0?fV!1Ce zW6Sr!3%?YL6=+hhkFNA9A$cp|10EwEw=S_GD1hh!2cMs5VAm^E-%7 zVf-R8!ZsC&u4Oc&a_3YIduVX7d%Y+clP))jK#2XaN3DN16BuJOA|Tms6P+ou2o0mS zqT!Fx_0@9NBcpx}9>rdVXTKtl+j2IB!-vX=a(EmG4!PRd({w8+HK;5a^g*=?#wo&B zBFFDZaZ{x*uRRtXHD(X}d(^rgnVz=(6u;B4)D>0R*bYe?$cTUUp3LAWvEhziPq0ge z9XeYMv)}F`88(DiQraKha;QW5?|NE(3%0c1?#<33cIc9h`U4*s0e&T2KLufkqFsU% z_c2_8?r192JFs>2a{rF%Q{Pv%K9iL&Pw=tsIG$8CvngDr`Ks}VsD^tRiyB*uGugc) ziynRH{`g`AXHK7Z)7tZfyO&%h$1U;4<`sZIdZh{#EEv*B%j!PqoO*15(uxT z^?TC?ZJkZojugq{>K3B|>zJNKcXEh%jwGmWWBn-Z;`*)wW0a!}S9=_T_RHOchh?U> zvy90pQr}F{iCTXa3)F8#tvi z+bYd%z8U6`G&$HR9;@=_+8LRsEWAXX_}cu^R2p@-e!J`g;S>a+tRlj3e9Lp3AM0i8g*k%b6WV0B$a%MyP{ijM@~7^zGkmI z8R~kHYj*==#QECLVI*iCkYmd4wb~kzOsG!}?|XdF53UQ@m4veX15-l|t3=NE2iOo6 znr?08x*~RFo6H*(b5^HhKbM|eiC#J)e5kU8Y1l$_SdeWQOVUWiiK_00r`lSuJ*~ZE zds?u?orY!y7uBY9VB)m~PdVc-~@~ZlD)P56!HWi`I>%TDGMetnQXEu#j*=}pxaF=u`U%QiO zcHeQ=ky_hwT-$WcN=E&nP@|PXvERp3s4LTJnGYH$Hbl*t8Vkhy$fQ)%`iXWX!ki&o zdqYDVVMn!+Z!=X(bhT*$#>7-F@4U5Grk@y$wROIR>(ku_GwX{HNpZ9>_)fe6(TCA$ zKkTo@F7oHux$$>?qZY~DGzyc+IlR&C-;7!4RZ%U=qf#n{$7hPia%Q6%9(OwMv08l+ zRF?yvpji%&%n$LV`VKj`$I22rL&8(Iz3QFnfsUn}Vi%lfWZ@51omAxJa~7O9;EGhw zsz#f`)$muf&hIlkuX^@0uTvO_!-dt~bHmFSjr>g*Fx!nGFeDltq_q?9!s@r-qLn^kr1t^)v*MuD^Ux)ldhwVS1|1 zzyR(@9%weop#ti&2iBgjI;U24syz`DRo4Wn_C#=0U032Zzc{qf^#YbV-Qqf1jP_C5 z!DVEYcJRhu$dWrb-3)CHQ>wz!eCv*6#g=zzh1-*ptg5>jig3V5pRE3G4#rbBgd%Hv zS5skJ7F~TwX8qiBj3isp9Q8LxGE+XHgYktV1D?C_+#@25@zf(WjGgF-O$*>9K};B- zsK$-x0|p1*h-}PQFgMBKY)|r*rXT*m(r4q(ag}bR)m=4oNy-_KO$WdZ{lwLYOwfI# zvo+K`YUuWqpvVKwU50+_I`b4fMokr|=^=^P7`5mgAUH{{se$JfLwi|ZUOY5lxrN&c-}r1h$1+zjmaWB1~1hxnFpDY7$!yQ&rK7 z3n1d^OuOvZ^S3Py{V-p?RNB@-8L86vn~otYvvsLowFV-#$<&d~&p=&NpJrpf7zYrv zbsDsXD!yHev5jSjS0LdAk?vH2Tve_;L(}S{*SDiBwqf8#Hx$~7>SuOPjdMvd*7_^s zEi{|0Vsw%3u`wkgy>@FTJDDy5ODH=7uDyeL{dSIQcI-f!GQr%#$VDz}ZTL*}3H`qt zhBUc|=W8`?nWEJ1pz#G3bdq@!1gFbP<7jp)r%pi1#P%zpbP3XVoNH=QclJ3gPXg7@ z|1n9RVOS$zV-8hktRjsJ=AG3Bx9^QPNQHST_AP}Lxy?L2V>}O%JPw0f2JS=_eAb&8 zRoQ%jay8dWdJ!;VITzPzw#-|{3J3PoMAbErlsD>PqB_)pRsRflrLdUUP;=7Ay&Vl# z+w#-}2cIo5Svbddqt7F{KjI*Xc$uXAPlVJk%9GJB9*b4ML7q2oGWzcQ>CxKekPOUG z7S1Hi?b;4T|K-xEzc*gK4M%PdNTGHp+bplJc_*shmYQMuMP1QgR7eJ7@|l~ir63k5$S$)WNoG1(Qjq&p6fud$ zFkh4ym8-W9^v1W$C>_lx2}Efs#8QawJQ6dKmTCPmW6(FwO4!7_DApF&@RcxOSBA1- zCZ&9}!fCI`Y1?2`$RAQX+~sPNA2Y5l=|O&(R7} z!~_1rD3WGtrgN^4e`JzRHp#;!$IqGMjBSn@SNO@lA#CFTlRUvBj}-DcA?L<(<8kVV zJ>F7;Mxp)Gq_vo|U4%AQv96+`hrP9kCF;J78FDD+!;N<4kc|^~hdOUJ3xm&02Ac;d z8AJ$!vxPzJwk+v`-&i5f^J3{X=s-CwlkSf385Z+&6An%Wm)5#>B`smqC+UwJ&d3cS zcInY0n>m7~{Fd-cHwOY7Ss7ewyw&(w)Qz57T@J<2Slw~5Kl_!6vr+q#v^!4KA5uI@ z8ILjz<23)Qq(E@)uLCCH>S8|t$8^XU`C@x5hQ)$ z%6d|-zhA|~qv)oljTs>Ru?+meS0!PuBdmG_HsoYbdMl$=wjVGCW&n5GBR8Y;pG)1V z7E2DI(2{03rgTF9@&uLpw3SZ6@0hT!NBk0cx&D{Xm#JnxFrY{&auXlPrL(&6hFhxZ z8EaG>vjH+%4Clyf&*_(lctg)79T^*CGO+KI8I{WM<=;b{y|75PT!yR9pzB3BKdda# zEAqsY2>JYK3Hc1g(ds0z$KcbI#&Yk+agXx?qMjgXt7w=$qCM@6cE0!*$RnAW3B5}+ z54$(o{h4X;;*X^V4^bXsMt#_LPoiTYdzv_1%O5xxvtU8B+ZQ#~gbkrq=0$MH3kuDj zD{u&5Rk}4f{27X!qlWICRJAOTe^Mxv3TruXhv||NNeevol&F+FQ7K0p4Z{x&{j@ql zMkQe!aS5#^&0+g)v0GFxzksn`j_Tn#v$1XqM)UlOIfWLSUOyO>d}kuUVh3sGQq_+7 zze#H#0qUE}?ZQc1@gN5=TxBAgl#UX1qUixbwvFe?E~#AI$!5#-{;c!4T`Sa5TtL01 z?nH_oNl`dU#?5Hr1lJxqlJ5Q}J^s~n+=25&JPoN&qZmV_J-WZz9?}iKDZkWJMv`bJ zF&7<(s&mu8&=KTLBMsQN$ttNeYVk}$GaJUQ&1{(eL}o+bidSU0>%=+<5pzN+GA;XD;<{jfqMWX(Aq5m&vE%RM&&JliQQW!sB zsky7t)qY3n+E6r&+bSFSA5e6DqPG=MkSkgf?MQvXBeWsgQ(r_kzuKO0j}R=1_Nyq(-7;0`vm=Xj)J6 zwYBqCSX_ez1mTXu1JInJO2yjo%qClPG_3^1Q0a!Ve~USGBI)#y=pu!yrucg-ttnLQ4j2Z%1Ak z63V!jSzvy=8fvylx{rpvf~k&uNR zxYu_* zE-oC?{;n9=hTdHXWTi~q^22o&^Epdq&Ur-Fp0vBZYi2Opv{5wH+=T4eSJ&t|$N`4h zVF&TJEzWZtxpX9%=tM)ux51blL*Ko9k9rR2p^dqGC54kqaEw*7aE7b3uZ7A5INjww z{}&|zZcJc1;#twPjX28Op^C5B$X_q`9l=zlRT;NB!j>N5&#u%s>gv9^6FiN{ zb<`JAGqP^?EvHOyn~HX%V(Z0SEx@wUbYwHG9C_L?-_&>Mq9O(eiFqpGqQ$}ke;AEw zp34O8AI9^r<-vpd%S5*E7_aIvm^<>hL;0O!TTTQq3(5@;4Uvn;2fKtqVy$~?4;^p6 zGi6Cr`#rUvS)tqVS#a&4qgze{L)d<2`#p}MuW{~^qeLl^-q>25JvA8}ZSIR6jqNge zN{(1_m8QTyAjl3d<1^YKo)1%(^Z0|ZVDie1dQnMB=h~KzimK0!C_kJ*)2?YMyd^avnlMn*kGohT^)?S(Y)2W zRp!q-7@Qf$d~RUF=`!00)9mf6v{l7B>u?+Lh;eW%$-Fp#YRb;9U@6@ zomB|~WO$O+yWs?dYCfB)sXY|rjA9aN?m**n2;9jz;z(dxFi-uwUQUdecI#Oa?DPp^p?_>ZN!>`N*{QaYMXk@`pEaD(tf7qWKn>kwEqdo` z>gI3)WejCkk0DDso8ri=|v{oX0jpV7$79yo3;|iEl9Q7mOWJ;$qx}6k0 zJAtm2Q~k7UT;2NKiDcI~bH|7{hTsSBJu3B`wLwaPaNo7o$}j(-!Mz|P zIZn*)N5+SwaLski33YqbU%$orGvt;0dMI`z$5A9E!V={Fkhn0xFb%65H}Fmpx6nU! zeK5%yRrfiu(ra(7p(QYtw@==bq3G;hU?j=c>Dx*gdPu#2$EB7Y$ z8Hr76Be5KRVmG&$*dydxC3dkSb}w3dj6hX>#xEzu2 z3J@1P^k1_j%Qtfpq_~Ii)O?R8{xzoXtc`Kw{FI(BZNceNN;|UAd`|7$xDc0}dwPQ97S$+sS8}I^ z=Le0&_&81BU_=!#5MqSBH5%tBBNU!8gbA*whP$n1I2wN4O=5wL8s8xgRD~`DXA527 z(xm#(hpNpiMb#Bb4F1`WYz1WM_)R1>k|0r~l=``e3{RsY%>KeC#kLlu3_3O^7furu zC$w%TR%BG7Ns_`MXrz%MHkffvv|KR3>{I_iBmz|{6>K0av%fnFr>N;orR~Jx)}r9y zAtHx0pfc-+edEF#UT`yM#p;}VF6OPF|C#XRoR#EXIx9@UAb3WtpWDyagM7?RJ+r=m zF7;_|V$$b_7|+Zlm}^Jy9=tb?j6q(k9;oB93|^Ez(ZYI?GTT<=Hm>&*Tgd7yBFH@F zcwc|s`Exonk^R;iv16Xsny&kUfy3OmVAm-B%{Xh&8ZLEAWO}+GCE8OoB)LzGR81JA zR5o3bTB?)M#hOl1%EHA{EU8fG^L*_iRzh1DXy2IaXJw?*TbLVen2K7ThLbigHim93 zOe%POu(1p~Do<7fml|x$7qeP_UYU~)2ZVLOTx#H2RRbth4u5I1o+~6>mim!#DGd`( zI+pz4SaL*p2;wP>nO1oVyzz^7ghHW)p~SGh%-WV)(3kUIj^3$Xz$YGP**}-qpFl|h%Y<8w4?@l1;mPH zj3w%>ZB3Q!WpyLO6<iOP0VP^JH6qRt_qiXffR|CcwKbahyoWYRt zH1rP&h<7jXng=fUEM#f0Gld!w$M^R>N-xyX!Hr(Ns$TmZ_49r4M@f-}&t)sQ#svtj z>24f1xtQ~7m>h*kRNX`{O&R>ue#TN-{e0_!;~~!EqCxWqIAi2^z9K!MNE3wge14?3 zQFWtug3TXhUc4=$S&~U4h(jFx>Rm$}?vtE78IaPD#Q0}dO8l18_-)oLbO|3;O;gsP z2f-B*46hF*o%Oo|+UEVRQ&OwFIgYEBebuCE&v@?#e|RvnZWOQyS7ej`$Of_~S*XgWjn+i*iQQ%_D-tv(tLC>1W!eEOIWYmD(RN z`mz8?tWlD<0NSQb{HPL$@qMPH6uzA86@7h8%#I|b5waxSPX=(T6B)6ze5U@TzGcZ& zB+Zt1#r!prZ+eNJ^c}-v$bnKo=H+Ngo<pQn48j|Ty6raM53zXea{0g0B|X2hs}jWx5~wQvVsg~i z(-cdeB$||{YTi5Oa3&zvo25(cj~8&F*L7xK!SAE_Heasl@j|mWFN&dT=)b(T z=pv4Sub+sf6rziX#!5T`4}xua9Ko2q&$80zP_(GJe#*moc>&^=8R^7K zcR_5NT&FdlO4U$E3Y8I(ZXWK4y6s7+riRY%(0R(DNgmZmm7K4t6u)3J$nkB&E|@|4O-iH^W2VWW{WvT&1!Zm^l67e;@0sbztp)FH)I*ZE2wOau0h zY(Z>vlr&@c--sp$ne(O1R5lriAp^$A8&s})D-JPUgZ4>+HqIErU6e~TX=67P))b=L zR1C6l>k(enAF|1&sqc-|NSRUMqR*8Wpw3>$Jsq&<{K*O(&R73&viAF`&7WwlcFdB{(O&0|G=ms6GitvCTs z6-4b*@q@OwE>mR}t1!4F>264+!6i!Rw&H;mc~bi|4GxrK=XWbrR%P7%bOpKTLnvp( z3^I#_7UO)5us56M4=j5`)omrLY2FDmQtTZz7i-t2q0<0ILz1UqjwgN(wqks6Jb&x- zt|NXMruSe~qLP4{h*9geD61E>{&mwV9wFcL@qU?fCDYB*g>^qJyFN;PFWFb#iZSsU z!qVWSdZpWC5k@QL7fK1KGlr(@yoyo#a*gl2)|@u57mDT%>J*K!AAH{f;usI5@h$m4 zoFo>2{0mVoVORTVx_1>yE?N(5ya69yEi*V?mOfmKy4)j%)`vb!hOB}oC=Q2=&!s{WI!Vr3cRA~RxC-9s=Ta=Vt1Ul3JaOpr`eI6QAT`wG1tL;b3> z(KiToL(9aE<7E+$F&WV{rD2B6lQ`lXg_^w0{T~nqKS1dYF7>M??MCIF#kK8LjT$Wip0;ly$XdfpPPLu_a{_t-lig7 zK8A3b-Y4^VL?;srYE(C9=bY&QdEKpxjhi9E)V~lH`HJcIn=)gZ_#YKVs?POI<#01q z@^__@b9hG(ubCWF(%D3B$^$Q}z*7vbLb=W|bISfb(co{0(M-R~Xn5-^H7pkAKG=AH zmj$COa`%^27(7<07;pkS-5nC^y1-xDcLLHpSVnt!%hU9=RMd1bAoJETGbEeWn9Oz` zHg}R5T~vXb=E*W;OP&j0vkEpc74-726wc@>oyICSYEhNRIFxR;u!G@&jf_PxR)+B- zFWBXMj5t%4rdk>*Pa-bW=}j0XQ`6(KWZX%JOj1+ya#B>oPsW=FL*}Ik^i5EoC7EEj zS>#FX!(YvGRV9w9>x1T*qI1S!g}cZrPMyp}by9Ot>K3PUh>ytrzfAJYEz95qg&J09 z_m)SRR)#7)e` zjbEjO3rQIydVXP=5JVYY_7Jd?ure@=co|6P7NKFDv1J9LEt9o+!6 z7d5;-^bQGcC!1q=Ss*W5m%UeB%H<_U?(OI0I(e~jzTerN|K;Gt;pXu9E_oZG-mHpY zUu6wO42@bhHlco^EP(W;s9C7q*hGe#GKN>Pc18y&uPl_yUf-W2mdv4q8+&JpU7gb_ zy*~7+e5P@j*~DY-e>q%KgMFBAncuz``^=4pc;8H4a#)K|M21=s#cThRHibVUQ$Z)E z%Ty2+Q!HR4OuTc3lY|dmYq$|ji)ij>a?&?OE2Z2f`XGbo+E>Hn`E;M2Rra!Sr@hKm zQBhv$EG)41=H2e9Dy*~@xytgLCFN!IszRraMSfMq)T%jEQ>%(y&VusUW!?ZUzOrz7 zdAZXv+T|>)v6qyUI0xH%R#+zHnGben$*jV1m($+UWyvm_l~++*URmfT%POxj>3dcU zwio4GG=Kl{dY#&`xQx#%5>aT68{(^GcnTb0_z74e9BcC1p9kyS>K+7smE%T`q5Vr@E?2 z%4ST}(JdBlxm$%JB4?p6^oE-eTF3sAa2-3NtipvnvMckESAso-(kLi3rJk~VPg#{E z3X@ivH>1j)Skp7{vfKoFcFB!}pe^GNxm2i6qE&@u1(xCCGEzpQTGISjXC925NX{}M zHD|Eh;iL=|V9M=zrKRQhdCo$f%k8Ckl`{(M1$oXqdzG1j{Yv|+yc$VLMI1{FmlxTm zyNZemE2~Uga(QK?3uejLSvmm4u=f}y>Y*Y5)5fKy4z`ak%PTFJA=Ml}TTxz8CS~wZ zWt3Gzc6yrODg$J`vM{e;j=iX|5OH{u(Sc;5q)ZgvK79@aP^w?0a{}$ST>A~KLYKs& zL6nx-XO}pOg{}nIR9PIRT%?s0m6JP{J-@uHtWdR^DlKrO1Jg^&rdAcsnwn2moP}|{ zglsA@of&^Rsw%1AmSmMRQ_Tzwvx{!2XD`aLBiPv#u-Oab0w2O8?JStuOrHzJ9jgimX@PuX^{NJ#V#p2Gl*W;?>m;-g@sN z-M%TF`2D82Ii>HrH;12h?WX$bf2P;;+BE9q=rNz(_Oktxj{En<|FL+>#q+@WDond75!53iXz>dT(}UbH#>nALIXT@N1b``WS-&pvh2 zGa3I%eD?JvThj)8@J{N+=PrEe(>cFBdF`2@*E}`6%cS1%U)*%Y;EnVDa&@{p&pLVO z=hy!|Z}IB+(?j35edW>n?!U`*q-@i9a~+!>h<_5(b`l5K(@Ha;6s z{O;$%Yk&Xs@PMf4cW%$ii+=LXyZ-h2f|b)&R?ZKZvgW2+ugF>IoH4@vYvc=0zR|t; zsdVQ#lU|DLaLvH6$DWbl`~LH8>^i`6hVjXL2Znwc^Yq&nHy`>WzPSF< znjuGTnY-by6}OLiD}UL}HFwN-qBOPO(st{Ye?0NgJEsnvus;9N@aGSuoJcyWQ&aNt zo6lYQ^9#ElpZ)2usdcyYnbPjdkI(*X?O!_GylvW{Wp`HnE9%(7@R^s5k1($Jo9Ep2 z&;Pb+dfEq%-Vk%(qOMK3=EV!%Dctzb#=FOi`?_xQI}58zzWqzw^<~FDdf=~r-}Tq?w+^YkG5mYi z@%-}^cDUSji#zwXU6q}mef@`O=d#yxsL)(HFP&xa;{97j!vT6n62O z14IA*x7UA|^y`N|et7>S=e#_@)Ah<>9lv{P*7@I#3H#>NUJcuJJa)M6iWQ6AOGy#ch^qe&|}IS#${8_tZjV0I-}G2UoJSD99H>D(xP+P6};Htni+%h9=~%} z-wn%0P8vD4&+-Rqo;+E)?7GKqzWtNNhOTQ9|8>qKlh63}gNUH-CQmyOdeuK-!!~W% z|Kr#@Ui;zA6IZ-Fi(`1*{hr*?f2GiBJ>>0_^4apB9Z^0J?* zzX`S8(tZ4y3-7=3(DlcD?pHGR!R>!tvirRUA|AbH;}z@Yy!iab^`l2DTQ%m@udaV= zb?;Z!T$q+QZcmq~S7*$GRLaIh#ib@n&&ngoz9=Bu0Y9O^+diLpC)HC1Gvv=RbD!a1= z;>7+gd!_fmSySjk>8Fkzi0AzjRF+q0f;^YA7^g?S6;{ORe)>WrkbTPAqI040ZP8_fsTqTu-Ri?H6k1V>kzt-%^E5x-l z-6NclsRgjjciQvmvFJ5aCp%_*W~RL&Pg0kTsZyL6@kNSFFOjl|pEIx~-ZFMP-b%LW z9#YKT3I(!FkR=^+f<3L&?-<<(#y%m#fh4Mskt^PkKH8CN&#R~)GrC9a5!k(n$D}i3 z=1%oj|A_?p*t6k*^Qhwcy1YtDZceJho?4b)IY-IFm%3MCA`>aMawTD58CO_QI>%mG zST@6SMG9*wkR4*f|2nn)#-(I=Gme+y@7a5o7FJc+&FW|)TI-J7tcd@lz^ZcbdkO~Q zVVTaF&tEMsqXhDXlT=wg%bwUT%(++g2JLaSE(}|-=xs)cj3j)Dk;N% z5K$@?mMrBE7uZXxd=84~(^-a-ywGW_!-+$XIu|N`Wref7()lyp6S<#`OgW}SdHIEw z)N$j+jvH(jcUuxI5&zwumXS7Aa+ZcV_pztYkSkQqm16fXYd@v1b?w_zN~-enDplrn z8yHuZUszI2HJk4~HB$Oh=+ht4I3=pC%)-i&q7vMAaaYw4sz)2NZ6))cxA#7FM}B@G z3N4jnwqe!6s{gn1AT35%v{k;g@+|bC`^EVFg_Ui^${3UN|G{in#32rBM0%hgqXe;6 zvt(%NZ*HijcNA(Fmvic{OPRMyHTqJ6T627>bQEVheP4-qr@gSO+%==vKC6)Y&9PW|J?inubz7_XHgFro3cefo z?&jN%uz&LXhVM<>3Gxu%*ZC@@jL@WjmC6>Cl^4iBvkzTLRyIR!^)}efYnqI?Mytf^ zbRarN+5-)K`W$DWbe3ZZowLg;XPP?M(Tt-9kEcX}d^~D3i?MuBD|W(4CINaD43?Pz zG1*dllBM12k*Z1HQiBSwRhoq%%$vddLPG(j-30Nd&UTGWI6T34@jo_q%@(vSK0bAx@;!@nAiaus~ zlHoRz5VZYLe$2k!{8gPwQ3Vqk`PEa4DwMv#32mcOW`1WXijrS3hw@MES#|AT>N~F> z&YKxM`yv9j_pI{KjDyBB(G{hI^x4UdF<5#06f#Lxp_O?X-D#;@DMj$bFYwzhEb67> za>iYnot9>@@Da_fWCZ?aIUz+$#+Zy8ay8gqP*`1(PpVP?`mYjaB_mTa6BYD5BqlFD z#%5R1lCx@z{sOk-SW=$vEIlo~bb_ZPKuIK7oTAf`NoD2dl}*hnD46Q&b=rvGFHD8A zSZb{G1cBdH_zUGD%`3|wciK^_iOf*>=S!#OxeByG znO4F-%O*K#rG4JnN)h{DyMH1^tVEvESy{py3GOxhb4wj-8820)KkY@OuBu`&aQ~iE zSrPhui0P4-nsp}pX)IS2vw%}8Yg7(JyltzH@<`QWmVI0eqXSVh?Y0FrH-E;>YV&gU z)}W!Yl3ns;X0MEkNpyRda5HOb==hKj7h2S_F=>9i89Nl>}r+w zDTis!Dki6$YMK*QTbZfeKC5NN`xJ9(8ZI5(U!60kPRX0uiK+30GrwZ+rI(Tl_Lr=r zj~{L+sH~Q6?<;kk_|>z*H9gK*6YsTIRlHXEUn^_uMJ1)ohN41nQ!I$VbTTDHr!vQ0WAaY0_tnDr4;jd?Ey11`5Lr7xaV;~N zVApw`N>`(%cmFI(U~YZStz#*1x0+;C31V4hv;3f#%kUyQb+jWZeeAf@sbfc}?yjYN z3m;RTrpin>?L=y*MEv_cWvUOmERm1GQ_KW=FGb+9PP!0YBNf0-Ddp^`!o-*PDjJ$8 zZyh0kUQNU+AH!6C?;~|iV@RNV_H;3N1(?>v>wPFsa7NA_%VnJELN?j#`;lRyC`{sVb?J(8d+wAxkK_ zDC=5kebASMiFq>%?K$-LVo%~)WV6cOfP4dTijs{4{?D`_^w>AJWx!!-X9`Q$=HS%d zeA*;bYOESHbtDVlt?S5F2#F4R~zrH=81wNxRP`1K|| zue7MQ@|y#iRgp9|Wx5K)blGw4F))5L^fAuR(~M?4(0ol9QfpPtQ-~ytK7gvkK1$uu zKS^`w;ir@-4zXedu8LBbH!D;O&5{O?=~TUSYcF%n!tv^XT;cAtPiJUA7jFlRR zsD8#5MRhu|$Sae#h5yb@2bd{@ChPS6w%b^d=VCi}R|PXEsTFwD2i@Dy0I&oK;;W)o!$)+Eo_hjB@#bK8UR`Hl~?expGWZGL=kqW z=%8wJefsoiK^Txo3lq?0J1=0eNY*hDR4d2-p{t@tg)=TE$@w@3aHUvcqu9q|+6`tl zs%dL^MY37MYb+Fl0Qt0R9_Fyk$J`XHZW-c)nF7>?Oqz?bPjNj9{AMdq9@^BpD(D>8 zR8okH3aM(n4$;y-$)Qh{o}s{{?2J(T@8m=LCuP5Uk^j`ql_dQ6_K#Tg3_+oHal!Pv z0{N-=Y}0q9FO=R!#A><`rvK@q&eo+B<^4a``zOongJ_}TMLACX_U|v4jJitLDa1}F z_TQL0&U_j5lj-d%7$U_pxpWW4)9gre&ENz1HdD|L%@*s7R#5w7~rqK1mJJLB%m$J z4y1xy0Y0_FnW0G0xmj3*z!JAtnPBPVz~ zUjVNM{st@uMn_sK8-Q^@wpnm zW&@W2f0^v@d;lCW1vvtD1MN2CaV_!!o;95{8(J7Gw?THr)Z1in;GmX1*R6058zF}c|a?hbXNe612+L@UGMSi17@-d z^&4O=&~k>wQVi?_9LTQV9AE`-9&jFz>-R1112+Mq*me8?P<9`G16&F0bf(4fX&G_{ z&MGIrz>UBKz_k?~&lA8yzz={sZXn;lcYxt%k>4uP1C9k211A9I0jC3(17`vs1y%qz z0DlD@0m_kvX`L*V^MFp^2;dUnL%`>OS5#9!z~R6nz`g8J@75VP0uzBJfGNO^oOGE2 zyc4(#xC*!$_*dZbz=wf5fsX<|20jiv0(=q}(#2wV78nD30hj>X2uuRL49o#;1{MRi z0_Oo=1uh5f06q%b1>6993-~5*H}DYfUEt5a?}3qLTPzWrDvbrk1BU`f0CRxLZlr#I za$0>8um{Inz5vDpj{zS9MsjL#66f*?fCa!B;IF{dz+Rks+5qeWd=vNv@Mqw8ob`%4 z$6|Q|m;fx{#QQSfSHKOxcHBMjCh!+vr>^MHEvzd79|sl#-{y4xGGM1V>R-ZvjX*c> z1K=9q5#T4l$a9hJBJ36LQ(z|0x|sX|NFVqQ;K#s&z~6u|cf+?k?fPEY1u*eG?1>#aeLw9II04B1e#@!{u|vSG zfIET9RznZG8))fav8)Gn1IpjPEIWZiftgPrN8qEtO~Ch_q#bhNuIitp2aJB2aso4ePXNCLegPc% zEahQWbsaDXIN}A;113;@ByhOZr zw^Cl<@NLK)=y?sf1E1PM`@h&?>HIEw0-X6C{D2GgQ;)z$fH9X?EYAQFfFA&pfbs7m zAK)~g6NpJsAM1_dEY_N6>$#Eb!sV}E5S0aWv+TTr_J!TI*rL;HF(acQW`{4ZT-9~R z#h1rYD`xx@U{Wgi6@>m^k}XsCPEYgWC9Mj+6TqbbEwgOV<80v;p#Fz7Tp#eBAZ3_4w;Tsq~7u>&E;Yz{nYlT|??lo|9 zCF&z-uK>5L72R5J&$pu61n${ZbbG)(5`e=5TD}0c0^ATuAzkEBiNti>2U#r75k^;} zWI2YA1Ri6+i!2Wbez+}qS&+jPvp6`#X0HuNvn2(+ZL@s8x z7ukA067M(gw}3Adq}CUE&~>)xWV1}&g0cUEOWj*W*`m|Qx$x)*{&nzSg6AXQ>EJej z8zG1hw&m8FO&-(0H-pENDjs9uA@nuie*}Ml;L+i0G=4ew-`b#G3qClbCB5XO5qwAR z*9jj!NqqN#n+Wb@K_I`|f`;2-8iG@8_GKXsTioJMbiX!iq-}vU=zd!w7>CUc1(Z}K zQG{4n#zL|W`t{J~3qAF^Sai2G_-d45 zlr1J%IKoay zm|xz*TgrQcEi35YDdJ8cN*(bdGd-T)b^P0+`@-Dc<>#x6*HPn+JJpx|0-TPd1) zpF|_*%-BrXbEyn$t<+gA_+;=acn*+lve=IiXw5AFb(RRp66pU1{oO6;(ahQq(Xyoh z^g<%#*hHKTjNhK59s|mOjnZ;MOg_1-4i3IOr0sHuj`H_jmYLZePj8;((~oaAaCP9k zWoVFkSr&|OSuE|SHZ+s+x>WN)!4M?PN9rMmc!!90L>T$?ZzTHnnbIm`BziLsy0wh! zN`#K+nm_s1{72eWTj{@~efkm*T0YW-HWB|F;s?rpAozXYJ>V;K{kFk3D>&DB3STL6 zG&q zLxd|iQGVUW=sM4uYs;Nxn|6(@c%-djlr76_hcd>$eGqmD$bbGYlz|qlKGJvp-b0#s_UQp*MNJKp=~dH^C`A|j4dfR9n*_GVr>GAJyC`KCU`YX_460p9&iW2VFJ`ga56u% z7hIq|9s~C}I8?w#7YV^;aNag7_P`GAX>hj+mA@{jqe@%ccw6E~+rUg)lG()&jAgS} zN+Hc9o`-mH?aIF?XPWJ4D;@I&Yk{rNI>NToI?}esnrZvMnqfO+O|cnPhwX?pONdhc z+HwH^X@vBpW=9s#!=+$6!Zs$0eb;vJ~U6+M>uurHxqDYX8w zi+yPDwhu`s1-k4!?JMyv>EwbN2~NgR0daAD&@L8)zf9;9x_zTxw<~8o>qXTrRlhTG5q)d#Dw^1>pVy&TBt}-wJRGThXlrSJ{eg6SzEZ zfqB^jZfq;MFTh>ditZS=gjRHs%tM~rip~zMJ-86FxJrKgz#XS<1Jg|h_Z2uVoz&M9 zaPNbYzL2qxJ)6cMcqjM+ZQz%IKM0;_7$z>nYcuH|1^;C$y!0QNz&C?W)otvQejb-I zxX-Emys#Jj{*Cxj=K}=c*Khor>%Ho&=;VI%KcJg>3SCgPmr&|0lb`;~`(gsrM{v{l zi3eA$aXCOIxO#9e3C^#ty5FA`G{#n(WvfWF)i@ZUq}Z15UCwtE-_?BA@_pJm(Kc;z zfKMoCy~)pa@b%hTDdQn1X)ASHxKgo-L`qzEsIS zs7jSU*+5l(CMGVLq32p4PvP4S+~wfDllZ6a!?GCkY_SbYKBWtjzI7gaK7@}Nr@<$1 zoSGuzROSB!jkLufAKysF^z}9n*HX-%I7=Qxd`w)}dE5hj2>1)N-Bq#;?rK$odcsBi zGH*Y)MElJdwwP?2Jzx4Q`AC^NF^Msaa4D;NL_gxdEeF?E5a>s#ZktKq{|^2klnH=*2+&xgWaX>ph;qLN~@14F{E% z=fN)pf1%*BY|&S1{F~tK0^dvUd z*{`$yHbt-Q8!Ki7cm0#0qN)FM%EeXOc_R7o^J>e7OGm~#+wxkHh&m5G5l-#X!bkhR zYK&ad!P^c~Bj)f-v1ya35sU*Vt!kdC?{9?11bEDnyeK)~i(O-jOSdHsw+&3SB{4a2 zjrPmLSCBQIJO79D>CoG8sP;hrhw%5;rrDH&0=mbbEAi3E(0Pg~h46Wv@bCTyd_IQmjOst<^Bdul2>*Ba zk@c$if5J!XNebcH3GXlYrD;$kN}py+oN5ct1yw-!0m27K`(Zlz_CKHB8EKmqbc3yU ztgT|At=OSn+L-KdY}@|kTW{}P4!cHpZ#nj_+E|Gf2CCnx8L-cLC4lJlq5| z4=1`R>waGoHe8&^)3?hkJc{76gWGDEroE40P4EzFhGQii>0d^g{YxVFvv2lz9uvIM zVF`Rdw=mQGj=A(uzeCnzO^i1tYtBV5y!fg zvJk!7M7&EE`1ME$#6k1M$OPvoT7 z@{_{)r=yN}5M7sA2l05@@K-8=8~*iZMo{^GK{gJx(8T>QgQw68$B8VA(%E4mUN+KyR=1@=aYW69&qYi4 z|3cwI8jFL{We%EgGiiwlSEE1EAE|>j3)&n_TN{K0VeLw23c$&FaUJ1x5i;Psl@<9VPZFMs`}`ugFK%zxDU8Ly#aaTC1GuGfAzevsCGX^=8a zvkd`mw}sOm)&?(@nSa03&Gzvd@twpUB;}=pmH9$xkFvgg7x;$+?{ANO+axn&^|m-V zYPw?x=#Hh%Gl};H@y6-0ozjlQltL%{a1FGv4a|MDK&SJWS0>zB{y@K+j!my0 zU2R()#LQb_tBziH@{#s81wI!q*JVV$(#k})WFNvL@L5_;+Ftl|!0(GO4h(wVRwI4R za6J$lW2>lXtJRrh+XL@0?2T|sCRhT*!=QxXIh*q`M+jd}xVoHOwaes=Vd=LA-xksk zx-4u|ZM)#;AeO+D-`R~tyXWp~Ij@ljZVfo^7*oob0`7ird6K4Bg(>Fz@D%W0f>-lT zlwbUDp?8A+6+BZAzK{5}%fNpNet^ct0#}2JTEW?P!NH?8DBl({&SoF4lw*b}m&Dx( z-F46jfBA@=|5)QH1mV|Xf4`DtORUC1j0w==H0`+g6kFo*k-Q|>*^fmU$%0U_Q#y;W zn(b9p%QS*=?Cgt!?xugQtD~_O4_Ix*!)+DUn7+p-s(B>6^C(=5d2QFTw1*9(@!U$r zDlK)WEt`}{8khZ<9Z7;$NDuZq-OYTj=G8{KO=RUpyy;OYN9D@d^@&JilMau}SiS!1 zmknb&b8=eDeIj%f&@Ent40T$8YaTSh;LEM5GT>nP_`>^9;@ox5DgC^35|h32=^~Ri zq1z9gy0qBeceN!G))9jr!bV`ZX}?ee46iNo;1z>|HR68mT@XcYi|vF-G7S*@`pN+{yel zj9NcfB{1NA@E^>{>blc<(z0LhwCoqe-zXs7yvOx;otmu;y4Kfj7Z6rUnAa9aTV4Tf zKDdi`mXF}pf?E#mYK1Xvo$Pyh3)~fgV;%#uFiA1ym9EY5G2vejevgE!bVX%u_xT=z z{_p3%68NtK{wsn1O5nc|_^$;1D}nz?;J*_1uLS-pf&W(}kd<$iELuYu%E@P!tS9sF zzVB=G{za?zqpjY9SYwq>qzNq3WFX3itv2d&>>Cp@^{zfkMl)FF!_=<&$o!Oin3`6f zH2J)^Oagp)@Zm+!|fXG*YL20M>Pyn3kw!Y7Y%!9I6%WR4JT+= zq+zv&i#1%S;TjFsX}Dd({Td$D@Ti7i6U>ry(Xf|>12jz2aDs+K8dht#Si_YXuF-Iv zhTApVui;@0k7^h;QKzqAFAWE1n5N+b4U06a)^M?gD>YoB;W`bsYq(#-!x|pdFib6y zAb$;eX*fW`Gz}+cSfpXKhKn^^so@$8*J-$2!~Gf_*6^r?Vb|#LYuHP}0UD-hI6=cA z4XZU=tl>%x*J!v-!|fXG*YL20M>Pzaq|?{1mxcp0Ow(|JhD91yYq(g$l^U+maGi$R zHQcY^VGWOJ7&cj_uVF6@2WXh4;RFqfG_2Nev4$%(T%+MS4YzB!U&F&19@Q{xicVj{ zUK$S2Fipb=8Ww3-t>Iz~S8BLM!*v>N*Kogvhc!H^Vc4}geGPkQI6%WR4JT+=q+zv& zi#1%S;TjFsX}Dd({Td$D@Ti7i*Xi^%?4{uV4bwE7pka}Q)fz6=aHWQ8G+d|Qb`AGy zcv!=u8iq~P>1)_a!vPwmX*fZ{A`PoGT&&?r4cBP6PQ&dQ?$_|JhDS9Fo2Jv(u$P7d zG)&WQf`&yJR%^Ie!<8DY(QuuH+cn&;;b9GrY8aMhQJ*dv_R?^GhG`m3(6C6uY7G}_ zxKhJ48m`lDyN3HUJgnhS4a27E^ff#*p@%|PttP(p?>~dv4v2iMHRXTyE?mWDIl)(+ z4IGJRe4!AYMO5FJAt}>^~enp@DeG+?L?ow}kZ|Xa+Ph!7#6RQ?vO~=P{vnFZh z@P3%I^^pbKAj|ipVbUMf^!B!h!I|`XLcR1|3QWQ$PfIUT`6mBunm+2Z^bg=`ne=-# z{qWP$--~Z*(swE}3B$ZzSgUwu{>AM!21W&eIr@FkqU*M(RQDV|NPD@`ywVC+| zpJ~!R(<&d{S2I7K$9w5t)buM)oBw0|z4T+13(cXH)6#Fh%1b}J(oA`W*Sq#+L_;$_ zgHycp@pH_8-KJ8tqW0>;{iD3}$L5+O8K;%cUR*y@K92b&{S_gnuvQ2&KO3ic>1!66 zbPt))Pl;sG$JTi1&sl1cbUkf;e!j^|e|f!0zyGxKFD~}dw{I}%LA3cX^OLg7OMknj zf4)s>uRJ^d#Y>-jn@N~@+WeHR^3pH4-K2l}wDdPUU&L!PfuGu;{z}KP1^9y zIjw#@@s*eU*VQI}$7$(Pe)G}~e9WYO1dG_#$ISo9Gp$UUcHGkbXHqyA~q z&pEBUSFzr2Hi#uJnDm~uG6T-c&jXzEH|cL(XA<6f+Wf4)+DqT#C6nHMTKZMjdFdUS zO?vrH-nKqwe)dfF(pNN^REejhUp&)Gzj}*FUwT^mw{W(X-rGqJYAZ9~%=}ny_R^=m zW)gmK+WLL{4ln%$XtI2MI<0&%9`(|9-ec1D{gd(zB{<0P(-U6$w0BJUF6Wvsak>dd znBbIOvpgSu?2SL=8}cMuuVd_wjAZkqEMeFC-`^s2%0E1ckIa zOw^$8cAp8bhSjRD(8mG6A)#E7Ojzi<-UNb{iT@j7r{aPdWFN4xm3NZjhG}aiR$I) zh&*|@%qpGChKR{=yj-sG))-MNA^okZN#|8dSL-0%)rLaOF0qN&)?yoH5tCtk-|ek9wr;XDXdYExmK_F~VnL|p@`=_=|c3nm69k=ikO~{#+cA;XUC0mu!~5p)(rF=&mQFH{W9{@XG(nvn;W@a|XZ(hAlJQk&r?VjpvvkY{ z$oEY2J7})tLiQMkUnzV#@8HpTj&yD9gO^Y20Td)Z)~-+U+dg=SMs^Xu)_R#_^67kj z_@tS@V!hu=(>mJ)t220LADs2A84}Z^DgOof9P4;%-*c=v?St()_#Eriep<>djYt?M zu}53l3D>UAN(K|wYDQ+)0p@<`CeJOuKmsMB*724uOC*OENDil;lEX(JS2=u+hxWn6 z-W=Zd?{ny-)j1RfDu*^pJK@^(c0_9J=CxA(97>_jJ+FfVihRjow~avghHtWb0tm6( zKsY zYeAkP$krLL-v1uhcApEuxk4bHaP#09XW`_n{Tc%08*-&(Fl7m`{NXR)eB>boY&~#0 z7u^331q^u{{y{5bloWEUJZ_N3(C}sao?7^@@Q{ndL1-rm7ZQIbkCt{PCFhsObBHD6 zJ_$&8fR}I~Z2vs((V^{s7D9;>8X?Baj1(Fvwk+JzVKG2XV?+$+!D@+=8(_j7lsJ*& z?#;Dcw40}(J948}>nP_V;?+=`K^sgw!2-e366er*j<<#; zgOZQ+e!0oWOz9kXoB~p%bgnn0!J64+gm&QDBBhxvQxb7@3MM7_hJD)k<^RRrdq7E5 zWoy9ac2(ECw?bESb*j$QiOzJO$vG$>q9hg2Q9w{oQ3OOB6-1O^1S4XP1QTX_CJZy8 zqGK3G=jo`UJ{5Iz%sT3r_5Z$o&aJKn-+Rvd@2&O!YrVVHy|wo~`|Pt%y!-5X&MExx z&OHGS-ho%tdC=Cc>QN!4dn8~6vGqJMn;Ic`{iFD5`=?uvXAL-}VPtl_>=E=wr~q5y zRci7L9#+NECQ;}hm(}?Me(eQ|7b1`^#cjBqe>Yq(5tVBlSOQWiY6JR(m&I4#W3@WVHR+%1dHw81%)&FvpYHq@wf-KOMNUA)E)48Ai=H<80_kR zLEQm`p{oN1yE>q02&P$tZbwqq0CvYplwtV35YbMcDzcS9eHdg7Nrm;1u&g&3*21u_ zO(Tdi4lb*c9WyF|TFA_nAHy-R;Af5=W$23%os1k$vx9RO6C*8sbt=VbruZh&uX>RGQlQ0ycUTEBdHn+-<+3`@p_Du8$iPgU2r1FAOff+N=tc_llKyL#P*d<2CE4)27SJV? zb(GhRAetT7(K$M`PrC%*#rtcp^S0;a&w+xx?IZIm@Wb0aJpXG1^0uetM?m3i&sWuG z7>2k z1I{&MH&ZvlX*N#UVBy?}g24;?18}(6fHOm@04kSn{md}m`VP9$P58CR6XdHufCBCQ zF8>Fp|K+<}7`ld%aMw`cJcsg(*^}l&sCxs-(4In2x$T4xB1{cILU`i@z`1Tg3eI=8 z6TWg0#3#JhUZl<$S%M1Aib9sN&oYE%Z6LU>P}dP0%}P;07I+g_rIc!we?Nwe`8#5m zAyYUG@Hom@b`pcE@#-G9|$L0&agv25>C3DVTXPqTo>gGJESZktOXV@XXAY-CSDJxTu2~nCMp@1M$qnu%f9BW@_I3tP|s0sxwp6fR^ z${BXZ%&?=JVTa5NJIWb$C@vG^rP0fY`=2s7wd*7XV{^hf^3d*h8=1VWLuOo>`<#9+oPOehuW?C5obq~ zGwhI=VMjT`4)wO?BAs0-#u+vY3z=buHZzkhXV{@F1eJR(bG4P(bzIJ{L#Y{d9%upQ z0??#QP;F^7q_Q@Jy40iQsBF%#_iM`VT_{0zJ=fip+hPcs5%*pXsVa&13*O;%eH<5=DbfGSUB*m*L;&bt}} zU*2v!{dq^=nVF|&*uh5d^UlFABs1(VXV_UoC@22~l#O*hyP!22cmWQs2Tm{{Z>n_+ zLJ2H|9)L1t%_aI7<#9qbNCAf>lFj&QqgGlneDGde!k(5*TE=A5J zxa}w{>ka(_k$=H}q(#oA$O~{6%lmTncJO=zv=sjfpsb@9eSa{QePd)uUj=a`h~=Df z%zq46#`-a(_#<0oEoA&N5tjTBm0&F*`WDa%=V(B<&cVERE(n#JkyK(vavJ6@vrOQn z2t+`}5>cbIs65bF9?eWXJwt%(w0QpO^r^OfPh3H(oKeuS#(Ae-UB2ne-#t4~bPgY~r(-T!`>)&7{O+ zW49@lv}SURiN~US*~I&=n#t{k|0D4KUGqyb>2H$I&7^{5Q^B%1(C~Ma^S-IFsbJY0 z4YX>i;rd1^Xqw47N)eOKvzs`+^RhbcOG!yk3Kt$$3{1-l30=+P4QC1B^E5+n>V^)bRJDJuRz+%}@dOOhyaTT^&O~+b zjt*+{+-g}5G=5^^n0(yP-c6ocq49zMhBn;M9*s{UhT0%y(_Do11pf{=8vGWV zvEb=|lR?&cYtRNfO!@C2>)^YfPDpGw=S#j%!@FU-Iofs$LyU61qsC5{wwv=k;aHfq zoAU$VM3}al^CRJ8n6{hq6XCiDZ8t|*L|P+b@pLRf`bEwqk|D^j2yHjVFUXh(Z8s-V zkO>jmZcadusS(<4j$^%ypBWL_Zcfm81IXM6Z8yi*ZV}pUj{3~@-JFdfvE7`_%w(9ho3n+W z3e$FTwlcd;n6{gfvfbzp2soU2M%lQic5DOyQdyfq4I?d~rrU1LP>Xc2-JD?>rtRho z7dYV1IqviZi_J&QS3up>)FFqqoV!Lq+H&q%0cpzx#g>Z>1obrBxym6!4sE$$F)7{M zcyV^kP-O;P(*cJqCFcV)%5b%S90kMjWg{nvHXrWGkv@k9poRw$^xuxUiX=J+a(z&w zm;<-}C@^G2=Mn4!DmI$~42^<>1yN@QI%l}85(VRaj6_v<8R*d<$xe6<;m|jrC&No1 zB^oAN7e1Ku2;tW7Ef5*aBHS;$h;Wqfu<)_{4(j;F9DvAw_xUM6^#>~6y|#% znnRwc;WwarG?(y<@HOPmdkgT~yd#cM(fr4u&T&d46OCncs_Ha%m@){i{b?l zTtQM$%;KP!#lfpV@CA3{=?{uo9MooUvj;iWE0Ep7dx*|tq2EWe4%yJ?e*i7Y0D7m9lX@?&DvpC3^i_YXC2uP6 z)=xbLdMUp}mC}0j!ogJ*fHZ3=Yh2H5@hZ}hp;kY<1d?sT@3M!hK`Dq%jzsUpDD;E&Q&H5-bfSp3S`#e59q+K2BgE0dL3yVC)up(`hS3Q zIl}5c0PqNahRf!P1eJ%BsT96jNZvO3ux>mNrD|9PwaIRJ-+mFh|60YT~a8 z*61tsh2{X%zEWS9A6e+BJO{rvd4gP;!cT$ezEc0D2SE{EslV&Hr+*8Rl<%JY>x6;6 zQh(QXPycOXFrQug^${pr%=b_v6JWp0e*0n&7T;m!00HSc%pAx#D!3AlgAp!j^i_UF z$sB?q2=e5!UQ}DV!Acqtv0i9BDt0ZNmh!)W5)bs`U)K0v1SQaG0RsKMBG~_GPy@~l zcxIoE#}3?a2CEzz7ItOEE@5CPglSkf)dJG6aKx|()39*Fun5zzaKy044KeAV7al`V z@CE1}^of&E^Lf9KK)&_zkd6F>b52y&@C$)r`V0(SB!f*Yc+NVF zD5X9Pw4{@08LQW~e%%qTm3-dOTRUz{SWfJlW8tUIGr=XZd%~m$(19a&OphYm(l`Qhp%{gm>`s zir<2ZcW|jyF%G}HgGsAm1%7!4o2+t~fe|qTI`^)Y>xlTjA+W6f^P$hb;M%uCqzgc$StU~B>xYNJ-W^Q5}`Rbb~!;gIR z&6H&q^3^x; zcm(KH?~9S*oyX#V3wEqrRww_aAmS~rm;WpXb0T8NN|R#^``8rw(_qh{OSSnb(6Ce^ zdV%5L^yWc?#%R9A^fHd@+f3jL1Y$NvJ!+`OQG4m}J@xR?BLbf}*^9~U)wT?zz^zWE zCVG^5dNii#!I^wFJ!Yos5%(N5nXlw{?N!Cm5dG>cJWWgMg>KE3=9P`N^? zuf7?&r@!xfvLXmhky8;MpACJoFvu34i1Cm7%xA(U!EQbi%1CcM6P^h&*7=-|pO_#HbIpDgkud947UkkljIjIBr0D)8_5}! zub@qQ<0$_m$aR_-Aq$^Qqv+jH{poZP%R_%U6>9pYQ>IZ4R!KAU>GZD@(&~)kdI&9K zyp)CrIY6i)IsONbX=ei6XX5sA#qDQ1=YbGdfk(FUIXJcjhi9TS zx+9@}a3p((ayP=B3d-Eeak(rZIGR}uyTzD>1jiDN#pfNbf-+akjdQ{g98Yq><>!Xr zfy`3Uoq^H~PCORy822E;lL;?Xejkx3T&a=6^##_uj9Y&K9=LkwAB;YyL9bj{Yw<3@ zh0rjMDp>E6|2d%fLrkQ(A^6?FQ=nhfiLr*h7<5BJ*I`C;xcb3*h!UEP*Gc`5O0gc& zb&3x$MK=ahLe}9t#DX~pXs&!4duR!C|2@zm`8M_lr4@6$-gPY?-}-IKOBN7)lmhGF zNiS^yu+pTr4m{TLXF!j#{XpIy;blVsoB*JlfypVrE&`Un$wWB=`QS1e=4CmaQ}BtR z07eDOiTs-l&w1cEaSt9s$SU z_Jrd|P3^9tg#D1aT>1XGirwKdqEfr7Si946JjrWPwY!!&`PT0+wR;Xze*k=?l)T!c z*9so%io?+l$|^y&F*`3S0MG!SoPo(EVB>-1Z#7X^yKRWTB3j0hO{?A83=eDfz&&_W z#SRmiR=aN)(hTa+xt@Bkc2`ml*6ytYSi5fnQ2BEWJ8PHAK&V4n?RvRl?Q(|h)#BqO z8f*8BH2RB%&f5J((|wD+M(viH<{-6O`Fa+VJ5lPjA4)^l>xrp)J+Z4^7m-QTaCMS3 zyTC{c{XAfVpcSpaT9RXSJWAv9nhdhTN=WKChIYCxW366%NXYzrv;s_e;{x% zCTzK~G)o4$b09KTmS&CJ2%Z;!mLR!tj9iJY7x`Bi33Q{-U&jJ+wyFGoOQQ!N6ZFt& z%1Kr`$sS8onaY2~F#Hh_Yc)g0q9iIGldOt&O&~Lo|968>wegx$dQ86l$4wlB3*u2; z01G>smTgsg6AN1mR?o^Zb%E>-K(*(V2m`@mk);wD(`13;JwWSrHX!;yzWOrOPs!hX ztS+jTq1j(_nw%Wve{AUQfc}pZo!Mzq`9GMzzauag$*_=4!&4@w`L@a5j|gotp%7V7 zX6R->;LD@(Dyk~qVSOCRWE7}iYpJ@ajUnv1dO)aR!@+lVEJdg%wO*DXG!Rq`uT&v7 zHx-Oq%RnoVhR%Qd+o{A^bSIjpWrb7!O1TGTnPZ} zeW(!_3`?0>ZF=m0kIDOl8Tu}x#rw<|3iw)TkR{%s_k1n8u~b+<$FZo9s11I@+f|Jhl2i=3jFd8J>hG4 z8L9COed%lUrUzK*{Uq9pAB&k_ujqYWPsH@BV9yQ4t*nsl%L;#P--ygfIPDs_z@dY8n9^%oWx%vR+Z>I}!o@!~{@mdUk#9LYTjB z7D4W%@E0v6_#L^5R}th|^30bg$?*r4b1AUs5j(n}cWIwc7v&#z;014XBJ~=@!tW=W$C!ecP4fGgd+2t zY-A@u3qRkPVfP#dK!n+?kAhcakAjwVJIPM=n}j>4O-Y;)}I{Zv!Ltje{aNUF8KuaRfesFoJ;M`Zk-*FwSPHnl^oW{%lODDM-bSopXw^dN7e0 z$~TmeYOe&6IF{hH`CxhKL_Ba^u75C4EJ8ae+y`yI+D7n6)OX=M$hx)d6re*3(SL7c z^jpsWnz4RVQF5V<`z$)$V9<*B!N}997{ltYVrwdwOcnJvocu&MM|0YX6jsDkg~11w zVyqSFP$kn0-!kx_uvrOat(ug?Iz*L1%TbAmROKS(q_4@zC8?Yo2!(V`E@Do$Ky{sy zis(!1P<;SzIeOAI2)xJ;%;5rD%0>_>pk@e=^3l9`5mH7G?F8-yhx zTfX)x303m2;gP&0?x6Z-Q~l2tXubDMsZS~8QiEr+rTqr!6=r9X|32`%0JPu+Mqi`V zpHdVxqA!9j402o1lUwV!Lprp3{-9+O)YO8M#rq9~ux%^Vww-I1%e+QuYL&N%Wn7$0ai>&C889~ zH0%$9au=Ap$^e#9(U~TcrN#wSI#d;1Wauol&rrb|XaSff<6rz;ch z3SI)eRLScmx*5tgf!5=ODDpIgea<=$5^JTKOd(h&Uqq*{$JB?})u*#>H^{{Pa1P^* z4fC+pfG<=IjO}dWj}u zPQApF@ur^fm~evtqD>>UQBC{BFf< zUjsTu`Nd?DZ?olL2-Y#mB}Q{A1o3u;_Vm27&E+T@-tM&KQxU}5p3+ikp7V-aU_h83y{lWX=6T6K)l<|1%~W zUuDK_n@3RFZKo1Uv)i0!K?u;l>yV^!*d4Q5LrK)Xt@VaZxc|R_B*skIi3nGy79~}|1!ShkJTK&4M#Kt*N)&1Yv{$7r_@1G1h$qiSI8 z_4DH`W0KemY1YOf@D&~o^3ez{oDASv0%HKY0zl;~GVIJ2mmGE}f7&orup=$BD+C!v zwm8H^+3l<|qlT>+Bwki0#T7~Ep2=)s&uQ@_mi17t$K3)AG;19oT>?YN>h?fI$j~#C znLG$+{!DyTz6RVE5Se9=ZM8r!m6nk2>wv%>7UZ*fAae}zTmu^5AwZZ8%!t!it-?01 z5l!X?8NM;Sq(0I+ScuX)4pb$25M!_Pk)c$Ez4A4{OZ6c36hS>HmqEA88@UwSZGOd% z$7alFfXTu!XU`*~MuO#E8gqQVUHrgCc(gz+)7@N_C|Cc9>TsL7R zj8q`=5`5sfUV!~WxATfKduw?5Bk)7;MLQd-w;eTp^H_Me>2PLQlQ22mSD)*iNK8Y zGfM6?67tXzOP@E$vk1HycNquWSQ&;@^xcxbo6sa!kqKr_6ehPQY^j99q%NasXBzIz zlxoA#Qw#55jxJ+!+W}q5<&|(5d&Or&soG`aYrrUx^m4~@&Y%iS>oPrkfl9PJsRpx^ z*hHzPGuhq0#sk+D{eu!=Y+WL!vqX-BWL+X>FxlIP{*KXC5dAAqDWEmFfQD6Y@6UmI z=Ha*Y_IHxRn>SgtTdO9~Br7@0;Hg!J;1e#o(AGULAW+m{#pf#{Je-=n}*G?G<2o9OjGYnCCaJ5A!BB8qh!w{=xs z3i9&^uRI5UYNc(7z}n5g>TbZJ3Zy!2gIYo0w*amo@Hl`!0I26iQ+}$z9AG%W)uuY5 z5XQ?|csx@%5wr4ZPJmDyVH>u z45ADEjcn*Jkp=IK(ECy{E~~Q*3F#T~ME31xk*1!aPh_FF?I>X}d8UvNv+vT;MuUT) zP8Dc-wQ-rE&ox}4fQ(u!80m01s_}d(G}gBiq$axGtg!;p^=3fnVq>WSYkC}O8r_DY zU*l(t-0u4iL~hPt^|ni7G5Om`WsDAqx}-G)wHc`A5=Pg-i%!C#E)5+wNEP_45em$%(J<;ZQn3_d8{&ZAaqAynmUx3+ef{;jh> z;cZWC^=1LVDXJaQ3cvaS-#^S7wgqoezG3$~bg>*Pzw`~8v6qiFV=o_VwzI5IOZGhbso zdFN*C7Ugn|WGpTIdw}Wh+{{lX(&wPsGrx_a;`6>oBbgfL{T|@#Tk-86(5H;`lYIzS z0)0CHI@z?h0{sZbvJWKO|0Rq&iTM1*C#k>yrk~9IJ>&!iGE0^5#YAk*T?0Xx-+zN#+00tr2H-KfFY}h&0?XI#9|fa|FPS$} z*`jvp&;at}nGH@i;MJ48n?3Cx9Okgx0uM)TPS0ioboA!*Y`wwhDo_&HdV>?;WVYVm zM7S>BY;Ypdnm-m#Y;YpdFaKO3W^;PJ+2F*GG5JfO3^q6snUK%f1~xbmnVN4lIPHdp zGxE`0xxwjOAanDNBNDc#@Pd4^!HLM?{973km%THAZzl?2B-C4SeI`$II&%9$Tu6Dh-}X1Gz1%*h-}NBPNY?k?fEl_v|E2d z$c}uo!HK%<%r_gHd}vv_RKXzXvoY^O1SOo!%w)FS;6zYmpNm%PY-M(x>NW{D|64M~6kY*+}IFVk+&FR?SByfL-zy>G6MPC7S zS2N8bu4Qu92&gwS3COjc!6GUWtw#Eb5UE(%a~YRw@Pfspl<1Yqp|<;hl&%1?Dm@qv zt5kO3lwJ+kSGpTdf9Vl;W|o>=IFEs!cQHmt*_>YVI?@Xbp&Z}w>=P|-0Sq|r;aNs4 zegIG|4F%K(FC_} zq%PuFJK^hufs5e6w+aK7T83{UgIV_r8i?@e68T}{QG zXpS1O@DHl7CRwdD)>K&gQ);YfuFsRKdJHzQT)g2Shir&nY2w4?TuS|F&V@o=3ZH7( z$SoD9N9y z)5~s;w+s)zCNTL$lwZ$9@4T}Xi{JJ>&_WN?FV4Zxh&$R|za2lkW3}}w@xwd2uX-DG z3BO+gtxtd1UX-h?rs1a0IZ5FaEui`GGbft**lN%#IC#On;YNM`UZ1!9UCxP2{drp! zU3dGuEeZL~I}76ENFCq#1ksPT;Ky+|zI%=f!u}&+Zuk=i5!8;0qY3Ko-L$0rFCdGV zvqux8DHV8$pzF7nPr)b=LO6kv}P&a13XrTt;{N8Q9N>Ih=6}DevykO3}*~;Ec<-)m3 z@r-Hl{H~oRrK9}(-fe$Ek&eSft9A(<`HpiJ;`{h-+6BgbxC8HjxV9e_B22}R6W9;i z_>61&fp9FY?FYh%xV9e%C*#_FAY7L)_5+dD#8^CGKM?7cF!lqHVF_bD5E+v&_5+a# z31dGHnVK;6!w1lC2G?BCe)tT?+{AH2!WI=?kTCWGk;MsPKQOtaiFErRVeE$k5OQXs z1W(uxUqRZ+gs~rNG~G1`V?SI5hII*JKWqWAAz|zXBAXM&eju_fVeAJY+Y`oqcn8Ri zgs~r}+s=fsA0kL+mnziuL&1j#g8jfu#QQr45$%U!V?U5yZ0rYtjr~BlMB5Kcvqaku0-gxmT`QorA4CyW_34OI zs(cF>SKAMylzH~Uqd>}6Kt)w9_CvYY59L>b;49yar@vh6hjMK{#Q4pecd2JTlxX{b za^&Q_aDNuDBMUeR-og;q8tKV%=;EhibdR*Mi{b29&?D_^;!gZqj2)3)gk$kH2zL-p z#5>8;hy2O-ZwdD$ToG>}+>dZ&{4lh*NPogr@i5^5gsbDVxSgo%m$1Ta_GjRs3MESXGj@_-ew{WI?ZH z{k{WGj}rc;5Z|h~4uoVC+3Maz0wC#FA~@x?USo4SPU?cAmcFdc zioVq1Wd=?;LlZG%$z^p`enoLFu(rpXp^05F&%$f9%8RoAuOC(U9<_Unx#%zn_0zHN z{-!genrpu`!)Lwl(v$b|<22z1cL4o@(Vr%|7HE$Ge2koK-q}Y8E0r2Bwy;0n`qJGerlvQmZtICYj}DIPu~P%VnV8TC9JN6J}cHWEFE#+{eqw`6eexwkc~9 zt21N$VT}ixd~Jm635d&t*Uv!02vl{mO{k>Yd@a+QPq7vk!uI4+b89|ZO^ej&VkV&~ zXOL|=*?w)zj+KCUS)D&nJ&8A+@y>#JNr`(zH}z(C>OEm3TnqKMsHD4kUz<=-uij<4 z2YRLs2Q*$*Cs%CL9c);)Lr~p(gWS&ot*m9^@5K~npMeLiXY~)_via3~Ou>CdfcOsd zZ7nAMer@YX9pkLfyzNh%p#ka20G~ptz2Ju%MuOWHy&;L_t6SA@o!Mc%e=?C+?deqx z9nUsFY`Aq-8RRkWHQsNKKLPn3sUV`&566-iO<2TrwFZ%r>GMhzD!Y7(!hky#8S1Hh zc~=APseO5s7!G@CUmmMP^<^`XGva}KO$sinlO4SFcmz#Be)^pPpg$QWm{zz-^Qk@_ z+udLruxIGN`A{Ka{e;GOCfciD=Xq1<1<-ho31r9OT2%Bm*v4RSeG5F}x$%}Xrd%+l zF`eZx^?p2!iM>{Ly=%R26zI4#j#=Hs^fheg5d4mz>OMBSQm}(~0xR$E!a;m1@D4pN zs4pnI!xIMo7ULN2L6d>=4o@5OCVqH_j~z4*KfJ@E2YE|gqkRWufWkXkKd29CpLclp zAig?yhi9py3h*XWeTy*~XgmLC5a=CUYO0-+7G9SZLX!0}c7Asg-$xVQzn6E^zn6Ek z+i5^(&WP3J9rdTYqcmsR%$)JaD&!7AbNh`8vmrsFWi_oEA{-sHU3GNU%19UDf0{09Ka;= z3pZhL@wuK~xFyzdAbNh`*2qDadVb+Hi{nwxFWjDj==p_f{F5@jaE*Ub<`-_e^$JQ` z&oA6wqMM#yxV^2jk&c;PxEu3je&KFrCS`u%ZXu}W7w%SOSI;lplz*}vG@MS0I*hUV zQf+B?q_Q@JdZ|ZEpI^8`Ez)Iv;SSR`f}j?@cNQdy@*n-lT%CH>n`}%O({*J*k)h-F&<7$m-vTxG@g5 zRp_@;M>qn9zR~EW98gN=8;y!@w1mFVsQ5-p=o^h*Ck*tBM#VQ;GL~SvZ`3$MrM6dk z^2=2?8LQq3RJNMNdMqNyU81pCF&TYd!xW6wF@o;|kh2Go*;JWR!vU%MR*WyI{8xB& zS;}`S2cfzhX-thA!OBM>Se5@7tYGQ|#OcW|oSvk%o=B(skBF?wN0F&~3!WL}*Mj0J ze-KZ<@=d4gz8TBaS4d^vOw*7i|P5+KfkQun>b3`$fBRz`oa3M3$w8t zGu5XMp^@JLzXH(Y0%*R?u#SXkJ;kBi6LTtOc2Az6+LNox0Zw&&?|i29>S;|AuWw5e zVtbJlD$uer8Yh8Pg0Zu4G=P%`3<9tLK=VT;ok=F0Wk`+tFOZJ2TzKNYz%GKuYge$C>h8t(8J~XTTD!-Hg`4GW(m9+5JejeWl?%&T#7Tdr!)* zXaJ@-ucExpF-*@QzV*KK0TOKd5cI)dXnx5A9-}p9slcqiCsiIiR+j~}2q`qbZ15JsR(~bMR*w9 z*?LYQOfnI={2rI4B0QIh5M(=gS|W@y5jei^vN}0)(<(ikiV$GY|6U>tHxW=ya#@{U zr6T-372y%4Fh$U(S7}B$-2TnJ z_k*fc$G0Z@Glr#yqa~@1h$&nyL>aF`yOK~H)h2igg6E_nW5tW1U(-cXy(h8&E2YjX z2K12MI9O9NA*_lPzQHdCu4^hH5}pR$aivv6=@6|KsEzD4w||r)L6`2L1<$GV~cX z#(T*z?<|p_#_J!H$*~YI4Btnrd)b!rhbT3C0~Hk1no>&#^9bniTZ-Br!LP{hhosqH$2=Et(t2M_AoHr_Cej}a8`>6nc;_;+xsK^#V)%16dq1sOCjy;(=>S>J9xs zHvXcG8~e%tuo#w*FFFjxuoF~W3@5V~rh>LFOf&TvQrB5uO5QD?H(zK9^(DzHeOs#I zXhVAoG#AoY2>5c^e3zkfgwZV+%r_a$J_fOmFysBZMs>Vm=wzO*g_z;!h);y{40jD8r<)}clQV|E;3kP_(78w3uY>!-pX zV2^EGWI}7H;aY>F3J$!m?YweOL*E3KHGt`a466??FRSw+$Q~{YRv7Sl9d!x&V$bJR zXqK+AiN-+t^M>48hf3RMrRe3%g5St*M~Y}p`b0;D`e=C#&?h=xm!Z^HHRd+(_y$WL z&87X0IARg-YrqWfcz~|})KLbTDCHOkGtRz>^4MVpi1YJoMj0T^&$G!lK%AdvGqxI| zH$-t(<>SbwV+DkJ#z3a8V+@oS<2V3%zPCdW$jj>d29cXMVDA439&mY%{}#Wm zA|5~Z_4ih*AfvtZq$V@aFHIAe8-KM>KEXgpTAPT>cC)nkW zz$til0yyA7JPsuH=Z5R5EP7RZ5ZgtZ3Zaf!3bD(SEU>d6sQ8SnhI$^7RF-r3hrxfJ4g z7yRCu!ZPAr@TfJ}^S)EG35=;6Q6)Bew&6~Q!oU7mKI=V|Ad zWQ%uwFHgHZL88mkzSjv7vgI&sE0Bw=KnEZ%xpakmFP z;@V*C4<|9r-OhkCcl#45)WudHu2>g$d*D@q+T9-LT1ykyP36M5+>~M5?V$`aQ%-FK zqDb4R06mb8N4~8c-u!~5*V5Qu-hwx!_`2;hU$_0;)kspWrLn&!tk=@mKM>YyY3v^f z>$NoYPlWYa8e3UJ^jaEt+llD4GnHYiaC&AbKs0?O1>HdA@Et zXmO#5_I2CozHU3+*KMc!y6tpdx1H|mwiB{4NBg?%63g;?zHU3+*KMc!y6tpdx1H|m zw$pvxcDwZkvaNmHcDk?I?rm}Li}7{a8}(WmdowdBzHWO9LGA0dw=%oh*KHeLx9!{s zn(Z{B4#hu0wT;)zc37K2E%2!6zHWP{MY{O9?O_^*mqgja1r}eovzlp&uiIH8Abs7= zS^??ncD1jYi&9R8F!;KU!;kp7-C|N=7vaIXyU#i}WHo5E!&VxjC2}87QT!+6+z7bL z!Ej}jk_;R4@8G~y9wYJS`2c@oMzPBzfTjeGbkj>FkG=-6)ILDvQVnybLsd2zzWc$a z%J-pi2T-|@M%Z*M2FfuFt=s{k+`gW22T-~Ff!2s};xIiMsQ9JV8ad1kFKfm>piS)+ z5OzO!YWYtsuM?oR+8zy#%7aamU7%E+Y7oicnFe7FRe1%K9mb;Y-UkhUd0CzF!I6~h zzQYLihT!C#bsqnHK((^N89h1%58K&^XPy39FXksxsn=iYX~5R&uk~ERSFgX;zX7Uh zD1@ENJJj0XZL|*$ZS>yZ4c=~>$Tam3UeA8@Mn&paqmp%Hjs06!Bv30qYlE0N`3veiJ+Ba1-Sus^a(=&L|>BJDya98>-*CUE3V zAYrpKl3OYxyI~KQ|Bi{k{_y@gCbF3D_iONsMbiE|CZd-{lAes{rICc|vdq#*BCT0t z@$~*XCW{r|{dY{3SsF>UFxA1n&m#5`^G? z|Bhu`y)=>({O=!IWT@?TK>msU{qrA;RvYTS3bBIECR^v@jA`wnygc}&4xQr1N|8Xzrho_hqlle_B zmwnZPysQXoiYmU3Li-IdW9d4y1zuKX7{jhkrXOP#j|Do6smLGDoes1-`LY9C&Ov+v zc*W@q9>_5ahtDsooMg25l@_Vq4&V*TLrG_|@^JS1vg*T-$nl1)6|i*_{}QI=IDqHx zhj-yx6Lty+weZBZ)zamY{D+ZLO;O}e-ut`%P?Bi?=m6xLyjt5%ZAd+d-H`nB|BLTP53+PUTlVNZZ+ql zE;1If1^Jk*o^(lNEW96h&*>5*{i&Irs|@{LBrIdib`;slRqB5|G7f2Z0qOG2nBJOs zl`j%hZ5fdAH7K?s)bd9(1>TV}TRKp?yu*Fkz4y6VjdqB?eXGW>q$i~>ArfEW?)f?o ztMre01l{GAPD=l8bF7j@U;qEv9NYa63iC(Od1wZDPiWxF&1k-|Cp3_@Cp3_@Cp3_@ zCp4hfT*;o$fL?PYdqM+x&6Vs44VX1ovL`f80HXJV z2FyHE_Jjt^JXH3C2FyHE_Jjt~_k;%0_k;%0_k;$_JXH3C26|iHA|10QG+_3G1~xO3 zvL`gKg`nOO8raJ0>OG->)S9d7K?^uZ)M4}*a8hmA>qshVQ>Z}<2SUZsi8NefPiSDM zMY`+>4Ghz8e~1VS7g+X$+N+tS>^p(Z`VLEkH%Zs496JgOgSD8&L2ua2iG=TqWyBtk%Sx<~3h( zKZ!M*`nkT%hFE$HiM32~&(RI1Cu1NilkX$7mxG~p97bB105(vGlYk~?U?3g`whDZX zYNqJQ#b%IXWL4F}V9S9Wg&UL9Oni5(3aiR->5Mg=8#CBm!&x8iP=EC_qWIMTJyJvQ z2T+$o@r5Sxok)aNL)9-DioN+1ci8=RhZFDs*^H(U5bo`y{{>8a3)As&8kdE{1cUy5>sopMV<25e2I_zP1}diYzabN$Dn5)7 zu4KN(0?(P8LREY!;ma5_n?Zj{p(?UJ;Z+Rsoq@2dxqUheuHsKJYz4!(`cMZ6s^V)H zbQ+bon-Z@~p(=h8;gcEkCkD-f??9tCG>$>XGRXIlNbJ>aa24k{9oA6{b9_vUL4vAy zh|y-U=&BHuQ}>nH)brmS+)U9aP|zhu5(4SgzOa73C8~Ia^1$ z!Gxxwum*26M1UrhIMmKRK%%HTwy68}V(Cqm-3VfK*uoz*EJ)2rnM#($hJ}6i8N<@m z$1ekm^xyr^e-rF+X8;JjY8X8=3psL$R|%rKMmQO{u4PP)HLoyc-kyWiuXa3 z`iH1F4(KBd=RSzai$1DfYFl^v;A4)Hg!T3u@-BtwJ5L7cBoJTfFO`{Ix`RyiPw1~Y zX5Jx-MeneVBn4Buuenk3(&Lv|0@Hj-L6>L9-j0r8JEc1uQp?*ZnA0CJ3 zw1Vxo6hAXUoQlKtTLxrq=r|%_YZiVMgy^(_?MGyB=vIapr&Z{3BF6R$(P`z`ej&CL z*nVe$wlYMg6>PstfUF78X$9NwR4}Xy(P;(SZxxUYAv&#K`w`h3qSFetACYY#4oR^6 zh-?qhX$9NwS|B?@bXvjoqi#DxbXvjo+lX{_sW6>ZfsO8m2ucJtGm}9&tpZyJsvw9k_S1)QD0BCL9lfZFz(#iZ}XBZv&emHiVV&}roqlM<=HgLfRwQqJ|r zrpL)0QUqF#jiR>-_v|EA=ZEOAxw#TZ&l6W@Yc03i`VW;|Q7zo}$xCcsU3- z*Vk&p$-u5}l<_n0OlEHD(y~?4t4Q%2-93@nCC`e#SmX zLYa2sunGE@nR4;=h#M!VD!la&8HZHHuZks;)AyNlU~>O`4j4UU3>-OCo+BqHj-2Y0 z%O=a^YvtGVsn<#&8a7`mYm7pFL|5WhN5R6Q$MqgK$Z~v{Ej{I#?gmz zNTHH#Lt)dLsd*Q_28P_G`?LMk`w z1wPsiP_G^!(JU9(2^s?oO6d=#P_7>M447FxK+sz~z<6>JM_@OV3+K+o)2tq_P{Hy! zHnnxMhX74)+nwdk*0^k3L zTsh2I0S`5kqo3@SEN}#zT;^atBGv&Ylt)iM2;oU+uny$OH-^IkvH1u%Qe@_<+>;m+ z&4DG9;~iMS&!pagC4{{LO9*=hmJs$1EFoN1L<7e$&aEOEINpJ0MduPR&aEQzRgQ7S z6w$!(4m>NOf#V%`Rzw2_U*$3|vdk!=frGDd4v@J;G;q8F&x*`fIcmSS=vIap=T;F7 z9Pg`K5e*#gz_TKZ8vH7k1!*gb%vZTGAZv7I5~1Fj-DPwWV{A%Gwlaheyp(1vGF<%vU+mOK9NWz%zkq;NYtq;Zhnn z?rNr4N(0ATBOnbNcddXlaP)y^u>qi70?sllz+eO#IKg64Vz=SJyUa6iN@?JPhFk+$ z`4AMnRr&%zER!{Etbh|n?BszAnttUvXo2f~{R5B0?Rb08?{p|*-G;YR`B-uuM!IkP zb<4|})6fT(S6&Q*^&=x?xF=;MzrR#nji7&rgzBE_b--I7@c1l!p45e@*KCi!7y%C< z+A7>URB8#HQ>?M7$9rjkSDV1oOknMJBl=^A)|EjSQbh?>w~V@uVO`c3Av6tmS)Es* z@7K#Q4rACieuSd+y;A&rCjiaCaAJ)afzSm&8?I;Q*c*WUmFPw!Y3)Zb?Gy0^{N3-}58)|h;5s^V6%x!|qZ3E*J>&0hI`1p+cnyN+jValxbf4H}N-Vrfmn zx>B4>hOdjMGE>Gu)pG{58o}BsHK{|ETvlh@2@Gst0sPLqvyVsx4gg=vyrW>9HZb;g z(5Lks!_~`hHEgAT4u+4Ogn!_}fFrG=H!1gmQvH>Q5rDBkZ3i%B-MNfbPA1P*=#xs9 zEvBCD4Xd0ZWZh(nq#8-`F9uqDOE;lhWo$&ZYdeP-^0B~sX**{q2ssk!ME1XA5!qc9k^O3yMP$FW6Ka^V$^Ki5$o?c{5!q=L zk<(=nIel8tBDF>2q*+8xnnmRFza7n8TSU$Prmrm`r^_O8x-23m%_4HrEFve(B689! zA}7rva?&g!C(R;q(kvn;%_4I4eG{4)i^%S>i1Ou_S6^Q`OXDqd=z{(K21b>`V_tot zHvfH@Hc@~)1!kEk%fdTSfvfs{=17IBAx2w3ZrU~kJGj)F=T`x0rl|@7^ zGsTe#MD#LK9H~G=FEhoF3PkiWQyi&4L@zVNkqSigGE*F>@ONmKI#S_lApdhmD*Om( zsUsC=4*ky^slbu#=Z{p#MLK&OslZH{BNYgGM=CJ8-H%kTorgfP9aricD0oe{~ zQ>Zkvgqpt06h|tM?j5NhFfAY)sX*8qslYVNkqQFR0t&7bkQR_RQlU4fXCV@nnV!P9 zw17gzq{KGi!Mpo1)9?_QM`FJ_Ee`;+orm$1qg(l&k(X2XtAG$9CmD z+C(!ib~Tt&7Lhq&A-0LeoSd)_>pEc})^)-{>^foK2@A1X`L2}{7Gghh!b0*&NU}v61Y*2Jj$&#up4{Uuet|w0iT* zvn2qrLH{QxL1`WjY$3U<{b*cvNqpav7(EygKk6nCYmt&aBe%xO*a#NeStiPOA{QED zDv^x_Ig-e=200!`<9!A>1xS+^_h>37vBb;of|j27gix(>XY+SxN4`tN&|{P6`JCWn z7Ms;~DPKJ;^5(geRMncc1CEuU4-AtXa6P+r!07|S26DJmt*=zUN-OUK=wrJvM~rbc zV2&8$LD%MpF^SPO87lMkEo*b}!#lf2+x^gucf7rgJ8yaCENtV^ZoIQ9+D3tow{Lvg z`w+=Hx2cV1xbe|E6#5HfWae&C!MEFl*Wpb^6i=Czhzw|1LIqu|%~2jdRTxqhADm z>IEKs)R=q7&E)@84Ju*k@fZ~Kkvi_Qv4HhaWA1cX|N5vg_fVM$$Wb-!5%OM=qsH7B zui+h_j~a7l@@=e-8gpk6)<=!Gv)5w?GDnT!!y}cjok#Et?7$;oEMwM2CU$BS3{<@jDu;GaWKs?4yIYgL2Vfq(l;11mT}=&hzJ_XxbR#e#xgFXZ!l;q zF+gmXqA1}qf}TIU0qTS(tv&@6l_q;D{27QPkIHyAX& z!NSXln2(=@^bH2h!Z&_VP{D-7uPQ4G=^G4|SXTpCQ}}Qd5aSyxq;D{2e1nDb4F=7^ zw?g^`gJ$7d;dCNq;aeengTZ!-1NV+X`UZn$;aeengTda`4M=B~Dxz;NXbu|-Ze}LM zG7fGbs4e5*R%TaQ#=+DEtb;+boo66SY+$OLvW!`qLcQ0c=BVP7Z!kF2B3*og!C@Mv zWgHwXu=oZ;tC^^0Dqnce%{@Eijg6dV?5$(0ou-mcvkQo zO}|{FJZ=Dl5W3N^XHT9Sm~1)tSX>qskO1F zvxaa-SNBz_QjaU3vea(5D%JKij}H|4y3-4?RB3`X^QQAaDV;=6?Ca9e1jW8CEh2cG zFm&11r98n*+t+eDTDBaI7RI>Zpi9VcW$_+7!B>tei>Dn|7O#5`WI3)ZXAqf7d1iBN z8B5r9I6j(I;MQ=IOUn6W$+Yv!+`1OfJ*Gwui%B`ZEcs`AwlwFLxjp%hx*k*8wPcd> z%aU?_SyIj~OI{1Z#FtDvzs&8+<5t}n?r@HVa(tj{lV#}d}(m%00K5Z33Hx#I}y^UK`*3G4IA-0_6<`DN|_ zg!TDl?tz5$`DN||!utF&cVZ57*5{YGlQ{V6^UK`Hgw6S7?iBhXW2A6aVg`b$w_(0n z7hCKjPjXQfu6^|nT+od$I;(f!Ed>t39q66amuj5-=nUd=y3xfJ)p?z`oPMP7A&0=u z&b&g)YlDCu^6wQBdsx%pNye;1&tq$6QRFO9!nz!6b#e^GEIIS1PEK1gu$;7H;H^3m z`%j(dFiUi(lclS(Eb3P$x@fwpx``1EmVhZ7@Nsc!#>?u=3qf@r)CrDy6x45^y3WeM zBK8H~^&P)o~LA8VHLQuec`*zJhi+?$aP5bk$@Hx!%9orTO*f~kjf z5RO4O2*)6x6wHALC<#Clg*FL)jE&m&ua8~gR}F(r>?MeKsE&;dB`m)sEI%yS=z%HY z>5So9uL5W<{`C$b){HR`FGR9P5|P-5Xg1Z}#FlIhk@^BM_2EpFk_FumDs=;qa;lVa zsFO0%k?N#;3|$IG(|gKylxoR(PiX-)(gJ$QzS9vxS5?1f`IHLs)}>GiS5lrJ%PC^I zdP}8xOQ)lHq=ZXFy@QF1=u#2AmAF)Isi^!h@D`tGH9T(vS!WwVf#C<;i7jpt%3uYx za6}910r2TEaC8|+0*)l0%fk`jt>P#s(D`WFo&yQnI2>#;?uExJoe!&XMHHWsxfDowsB|}{wsXhn6q%9vV2y@26Ej=i}(*9_nuF! zEo;0fw+{KN^~Fxa`UJs!_(|USl4$&Jw7i#%UK`N_&didsuv$?Pu5Z&<;NjJfdx-|f zb9XnM-y0sb%|-YV-~-WK zGrF;$rw^Oj^clb>zWp3VXml3a> zNj-_AIz*AFXVSluYw->?4NXR#(M0tzBH0d`Wg;#oKv7!(4BeA|*lMWxC_)-{7)h@p zn>9}ugaZw0fT=b!-q)&UsN0zeI+Zl{_!pvv`e4*00YU5r3IJ|V#58;=4&g=P|< z(w7rpHl7ABbWc%(S0VAi7veE&10KGkjhauHBw?<}WevBMGF7VC156{R<{+wgATZUi z%J6fXz6^|Aqr!58K4?N&B|CMfsgmbSm6+;l_`Tu$J2+o5a+aXN-$ZV zyA0KZkfKHEG;>($BK``}P-m(99946y;WzIwGj8ekKJ-)rX((QQIc39aO1*s8=LgZh zyAXLDbO3-K2uugCW-frE0OZUAun@pi1eO6%#{f77z$O4gD7k8b2v(c)k7}e`#(5DO z!ukUNMy@y(0Od|4z?9Y#VA@X-pfS1ZWMucCREK16J~meZ~a`DGn4%5 z70ekN>uU1JN;y!+G?ntHsT5UHXe5val1+H+HzosWq<8jG_N-Cf8iA2K)s%PE-$(My zOx{`Fj=T?Xct;)>IT3>w@4VKLo6v%I=l37^CEm=u3+hJlC`#V$F(bVbq_T&Pd<=oS zoslE2!Vm9)+L2vHK8@u6nea~3s|V3={c3hQxV0nr&lr-qJ~MWO*4^97y`~xCyYCwclF@XJ19%vevKK1`$ z?@gejs;;)-d;8XKYaY6~yQnIZfKeY8U&4s2#A_QG^nVcD2O-$q5=X6 z<gw-ZlT=584 zZIX>}ql8y&l8tbqgja2njnP(!!wrp9P1gyH9Y(5A(ZV+IaudKk!z7+SL79M%-0ta4r_{K=#n&_fV9Oi+6r-4(~Cfs#%L?_YFlB9wnFEyrWkF7&S6b4+6tY+nqssS zI)^pIXe-2FO}{}1TVu2pI)^pIXe-2FP5*_z9Y&nCLhqXJC*VtZyP3!cH%fTd6Eq^+ zDB<0}Ippv@WXl(H4(Uk`phN%SzX!J>%k5B(jK z6aFJQs)oS84%GDs?>P%JJPf}^ggYMsO{~#&g!h~Unh8fEy9u`tPDXgoSzs{vvk~5N z78pXfG{Sq%0&)aJS>*euV1YK$%OgR;LkU+zc+Xj27#B5GMtILzpq+44BM@rv@W)i8~3`yx#1anM>k*YK}#B>;KC$r85 zPe1l$DX|o$ax8_ODxN&=Fx9a0ONpg0m18ON47@OhsqsZJiKQ?lmco=+3RCx>>#|Zg zmO{^vHQ=MnUPE%(g#JBZF{w2WtnQI?F z0T+vnZ7OSIJ38EAF=|a^?!6AQqvPog~l0#gCU?%#))@x^wpXHos9gpB|)BF zHV6OC_DsTZXj$Ga)Nb@%m*DNa7BAV=x69gJz^?JDw`B^_>Zg`rZg`r+2+yso5q8L4a;vH4`ha)T80%g8R6M}Y8h5kkhy+p8CIMd z=ZyJ&Y8h6cS%JTWerg$3k=X|1ND~bCppk?@}Wmp;WEFeq$)H1Ao<}@&@@>9#O z>P(DNjNAOwGOU4ubo;4gSoMP3>!+4sH3;&spIV01WG;Z8t$u15R< z;q1WI3V+rbTeJ+Tn~C&M%dplHGb40oE8;MaKZi8xc@tz$sNxG4EIMXk&9uT@#y|oKyEd2@8y}bVQw{ZfBFEkIr1=GBt}Ou z%Om`7(m|vA=JDKGh1yZ~TipB}b5Yj21dSN&_wM)U&mTW)y5ZgsNl_*K06_Wt z>8)n&eH1CnS=?X8Q6&mwtC?re$E-5kGT<3}EUKIl<5n||T38+9Rx^)USRLb5Gf!JF zc#?72wLL=_em2IfW}ab8Qdt~Z%{=Xle?=Ty%{-zGR>ip0%+o<~ZH!yZJR=A<#JJVW z(@D4`#;s~~to9CJyklHg?QL7cWX8F?%`4Hya+Y%`xt>eXJT}*u7P2oL4WLL~YM4r$VBRal!0f6gII{+vUa{5gj-`Ew3w^5K*tW_bRR&isk z3K6x68*5dFs8!rpt3pJr;>KDPB5D;k)~fL80kw)7YgMKJQLDI}wJLHkp0id(F5Y(5 zswDYkaMr5G#dywI6}cD>YgKsSj#|ZywJP&~s8!s~S{1o?+gYn37jHXjRpjDrXRV4{ zjOVOXk&E%LRz>t3xp>=It0EU~W39?%2uH8t_Ul8M{M}5X9Ma@pPf#7wGGMI=VOhl;Si&%6 z6?b5%fNHIZfW2!~B9jsRC*bUBc=yl)zYM`NDf(`-P-BY+YU(1$|IaSoj*I|5pF>xF zhdL;yK*pcpfqw-Y|uo{2HIQ|T)@n?+V&#)SQ#yI{AtMO-y zkd$L4VfEBTV?E2h&XKqB5P7qDiJfyFqJw<=GwmS-)}LxT5~+X zbCDNS1v*}T0RdTnm`_FmaQPY=FY~XID~`<}zthsnd!+pcKB~7PI+e1_p^d@+6e273 zY1aK*$agUjNM}I=sd)sryc=ISYJzd`Hwc!zJHHV|$po-~i?d);O&Unf20ep1LMEwf?V3{K1f}#K&B<^6ZmP5aazKj zIu%XWh|x@GpV$o872~vot)?YnoR+ZFv_wqZqI?b7eKe+SQT{nT5y_akMVYlG8{@Qu zt)?a7>K5fo!Cz$*@)l*cX)+R8)ns`n716i94NY29M16O%sEGRRo$5Y>(TtwpmHu_P+YbY8|&ss$+qVd4FJGqF)1LyAKA{q~zyOWD(JaFz# zE~4=O8~u1|z_cPH!oc0h7Xg`3MB{;TcXAPp2hQEeMKm5bcPAH7MRe{?E~4?kxjVTi zLzkp^IixKvqVWKCCv(B>(jpoUoV$~YXgqN4PA;PHz_~lQh{glw?&Knl7M#12i%un? zRm37151hM`i)cK+-N{@-y~9Y-c;M42qOY5Y6cy38o}f|@eH)lur6Ts;o!kkU$9@XJ zL>XkXdsIZ0rck-aS*ZC~1cwYt(RhH3ex#>pJiy(_0#ilAMnA%78V~$S7-pKr1OHM1 zsUrH92}l)DZS;#g4yuI;pE0~&(F0Y)K$?`kYKkJ*codN0MUZI}Pr=J9mMMzjjexD< zJ$So{Pr=(=tfnX;Q^3zB;}{*%G&%%3C`XT~coi@vY49%LS8pYNth{an1ee@V6^Bx4 zq@?uA(7;h>G@@UIa`ekk6Ptt5FGJ0Qm3|p&A*}SvP>y~X%F!=FIr?QNN52f^=$D}! z{W6rJUxsq^%TUKXNWh^J5mJulAj(pXB}RnJ>QV% zeKVPLEwKBsXDgOTisGC}3cHFrq{CFhuCQ1pDT;F@DeQqAIZTb$lSw8iie-|bSSBfo zWs;&eXOhAm@*{BKrumWV0aXV(ik^)aCn;<-NfA@mF+a_E6I0hQ6SiZVq_EW_MU0aa zwwk1fagxGTlN2#dQrK#eBBrimei42XF?Ag?;be@H6t|JmH?}n7J%7LJE!Cx+Acoi7ML0#e$Hi zmJgFy5E28}P++8>?I2M@FQqfGXq!if!S<1EgpS`>^#@&Z0kp}oWz>F;FsZe8&If)5 z)n$cG1YRyHC&!C~yMR~xx?B18LphWUhrFe5y(aS94D03tiUY?*Pqm%O z}55wVD#7Q%6<)= zy5DM^EK*au6M&`qXYslacs~&ma zNCQM`$Hj2mpd8&nQ>yc-qA=J4F6dDK}wO+7rPXr8T*v!y36LivNKo?`J4)3U z_RDUh8NZQw47+F0e?Er&|N69;&4`C*BVKx5&?dq95mN9!9vSl{GR`x76nXcR!%)17 zpigONc6~K!vp+K7tZNk-#3{&g=HloBLET^3 zFTDprL^vR}4v?BkqZ{`Fu$l0KOTHV zqrj^tN9=uKoVStj_SdJtF)5QHzCnZ0qa-*v;v4)5KqJA)5uchINpNz+rzS@doE-7B zU5oaWEa2pbZz$uPO>lC=H;hRtE5PK4ubuI)D8S^1Z#coK1Sdy)9fWHWoE-6uAl#7P zOV1g0&_%IpP~dp7sPMM|`6RcP2PF;_D*ZRlvy+-x$K<5}X|IjeQz1 z(*t7rz*r>3X3~=S)EQn!lwcQOwLJ$$qd=WH!)V(^AC7`k9FgJ>JaVQ!%>s_g=Q;H( z;e>e;=w5pr-X4PK)QVEjQ|3>E&J!Xtm*K@s>`S2UQojC#0N`y4-Zq^)d?jTeo`3(z z=qVDMBG(fk3Dg`+glr^p0)4ZgH|-`k%GH~86PzN~n|2fI_w}aT;@nNU#pCH&Z`v(h zPDF3oE#@fK*|b~CQLeLTx0s_`XVY#mN4b~?;izz0F*1gmc5eqVqj)9}y=k|Yqg-bq zq?m2rnFuN7DA$IkU%=E3r9OXI_A;lc!Vj^SgkhF)lp9zopqdB~uy-OP{u_kf54E@q^$&lg9OVYnr0700)Hn-> ze-UIF{wa8wei`NZHv+c&d+>JoPr=*mSEJnceDL!rb4IzP9OZ^OC`U%QzWSR1dhI*# z&hV?tz4d+NC7b8H_DICaYqR6=+U#Mx_9VQMdKP6m@;9MoQP}7(hl1~0xQWfdPN-QF z!qJ49MUiHbP_roH&nDC?3gOa(nnfX8mQb@Ogv%3Z7KLy{Ld~M=1YDU=vnYhC5^5HO zJx9-`-ItJ*fF0?-igDznV3BIN8;Nfaqeu;5mtoyOhuZVN6F50Ke>ZuVhUmqtREDG> zdWn!F4be+UZ%VwM1;=xVOnk~6WRH;||f#E#y`bhr}yenxL1i(93m0H9>bOZ0rps2$MfyV zbNJQhMJvG^`zLehiaU_ku|E@B%xsN$$^fonCdJMm^=4*J>{)_q7-X!F40o_n7|F}C zIE^xT!B&P%J85*TDu9w8;CWI2g^XC9QK}3TtncNe5N0-ZqZawB&!zyuui_{YcOC2& z%xKeE9M+KG1K&>uX}buHxe%ymvb)&8Rs*fvzEOGlRQ(xi@!jsfG7EWsXOlGM0sWfj zKgc*9Xw_PxYUNZl4(7CEJbVva2E_2m{ag#gmsNh|R}WzTT2l+BpM$5S6u>_K)Eajy zhO;fYI~6{(z>x1Ukhbc%$+`O=R8R?-h8c;#{9uY_d`|JgOOf z3tvX%;~J|VFMdhXnkJL=pi0=6BU>7_X{Pt!rQzoq`7@C>HS%{6wo7A0N|v#L!f0l$F66X=((9I@9&Nxyh}lDKzKFR05~4NAUY0S4Qws2A!`8) zI0JQYw)Q()iNJPL4&m$P!D+zn@w!O6_f*^V=^==9BjTrD492hFP_qxOWx#5eY3>rl z4JByJ*&$`#g@{s^<2->8?c`295wr_lYbfXd0Sc?Q1kn*MH)@GIW6K=(d&kR>VCW6| zTwt{?9vXJuoH(nS6ZAUm`YPpg#gRq{dJ}v~(7zzSp#KKIXk~02ft*k^zbEX;OLK#5 z2Uh#;zXn^$V2^>20V5z}uXb*7^7pAvnZL)vsqJ6g2A>4#TnKG>5P)xk^1>T>&6D0@ zj9&x!ez@2C9Kf##{0zY7j7Fj6K1y;PCys&k4;}UtRT_D7SYrkx;iXD*FL7e^%nK33 zstQhR|LQil8Po!H5slgx<&6M8+vuFQ(J)feS%DkAmy4W`i=38=%*sXP=OT-9k?V4i z+jEh-a}cEJ04nrPH7Vt!>V?mlsvzRu@O&=&fZgDJPgAlE_e&*cIrX2xso}$1?$*s9 z$)IS5#Ai_gm21KLZ;MW2C5ZTla(><*8E}0ypu~{RhBBK@}FlHcnhsGai z`b^O8S9G&cdj0JORP5@^sq79L&()k4f%ExZ2@Uf!U5en!9E9E*t8_)U6289DzAgv- z>6~ygh(6+DHc7Z&=x~ij`yLeo_U9uM4-O>G)&3nPxE??pM_!VxKFYtZ*0uL91@&n`={-as54f7}Dg$U{x!y;wyyh=o{ z96N+#6*)#wk1%hb9sv=!zw{Pz8N;?R(8c0|^+fqtEHa0kLbrM1#+ISn<|(&>bURJl z*p`*sX>=Pd2O&?F0q(FpWIJBi*rh7A<9pdAE4IIpO%{BZSN5>ANl2ad&~4C{-Ha~O zboB=#BRhhTXPk>emj_X|!J_D4-(*nX)PZ~KrP|ejdq0Jj4o1qlnW1&41NTTZMm?E@ zwsa=T+M*`XE_Z&Pc^~k0x%2zXHzB%R?)*OUPoNs3jzd1@O%)&fyeS`3dwoo$4`b9j zi4D|qCo=Vr5mvrP?6 zjmFr(UB1S)p@SNRHZ&Vuy(b8E@oa5AeFk@xB367NBfD56d_vp0T0r3w89c_5M0D_k zP4fuHT4_91$kEXA!%-oWU2-z2_v?B1Jn4qTNn8F-Z$sW4Zr`Xi46b>$cMn2=-EcAd zy13Z-5aXna_W`>4w}921bJe=5T6vb6q~ISsE3V=@i(GN7B#7Bn`#$_@lcYu1rA(5O z3G!YKcb_u}(rV*Q;rp)kGI(|!0nk=lMs|d8GF-eh#Jh^YhYasWpW#2s z(U$jP0coxD?xpo1N^7O}(=bZLh;6}(#5gm@h;7G<4jO$0Xx|>xAN9Up=dLnbvo9Pla8Qgq1$;Y`EBfW*vibRjQGL1&e zi!qLcw8d%K(d>-L%S)H0X-C7w7`K37Rho7*T#T_E$Zcub(d>bObf;-Yv+D)9H%&Vl zF2*3+!)e;lY<>7$nszi?SI@X@Pt%Tui!n||I6I6C?P&Iz)F*IC+TBcKKJ94sdV)qi z?P&G}CfClV9nIcEAyJfL95k=J9JCmlC!;OpPby1Os24g^eKAH~+R^M0Ch2`?N5jP! z0;8kh#TbN(zXa@C!Z3?jX?;rtq#ez-OhDSv{3%8xwg@ub04KIn{(>GR1NWy%iG79_ zpAvK=A>4C|Ja6OhpB$QhF?ne) z3SG?HGxBNl3SB~SBA-UD(50j|<D74^Bp!t8Kz=dqaFzJ*6UPRc;r!6RSC0X*6=RY}~{V<${t~wu|Y{hgnnT!Ms zMxkq%xIh91qtFt9k$jr>LrV$g=hM6&T1L1ipXUA0wS?38H1CI&6E4Z8c|Wv*aCtt> z`=OPD`{&cVAG(fkO@ikA(Dj7t4gag5)ps!}HY#H11`>?~Z%_-}$aJ{!*@cB}B8yw4 zV>3X>l$YrFmUntQ-us|tVyqtHAlfC5G=&&b{Y zZ{|NPfUiyWNwJ|Xmr|l~okaBII!D@ipk=e> zoC#No`4nimoD}vY!>YKr07hIL;C9ORvfnb0DzAXu=}iDf5_ko`Ed;g$_%(qo0MZKp z+z((9fpq{@65!P6BLFIYrNtfu0e94!P5tHAF&;pMd+E)F{^mq3s^~9kE2j3B1Lr0p zPF|bYUscBp`SWlsT{FKJRemqTO>q12Ra_#QN=Y&yjMAUuO>)#49D96bP4-vIM zvm)>0XYL#0i27h5L@n3u)k>7lx<^aFDEKt(#w4AM2SGtF!czHi9Ab|Nam~~U0Y>&= zCha{Y=5P1mh2K%?4>`jlQdBj0k2w=u6voPugyeM#mf=3-z?J+JqslM%(d4AoV5RD3kb&`OjRp>LvL$WG8FIOPAm+wPNJe0N6#GPJp#y83ERcX9=)Y2*6tLM^acT z>aPL7T5&vp$}_a+e^V<49j;c)(|)8@RLy6~pL*k7rWKn2)E`oPSI9~AQ(Hh>htO22 zpJJ-_0NeAPLu zGIL9GV6${o&9&PwdR0|Mw6-xwTD4gU-V0v=5Bd!GW_D_S6PTy-Zh#+Y4Of6$TEhkc zYz+diHM|H)Gh2fwPeNu(AX!?%UjS6j(qeO4f*U8bDcz~X$tJ{tUrQKBYMqF5BWW}X zBWFFaHTT?nJxrq4Xlc?rRDHk%pZDk{mD1h>)1s#meBKtgg;qKVo}HWE*R;PV6MQ~b zn@WPmf?E=NHUTDB04Df4PJ* zU*?t@`KY?kzN{V{MCHTLm&UnkiEb2WWPTIq0L(m>&@HkG8Ox(D%`AQ1L{z2`1^oq4 z8KDTuiy>9lT**>sT@6&a<{FmKBA}{k9`nULkcD5}WDPvPoH<`3%+hx;?q*IiOMBZA za}_5XqR(;9WBbBXq4vYl`C9qG7%O-XKe#@rU76Q?ktNLQf9ZW*)-3F}haJL#u~Y4L z+La}7ymm!N)OvDC;+!5|MqNPDnI5C%b>yk_1WU-`_hk_GSz1qQ0Y0b+6;gvdvqys* zC|XZ2qX+R=W$TIc1bM2m5;KU0Dr+haiB(i%u(~Eu0%9jLNL`b7O&+FbaZN7#@Uec} z+I#(B8*YX^=JdH2op-@GSq!?)y8t&s4|Q&a#&I1fE<3VyVC^A{P89-gaGtzE4^EoG;+^1Q1}NKmF|H@-zM z`5sMo({nAPc%}+0rzBb~@1GzHE;McDDbx0Jy63qcAVrzBM}U&YGuB+y=g`p>n>O4* zS;3OZQ#NgaUfX^Ke{P$>IS4{7srFvJ2c$5qa7Lao zH#7L4;r-}d{L3ZP-j4-T=H@3!Rpw?n%R2fBe3BSr^o{77c+o+ldw{;tgZf}@_96~) zNwxP~g6fiL@B8$puViH8f{82e#wFDhUj)7a$sHq4nVTt6UGrj}a0dmdy^uUsOx-+S zpLii)S6uCdq(pVii+!?4mup_^Q@G(JD%ZT&(;jfcC>mFLA@@KGwkx5c+ous$*Sy%% zxj{r<^8yoh83Hc)G>g)Xn=I|3X9*|FXF+${zrfojm@MMTQ*X+AOX%<6-RH-6eSs%M zAoUnub&von7{Fb={qs;C<9iBGAHEn%dfdj#_svecor@C*tE;1Z-x78%P9&U-(?ae$ zNLX3Ov7eHNvXEmxB@tyI$9_s8onj%!eo7+a#6ph!lth$;9Q!GWC<{6EQ*K5Km4zJp zDIW)-Eaccv$p|Y8IrdW$Q5JISr=&)wEaccv$>y|BEaccv$-YZj$g!XDr;w&Bjj}?cbu*Fr;zWYZ#feO=b8#YtL{Z$AgXXqbrct(eMq8>ZsVq&Q?slm8 zM&A=rLdCR@V?QP7#k7!PKc&EJ5P|)agiF{q{Yw~T2`%LQr2^7I?q4P#E#!feMC5qz zcDhjk49_6^mC!;SNRv|Pb+HEsHZBEHwg{k6HU%%UOjeqfZ3JwU?ZMks#?I1RrdFCp zxx|)F79FHm)=Owv4|Y(FTkcQH+W|1t#*B{c#Op<%l6KQ5QM(JD0Hs9jE@U)I)b7Id z1l8_BVVHy@hBpfXE&t(%$bkO*T_EUfe}zBE#Y&HsUt$Dt^5Gbua%oDWvXI~^w3SGI z`Ze;tLW7M|(L>&OAV=HDth2)I$1b8wHWiksO@(=z(d6u^lXIAA*r$}qrou9{sW7j( z2uuSP<}fw#jK4D3R9GgP3d>|uVc9(pXO*cBFW%b|rF0iam;+)g3A7 zzE)RUZ7O^dWOYZ1J%+HlBgGy|Sly9gA3<2%kz$V{tnNs$#}ig}q}WI90j%ywv5z9G z?ntq}M_ApFVjoRd-H~D+Ls;FBVjoLb-H~EXAgu04v5({7km`;Udm?*Ibw`SQJmINE z-W`RA?xc6Y6eVRB602JSx{l(1GVL$mlWmqzrV(FAI7`@NRO=(+*uqrx8q+D>%1pmCsciHaTmQiigfXo0K7a8sCpY(NM!**AWgBZxO( zGGry_;ll}P!Wn+__LcU=oo~l#aj?NO{!pix^fPnl+ccf=2&RHX0}COyWMvUnyqS>U$S>kZkwrZ3}L4VZp5SN0!eI%hLRvX5j`+il!0AZBx5( zYh{uZ%q_xrvl?_e7!(DnD*Dl^=&IFCV5_^G0%TM=g#!KnwEhloKkxuB{5k=fGg^WO>H&c6 z+c3}}t?miDs(_&&sx>cns7?YWveEAh2g_}vahi7LZq%8|9Rot6ai*pp4f<6%^qV!E zm1BpZ>)QXBwi8J0cT(4cfvJ=?E8_xW;E%O`7nb&U_G!UaL{Tr`46it%Q;$^}cWBlV z5d}YjL)6`?@0PmrYK~Kxa$@CZ{DY=XhnMl1J`WxzVT=snZtRvt)ocE%W@F7~y}E)~ zB^8KeBNeE~@UUhKIh(~<&w{a-_3G}DdX`T0vlwrhEp#%5tRq{Mu(3N)Y*oE%1B6Xq z&G8I;SnP>fWyM&@cHphDVyt8*>P@Sx7%Qm*)fnoGG-HE?IxC!l+lJD5z$ack)EQ~! z4;ktVMH5#Jb(U5&XS50c}_=1p+}yKRL;m#(B6@!LVHG@g7%I)71}fM6cj}*BhSkbgdTbB z1qn;l7!5V@Wbhn$K8k-m@)S^wJf9;~jXYnarzn#}Vr&!uBf1+eI%t&Asi`WIBhMJ( zphunroslQ~>5(TR7fdY08zWDOF9lx##p`XE-hC7)XI6T@9s);o1*<(MjFOWpSna_J zS%`6N%e2+D%s97Y+G<;7oZB+(HaT=IpM9%6bT`=A?;;#{|3cM@)ibKQnLl5lIB>o)9Bgxlj>w_%Sa+!^P(4ZDkQ zS3cKm*kcHfi?^Wjw#TkQ?De)x?}1_^O>XT^OsENnG z*+ZTp*@I@+bCr_Uo`!dF7TD(k=p(O70Kuh?xHFg4q_NG+^YG=hnZ4GX{ZKdy)(hds zc#D{w0Q#^+^kK~V2+Ev;r+4u7Mg3QO0+x8X3ZAbaj}bpm4tVJ;AmiMMb(KJty#gdE zO$Z|kDP_}0aljH-_a&TC9IyoBF!mG&ECD%;J;eb_V3RO#z!H$d*i#&^1ahxTx2nhC)mZziJnLNGHipMen0v;Zmm7Nlt8p^sfi@E;Ib@g+9A)|!KRkSS6jULu(Gdogyp|`~<1UyKviDj3{1^^Bb@O5~J4I^0i1%gS&&s)L% zc`<^CpU)&4@nMKn`~t#u+(J3T=P-s*sd4eSb!5q(KI>E?ej(xfIL)B(d4v;2FdDzI z8v-N0MmEK-BB-MMFd&I`#0VziONM*cBUFHA*$yNq@;2G86|kOBSuS8dQdbCA!APwX zun)oOPKM;j=j6SfsfoN#s;ml+ET*^BJRBgBB6x$uD8tZh6!1uTyJ<7L8HIO&Tou3K zG(;$VA7xz43^C%5626(yjv7`7O!);&qIDOtH9yUc(fSB1i6Aq_`Yj|DjN=y0tOwMn zT`=QAN}LO%;H<>}@ePEKg0mTrD}H+=;ByGO<9Co}CSgx}1L0YOy`|Ld3eKe%+!q=p zZ9g8#L@&<8DtM^S3#na|pgp8QxSJse>@tFO!GqOc2+f@h8hsjte?o3V3+_LO{u&t4 z1Kfy;0UhWCKVdey;^&b5C`H>w;UoyO3!dk3l`1JOsDN&whaH4nMwx02eTF;&uFM2@ zH#3*wotK$}s9Bi~@VYXO;O)*_0C^s5Dl6RIh^!P-S>YE9TbarVzhUiFrn15Vgq5kR z@LR&lR95&MVPz^SJV>~zoQp{du}T3*L-}~T3r#^<%a;?$6Qr~JZhQm^U4o1&=VH=A zw;&VBxtO%jBgoWpE+#Fs&9e~0Y2^hJ;5W|$GNXJZ5xpt9oQp{d^-ap`VaB`~$kOuX(I5-;?I`73Oj@XKQZDCW(n5Wc zayb{17V4Xn%h^pA>YJ3yPbJc1et{6SmY!a?S8gtG%TWHLV5R94u{ zM2e}ba6Lg~Dl6Q;}jSeNWA5I!EIjsN3cMe!XVIUnX2L!3CqK*r?4~R`7)?f1ZX{$u&PZ z78H_M$Gf%qzeYdrk?)U>JNjz2hf36$+0W%@#B3I#!S^eg05lyo-S7b9iYq< z^!`hrH8f;A2REO!Q1mpY9{aV}?@*s>{aci9&Y{-EG*SShu1O=MKu(8*fpTO_?Gd>i zj>+|Kjz((X;TG|L)0&L>D>V6|1Z9Y209nbz%gg{HC%I5)*pC42|2y;+=9^63O**2- z_N4zZ48W>h5C&=(!*6GwjUL5(lL?+jbcLWS!{>oER54?BQCi;WY1OhB=xy?b*C2`8 zbO024E*?aWr%)lKKI@BvD%64M`r3i!M16PbKy1Of2$}W1_B;g1HTruPsY@t%;v>rA zC`6DybM2{^V^gudgt2Z!&{YT6KMJ~us3bzXze`jSaS0Pqbq5|v#3dASDo|D8D_PfYiKoF) z34d>ekZ)623!mT@!dm^+6}2a8o=(<`>osx|kkw#De&yMxBcselWE1(3M`o*0yG}Do z<=UhXsa!8;gmr}jP~<%8%Bz~3TUVL~7r-c{Gxam@nm1Ns9NfZF2u?@*TaE*;jKEj` z&jP6L^QcP66i8Q9j#0b<@Nwo)7#%3_YRv;se&&XSj@12*)IN7=sqFyj*BmO9IZLtg zMC=Hxx|ji3pJ*mpiOl;RqsZ$(UQS7i0X#%tK7iK%7T=*9=k>W@<#L z!cR1EFTB2?!(&lRvi!}o4KcePPnhv3g=9c`f3!w+HiHVRZt$voLW zS(nu{jeDz(6wi~`HW=GZqqar6N^FN|L}I%~BhSDemq{_lVUDQ_=-z;ldFqhJ?EGIx zCSQAIwf~J4ItM}rX!^?#nirG6tT|sXZ_EZsn`7BfX)|iuwFim!XpKm`r)h-oJ6?&R z3}n`q|2}?3?bX_wbaEI5qDPWmoBfUS+Es>qCg8#UWPc%BBx@g*yf<8`4AB4a2&5{G zpv}|JvW(zeFhF5fl6l%*U{irri2?I8jsjQHar#VbbUf`P#&y!0;gG%4 z*u&4H-|BTvZ#av+;XOd5H%uZdpVh5XK>e+n`*q|NOZYPE;E}7Pk?Z&jOvK6+WI4Jxqwapq`bV(d0I^_%X;0UqE!t7a z<98a7^7u|8ERR2mH`vCdJbu&L@O#t10-lG^{Er~n`0ax??v!VLG03Rxr^!-GQb5cC zDWE7u4S)wf%L0;fJ)KI^x2J%9n?RQ z0q~H3`cXQJuaREntm%QD^0p<|Bvr{mH-gYt;AG-h4$8OC0fmdXqN~m5oa>byH)mOG)M% zHVdk43`?@UK^J)$GZH^@Ex&3*L>sJUv28~F)sE9#34}28IE`dga8z}$Na)EdzVT;1 z1rZiMV6u7FI`diJvU%4!b2*x&>S#?K62~31|N@jP=f_Fat8#@jl>U`3F=`2Tv_Q6wb5E}j||~=LSkMYLLH|ghxqs(9KOF1<^nv?>E`esB5iz1oAZo3cyt;4j=tzBTaYXG9aMkD8(k2qjOA7xXnAT`R-RgMb*RN$_7q$F6q_u(l0C&%|2BBc z-BWB;cT$vEf8_#bSiO6St(8}Sz&*vA@o#U$%h^~=f@~~yB_{*4Sc0;<*wyDuf;5Y} zdUqGQcOiXPkmXr$jEUU%Lm|X2?IfeKAj`8%P{%CpxmKatEbdt@sACrQtWc;ni+ffI zia{UD;+{*nUPsL0p3C0=DZCdiL-zlARx$XX;rVDS{>3cr`B*@j#XWl;AeClu&!;~H zXhfMT5@U?M5&Z>TbkHcJzubfRqMo$f*E{%!$X#U?_YPSP&=#|}x0P^I%;Mg* zI`AaLEbbl3@ReEIt4=GVS=`&s_={QGJDi|0i+ei=E3>$F1Yu$_i?A|_d&dw~W^wP>a}l!%hU;#o@PG}(V$zgZ+#bSsi&@-m8)3s& zJ`YZ?CEB*(Iv1Z>Z#^wTUb_SDq6@$>5kOL2Qvt!n5_jgTI)2b%hS_|1ZDwh7BiOD2 zDj9DYeQ2rntrKfHE!DnmitR&7wQoJ!Kp$GFeVc@VmTKQ-VHi*FAu<%c=7CuM#Jvz2 zzt4-}oDIfBA1vugEEuqrTm4Z@2=AS*ED z0NiB7PhhN2x#A~q1e0V$*~sq)tK?FD!*wLx#?1yro8eu&+cG$cJg(*Fwn9z61?aVR z;VmWeIe;W1J*%0B(3qFtY{$9JGjzl@z|r`L^fsQNTjTBIKZ^YA@ry}6nqoTR zi%36~HD;V+V{*Mi+Jq{&tJQe|`8{(v?Xx ztoGN->cQ|q(yKBwiG~f?9^a4|4-%&A=+c^5PDJmo&(I_q*8A%-^C?&Fug|m+(fjK& zG>L|7^H{`iTBd*k{N`jJGcq%Y=>7E>nnc5Te|?5U8rJ*kGq(~cl-nB@W@r)(>;3ha z3|*2Y50+n?p-D8HG0y?AG((eUSnsdT&?Fkx`|C3_iH7z5`V38?VZFaTLz8G&@2}6$ zBpPlqcO!(Y8Ja}HdVhU}CeiR9^L&J}!{|$sXjq#>!`)1zm_)>r&?Fj7lcH;Wtg#yTnqCB%MtTZfW?D?5 z>5YJ`^d7uj=~M7_r?p9x)wTtGvPK`;LSr2i;I#`O+0~7T8*gC9h1CF~@gclbPaG}b4SczpEbXO4Uo5$ks^oK6ByzdHe3LEr`e>j6|&X&;Y+z+Dis zbs6I!?l>8WR{oui_X}|U8nT?d7d{IOT*Ba1w|U?UX-U5VXA$B^PVTwRv$q>nCu+yH z;aIO6>8Wy_rhlM==gv784;*cgvKga^)|{;f4abHcSG_hrrT8u)I@M=0hwB`ENKxrt zYXK}9TTRFHAnia}%fuW|w*{W#cLN;&Ey=9g4cDWHPKW-hn6Cn=GP|Cc{WG8gZq)g( zPes(tE4iYGtKQ{}zvE;WISF5TDd{T<7-KCi)+q2%K}v$ z$Fv(BjDhs=AfAK_Me5lY_{6r=hunr-QJmjceT4j8N$B%RvrV*g#k zA@-8~(S&s`>F=5inHB}RhS$LH=-mLl_Mh+$8+qWnMVJY_LWn5bB^cSV5ZKT8w9uYH zr2Y#=)(F{n1(ebenoC$I9U&?m0i|?=ZY8Xgju1x~0i|?AsdNOi(h)@kGXh%ah%P6h zm5wNtj(}D=qEtEpTIq;V=?G}0BTA(sV4Kf?HZ58}0e*7_kQq@b9f6?92+xjE=?Fvx znJXXMK-^pim-$gD9RWQL8>P|_&`L*?N=G1R{sPh#N2zoKGUo4qER9m>2=p@<-&Ij6 z9f3NN*>+o$N=IOzAl*?a9f5j5?u}CE2s8-taFj|%pvh!@Z;evv2sBIFwnwRS1O}PA z@wdZ>QRxV*34Q{;WT2ag3^jW}T2BzCxG+^4m|QzFfvlUDS{~}N5;U*v0nK+GNQ}1B za8g;CLjBC4<{NP;9r>Jx4U8~J&*waBpi{wZ5D^$DaDYlja0$Z(MILDbVtTFftQ0WMzNy+ERlyF(zOtu?)Bjs~tN`&7*2qxG>5dp4Di3|~t zD^nuF2)dp??T;4GoZz~LU~(A22MP8e7#s(%J({Uy@AnGH#g8K-BQ%q631L?#uLf|I zupPRD^ismXP&MJQy8uT+-x4mTm{@28;fnh}Zwb9dxF6wG!$;P3ut*ML;{rPaJJxb4 z13wwvKx{B04Mm=?q{W3q(?gX@b)c%# zL5_xGLc02=;7%H@Lgb7&U?-3izY^vXjDO-uyzmPlb^Kv#Hi{`N`p**t^ELsMpq^k* zbBRi5PcXDU5&b(O^2GCC9{Xb$;dT<;O5ryE?aL|YU2ubS+hSZ{aAOQ#Cqqd`7QDZE z7J*x<4_uKIP3p_{!2RUCP}7*`SGUp&`hhSwU;nEIU*d0=7xw}93_u%z^4*$gXb=h) zr;_p@qTjQcIv&&#FI`|6hO^H)PU}b&oH25uWmJBtJ#Zy*<#!r61xUZlQz{k|b@m~m z&ONNCes$WzIq5{5RLjwJT30{wP;6 z({>!iSKgpmBptVFMAETcBe%jc)>ku2RJ6<%c!m|a-+yV24dCcJgrmu*{2*8G-dw>x zY9{zGgU(mpD6LSF9|U<>k2Is-08M`i^i7(*k-1}MjmjgmqeTB0jY#xoYJ{PD?t~&G zdf@QIut9s+2@lPv6G*Sma{n-iHU zlx$tShV{zKsb2j)&>mhzWOxM^GoR(XPt%!6n>8JZV`cnlm8b85j;@7EWxX~VwvU<) z+m!T8VZ-`4V6V+yAw^Zsy#GuveD;L$UZMWbv@i5S{b%F5pHgPuhqf!a_x*2zWgAgZ za_@fysC_@i4qs^zXlL@v%Gl;XNg&bsst_h8~)zXQj(Qmi*VBp)aPJ3uH>i(+9j(oZE zt9*^72EoismN2CXF!53aB8J7B9QbS_I?`&U)M6^@8<1UAHFeJVAp+8=!5FBfTaHKE zEq0mpYPyAv^=i817J_QJ`cBCtT3CNMtFP* zM>YB3k56G+Q(sW{6b^1`28B=I*rvIl@F}{nX%GJR6rR-V%w>e9o6XMDO0sWWlXKxz z{@i9~iX+*a*W%3UG&_?f;q%SLLuX2wzd&O7B+tle&O)!`lT7Csyd%tI9Qi#|do?gx zj)-yZdZ})LS^asu;7IEEvI+fvni;XUm*9|@5!p*%$!V*(dkL)E(^f6!wAH(pz~Y&2 z&R&8;21auHs%#i=B`1JK^m^Ga;OcW4@tu^!(UL1gP2PTkIEPGby>-B|fTgeJNJP)- zog)#ncaB7%J#!?2_Rf(gv}cY)P-L9Uk<3I8xpO3+fv&a=cvdlZ&XKIgzn&uzP|cA% zOsbkAc^04%-GUd1danS}M+c2EdB5sGIY+`SLeG&9bmmCtPtTDsa>2w!cw>%);-lb` znOD7az_X7cW$S?F>q*ea2fX#1)b-lO z;w@|be*~b9ylB{f3nyW`Hgj1G)oo@T4kQFYb`AIza4UmsDDc``_b*}|2cWhNu#o!* z$|%6+cD#L2-&OB`MYaz3t|5;y*!z|)q%^g4z_;wDK=hDZkL8u^-M@dX8$LJ;)^|jS z?Oopy6=&nocSMQpUEdKE=P+2`5hb>FeMeM^!(hK22B*f;vmOSgmJ`v#;1q|!&K*%H z4uhRLqEZ|NJ9k8-I1I)eQ9nTpr=M^tJvUG#F~6ot|9LUlXhrxcm967~duyaRLio;;%j;Iue!G66Q zImKbHb4OH)!(iMI^&vvon&L3nxg#pYVKDB9`W3?2VWc?>_G{a_znh5^+q-`~L1laQ zZ(wqj?Y;Mos7pcf+W&yCD0CKs(Ux{gDoazS?>p3dBg0{^oNbFcqDYssZE;7Gz-`Ql zkpj!vwt*!KQ_i*xEESN$;J`8guY{zaT8?}ns2yk*B{;hme{!~MFilEU4gErm*8nM9 z1o=kk6uit*8TyrO1ZU22 z3a`5llww-8!m|6Nn3k=u?0zYxWh=Z%7$y;v-7m!)%!Xz6i;iq0UEoDD7ndSFrTuFW zS;P81K7x_rZy?*3jbu4v5>LP-Qo0jNu-eA~m$AjU;-g3}Cv3;Zpe;oz*yy9OUp~^0 zqLcAO6jw=}jA4CCq<>f6W9-D5egc#!GaqBh&H<{f{oKNkpCl?FKf!?a5#NEdC(WSRNo` zKDQlc4Hv`hU_KlJhwAoPIJ`oKB-(Cuet)3YNF%F{OYSfe+IO6 zB3*yWsPZm~>iI->v2^y6nLDV=-*G)p5{sScyg|eG^V4v|Z&eshZ;Xb=fps7cgZscT z0ILWT0r)w9`sg;r-30>kZuJujU|M&rzHNaAGXS1BxEhaVrcE@PpjG}-i#{IA4ew~= zhd>$|wHU0NJJ(fFB)F8f3N%(b)>s0vcYVlp3w%E{cXW9}afOzowv<5y)b9c3wE9dm!k zBXE5SJ%L$ADYJproOa0&J4$cfylo`f~)B=^p?v#M|528=9%|HtPk)o9{90t&RY_O$4Bd_kP_(wzGI| z`@->Zk>llU$4k-U@X}PLL%AG6`XZ4iW0Vof#~nOqeO1C)p3A^?v}WUJr^9mD#PxRV zdLv_^Tromx=+@-BKyLWCM(!iBPa}^LDbO)~7D&^{8uvi`#yzf5J1RCEO_EU(S(ZSXs2G5Tf;_7_9c2I#xMFhu5PO89vm zqBcN(2&&O~UIzDF;fW4xbJlL<%i67;Q?gYk&$VuM<{A(2n4rsrs{_=&A=!#5wC-nFsBF!*>+ zl(V;7#>8XMKdS-Glv*{w8L7L+dfjFs$Nc95oV?tnUoybS`)>oByxakfv#yIfoh=!- z$e6{FF^ddWEE%r2U9JT&M99M>T&|uAXFWVq%hhv*gNJ8oxq7Z}@bXM8SI-p=UY@Dt z>bb(f%QLlHy;nHcF4v_45QL9cIJhp~h_dvf&qTbqv)Q$Z!DA)RN2lOFKqHCkV*xol zaqT^qR1QyEpK=GX5nPEEiJ?)H5xfmAI%t&ASM;FnsOzm~fQ5O5gX>*_Mwm7V*ZcJ6 zkD!Ng?P27C(Ls1emH3|VjUJx3_EBV9eL3CfzXQpa&v$;#=i6QUHt6oGJIk9Q!u))@ zOBsq0=I7fjrwF;i{CvC18BIIPkDR-L?9p%+lIZS7(aA7B-|kBCWUxbDhDQ8|yZe6! z=O8BmX5*0onae1+1QN~CX`uM5X(yI4M5BqS6^3?*ZS*=yUsghCVKZV-F{@{r(A*^w{ly@C%^VOdq{nVC?$if5K)2 z6VlcT*}$+K1%j^8wf|u1uZXrz{TQPLd3hYpXYwZu8T&(l=0I3FVcJl-KCzecaa z$2;73lr`V@>x7Y=%NarEzMpfsLJ9&Ia=ON{o z*Sl^sZ{<}8_ut+{W66?HSuJYyt`@a=SBtu2^4NB{7jz*FK6W+kp038nuEyQd)%e)e zxO=)9Kf4-tPgmn-SL5#KYW(bK+`U~*z~#R52W%tkYTTE?+4FwbPQsCyNI4;b!` zZoq$-U5)!=0om2K_tGd5W>@3>l=crJf|_oS7(IeABHQtzgGMQxh7pC@QTJP)1B)T@7`zTUYi@Luqf@6W)ZS5KKSHLk^ zLOg>fq2?Je9-`n;t3_j6PT^@?4{|idLliu1<={!id5D5%=yuSvF&?7e8O9`)#j#q{ z)6V!;#Bqp%XE?#C7!OhKbP%qM@el>i2*M399-`psB-|3?Aqt+6gj-|WJ>nTfxIM;0 z6g;B|cgA>#f~SjcSDc3^c*YPO7vmucp0TGOW_q=#`@nZdmBpkL+y=o>?-0g2#&L$X z?NO+a*!GUqqF#x%UM=dW9|#_-^uW9D0tyCDB(Gxt!R4Qj=e3!$dZ7X{3~R+0%o22# zL3`kfph!vC4FrwYtDxJmG1H2@M7V`~O?ATB=NV}D=FU~tVY{^-_x+J~* zO~?tVLM14Lny2s&fvZ~Lx{f|C)Mx3?u}U%|^AkzJikx-vqKXN&5;;Mr7Q!Cuv{t4KfQ5&JLpw?JK@D1)snv z>FZ`9V_at7TTjr4ahZW{1CwjVxXi%Uv$pYh(7g6AlwssPa5CCbaY$up3bmg@%{NlC zucY|eq#GY8?vzf{2U5pDl60cl?e$lAsT(|k2N^);+Z z=$9YxK$?_DH(q@D;*%pM9AAi+ ze!%8jzZE@^4Bmf4my3zkqE(qQM#0-!pry05j2S4%vNal+1Eidz;u#Vw+d@Si{dMfv z&H%CaTm3<;_@pPu4hG4Y=@QxJ*1;Ba3uaPFWSv{bdU#ognU$>A8YZ*zIN@oSH4bi9 zvaUd&>miH*W17vV4CvT!cD1x`PCQHNHF6UpeS}817F_!+mzlcB<<3l9@kZuZG4ss% zx=&JpA^}W!iI_u**{f|toJu5$#f;)Upjk;zDbpjUS1${A9H2UawR)d`lvYcU!nsOq9T_gn{q;GqnC9D4G(~X}9cl(fZ39AcgkgWoZ3{!BcD5Gyget{PqG)n2*nxatZFWlmy^%vRgqV*U0)B20-cFDhh zz6=r1JsAm#@6lg+cDuM`w~M2{a7&2RUw+6cq4k$d0BxlpA?)ZcgdP2bu%o{acJvp*j{ZW}(O(EV`U`E6J^G6cM0UG4`U~T& z^_M&}KSzIIw0rayei+qmm%@ucp9r)_UQ+?V#S-^_+3lh>x;+yyXF2py9pb={# zJee@3pq|6OY;^HWAy^hNG` zR;b+Q;y;2(G9ql>_kdM$NpE!Vk2?nxXDul=x&%g%M>e_yn|=w!($=8=e@Iwm{hHzxp5$7F|sCL^ql z$qq#YQO9J5;^r#2sAIB2dZUXRlN~BD@d?t$WQUUG6i8FYWQQ{589>xA*`a>s9bi+( zWQXcZ7O*-dJ2X%bbxd}sUJ!LmcBnxRbxd}s$=nS;>X__Mv&2mulN}ml&O|u+nCy^N z21DIUq$q=-|A)OVfv>8#{=fI#@N%;+FJxf}Nk{@oAS)0c8;c+V=nHgZFY~ z=FEQ1nKNh3ox6viR0fl7VRxl6m~^|~1W;EF;$q#aFo%MG*=#|;jOA>K*mHHPc};dw zlg)T>O?J{K33HiD8ZF@L_W&nf%sR8F3?^?AAeF)7O9V(|Fr^n8lClJ`&jJ%KlKcfT zP#H|=&6pID-+Lk{n_6IMBXuqLz)Bt+X!xF0>M%1s*r&>jKs`%B2FZ!7gD1KiBHX=p& zN3m@eqsas4o^PN0iyz1a?LyP}v3G8d)9pH$?OKhR2MSxy$z=NPG01(Mee&}_r!75S zXpSe7Y)WC~mYtZ*POL|;Dg19ldjDyU0K%seZRCNFa9*;CW~=Bg zu~YY}z>Ns>e?kRlp>G!%a6g4r`m&0?3(?wvX(lhr0Nc)El?9v!t$|fV`dbbBe4$wu zaJ}gbTUEZ$EDN~u%tBE1sE|F{&EUl>t%&`lX|3$8Bm{?yK{3vbZ*D3Z&D5bXc<-jN zlNlT)gWujHpEapH5y*dM-j@oIdcvt9?>(CaRjIMkdhbeXvgcRF5Qvp|Q2b1xeu(?vJ?rGslt-7a|SL)-7w5m#d#cNtgrB>ZT zLn~8rz^wRYR8@LfeC0UA@S9Om`5hF`Z^G4;TDK2XR_c8~T5aVIg1Aix--Mg0^jV5U zi4$X;I~#&bs{UWX{L_;w@iER4{DtKo>s-unw+2hU!tcpzYbCOwNEc`VXnJFBOze+B+3 zU0;Aw*B5HPv{h2Ww^HuL4^D{v&`HEI=KL^mv0s3a_mmAEpPOdMI1vp8+dfpFT=j*WU?H>-vPXuAd7Wt?RRX zt?RQ(O4n!mm99@v>-vPXu1{F&`h>NvPgv{vgte|uSnK+PwXRQC>-sc|D6g#^9|^M} zyQX!0wp;1?f50-Mb$vD)&QN@^Jy=l!oS<8Q-^|sB9}6H${7eLdl($h{(B;Sm-ESZ! zmID@aIhxr8eKFL7Vp*dw@VW22ie*XYbgsP5Q5g8#zwcs=!ocT#L|E!{?mq}iozDH3 zu+-_?PY4gpp@9!C2WOx%XCi*_a&QKQ=Um1>KmB$1(ZN5Eth1gN!<>2i8x*Qt#@N#el+Hlsi6z8o6(@N#grYI9B>rexa{D6KPx20pwTya|DAIW+L$<={Jjusw$cKD->9lyyT6 z4Scxmg@N5UH1Of&;0$~%hjWUTgEMe<4h?*GIruLS_-+mje0VuH+xAe-3Z@LT$Dy7_ ztzIi3P~!bJuvM&&}332N!&`a5T8^{ zf_2lx3&3j#r>2P)fDa*@owk!W!-$`k_5k5p!ue?xgohI@NaKBTNh1jNPfH{`l5k<# z0OHh9A{3|f$EiwEJ>h|AClaTDd^*T-CKIXg6|^?{UVzEDY-aB1sNAlObF4Y}K!Y;7 zcQ7JyIT$uKym`{TMoyIGzg)qO`FoKTy?og_Td>j<+>fL~4*~cgfV79vSR&Uv#^O=0 z{9~Q0Q7;09K-~+VaI`{WNk!70Sj4Aebo+|L6CqY%mBMTH@X&j2(Jt0&a!RfB7z9j= zHD?ZnU#`Es%H{eyP8IUI9e$Hnp?dvS9mey#3HYc6uhq2ymGqEqQaS=~y4qdb-b*$$}9cy?}yF(+M)UM%4efUe*8_B)u z5_Yy*dQ!`4Tht}&zd^LRgq@(igq^Uygq^Uygq^Uygq^Uygq^Uygq^Uygq^Uygq^Uy zgq_x}$R+Gip44%*^paMWu(yCc^(E}m{?^5l+Wl0X)ZapR!jn3<7PUxsYVF$G1HAU{ z?b_Uc7Dil~$0G3gxi(KkX%W}vFalqMYx4rs)5W!!om8&P1hs23yBqD=oQSwscPnO6 zJkQK#_Z)*PjOA>K*tI$~%C(vC+O=80T$$n8Ojx-#vrgsOEI_Wz36}_vE3@I+{BvN! zwV7`UQ?AX7$(v9CW^hAqy^lct0xR?$0cby|SjwPxspd9W1w;&e@_VNC*Z$B`kY0Ep zds7JMZ`p;yAG+{Xz)s-{_>C!CfZra4${%_T@cE7Qhh{m3KlCO9#VAGmq1Phji2l$5 zp<91w^>l!E8$gQrHUKg7f6-OJ5cNFv!Kvj35#v0a2(X6QTVh^XA)hrBw;iPwKZ8{9 zezUXzn~(~#JkrtzTKIMNezWv?BFBBrF1iYTW)0bugE-gjYJb67z8H*VuWQ{$D4&yT<$=rfyF+{k0`hFHLcqn3uZp9?o`>23i z@I(CI^9V&eKK9O0urm~ki%<4Zvb_H=f{zk^KU2zofZ(^OzwGBiwS>Wwn0gnH?`CiX z>$#i3j~L_um3@y8nvcNzwUx-<9FL*`JFJ0ATGw0ly;Bgn5Q!ycB5@G{an1!nkR?8) zPahP2t+Dctbt6V^AWSpAVD--PbSG-cEi$N;baK-n8A#~p|m1RbgEA(oA|NTG0E#8UAMh45`4B*7X6 zB)f_z?$@B7swO>*#LA&6@Dl_o7OB9~2%M_2RU=!RvoA*W8106W*dSa#eLjA}a2vyO zdMei+kc*}_cC*T=xYdZhOhv){(f4Ny9ybgp%B?A4@DlReN zpH=baBmP?|{zKruE#hJ8%CjooRq;Kb{FPzaFa~kX%a6(0QK1u`H;vtCV|Q4)c=K0T z(T^oYDzYI9lF8Q07VC1IjCD!2;@K<`gP`9MxS9Yi3X*)TC*_V+r8LUIK)E3>X0bbv z2wY-sz&sZJl=wH07!NR5PujeZ!NI6c(&m>*n`bd7X!9o0=3@v}39A1JOHF?qK|%Gq zNOltuEIU`#zYlHY@*zCt&3@MnyAN4Ps@dJ9oA^Bj1^ZmaCiVcu$tGUTCeB2#dR@mNyw8rsI6E#lzq*aV9Wwah`4vA`6*eIK zL3D$IO$vq?a$Od=WIX~W1>7Z8#ft{&U;LW8dkix#=3I&5j7uJwIvD3%65-r1W_~s*DteBSIO&}riUcL` zbCTq4bf^Or7r%=#?Mam8C!s1S2d7XDZbPt2*ukf^pu68ka9BNwc-r$o?jc0vR+JFu z+^s}ptphsYhfc%%RIhHs9ls}YRd#l4+f-Exv1iXG;r7CiRXxwaUPWQP9>L+m(A^l- z(>#tz+iMu{^7)8<1nK270lZFNJb*M#V?|F@VGTNwkSytn6A!xT5o1*hSIHE3lVoz7 z^SXLe8(4A9Pa=Vt0T&!|lGhun;zX6b38gPLO6N5NmGf2NWF%HDR)JFxs5nOjC|Pfl z*~pWqtys;ERk2m!EJTI}B1Kyj-#7BUrt(sl<9&FMxz%E9C?0E2=&M=pdq&>=7(dDa znRlr#uT^2IQQnAbbrMrZ_c9f~1@Q}1ykygJpCmh>-(@ul=Stv^jj<{y5lLbYe3W9j zB(0+D<(R}Fr1x=(_B?^Z#jyA(m`&^jp|58Enf;~sk*6mWH>%{@k$kmC#(nn*7$tba19&rojhnY@~SU( zeWZ8Q*T_fWm~=KqVWhn3>m`ncdh;H|fJ50NbBG(0We)M+iOkVY=C~^hxWdWY;rd>; zU_l$gccKJR;5%mu!oui1@k;y!${EJ98CLa~ghre6-WEPg}3 zZ(0mwetV7+H}`RAO1i(H05SZAZnqmg#Juwx+GjWQbFmKKn|?==endaDy-6PlWtNZ9 zhcu0^LT!Bk-z(WO;c{T;VoeD8;Y}=cv}j;>ECVGg|he!-HmDx#c%pUP1=x^U2C0# z35~ICZHD?S4Ow?qN<&rw$e*9LV&vZ7zP)}TmWzM#I|LV@3T3|H=q105A8o#3^?Zlm_4upaAt*p;zPg>UJW`7N>$d<( zZIF@5UiA>-n4p3z{n1E}?+|Tckff1!2(n1^ z4#7T1)b9{{3$WOCxx>PgYe#v9;6UJL^A+pY=BsZ3R^}_VUzx86YV#FgZN4I`%~yoA z`HHYMUlG>kE5h1*MOd4!2y62dg?_|*hplDY+FjNC>(k z@SC+7@lye0iyt0yAca2lL2-3iP~6k!a=>Ew6LdMGL6>iMRPMame)SPptQ-3ksa{@- z8!u0m)T8-~m)GLP%abMbXg=fR$r2vTXF#4T;n92sS9?fS! zo-E&q+ppMNzx^ucI*1Fp=VDsLL-=gA;3UR!Hbv|*9c!K} z;n94?i<2chnlE5wzarfCJye`o( z#`M#ssN^8{??RMm<(+~bJ5QLR@@@s}F2=4F2if6AOoSH7) zGq#qjoozXjnXv8;C?kJR6~Mb8N;vN?h#h;UIP_s++y~8^pG)K)3@)F%FA;MSX47(hhF~e@M+7?%EN@wc*ZG9G zQoP6@pOuoStI+j|4sg#CC4~w>{DZti7eC(aQ0hSbT>}PWj z-vL5_CWvK7lTS?GQ3;ycz-JuInH->%swfPjDvIc`sF^IP{7Dq0D~u`%rBuGkqWZC@ zv8p!%!KM7zJAav^i|WUsmZPYWzp)nr|9=py`iR-{nceyYf}IQsOL{GXli8yp7PA_` z>T{S{N?LYy?A}z<){eKvl`*&jsbXT@0V-}&Qxh}fnV+&?^iocgRgC0nG5LdOMR0ap zv#DB4z6##3sZ`9i3hvxg&1VDc@(+>E*>UHl8bKNjB#mcK<&alFAN-7zf2^MYyGGFG z39Av6`b#kKTMCB+I<&tUZc>UzCG%B#1(oQ=lf~PBG#6V&&{%>hCJQ-}5=Cy23?duk zWrwL1`C`^@+Z2>JL2I;#mX#aX$NRI7JVJJ>Y^srw*DRpby55TDjA$uqWqqwiw*CHW z4c%n3%C1)#2B3eBs|@IP*&kIrN9-RmUh&pAuN-g6<)~RhN2-CY_6_uJJ$8&)k4r#c zl8R5plkSR4o=m}H7oUa6uB}A$_+J7j0?%az%@0`B#y@nA>@0IlYsMxt({GQ^Z;$?!o3fuxvFz zC(In&h6k1rZKO4VJNJOxxnGXNBJSJ+4J;1e8h|WAW@(UF>cncQ7Lo}_<;UK+8#UI_ zDdR4TYc1c_oAxUJmjbwvz_kEg0#MKF;t^V8gN7hJeAl1Iocn8qI)?x=pGSbjeH%an zyBwX_{#xx6LF5iJzF|WT@lvtQXfANfrjG!OA=Ugw)m^NIXVYI(QN<=CT@S?Cb^wnM zXaVpi07E}eIhM$&fF$9HH4>b~SviRi%+#lSEDMBe>#<(ESW?!P`V$#npzGT@i@jxi z@rP7>!w9gxW&lGgRSsR>`flq>gQ6urW7(}Hm5J1AUn+_}PZxhDfD>5!&^BMu^3EaM z57^s9NB%cLV__lWAvED6CxC5*GjlNFI3*rj4Eir#2u2*I#Dj~$%cy+B=m!^r5yvU<;9}6ccp>Orybz4O zcp<1RUI_l_Dl|hlGY7qk7lPi!3&G>Mcp>Orybv@lUI;$-5E?I>nS)2acp>Orybv@l zUWoNBUWhd=UQn;;5)Uq_*K~=C7h;Wz7h*@Ue(B6CZ!i$f%(33Z3$ez<3$ez<3$ez< z3$ez<3$ez<3$bI!f6|#b*0^{f_5{XDXXaSr;)PiA;)P)J#S5-?@q#;IDHc!Z%pry2$)8Kz`+&2j4=)S>k5`+n{Vz`g((WSQY-guQ#9* zQRI39Iw*a9*BdNFX_4y2JCM1^#*+LR;;@Rb15z| zV6!9F8*ny7>}5JO>Usml>+1~!OdA!hHz2I8H(;IWdIJGU?`HwhMrB-Y@G3BIy}|R$ zAibX%lPhghiB-H-vfqU$-|BY?e(Zk2M%C|Dz)rsx@Eg-_0e*Y*lQyapk}U6^>}#p} z5LiG8FER-O5Pi(Udn!TgcCU$ufv0bCJ_>*>h0CDb@YItcWUZ5bpkgLN3oJN`IU49L z{sPwL{=)9ium?CTzl8}SH5KtFtq9IIO_a=kLu_&A7qSdqwsxMljEz^W&9sN&zCUqj zIj~V-@TeSE_%jQ4w%L`$!Vivut@*NbXdl;Rd-xAj`!XW!TY&bJtb)>|lOnq0$kMA2 zUH1&EG#3L{NZ?!mTLC~(;A(CUYy~)36}ll(Xfe(Dq^7c4&js*uL8#qoDcwA66;o7#9L^uAQEu@ffPsK`xu|&XDrP_>6CVXh#tg(x z*)ng_jwz`nx_r+lx{uV$ci`8_Lm=h~f<4@z`)&Ny&tMUDUPM(ra^?_x90m6fm(Yo` zv|#oW#{LPqYA~mT;5SiJu-8QZV_#>OS24sMY6R%U#;|&~iFfJ6S%|md9xT8}$8EuH zAZ|E*9bEhCZlc1GK!+Z88*}i&h6G+X@AZ>lVwx6Ng;cy;3DzQH21_V&bz5;x~pEbvq?VBFj~@Vgb_ zwRCaeOu#Xr(=kwS%`DLkZ6-WVlpe~$@Ww4@LGMySd=YQl>1RMlWrsc{&O)|2FI33* zMT848T9>S|;+C8S{DD^XcTh1NJZfem#8Xc3?<{~C9C`tT#=lFl!vQsZ;{Sd(e%(+z z;g1NXhIoxp{67e1hps0q-u;~yT8<{hf5Q04Srh}2vnU24XHg79&Y~EIoJBDZIg4T- zau#(xS}31#!dcW;5Qv;bvBB~wC!9qwAfIx=S=0>($fule7FCJB1^O&%90KwwC!9sy ziqaxyQU8NLPefgt&tJwzSTP;9&HYGrL zHpPaey$`GrSmpa!vE}%qe5)Dbzn)yQZaJbwo8gHqrAt!P&4`P;5Jg#Wr{Kqq6IwwW zC&Gz)0lzVE3-H?`PHF{de71_;XeVlx6LiUWS?U;T0T?92buYQ{5K6E@@)%287ZH-j zScFqU@)(P7c1Rv$5kD^^kFf~nhvYF9;eyb7uv78~!u>jUWNFHPT5pZ!x9%B(6 z7?Q_WuLF)8WARQZhtB9JBS=1JqIG`iu(;vfmDM)TzNj?bxBpNMEV&rTX824DQ*vb z197(@#)*3nzcH56%(83812g{gxY3kZQY4OHW-Igra>R{21TZF4Pxu55YcRB$@HoP5 z=oJ<*o^X69hpjk~aAN2Y;!Gf%9QqxmEp8&=)X)x?2;wGjN-{!xB0O#~;q1^!)4?W9T`R!>=82ZbRGE{^u-=2Bj@YLuP}Q92`bK+t0Ez3M=g&-1J|;` z(ad3q#m62)I7Y0H_E@60VuiHDEQuA;9w*l@uFdxN4M0)rBtb>-Vp+ZjVY%=+UuHEY zW+4K84KrWD-^5lZ4R*Mewb^)q+0un8aqoi+=30ph7b7@N2Kz##I16`5%$LDF$h)-7 zvQHJk7)%XrR+;`W%1jk*$TJS1%#belpHpLVkLfpjP zVasufO890uLXJi%D|c+KS7tuLw+Al(DImHzba#As#JStW&#v&(l$~FV=Hny zyP!g|23*6?3Yj)@04ZFDP8vWOw_9Y|+ySI=9STFTvS0bJ?DqVaeX8OCk&3U3R6Jj3 zjk;nLQWc*n(^SPOq$)m5rm2cmC~OV<4qH_dLu#ZAoS)%pJnWq>BSp)yT$OdKh%8Yzjn>T_HyFW;Kz?vQiN31e_R2 zqOA}kTJxM9(F!r5s}LTf=by8V8oA}gfT-OZhYhroe_l^iQy6ous-l0SimykiC=^xP zh9XNZQE1Ph-&X>G#d1JOu2KnqM#5m-UIwhP4o z+^Envy1``0WOBHE6*A`%H_s@{w}F`}F|qNtO8;n-FhP|7N&%a`5mmxJ6y_%=VS&J$ zWe>MXb5(!XgiCw{WGX(FWkq$=#cZ$UXjCl3ZxG|_RgVcdUy{y@uQxH0ANZY3crny;EVvSKyu{iAe)a>F5m8V)U+yD&a2*GqV(` zuf*iMlqCO|LxZ&gC71Lz0;OdtkcX6&UXIe4DxRI$tn0K&PE*lBK%K1uWyrf%;LO4q zGnowCzQHKqDP4eQbd#SNOKw+~!`QfoRbVs&KQjWQeGT#+fNAo^adlLI%?fi0%E0o# zMKkDf0WaH1`ErS%o3FnlM#Nekp__kTo+VpeBIu_41<=XEq>IZ$j@<}XiSV_K^|H)e zCA_sBc7FXQ87>$8`1=L^A>dbDS_q+`kW)!WcZ!=q3U5OE-+@rg$eKG4%KZbSfI^*( zrt{e^bdqQBC3ma%(>W~PHv>O01J9U&SIoe>MxZEDwU#RjYY?jnNKME`tPz+$RP(MH zAu-qaDnIGrwsdp!UrV(`-<51AnW`{XqN$~48`+-qWvfo}Wh>pLFiHF$NKE*MfM7^W zjjF+{y*~!boBK&o#Y|L~ET&Fk@@A}(bBq#7?=S+bsyM08Tp3l|w-n~R;QLEeac$_A zo^LkjUR8pWwLgt2;Z38i=M<)t>xq8mEea~;RZEvz>#HR{;c34-P|x%Lb%nnR%PP*y zLD~G+J73S$v^zaOnKui>BxT<80A=3g2$%QG1L{msf(>PH$a?B8vjUWXLxpBCH$crK zP*uo;&Ca=s0IL34h42PviVlC9;VsS<6(05>7BGHpLQVXv?v2`nf;!HjR=NN`mDiQv z2|9>gex5{?_D6x2GN6>+kNDbq_;WjcB;M~89{f8kJKjmcdL4~7JO<15gU_=xSXm@3 zS$3849$37vFVe062hrC4;9q{?8K@l#h{8^Cti&LOP9n3xJ@DPXMd~UFaNTpo)`%=?#BzMg9LM2agqdk~hzg`yeK(~-@1x3`Kgn(eu)E8yrBeT+Augy`jG6{u^h(?gJvH-L4 z2URj>d{w`5c_@3nV=&54yIfT5((HFaz@yg((NT**}z}3k}S4^u`}HX*T4G>YSXdl5tAnvKyt>7=f#N_0LQ8_vv1RNljwE zz*M`_8gQ{nyO(X7{Jfk7mj9Bk$iGGvxk_PDz&Kb)1nt~F+My<}Ts52J3=pYWxD8iB zgF6ir&bbAk$_rFLv|_soaJUx8+(PXU?+P#3YvjWtr;ycs{#UkoH`l9Kft|=A*m*Sw zr<#$HSWX44ad~@2jk+syS@sg=AhJX+T_r|@US+5|cBR_Xf& zPNfg$Hws5nT#XWDEUnpx`EeBHLIZP)4|7POZ^lb_s>+Yh3ZFBw9q?t_@6T5HzQQD- z{8C^F#V+f2vNX2vBVPf3@fT3iM`2Q}ESanVyj7#*R5P&F3|wdit~LX=8G+IlRDg{* zr>{BapQuJyCBu}8Bf5Q>3NXW7Uxsx_dX_dS9CrAiz)_r0ZIxbUW|UI$ zoI(;>&wDDs@p`hKNlx#@d%T2QM2Yo`EL3dEQ&oTzR?<%exGgWKRsr6QQ94EievUvs zn!!csT>SF+>(a$4kyTF?iP}O=5ni1_NbG{~Rj~b0x3R6hMbB#dhtwtGTm_u(peB4(? zG5l%tj8(EvWnuq{&R3n)t6_8_A-+jdUsh=7r1;nq0#~CpVe9!HbiXTLl`PTJ zi4iZoMFqsnt9HtL<4myFRPrc@@vKxm34`t637hoGl=g{>+%` zS{bkGs}ucmUHY`bq!5@PF{J_XHI*RvZS);AnDJL^ZZI8IHbxu}ydqf48v739l>KXQ zrfqXKEK`3iQis$JLgLdR@q{5yf}`z2A^@-5e4a9V*S4RDv4DUi)=U%J})j++f?>6iBQM0&C11T52}f-0hwS9zR<&;KVaDG(-pl z89PMOeU7O61j+4NY;J>xyhbUqO?5=nd!?)wZLDJ2T9M{(Zy{@6D{B`et`)V95j)?t z++riwAU12J>>2f4nQNxZB`{|SOtyKJC|tHw!J^#RW=l^OEyYOuy$U6l+YXf(S!%f` zl_gafB`H{xR4rOKp_7doVynJ4s1irN$sYETJ*44EmfFwgVLy@I8a;%wkSH*1YE}|6 zQDDl^O_7)rA0_6?6vMH<=77Na+m?Urom^ff2`YP;a{MXq*yIb?hCg!_3;qmU9({S8 zndc%fSxlh_-in~Sx$_O8QffD?gOxEGB~BIM`vcDBG%9iXRlRYtTC5W5ij+`0h+;-W zr%M5M8d&TCm6HPQTIA_=18|2zBGW%8khz5&^a zvVS8RuBBJ>76flRR%Ov@Scws!h@jPQo{AT8WSA<3gMPX~G7W#jpjIgqArB^A&Y8G_ zgMY~{WDCv@$iMc^4+rX*yMr_LD#me=Ah0_)9kqW!P@G?i>{l}=NL>Vf&!9N66u~lB z_9u%e`zEJs1B08hQT30$0Ydo|g2T@GrL6Y^`Nvv40JASF_7CedyYxbZ!xeJ~(m4j$ z36!$wdoRtNfl#*#EjiwU1ReZqS7y`M5-KLk%@AdB|p$= zEOd_tjLLqfDw6}SBdW5;6eh>{_YzY~)pIIdXh83)fS|?cCkz2W>>@2X`C#c8V`3QQ ziZFBWYCMrEKx_KXsu6voK${RjyU{}vpfx?6XjclfwLqKMw)9MdDX(Q|0<@-om1vg= zG-13HXqS3u0t6b{wpE}}+{n_l5^cs^I4-mWICJS5ym3{4*7Wf#_&id({RW#UIOjZa zj+9;JGs&9%R1FX|2sBcgMBCt@Z4_t|vxv5e@OVX=W09L5d*^k?CmC}U^G$nA^V(|S ze;L7(h_YN|90d_-w{1gA;r;k|0O^JI0C<7G?ErfG6~&g!Rp`%P0tsH(=PVN=_7Zc5yK|QP19Ljdn$6{`auM;ckjp>l$iro5 z!I?-Jh!zx{2cR9ma1LLcLPr0@$1bo>CiW*t+Xti((Fis1sPswp#A;w|^Hc$_P>RoO z%*`q+P>!gy7(mgP3XR+Z{!=axcN>S5M$R>XJwMJf_I#8oO))NqAS!w7+@Yj`)RhU<(PP{((SjIAo8 z6jgaXJsnH7!W2?yHnrm4sF)T#>^tcaQ+NfEuEq47aw7nH*mDZ2pTc?ywba~>q!)lw z@}^1^wzo=Z#{W<;&yxY4w@+n}uOdF@4NN^FYu-bs9--kBY!zyQ;OIu&V^2et+Qmq# zor|A2lxtnEw%1-tgiZKCD_m6w#Vr&pb}n5-^Q(^te_nyV!KZh)f-^_90TIA+8Wky(EHI-Q#)-Q7JS=Rgj$e-V^zS%0X zB&=V4(z9~jb(uIp!Z+(NJG>p`@SCzId<*{Yo6;KQJ0JK>Ss6YVfA~!ahnGOC^4oK0 zcxE;h1AODwhKHaee&bez`N#mj*<-_ZqpAGn3<&EtyJUtfdPT-q4=#nbn)LGjA=Vc@ zk2wD|4k?~EmVd1B72uHWo=5D))BnHkRgsrq{pY+_rKfPo56-y&GoN;95zN7J>p=Tf z8eQ^(;Y`3WX>`dCHuFs_ZW?vw;5@>KX>`dCE@%O7rKZs(KY02SkY{!pUGjqqA4f6p z!Daj+!g#X^T=IiUP6PfxE0ZqyJ#0G`6|0w$TnzI%xP>5U)Piw#M+3T3JMiO;(Rw>2IIH zE3)|Q12HIGPTZRpM#VR>9Qjfm;m4jZVkdH?kjUueFZym?K#bxKb@~0QguJA}mk|{2s7xyU z4ncakCk{pDmwR$Ok=0NHi^$%&!pl9^@Ny3h{K!BmqddqJUhcVumwT{0 zAMv`Rs#YQiFZW#G<(@0N+;eY(gm7{VFZW>WcwoAx2S-y3NGUUhnQ;RxrN-F10mh`! z%RP9)0l>jDdbtP35q8t)A`u)Y=>Hp>PIzD%z1)K{2oFl5mwRyL z-!Md#Y4marof#~`~FS9srz_jHFGgTjg z*FqnXwx>ShQNni-%wMC{<|Rn~6^bm7uBQdqAh#j;ODdTc(Z45??MfuZIp5VD)cMyb zoU?($SDc~6dQQ53Ii+B@5Lvo0feaU7ULsW(MoJ%450@*vp zAi9^CS!TU{Ob&DR?jf6r7BGLGa*K^ylPqgO1CMjS{f!Tr_3Or~7U0PZJy8M7ri&in zExznQ+~?I8J?+7e?M-s5f0A8E648`k+j4>v^aLk*&6U%L7q@nu7}d9AV|39sh#AL~ zG|9nE)sw}ENHeA@-5Z0DS-NlLGNMPPrx)?5=1uZO4^7qN2j6`8YK=vYbQjcYfkLhw zlOra~=mVY#JnXO}_=hFYYd8i6EPuR2*OkjbPkIL9^bE#F&tQVTsho{OuZ7@pe|nyf z5y}2Y-yo%Uxk=Kg{xM6F)2_xW-59eYO*S~fS4YntR#k|lXZl7Dg5&cWJs~6gqA||T zHF*B$sQi&-FdZ)T*US!f@XOUyO@UwrEk)DSTt%d4h(a?XT4?svLNiKA%Bjlo#vc;W zn|;X0BTQm1FBgZ|6qE?|ku0hvv9H0{NX$(DPo&3^kop-ZVEH_+b{3j%N`L}`68h@| ztdz1Q@>fxLG!+zUDi|JUvUgS-elLE;5IUp}mrtF4l- z(UTXiCojQIYKb1LaM?}rQ%kZ(Eh(A^Q#FepfquLRkm5Uo1l1E|E2+k+GFc8*R+Bn> z%!k*bYcl3E=6HoN*sHIag1HG{lm^O?Q$w2Zgk@i2x^vB%qSi-JP-K12^N7JuJ2-_E z+75LCN%j4`HiC#eVg?x*%>~62bK1S!k&eQ>&CA7p4P?JgvS(+>eqoa%B~YnHtY!X= zPdm6MUvp=@)&`OpvOX zAg!m(IVAU{_YhxnTecwvBnH!>3Je*wn2V59#!?yIG|gz znkb^gLza<>P%`D8QnpDbru_3y6C|J)0r}?zKD)#bii=-_MC*83P#i%Qkg_WA2z^hI zqoqWDvVV+I^!Ra%Q;jj^s;~6gbYHJQ=^-!TGgGl_f2>w{UH^a_$MS9J%*p0ju9t7I zqe@Kztx|TT6{8F3etGKCYoaJA!%wp2t_PHqX%1(WF`VW`$1kONc@qK}_5xyiV+2up zUsIrQ!g94p>z4pACzfj|;wWs@>=k?}QESqXk5!9h&lD96FbnnJ4MdYQYk|{BydYL} zvvkURDQzKyqm)Is0CD*rY|2{*Usi-e8jt!U6Z!=&=F}&6k0xdHx=ePA@%H0-3$Ex> zZNN?9GH5d)At@m-f#k%kxDsJrWP(YCR1*}2P!d?LU)E}_7wQ2h6dBZrvW93{)r1Vi zKyK-KYF^4DX^ZVPR~)%v&h}4%Z|ZXVq#Y5hq_o}!Eh}A;Gjs%s^iw(3coJy7Q2PKB zX#KChseG^|>W`RdmR`j9pPj|nVw2#c!obyDjSJR#uexZW^LPjfB^~_+`Nu$$pw0?go%F>e-$4QGf=}en*FoT?bgMJvq?FVx8^-MZu_k0r^y|MEKkgFi~ zF2?E`((}OK&oHLHrzcy?1sf$q7Hlln(V_~(B}EhWDTaW+sx5;9a(r#=WA?(66@9(j z5P#+b{g==6ux_&xxOjXTR`;YdDIt0l@+Q2mNffyTQS|fpk0ns=_qGoC(L7$DiJ`wo zbF{JgD5EHvgo>pM5nD%aycQ)`V&s0MRIdTm7kQNL_ zUSIr*{V`aBjv^McAka2nQxyE$E;)X!EmN&n$^ebCRXH7?No^?6ThPcRfohNv3v#2| zn;YFe(ff|Rdf$=j?K?nwTtrP<1;{_&Kbbz^0{YXHky;HZWH7P3o0UbIp&DzD z58YQwQe`J=jGEDpAyU*1)eV3fQFN73cdzZDyAP*0hX0ePyN}d7QKw}!UUJJB^bT$s zyojT7il&vr=?R-~b5Ee+9>ALhIq3;;F+TEkw~a605e~ zF-Rfm@vczhN#`WAVnt{QZGa>+y=zpl+%-}lsiI2_uIj-;$~0GDVJEQ-_UN?SV3P_n zAK1WS!Kw%~qhCH2R6HR$LJ1#sZ-}mf^$#_(YXjym#eZltPJ$)65*owVsH%`S+Z++e zo8TEg@s==;cfllHpk57yuv#>5`_kxXH@fO3f0@1xjY82{t;f8K_G)6c#(2eZ*2a2O zGkAhouCLT_#?XrMrSY6dj?IZi1t?;IS%jy@Pek3;B(G`kvhE^Drf6X?RRAb#nv^Zm zP1!QT+a%8PWC&MW+E`EWqTq4p1>}l6%NOz4b+>3^)_;=V5yk?)^!XeGjzL$L`F?() z@KIKtpMGF5h>$OG7I-`yIddY_6&h^MHQAteu_m($9s>~9Ta*3G(E2_O3OxQR^^pj) z8{h5e}eQGlQIoxGZG{a^{^DZOv19ORVwY( z0Tii0=@Uy7AtR1Q5A|A`JKp^u9Uo2<}_^bN`qCrTzMm3ZVBIaT7| zD9w$avG-(yyQpqbkMb*T(KJ^%44yGi-u&^DZ^rKP=+vm`f%DdlsWYNB{U;ea{S5Ir z?mYcObgU!^@-vUn5fqkB5`rPgj!};Jr~CNl_XzA11UnhBGL{^n2^`KSnjhk{0uN^t zDqIOty@55-;EwM7PP_^rk+N*Z^^|ZN!syCj=JupEY?1yZbNE6Y<712Il}g6w*+qBA z6fH-RvPnV_g95Gf2>4MLCl1Fyutyf-e$q5{92Cyls;gx6=j)_rj-F3?MxS08!w6E1 zHs|_TK$vtjZE!|Bldhx&5{B=bAX>cAdZCg5oW|%py0loYi%HDc?fZa_^eMC(#PRym6kW0&p z@b#c7Ew_Mqhow71_HltPFvSc>37bc0CW+YI4r6&E@&J#F2AVZSozxm?9P6ZQMQa5J zmYKvUR%vNOR$EE6aT7;CGMjJz3j>Rvbt<)htdbkrYJbBteb<=uJ%sc<)GLQZmME)8 ztrvj@*}Q<>-W<)OsAu#rEB=4-ekF>^xqbN@_bVQ+c-Cc4lNEj--I9gRkmwV=T@N}n z%@=v}jAKsIu;(klIPWAq(_~_-+$APGlS@ijd_)r^7-d29+TWf1&?L)Bf2%YxN2#Nq zS?2zKM2(8?AU;8rB+VSZsO_a06Dy{c&&MirqpjU}+S;A(5iM+Uth#?>;<}pev>_X9 zBsq}?)vE=Wm5R8*Ga1mtNzO11ek`#;S|q<}nwmm(gpP=F$A1v>Uou{v#{yf*Y%X|6O^`_K3!k$*Of zb7hXV-m0kKPw<96Q4fETKH5vx!_S9Be8aDwD8dNJ;m6_Oe+;#nq~Q10_NWsb6VwS@ zwGcCi!%!J-P$=9Hyj^dmC#JOx&A&K&F-M_Vu16CfEv#Z8Ao=z;$k%l2_lsJd>2T`F zE0Db2n$cBA^B7buGjR5&OPHaT^D#2Ryef&_=kjlI0NEy*3pAx3M&JFSWZgfLdQ=z1 za+u{OoNV2FNIA`x+OGomk_+{rdW0?ekS+U0OT}C*75jPQ3e!9X*7L0Bs#TbWf|y)w za7FE;jL7bev~?8EimqiJ=VlM9cbT6+2YD7@ZugXi;@3g+aTe7Nt+${DP(UQ9`?iDZ z4t9KAiqw<*yFG8smV`aji}=i9@i3}$^rV`Pu6P2;cyPsY5HWm0yvQ#8)JpD&1)QXz z7j6(2mTkRQ;7EaC_=RXOK|vY)5Q~j5BVjH4E)j zGKM(eW+}8W$}IJPcG_S2lnatj7WON1-7Rs%b<@B+%pymt~FWI^N3dfCtzr z4>uBHOhoT|IZ9=wdC*XrB?FH07!VQICybY-#S^{wqcf&74Ej&^yi-5zw51mwH<}~k zw3t1d%df|LhU2dnnPmEL@%%3`oY1hz2-K_<9fLhJN8(v-Cem?BC6Xh_peny&P^rm? z=gauCxMxc=SujURpI&};)!H=pjD_{_I8fUXBOI9P&AjBme&j%(H8IMzhj(G?hI3uv zs-tNFL4$X}xqga0>JgtwPo(Wp*^2OtM;XLM*CS*$LD&;b4jyE(pSjGK?ICL#u39XJ z&RU``+?~Rj$T9^7%auy)im|ki-G_ALHX0No6Mi_aEig{BIT6e($$z9r{^S#~PMsHZ z7>>}hORCbh8X#lzDI=4El4ZmrKR9BN#Pgrw#^|STzjKzb@_6eI+}zpOBXEJ%&@}Z& z*uk)>OLoX3JLE@;jsh(@JS$IEeOp_3lxiOBu1LnycQFhwT?6r0t|mN#?xC%ddQCF- z7AlzoC)|3;D3=sVIyF79#PU)p>9@*cl4@gptI-LdaX)kGg-Ie@Jw{wA0XIZR^qx!A zaFY)XXTI_1S}q9&q01%VGj2EzqnDXJ6MD0a8S=zBPY0Di^CG`spWP^87Y25ZzV#7O zwCL^~gPHJO5zoGyDW`eHVCKeX|B>TugZ|4;o=zJ$iUf^k zd7^Z{!#&35F|zLwK22>EegZs%DA3w46-zi`QsRK2ib) z30Jd_4zw1pBwU&|x#@axyFPZ$$?Yk*Av2n6vNYLXlkHgocuHk#0DRXlMU8&+{UTof zC})I;&Pcv@=k$kL_E8p>+S-h`swZ@7(#xkqQ zpf?_tN`&B(^k0gwdLES`Jh?2*J4g3OP->rPL)D8~SL+egzE5L2^_oM{iRf9J>1a($ zDOXWT*I^0AxRirMd$+sk#l(Ly2YF_m%=sk~jY%Lgn35#G<{kOL{G)9vkD@VYiTj`Y z9KN@o)Sd?3WGmW(2<2j|DD2q$(nw*TJI@~y&vVHo-7~)#k8z0;W5eH`Q|IaRrb|@h zd^qZK_|uA&qfG68m0`6*lM^o~K?@SB88Sj1!gOnoQ;V*)$9cnz7>JN)HKtIjF}M)Y z)Chg646cUMY9WP%>Fo-^5bf2E9418ixP1(%PA$5 zt*JJI5n20hV{qI*lNHo*A~Qd#-oOw``6;2g$N>EK+5hFHd9^PJ2s z);I1n4f~tiX&N@TqbqIRk#L#lr1LOKp8S9^vQ_j^Zmy%YM-; z;W_P^Ea77a<%re2sunG7>4l)U5?f1?W{&@93B4}>okjSHl*)}|q%NHHXhwlO#A^k) zMx1PFE`<}h*JxiyyWus>dgL{)HkOIaCNr}g=Is>Gn_Fx$<>q#{u)rOGzsN|h+yJOCT|VV7NDCDJ?^Ilnqa)25&L{A9 zaS*w}9!5{|#4wG0J{L`&u+=9z$_go-N>bVivNXV%I#%V@54_%4J4{4Clk*8_MV$ts+P`kLUPtYs_(**F+G+f4K{~i94Ha=Xp@V~sgqOEmt z#lqIbE3Ar+w$_T4HH%kuELmEyarm$W!-foA)v~5zo1 z6{S|^#u=doD;Bq{>sovif@J|~LEBkv?MqjeFJ{Bq&sw*%4X-Z5TZr1)mn>Pj3@~08 zW}vOW>kln7rDbgdO@I*SC}_db*49-mZS69R*_JF_)Ug~vc;eu!I?%kBe{s^?+s;^D zka55Y#MqVi2?P&{-(T=|I)5Grwg*=n9VZaPxb8!V0qaWqe%6uhZUja5+gnyI?QV=( z*0c}qz|R`5%K}x58+-h&?s2v~CA?$B@<0HM%)wX(EWY~bNDZ!7x3;ZiJz}DSHWG2TjW< zGzp(ge#C2XXdeCrdZ1k+!~~|0myf{P$3B5#vOa$f7a~BlLUj7fj-?&PLdWJHkd0-& zs0m%yzM^&M!X=SJ#pA!!1BN@=IAHTa;T0RyZy+86b}Gb6z%)88iVb)D;fx<`T|csM zWbVgwza)wS~{{#3x~s7wmjih)KxT34PO%|%$TyF>WaDV&+gbSX33-1rgpfNJ{7b{&1zR#sncg|7kJD$FoA*K3t+;5EbK09*!f)U8 zw9~(S%L-@1UWmSnHnl_cJ#W=Jy_SjKW&}U7=GHYhiF=)_K#}d%M>1c9%uc^If%nAu z6qz^KD%%t1A4Kpwc6nXH)mwI78yJvLIbnTg!$o2jmni74`UrHmxb>`c?Q8vuWtXM! zGwhh7*4&D2>XTEkV)eqv&Y`xwpgtzz`oEzE^m?Ht$?D6pL$Ta%n`Z<>3?TbPZE?I4gm%s|gc2(7FKlfKtj4*~;W(#%;LIsk+aZUjD%6Pzo41J!9O>!y`8baXJdkw0$R;yEWaPIQu&1u8-Tn3)Sgf#Oi0 zD9MT6g=H~(KBEgl?moo2k07!WpRWZ5g#v}4E8WTNj=Ban{~J#SikU&CMP+E1&@_40 zn7=nPG)!@~^m4}?y0*YcnB;UUduH;16%*!-TwmFM+1n;&@;$45@Ev!UI|z@Lu#@Wka9e)}qC%J!AcS@o5ZZ@ziYRQKkk z&4K4AcbgYSd~H#ARZ?5w-t z&Ihi+#9u8|jMuHX>z%X9Pj_GLIe+eZH{WvIop)U`Uub5piMhSv@N@f5l=DZLRAH2r z^0u{Q$?{LTo#z}xNp#49rLD^rF6O>R3HjFcg^O0H@NsO)QHrPKbu|QtHb@;lvUr@i ztVL|5Fy2fSMq34&>k5hH{c{x26xy3VaI;&RG0TDAvY?X?IK_VY+(*Lm5n+=680%I% znb)+@UA$raAX;+m3jR=B*>wVAZt(p;40u_pnJYhs`Bv)pF`N7RieWSp8}lvK*Uup1 zG1Hi1?1~~Pq?&I{5m4p2nQmq{lJQ(AfZ7Nr)d5tb;#=0Vuv#^n5j9bXfYIlv+5DMh zPdO0Ye_(&*q_^Li_VJF+@Sc|CQ{1Z#zRk%JKZC`L?Fzcrey=lp)nIqy71i!WcgxL_ z-9wY!K6T2V=IS#xUi(RBvwPK~x3Aqlatbq6xYPJ&xtqy9ocKU+ZqO}ch`J_11Z9jQ z7&pU7cejTg2)*PyeSY43?=-ira6dddsr;71Sd#)4T9@-bML5HtlN&*&@ zi^J>)|CMqFq{@S#_SS`K+Sb8tBbjya+BIvAw6=iSj?bi{$x>0Ns7DY|H$)0zJ0g+F zGCUDyP^%}aOjDvV5SUR)(e()0ujUH5riTVKDZ`K|US&4v|454^CEdmg6>t2|wzq%i zHtcW`+MQpV?;b1wq1nOm;7e}9@>?r=HCD}@GO~GSS*JVNN!shQl{1+F&@bqmB=@PS z8c!*Bt4_#2O2R;j$9+H6U%5{~U%YU@^ql{3HbBs;UxzD-p zM?il})O^5kcZt9*q&(=wxl{>^CcD?=gB#|%O%(+j$B%NeHk??oe%=O5#28Xl)1>v4 z>zBQI^Ty6CZ$IHayCKjA6LFWAhzVcJL>xiGJ-h-W59^iwa~w+wre|R*M-S8Em)zaV z4%Uk!t|v;l(dWxbx+4p{6@*$#30`xVnviNc$JM~oVASE!j8U^h-EnBkn={J;zBuXghJ`PWoosNvelXwVn9Q;ob9`vo|led7cx$J-i?A_67SyC$1N? zlK92Y$`Ob|O2!pSH!fJxv09M^CF!R=^E*DC_47T4dF+=IA>`O^z7Gj`(4u~RV3SJ) z{V@@EaFd&kz{9W@+0Hok#j0k6hH)J}DKN+eTuyklTmJMOuJ9S<&Z@ai8nlL0bCFob zT&MDYu0Km&@FJjmW?1632WUpRT}%yqHa-J=i6O_Bd^#sA-)2H>y_X3WspA*3Q7fO= z&ihRa-AvsvsPEF=O#d$+cb&&=bg;t5$+dTMgx#i=_1B)cwHa(7bej#-X9MoU17|OU z_BAzQYvztXNvQL|g%zEcj(T|yAM{#Bg&_UrlYoI8d)hmk@m>N z_BiHS79_Jv3NnodEz1_H;@LS?U2pS7v?wzY_ozU_d@<46KQg2;s!dvpr22?o+$lRE z)ReKK;Odyb$)JlQH$6PKqT2Y@{0aK*&n+rd_iQ>SU=q-GH@SOPOrg0OBy}daKK;$g zOrh^4VZ;JfEePpf%=scXHk2iq5H9My;Rpc6iF&2d24K&3$*|7GVgTcpWp) zc$)SU3{?VLe$f?oCBl=w zp95q11^ee>%Oj(i#yRSSsW&P{E3`BA4L-}AJP%YhEIhqnirZP&v8{5-fqj)34RZ#a zwY#ovauqh!FvPv%hU&ygLnrB>mOrNoqJU-WB8FUH;1WNQeuTLWG$gQaVzG7Kib~;f z@Ke+tuzrZ&E^CFU4SdE!WwWR#^}*8uK%SBL1;Oeml+og}2D9$pFsoHpyV!#agjqXa zo&7JN_3p^q*L5Lkr2_GpiQQCy6#YkZD;17XRWuDlx7CBIR!F7j_ywSI@X5{CuMVU&+kkNI|+LmCplU5Zsz@!%ia}MU(b4a);^N2 z3?B?SAz1P@)Q8<(74WBU+Lk#e7ThE zN>iW;dL(43Gm7raD4qTAC%C3cqx2!a05=sJ_SmlxdD;?X^7%Uz@&4MfGso{5C1mXZ zS6KR`8U$DFiiTUAc&ZfU3I^Rt!97BU32rCGuHf>EiSACuxyi2Ij@ZBe z&PaC114uXQp7g|s4K1g+;cX4mYMaU?H;!Bp4$oNo?Tl);0=4Svu2OXc%VOR&-mbR{M zS-fR-qCv0#SV`cDGej5mNMAtj3|R;nt~cp-H2XD z)FX;sSr95yB}Q3<7sJREN%MG$b(_XwhE44w;#{W$dW1t%Es;|J74~eMe#?mHW7OXE zz1@m~hS;GFXOErd*1zq{4)nM8IG1j6X`U+QhW6w@Ep1zasUOdylVuU11qT5M^VQ;A z&MWZV+r4S;j__7&ed{+P`2=o)>uK>iq277kDtEq)WT@Mnbq(Re{C7HbVUMxQ`QE0z zofAhda-Ol~I^W#1y>nv2d>pXf=ZxA8eSO}EQwPuM99&TmD9v;R)jPB5n}L8jaT*8j zFS5eD_z47g%y$-p!M(xT!}~`zR-(Os5PqIF+isq_em-0Woz`XHmJt`t3uA*+jr429 zIsEJPq!A*(j=XBuPi-s_L3aBMabCYe;QgOnzO-S-L!B_iwr}m|=r}jL9(XUGM+$#CiAb1abl)bP+dgj5NCXq}UiXkf{eeLJzCitf zKz&f4J}gj25p(K@suQcqn%w+rpBT}Esuz>q^4n3ha~i<`t>WPn+*Jrb>G(9#@6Pm^3de?|3}?-0N7Pk zYoD1LCYJyb2_Q`j1VLIFHH3tc1W3Pk?!CiIGRb8!B^ffA8K$IBf`npwN+?$32HUd) z5b-I3C@KOX7JPyNJ}cNOAU?~3|66;nZ=Ew|p9%3j{onsboc--})>?b*z1QyhoGX-# zr;o`sB3zF!H%{`fDL=Gr+oILWrcP?d>yonD^)Ywv@~KF!TyGc20g)Up68%yFxVH9+$p%TOOY+=*!W~E%Rr&v$QY4yX&J*{?A(Ku8xR1X_}eyQa4l$cG+=B)(uV@=+K7P z2uEwNHag1iKxVW}iSBf^`ErAy>PSo_wKZ97W?~m#xOgX>vPp9O2?m$~zi?h9(e+l1~ovZpYUiCt5-h$j2r^6Lmad2pp`$LpL5E<6BkaI+JxaMx1kG{(}zBO`>dHQGTbaXZBg#~kqkC& zoXKsdpCxU_M_y5Xmb*qF%YIK8SASw%%P{nSqSLsC8tNzSH~X~ZvLjH}AT6%0!Ot== zZec_0TC||=T_#@tfja44zUKy<57srWUv%ZxSsR64`YM@u*3aH=cGL1{SLSZtlD}5A z;jWVF6n{lQ*GI>|2S%CnP3aiuUf($|IHkR#Yvr#q!P}l#Cw@?S(Mcjk*sJCO!`B)fobiF|0#lFh?F}+W?jL28p!V#6E>uk7tnLJ4B+uy$wx#Z#ROxy>u%nEm^Vs`#?L21G$xL?uH!gDf z<=xStEcaw*G?{iafpO&{~_H9~R zTQ>VpXzR)^8d%^aDzdd$-|%!p{uc|k*1mG}Gc#vFcdMHh>;P(!Yh1@R&tJ6U2a9eO zyYq)R0X%ESEybXT$20t;zr4?)d-DD*_0#0h(|CaV~5nh#y zgrm0%o+%%rCygYhx%_bGoz1=L9}b3H?Y%=ifA35B@l0^^0SvXyT1B6p;TAF`q~Arb zfejCXfei=7>$>~&t3j~?CtXRmByEs@KXF`=_jv{WrZN0L8dF36V$amWq^d{}^t_$al z`Ire)I$M@wco8;FeYTKW+YEiPzOnnt;F!na51nI%R&#bhMkJ&~D!4+RekG zFR_xB5O(g||AV(C)9#+=c#~=Rc?)_en+6l?ZOw&v*s~sXk2?FEb?|bW33b)xBnvA~`j{Y@8jLwd{(MpX;3E|h z%#}Z~jXp-EDPv@IG)CqEW1i9tjjzc@fDm$bV!zLbxB%dY_teS#fib_6KZ_j&SM^

    sHmT@Ww*Z{fV)ahkxisa{9 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 Xvvma_RY~cDPW@@s@ip!JW%rl( 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 kry}OHANO^wZ~ya-@rc*|A9pO)xc~qF diff --git a/Program/libcsp/build/libcsp_py3.so b/Program/libcsp/build/libcsp_py3.so deleted file mode 100755 index 7f30c26bb5ef8b55ea02cbe09e5032de87ae8360..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103352 zcmeFad3aPs_BVcSCxK2kWMOR}KnnrF7825d1PCOMrGo(i1PmaCC1FvPn1oG1Q9y~9 z5!?oqQCvoGXVg(}Tq3xjj>UM5l$@lyF{rA4lWAo5; z&Z$$UPMve=RMqWt_2mU6g)Y-HtXGsV)*zNUNKtZi#i?srcyf&_qpgu^^fmejZ;a+S zTXDKVQLWN2{6e6#Hu%49xu7Wh0$63ESJBJcsnTla0?KxWbh|^komC#yYFedRH;+ci z|A%zFvrN`}R!LsINGkV(p8hhq=#7;l_x=9VEuWv*)waV6?>uLu*kAu0hbFDQ{*4YhoTc_K6gnIIhgRroprd6gySN#x$j^X*&L+PL z8vE@6G@Q_ioSRU8HaR;X|7`kv)JnfKt;kt~e$OT+8sj}%zmK+JpO;#Z|EE^yjH9#3 zKi-P|44kv^Kimrc<*ke>r4>1Ewjw9K6+8T`6+857MgG)Q;^)0q4m9z2tT8W>It@vwuEA$I7 zuCvKM-paVzw_=C%R>m7_Wn9;_VuyEHk@I3J{cdPQ&*7l^@!$FC+KQYKF!pgW1NXPW z|6(h8J}&<1Vys=~kC65#utcMa;n(zXUHh`|cQq0&iR4ce|F$#kD^iS40O#u%^hq?j z8iwY#_APTz*THCKbRR5i#za*Z_n;*IDc!FYV>D>~O3k0A`JVRr(x}{ii*X{SFWh2t(#v{S5aY9ELyr^sZmi}HmRbrs-|l3 z(%QPJnzBg~maSY-RW^UYvMN<~_L_=?Yv)tI{AEiosWKMURs&hIvZ8LSQMa~Y;gb0) zR#YuBs#n$38jEVztym}=3sx;!R8>>4sHUpQ5bm0_cKYI~I-{ngF=Z}YBw~f@VrjCb zW@(-3PfM$uUpK#^)>1+fop?>v^7$C-ip56hx{C3umM*KDIe*zIC8ws2W38yJS-PUm zs6hQ>jDLDv&8mfU((l5RD^{r53gLu^f|{C&!j(14=hp$rt65x8I=`m2s%%v?Y(}-0 z)U8~RG2E!ASYEY!Vf8xL<07_NJ%3rn^!cl+%9hkr&979#mseXg)2eFgR@PXR6?D_W zi`cYc(fp;$gj=h+Y^83k@r6sO7G7j$Sh%ceevKkjR#(8T6)UUNU}}KZ+VI*XtLiFO zu34d&s}`(WsragCD-NZuX8wxW`3vioB5>AFOs$Y96NXu2)YjFkzz~H93)3JI=2zFQ zf<=p}>L$-$UPYFLYM5&mR+O!)u7dei)G3%37Q6YO7b)*wD%rblJ*U(%RYz(Rk7Pg-XOF%P(HCY5|B5Hke$sMww>OGE6UV#e#JeD`*yq z)((V61YKKKg;<7ZFRD@_t690Ku1ZhXy7{%r$sA#o4$g2O)vjE45u{Md5dlu4Iu&Hq zs;pQDPCao})U8~C=w$y3mg;d+yDAk0^A|3xLbQ~wE5=YNmMvXC#_Dw$piEj>NyknQ zS;Il#M8FUW*0Kpgq=hH1vU19T3#n$f8A!z|>L#pQfyl;GQ<76_R}#`{0!vMk8bTwC ziYiWTOr!;{x8yC5pmI@3@%RZ9!&5U-17WxY8lIYIr9CVaa-OpA7K}COW#vdEHvC67;&$sL$mV{jl{sp~g=!hDFcS_*Mt~;_1R>>~_$P zYTPO$;-ELBt8uM$&@DL|9rV3g&Q=F~{RAav zr-N?E+3lb|rRD5#(2o@=Ir|)ROHQMM{+yO`$U%Q)ypnUoLAT@_birsbqK=(9&CIav<6B`4QG|5(cjI_Og} zm7H=1-I6oUK@Vv;OC0nwdV{&vLAT^=bkL7$Ia?j{j@r&U9dt|1ZU_COmb1q}|8%4p z*FFc`lGEs*n|#oP*C7Y}aV_VFgKo(=>Y%sNazYOJCN1ZbgKo(&R{5oWD}Fj_Ic^7i zx|ZW}&@DNB2fde;lj5M4>iL!Bpj&cs9rS)$PS8Pru0Yf_${ln|&O8Twke0K=LEmJ> zkArT>+328;)^fHw=;QSK+UcNMa&|lDxmwO12mRw=YFzsqbW2X7gI=WN9CFY%X*ow6 zbW6@r2fb9w2|4KBrz(9;Ip~%gW3^uxtoS)!%W*sCMOu!}LAT`i9rPtyPKtx>*8a+J z&@DN+4*DuBC+MIr&Q;?ochD_4^BnYzTFw#&eYhUiS_j>dv(Z6s&~mmq=+6&T`s{Sj zEjha#^jo!@Jq~(_mb1@6x8yWB==W+lhaB{`14^GG4!R}hsDu8PmJ@Q&zZ|FJoN~}D zImQ~lFj(>Ptd`?;(2wYSozFqHWIU61He``5g9rUq7l$@Oox+Q0~gMLcO+2f$UG)BqU z=b&418XfdDGZg*cr6?avQVY;^U+K($D-(Q(WVzp`v}`?HE%8=bzfUO^k(@+Ip^ zZFD?X2*1j0bWfOS81rm&uZ_OMMsH`MSKH`#kP&{ZwbA3kRKwV4qsQCmTWxeciq)kbf$(S0`hAsfA$jegih?{1?X zvC(_j=tphzBpW?sqxZDYkK5?IZ1ht$dT$%uxY#ck<5od}8g3i?97U4%1RK4NjqbD2 zlWlarjo!~jPqESa+vsUF`T!d}%SKPJ(Q|F|fi`;3M%RzJq_)&X*QrqGQ~w$amU{A+FWbQ^u6jXvB)-)f_0*y!7BbiLF`?M@p#)5gEsMjv6L z@3GNG+UR?2bo~fGYWLab**5-08(nWHr1p@FuD2{gKWwAxt(DM^*ywr-DD2j=H1~_fdwlO)K*X1@Wz*4Sy!!ow zCQG=)G#wWFJK|hgni>WFk~o)?roDoHLYzxU({91vC(b3LX}jQW6X(*=v{CTah|?TR z)q)=&?j}A@@TZA$>1Zky{4wHOGMaJ)e}K4`c$(mM5$6)oeb17&#eg=eoR}xPkepK*Fh$j+1EO-rZru?Qx!7n7;;!N#L^8_D7oGHDjRPf=%naZ1T1s_D5DZD97@IJ(u zx|{rhcPGx2-IO4B2jWcCO@`ne;!M#^$N$UmyNLUV9~JzkAaJJSro)1NN1Um+sZsDR ziF0e!v{&#?h%+TO?H2rf;!MR&+Xa7{I8$)bM!{br&eYpfE%*WADa7Xq{xtD{#7hN# zj5t$lQ?B3-5FboDP4K&jbL-aR7yMS@OtDP~f?rRZskO-v{2Jm+sZGaEi~otI5kD&U zCB&IRn+^+JL!7CzsZsC?iDwYsEBFH9OqET$1)oivDY9w1;M0gRH8yP&d?InC#HMP& z#}j8NY?>$dDB?_kO{IblC(hK@lq>ik;!Jr>X@d75&Q#ar7rZ-hrnsgA!8;IVYHKnC z_Yh}FYdZe3_@8(#@uPzOR0NzUtm&}e2MYYgqV2%t6>P{!pW-)W1RG)oq6}uA3f6yC z*A1y=BKVkU+Rtr1x+pci_h#XrdyrYC1xNdDCxfve^Gg&nf&eei`dQNjA-!52c~ zg67M?znrP_L14BP*p32QleaPFe#kLa4GV6{>52vr34PiHx8+R3I6^rXVJL{Vmt(E~ zpGkE#Qn3>UAu?aF&uv-+jv3Q~^(TUxUiPTeIrKn2GUQWTwrwzin+~)IJq}}Fc z1WA}4p#>nIGIT4VDp>zf=z7eq+3AgQ<{q5>{7>j1l*kqh)t+GeL5wB?;+`gbTUO{t zCF`<|!EKqOr@u`B^FclKA|xDyDoEcU#&59xrBD!lgOE@o@VxT+ruz4x!=rw~m@~Kj z<@ClTsb_;bz%UziH=#~yQrVIbZ-WXbq=IM>IsaXAwAfF3z@QSa>u}oA3w?+5k^bOW;PUc?;r8fo}N|JrShO*=? zV#I${CG|rwCzqtVoH?B|adgwXkCa8W2nQ2Y!w)M$Lp&hVC z{F7zLU4z@|lKpJCI@qv2dBgtK(WpK@d2I>a+*`|%*N3`*HIxUb@lTc{uaAFnJ-V)c zsbm}K(bo5L3|ee@!4tYbEctKPa`S(n!UuH;=<~T;&(>u}TbJ%o)hP*;-{iH#PYT_P*-)134mQ*!N7KKZ=%s{U z{TC6M`O+I-iB5(Kj92oLqjl-lWjkGR1!g^0QX{mA{ULB+m$6V1j!Y`e-&T_BPjAd8 z0?@auEV&cBn-B^@)!DOxz=F`!d z#L@UdOCi4gKsmiQt1g9FbfOLk0NSBXMp!g``gcdp z;Z%oV1B12={Q%vy7dtVW+lC%LDbm|n(j5^}sifN@B%xL5zx{>uRZ90q#%bLh(%V?l z_5A+>_8YKjT7)fAl=8i3NKDs~9QqwcUH=g#db`kHen7&lOK!L2KOlIU2+G;EeFyK1G&%$B2=mr&Rx>e|OS4+cVZYJ}`LD#Q08Wm`2ylXHm} zXm(Q%F$R_dm#Sk1yg=7Alf>oXb7+BfoPOhV-KVH4uK!PZWBp$+mnLm_wYdKHi3jRB zf(aUua(rlSyKN>)3FoH&6b@Tp)cg++Kdci(84j%=b)<@K7-`Eb(zRzPjU;lDw7kn)%OwkxLXofB&$ysnUP|ge4%UB}{y}gX z%p7_iDjdrbO}_~p0D_2wjz_Ui3T7W%Su_p-+fGp|0^ym3px4;kZYDZ5B2t_d!=~ zA6mGd(A*v4pTY*IA*TW}GQDwD(+15soqul+Eq)GNqdC#dE1^^w!$;5{31gVkG?sB1 zUWGfOyNFQJtMDEO)yXuItFXuprP~F+BLP1q8Irm03w?$ru*mJBU@7IOi1qm7x9k_| zv9%$Zf&&~Bfj7guA%ry6J*-tsevIkP%qgA31_;t*1gQ#DzN_ugNM@H2p;O<9bpMvd z_{|$>21KVHCcYfeS6u%>dLw3ENj*|@-O5l26lJo(Dp7)+lBAxp9NI-Wm1owrZf3U%}n47Y-Asngo zYe<11valPQs@lqx}|Ydbb8~l zOR0t%qps)HbxR{cw=P6l0%)r&+DmnR3l&2}j4*mzr(}dW<_0E7C;+>Z)PI42-uiD2 zREGHyj^P+)r|>YLP3GI!?uCA!L$}2|lBI{~*h;if!}N0&SaV<-gf*4v4R+)lK<0lX zv;b<<I~@Wn?pcCxk@Kg2!|SDt@Ry{v+4{3ID~v;J?z&KmHrVzsKUw`vw0rJAVzT zDSxfSpQ!nfV@~Ml_ED&}Zqk)QsGwCEGWX`eDmb7VMuRz!Fai?NPhwub1=F_7)PFHK zA_K@wO=eT1$cD@sw4T#+Bign^$ZXi;e~S=o6)}6FB`!Xv4^>>Ov*Kcv>MkNK=3+Y_ zvBJ1WN0-<{M7IP*Gbk!3wtU^(yy<6CqT+2D1p9yZO9elp;u-9-LLZ@9=EV^@Dlm=g z>H0W?aM6~i&|8b`5cWThEYz)KFy~r>*<%H?Ey%ZXTMm2vJy`!T%|8{|%LIUWJ*i%< zQtv;RT0KY5PPNnvXQ`8TYz5_(L`=+bH8J6}PePX=rnH^sGE-uzd6X73b5n5JGVF)f zfho8%nEevYuMIi(LZ%$vLeIkG$NC4kFf-xs)W%RaaSyjZzD4yDc(^KQQMMem>}2hZ z@A*n>xkMeSvM`@8$~BN3p{r~$W9D!eRvJlQ&V-LYMlSK+*%pC{je{iKX#PQM=s{RP zC;uQ7!BbJ38F-NNrN4~;lXHoz-rJ&+xq}F0qXoT{%ZQ$q5EM9-TytR|AkinaV`Bv zMB*aVe~K*$Uy7#K;~vNQVKd?8*J8S6JVHet-h&uDHW)!shQPyq^4u=L zhUqTs;DXq}1xjJ#&%wxS61oC|;4$tA(GkHBJ~~|uvDnyhEHc-uRrfJ8#TebtB4UiE zz^I}cTQWRA;Bq4m5Rx!jIgEsEL}y%Iw}6!gN9*}R6-45+ej%f(e|n?X0NYx5)NtZ~ z`oD*MhAvozk`O8>p>Kcy7!rC3;%K0*^2~t?FHSJ~dE9xLkG?~n(Lu8AdYjO(T8@%v zqJM_AU_ME7r4857wJVt;fCa)29=4zrEWnXQEVT#X!~(fa3uJ*{&1+bojWRx_q26i0 zB;1+&hW?TVF+0&={FC{~ZO0s1(>6F7X1XlSvdPsrn;%=qm{_DOB2fV=v zMI4|${i|@1&`^^DWAi;tFSmpU4AFtvWe}{90;D6#fuVOk#{;U}5Jjsb+JdCh{&+Nh z8kx!nHPXovB%gy_2gwA~BS_|921<~4(^?IZd0*Ir1mn?<83tobvdxe1qoVDwoPA#$ zszA3`aaQ5roAVJOYtx&}p)U}*$1rI-FXa}wA#(;kTH)THFO@}}kJuOglLELe)~n$g z49~Of1j~}!GZDsdYR1!|2{`-3H-}DR3|gl=aew@i=O@R9-T|3=+Bn*;ef@jE`U9bl zLDPBiBJ_hiJ({|5mH9kX8|i#mvBT47tkTaf$Kw>W$mF7JgmrYHM*hbGp3p@t3Jrm~ z@njiW(9lbCkXj?6RNv1dtflV@t-c+*g#(|7ZRBy3cFYfW_!ZGL4=jj9+4x9Ee2spz zIR>Kl==A1LcgWFQ-v(b`*!fo1{~oG`?Qlzx>bm8)vW`x~Q?ZE7W!!KHHE3_mh9o^3 zBz^V{%@uvHW#F^03qo%K<%5rS@eR_RxQ9oLP6&;J&Opp6nVjN8p1!?saJ2;5LW%Hd4f<7gLY{trg%On0&1bM4nA1V4}DC z9=RcOm)K3t7PG~P*xaNuruEq(WTH>;Fi-X`g}%dyR_lJ=r)2wJ6`UWlZHU-dl%A>f z$K$C4lui((9d3V}ZI#kcR6G7OT1431?s%jEBlJDSsvSQP5f>dgAv!dQ{f@#)&*7O< zbEp_oSX4QHMzG(vV!u~HTj+7;?95fF;2B{<&O2m8#!GK}P6F*k+ICy#HwOC+*rOrm zFzV}FYX<;iZx-9{6x$+Ut9PyACg}szhst0roZ7}f#>J?_X9zVYu%9^@+W)bLo(Oz@ zGt_*JPvf8W<1N%n#Knwc3w|uY(_<>c$-aW8|L?iiM6}D9;xM`8OwkLw$T>~9z^y>I z7_C~*_MFOo#&z%T2H*x51F4QK-8V?OKX$of_FpXep%7RZ*u8Ce+rGHFMK2zzQ!!MX zxBumlyuAl8ajZW)I3zR`l>kz}S4fjI`CI=!Hb0vgZQE|N7XI+Q_*!y?7k-Ai z%33=iJ|cqj?8Wx73={8<5T`ft6C~JS*mq*#$G1awVvVIq|HU~Q&s1JctyMD1r`9ir zzC-v(GW*>?F^z2KvFL_3ygwX;5Ja_Y!`rD9jSwPb*mcA33E(h7-5si7Qs0Y^=w0yHQpMHmQl+^eACXO^ig_t2uDE)>!^2xc=1l5>RPhkaJKpNk7SS`Zx08$y7t;A3)`-s6P;_k75=m)uuf|(XP=nNdmnUZG)zvYa`@Uv{jnMU0mqL4@KTGP2+qHeX3|xnkKv6w-oJs zP2=Pb{YlYEK~o=lKA;FwH4{>`5xQB?&eb$g?n*@~&@@qQg`$nsH0=0{&}>BuXc`J5 zRH$f!G))FET+#fRCVli$w9c9)x_A_=9cW77|NKKn-`39bnWC9?VSiDyGnnLXg6w}o z&nnt~G!5)V=zc}}QPX4)H!0e8n&v0p6^eFT({f2$u4rFr+D6i5DcUhjy9nmzgNIOM4tZ8DoQy+){UePoe#J?1+QPX4)hZXH9P4iQ^XB2I( zrsa~hN743Z+D6iDRJ6N5QwncVgxkrq={2qcp=w3CMYRjQa^MW-@N7lh5vKl^)O?e@F+y@JB$3Ru3ziy>p zZdmXys=;^E+Z#)lE;ahq4)NDi;Vb=h!>ahr{ZamYmBxal#S7L9k}r|t%l#GAD=(@_ z8R#GCufkWst15AOfPeY?wf^uu3@tqN@4fRPgOq`Gid@1?!887f3xXBmjNE zf(6BE2I-D%cN3rrDz08y%P*nh%i^`cpfuyx@!5mAlE9Cz&e!20h+6-u6;*4i@$GaD z88;FPf!+$u;b<4HtV3zF8YL_sV0iPF@f-K+U>=N8DTZ4b@QwXCV_jcrx1e~+`eLb2 z*A$@hDWKR%>gED!g)i32bp>_86K*AKj42ppwGz%N0r*9DhlNQ}CO)@#`gEff-Kg6c z{?{7|bmz7^3qV=0eyLIk{#;sFwStDjJqLIh3yO>NsOZRr%W&C13Y4P5YpXDX%3A;Y znks)n3by$t*a0X3u@P^7;3p~0VAtbgSB6|psnJ(bb+RUUzH2#FT@Rcu3Ngi3fD8R zKVHzG!$IA{5TTeN)eh555us{qijK$`MtxVWT()X?Rr;{S=pMIB)UB+j#q}aB(~>tk z_{+-u`fio>k*&bXCaSTs)ihfx%&4$Ol#^gb#Hg|m?}NZ_r>s|3L8x0Hlvz^MtsN7l zmsU)eRBEs+EuLJYfay|9DwtF_t)M{QX$9k_Oeqs^{EWhiFnva8S@9&rk~evlYCWxZ zO2vd}#bw14@=97L!Q!G|3pRPmv`H;k$&~X1DJ-0pr&K5mPRg60Xys)Ec?z1AuM{nu zFl_>Eyr9n0r&LUyGFd4A7#!0Irdlo0OZbMo|&x#hTVA`}6V<-eJln#j%PoAm$ zL5yz8pE5(al!O`63-ZIflc$tTpP`J+y74onE8h~yE16c1m*0Xg(9vT(umwgq_eVI?$nZ@4Gp$jz{HF$tBVnl+Xdqip#W?r z1dtTPD{*WX^fhcNm!U7?!M!_jLzLXWQ>_+G4sBW0ip6zHtfiC`rdtcQmR3XVf0E@G z>0NTPqKHjv#lw0mxQB+ruwO+uXbpBbr9E|h+hd;i|td_Ky)N1B`KP~MF4 zT9gl>ya#1Dc5#PLeu45Ulm*!R@h-}{Q6`~WfZgvHl#_5C*o<;1%3Ub8pyZuqccT0= z%GXdHMag4h0uF|E^Z1DJag^ty{21kWl-`ff9_0v>`&f_iFv{m})a``B<9#^8=A(QH zWjV?(P_9MU6%PbUSR-25Lz zc@N47crNn{%7J)7Y2XAi5D(IZpe)1#$!e67@l5q0l&_vGg69d@H!inbP%ithqF8H&+n*#bJpvR%Kjb&=wao7B~Q?A0ejZtMN^MJdaiSuE! z9G$XHCEAo=KGgz;ZhqH_I5%}(5Bhy)q2CC)3-iscvmg8qf!+-MhXF%QnyWG{t0XS> zg1D@_xU^YuZt@%k&sMa(PV+2@%PNe^EsM)40RIHlFCR;v0M7-A$L~U0>eCMMHyiWT zPG<}xgMK;a&yyb`+vJ)Ym+N{&hDhJ%qrMmB`LS^Q)VRau!nh-5Vcb!(3}pfE87Lf999LctH*X@}OI;6Ix&*-DLoPaj9L3Kkjqz~_4X*KVzH6i4y{n@0 z;!-xnOoTlzjY|OmK@EoSac=fqigweH%LwzuvG9(=DWIj2fN@oL;@m}EI78QOM*UpW z57PB>QD30zIX{>u7o&bK>&5<6;n-?K-D=crP;LFLwQ=rTz(+v;0CcY&ubwxP<4PCB zl^4d%D~wxG7*{f`1MNJ}(kKICFUQzQZDZev`o;f4{chB+`5)>VQGazS^|akl z)c+RsT-%iGmW%CJcN%s3QRlQP$L_)1v`XZ(q;Uj+Sf z&_5^Lq3h(h?Jn0faXVd8<96f!PPlNptHP!{novJC*06K17V@bb_1F5bmFr8Jez~X) zfcFRR_9X8w`a6n*7(yf+ca@>ci#zIay%O197MiVvj5o37@-GV<{Vk2#gXVkDe2=Su z{XbyqpLyyDw7nJUvOVVMgFl1b4EmjbTYRuxe86^Jp?)LQ=}TG9{JC1$H5%*jr!90p z>5SJT&4_|R}1`VfnP1~f4c<|WLLq02&D&eY{1U9Q&URl2-cm-p)ONnO6I z%XfA8xh_xYvdsY1Zx>zm*X0OZ7V2`QE*I%?wJxvH<;}XhSC>!f@?~AVtIN-Ic~X~c zQgr{i?61oax-8V?OkFP0%d{>vB>++;7+YHqG>$1NtN9eLp zmos&_NSCX1d6h12*5$prd{UP$>+)S)ey+=tx@@EKNf%xA*QL_xm+!eX{$CPp6f5u8 zNM{AD-+QnsG2i5M^na0W@wZl5zYAgg4uqwTb^oaKdk@y{J2>mD-*K>hw?U^T!)kB+ zK7;jp49vs~Y-$iiNTfcu`{oaAI-uhhw>vs&C_15nd zSieu;thauLU^Z{8!pm9z@pMJEeow$zZ~bn7^*aI1dh7Q9to#4nN?h2!);<5$z5dR6 zvrILx?(28fTlex?_wYOGt^4+^`}Ljm);;>xz4=c4t^4t<`|zFhgS39uJ@?Lf>ppwy z{(5J)N$K1NN+}Yl`pWM2S+*xnkJ8s=G?yR@&6SwXUch+0?gj@H5JL|3czpeYeo%Pne z-qt0?a$->^;<6Vofr)xh57H{UU6gQ&NoZF9_Nj zx?aLpj$@DTgTE+u+rbbSWxC(OUOajnNv^ivVqYB<-8Kz1(bGsW+x!L9uD=5I^ixbR zCZxOK(3fYxxuC~H$MDzgT-$nqGEiE%WA-M4Cmp?chOjr+IB4a$_C|t7@b?s+27+ze zZTWeY>j3%wNQ&G29^Tu&i8pk8gqo2MI~(VbBiVP!JK)b|PF@MJ;aS@U@Xus- zd$PdeJxw^l6G9)}{}T3jzQ;u!-ZO;#o)b9tc$*2Qc*nE>Y?wsSyr1KM<241z@{VH* zmms;`wm3m}qXh|ic@d^JMvzkP;f_Gs2vY7%>IuYc?tzB$yuX9uUXS?*kR{$Sbl`1g zUWuaG8-iWD34+vlpX&>xgLyA%)_Nzw=H4zQExOS=8z%O4HTf4HS9G1f*^9 zJ_AE~lT7|@_$+e<6}4$X@Re zBE!w0XtU4zR}MQvbZhid4{xUV8v1$BaPfwyc5Occt=%Xb)x5XHo`+8xecs(1uO~YW zq&o>3p1Ww2yEt;Uryp%{@0B1Yz_V*eb5llp`jjJxV{DLG4MeE#Thxw5{394@LMAmF zXOf;Uyc^(L1z*H|@&tCfk3vXv6xiGH&GjPUseREw5EFT2R{N`|PU65$0JjQwDH^x0 z7jSf6sL}mO@V1Xd+Zp)Z!HAxSB9Y-9*MpSAQGEgSB3B~+f+4QAP!Hj-89$T(l(-Zo zh)*RL<&Jp}PR9J|50AQbA_FD#;5gmxKSEU72k_Q0VJbE1<2nGu?Pjxt>7*nJC6V8( z>X0mgH$hg1;nMSU@K1-40v2E_9Yzy$y@R)ozAAzVn3Em5ts&Te$=I=bJ;4lEqhpWT z2;PNZbSmqJPF({)?KF1?w2O+4z6s8Zaz`J8zY^M_qH~i(LF`4CYVIz9E5PMR8fX|@ zMzBl6lZxYZ7ttgd>YtD5w&ZC~jrmuB;#bp1jBks-l(^$sP!gYmLS1)@@=GDL>z$nL ziHT&mR~Q<}@Q5(5+pdq2Az?Jm+g*K1n=fI{1mA`6G0@<9RQi@teZ#}A&iIz^#ykGj zEE}Zlrf;@M+&dK(@y#*c25fk9U^L(PCPT#M-HaLLn`=^n-@C*WMpC?;K=REupFpZe z^Y%oaz6IuAfMj`ZW~U2HR~&v@&wCH%xUbR-010}RVv72z%u;Au>Me(reTz+gDZSkL zJH)K-B6B8c=6P?W2FuLzfh_TwsP`>57XYdDwnv!zE;iSIw$^(e-0!O~Q&4R5eoCZP zq;2({hY;}9nJHk~?!6Ee^Q|%~fb8_%Ptj{l-fXaJ>C*b0pA80_FnHj zaIxU?m8hU8-@@u)it>#WhJLHXHn{8s9!`?jzbKh^wgQz*;^%1$w zd<)1?ZxhwI-h2?9hP<~>^bO{dK#qGqqHZ^uF-SwFIuG{)xk)@?n4SL$Tl#J`Kcv6R z&JC3JTk`|ROE5d{8vtyl`2{ea+4)+e8s9C-M`q_c+3r^J1nN@E&NGnVeYcr|&|4a0 zB4T{I%x2VOnVqkPXy5P5-=aaT+4)`i=5`rn(Cj>d-oHb7FEu+yA&`B$1uHi@ucG7b z6l|W^*~cN=CD;dr{OvusPAEZOVsV&#Cqy|eM@~ReByiLcT#^h>#5~aR=rOqt!oo)w)cQA9U>Du z`8a|}t8+hX^VnCy`JKh-w~yTJ zZukps!?#~7?YW54{%OKK&jkAS87krTTt?lVC7kRjr0t)36L5;>Uswfw&r^Jw=WE7o zBjGGh6=U%Q!nvON`T#z_euFR%WxM`40HlM|*!6Epeu-aYcDtX$yNvqp0Msx9V!x=q zi~O^geqQDu4!hmo;Jy2q2wuZAcpw;##bP=m(C{t-`!Y3!jbpg@M_#_Kc!#3f9k7^~ z0u+-N$<>Bl|9ZMG&9azk!b~DlID7a_-|=Fk4$pol>idC#Xn3aKfu8RqVYlaD&YT|! zCwR))_bI|YPg^ScAHsf56KCa54AKK(}c4;18B?t63+EZVicTV zyaqifRJED(Qt$66$1o|h+&jq+#1v$ncN|DQmmo{L1?(b9kZNxq`ZQXQwO&3!^u?Hz zw$b|vL${4=j<$NQCtF*o+3wxPnpkPG)4L-Dh)0m!-p4pXuONH8*VAF`1lj8yOgpqU zImmt9I)+)C)HHhk$xIV3$RY2anYt4MIqW^jESf0D5pN%|br9sJx0C`p2@>)irs&Rs z9QW>JEOrs(ROe)-rmlh@+5VAPy_<{y$@Y30tB2Gf*)HWMk_7XaM$)UyTRly>yl1Je zxA`$#?7e`Z{U&F>;oa^6a*i}`dy9zlF*)xOynkRM^cBSCb-|RrWHF-O%RhYe^)osB zQ@mf|-Pd1g(!8@7TLVl+be8u;vJDi`x!&`L3=(NUBk4g##9(s<)amK-4K;fq61@9q zrc|xhy{PgH(|WbxFw#t>k_02^crvhb^J~>O!<@s$>1-SjqZr<=iDW7Zd4FWjBLqR? zX2#h_a}e6}Oz>r!+t`>_F8M~84?}Ik`xygnwD};?Q(h#Pl zpcx0nkpJ zxnl-Xr&bg^3*Q}%>!qb!<2N-(O6}*zeDl@&PcDobtF5Pfj;NuRkr7t6CA$Kb? zOn!vpc8{@Gxo1-8^4v*z5T6_>F&nwD|L^19&kdp%9RU^?(yXDc}kEqx+gH6{1EpH#3ju_82TPJ zx#38-fcdz|^g?t(UqKR{(KfM^yA^ChYcp z4;6bDvb{?%dhO*r>~We^y%#SudYI;|0R6iMfXQVRE8kFFQZ#JZBg!P4u(uE37}J9} z<92@sN|%JBQS#iO8wQ#*nn7uJ79;^4L)cA*aiw7Ic2SyM+y1Im2CQe3@Nt(pU zMEa$thdxL=h6SmoSHNeO_u2{g1nkjMT$p$QandtRsJ9~md&Ud68UfWaLBL~(?4F4N zCc#NPI|z6y)`FfL1q{I}Jv#{)+ZSMG0m~40J-Z0F9+Rb~WR=A4&H?BX>VM&fp4|jo zfW@^}ABJAyBv5{=QNCS&Uu?a_8Eyk zz^Z-Pi9Yo8a!|$g%|>DjtBU4=;%a7-p}*lKVGIumPfD;u+|ek}M3} zFo{$8377{53>+-rhnSNCmHE~njSLj?CBD-KV5%_mKmZLIF5p#|g@ZB#ya;|96cF%j zGGq$40iiKygn%7k%t0ds+z)RK$`Y^_JT^F9z`+C)1RQ}d8k{H~FMJ%VhM9oD4_3o0 z#-tvi#`YdYF~lppylrl10kcWsm9WmxNkY8|Q9X3BfFltaL#GIMB^=T%j-aa$yxlr* zsdF)5cgtbob-R0`kHpbYDs|{qkP|%J z!I+w=jthT=j;X__nBPcdfuj(ZT$GcVRtPY*Ba}!;9rGMTUNHdV90op;i3{*pCT_P8 z%e8b#>co){=Xn)jlX~uNz;Ae>(Kxk)>qd&_8RXB@Nrclp`F#OTrVd%2G{RE`fj`&t z37nN$N-;st7??eED);xLo|C9eoyKi*xu+)rFm*al#q*%U*eDWsdal79IAwC*L>Q}L})>xa-eGlT-Gm34K2pXP;p?XHo ziO|yRSpctR^riqiFn2~Jc~U%?gsTV-@m!1Sp0W61$V~G*g@l{2 zgm9LpA3`HzsT%iYXqa)K8utzgC&748|JVUATPVzK*1`)o6Z4Y@~VO;!<6XmeyeZsfT$9Rtn z=t23r$$!{AAeJ59N#uwd9(n}P<(e@Nv&4Xqc+2%nJ^D4!#;Sq}A8)Q>tLIKiO z##r+yz=?~nYzKPF1pFB3G&7bdDsd1dMrM*wyTQkqJq7f-@ZD-jhKVcCcBEUVPrzX# zV+GuYm>H?kARr@4*5AY*kWRByN_RuqES1vvcp+<)G%J90vZe|65axK+bOBeH0Luhi zO$jpyy5wEcUQ|o9fsGvRCr&d1f~2*45|Afp_+(}Y?TA& zz)RU`rCbWVveioY2nI8%%bVyku@Ivht(K;Peti4>OG$j$XqIy`RZVPwv2%Va;Cl3y zbBlnnh=H8j1pFf$nzKv5(eP)^?*!bA)R}X;fa77y90}0Gd8A5sCVoubyM*BmxHji* z1+wFN1T2gJ_DC}VY-@%A;9ue?0 z>hP$5KV!<~>=p0^WRRT41RMtkFiCS>6YzS>xSZDoe3;;$1@y4DHw1i* z)Hem}O4Z*I@Jf#Ouz=@M^}h(Xp6a|U;H}6&PQ$+&P(u~ zIH?~9dzse~;}I^oH3GhYk>$;%?AVv#iG=aXzXY=!gvYNCNuDxfwDBvs{c>aHh9Ql= zn7ebg`z4Cy2YBOGaT3S=1OdMB8@L@*0xnYmZbRkx%g2E1_B`STypjDS7}0G=au-tF ztr+w8t0oD70upzl(S){=9DK0z1eH9`K#K_~c|MBlk-vZp?Po#4b!end2+@~QKrKvH z(4J&DjXY|rzk~HjNKXabNlxS+EEe=2n9^20axWa_f}R6AA)JhXjTo{y@I(0BHLwE` zS=2y3_@f7YfHf&*U_l>zh8}J=E`{w<(6uq}Etta`$e($14Lr9m+8JG<3oqXWhCw`0 z6>gmdu4sItbM}@psdg+rMJQIt+80>Zk16qiv9aNonhCa(d@HNx4N}P(HQEV z+^q&+4#5;p5_&2cD@OBN2VMrKo=GM4Vsl2uDM7xg{K)m(HvUrRNx8jkrx8?{1yV- z+3y21x~*P1-*AiCZo@Uog+|S*P!XRv5NGV)Lz_a=B%%Edyzzer{N0A@8#GNEiL4$R zdlhJ|{WQ?9M*zCrPvBkF_(K4E^7bYm)Z|J%UE+4r_HOrddZ1q{tk5QP1ESdTZ_LIv zX|$r@8ICcx8BTAwJ-kh{O$Olv&q{=Tn*d>-Cm&XCGlKknj|=Z@MiM^9^E}}!@rLIH zOrB06s~n%?X0xyuiD4B-?{6EaU5@!1f=l?LV7j6Dj?ySR%7 z+}{^^-G_F?18H+S6-3@E9!wZNMsWz{Dju>GJYD9*to;vpIfj^Z{2L2H#t?G}$(>{j zF_)4)+_NA3#jKA_hOIpTEYUF=x&fZ1o|TX+0o+sJtP(^CV7#au}imukESpa}CAT{2=ee+yJGZ6TAvIF7lBgYzL>5jbw>Y<46T4<9LOQZ=Mrw{99Y&owmle zsK)0Uj#+arnEM)7xMD7Q0i>YIz15pyfM>^lt6 z7jqkf!ifD5v-s_pn!m8`nMmp}b;c7Nh5h*(&91 z#Jrq1nku_Je@3&3Ic(O>gAg<(jw9UO^E}j>m`6Cyvl^3S;snC+hU+y<@QL~Cei;8w z$COiVY}D~}=nSu6o6*o5a3#RlsE{V6%|$XZr$pTmMXGU$pPWWo5fn2^qZIEci+2I0 zQJCtsc#k0F%^6WLk)!;Yw>_W39E22cO1hCg940cKjd~oU*eL5Sz|&V?yk=B1pP$4= z&8tzp55J7O@$!KAz9Lb`kh=~5n!7$q!)a-`VJ1pFYXkc=)3`NQXR&r>nloCYWtwGC z9(=+P__OAk2(A?t*QQb>A6#Zyra9G2GXf#aI1`LFC`MN;gqFodU9H)Tz<)H;d@wy5 z$*DdO4(RTt#^B9ika8)v!^ILF4B2&-ZoR>!y7IENd7OdIFuNY3BeI5Uhuv5m7T zlJgHX&VUh^Yva5wlJglGXQmOj*v7d(lJiv?=LjRP#m4!sNY1~taJt;hM&M=}YaAw+ zZSenSVWoc_uyJNZa(-jugh8LPaW07DJZ2ew=VOtaGi;oYxzfh@k4VmiHcsfd$;R1caKzZ_Y@8VTZ*81uk(`@s zoUrGEHqP0RoHyAx;iKnmoLeF}?`h$5x&21quQt}bk*rVJSt0cc8|w#=tS{SHHyVMT zZLIu*Xj|C7*TNd*F-#-SZemNAq(}08*}}^y;qa8%I7 z`Di4km*)e#m_XsE^KG2(MRInral%p6HqNM_5u@*G7a#+n|<`mUYzM=T~b*7GA-KeMx*L%^}Y#E@to%J>& z5M9#Z*o;Wl0e03~jX-xB>jjalnReD&j6kZ5wLX$H&&J9{dc2MGiAdJTk*p(T+E{Hv zn%}|}(~e&U#3Sl6UTp04NAZc2^_`9kHBjvLD${Wi{t^3J&B1(`)gK2YjdPEh&3w$) zGDLj#K8>s)(x{OufsC@g5!3(#I>kn<*GfW(?QJ0PF;T+$;t6)8@-lZl5mrKR{0VfW zgu=fEp8d1#YA2){BbUcR-h(2~`l3sVyy)T9pcKbY(~_s~MZmKYhDh(m-6D@aFl^o} z@~kiB3{v$l()O@C#c>DaZGt^@izC2C?{)*fCyGb$WS3zCwgpssUP4(10kBBa3A0SL z!p5k(b#2&IKb7k4jFBJk&~TgRVtok+vs_;0t|a(QIZScPMqf%7h2H>N>9R|7`G~sA zwdrC&K%_3~oVwgM$g=m>0v7!h$5+@2CE9SUb7{~JbXl{+--(QXu zvowe*#+Z5!DlS&i9tulS1SL(uW3S{1sV3@8=rQ(je;CGvZ?t+<6dx5;>VU}8%9^__ z$3U`nQ)9)!KMu;^pRt;YM1h6C$L*YtKf%#WJ6cVbMCGDw?sKTS1x&e*19*#It7F+%8#$;6Pn&=VYd)Wbiq$r78+ks-|nK5pIuJbu-kwX=qFL6i$^bE{EzFPKJ5 z)(pp$HnCAv;n^9;(RIzJ>yB0kQVh_@o~h~HwGeQDM!Evw5NpxXm^ZpYwK2-0kD#TB z4@FQORq$Az!_6G!QJ%xiu~9sT=kXDrIZoiQvH1MX%#GqTjs5$ml7vSE~yONfyq>a3)Gb-AMH0uk2-&hvh zbz&rpEdj4M-lXv*=oQ{J2A|Pi;)R5^QG7}ewWE1MdLakumH|cW*m&9a<+Y0qvwajF zgGBAP>N3@Rf^`Kt< z!H`=C;1L3|0Q?oeh;q%|M_e`49Fb{GGe>2b<hP90v4B-85cDP8s_#vOr44W&=mmxCL*^TfII+3puKK00m7~Tb4#j;jlvHV$P1BA zQ$Z#wew51dx}x>w|2|?TX_P3{1IQ;g17XZvWDy-2UT+@%Z5l!#w6< zOh@fFwIRK4KlJdG#!u_8_*&yuSe$f4hQ-gWE1|=LnK?=oD=daUAr%&PIB_)&$$DHP>VJ5HmRB|(y1pd~Dz|EJlJ z-)e;6ll>=+C_j%F2*bQCezv|ZEcafcLvz=W(UzYTM}Mr~%Fha~0IvM}XYJ>EwIAQm ze%!NRJiiTLzNzc)+mJ3<=Ph0T(1!G0%wvaLTnnRi?A@T!!FvwB|5N$>{UOQ_*e%Gb zHxyKU|497)AQZ~~sKPKl(u}!aGmpCdI|{arnWw(}k^2)E+Mv7Ke*+i{V1x_DB)%-a zXG$j6DVe|$B`$BL8SO65PlXeo&>d2W`486$D3)6WdMW!U2C$aESOB-NLu(+*;VXK2 zN5f^9>@N4~h=h7AijlAva_o_CQwcjD4GH326$yJ(Bs`=d;l2$`xpnwq=52Sw#}#ql@jt(>p$_VAl>{zDGuKOALE`%Dn$2?kdP6S)qjUvUC3%@oyEyw~ zw#Q@bli401z}a37z!=AnxktCdDy-VQ_ z*eKHyBsT8Sh{VRb8d0%P-4({$F0o-qLOvxGV_YZ5YoF0?ivWequv9zyD|6n~Dw~CER$B7B?*^PST z09Ubbr^Ln`P$>V>dH692&A8VE;di-u0L{G<^mo9JdozHa2y6q;yFFrKw`R9uV>tH- z<81qcjhaD1y<2Z(OJ2$J!uV=7@)lDjqWRo@J=&(J0BY;^7L3hu6_T{=@Sy z6E)*J6M9|g8U()Fzk+V!_?&wPKr(@60r1-)Bg!?q6%Xl>wdaO2#we>_n0mwljacEZ z-q0DNzpj8pd6}2HHnU^y50F5mvYtOj~Ax7YP-ltks)VA)gHoTV!v*z ze7>av3|A{Yw;pwLSDL}+H$b*pPZY;D7?$$6!UrG^W`8_b@yp{9>p4jH5x`|7TADHP z0zbN{lCG?KS~i5cx_E-smExEO(W)zj-vT^c&f|+jf@{Y-^+ezz*PDH?MMibt6wax9 z(cXT@v)lWJNvaO^cEM_aIGnQh;**S#!dqsh8`(WHndia4V2x}8vQY7~d<<%2Pt?_7 z$T7)Sm(24-H}i2Yt3#tAs3V+$$3Ef*W4UZ!)Psb%u4kyp$WM_~&50tRL{9=9NBJ^$ z-I8zFM{&5ZbSe8NJP&yKi4?G&E9n>Z$&e#vsm!hhR0nFbRN5yO^6d6m6KS99O`7*+ z8sa96FesO)hOtp^S)L92URTrU+pOxaVpO#VbJfs3nal9KI zrNZM8t!k8GBS$$wMmY!7fzNbz9A$sV`=3U6QuE%)QMyx=u{p|Vs$p!@$Kg@>bTvnL zu~pqN%AvYijj~|?Mwum}wC+6Wtfa%2Z-qyxIPQVk%9jfN5P0@zE$<zLbpDM*4dY7 zL=AdzCk*-%8MJj58D^8b%w6%t)}R$fdoZiGS9l?CwT1Z9!moZ59_7y*TZ_f7uG8_O^u2cycX^4 z7If;>L-T$>y+&z7*=ra>`k?4FPFFmy1S3!MIM=e5;^>MLqU@#cQsBy7_@1=b>jL$p z?j@6tY!JBVk8s>CTYgXP$Vu^vX0A{R#GmCFm0gfE;YO{3UeS&EiPjeE4U^Ak{tBk- zTQn25&)JV_onS8DZD9DH=0)i*iZVm$EC(KO0cCV77YJTQNxa>fnt(A6Ne z_!l2+XRpw;C*b{2murMxiu4fvs`C;IeB`r`Xl@Yotg9MZ)SCjgEAN#ZLEtV#`IbPc>VMVpmMIET%X{p<|_( z!ubd3O0gB9*z;8ETbp9#5D;mxGrG1b6^qYOzCW8{T}>#qP!zLn^&G3X5or^qSc)l* zAHs?$JQc}CDOM?pT>?Citb3!yjw{9R%!i*nV&k5!EBivPK(0o(aqok!Fa*VE+rE#Q zs+oSFJSD=0W0L(C!DJbMc@R?6EK~$F3l%)}I}UY^N!^-fKK_xMa&+J|8+m*S z*{vg;OV47}S8UYF;ZEcMN}z{kVx(QA+S+0)dz7wLi~Z$Zn6R_h-?}JQegF_ko4XcI zw;ZZCeuBM}LlvHZiJmTz)NZ zwsJPS%|HIZ3Lm{=-{ozL5$$!2<>}QB9oVDW($i;z-TF&|*r*4>PQXSzUp!qP+lE5f zHWV3wM%|j8?hM0fPoJZEqDw~!8QX-%!_t&X1Dc60ou%5^T{>M?i%SbG_=a<#Ych}$NVr7O)a)8utundLICxa?0*DF35* zc+{a8H-gPzL z2+%fdnzTuiX4~wxP21$|X0u7wCcE2xv`q^XDS{wqt0IW}T2X!i3iv=?6$BA^hzLFq z~IO~ z5nN}zmnBe}9tw*?!i3-vhBZ>P>;8) z#x`{m#9t`p-iE_=wSe>YOHk~~IBfpYIZ6dZ0ri|^AiNqM^i};% z9e1ccr@&6tFzOM^PSp<2P&;(0M)(yqLZ@ng=cxf&I+bOALzcz29{)kXR6Up)__mR+ zjo{v#}Z7SX6DZUb)``RZ89S74_avTt{U zewTz=t;uRItLJ%NXE%mZsx5Fsbd9*HBA|D}=qRKPFDIYb$4qO-5EkVX_9iWol|hu# z8bUcYQMV8(rA)JGA_ znI`3^!wooWJl$Q+y#16z*Yg9HP<`aZ{|f_Rx1X<-aumT$rW|$nI~>-j+j%afN6>;8 z$?E8_t-w{pHzD}USd9`?N6(-Iu6{`&zb#057%lJ_O}Ueiy0c$LoqYy)moG(N{Uqy- z5dyQemr?Vk2+%gkuHVNesi)RJzB_czHeHEs6j38&6OEAh$uvSD?XRCY7c#KD1n25`ZnUbunDHtKX#9lW zIjp+Xcq5-y9bCNwh|H*-4mw;v!bQrf>2R__qs&tESMuL!QI5eHL;KgXet@5987RWTjk)w?pV z;-Vw^DD`l9Nvw|O8!4dB(@yo5b8*yYPe4_7qrL5FG+uvrNU!JP3FOKTM#%`H!KVbtK$%G4|FrdVX}UaU=GeDH?9gK;Ij zH8WsS-8Z2^ohr7)sJhEXpvoR*s)6kTu^)k<>2jc-1!>a-06qZFa3>ROuth=SXA^?I z!W@e>@)|^>#)p`UrgZ1Zjcil_ZM3LjGIg+4yip?8d~^sA zP&b*2!k3KF+EDu?pxBPXhI5(e0+?T!`eIm%Hna~?0+@d#Wd<jJi#Qx*x(WzDCu!Vs>@nonh2L1oD;%B5vp?^D*Y z*C^V|xF2;1+zHVgr$GXq&Zp}Casq*5VQq;SR6=L(@xY!=*zRm0hdDm+T9Ka}j2C9l zsK9l^OK=#Zd!jn%dB_8_fFGe=2dLK!MXhD@5L?yLitf-D=;*Rf)zdWd>!8G@>S@Xm z!gQNv)zd_P1va`XZ`lEmSM`YEYcqV0IDC&de2*x;Wv3noj=hRwo8j2&aO`zB_G*sY zk>I#jaolb=?sYisbvW+T9Pb|mj(Zfx?+wR24#zzX$32>3-4xspcDLf7fwF@p#?^N# z4w@7*NYf_<$tu-%lbjBkBvs!{Htz_cU@fMD?rCG}yRekTT3w$)D^)iKV^j!@_tnh= z!kjehFZ&$^^3XL(4Y~!p<4?!ZF{u$w4JH86^YUT!xV*wzs}4ULO?v{pYduJJjC34( zDjk!Aj^9ovQ0a9Mj)N!6#9wRGPDra9q9H6u_oZ~uYGUQkuW;P)(?bcI1YsR7V??VQ z(j4?2yUO!OP>^m~(j4lz<8V~1QoSKwbDXC+HdFyUO>xkD*P3J64@?=;zHQ2wra8U{ zAFdcAy@MAL$CJ>qVvtmcTB~VXmb?p&sqySg9J1g{YCA=w zjDTV(F)LA@!_oRu+TO3j%DvyhpN4uCV*>bCrH)9-KwlC7rtp0m)xN3kLbYGqcZJ%A`>s*@ zHEVCg{?lMsN7BzbPfI;e@2qbQvg{v<>^}lnUrN?{Jm`8)p+B|sr-A;=r$4Ru1M|GY zT9bKR2g+@p)0XSP$Yu4C0~rZd2(j#kMcuGfe=2KrD?F?kwIwg3>{&fX-^eGaK~L5v zCj@I*rq#HXPiqU(qaN~sq>FX2u;9XB)bc@`IvDv-(~|&N0rWiwpkkNZ_lnxb*8Uay z&*8*6lJfl$OFc@hKr$W|8Giw=zLcyt2D;v1`jf>UnC2=LM5cKkD7R_eaht|gbG(>U ze=~D@59T-=sw+d_BrV3=$LGizbJaPx_$p(K7x=Wc2HlYLrv=&!7aD7(V$6+}-U2sV_i@zjMVvae7QmkYL;&=?51?XKZ(n6A?fd#Bt9`8R zIJLLeo`(HbK)8;izQR(ahlNDuuSMoR0jw`2>-`k;@7+m%uA@I+p+C3a52|?+izNHB zLY&(^3yd|VnVQm zWm}CE3oW&24ui>6VTijB%=e^$0XR6Q^cCNq z;*B{zcn_6nxR4KI{hLyvb)@Pgd_uB`yC6_0N~@7d(Io)Zmy-4Fg&leyrawQSKfjWwXKOWHcukd`2;l1g`lbTF z_}e#K?K{?WW%{beKvyIdEth!E7%Lf%(@t}v% z+-hiK{J0h(HRtn*gIM;NqU0AKTPe90!1_|M-WY`U4%443{Tag_nEgYpG?~2*lH6wh zR;MmP1ps|FTnC=%;PPp?qo_F4qFjv8)B-naLDB+cMwTLT=oX+W3-SrrE4XU7T{Me2 zJ%m#)QstfmKuLe!uK`eWcnSL?5bKEhVU{teNK=rL{i_~e(kZh;$K&7o4;aO#g#yUPL8Aj#_cJb(j(FR|Wx`u3>fBg2|+&th7o z5n+F;K$=_(4sC>hUjR=ja?@h~C?#$iQa+i94iLRI2d{v* zrSz1twSWqn#S~M7Vq5TeDezV)@F^;=xwJsh8bN{zTt|ioGtp!g*Cl57fMk&wrZu3E zOUZiw36u98go16FcfTo_ajR=0q+aXlA74_0GaFc`P2&5S#iiw%4tcqf&-3Fk(^ z)bt4epCjNZ06zfG@Hu9ol!3xgsD|o+NA*@rFz@}MP=*&pSPde7i5OenEk-=E6puU} z4;~Cc)@r(aPrkYPIZ^9|`32~Z#;I3GnXLehI~#6s834*AKBx9}?{4hZegl7oadrW% zi2fZp7;UDVZV6nRhX`82rd!3-686IY8mf_i(54p%$9pkpwvIGAlZj-g{sqY*yZ?ID9)D#i*g~0RFMr7AFNfuoiIJ6OVy^$%)+LbhWjETgqr;A=^ zL4?w49f0+vWW5_uW-ne{YV~fTKNsT<409PvBfGALB)462ZoBGR!ehAUl{xyzu0Q4j zvg@Zb`-I>oW7k*tw6<$_HL?=MIFodG30+eRr#?aYZve0tK;I?+G{k;F?K^s}!hY?w z_=9&*>Z>iMFVP0w8AK3!@Qh91CX=3z^U9<#01fk)sGLcgTbN)Px6Tg8S^G7Vb1B#x z+xe^-sC)R}<6H4UJdjbJhIcj$Fy1pzr}%^n)K7tFDPZb$!v@HDdN+gFz6BIiIg6X$xMyvuN=(nUNam?dWH278B9y{(x zgh>1remC~DL$Hj5-@-d%SDu9V9Dehs#a@F<`gNW)aQy+6MZZ`J)TLkNtp16R9>A}| zBB-BMtS`f_!y+hl%T&CnAHO+g#Qqz{^b3u|o||M@^b6%b-$@3Ra9_n-vBOXn{pL)MtwPtJUwa{T9TcWtS7+=%=t#dg$Hjh+lk^KW#Llk5ZK3#uI%B6p z8Tzf55kCbQ(67275IY5Sp-JQJn_f|DjrBoP5H9C)yicMhm0@?llm6goUeO2cwpAka32I3`VpKzh#N zkSSn2|7cjHUdsT}f};s>C?imyMjQsWv!=k8tix6DRVcoSgdO234`!J4dYb6?dq?%Bmi%mtvukYD=!IH6-Vt_1Q`u-0zIh~ z<|P)7FjQNg(ZU+RW05cn1e*PtMMu-oc`p4>==pAeHL7vvIg$`a9daZ_AA>-u!kURa zs# zmQ=+9CZ;D*4QnRWtLBfwHr6WVtoz*RTDG)tmNgR@gZZAT8Q_s?>$wru2??2cy|y}X zMmmkuOi`go+r^Ep605Z+exxVqZh>)l90C;m;}EC>VsHa|6L0=<&Y&t47;G!7$rzpk zf&ZCwF#h7MU>x9oZEYQ1xL?$aTJU^mpy z97&~%TV@WWi=f6AhQKKViF{UbjHLSOh7t)c$Js*rzmQy47|Y^yR&Eu>9k7mbYa2$# z<2`!j$4b?#i{}!Km`E2!SO!t#3i1At zq&^3M1IaM9z%>oEpuJXvx{J;dq{8qm=B}K(fC$q!0SX3dwjb7aw!85;E^b zpiYU*K+=sG$)tx+i(E3B(~=0`Cg{&(M%>4PBbj)?jYwpmUUG{Ym5Zl`#+5Rf9L?m$ z=~gI$$<0H};yxZoCB_|RN)gF)an#L#?{>NmM>7M(@g)ov(+M|4VkDj)XP!aK0Ney{ z>3B8|DPr(^Azt8vLJpmwKc3j2&*eu_iE+G%%G^Qi@EDCkgP-`agq8|J?lj9>)KVQr`KB;3_u1M~xoM$98m`sc%q;iSm zrZ_tp+|9Uh|41Q~)~3{qRHBGTP-HmM%GC;v7aacY~jAWGkCLm1YR8>J)yb5C$09O(6X7g&kWvo;m&0}(}F*!*w?XkPq0u+f3F{_ZJ(E~dp`JK zWxE|5D-=R!Rn$%Gxo^&{%F5tlTh~C)y;Y&}aq#%ob{yPSwMLyF_yNFG!MC;%(ay>> ztJMJ&y{j@rXa2fPAJq0NduLDZm5VA)2(-`7y}f7V@?A6Q>YjftI2_tJ9+3?}!#%;p zwZRGP!OfxD-Y)LIcBx%acXV(Sh?}9|2NiWkg`V6KOls!PNqhDL(=Ip>+S!$9e=pRy zV@FSMW>?RD%zNUzWovi*=DFal7ln4O;5wc@WoBIrA8cRKv+YtGopT9}9^8IO58#IsT@wj- z$XbKO3{Kb?>cPLYTh8hE{{70lpWYtY9jfa|&f67QaK??Zp8Ni+J)xWKm=gSL^}hCb z#dZHZt=K{PC#LlTzdqJJef7Mao=f*kLsPAxCV2O`o=g9}CwS9^p`EedmO}dnJ1XWK z@#@U4^@Q^CLi5h6>lu1Gboido9b;tK6uX%DFW^Kd2gm>;Mf^GGGst_t4I2fF**ydB+VYj7)iXgzwUa;%-z zMTp$B?blSv%Ftm?d=hMzDee9zsQTk&N~3=U(Sxgkm+}Dwg6;QP$pyb&wQo;w3DoRU zqGw%JaoQBB@OQTD44$|<*tXX+b+S0dn(sZJ-(>Q zeLYC^xK@?)Mo`t`8a~kVxP$5;y}l=OM5rgYn0xGb=&#EwPMksw&>z|@E%F>4@7%7t z_-eGr^4ke>H87-f`}?GFFZ?i6cOJYtG#et{yeM=VdBcBbCz{ifpVvbtAHca~a09r! zlC-NQGz+M`RiT}g2LvA(3!pytR~HmaE&fpT-XenRzA^HntE&rjIP;)7coa@moLPsH ze^$rWRqv||1;4m8GziK+SA}-(3I2AhHaJ`pJZf)n`2658YgB*xYSo%`+OH_UKCpE! zsDA=)APe52JmERz3Ad`o|Bd#9oB4n&SaHe`!OJcr8d+_CoQ0@9B$S7;I zBmc*)UBSC?;%DZ>^>Ao5Nbt(-?ZFSMP;Kz??dJnHU#t_Hx+a+33v>LaI&|9!p(Acx z(6iu?E$c#4LWlw8-vT~f;K4XF^Fl)9;0RNvq83FizklnL#03>qnDbB?nU9YYFn(sT zY6=q`TarxM5sc{8U|!`F7{OD8RD2}0H925~$844IP!eU?u2kBxi|JxMIWWhvDSt|5 zEc{Va;jxx23A$W~a>gZGX zjW$xKQ7heV#|KEACCNf}vap!aWv#VsQ#yW*U9fb%lDGTEP=$fy7Rz3QBo>LcjT8&> z3UEg#{nUJrj66_FSCbeUc}YGAqDAq1vP)&_nv#+UWMCVT1r(wcT$s-%F`LPx9WB$@ z5oBp7Dw~WKEL16;$Nw=hTX<|C0WkFHTs)gi4y=lg6j=>a4D*IuYKuKuMADTV8Kb(6 zF9FTkZyI?aVFG6@%ka|vBoDsSUs?sk3{DIC4a8Zxq(&B>ev&Wsfw zwc}~}S{!A2wp!vwMVgVTIyFquG|yD94F*i3NlX>V2zlgf$_P+_>uKA`^rln})8#}l zmqeqYfMSxWPtBHx4_WzCmfVgl*F6TYTUN(&Y0L?!E?kGLy7C}Y!<*3OO;Q8=Z|plPL`+*utS>%cs2CC$UyF!Nwf*L^FadZ%)yjm0GV4;^->Fif=@NX9X3QJ%U8lgEWL zqqLKw*}|Bu6KzXn`FaYXymGjZNza`_Zib0rCT9<%Hl+s0h7mQPZl$XzFd%dw8u3?l zYa59^a{E-8q^A>jw2Cuw<9^L>dd!y5ek+rM6lSy~2UCL?QQNi$M+;~Xn!nqKR`EP0 z;Q0;W7pkwoWbpyU4Cazao9&)91tyf?pf|O>Q|iKg^dl)%M+dzUVPm?<)Lq@uy!P@; z6!D-NF26XHgWj0*TA2H)nxX&U!qS+h2w|pz7v(Y=lId_tqMlYqI*BqM#WS>2E|nOj znRh&wq_|=?4<{2FRwmK;@-S8hd`Hxa>PdeDlk)rsoI{tV3^1ByZMrcEke{f2ZjB-` zB&8oT52r>3!suwpd|tDXH>zu7=<*babxU{C+?d)pmmG~#*hR>pZlF9nm)w*hy)4@4 zZVQ)Hok6>%Ce_g`mnmZ1Le(mgD<-?uJlO3$CP1nY3Jq*EcZcopO6aw;ZOKyQmr4jX zlD#UK>qkh}eQ7Y4*_upSn-P`~b=1Ti-c#606KvF`GdbFy%q>n1iUW~0@K4N75qIHN z;V~VE>^4LoDqO{tEDbL-17?ecX_A^AT8wp-BtkRlF0GhLqSxgMGLrBT1GTBLx=m#z zHrR>b4fY_eNwU0^#WXD;i4axcw&hD$NeYHqcX-^YRC2Sns_G{ARG@?hs#SPwRXnFh zH8OE$JRKiO4lGg=Zp~HLLd#?rrV|)$GQ224YUFZuYbJ+LiW(!1ws#sBLvB)3T}1H- zb(aW=kQ~nq>8bdD>Dla39SFk3tadDlfe0-$VCrF(jFLb^(!6S1%3EqIwK2qy`pYwE z9zTatBWigD;S{EV_kkBtMcSE$c-_{zPq97OqgCoKy8+69Gab*3=@2QwIjN(SX0>E_w5GYSvF7aBvubD6%*59W(#d&P z3QD3o<(GU zEm<5VVPVG$b+c*>5hU8ud7@GMfG$Zk)RPStQqR{3i5XidbkPYtDU`5v58kxg`yuhID7@RbHzRz!<-uKPz*_l zru!-5?a07`wG^!F7VI=C!lun5Mque2j;hu+2M1|PfpOC|b#=rYdlc@D0eQ2XM*hQc zkv&qN&g5FQs7}AUNC8U+Q%W5q$583YU@EN=c*Yo z92HR}$EJ9$7V$9nZc2_|0H92C03(KqKy+HI{d)#GzRWM=~oL@iIvy7-H4_FSfoT=j1En1fCP)At6q(0NUP-J52X6y;^^p@g(wPV zq^td8O}&n+$)P`dLv^dFT2%K+7c#?0(VStM9*u>3gxOKdLX=ZOr&jGMbO=ABNto(d zs1vPiYt_+x)$~DoI3{%%3P+Nom?21xgwb`>LJcH_LhT{sfT+wSbOag)_1r`nM21`A zVlblWMJ<>>v~uolQK9y5CTr6JpQH8wOwq4$W^G0*g`g<;2IptUa7I?%YYAesiNbPE~hCiFoF zSkl(fO=%cB50y8)6E?@_oaAVWYi%|zCFC*eE1$^6HzoDh1&KM;l_|&6O{`NL$vVPg zoJ?wO(DA}n>eB@z1@NdrKFl*gwQfL{N+8o-OxLWGzf&LOwo-W?LKMb}Ici1*O7u%K zlJppz1a?#El!h}#)6|~_T2sl90Sm1W=Oqm4-pg^u9ko?J%~S8PGPtyfY074@7F8Ql z(xLQFd{lK4H2~og%i*!bxb!3i+cagRSg%rqhI*C1@bC`nZ$X;G2?Z{-6>|xbq2XjY zIRuYKF`V*&65Tyae&EzhTiDi-Pmfy|I929M@e3Ur4J*qA3%fC7Xw{G>l2$$uHji~Ar5m(`btGX?>psfTG+BZb@!z85GOYPv9+c9d zEVsojsM)`;4HqG0a~i@iL#ElW3IG(;5!0P%hVn~2FyXSN>ghaAahTT*VGiMOPcMaRB0?{QU+#`K%QS9DMw10%d4Tn(sxB@N#ZAB z&=y>W)-b8AmQUc5G(;hH!7>rNLOL`>Y8p$C7YvM;2{Hv_btzOO*}BCeIsw#itU&1* zxJXqt8oE7v43S9(c6dHCrRizFCr!V3V<(q>J~0xs4X$rP$d;osv^1zmJPuP7tE zAy1+{q1#tqzt!oFlR9-L3$lc#$yDqaz+xe4MS;S`EQ5OSN@S*pO&liCCZlSd0SgLd z-9j0I&g7`V)WeX5VCJkV0Spbi-H35K>K3-zD2S4BCZ}`|Y)LHAVNrwnZ}(=kpxc$D zqt*IqzO7=N>PD!>aBIN(cq{u zmVL041kX~9u7z`!t>y%jn>tMhjUsMmp;e%qg(f8r(eEeY#xF!Tv#`>yV&8{rlD%JtDIVMIyfIn5c2xLEaeS^;a6hydt9 z%2$x2CiGYaM^vd>$K zg`?Lb762EDq>R|sTr z3j?!?1bWtl9_kolTvg!FI>^GoF~Y!2X~>tfPt?VjgyjJWbuW+4K zWNj&#M)0&jau_U)j_OI3Yi=vn-jR8P#>zEjvmpL&rlQ`P`$w{P3T_C5ex$coP_4W6fNn>+2*)eRBzE2yJ+UC z6;-nt1O_Y>tI~CtS8GHv8c^#|6#Qr1@{sXbWc$wR5a6ae=N9*^5&{se%fi)R&R9s5|4Z1dl0i z-p!=1Bsx82NwPq*Ej0i-b61Ody|yMvRbqJcF3=EFonk9-?)zzbsx%6Zs z($N(fT5+fPlcijX9PZc&3Ej!@11r^ECG1=)b)gq)pxj7i{9N9(vXks&W^za^u&$?c zL80iSxQ-2-Q3THgm20v-?nW4Qoeln6y1c?8k@)Rb!tkrXE*Su!5z?bElJOHoetypEwkj3 zSV+?g&CE>_bsxs8f)~_eutks9GC;nIE{EJNp)Xq?J`Z6a!{Ci2q8!#ekgI87s3PTh z9E`LY`f7sC_VrS!S{u_V5@ekk^=I6~!I|a`AOjr6dUY`eR~;#irZHT*3gl?RcFn0S zrp>QoH>E&uQgzYV)i<3hXoXEUpRja_q|KmbR(5ItlRsLS&#N^q#8Fz$qsBt-z!`Lm zJSMRSVmL+Z2fv~&in-uG1{apqQk-%zvM`nh$MtH-w4qeIAEA=w$K$S)!+C~Pau^Lq z+B#{lBg-O+^=INax*m|s<%*aas)+(pr6PL|9joz^)*!VJ^eQ;8bjyPiib*Yfh-RUl zgUOn@Qld1UHGcY|Gg|actn!Ro9iZOiyTGeQYw8pBVq}M_kxwV7%TO(qSzPUbP&w+% zA~0FRbPKZ;SeR~WFkQT(Yc=%}S_xx&EJQw(>WA^Pui>QJVbDgGJh0ME(K|afm+9RX z!=RWf@aXY1?~JW>W@LcIX9{rI@?97uX=O_n_NxyrcSg+;LoR1a>5fXDlNYpW9Q!`H>T6s-H3vfCioP%a9 zPv|KgTYeVGS$m?jSTXIOy$+(OJj)w$14uPvvl(wMbrK#s>7o|If zRY%3tf{WI-ub47jH=IP&60F>Ww*42WU#@7?xF{l=@blukCe(}Y)nSyd3 zT?`DVIu@;BZQ_gBP**Mg+H)K1g^Sv3`%gu3M;UTm$MF5>-O3MBrwA$b*yURDrra201jIJO1;E7}(5+ zXSWTdas9xRu&Soi>tWQR&=^Q`F~emu7YkU-lT5u1tL&+G9c~v(*I~?GMT1(x z3k@o)&pCfT&EPe>4_HwFf550p3-1ozKF)j8QNXJifLViz3h0*Q zRbnGE>@bYsD;WH=gVKsRf6wAm=Npo!fTEng>cTkRFh&GiWKdB7-Lkx@H#5Up!x$E@ zk5NIytUWd##2q@PCK_sI#4_HaDFhT3_OH)+W=I&uuz*(@R5wFrCtP@PQEfph^bb!L z5TY~_1+0jG4qyJjf6F()3cf#9!$SOb$Cx6b0*Xcat1V*KqIm8yBH&UZt6M;~EN?TO z#tikmueSF6YO@sJ+TV>Q`f2+<@6kpA-o#q_D=Ul-8^(x$`wS{7pj(z#*)zDLdAvtR z74Q;+TBQ|r{t8z!lLW0@ugS|d4V4gyJP=)ckvYqN579>+NkJ~=Xj5G17alh$C91Gy zm8A)>ph|1kWf$#{BM~34)|9IGO}s>cwr}$uZ6)A0@#YQM{M$+x?=g%K0pBvHsDN%+ z-nLrKCB=A;wi0lQL3!FrxCWWTx2=Ro99?0Y5S*Pg@Ds zn@oacxXxo?Arg5Yy5)aE^mPx>_qmt{d0%a9wD4U5Pq!(hLv+-3bpCotq9XMnmW~Fz z`XY~Pary6XGo!Txd>pSZpsh^LVut$+V?@CB3@R$1Tb8%A)^JH1c#obX;0}XYe!)ymg5!@e+Q8=gbMchw#SpDd7olM;6(yHgBJ?X=I=$q z_$$L05%3shge(Ewvbm3hP`?R1lgN)A&RjFG*CWMKV;n(i?Gp zjF&^v_9XAoz5>cKG&u}Bx~{FT(B zk<%GiM!^5vZ-yg`O@=Wd;A(@43h0*Q)pL{?wi?Fpg$!Qipai_qpdwB^G$h5`W=Ns} z9)*`o(B^M-VZ75YMg;tcK}7|0%ktLdMP_)@Fox-syR?1apalGvL3wH;#niCsXd3}% z?zc8x#)u!IS9KBF>69qo3;Qim7@G`ZL_jyAw?sMnl3|Prn8I6xX!CC|VSLRnMg%;L z8DTF0-Lkw&$l0vJDBxrJRYDjy8^(x$^d3mspoD;KSzaaN?9UuV0Z+#Jl4$d{gfKp9 z7$XAy#h{`Bx@CElkh3$mL})MIANH$+FwQcJ5dk+ER8&B>EUyw@VTPLwV_3i^7*%2I z>d-cE{$9oBu5;J~6gHosp%Jf}p{daT9_6v;S$i{@+AI}GM;Oa z!l-~^K7Zp1<3ht25%6k*iVEnKni3<2M-g8EqzwLzauZA%qU>!5U$pv)F^4c!S z4C@VJSin0B%Hu5k+}(yvw~Gq60I%dMueva14P!*WJq8sO&@IcW`d(&u%rJ%p{IfxM zRHv_m()KGu5*Bbes~)gCZ6yN#=5PtAqDxh1ISBVIhl;l0;(8CO79F*3^`MZIO+01*aRNT9Lj~so& zDBzr$g0)EG!x&^$;prQiG^-6!={sJ?6iT4%OY|nC_&`7y(V*!QDXSk4*X0Zti zQ2~1ms$0OgK}7|WDC)0x3p1=Rj2_d;tqRvWi$DV2X;9q)-eXWv0cByyUxP0*!_9`# zqk-J&F_|yIz;XgkGpH2;$`vsG;zSmGjDR*QEea?C0@g|a-LkyiDrwv~Cclab*tp+p zQ5fqDV?;m^5U^GV=$7SG;$*g4y|G_ZK)J8O-x9(&%P>X+6ai2|K({Qf5)y}Jn)nhG zu-%|~1YBlf6WyL9M-n>&R*!BP=dXxwHnJiDicGB03n&7q+7Tb|p5-nP-(_a^Nmtg--!19L+T(1)Sv+@b5_cR-wIOJXM*;C5ZlLK>eta?76NjZzLJxlvP+0vtj4+A`{(r0? zL;p=?B##RCltFb1_!~xPz2xYR4xxb3r~ND7Ei@v9)|eo$NYkARR7*PSQzz2M2 z^Or4*e>98{0S{nCjAjD5WqD0Lof*zFj9~#s4a#GKdOp>{dw)IssJt31VHs0UmvlVukzr3~@H7Wi zqPZm`XE2Gso_1{D?1Ez7IK)y%NlFothr@D>ME zY6ccSyg|UuBlhPF!uWp-V?@Ar3@R$1Tb5Ue1GuDPcn@#* z7=v>hRH+#b;#0@+-ro#USUvC0o}5^O5DW^j~d4C z6AV7%pi0dkB)?=5e>3<|c{LFI-Z8~R1x!udpEn5OKMi9ACJEnXgQH zXs5EA8T*k}N&|WF5owRS29`6A_x{!Qqw?0ZlnRe$oVvBNIdR;}Wo_X-Zh))tC{{{@ zO4N+iC~5zeHfT-w$U`JgYkZTRP(YX!umRuMq|Lwb!uVao7!mLpgNh31mgP0khsbU*Z*N@6u6RGDsqjprlpYK<^ zFfKNX5dk+CR8&B>EUyw@Vuo)R#_;V7e$PRbnxVj_F6X_UIfdpjL$hm5sT?Wl9;Wek zA3rK@O{AW`W?Aq~0k1wz7wj)y7=LFNBLW`4jF2UuTb5Ue7G`KOj9~#c8kA>ro6M(X z@ZQgyLUV$l*%dA|=ec}tKJU>t1awOGjFQ*$lKCCH|1R(E;k`UQ@em)EmilAH|AhDQ z49IJI{08sk!I4t_HooH6$$PmRy_%2ZTJ%;vzL58y;C-n)`i?JcvQj;lk7bospLPCj z;PW}&%SE*-`1mut{|4{B%ljYj{)fDOl=qHg4V}z47ti3m+~Pc+j~DV@Zk#UVZ{;UO zmhoO5b&B)x0Pp1?s#5-CQ#2;bdwG6igpV`4m*+xC`Q>K%xjgfp$NMJUxA0zWt1spM zcYMp3Kg@f%d0y_6FO|1}>9V|+M++|F<12VC4=t4POR^w&%e$PBNb*oh|4ANXckx~> z_{r71Qu-5l{5XyG@)+TKK3>Rsc|ft0UwZn9+>1})y+nsn`v1jo5HrKaxf{C4gI0z0 zH(z|v3iEx$5D(ax*_UEKiRr&wIBXa>)z2C&xxRQnDvk^ zev0+DFaB`rmW-bqERAIS@Kdd(oFD#3>tfCY-AV;5?h9@t;Go66@4>S#d+tC;ItJKZy--IO98JY5{qca|+`h zEWtN2eon0>6n#1vzl8C(vz$K0zs>m1GCs@r9d#Pf$N24xf2jn272_Ao(u5B({k4q$ zknwLY{#M4nK3gNigYRd2)tvG8pE7=W3I6wtpU3zaET7UNvgaV<7vh+}vvj%iC3e~#Vf@+#ef+xKSnYFZEr*_zM{S zJEmXB_?||MxPkG*jDLsmcQF1U#((WxjkurjpJBXxo<>~E_^&Yj_l$p)@!w|rkI!d> z*je!NH2!0Z|0UyJ=8A?G|3}9EX@RDfc6^`lLrofgquyB);9z9u&_a#a#&~+7hVVN| z@N*geA>*H5`h|>tY>`IX#rO`!U(l=(S1`VZ@w*pm1a~tl!}u!3e~IaLF#Z|F|Aq0_ zGX4iG8u2;Cf0glJ8VIm`S?{cGG5!t4OMBf9e88G&#dusEX8K1N|03g?s`ZHgc7Edm zJPlX&md^7OU$6aEqb&CEVOTOsb&L@Y;$hn{lei!gHZov%a&;Wk=yk4eW zw?mGfp68X3^Kcn`epN=!t7YhqFJsTQ%FtKBzx?WTcp3b3;3xaE`|>jNij~2irsR9` z?bA$Fq{2oPrq&0c#cq{dlk&{t!4zdP#z+cGq{YM!+X?e*{&#SoH z(ztpb@)ke(>&nQvtqlJCGIAbN^vDmFXvMz=KcMaB!28+l)iU_^%iwP+<5v?gq42BM zab@r)0q>{JebCiU&WtklpHoJDTN(MQfT#Flu|MEYZLu=+ua~j&S!L{Sa~b*~cU>h?M$V&U^t2K=e6|E{D6UQ574-U*%y{)_ zfj&Wkj{)Jm#Q11{Jv5T($EP;%6}%iil3d(^mu=Dq#qeVG+Or!P&+#Y1+a1#>JFdS? zo2C~%57Ng1Y<_2^{;aV+Qg7`XN2*@o2%Yq+9PyS;ep4pDAyuRGt0M8XQ2LT7y&hMi z)k~rE2R!79E*eEIj+Bpj;Vqixb10fkyG(#o4Z)fdag5$O-!G0OFY zV+SLzkJgyHd})UX^y{?sf%?#!2Jx0w`52PR5auJTnuu&epHvxfk(iG_xW59T$?5&5 zmYlDhUEkQ)NbkT+j?~URYu2n;crmtqm#sRS?fYT2{d^FGl)+m#=^fYl{r1u%c(*i8 z(P{O*n=nwE65Eo!#s)Xu3r3$K^$REm^-VU_ACAFIPFfa$y0;~C9+b9Ho5@8iXr*dv{I zcd$faC`NHOqCUlgn6=6CsX_X(tn@0iwaD5iHy>o;Q4o8%o*Z8M6#B&= z=gi#Ndi5S)c4zfoV%r`X#m7gW9=^_LqfP8_?~djclFzPF4dwO21oPL?3HYX~1(FW^QDZWx1V}-@8pZaX`?YRUibtxZ3e2`t%NAT?3PRrB9Ei{M~8z z0)JV~;a%dWqkP=g!=1N{!`Bj9;^cPf!?@$CZPn(-M$uoeFObUE4-1sW_m*q%CFWZ7 zp6i+T0E0SGU(Tr=7)yiGQhR*aK%Ljh1C6;wSua-Bb27uc3{~#T3&L z{-X$qtqDJpE&OtQRQ7L{C`>Zk+fp2SnY z<~pxj@5Rh(+*V>vi>@=d`OWpzhLRhB! zTTA%m`nT){#8Av%a%kNN{3QIuzvMdky`!3;lwOWyPuK6rMTK9kr$6++2mjdr%qvC2woKcC4Sfw^IIN%JA>{ zKyy_e?B@3BO4r9pW@$aIt=1(Cml#lE9XYd^e|#wzQ|dJ3UcO!^=Y?O6&o9G&-^VrO zL*f|BP|8ooB`&HcFHUPpdHwfvU^n6?ek<{x!c$2RivRtKHUHhhps-H8`4DS!{`_}b Oq50eOPRKpJ@_zw2WiU+u diff --git a/Program/libcsp/build/src/arch/csp_system.c.2.o b/Program/libcsp/build/src/arch/csp_system.c.2.o deleted file mode 100755 index 1e22942df185965ae2a82885513d7dccb0cbe182..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8832 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 diff --git a/Program/libcsp/build/src/arch/csp_time.c.2.o b/Program/libcsp/build/src/arch/csp_time.c.2.o deleted file mode 100755 index 0231b9869dd1b8ab37456c5debb0302b9d756771..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3976 zcmbtXJ!~9R5Po~>#Alowb`p|Y9HB-0B_y|J6XX2h#IdoRAd^HSK|mzddwc7<6L-7T z{v;O)K%|NgB1lM3q(U?lNFXZeG&E2kfe;b}9Y{1OsDcz`-kVwPJ=PT?`OVBXKX2yk z`#Ha}xUy6-48dfGQ({A7REV<=ZOC&{oD+|TUE=J`zsi50esfl$>DF6YP&g#V*YExY z@{qKYW!i00&J9*hE*WLiN~K}Rh7>C+W^7e9nb;iK(g_lkxpeR(29>3uq}=3`=Ds(; zAYo(Abr45POo1eG8C3+CEE0@6KY=9YG$z~umDfIM zw@M`_FAd^OEAX2ZZV(JV@~o4{d0Kwr#KLhhup0&~YtVlki*aHnTw9C%1Z(CN>)HIC z$YQ*<8woiqpTA-)96xRywV$&mty(Wh1An&V2Y%G?K*dFxg>|XTOk1^44Sd1_xxtZt^3#9 zpnl%J{z}+Qdw#tYg=x@qV78IfuEw0cDl`MiBehvA(j^wPFM%7G}0hRRb#ay zsnn+4o;qevP9Ib#e1cu@hh)6BSa@@@E{i0_vcAuQxCRK~7W2DcuWC4&$+ z)%PCcF_z83n+ZO@+7IlOag%PI3;+S|A0vmWyGePN>aNJUOW9PnK>=Rehnbzj!4Ol7 z4g#c^V*4ie!<*n^o8WNcXoPFOBe!lA*=xXyvMg+Z=MO4x5I!V$Fz{?KE}Z3+3-f1I zoC`}!mliKOm(R?vEIQf#im?QFD+9;%ABVqx9w_1!!n2LG`-JoUVx0Z=fe(_7%L^WG ze759Wj!r=Q{veKX@db}HATj=uQsIqL#P~37P@t+}a%Ho72(W{Mqd)#JO_IQQnxr4q z@SjOPrQxKCMGZeh`ih4CN%|!X|C@A2!!6Rg8vZ@$@}q&w^+$yFHGkg8H#J=SIuP<9 zL6bV?W6B-)jDRVcgB(`P2EGmWN+TUT>avH~IaV%Y*xb@%+AG z8D04->2=jy>i35_Wu}m$(h!Nu+q2rO5BPcH;NpS!%k8E9^!Luc}0wej{x; zonS2lo0Q!~Bl54Y)(yP@Pd9RdmOmH`&$Z9~Fr~1)u-Eh9?Xd%Rm27z6;8lWGiW2#4 zXDxDjJ~i?`nFaBAn}ireo;-1A&j{Vo}t6R|_!oyGM?EeR7sc3)|qo0>tBF?7?sPgI7{(*U)(=Cehvb<&M`o| zU$A~-VB>gR*P^*GMW5#XiVB8*n*{!<(&KR&{pHXvHhobn~RR1?J JYGcsj{{`YQbXWiY diff --git a/Program/libcsp/build/src/arch/csp_time.c.3.o b/Program/libcsp/build/src/arch/csp_time.c.3.o deleted file mode 100755 index 0c62324a34ff227101b0942b3beb2f1da33b600e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3984 zcmbtWOKjX!6n!42&4jc=(iGZh5HjUk=-3Gj>5sJeG%b~eHli&8D&crM&Wy#39r@Fy zEFhw*3L!us(M6?7hz$!Q5G&T*uwsD(3nV1iv0&46k;=W#_qv{kv*Jo~Kj(hleb4VR z?=Lq`S2Rs9Y2t)Bw6Lkf#aA|m5xdlCWqAby$uct zYkRJOI-+9EcZP)PF z9%$t$F*x1MJ|}4zlK+=|15ibL z3|!Oh)pi1xy9GX`W|~$Uxt0^TU16nhWch*HOWU5cab(t>ooV#^Al+zmg4AmHNh~0o z1KfB$OB0~kiQo537q?wLf813J_9YRxx4?RF{^ zXfF+7zY}7T0LoeEi=!HSY7zj((u?IW0!?m^8OR!a*nUxRgiaf{d zI+2iUuqX~0cf%+dEKd!|gfr(Z8B0fx8i&o7%qgSMPtw4f>v(||`7W5am~*gxjoBHa z(J>n5W1|5}F$b#%NsYCYvrE9^#BtwgtVdzuxk(s7Li63Dit&;Nab{`hnDN}DRvIK})^_7i zDy`}FrjM9YGY2wM?w#F|!{&JRHKA>cX_GsKtDnG^Mf@@H87NQH#xBU0C;04R75X$3sHqp}D+yEBU6QrELvp#(3Vhn}Cu!4zGL z4gzH9V&@k4!&~5ETi|f>D1>XjtFUec`5Pe1sw{1R7Y{6N5k571*ccb~ndbS$g{FP} z^yv%B7wwA+i_K*_-(fMfAa7@oxc=kt`{#Z}yh3=!(RYt<-d~J!{62_5QgM0F1CGy^ zywfoVh~FW^aje@20$~qGjGxL(cFOaA0Q^7wY`+|bsBimMRcwr><6#OdL@}q&y{riM(DDeT=*A;w*Yln&s zN$v9%)lqSSaGXl$*ItX9 zzDE=JpTdBAT%+QeV##@AK!)TG7{(T95)8aA=8GWcn^bU>@LeD=m-hzz36t~;aKz<5 zj0}=|wV)SOb^L?i#F|^>V{b)L?OAZDH8Fk_8PK1Z$hjIj4W6?3|3UMAgEkq?AMaju z{)>RAH31R}1b&1@fz;R)@TnMv|3u)EgdkguWbA-jnDfG$H#j{9e)!rtjT?XD(Pn$e?=LPO_m=* zbXop>+Gx*HJrsmH8me{26zomvJ0K%6rG<}(I}8QfBgSYmVcA_|Gtoms+#{V DXBKp! diff --git a/Program/libcsp/build/src/arch/posix/csp_clock.c.2.o b/Program/libcsp/build/src/arch/posix/csp_clock.c.2.o deleted file mode 100755 index 73b302fdeafb2058d9a5ba4ef385d38b77953ed5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5696 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 U{m1uPn*Rtr%|A={BCGrV1L69Y-2eap diff --git a/Program/libcsp/build/src/arch/posix/csp_malloc.c.3.o b/Program/libcsp/build/src/arch/posix/csp_malloc.c.3.o deleted file mode 100755 index 651fe5b3fd780c711a71bee02e3beb17d6fd8bc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4872 zcmbtYO>7%Q6rSC68V9Fo+E9oIm0XDyituiuhV%#8rVeQmDQZgVR7gFz>-EMlwb#*l z-I}U`s^w6A1VsXIsRT$IKnPI*7Y^JD2TmM%r1IX(yxsA1BO!QEcHaBm z@4TIvo#d6drQ@byFd~B;VTnX2W4AXa{0wJj*mm|H`vv*r@h13YxH`+D40B$2Y*BdA z$f9JLgM7${Au9%Blh6&|U}XjxLBz}~moiyXXoc=h2`r?_6yDs|*om%4+zv+L=6CQM zT#rI#?DSCs#A`t2JXAbntXRJrD~vsWh_Qo=P)efg0?V8*2yg(>#5m~1BexcK{<)%E@3W#L_a# zFnC)ZNPRren;Mb`I1)=S|E*&=&9Qu6MoKN#KCB$JLM#=Np7AO0G`V;DmbpX|q`)+O z2#m?D!qYJR8rcj_zIkC`7`E+nLeFtSZ_Qb6cN#tBbUUHb2)t&u<_n?Os5*7eb9x7+ zE7McOW+UkKiuIuD?2ql3*IBQ$+-9@w*&dz+ou~$G_8Qg+e9d14-ok>0MCHI)4ZDQL82Q9x<<&|*1Sm&*|A>)rE z{#rYXc&wyw?&*owM= zf4J@ke%SCp#Ks?n#ulfi3dMS%xZEiepeK@bRIsH=$f59K|@tr*)cN5bEdGWHpX@F|&hPQWq#h?JK!{39u!*6={eu7>+k zeo@2ENx7}z^dY{i;ZkJRG#tNkNY}*>*S{!bnm6?m=Z*A*7`VNByp+}^+>xFd&GJig>zQ3 zmoS^x>?!Z_3XXX{lMZLJI5gj;Vvl)geXnnT_cZ)V8UOMI_^TRzOv=|cz-ez{EmR|> zpfe2J)cy4~DuHyoz)@kV+D~aXgdN0iGywr-^DvVJm#x>$Xzv z0;k>ZM4aC%1;n4r3a_$yemq|==705{246iU=A-<0H&RIx*(4~_=6^>{ z^b=Va&L7vHKK~M6dQ5=WPZInV1%-6mlc3WvG`}e~!_SH@vbycL6b$XI$hztKg&30V ze-^N``Cl34=JEXz=a1h-ef|+(dQ9}ZCG&rbfk`!n>7C)QP(h&QHXEXUzU(<4<%Sm~l+?55x{|ERjSNF#?q3>PvUyz2gC@7@Q TAMbBz{-g40{*~g3tnU90(&3v@ diff --git a/Program/libcsp/build/src/arch/posix/csp_queue.c.2.o b/Program/libcsp/build/src/arch/posix/csp_queue.c.2.o deleted file mode 100755 index 90a3ff2a89a7c6836c82c83e5a828b7df72b22ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9368 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 diff --git a/Program/libcsp/build/src/arch/posix/csp_queue.c.3.o b/Program/libcsp/build/src/arch/posix/csp_queue.c.3.o deleted file mode 100755 index 49d463822288a529b3bd2a7201e26990ac8be616..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8784 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 diff --git a/Program/libcsp/build/src/arch/posix/csp_semaphore.c.3.o b/Program/libcsp/build/src/arch/posix/csp_semaphore.c.3.o deleted file mode 100755 index 232b5ab07b7d3b7292ef3ffabea204a17a5726d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17648 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 Pr}X0Km&%NLH1+=nz?bA` diff --git a/Program/libcsp/build/src/arch/posix/csp_system.c.2.o b/Program/libcsp/build/src/arch/posix/csp_system.c.2.o deleted file mode 100755 index d308b33849a4012269105148faa3c57e05437004..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16888 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 diff --git a/Program/libcsp/build/src/arch/posix/csp_system.c.3.o b/Program/libcsp/build/src/arch/posix/csp_system.c.3.o deleted file mode 100755 index e9273c87bca27633751891f241a147ae82d0bf40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16864 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 diff --git a/Program/libcsp/build/src/arch/posix/csp_thread.c.3.o b/Program/libcsp/build/src/arch/posix/csp_thread.c.3.o deleted file mode 100755 index f92e685484e5953e01ba202171870df856c5fba0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9256 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 Yuc4=?dgEIA54=NpuK)l5 diff --git a/Program/libcsp/build/src/arch/posix/pthread_queue.c.2.o b/Program/libcsp/build/src/arch/posix/pthread_queue.c.2.o deleted file mode 100755 index 937ff875229ff49d0626f42accc81ff4ec6f1f8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19096 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 diff --git a/Program/libcsp/build/src/arch/posix/pthread_queue.c.3.o b/Program/libcsp/build/src/arch/posix/pthread_queue.c.3.o deleted file mode 100755 index d48170879e559fd7c00def37f5efb2a943df8071..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19104 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 diff --git a/Program/libcsp/build/src/bindings/python/pycsp.c.4.o b/Program/libcsp/build/src/bindings/python/pycsp.c.4.o deleted file mode 100755 index 0b4dc41dab0e324f944d357e33ceccb2c2a2d333..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157552 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�WP^>7P{?ZUz$u3ImeJal7#7vGc5$xpcPT^r9skt#G99iEM4hP$D?1B|^fO0m5x_WM`IU3wZ0c^s)4_hzN(cZQ-6tNlBZLeR4Z$ZA(NPbMPbgHr43qKUd+z-cdqDYX(<(3-H=QQO6~SYTRop;gOr5GFp-4*&hpj4Rj?8V z|4=c~ox0?26MI}(*iySO3Twbq8pcp6X=~eL@od0N1Btn;f+So51g56ktJkku)G}y zQn<1hmRrHn@*tgxPzgf;2X8o694MN@)Ka(}|MI9j z2EgGBwXs^Lq`|rfBM0mV^QurI&1LN5a5PkJH8wZ4scr>>jjg1VQaFftu{MhHe{_?| zAu;OUQsg(!7c|`lWn3_>_`O50UN|B2gUNYymU^NSFg9VK`9Y8C$Aina>OFsm_6 zikc%Z9%pV$yse^-7{K@o%$-S1C}HaJ!bsbuP}twB=27;98d<`vG(#eik>>g)I{4Q{ zFhG${i<(09n^uJ|aA~?ILvAVaD)^m40Ph5%El3`2PdK2pU0Smm>kZ|Rm?*4PUXo-O znwnc0{1}v2KUkEqRs1n&ItM}l$A2{)%_;JcP-`tsSp9Th4sR^NJDw0`d;~~^G!nuPjmFeMC0}Il>8ETu&BzI4SBX)(>B+!3VTInAN1>|!xyBHO4&Ec(<% zf9E;15neRO-^**m*djD66o-G7ifyA;cC;(ND%K`n&mUWG z7CFJuq`+fw4=Jk`(!2&YsF@dgi`vLWp{uz;FAy@-$}od>v~$9dB1}ZIB=dq!{;9`I z#Ey{-EelbhU#t*n zycS}XXhQxp*Rw996fH_{H0`fsut3oJuZ5HxVt2S?MMd_aIdihl%$=D#Eqh99tRozn zhj&~dOcWq#4V;Hp(o<&5$eyw>drEmUdkWs6&ch3I2u*49moCCxB-<3kIVR>Va9}gA z5vxTz=n!H=sm6N0Tm%AB+UL~2Y-4isUUo9UwjvX8n|)Y017`F}`z z4=5{&C+z#OWP}Awpr|Z4hb4n3IZBeC2+ER{AWPaMiUCjrR1`6RiUNXQ4xnN}%GULr-bPwy`6sQpv>l_g6AV`g1p~csb*p6{oETT} zQT##&-f>XZtgijLbP1YC(M)Y1n`l#8%XCB((9v54tMDZhFx8Y*kN zaFLAaU4fV%8*57Q;I0DX%2zt_oa~8mm1M&_86ZqdN%pL!L8(UhEyu;z2k*i zJcD7hf`NvO9rBB;#5&Z?F5*yET(pFXkgRc&r)25RJWtFTEfLefe`;j7N{GQpjhDt) zIv=g_sIVA!%4Lk8&{*PhO~F-=Fd2Bp0LXzmP0pQsSP>MK748^hO_MuHdUctnr%BFQ zh?!go%GGOj=}JJc?DVy+N`ck$ zu48Vr(cya4244MUV{jddm|Z=`rYy^%8qbJ&pPMZ;aGG_0T7ht(9VT(~W|lT7o%OC_ zsBB@McmWfJ#?p{Vf7c{j*@{xy2RYwXT?d45@&FxBPLe`DXp%NCqq~mJ&KVspt1zFW zvWK)h{j?NW zK0_gpN)fKUFb0opb?lJy5M7)-DGxSz(_w%NSfkG}tVRi!ce#2UuldpDU;ZXqzWM@A z%!?$Pf^bsRiK!tN;W{X^UcI~Y4vm*gLipgA5uB!QM%}cAehw|@L~XeB#=neLv=h$1 za+g@(qE4<+W#&)1b&0fgHW$bk7p}|rVipD$hmEb`wV1Y!xa7{0A(UKj>tW-(nT(g? z6e3Dr$I#-7y;0hocbYimuqI@p%sPds7HNqmWzSSaL0284q^2b+lk!G{DxWn|r*Gtv zJhqnOrE!%DGug3V{4^j(>V&J)QjW82c0n(;^e${DJ)OE*6Drr#(gfjDyQ78vqDfY! zjNIh{G&f716VS#hc6p&M4Bf7_JR|Z(jUS&ibDXr9;kK@ncWHY?sx?F}039mRj4h;u7S#(3OH04j3z@1Qhqy?QKvlS^Z9w!CeDb$O=(c{O;5D^`L z#7y*`9hxC4&EmPW~b?~AG#uc7i)X2y(H!pN{sra}| zv}%RQ0^da*P>Am}i(%qR3b6LKp-9SrPGo!lQi;W5U>qXH zHguW}U}e;=z9YiY8cL~@Rxx%tQdh)X9mVUsVr(IG`YIHnFmDyE@FwODD~F7q5*=5) zmUOwR9tuEgw)Cny%!x~Lm49I+HCyYJOpnU!jLuW%2J>w%EsiR*Cp~;{6dgiqA)`GFqSmb#rFhRjwq*q)$pP8ZY>pPe)V3{-(?dfPCI}=q z{bfWiZ6DfaIb9Pmfl@F43?b4jxna^lDya;&WQHSVNzRK79R^4nigClV3-mzRP-+zu zxek%#HCtw0Wr|yyfB`eZe16|4`swWW1V~nBOG8a8IR6EMyin8o_UJRPOaH9y9R_4| z?9!!A7`1lBQNpaPoa>P9=v$T)1GzMjxjLEuld~C$LU1e|0aqpAf=UPN1!q;<8tBWB z&fn#x(sx;z#g4C^pf6YO8%6u zJQ$|4IMefoz8Za*JD4B`_4C9bIvPL>C&P^movqgkgPAg}nLJY)bX<7m=)gaA8__vj z<%E%D?0V1A8x3gxq9%|SKACh0bw!TXPudZgq3R^l0D2pw-~`1|EOjmvBN?%e3f*Wb z_Rpb5mEszPpyMY^ojzXXW%bglX%nfbq1}@G5J)YdaV(^{M`t1-&kAu4mp$TzT_vZa zMF}-Cy4^#^iqY-Sa_dH>l(g%aT5v{Ve&rq-a;xVqT+PJ&3(99~m8Auf>uVVU$k?1G z31jYYi%XkU%=7D@NrqFSe19Xc(`o)Z^l70tz|bhl^0eL8hoE%eghnS6u)`W@$*fjP z1YVD+_jp47r`eo|G=q~T$(4lI)23ELdRZ24O5o0uO>@c+BD6X2T2NR=(pg->EvKUS#s&&EKuAXsiFhg4tyTI|2 z#!S|-gqw0QeXRr4f+ns{7zXtofd*U0!m%CIAyz0$GQdO-!UjD?X!CX85YM{Y;KMTRRd8?4Dh`^0!%>n0>D${0w;D2spE zSm@>aG$|_R*up8&URKJGTx(^8LG8le1~7Xjd>^lw2u{Z9*EnJ3hKPDWn12-(Z)aw8)*)kP`L*?s@mY96RPF`I97UeL zM2I)X^V^<++So07S|4c~LhoKMwU9!C6I*IEjYcUIMzB)IWMVAFLx;Mtnue>{&_Tot zzm&H6;aWiIwcJVwxzoX6!QcSZSDp#5hXHi@L<&v*{eX$FX^}Yis~qu2N>He9VSF?u zNAA%huu=u|RxgHw`L|B9q#@S(ih65EgQf9y^IE>K7YhTj-Jrsqm2g{BI&zI!xClZJ z!h;Vo-;PtCKWgaHw|{SqZT>a2jJ0HfIE)9x327DN`3}j795O3jm4^xd|H3F2Efr5xnm*Y7@07)N2$djzM2nLVA@{E z+>}NzwE5Cf$S7Ib^n#99yv>czbLgc@W(#zFvA+8|rExYQmVwv=9$r_lBPM}#8*HfE z*pA3`9HwJ!P$9K&R=ARqYA%!aqvG8-=|ILxKP{senKaCmX)PJrqJ55S9a_ccOuRD| zubbkGe3(j&Q%a$e|8GxUFzYZ{2F&C1u_1kiAWNE1DgHUrCr*+8RN{Cp zV!z@aD01h&;AZi(8B!}prQ+x@Mk8L*W{n?>z9%nCdrG^mv%q@hq-II3Wo{u)rVyk( zl}&mwrSNIpmy7VxljRwUFl8Icp$1wel@Dt!?D|BU8ZlB@ZJnJs?8y-+N#nw}c~HNB zJ$iSMy|qD>26W`)5xIJUDmyoKx;`eQV+Uy?rlTkwRzveUeVxXR5s5covYIaG@`tD<;39fr4r)MMtj)wIUo=_dADk8nYe-Wbv4j?173n zlc%*o2CsSvVnb-r*$_eortw-&nk9JzEnA0OQc=S*II$ETc56HyKRyl?4=lFab6W$$ z#JoN67dz0<;RXK+s)hJ8V7g3T#H?zW7%@t(+lA-P0mf}ogvNvk$$01?@*R)P@?4UR z>Y@V@=TJp;HgX1@0FjJ@+XY!oTV!?U*dt2@d5oIqjEm0ef~XV7R~QN@Ld#D^ed|1i~AP|oFPEZmWmz{IO^jZFV89sBkj7#mi-16%M2tF%91 z;1UL1(Vc$TxfA6^ZT>mb0&rMsdDu0n3^&49^FOm+(U|pwdg~PJj`kLD5F!(cuISkv zws3EEbhtmNfv|gK@@*a&(@Kep!yIkaqzje;;JYQvkjifP{c%>0v6JL>mK(x{;t=OR zwf4#hl}iDcf554lK20Wf?Se)#FXh7K(^HM)rq1{gjpPZ?NsVNja+dbR*^S1^AXM&d zXo;1uHHs~1Bc1e@Mdc#Nhv|YlA~INze_`B$%B59VXS55(x3Lmx z_asG3;wb;eCM?yhQ>Qi=wFixq3xVnJp_>Lxr-x6O7iYF=*tl7pNcAgIn(!sxRG|y{ zrwYv~SEy3y;w6^KS2e54Hhf_=)l-EX(#u_*)*-#(rG?K(&zO~7u~T}v4(TOQ`la8_ zx?NI-@LzhlOVciqEz!nsWs;iee+4!=r)QjnawMuTm%} ztZ^m0ANb~o|HIz|ud1)2KTq_n8*ODw;z_?szZ9? zbJ9zwMq{t(8vRc+aLiy;T>{cZ$c|1kJFh$w-rZ)t^_7!1WyN1%F2MlCw+G z`lPo{yFX-6&s`CGz3rR)?PsRHS!h)H&O%+&cNZEcuU+KxAbIU6pSz~-E7Upt$3mlp zrFHjl>IFNY+(_&P;9QMP;1?c&>+*WngV#}iB3cLjK=nQx;^-wonN-*Vq5sp zKP_9c(o3`#*>doskYCijKI#3&qz~?zKD=xCxUT6_2Br6#kv_P8`tWnp2X~MVbj>fh z8na!n@wL3y7+j_G_i~NFrA5w=67Y7&yEufrmzJ+hYw~%|0BfupB=3VIZ~a`}+y5W7 z5C1=GpZou_U1PTj+rxJ}L+mDo*y*;Xu#MxYdEbd`AItkA<^3g>cRj}?m*j@~T_9@kNmOwui>t_!5+{m^3g>!uw_?OD* zJoQOmnwEA&`tr0h(^tvgayf-d)3TiNvWxn+4L0;^_Ub?U)4kI6JOA3t<^#~4tlIw^ zZ?`mv`=liOm^M&eJEZSUOMCh76KVX0rFZX| z-fv)f_bzgFW}AD}MOF^0k3909ebUyLPJL+w-D1^gy}c~@Vn3X)Liri#<o?>KR$(V zIAw*pU~5TvnyBZTpVFfH54?dKcA7(tl!>&oqi5RI<^x1SU=KeZgHz5zlP z#ty<>2DhK*3*!Z0AAs90=7lkWuzle6BX-7r1-IXo3u6Rfa>#I8`$3&BHV}L?xc#7t z)>}iuJ2H@?Fk`I!;jxVY9;PzV!=4U@}`&EU| zkIOz;;NxYr15L&!fv+Hb3HWy6OTiC;hkjb@-3o3$=wbPN5Zr#JBlORre-hk&UgcJG zO43{4wz7EWe}#VqZVO~T71XKJ@8Gs#^jz?gQh)S(+1k)wf}a3xKm99`khH$3-hQ$? z^p&!uEx7#%b?EH2ji8?k(7s?->0PWOOpP;S|>HJsgXDEGg@FONm43 z2>oMQaNeT>cqL~;-*yE*nfMvtRz7TVKk(KD@HzZ|7x2Tfx95Wfz58}Sw3ZxO#8dw8bDs`@Zy^3J_&vmnhM{NC)C0ti0^dcvJopac6~I3uelmC| z>92gM2404E{B_`>smjC~L0^q{bMU6bPX%v7yaTw7BYf%xK8kp6@EODhfZt5~9Pqn{ zXMsOJJRAIZ;uFAMBp!e9xM=Di@tM&7L;ND}veLi#bSe1J#216tAbt&aZQ?h8w_ZvrBVG@DCGkw~*l!f%t0j2s2MYLU;4hM$PT=nlkE_cTP3;A^isMSdR$ z2e-LMJ90&EUKP1A__bswu993dbvy9}(AzHsoBd|skCXmX@NL99g1=9^2l(g2#m?iSOV91nj^*eqXfP`f&ZSsHz(xljRd|cfuAMUCr9#gZ-V}} z1g^h^cqBVzN**;~A-{(b^yek$ zCnWGu3GL6c1imnV-39EqQp z!0!|L+Wy<`ScLmv;@L9^$9*$_f1bd9OW^T=BU!U8KIHgxv#(>=$`#=W;v;{lQk{{b~|Co|yg* z#RKb+^K)jA;%w{2!=A}L>;oRqc7Etdha@}zr_WuSU_aI+GZYqg3gr=xR7O>PltA^-J}rTMaVOZ5EXFJqxEH>? z88>5ri1+~y7)r6lB2xM-M_s?IVXsb&^}kI0uZjNGRR3$H|25bDTIhc*^}km7Uu*p@ zGwu@h$qYMXhP^VwZkb`f%%}{zXNLVVgMlVt-zM>RVc#ZU-zH(-CSl(uVXr1(uO@M? zV6AD`w`tf{zUCmFG!6SU4f{3?`!)^xHVu0<4HlY)eVc`Sn}vOwg?*dFoQ8dyg?*ca zeVc{7ngt8Z!oJPJzRknF&BMOU!@kYKzRknF&BMOU!@kYKzRknFEyBJn!oDrSzAeJO zvVfTQ-y-bWBJA5D?As#j+am1SGVI$j?AtQz+cNCiGVI$j?AtQz+cNCiGVI$j?At2r z+bZnaD(u@T?At2r+bZnaD(u@T?At2r+bZnaI_%pz?Ato*+dAyqI_%pz?Ato*+dAyq zI_xXWVkjG7=gh`o@65(w_sqs&|IEh0KxX4$A+vEXk=Z!d$ZQ;pWHydgtcXP`C}b#Q zC}t>U@`WWmEXr6cWSJ;^v9M*v(w5mI`Vz}qW-M@-vBYJ@B9|G`XorQg5p+fg~ ze5mDka#-K{#aHw*+97QM<8#9fh9{Wid2IL8x^6{F6~6?fk9q5of%p=JZVzpB?B&Cg z)B13>^zT^c@IT+r&|R=X>S15}k-cUdzAiy99#`JfE%KzkTkPmR3qGpa_1dhe|3b}kpo#}XEd9O+JyX4RGtrSX9uFqZ=Z!hmP zDgQ+NjH^ve%6H43@ho|-N&Va-f5s;$l%)F4IX^3IX+N6o1K%uRr{^u^__l@;}e`- zpLsJompi@w1fKD0onD{$F#eR|KREuZ<3BoX&z`HFKRN!r(`&5E{vmLU!`Y78Pq1*@ zs;f|v+ShyHW~VKpQIR1;{-p@areeb8;4`n}3mg{>>%72qTJFYz&&*x={ z)9c)o>Fv38J^WC|pKyBb&s&cB^Sc+E?VO+vO41h}xA^=^%QslOgQcqXU8A+t%T!#?t%J8lu&$Km{*1g^XJ z|E}+&({s$>i=-3zr%5#ue+Tc zpReZ}_xXC)@xPt@Pn~_=&e(k-&9B%0nV>H%_Y*X+-tH4=zP$Yb&?_Gye-`ISj*oQw zM#o1v{)FSB9oPFpn)rNu@ASH@ZBU7>M0}(EC_f4OMB?UWJ>q7k4RN#6mAKjI2d>Bb zSN@C-b^2__^?ryZuBVqeJN~?{c3f|_nf(VG*Wa@={)Dry&$=6b7F^>qM*fVyAnBYIj&<}^YcSz$G01QJMQh5C?z{fvT|tgDFd#@EaKvMEO=ev`{mD$ zTi@w@c{mMR?d!9broY1Jy`PUd?%TI7953qp`N47DzWoKR$DQboTmC5dAc^yPJUHj~ zWbnGO&wlwc|C>9#&u>p>U!N&8{bf$?^ZU5tKEJO!Ud-ipr{g}qpMz_@CcEPvbljJp zznvX_ev6croh5O8PXbpPKEI8@^|({y&+^;P>5Du62Rr=$r=RQe`YgNIS(KoE(CJG$ z{pJMyZl^Eh^!pO@$CMH0Bx!#2I}hg1iQrs*sye-oXI-cF`R(KM-u_^x_vb6e@u}jI z`E#qY^PS^wIqu8V=Z@>Op4s`%abK2T{jB5o z7f#<2T;n<2@iE}+&&AG;_vboiXNI$Lx8phoV)5MJ?07#*mJ^XA^Y8r_v88hz7m}CyV=?K#p&O4 zb}n_i!m;u}5|`)m9REkQTYg76?(;R@ai6cN9QXOU30(7anX|thob&aZv*Yvip|i8V z+4|gHm-p`ee zmv{Cba$LXjYW_dv>@RZmUj^rQ?say&p9h_t#m-KJ3!TbIDV}2XQQ)om9z6aIQ#RFv*Z2w*4bI&?9`|rA0%;n znmO+4%Rt9fVFQ021_xXCn*}2Bq+3oZ`&V?$9 zNRsB)=c}CK$Gd!0a@^;u7C6Vh4Y=ml*Sn6+j?dTGj{AJ&I6J=lT*PPzRXOGkS z^YVw&>%B#bbJ0p-RFdZRX8ALI95~0h0l1z+?`L~w=N4yYoYQ+hFLZkE=M7G;-^n+B zRyqBx&i;eo?B_OT$NTw#v*X+6BADRSe0e`Bf^#{q@ASUiKGpG4oc~=N_vNiWIQyRs zuE+KL(L`s*w}GSDkSJn zar!%)zFva9iPNuj`gRHWu1>$s=?5g}hdBM6PCqt5KgsFWJN>K#{UuJn!RfC`&|l~D zcRBs41pRuazuW0ICFq}Y`g@#yTY~-#r@zKFU?@oWe(-%2KK1ky7 zb`-dlw+H0U%3H+*ePySA(COrzLr#BMg1)oUKkW2pCg=w{{YIzHPSEE#{U)cM zouHrV^p80Gk_7$rPXDOWuTIc!aQerb{*eUzQ%=9x>9;57-*o!No&Mtl{a&Yk!s)+H z(EsZ6Pda^CW%(e9%UelsEpJcBpOv@c6Z9uL{nJigH$k82^jn<%^aOnur+>!j`zPqn zar&)JKPEvx(dnOc`U?{D^PK)Ur@uNue}mIM@AS7P=0fdBUJ3dEPXDUYk4(^ycly_yepZ715~qLN>90=E-{ACbIQ`lL{XI_qrqe%>pnuls z-*Wml6ZAWr{%xoKGC}{H)4${Ne1@^t2YZLgh3H+x7-n7h-?GJO@`|~ia-!-0|*N$fN(U!34RU5>mz2kcQG8doi z)%0DUUxe+-wQSjXb9xP~$@GJuUlnKpKMQ<=<7&s&E7ZPT6WiGuXaOGzJKG#rJGM^Z zPREPNd-G>Eaa&h(pW|xB)?qy8xVIA=lx^l`F8s0e>?}UE&ZEv*X)?X}lR;d+*RQFz zF&7NvGwByJMQfaC%y!B#yPHbY`wf$j(ah)y>ve+>SV(48eI5BWMid`wkz+}p_@{tWEYc3j`u`jV|2_jcM7e-U=NJFahS z{mQ|PdppC4zX?0z9M`wDKISaPy`8zlKZ2b_j_X@ne{;Fx-p(rGdtqmTy2nCfwcd*b6^$G%@+{xpG|!K62Th7+F-JL4Qz6SiLPEXTb+bBWJ`okfnT9b2z< zx#Ql>D&kkc&IZTTj$XrS+U&Tuvz7Qt*xBZ|+OhR{cRKFv>?W@3x@g+xxZ1Jxc@H}7 z?by<(RvsRK9s3;sJ72c`Z$;f%lIiVyWf0#2JNA14W~aKok<^OxW~V*zmtm*7N#bjqmcHV7$ z@QRLmI~l}no$=a^t3S5>wf*jb9oNpgt%Gdbj@zB=d>6cv{>yRi&v4@1kgsu$t3P&q zGRtvqXD;!9u(QZP0YucqKevGKP4_h_F23X~^#^;$I>DR}f!aB?7%CuF3rD zg!{_3Mx4*zIXZ&%#C6>vO?pp3liB$V{=X1$KDX!gb`j6O{gp3?S2-nupNaRzadnPG zlO6Ym8u+XgOOo+FU|*lT@w^xcrrx{syfz9>L*li{MqL}?Pof}qBYq=}tG|=r?Pue- zBZyy#0&%J^4m!N#EAwE7HE`R-GvopVT++g1$Ha?(M zw6#D|Am$#=4dr=vZYO5DC5GK=_~sE?Ns{{;Ec-*eDp`MM6} z!M?w2yhuinr9L9PtqW||iKZ`${C-RNwRqmbt`kjvHjaBN>ZS3bRpN0g6CaFvQJ46M zXeXN!9}D~KiQkQed?@i7(e8~Q{!q>6&s5?AB2HaM{Mc%7gRZ-#$?|m%+5ub7*?4=@ zms?1`81=%g?@V7tJ5NcEk=}k&Z9DOI(LTIK+{Q(Ay=L|+!k=$Q|2*2C--x$B{0pJ} znVpAFZtXY6jDL;tQGxXHQBJB7FPl>n!8nqWo{9zi0ec#;d4@5umJL&ZqAWel)9! z-$<%Q`i3Z1t%$EeztDxauG6TgKXLm$e_V&YAU<=eM|}?IpN}{-oA~AE2QMdn8{%*s z@tr6qc70^|t%7l2T;ILGpDU5yC&*57v>PuI{|x8d)_*qpr{lcuA-%4zsOfv+7olFq zb<+#{nS*jz0^=03e>40%j(E2^(SB9p_MBED;@4$FeOuyBVZJ@CM_%AhT+cj}I*atn z5YJJ>zpEPUPa)nL{37Bfqn=(td=dP-iFg^g z-?+2*+xIs2ll~>NlLv`U!nnE^>ZRFv2JOkQ#C3gOO;w2>l@@tp;y0i_IGuP)#MADZ z*>Q{1igt#OJ_F^=?su7fI{N(?q<;_nyZyGF>E~k{V)t{5??L;&p6u*JJ8$a`nBLl@ zmq@=0aejyR<%pZj-5od8mW^jQ@;!I)L~E=pXZl&yL|tT}ONY+H+k$ zSd-a55Apeo`0L15X&m45cOd?4iT@AnKzHIFpg!7sfY}+0;|?eN4Tw(;@yF4=%_80t z_3JX?m!h06C4NfHnEyM7e~S8L>j0RauftF4KaD?+{^DP@%u1tnNK_u?Z`F6|3Z1Ym3UK}_q&LHjPcc@#Pe#!d_7P6 z9n{}9iT{=n^&b;ofqJx`_~SV4@5KLspSJFSo!`IE-<3yuY`h%W^UB1Vp*%Mr{xZtR zsl*r5kN)>0{vtkS5x)celzx|0EtZbsh0}IKQiiw}Suo5q|>h%M-+# zBEByZxAoNCC4Lp`e@5J%BmbTF2AuaI7=PJ$c>tfw6aNeTR3?5!?HGt=#4}*O1Mywp zwr+zRw>jc`F6l2t|1y>MG3f6uCf*(O=qlnjV*In5`0^^z|3`@1_gCL0z7g$YVYGAR z|MzGo>k$7M{x>JyALD`H#0R2&pJkZ0k0d{YP=$ zZzugsj2|8*ZqM^PO?)x(wVn8Ev}1>epN96fG~#6bG|@MbDiW_$H*#D5!Swx5uN#y8 zlsZvw>q40RT(l?MNxvF#9!NY7^>;Y&f6mt0YohjC0J zP;Q?j{t)7`o%rn;F%G+luSR+Pg?M?K_kW4kLVtGx>Y2rJBjQtocw3Ac&mrC&{$~?6 z{T0MbekuD@a%<~dnEhAvjih#@{~PtLC-JeUUxSEGMmsQ^_y;)d1md4ojmMoq{A-k- zdBo?UoLoix9n7=bMBLWXSws9>jGyl#z6<4QGx3K|kDe!93;GX;FG4?J*Si+y(@-9M zAbnfZ-#>`Ii1JYk{hrzR82YNjFGj&_NPIMo+lIJZcXuWJIL_Aq;&pMpCJ`@#ayy&& zXDBDv6Tb@j+ljwgKbD8PiQD|hBgCs9&RdE9i1@rhd>7*LKJl09#^dfG-VXM^C9c1V zr0I9!`g=^8($MeO`KpJ0qzv(P=ocyyAAx?o8u8;%4jU3LgZ{lW@m{DeorynKnjw9X# zpEHQt_$`yTt>4j>_%rCgx)JY;d<`IO?M4=HTlZ}O@w?ED%_N>eJg*^c$Gw@j#p_Pu z7oxv-nD{V^bDkl70qW^1#D7P-w1fDMI8UDwFM)B)55%8Dz5A2+dhp_C7w!D^LVt7& z@p3qBW#Y%8-Ka`I$>R z3vsafFcyaesE;?2z9#DLYU0aa|6bx>;=J!5eh{e<7Zw zvE8_?$*8F!@mly?o%m+Ntub-C{%=csCCW*6;`%#fnyh}CKTXkY4=4R^b)!Cqc$0`z zvxx6UzjGOJYxkED--Y^qD{*^n<0;}3(C=>}Zs+A);`TiPTj$5}dkO4(OZrua!$IQ9 z(GM0ueKI?BQ7>#=Amf+e{GLSmK`4i{iC={B)QtGG7&o>j{t()wUc@)!^I+n4V%~l< z@!L?&rw}iW{9Z`BF3#5?;umB5b3O4zh|enG6RkcHA73&SEX#+*vp@I?q_2*0{wDD~ zIDfl{w?=!ikN8yN>j3dF7%y4>WB#0pexx+|CFA|De?{VR&@Wdfel>Vw;?3ayX~c6- zKF=h6Z-W@OT;g3(PgfJ)j`rWy|1tm1MjSS?9_RN{;x^Cw4e@qrP||P2Z>t-5A+!^A z+|g)S$^gp1T{EGM!x}&6@iT{lH_&4!)5Qh@Tw;k7hH{uxLuc3aOLVR94 zY^n}%%TF`no1kw;{0a0IJ&D`;Zi9%=M0praJPYxhK>QW-Q!|L$Iv4YZ&qF=Biuijd z&o>d*-__M*>p|tm6ZP&s(ica&XX`ePDX8_9KUecd~ zdSUB6nSK=7r9VhN2>G@952hcDeySY$VdE#FoK+&;5B+IP;@@Gslu5iC?6)O;2Y5H) ze-w>@=uiA6@bie<@4Jj6-nVYFlSlk~@QaCCf3ukQLg=q2UIypocH%uy9_}W7JkHA_ z#E(IF-b#Ek#wV{3uagn;^*-@AD4%DZCB6dJJGNevo%fOOKMk+OzbYP&TZZ^c zs4uo&lj-eyl+{Ro9Igu*5`PHeqSnMaVSH}uGMW8z&|mZ=y{*4Igm@E_=ktjVMBHrM zB(vWbd>!e(LOptrcqg)4m~Y-z)!%cp>;-9PzV! z&Bl2=hB?YZW#YE(c0J-N@!8Ig+3$q$)j-mBL_42F{56!z^NHJa-E`vDVtiuj4%u;^ zLwoxO>GLoy+Dd#q>f=u0Z=rp&^@7ZPFSKuaN&hzo{GR(Qm}dqWt_t z`~mc*r4F8YEi$Acqz1R zn~7IId;UD}O|bJi@#%;|*(#}!EDmgi14Wf9LyiQ7EUHN7s+k8Z9t1O4(I;{TwW*z?yGx8uHK4ud?9`T<_yaMunG4Ya`aY@$_FAw`Gi9dn< z*Pe^Cxb4OHeVX(Z=k3HT&hHVoIPW3;70%ap#BH9X3ECU;XKLw~uhWVDiFUpx@vBgN zCMWP~iCa6clDM@4cM-RC;1S~14m?ZT+JV=ITRZRpacc+uAie_Qx}$MEEk4%%w8OE{uiH}4({2TE}74w_M`%drT~^ zi%7o^?cohh|Dn_0M*0J2f9`Sm&z=4S(tnC^+FMTFMf7vA&xfS%hx7Xt>Fp3dlD-W3 zkw2YYyO1TA7pR2odLDb45qZr3*HEhdcIcZsu6|nT>bUA3hJL8yMTK|OlP_tqYl)U!ecMan%olexKv2FOKVx!sur-4yqpu{n3uA z-sVRdIIj9h(6@D5^^IWvY{yl90rX=WSA8ew=Q*zW1<)^bT=i!|e~;s;Uk1JPpLTvH zKyUM5mS6kc<`>S6+P@HbTNuLh>tMeu+E=r`6#BZ3t3QuH-`a7tzZUv|j;sDf=tnuO z`pwW^?6~URfqseOs(%&w4UVhc*57%|anJLDF6xtz+ zPYE={H62&|KhQUKTyE45eqZ@x$5lTb`h$+E{xtYg9M_i?pNpWc>bOdKL7(Zk+P@b1UXH7D81zFO zSG~>e%y3+#6QRG{an;-Rv+TKAEB}{3{}Ab4gFml2uF`9u-{rX4-vj;cj;nMH^d->G zSbTnlzMA7I-3WaX$JKr@Trc!?T%}u}Ki6^9p9uX-$5m?U6J74O>Kj78+Huv}_jMn1 zT=gBHf5mate+qv-bX@gkLI11cD*YDvBDnsr_}IKsWye+eJM@hlSNj*keox0$TBMl# zCuxY|s$T~EbjMY1^WF;_SN$E(uX0@Vr@;OLj;sDr=>O-q>gz%Oq2sE575ZNtSAA>f zi#C)Gk}N)-L7(Bc>bpVT*m1Rg5c)G5SN&kX$)3%W>5|4*ep>RlfoHI~-U2Ht07xuKF#|zwWr|--rGa z$5sC>^oJZ*{pZk^Y%CunS^3$Y5k97>JFfa4p>O86+D}!9`o4~<{vYVG99R9Z&|l!V z>Pr=mcCK(-^|hg2=eX)CK>vv2s&5PZtB$L_F7&&>O9|^Ee}9yg|0I3m^lInIKxNFF z8Q+-xRkY7#9PcTT9?&1{xY}_4A>x3SLM)>v3-cZ$$hy@V3P71n)t73-}Pn zL)^f#!7X295uYheum0?Wej({C4$Bb79rQa$Z+?E}xE{BG9!Szxj(b0Uc3kyip#L4*{QNCgk!y-3@l7dtQ9GS*ol*|m z^tN7KEz+BxO&r(b-j3t8bX@J9j{cydKS})^SG}zdbvC&9IkjYv zr=}BM41T%eTCRq`&ug81J+3_udaKiGxw3WtHj>`ru*GrpbBOLF>3PR}9A0-^_18iF zj^jQKpE$1iPoe)D+~Uv)`7P8`k6zGDW`Q5=xW?gZ#NlM{Qo{7OHEk;8Ps;^GkEV)lV%y4;>wMxYFrSWW$Cvr2qZcsK3u~&98m0=V8Zv zy?EMj)epgS>r3F4UrZyUJ|q2|(0@gGd`um5T?bgIhe!pSq4~Ie8uDy^-TuuFTIij;r40H`+O_dYcdF zOWeM%J_p>&$q6{WOG$qR>dP&T>v0F5(5)pq)nMmdr|%{DerN}ta$M~!hMgCQ-w*ye z@pr)A0XP3o$8ir3KLxx{OF5V%({~3yk$7S77T~31ANAAL1#UbeM{ya%`y28%$POtT1l^#gaJC3WJ=D3d7McmfO`hxf+ z(C-H~|3~1sN3{-z$uIvMz$+5B?>}b}PlvuYcquWbey+uF&mz7ZJd3#f4n;QEx9^|N zb6ihV8??9U9amHj{%j)N3jA5(7lFS{d^PwkaLt#NpC!01_=@zluKPcvxAI)FjqEJR z;!_jjv~Q-|e{i zc@O;DNOoR?ohO}M%XxeG)AWktYG)7Zyi2?ot_waUUJv{;aP!}O&*mTE=Fd^5hQsHV z|DWM!b>cUJ*9X^dssEPRI=HE$ta1oh|@;8^n_vQb1 z$5mfOca&7gabN!H5x4SxDse0SLy7mP9qlg!xA@!o0=JUh%Kv)D)z5R_=YwSDjANqx z%}%f7XE)B{HpkV@8rXS@_>15l65kL0DY*HcgX10|ZvGTIE&65p8PHcIo&kO;xE`*j z{FTLZZfD}Qo?36>gP}j0>|X)#{ww&EWd9)A^YxDV`tq9NTJ&wb zi4Tb{f}dXze+v9paE*_a&$TDWf0|B@FBWI}U6KmmrnmZ1)p3pUiKXNIwH){LrHSLJ zx9>r;bllgMZp5v=oK4*7%S_@Km?yjg-10Tz*y!hG(p!Cb-f{KwcI4|-vNHj8-gSDd zFAt(!+UvO5v2_E!BX0B0zY(|f$o>R3|80GTliJ067#{JVQF-jR46@SfnM#GLw{ z0sn_MuKsr}6OT8F_;~Of;!D71fSaF9aomfYUXME*$GzHdJ?=}ea})9X;H!w2NsoT6 z1GnSadEZLB68zcaxYoP7;7?lnXwU4dfxd#{s(%3bT8=BSbpV=!Yn-*5cc~=*NowCd zyyW-qFQVL@4Q_g?cOxCw_;f{n$2zX|?YcYHan)Y}{Y=MIZ`a)miCewf2yStxR9<$H zw5@%3$-h3bdi0LtdfZoV++E;i$JU?P>-3>Ks6f(z_TeReTw17X{QNiZ>fpsX9Io#M zeiXPJ_jLGQk9Y=nE8^Y3&m>+Nd?I)$IlSgK2gjX3{95o!h(7|pfb83PR;wM?@>Ut; z?QzEy4S_$eJFfa_(0}5%q6N_Z;<)OYLSLz)e2`Q~{uJE~eI0Pkua=*4P%oO1ev53= zbO!0IJfG#b#_fB=VW{J3-^%kC$5meo^<@IM`T4SJ(=?0t&WKZs9oPJ#I;O67_Vu_= zVj}W(r%w~U8RNr8NpJaj)^YXI)}edJai6cZ99R7c{vRDzJ72)g zuizFRTNk)|ClN_fu5mb5-$<(Bc$$1Zfc&;1UZ_-%r@9a?4?e_kothaO<*Ct*tNq5% z=Ys1;&F|mfmlC%)Uqjr=$t}d~`%UYKTiiAgAF08R^bEMg&3+f}ebSphdmQg6`XetgMs)mN+$J;z0!)-AqT{GUb~$`jvMCF(N3Ee_Wr zK4%fP`?(Vw*He34G?SX{xYi5%ouNy?&7b|%;|^Do-hSV99qBFp4?3>#wCnUo9QX0x z>bUBkMf_iM+{gc2;uinUiCg@CCT{UB)IH|U@@w%gN8I9H8QkK3a*??IsgCQ zp#LA~Ee`KFuKB8f_UA*#eH^}UT=o5+-|x7O!y)2!9bH0qmSq0hxU>TCiD>sS9oM(F z;WXGO+A4hxz>`y1Y4*Uw@x!`v?uIN_z)3nWT zJ@1c0|FPqW)~Hz0500yTJM=})2%GcAS2oT`cU<+KKz|Z=DPbW##pC`Bh+8>nP2BqH zF2sL={b9ua!uWhLakD>%xY=Jw{I`>$pVtweR6Fw9i8rbc`4-|s(2u-9-2C~7xcT!H zar5UF;x?c5FLCpyqE7BeviLWy8$VYAxANQ?^|}q|&Cf25Ytbl)exax1dVV+8iuMON zuKJG94{==eBT;~|9asI;(4P-(es(Jz?Jpue5c~$>+2D6Nu0_Yn?PK7jgsDG2RgCtZ zb9yb$<6-9m(p!A?ItL<{xA?4wpIeD<0)LIT{r<}*j{Eq04Q}yy3-bmCoIbRluz!>~Ey?s2 zpW_`@|J$G(R&re5TK%f&xa#wuujjbFwffbsed#ivvm*(m8J;uXOEAzl;wguZb^NwbOD@7paPZtK-tOWej?D~Vr>`hFL2i~pmei z^V0sP$iF1L#o;H%_57~H`TfmtJ#`kJLj9sWjkD_ChrXEOsxMw5>W(Ac5aWmH#4Qd@ ziCf${5Ken!Df5+9IW#ytj=Q*zW!6!yOk@(f%x!@Mh&4}khr&s%SUY0qo z_FsUVo5;@7u(Ou<+u+X;-vz#d_#*IM9M^g=O&ykW+?ny!{J$0Y`otdu??n82@WGC& z{R?1!oa0(m3ZcEa$Z=n<7do!`4CrqFFC|RlIR|_d>6@!S(qp8z^8B3R8vj2K|Cb$C z`&ORcc3kyMF#y`(xazGP_>#D_1HTftcA!Xq*;$h1t91SN`559>{;LwV`z)EntzNVz zZub$+a9s0s3Gy|R`2WC%gIhUyL>-ni-RXTfpX<2VPoZ8fAUn41=rZD8!~VU*e*u4% z_|@PaJFew$7|P+lj%&HP6Z+!^sB>}NTX}Jm=X#E-ow2ZUs^hA+-$(4{xG&E`99Mm7 z*dGV3ZfM-P;5s*#^n3N-k`|NR%JX%O_Y_?V#Cf^nzC5pST=n*QJ?kC!<@qt$1Ke=qcJ68{YRJ#afO zZz68{onGx*xjo>x+PC#g50RbsV5itwB9dhGzXGpL{3r0%#8-h2a$L*FaW~w$8AIW8}Kt6*Lsm7f11v6_Vu_Q z;z%5?~;Qt!p#W63v(Q%)zEzZ6k zcMJN3ZBDQGGCQA=-tzUeQs;OY1)+i}&~_cx~zw{T5%PvE!<@w8U}M4}^Xl@iE{}IIj8H2SYD7u67ne|1)?gVOmZWpBQ)ehxjdJ zBR^(nd^LT`it%%0;#XIQybid8#i7+-1@uA99R1%SCRiDEp}Y(TmOEY=N!$ibkljC~6HmE?-{~Xuz zH4pkd#BTsUNPHc5xpRZL{C4b7@EVS5c|$XpYUH>c_dV!O11}}4kNmAi|K5r8mz^LR zC5?7^jl&GYVZ7sN$NKSEWM={F%yoLL?-}+Sk>hIL*7;mc+}4#|N%mL3{wBvY{@26) z3yy0X?u7m=;`V*>uO0XCJOFNSo2Cbm^oP@{eVebYbY9pT=6^I_jjG1a8IEh*tbEpW zT=iE&-w52wTNjMadlBysehzWFzMJZ}&)0?Emai1XtMi>+^R=X8^#2a0S3e(upBo(4 zd|5qu*m2dD!~FbXWZ%Bu_b%}bIPM5i-Z66iaD+i^2++<}g3kvch=NlkQi)c$Mr;)X@U?<^hp z^~77$i2OEZU(aJ5=$~M3Za*BivE$y)Hjb-)G4$=ozODarw&Ut&PxzVR?5O>AIKLMX zUx9M9kodi&WG6|>h+8~Y5}#Bh>NgSpB|Y*dh<^n8+lbGt8};uHABKXpoA}dc|9>QI z&z1d2+^#n(4v)uCH#9!IFy5$5-0U|99vdBpQ7 z;%4V2;%4W5;Z#BKieG~yfUL_c~E|Eh50gNWO8%2?v(VjMn`_%o+OJ1dA^qm7oNyNK^Z zIp0LQE84whh~E>%cdIoBf(7KU=YRt z<7f6yEEzu^=eQQ-Ix3J<%keb%ybk`fBfb&*JmNdRa~)Uvzo>CZiyT+`d!b)X{3G=H z&w*Qcdj$D?h4}a2UlMOqHyk$g1KDqecCSQs+-~-#KwqBtjo`BN_TUrhE_!~RXA-v<3E;@^X>OR)1Y@m$#d+;NRVDb2K`Lyjw20{wC0!sh&Wp4-9e zI<9ugz)myA6>WvSEAcmvjdn+XTRe}&_5S(9^MCh>_zLJRBm1Q>&RI$NH=w_hxUDCC zPlBD7h*yIB9gb@pUPK(ec3jbK$Zyf{G2dGJRR28m$2qR3IP6y?-W0s0<7&sQ6FWPu zc5I%c5Ap7>Gn{yD@HyaiUMe*dW0Ec-J`nsq;;XQkgLhg>vvJFY3S9IfeKN*l**w#-Rq{(9?0Xb1(EGh;IR(;keqV z4LfrkS393Vzl``^@cY0mo{f>OM~ROI|BAS+SN<*8Z;JakMJI|AlFa@$uu}@$%3&+$ zD-a(HUY+;xy{+H9n)F36zi~hDW5Hh{UK#vT;?=KxvTYh&Vzn>64p_v>+(htP5!4H!C4X|H+O5D%v-va%K#GeJP3~q5YJ8g(R4*O>~ zuJIXxOKqwxV_}>N8Ko?wc|bI^Eo(f zN8%TOcO(00n9m&SxW>)=%yC=~c@*?l6F(mOZg7jwT{!MW;;(^kCOdUtXS?I-kHzO> z$JL(}(EmpE55fMw#BJU1BDu1&BrDHmr&*D26W;>9knGQb{W~20Jh~YE-{iQ)&HQ=MasRuPI~@Pi+4;tCwX+uY3yS4Mk;Uh8 z_*s_tNiCzU0r7F*Ex_%(d;t6XNq-ykLy12JKAh})3p-OC_wB<1$2DI^SBie#M)qy} z?)Ah=w~G3E6YRW0{4MzNgX8K?ts>D*(P{D3;_wgjM-wjxKWjOzcIv`TrsJBgOz1li zZvj3G+|FYYk z{~OtF4*UNS9|~S%dOW_x-|W;Qo&)>c99MsuBmU<(uKuim{(R#1fM4Rc+G!0tiyc=x zuR?zd@wdPq1-J8P>wrH){0ZduW8%fy$U!81N%qT~6#4f~ul>{(PjcL!-};Vg9O^;eh3sDj`#nkD82Yn`w*#L{yeIe~;(fu_C-B#a zmw^3<=y_u{yJ5;uKnR@~9b^H{WdMG|;v;w!7h{mUirip1e&>ZAl- zjriPRagSOFydm*^Cq#Xd1m2qXapj}_v;^Lnc;(tr-#vl%C4N%bs2`BPhY+{lWf+#g zM-jgt?a$Z*K8g5eHKISc#9QDz&LVF5i-_BE9rK9)34az6H~m$_cU6r3EKT4y5uXD; zZ%N>5h}TDZduIZ_kN6iE(VvGB_-5k2qnaQQtIyw;{fzMAV<2z`GFt0RHqy;Qfd<#rYkWz=sk~$9NzsfsY|x z9R8f2z^4*_6ZWSk@Qa9VM||cb@WsS?SBddllEAMg{u0jD@&tZ6@e9!&-jTrXCZ2`z ze18Iegm}q}=>Ovhd@J#1P`_SC;I9z>5&pc9z~3jnyJqy~!vwyE_+4m!zDVHT5}ybE ze@x&9iQD>teE6ot&J&OQPS_;qjiB)$sr0;2Qt#^7k&rkxQFL zk?J+8HqW`6xXm{XZV~lnrxyHJ2d;MfJR636;Xaxk*OHA}Rj=1;mhAWLm}fwsTCX>o z#(P3Hn)FxV^Hs#R;PYDIJMsA`;@{!(yTtAL5#JK8t{IV38?WZ4txw*bxUHK#n7FOy zJcYQeCwx6|TjzE&aa(`&P2#p5sr}BC`DyEOmO#*r+qxY6h}-v$#}T*h?an1`-+Nt7 z+@6oUm$-eO)YjqF&H880XC8}r7vuK*2)oa0+`iY)o%Ey7PL3mP_pL4?Zr`uDmAI|L zvzxfBH&qVx(fqORo7nFn8n^F>bSC|Hv}2=*uK>S{_;&EM#1DaQC2sR4yNKKOq)MY* zG(YWoj`fM#^O=K*+jD?Zh}-jQ*6y197tvt6N_zYKNBjLu)7$TewM7GD+Y61REpy~J%EwRDMS&*HfR^J%Gud9x=@lc(Yv=1t3uujA}pZg$RyhSRcV zO-nT#J!0C3RKt;Zd8vlEll6njGaF{gM->Gk?;7Sz9wkqZ91iVc_Q>gDv&K&vGg-`q z_ajD*%*~#0*k;-Pu+JlMM@$-e;yszHt_N5%LcW{`!B`*<7`K~TK{i2 zQ{Je}CI;|o`=5_?**4qp?X`<+(D!`&6s{w-QeZR85MJBM>yhG@ad|w#L5$Beerk&2 zH$>Qxj=xniCTVbd$^Sni|6P1DNM4R~{EFz<8$++h*JJbX#|yJqKpI{uBA_!cPP1*S z9W5JXJ@xoH_T%I0Z4S1ndt805{x8pipxut2{;ORi8;-R9&WGY2PqeW; z<11?~6?`QB58?+_mST7HUr#0bzg!sG)LoW+tN+XTcJU?uf7V_nTaI-6MdxTsS+Ktz zU#AlJ`0ItSO+l&WaQv-Quvz;=!v6DrR4YEKPH^cvm*irr0se1PR zC1L6l$7#{u0wq0z_9uQSIKJiME!l9S{kzqRin_KVUTr^n{Sf<;EHxGTGq?SW|A77D z*)l4>ONIS2EW_CJ{|$}H@Cqo7E&MJ(!*2mJ{e!|!9Ef51Vc`mL54znzA%+>o5SJ!E z`;}5au^T{)t{+r9q9qZa2yoq&A4ESNDAOVVbpHzi<*?~5h=;i9Cz4(e6J0+5pzJne diff --git a/Program/libcsp/build/src/crypto/csp_hmac.c.2.o b/Program/libcsp/build/src/crypto/csp_hmac.c.2.o deleted file mode 100755 index fc67c42a36a990b72db111228f6c5fa6b002a3ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15840 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 diff --git a/Program/libcsp/build/src/crypto/csp_hmac.c.3.o b/Program/libcsp/build/src/crypto/csp_hmac.c.3.o deleted file mode 100755 index 635c04c9b8af68bcfde62f5bbd32f65acbb7fd6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15848 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 bJc)PJ$v$E{y`ZL4{STA==XEmJX8->NHW&ax diff --git a/Program/libcsp/build/src/crypto/csp_sha1.c.2.o b/Program/libcsp/build/src/crypto/csp_sha1.c.2.o deleted file mode 100755 index 68cb3e86407ee0ced529a0ac079fe9b34a14fe2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11832 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 diff --git a/Program/libcsp/build/src/csp_bridge.c.2.o b/Program/libcsp/build/src/csp_bridge.c.2.o deleted file mode 100755 index 32935b3ec97ca5785f46ab1b581497ea37136224..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13336 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 GZ2y0NNJ)zT diff --git a/Program/libcsp/build/src/csp_bridge.c.3.o b/Program/libcsp/build/src/csp_bridge.c.3.o deleted file mode 100755 index ff971a9cf7eff5f8003e0fda51d892cdce2d4cb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13352 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 X{|#0Ceq^ZnKVG5gKdmz7YS#Y;6%9r6 diff --git a/Program/libcsp/build/src/csp_buffer.c.3.o b/Program/libcsp/build/src/csp_buffer.c.3.o deleted file mode 100755 index 430fe1fd07d54df81db58d4103c79910b54aaff7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19608 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 D8jV7` diff --git a/Program/libcsp/build/src/csp_conn.c.2.o b/Program/libcsp/build/src/csp_conn.c.2.o deleted file mode 100755 index 4b37422c04b2eb2ba466ada937a9a19577fa74e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37800 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 J$UEBQ|1Zjk)Nud+ diff --git a/Program/libcsp/build/src/csp_conn.c.3.o b/Program/libcsp/build/src/csp_conn.c.3.o deleted file mode 100755 index 8e32c550ac84e9424769b99c5e18ad3165f67885..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37872 zcmb__33yf2)%H2}hUA98B?uxoam64gkbxN)LlU@w0D%N$P%k0588nm04U<&SfD$5B ztwUS+6m9F*)}eNyPE`;UtlCelRxOUL1B&xpQS+^L@3qd^+2q>qf1ZCo4B7I2~yFMJaAu#usx#0m;|3_t29o z_vY>1yR_`S@4C9WU>B7a?MP&W64g}NmM_TK#8I=hUD$8d)~|LSOzpSpD_!J|quYr@ z=58Oo7v=sSQ{i3v6WMG;`{P}kCOe6tURtzsX=Zf$1ensXC$B4Sw`Y9E3uJzN`O*hq zZCSMQ1aSK8x*(z%TgW-8UTvqcZc^ND^9PDl7Ga&9#&@2hgy?ovXEEw{&d6Mq|4yR4 zvy%>r)Ui*U)S=(5vXdW}>1#Rl?;TJ70Zs+_jesS zF7N$Acld5d9O5b+dNFVJ%Cqy&+8b?GHFw%vxU?wmjk3J=MQNu>Qr+X=n&I=dA3q}6 zc|j(+826-(SGyi5zW8C-sq813YU@(#T7D-_Z>hK^LMuFGRl z?Tx$x{dToQru_B76SmKGsgDX7_2Rl=bF4Gg0jl7_Y{-_CxUt7ype+qLwF4jjdJpq8ZOqw1FB zb#;8M>Pej>+Oan=xUgeYsH3)z#MF5Y zzbK%YDkNo@p3FNyHQoCFT>TDI=AW5=M*CYs^OxqA?|J*grDg5^oZ0bt$J2Y>8bUK# zsHAfONPFHKxaajy`nP-j8P4C9T9h$obo*;VJNE8*ZAeka!+ZWUF#VDA!|BhZf13Vy z?t%PGuWd@CUPx2X};wYzZgS6h{sD4RBOO`rU2b58Estr1PR z_+MQ!KkB;p&92>DT@N_B`#J5e&Ft8-=e2P9UaDuutLaZlr)j&baO?XWukyk|U8ski znK&_j)0=_9j>@dWAaVJY-HF~J=N(wV-7Ej>{B!bSdpqZb_8bgTnR~a*O~8Czg_wrWXM;-4*gC|hbc@WK7xNUw$SL@(t z$BWwv(hEBaQu3dAhYHDWe|>0aX91U7THRS7MV9)@NyO?nU5^~vvJ49h^^*LKFVRbi zJH8{M4vd=Raq&~y7ysme!pEsw7&Mc z^csqArBp}Tt{Uu~DsVbpd;n*x1@6J<#g8CkSM%U)rRmf=mvokf_PiU0RNYxhb$BRkw(r725F?}a1$YRxLHe7>aP%aRU#H4trojFwPR|H++2+c)+L6m99c zFs*CvJ24uB`Z}SuhwFrOm{_<4jpm4Uq;YI7mHB;P$+F1#ZSl5vWO#F=x~;xGvbHW! z8yVgfsY}EgTAlp*`liZ?L|s#3q`IjEcx6*#W4sbbYoxlOu0CGnRJJz9R@XJgTH_6| z%9eOVB0lmI&|;MLyi>oA)!N+DlITurSr^j=O^-mYl0|DbT`g73u?lTod?bqVQs*eM zB8jF53{VzFDq319);kNEBGoPNxLJwOk%o$OR57Q3R75K3$^NSKk;?j}R;pQkg1pe2 zfGS<(~q$VURM ziUa~_zyc}y6w)U*6<`pDl;K!y0|7N8G%{j5@RVM4jS1$QIu)Fd!MXe*LNt9l#9pD) z5Ek#W8^P526`(l12A2{X!mO&}Lsom@u?Z1VUzkl|dP>?w#Z7C$J^uy8jsi99C5SA)f_%LP)KxiYufw=L0~_d=snw^F*+(nyu#F!=Zpl2f$20vbbFUa7QeIX0YnNv4)pg@`{`%N4LXqUF_)vj)((bV60f z5`QG!A5lni-TqW?2&Jcn?jj^~1Bq!kD9c_*|9lknSEVKWiw5M;@?mrmZB6<&khKNr z-$K?Fq<;rlTaexbd8E3AOLtsEa&^R2k;ys|P?1?WlA&Q4|+io41;BKLE z9(IOMx|9A>)eM8vccPNo^*2Lg`4&`{o8eZ}Hj~UcoWnhL#E z&;ib|L~@S9A$_I`T+6czIbX@ggVXyml&Qt7zS!Z38OJI^Zl>}-C*}!G=v~Q>aU75n z(^4>w`{Yfh*=Q(q>Z7aVfI0@%F-0AFsbi{>86`gcPN3W_?zDX;f*;X&CqX_*%ab7w)AAI^Cu{k1$XQyR z`UuIVXn7jsky@UP;Wt_j`@S<)k!@-U4NpP8$;4ndnZ~VZBUgL2-%SGuQBLl+6YkXF z%@=v%tv=ySpYR(H0=z`%$zHW~yXYV4^oe9<-9k|{D`uY3>WL$eS6h}j5*d_{{ilJ< zO%@uC2}v~vH<>1dM&50ZMqvi)ft3BSLCVXfb<89wxm)A2?nzkx(pQD@F>xt}hGru( z%LQlvo+At4bXr;{go+^R#tzMa+*{*wA@|X86mnS0#gKU(oreY+sPXxbc}^{Xe7wdN zK-L{4v=FlH1ffNcb;E~BA&=Jl#dlEcbG5t#^K_|}%OEe~x|UC&ie&i8#97 zy3eIM&ZwaSG&X7=3!~FX7$d|2s&}@#G_aA5<$+LDw!7HP%XXJ2ahdPOYG)W8D8v`ff|uBRCyU* z?4IFo-7?5^w!7n6FT>xuXLzz(2Fx!A?v6*j3{Q5?u&-MN@{Hq9m)Rf4Kld?b0_x)qQ*GuVVIl*VJw#UC*B$P}B&`cWwX;w3oHt4N ziVkQ=s$uX`cPUlTr6H=7_4cS>PG-8hV{=%P_4ZmyEBE8N<@$OWJijCJ3i?xR<4+d1 zlQYI}3C@)?=O~wFPJV-^YG6)5qWdc9?LJH3={k-@JEFwbyDt}*k{$OQ@Tbv)@@@k~ zr%yZAaSuUq=&1|^cRwO7npx}H55CU&mlZU?wfKa}GE?Qa2Mh@dSa5foM=EB~EtGqY z^yPe{>8M+-X8ze^$DeiSJk=E_&I5+ZLWNv|Bf<~$i3aqBOk;^r+kupnN+7iUSlLN{ zDo1PmiD>l}Ci0pJACaw^bAwou%Sq0ks2%)d4lf15b?=%&<&WCT@Tm17 zGz#&^EWfY+4_Q1*o`faZ=c~j_lpJ++`R?q!;fA&12F3iCO4n6i zC)_bwo#VWqDqHSSNB4T`zX(ew?Qp_I!!ej)bPqPj9}qZEk!k(i>MH?xg;tVuI{G(p z)@zP2S9s3A@bDrjbQkPJGAZI!0b0l`Lj!xTP-=_HZsr=hJ1S|3oQs%SC~o2?IzPhf zmUZVlZn0$dibYP(OUIK969}N$BXHF+x*))a^{69E3q8kmpO)Fo)1@2~9mIixyW?uo zt%s8$(DJH>Nwy}Ka}zEG#tN)vPl}*#jIy$i^H32Y0i?$O9v?bhL{Q7z+^;5Sz)OD=mESAcWi4?5p z5=ku+A$X=I4m`yZ``qt|{qOe0-JUq`WKTSLtS5%&dg8!Qo;YZdCx-JqabT7w4$AYy z{{LMrmL0Rt_2oxgj}k8R#THK-c&aCcS9{`MzvzLddFa65j@#cI9v+Yp3?CQn?;e$g z$vu$eWMs@Bh^B`@PB46W#?*}B0knC*I9-nP>PHm18o&ujX_FkBLZ_%x`T#d01G!wn zdiV8IWMuTs=#w#-GG-7M(t3Tc&oM@}zCMGt9{MW1{d`rpZ+43Zpn(1-sl=oFM3gYV z&yVOpXn=4u*f}H&8sG-QzM02xO?#mpgIO0vkY|W^!EufqK((1hdydDA*VQ7*%pm}d zXMp^nffG)m20Ssvosj__i93dlqpr;xnQhnM9Zr*?; zL|m4!ycd*=>gD9A?4u#jpzXMX_QHuoLvGt8t`iu1)ojX_W9Fkdomh@$(XFpvuWq#( zt4(#BafV5xYrGVJ@@dTb*^386RF|6QJHT-!Y5KLZhrp=GFe-0=GHQyKHv=x!c~9rO zs@qQGl2v3HyFx{#XV698jBM&6XgELn%jRphg=eLLX>^e(D+{!mR zu5*rvoeZTobkBH`&gmbI)KxCJwt2c@KEHd(7kiX4oAL!4H`b$+ia3#>fV0-lXK z&lB-6u0YS-OfsJ3Wh@ub%vgRz^GU{9FXLhn&5VnaW~}!zE)mhpxFl)D%e{=tM7*9M z)N$EO68p7J6!9T;Mh|`BBu*;zC}p)QZt^fTL)3UZRT0>eRM z(ds&-B8o=PM8gdV#3e6C|TpQ-zbDE+MG?mId~>zu%6%2>#vdQ_^4J7V}tuBl$G z@+gZH9(0D*>>p=y(jt#iD&i^+Dig8FgGzlBTKbsoT@hTqIVYnX zpQ@!SPMhkfIim12T=>t#2;HUD}nL^jnW|#2hA+8=2CR(f`9~ z|Ku~R7Lg-rW|RIeioS2cl)~QozCvwMPlei??<@2T-gSGI&om-GWpO;)LC{JT&-NkP z^P)&{({y$evwcNp&0$Cs_Au$$iULmFO|~Y~+ExXgZPaxP+{0(;)*}AhgUUoamMh-# zxE5WHdKtajMMj)`EWF}Tj_B*Mt0Rj$Y9jLGUbZq3WuG|cw7NH4#pzf3JeIr@-65$U z8_7^FvJ~BuqhyfJ_eSYb5%G=&0yUM0GFkQPs0&y}mY-2;@Q*_IF;iit$iMJRDEkeI zj;E-z2fyeWHkax)CMzgijRFH08)E zv7XgE%W9-LsK$TJOKY=a6o(NcqIfH*@1#lOJemYO3Grn+C*0gUDs)GtquD%j+0%|k zWI^~c4<6=8<^P&Lz~yA{*`E6B@-Al{UT{MAHJ@b#)Tn>l#pw_8`R{ywk+_>%D}KFbZ5+%?&mj^bOT$l7@mX%k z?DFsCbh%T1n&amr>F+lG1?GRs=WqG!aQ;+2r|~(H&;9v)JfBbCGu{tHkXvFM^N)g0 zWuDx4%dNA|)Y5x2sRW!Z8fC6~n07E-3Y3C)c6JV4+s$cfZON%?tgLUVis!7GJTW$L z{FwT>#44jNX_})K%BTtFmh`H?=0J>YB!CIkCPu-s;1Ri7{>T z7ImYCRK=@FroN4L;Dt;sK~$Afi*l%HbxmF#B~tfpUEdmux3tvPwI*~LGF8P_x7AQo z>+l5qemzC0+b8N8;v_*syrH7Gwy6bCG939$h`5028tYI1*)eT(TU~u(OkLv)G#=7C z*ARhvmV&f;&fK70-KSKFlVhkRBva8~(i>LQ@fM1!g(aP57}`(Y=ek#Z9h!bsFe4Fs z`ohruVf4Pbo0^^aW@viN&vK8Qk+-zu^c53EwTJS9eQyu8W+VAA9NKW0N{2w|veaPT z(BH3~amKJurz$u{!JnjtE(Ph+&~NX1p(QjB@>RiOLh~R58{TMNbH$qFQ#VDIdyIb$fYAlN%GWmXPB zlNOy5Y@3!}5ZsVG{?z#sYvvTx<`mS<$3N&kPZ{`0YA~Jj4{AOylr#VSn)tcp%g>y3 z+Sr@l4Ay4{hh*O$OkXx9u;T^r$> zi-T8sa(i$Y$=`0ANBHJoHOb#>oJMkcaNbmke5WFtgUhPCNP94Hu@|{Cc*#vql!R8E z|G9F)B`HC54({K0Neb=AlcIZr_dZ7SM^wr81w%Kg$c>cpU~t;$6xpkacrX}25jygK zF2akP$ti*0e!9n`tp5(oqn5tx2e9<(!0o|xp?Se@B5=x}0WSnXG`s0}1ic^MwP1+H z=wk%>umVt}8Z1t%mBwTO?;i>eAG5?-;;l_>EtT^rY2^6)#dB z*~GLu^P3t6MPUTejN#D7E3uMA1@lz~Dkm0itn!r_`biIpp)Y5g>iUYBR);=@sTeob z=i)O9l)AQsz9Uj<+8SHyY8vT-7*wjlx6YZnaA~Aq%9O~Y>ngahwPKC-qF*=T(ihF|c zdsV!?VmK`MW&(#gMGMudDo))?RZKSy z)w3p1ORY^`Ts1bK>{x5vhPYo1sv`9Z)hMM)7L_k5SXAPGfud;8xAg6Hu$7~3(ssi_`~RYy+caY~)15#I*+UA;Nc;w&jFjV&rITIg3^yb^0}YE{Vv zC5y_6VrS+TmpkecI2uX#gbs#OHza&Yq0`Vres;*VCa1EtqQ%$gckP;ZB1Yfp#XyC3 zD%RK6)zl`O#D>O-hPcz(SQV>l)w6)^>PiXb4rREiBJB1$S7Usw8quncP9`ULDY)?R zBg#t{5tVH%PHj_bLX{`Zsa9Q-+TC!EYEe%CE^J79!J>r=V+AF}MGMOnb!;q;`Vsj# zW^_GoE<|_5r3ZY{n5Z^$&@hT=ZOZ-L$Wf*8MVk~(S8B}_Ra8ig>Mv?mg=%~+6HSnO7+%aqB)#FBHTyi-Zr@Ep4l_L~aRORW@SbZ9&PviAzg6CdzSQIB;R#Mk7 z8Uk&uziISL0)*GU8Y)_;25SF4NYsP z`_NaNG-J24s8z|)7iZMT5*2!od4pIPg6}5Pl_aJ#Ogn1cV;iZlXn6UZ4$F&L)6}A% zW*9Ux4`;7pJQ^{#(7Hk6GlmaONte3p#D}N$WTU(vQyy@tnqttTrd9{vRAS1fkv*rl zq$t)*eN+vQMvP)LA)&ux1eYye7%M}UY-*+@l**>hHr1R{Rb3xzrO`-ArP)=au8K#B z_)~u}>gX=z)y9}pyG^Inb=6Inu`!cT$D~!AhHO)Pl{BH)Ox;%1p$-!f+O;&lV17}# zgV`6;$Xc34n%1h6GxL`$bP@!iVKLYouS7MM=nAVvh!!b5Tf|y16fkGBHCB*IWW;m3 zt62keL2+sr)~VG?&2Y*MG{ z4K2TlWI5)5;JeYv|a0u^F z6f$oz&IGpy)`YPgkV${5=np}*bD%e&5PkvH*IP__6XC%HO7BSG;8jcn^{VmgaOUMG z|I*-`aHKsYIMr1q%%+mS-LIJZruG7lTL^Aoy+>6xea74cd`5o#MYZF608Euth_a$8 z|4V*;aL1E>5LA7AyHr^XKGlJ5Rx$T&WGIAh0{?__;G2z{CSQL<34`wu)CV4<`-g$q z;lWn~i^7rZDYL^PFYi?t&b>4>KRmfTZDDv;FzSXU6OtbuIXfI7Cgp%fwEmYY{V4Mz z#$;OvSPI{X(`Ohe02|Dhd@KWOG-I;WHlDCqj9rGDep^x-wS-454d>1aPc8}1njemo zE5}feq3sQ#uH$@}u;=^hIVXIV8<-!y+pP-kcISroyYs?Nxh3Hj+~V+SZejSKn;-tj zEd{A4JUPDyXTbJ@T;3p(zc0X?6zAivo;X45iS!VHUhnRn7}Ogb-9Y#_VCa#jJfjGA ziNA^2XhR7>Y@k>Hz6XC5;}Je%rv|vh<@^!VANVXvN06EnD>+4BCJs4>O`IMAJznhr z1z&ng_vD~M?>hAmf)2l-Yo!GpdEK~sLQsvG?igZ0{W0ee2|rDfF5; z9F!-~6HkKUWfkZd%~PE8t9HiaDXdzbsZU&;M9ve%Rw4rN?kR#fXa**Tu@ zp4vA*30}^6as@@Xf48UTqyjI#iJREV{oJkuIgp&9dw|+VjcI^>1m_ zy@|T-H}2HE%>IsA_W1GRCpy_B1-Urn;V>45aX5^}VFC_{G6~XT9H!uqr?b$V|J;&A zv-3-0i{{KJD=Lqb=g+3QP-UsUNsxU;6mQ;g(QQEYyI;>fYp<7ae~-B5^v0NM7kG+# z*aOrynY*Dq?NCC4W~y72Za3VXc6G0)VtO+hqTEsOjWQtK%hJ1Y0KEH5M06EAcFsHn`c7X;?;i6v#}r*{n@C34 z`9alTiNuvvdNV|*G5@)NPBr(4HwTDs!Y_mYB_8u)O7U%~ikbRJ>g@)|i!cS_er z=56IO^pB)J(ZAQgPc`rZ299fO;lIT=${lUsUosB;_@+wu0a_0cU=Mw@<>7r92S3}u zPhs4ySB}BYHTY8u{m>=#oo(nb?L5QaW3CiCV}^dyp7RVo^q)n42+amRkK&@|0>*9s z&<7oB>@e_g27a@FInv;SEf&ef!yI#jI z4*wiaf5MM2j+0rh$p${n;FlPt-+20q&;cN*i+k33>OeIKU+FtfeZFb+G- z{`0zlo9n{IhW-;NkF?|0hJMrjRK70|d(id>Va8#P>Ca;1dIZl-g3n5V z&q;zeFb;b#H%PrMH1L@Qez~Pb>UEXDH~sue11~c4{K3Er47`hRyIqb>BN7Gp0eebf z=ZOZ6I&7prgtHh2RziQmZ!~b+8w-97<94~vCei<@fkzBI<9I6%|k8_gVcAi(GO=Cdf1)n_dU(s!9K)6=uLk|(cjmIP>`J}!B?|hT$>>X z{yEzrZ`@;EkUMjL$zLGagg)IncD5d0%<541Ic z;PtF$v4%Z-GxN`}@PD(zDlPm|u3Vdix3T?~Sa^{2UuNMe*`BK{d=U($aJxQvc4na? zQP`zV9)2C;k6QS>Z2!|1{s~`)y=37nyqxg5bCWIwF2 z@T=JVi!J;C_Rr-O{va2O{Wb*ApWyx}*Pnv-;d0Zs-30#~E*~#q9}YqE^yWDB;Y|EkuIEAvm-{!ljuk!6aJ$r6{6dbmS$Kc8U*6jn zJ%hMierWL{%-><*@|EeYEIdnB$Ju4!2e_Z?wQ%v{Qx^UI(dd}whjv z4`92bUNIimLo9qT`$w+Ng)jRc!!7<(JYSEpaQV(5&%)zu=Ohc?!u2wr3*fp%K4L4i z_yMk0g@r%L_BU9#ddN@u)?4^P?5`~rK7{eBEL`?Y{>#GeV*7t(;bXbJf3$FV*;$1> z7A{}iJ!#>yng61NPv?2*O$+}Ox3ApSNITxj^TT%*AHOq;kk0vp|03(pvhYpJ&#~}g z_S@+eet`Q)k%gBtU*^gLB!6LT;B^V{=JNEv+zzX_c{yzCHLD~Ec{2zzth5(bA9i%aP=P&QM){9;lF48 zGZy}VYDN0hI}4ZV#dj?{9~Gw{KLjIwSi%00`9|Me;_qa90poBZT)&C_5YDprn|WN+TKrXt?KtOKe1@GLSo~R>aH++AiS=J?@gvN? z!Qzi#`)@V)XexQm`e%#(JnMhK!e8R}zbrlS-1lpXzmfIy;`V``!)zl?y$u}eV+ps* z(FP8_+$SGv;Nb7%esc=rXcyE=zKbk0_|S6+{UH<^cqYYVTrV_m=wA;qh2;hgJ-<+> zLqFcXLfB^D&?EP^GXBIr@;>5!S^DKVEqCmT_s9p=|$f14n<@!2RSj14lcK=JuXo;NZ)8db)vwFZ)+T z1`fV_*FVp|!GDtNUuxjs59j%Ig@J=F`!jI^2mc)ApKIWX&+~knfrI~N=5H`?@ZaKb zy2Zf3Pi4PtGjQ;wU9L57@DDKmrv?tbtP8(nT-rfM zWQ6_@J~nXh&u4yr-n^D_FJU~#!mnk#(7;Xo3k@9lZ)bkBh09N4UBI~X!`He0UvA;z z&mUX3T(ADZ!uN8ycQG#YlKb0z7GLx~W8i47DcnzA z7~jIU)C=ziB3x_Xt9d=$Y2h=Of4iZdRVzJzwD{6q&sq2g*7K%?3;!bvAI0_@ws4sb z)B366z4kgAj-t??aq*kH51ME2p;E46CmJ}~Wj^=M0s~j;GV3ojaOgRk`AZF4T^BKb zg@K#xUS;6Wb200wH*oO(oBKlx<5DkqkG8|Y6YS?(4L#8RbJl;Gfy2(7^oMYlftz;T zYv9l$*8>kSF7{l>4 zcmv~7uGIGegAYH;{^J&lFYk-*F!(G|F8be%3>OyN%kZuXNs1`a)S ztmjb!hu91y6#mD+&3^KtfkV&lSkEhriyw|*|9@iPAA&%kH$Qw8{&eOKweWGwpJd_k zJa4gqqertTt$Bf8w?!$pK!UCS@=%Iud(o7Fn+UzKhF5?3>@V~ z=nvt~jLZDLhW)V5-~+l&v1$FW_%c5qG;p-bcib-T8#vlg=It*H9Q=8FAE^IdH2=P@ zf$N4^8u zV)12u`;mngu{}Sr^sHq3E(<@4@y853@Y|K_pTAoC%bEYO!G}1G*NgWpJj9Fk*B1U) z=0^r-h2jU{kFjuh4m#b!NAdM})WWaleo|)PW!w*A7B1tc$-+hd1`B_i*R?GcF8Z%! zT>2He&H1yzho3)WKR;ygPvs1+S~%VrLU_-@%QftLXW{bw$&i7X06(ML5fCVhW?bx) z-#06=_^r&JmxLd)_}4MN*1|ty{Coq)R4Vh&g$52g<$iuM<6`GwZug%UxH<3r%)rs) z@?OV129ELg0sSF7V&LH8dk}}R{!F=^nHN{~k^gl~~2>tkl9yV1Z=U;J05 z2-g|7S>K%o4t^Ss_uUpw|LuVaPg=O#XT53RMa=)gz)d?{yhKhx>U9I#d7Od6PWk?D zxPimYCz)T!INAkM*F`eVSol{weivG}@XIV*=CLy^d>o9TaJGdDf3=0nbD-)Z_<0t7 z1^cZj3BJa{d3tj;B*8DXaCttoB?*4Hg|FiRu1tboZ{dTOe?t=d77Jg>?R9Gs{0Jy1aG0`+{t)DMI|Yv@l=e;ejQ+q<TD6%bU-c=JYYjWl<$X zm;lVgqZTgL!&MgkBaX}W9HQqs#&=qLxzByV!eyW2D+`x>p+4OHqF=7lCR@1d6INNc zTt95GaM{ni#=>QP@-+*W=Lnx!xICu_u@l8kc@A>Ch0Al6Tnm?dn?ehh=VBWzT%NDyRE z(qD_#HC8tf6~90lt6067ej~42GJSd5EnY!Cqf}tW+8E?L8|eoCv*{NF=?4JmSCUw5yq12h3%`W+{~<(32bxgEk*J)-g8h5b+}uJ_--uwG z3SSaxmujgL1Cs(SyO5WsBlR0Gz)xYEr*S|kye>om_-vOyns89<{PL3=Tdn*NE1pMj z=p1X|lK)w&K#9t^i1XXopXGX=%k!e7OFoIuBB3Y$-5t}67f#b>_z!I)ZW*j$^*`C! zI*~MEm?o@;awFJW%wskN`k&A+6y$l1jvdK`nLXKmNHh zcX57?z`{v$ZA8bVTuFVL1Ynq}%`lSle`O^|{e}A|2|f95GW+i}E)f317Kh}Q@zYb; z&>fkFBRyx}>k(XzVo2Hf(Wk90LI~~WFIFe#dMnYcKein$ipn^6yUzcdK6ytw|NjEL CwR1%P diff --git a/Program/libcsp/build/src/csp_crc32.c.2.o b/Program/libcsp/build/src/csp_crc32.c.2.o deleted file mode 100755 index 087f8a6f0bb5a545c9da185fe34675ab74c8ed0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11960 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 diff --git a/Program/libcsp/build/src/csp_debug.c.2.o b/Program/libcsp/build/src/csp_debug.c.2.o deleted file mode 100755 index f671dab84a2364279a74478eacb9bcf330c927b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13752 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 Ib6x*`06$?mTmS$7 diff --git a/Program/libcsp/build/src/csp_debug.c.3.o b/Program/libcsp/build/src/csp_debug.c.3.o deleted file mode 100755 index 12e08aab65116e541f4560c490b8e902a2a425fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13768 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 diff --git a/Program/libcsp/build/src/csp_dedup.c.3.o b/Program/libcsp/build/src/csp_dedup.c.3.o deleted file mode 100755 index 8bf285f7c2e176900e9d4f3f67d61c88c8c34aa7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8856 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 diff --git a/Program/libcsp/build/src/csp_endian.c.2.o b/Program/libcsp/build/src/csp_endian.c.2.o deleted file mode 100755 index a1cc8950b2b47d80cb0db530e9af5c9f38b7f675..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9144 zcmbuEe~c968OPt*SzzJr_Le&i?xflcU@4T_y_4&S0(t>~Lq)0P6jJQ5dpCExx;J~- zokg@jDK(a}+JZ$2mPD&(TWu4qnx?kKYKcml(vrre+9r)nG|^yFZEK||4Sl}vJkRXx zdrSXl-{fZA_w)REf4}d}ePP|T>m!z>Bw6YTRV@isYUf4Oe4oztsWvr7O`N&=&Ex!N zK5_i?Kl>-n^ds{TLlGW7{l|$j$4|e3#~(=P`03x`Inuo6)&4KN7kdXjC$3r){abT_ zo?HHlpg(NVKM`H@*XBfY5m}s1@b)yNqPos8-LyuX4?QMB`G^%mDH55XUs3-R^Iz6< zUq%jHStgY;hn~C_@3-UpB{^u#H?W|Xpghru* zFp_l)bo#KWif43%^t37TUXArJo~aG#A+lM&pj?B{qg01RYamk5AQIEv)P#cdL&UO6 z^oUbHU25K;V%CpG2qg&p1PY0~vYvkw2D5i$3d(w6BSCJ%5B`iir)nEOr;jKr5YPB~ zNKfi%JspcieA}sQxHsH}w`$uE4YlE0h-LSZpEw27C2B*|dTc471fg$30d4rs5ybM_ z@OTpfw*Xk*MB6??<<@GEMTa3O1R`Bje&5{<{Hv*9^aW-cw^8Zm6DUPpV?M?i))xg(fzB5uvDmGDdEm`TOI<9YL?Y;blYkk|`vVJY2 zr@uyOMbgP(UF2WV`nS^4vi=osqNl#j(L%9OsdTwCq|%jgDV=wR3YB3ey>mtHU~f-n zA@5dpc8rXNul5nEa!?P zFNvEN%(ASCyh~PeSPTxrZuuo-=V!Znt1hw*Y3PSoAgFdMwV+Cl6p9&76^ia?5J=aF zMCmbyIxy|*$hhh2oZD|I7Aj*-dbCumxWj{GFXQElZn}`qlDBlWk}nLa4c84M*Iss6 z^3v3&Q(eii!Jr1RWQc zqMt#7KGgj{&I=e!e=KU0xfcuQXXG&`G-^Q=bUpPLfU*MW2yQ%A3n+Km*}OEL?`?Wv>J&n)V@(EYcqj^4PThyK5dnZ6M8#}k|5 zF+DEF&cmM#^NsPu^{oHPI-ILB-*)wqW$>n&vJ`C9EZLg3tw*Z{>4L53R%IlRmQepl3o&-!QkM53 z=Cjz3@HBI&k<7Wvna^f@>8W+h=|ZEE=x=6z0dw)cjrqr!%gE)JFEI2y=8Fyez08*~ zm$>&b$7zlv{*O=|{ebo%iT)(z!MioB>OaN2hq>ruZ9|`SG@WE!onVfBLK6MgC=dNr zn#%VOrQT%T$6T*5%D=~4E=t0&FTjsnfP_bB!GO!{N4Va{gNp^90Qj*b+cRhRToPK{ z%kgtjXmu;s#}j)CPU!G~FZTr2366DrRbcOO-atpru0X#UOCM+8;d4~ZeAW++PMm3> zV>Gz8fa5x`k^33rf<5}|IX`93!*_)^zDS7v1LxuT0~N`zo+J;|Mm#8i*gxctm~Kja6o zpI|>98hj6zFXeVfKRn0!>kWRA^=~lvR^}Olvl}&L@J*~gVek!Ho;0|${~3d?;qp%n zZgKfn2A6sNdxO8t_4$XvcXI<~^T8w&d)PQlU6hqnRmX+)=02nm!>qqE8`JYN$9i=Fmr>luI9^ zQuJ+$K1k6ADt6@L21iPnF^4NsZx%&b-pK{o;`U2u-#_1b4 z(supCZyG;NjLS0bKf#>0ZI&waR*BBI29S2h4ZN~SL6f4%mf z;`SfGW=aX|hby!FYlxXX38|AjAh#Goqo{Chn+*0#IZ)0J8bv)mCWHO`{Ntkwg-|ke zKTEQD?ayIiP!fBzA1=-Id&Eqigw)SC{>vzYlBruHS-tp2IKIp?#BZQKGyYy;@G14A ztWIC%4L*+zB$On+ys>}Ovwy$QHT$L=s;QD}|E2_D z$I^a@GfA0x{r432UxFQ@{}S{k_R_C#Z^kA>|AEs_wVf9xmIJ)F3}p>Oew81mcb4)q^_tZLW* diff --git a/Program/libcsp/build/src/csp_endian.c.3.o b/Program/libcsp/build/src/csp_endian.c.3.o deleted file mode 100755 index 95892feed5fddb2857e6e9b4f87f3e6833a9d093..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9064 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 diff --git a/Program/libcsp/build/src/csp_iflist.c.2.o b/Program/libcsp/build/src/csp_iflist.c.2.o deleted file mode 100755 index a7ebd4047ac9733e340ad8e0151649ce1e934af8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14224 zcmbta4RBn=k)F3JtyWrjEnEJPY_Qi@0@+wAtt8vRzmhE5Yml*QOW5Y`d9^>%#?r3X zeJjgA∪6yYnI|Dt@@1d1YeA}&Tjl5?BfBr$R_-6>6`gHPk`0bD? zty4*{sP+e9)nQRx8>mnFtl?$8>iWeQUy2E9IGTls znpEP;l}IW%NCKgZ)fY{rh>N8{1NjuJ;U194_-d-t3!obtv$3liTPBrE!cWL2Olx2g;mf-u=|sjh{q!y#u@Ay+g3QczGB zPgo?gU^&XTZ8CT6MP2v_=V2rZ-7fccpe}j{E)Hd10#c@+0#jX)l|5NrTZwgl8}n7p}vS zb%4Fn0@rOfK^K#v!=Ux`R{-+93m4^_>j-vVDqO$23+l;;yMCV|&pez(KRyYhDEmHK z5S)VUi?UO2!3JW{I%ck7i_2VZ{t>vTfC|^IktF&zr+_Rek4J>-U39K=S|41?lz9W( zo-U(9KAuIBGM26{XF}r)P!`*Z7JmY?v|Y5M37ZwY^cawCMK>c|rs%7jAX8C3U}Z$n zvQvQj6uumXbXmDIEQ(g3|5fEFAXg$;qa;=#y-3lkk*-&C3(`%BZbiCT(QQbtQ1lw4 zTNK@nbbEO`b&Duki*!)o>)OGyP8#9)zrd*6IJB7{p}?X#FG#rD({Ka>fYty}DKCDY zpydmYceycgF84`5+!&A|ytv%ikiF&pzn5V-$xhv$p&g>X!W>p1bDu|Ah0OhDq$`yC zUyxQIb6-HZW)@t8TNudHE5?vavtk^QX;DmpWP*w*luV~$T$0(Y7#ISqxt)qBF>nF) zDW=pwhX)l?CK*dHQ;h@AGOU;x2Cn5h6f@J<0L(tcR2W{cHlmnIj5)v@QcSgR6vU1w zrq;lmc|b9K$(&G3on#(YOub}IDyG4B19YBNOr!MelwuYeRnX5%Vm7o3_k%KXE8Hh= zkSeSX%Y8`E-^St6G(3i*ErZ$nIn0>LeKpKv8E!Y|wp<*D;%rK^iP3VEHJ8ZlRvU;b zy2VDfN?P8@iw|O-iaeAfN3&$fEa}KH=>Hy&oFm+$tWYu=k+Sc>1%Gp37liyHYo1k) z0yYPECvgzxZI^6=R?N0UO__qkO<@0ldx6Kiwolh)WV{S+=#gI=wo}wvCr?l z>~6X3E74X}2_qB->G_XPQx(DDeE_PBZX-}_bmbfp;&K*v0n`q_4}=^;aP5K&8rS#; zHQr8*SFq+M*q59Pv>~UcLeyZZ5tK`f1c#_Ljy(jorUgm>mk<_WS)SN7)hHHXZEV0a zz@pfz(F~R=Pts@=3zFLwy#Y{3Ht@&izd|DOPZ3ee!k+^GgLa-Xx-mBAj4rpY%I&+n z+SrWI+Ttj_P;G3t#|&`Y#~R+g>kG#HZJ4=A!p(Rig9ci$koMTVPPy} z?RwQFL?aPukWJh!52%%}h*^L{_A9SQt}`YHzv6>7DJJVoWV6gL{OdN_af000NI@2&Z?MXSruX zIUFPi2R{lYg9vOGSYcDqQh}BGa#v|z|xsE zwMjV%IA2VXb|>dd!OAd<4dvLulzFmoYOWD`D9`C5I}I%$F&(ArfS6HkIK4SHXO@GT zE8tvRG2OVLQdzDnl$K|a1gikL6N__pVBukR zD=HIS6+|JH<^VV|t?c?paKCK-(R8Fl~1wjqKZ#b&xY8{WcEfUI+=Wvq|k}Y$C>*gr^}?>+szX?{V6H1 z0jF?pJbsQqHUZ!@$C=^57-9#BWh>p7Awp~_rxnVI>%CA|i-jfBedM^4pq%!ESeC%} z>9#Xra1&krE9a1R&zs3bLv%BFPZqk4$$JUPpAW2RL zNj!XFL2HW2UAf2I1i?yRl6x^kCzIR>NHNKsfE1J5U!GOP9hYUh>t<5El>pcf*D=YV z%^xgQ#Pc{7=#EKN1gBJ6?z#v_d5X*)B2=6GNk1no1P4eTFAvf#i!|pExFZXvB`+<7 z=B~KEIK)+OHH@#|#%4f)R^k6N%OhH!m@lG}ZRU6Pe-K-bALZ zCvK&cNPoPit~VT>D6*8bVPj^pE}R}5XITh9%y_Inp0@mOViF>4MdHZ@e;Px=00KAT$*iIz;T)dclQ!W!kL+Fc zh?)mi^Z|y_Rqk z7|z{SL*;O9_~ES~XYuxp)Ar9e>R3=d@_eXnq`=`!#z17I1ypT=1WMQr_s<{}Zys*MXfEvtz3GszMn34zF>*cIt`Zz3A;h5JG&0rIhE%IuFOgc*xNmCW@NO+-Y0GSTY;7obawb}|KG{h{8p zwAYs$6lOS+GQ-LK%s_%M=oGyUEWzHBnV$ZrF#D6?UBXQEM=%!YD2#{do;_AHEkIn& zcv?hK@geXC-KOC;Hh>|SL?V+Q=g}p2hX+x}1<;i7RxXbd#6Ydv(6QDW?9Zg-_;#n_ zR#b*E0q+N8E+t@i5P38y`^LEtaw2@=jIF=6+qdSbt9(oSi~aS!T6lSrh_397f_gj* zY$z4(TM28fc1e@3w%1p?DebET-&exQ1Etzn+6skt)efeTRy1rSQ_z-z5DR*1DZ36V zp&&O1b08T3FDwWngv^v#98Z{Vh)<~GGQ)kl>>=pI(B|?2WM%6hbQ-lFjM$bA4MlB9 zf(s2E3RE1C#>rOGg3>s1q=+%ZsLLs{#U1im8iv8|ib4IR~bc&IKq6iU=x8{K^!CU3N^H)ggG~qetiy=I;1Gr|K(NhNC=QN7 z{>ik271L|=3FWU`tTOGh`K9 zkx54*4VY}W64G+3K*u32uvS!pC>oa@?FRPksRu%o8C032HVG|H(RtOo97}qzKW>>Y zgYjFF37jk;)~{K!%vaOhlSx<^wZdu}Gm;DZU7*=t-?TuXVjA5Kja#<}W4O$iU0UQm z0=FQ1OqQ>gpqBUaR&Ut>N2|AD#JS$<`Vupm(Q)3%Y3|LS*-DG zWcsycOE_+W0?mu7R2y%1>4I4)dc zjK5&R=i2beHXQEW+NZ-03*-0GD{Zwe$fq$m zHYG(bcS&BoLsc#HB*1n8WM`>{zexVj^GmkhErhStl)BXE$qj5BU?; z@Uw*Deu0JkZ>4_sDL9LtCjOv?^S*bNhBx9wLwQ0~Svwz6zyG4)@00us8vZ5muWI<) zWamu{4-o&MhJQu&`C*;M`>%wn{|3m#;V9|fOz~j(+X=r#!=EPpb`5XD1p?)uhVNIf z_zw-2-^-!xzcl=P8n1)wu|EfhpQPd6CB8z#A11y^!yl#o>NWgJ>UV{PFDCh*hX0zz zwNu0A(yeo!hQCem|9cJR`F>Et)8x-%8h$15Pigo}^5;1Xf1UW3HT)Uk-_!6r$Qp01!->%^U#E)vY zMf`mlejD+RX!t(jPilA@#pg#F{si%_X!r{x{|gQOi16QNcrEcCYWPzWhtD+pbFu@U zg=FFRJw)=$G<-M7uhVc|4_h>x&(k++cn8^!YdG(NmWF?y{NAhK-yu5>YWR8b^C=C# zlJe>Y8eUBHU)1o0WdAk7ktI`xW>>9OJ1_5#V5*>JSK zk|uwa4M+JUWM{4oNBJKSzQBf~{0QLY_=5y6Dn|vwYd_G=plcymU;dc8E+w9=D_~XoD8s10tPulDt#Lv;EHTic){y#POC7^@l z6PrAatApgvY4UttFQ5l?ltn*lXukLj65{xKfb5jp*Y3i z?3d3aYc+Ycf1@VP=f;=~$A0%vzZnhxG2ypr_N%Fbdu;OP50^(Zd?&@{Ne$=w-3I#`MDysNhgggmj+f<&H2egO*K-k^^A6`1 z^Pkcz`$iA#lM6uQ-uZAoNDwaTX#MH9j|9+da$O=p4QD?FHJsPcH#MC1Py71~w9o5W z_|tm^;A;TXR!Y@c2l<0*IU8KRB%^-ZBjdC+|F8tx-z(5o}bNLhSt;i3b zo#0y$ykRG^(LPgsN2GxKjg=4ddG76|T8PmUMQ0x6K0t{{H`emfg{jmw1$LD^uDgR%Ng`j5r`)nAJ z+&|YXgyFj~dwHDtFSCO{bN^g#0gP?gMV}`9srHvud1N;NmM{LpK4q-s_@6B-|EtY|E_(~e=ospqq)qrMZDMrUevr-Q|B*VhqTY#OjsDyBBKH3q zfa^9<{-0<<_#A;47F`zK%jE0-aq6G-v46Z@>hU|0$0k7HSJeMbWNbz6{}E`@F%(}; zpCtZKYt&fr5Xk29|E)an!&K1y{~lmylgA09EdN8FJ_2+fVx0Tu`dMhmr$1ws(pbof zRI?t}r%7KE6D_2#K>PS-j-38(R0ar)>6JPgC z_wLhZRh6ntY2S2z)7{h4(=%`0dpfwOW3$6B1Q$bW5IK%fA@&4vbh9LzMWv_^-MfOL zp9e>N?+%V#f^hKAYu4Q0*xDybkQsgd9Rv@Zwp_unYdX)q5gdK>>T9k$GfC@5TRKq? zv@^?sqwA3loIcwS9D~0v3u%lkRR+h}I)h-cBsh8|xcb+b|2gXlj_&I`Tlm-~7cN{t z^TDw~v~VVP>!%kkOcz6e;Gvg>i#`fYU;6CXi-My+8+p?R{`{R_@y`%C{n7M2@Y^d@ zS{~mHif1oHO{Wl2rRDKfz=pgznQg##9F+>e@W;WC|Ge-7#%$bp7p|hE3x+rH`(}zr zBsf-3T?2SF1R*#2gk~xUI)J>_%*_>zO#L7+p@sv_OZ4aX#|5G9C@zu z?BU=TI1vdpD3`24)jaZC^EKDCTzf`{YJVVB9TwHKf%>%18eZe8u3wSyrI@gWqgjZk zX(hf~iKLQ)BoNA2ebH2kxL7JQkWaxH?g5F6uckV^1iG;?+q=54Wm?HJOeIyuH>kRE zqqkUy0?D{#x|Whew)&|piyej=afhQwRt2hZtIBX82$Kz$>RPxu9CBtAvbYhDf`Y<$ z!XlX^Yf;8+leyy{>cUSrk0M#jXbljR^5O>y zT0Q}Jmm4GJa*qSz#()&z#pTY1>{a(4pNHinJ9U4Ic8LBAb6ADUeI98QGWX|5S19?v zAgw~?zJPSiT(}6gFp#NNj3JpO#W*C>te67H1Qk;#nNG#HB(p~`Fa%h0Hz=mWzy;W+ zm{J2B9#l-3WGuzZG;W8MVa3cga4p}Wm^sE)U~W@Ph2aHjBZ|4$m=DYm#Z()|K9a~lgz`4sh7;SVwM{(gU(}$X^_61R?G^c3i^3Y%!78}zE@^$h5LRS zqzdZ;avxIkw{f^M4X1FlWiWd`hZ%FZFNc{d!|ev$mWu;XoK1-~GFq;(=3?31Mgwt0 zH{0kINy|HV@nP&!kw~ zcgbyEiMFUp7@;^wFM5!gst6Wu0Z?sp8-Z%0E9a09m$ASzpmsa_K*%u!*DlDQ35^d@ zq6S-ypj>JsI7GE^;y$=FEl~ovgs>3H^2D~PMzIuYV=JZs z7R6qUX0Uu=oJOlyklelOWq?Yufj_zE1rk|wnuuB!{u2N&Xy-Yj8)I|M=yLn2+`h}I zjU5=RosQxQ)y5us%;5G2=_iCAFGefR7II`<7$<6E<5C_FawcA&7$??%TwOdC7RFN6 zu2*eBG!UT%*~snkfQs3%f|2apx{7fGJB&4`srp^OLI|zI3l!r7W{e8$0(sv6aG`X= z$MTxdE}09`^l~)eh~a>o7;x#QBeoHO+$dDzdfAAnw!$>i!m<7#5C$>SRWxY~i zuY_awDrl3XiHT{F$cmH>3uA^+?Jf5>z4N>?jG0AcaF1|Q36Ez3K;Y4A;qSA4Uz5{I%71Su>In21X+F#_c%u*b7k#&S`i2$W+>)#z;o%v=C;s=s!d zAsiLQTEX&V45P8dzz8K%WAAaRG@0#lNnv(=(DG87ufTo*UD#=K&p{X9%px6to@!N3 z_q0}`4}QPMjmTynRwG!qji}xOUeAR6CEx*@LM)%?n9tKFS6FDu_a?$^md@$}yN>2}omcDV+DPJWsVDb}1lt4N=o6s!P;K2?b8(q!jfn0%m5- zbu(E`P=SDr@2^no%BR>hrQ&1MvmtgcnZ418P9|R=DRg4TN#;Ju=`v~ecE_YnUnB)K z;1urdC(jYcCIH-ak{KS1A@-73w$hCmBE+V0TA{4C-V24bSXe^cM@~8k%4tuEWeJR* zZab3(H`(RCat?X-yq;V%L^qRnXQ8W@yoaFt`M`>4l5&XplT07X8r#L>?KUx{@5qTU ziHA=tXiZVMEBAO4L9h~-x|x)3B>*5uo+^@hWfMOLvkY|Kp7h0}u*EDHgM8ISeH)0Q7jOhTlsNIbdR--qF{_76tW zibObJ)n?$5$Rd$w3}`r`pb-{^)0?!Ju%fA0C>#X|fWXaoGOH*_IESbAr%iazBYT%U zqGlx8lj&7jX)6^^^r8zOysjq`@3(5>i47`_#cD! zhV!P&p>nvlK6xPIEZ(zy)}h(Q981bao(|QG6gZs87>LZVfQqjJYVJoP=|An>`%k;~ zo-1(dC@>r?W%oPg!@R(IkAxKyrkRYzOiK)gA`pmPA>T=1WMQr_s<{}Z;|HQ3Xr}v; zDXS-gsu;B<#I{~(rlO&UIcTK>ys*MXfR>v96XFYjFeMMT*%L}fRU9Lr7ztUShUFrG zFIysmU{|E$y@_bV7w!wC1jxstDYHMC5N0e6RWjF8G!YT~$waRYT!1by+Q}4%^@n=X z(q3P3P?+IN$_yv_GXn|6pi}fZuo8PuW_tRg!t76m_X#uEAHi6pqc9$-d-hw=v;c86 z<7p8|#fQKnbeo3XupA7@BodhfIgc)FxuVKiMR8CU@-aX1Z1(zUjX*4Ovh4U=rB>N^A zONWM{Y6|I1rc?>6q`)s1=0Gw6+7^Ts!f49Ojwehw*e6uNnc=>DcGr6`+__uT=8aIu-t~C{V*c*FG6cj^oQUjswvm0+%Z-* zLck%2RxCa&11p!mT--PonI{+&(~J#ZBEa?%P!;3|at*3#RMiT>`5}#|EJc0D_(T}C zjPL-&ER)Ejqmkv9UYN6KxnZE=5Esa5l^}|?APHzsuy0a55TeYW%3!rsXqk!5tKQ{U z(u4hR%Y+$>A4n!}vV_>u*0#o1)7_IvSQ)jtYa23>3w$NeAgr069t$*Xs%s->O;*v=}lvr5C~V_>1sb4<41o#f{x)ttp&BD_Pxze)TK z4d*<&Uc>vypRk7ik#O8Eu(1Cv)bDKy&f;f?Kdj-r?|ogvS7Ty8`JSq>cK$&9{+ous zOY+ZX_@~7GM8jVvJFjSXfcW2OxItStKeY3BpQV1)e+A^?aE$b?r+BdZ&4k~m;j?Id zZ`SZFgdf)MLuBX28ZN(^L)$Mk{9PKagY2i?5 zSi@)2yxgVXAJP1t)bQhE=X)BSB!3>)@J+=3hlU4eyuZ-!56M2SZ;snu!r#;6=Mn#@ zhNp-xB0aYA&*bMU4Zni?S*YP<6bHYCzfE@5YWP>E-=Ky!k$ks?myrD)4ZoQ1q=xqs zf3t?Ci67PQ1H^wr!*3=2K@C4b{J4f+Me+G}4S$sQ7c~4wB>$3ze?<6iG`xZM-)Xp) zcyc^5;@P6=YIzsyfDuA<5Fb9 z@!a(!^*dX`_maXA!ch$EM@hcjCXeJRVrL+S7DQd$pZVwWE-iD+65yA}`Ap28A zetK*;wmn1gWi}k`w~;?{Z8*xWBs&XiILcR2elD@$C_h5-%LzvoMfqH{#wK41IG>NV z*yL%5&?-c?O&;w(PWG?Y@N)7eY_o$9=jUBE+;0B?n;je%f2293;Wv~0ahn~4_&NHF zCjS=6|Cc7e5_GVtIC`QrQaTAMufyMyF6Y4U9UT1}qMjWHXJ{qi|2qv1a!`v)}p)zrb=HhJ`i%R?F- zqkMiu!~dS}S2UdE-`4Od^5>l?@DDWnMUp=^1^#CZFQWbQyoQHq9v$=$i!sCTvV4(- zpQ3SjrocJxaDFlWDb2EP^w2)J095Xs59fmf;j)?5pN{)T0Np0nB@)zd_G3`Pc^!RK z!+HO-zu!Rnysm{my?+3{2S9D5RNco^D%v0NTljsUxz_t%1`TLa*Ds@FH6pt*mpcLK(??4pm6{!IJJsywpW0m~QvTYSn| z1-%%+_~Y8%X*#)yUTAKxdT4P76Xx3)w80sZ;15-+MMd)3E316uOw57LCbnblN; GuK)jBjg$BQ diff --git a/Program/libcsp/build/src/csp_init.c.2.o b/Program/libcsp/build/src/csp_init.c.2.o deleted file mode 100755 index c00bd4adfb86ed1bf93b826e324f9fd9aeb4c97c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14856 zcmbtb4RBo5b-r&`@~*5O^y42HV|$HdV}rGlY}uB7u!VnR;@S?z)DDDYrF|=HyxJA} zBV?Dv34~w+4unGasR;(A5D#ezX~F<)VjHJZ1`+=bm%!x%a+(Pu{;_%f^7?DBB#hT9r79Ds`ZMp(;@cVXR*@NeBzt}`H&LkyGNn{l zCjw!NYR~z&fD;B62!!;l!ra2<=1c$>#HC_xD_sKtog9Olg^X5IRHiZomRYb8GGU+0 z4f_c(;)g(1h9?}RTPS=KlE%KKwM=F6b}L>vt=A(@FIaNI3u}q2stE00PoYtqWaLPlawUY(P~HRzRbi6wLshObef-`-63(}0KmqeTAaJs$e|hlo`5Kcox52Dq>4kJAMm z%)%LI+-s7}0E#n%QNTu=5Uic$r})I`0!RV3-;Q4i6coUNZ&5G&wJsEZZb@(gBrQrFj37MF-)6g zzGIkn%{*k7Mb0lt=TXBf*1jD#%o1l3jq?*Vjrvv9oq8IYtBxQ@lgfKQGJP+?jbNdPtakOA6hIgb z>WtLQ^vKf|B82+;Nbv-9>nU@LRQ=r#TZQ@~$cNUgzXzv?A@45kNixC&NQ#5(a+4lX*UlRoEAiD8x|#+b9glwI!lu+ zHnRCSx1gLhD?jI$b%n$xL6n-)`gsbz<=?rh5(hN-LN zYgT0s6KBIP+I;f*9Opu3$vMsif$%9xo!^#TbR^}R|JMK7*3LjUGRmTtuEqXzt@bmU z{mg}aCgx|pM2s@EF$*=spBy_z8M zY>Eojt*BmEy_uFv1>-d5m8X#ioy5x&Izr$;gy(6#s>!LYhL%Iv#9Gfpb#-lZO?4M3 zRudRDc1vK*RG(UHNrKLWT5b2Vk}2AK9A|SA256YAI~z-#7@?`84|WnPfS3&FHX^1p zIl;P;n^Unyo7qOCk)39vSL*a8ieeQVbkjRcI3%)W8h|qxpad9T21;?}Waq4D#=lvW z+P_Gr+SG)Q19W)Kj;b}&OlBd5%y&26wwBDD8FflM9*#KY%y2ri=SV7e*;t z@E-0)^zf}EbF_AdVPmuuMmrIy?wp44+Y$7tX_-1>iLzu@>yt#I1y#8HZbO!?QYfH4 zTV|p;!eC^KJ-aRF=YJA#)J{w4)v2K!mb@J{s8y(Uot}c|CAWIe4ohC_LE9~Pn+NT%r1hTs;!f{Y&r}QF$IZPIa?}pb025N= z(^7v4>+JQ$tU5I&r&ef$g{n$($%uEec5eAJdt-&dkuihfgrG+nYP7rg+H*eIPc9+h zfO?sJsyWVwv^_c0s2_YZ+J+ygZN+@9EtTm@7ZYyVNY~QX($3a&DpMS3?avh3dQ*kG zB1tRImme}3=~Qo9e_!8Njb&DLlx1OqWD0IB8SitY^|pAfZ$K#;Czi^j3ei6JnlI#1 znf_QZn=7P}DK`-vKoTI6E5v)#F7b3`74{CfdDE3IBxr=zB3&{bl5mqm(~~w7tuX1C zvDhDDilR$pJw;8@!JFTkkGZ*AI+ZV&K4>P~-eSMeBGw~}_XF@=+fT;QFi4Mnh14J% zCVS|(Jef+OgXM-O#1hw+&A@%`V@28*j79c?BA}lcrYMLC&U7XZN7hsXc2qdQ+VHB~ zt!;~Z{}%tKA{hL+Dp2R6`vV=$mMy!fRRn^U?;@x%9BrQx2veEl;fc!7`-y=pWlP2K z0|fLIlPVS)iYFGU*ye2%Qr{lxBR7*YM+wS}hDj>sW)j*>qLXeemdv?sEa&F4#T@1w zfyD;nBPyAW_Y+Hrz<5$D5ii6SFVZ%z$fXLdwpz^OQ~en?5y6WgIH(eCz7UHi5@g@l z>URsV;t=u`%d1#v4B*;XZ$Q+TB2RLA++1E2MliqGoXWYwseCG%p0)+TDD7*mxVG&Wsk#Ws4L+o}QS~*-U>#Uq;0Od%7HC z8e%bw-LaI$_LZPYVf~nd$NTmahhn|)Jn`9N5`(~63RS0dGJ0;PSm`a5PX6UZx9GyR z{=xvIC`A-W4y99t7)^AFB8DL|*_|q%+UL^f30)MJ`J5Y1@OW#p*)(Q9McLBRfqpYx zLxr67gNwiFq?4G#&Jwb-$0z|2_U(Vi0@6O`Ufcc`!exC z6SkQ)odN9+hC|8dsp=ws2eSEsCv9BPIm+32hO3KW9Wm{G%r`NpEo4yV%J^LprHPD{ zW?5ULB|!=3SA*`LO}hso+9o+6q=s!}sups60Q!j`Cbu`r;gZCGz|c49f1 z2sDOy(W<6yw4+|Fc$Le6Bvm4p8m7gla}%ST!%!{^e0LQ1X4 ze1YnktJHx zX0ps-pqH3VX9Bsz9%UwW)MCT7Ys=qm9kFaWVY7_NfEOy47{X2!yMih;dxi3hnCjHt z>0N<#3a-pN%@FyG!!?o14rxEh?4e}1_N7S8L3U{)~$%l-`QKt6pE$_TNf8K*YTB( zu4sGb0)zTqL+raiIV1JX^qNrkCOS~@ICut5PHOf^yP4>AjVPtxdz@ESe{~>mV;wzf z;dRCq?$d8;*4Nb!QU~w^kiJcf*Mf?EijUKRI@@DAf~sLGNJ!9p^BC2K5gUE^v2%tw zY*6o}0ITTR`ZD;=GPqj?&zHf!RtCSR41Q-B{Ad~cQNocQ z`%B8cQGB|L{EKDqKbFC3c+F7vsMb;jUrjjtd5WdI3j35@0$tc0^-g3C-A!Aztvzo` zY}>|-J2qSxyYRfVbS~)bQIB{~H*}2mcne$~XyX{>aK`EJ9%6N7?Q=iwcs=mZDbwr<#SYQv!<&dklk!+E zXpo1DwPV*4aO`y!Ur96?@X7Sg;u`@{1CDpO7Pr60F)qEu@$g+lqd^|~ua%Dhq$d4L z8d&3gJ4MD}hh9&4cCIWVk9CJ8H+0p>)yaUI-83>S?-Dxepkd-iZXciyhqXRiaqh+ke)(l-1 zFah~03)0=ziM7+rc9!|%(f13+?TaNVkNpm9gSmPBJj4EP5%`mA=ko$T!19+0d?Mq0 z0>1$PQnU4A{h7!1uQJ`9Ka<$bwE{oR@;3|oOPpt057z$Gm}qK`n44$+M~t5k_~ZI# zzEVFGcq9A&yuj<&&g%m2XZ{0$Gs}O|QL2Z@Z0AxQ$NGPa^KiMqA7%L~1wMiEaIL_v z;enqNI6fev{X*b*9yh?_Sby$gyjI{tY^Pb^3C3Flely!?7x;%Pze?c$%6N~!Ut|0- zfxpM`TqSW6uKK3HUuOPJfp6q`yId}FFDCFencpMu=`4SRz@K5<=Fj@MlJOgb z{0;2SVS#^{>-?y|yIB4afzM|Cq`;4Iex4QhO2%In_#15hb%EEiKmR50-?N|?pJ1^yb#FBNzL$GcYGU*Nd53cQW&>=yXF%qIliVZu^bfj`ajYyM8Mbne{7 zxV2~FTEOEzAneRx`R@yy-B)i3{Bz8IDDXEpZy{E+6~Uy;$H?98bT%ZC>&Mzmw;Ezrb(fac>a#MQs1Dz<jgfS-ox?_2>gD=e<1J&89yQLhZuiG;MV__7`OS~$9aBD$TO=x7V-<(eu!Tzzz#(0 zbNm#6pJ4e}jN5qad9*^v+vnGH0>_`(qHPiQPZ+;Q*zYsqYFNnsf#vrL+&*uAUD&Z- zhwm+eKOyXNb3UIIxXbvn!p<%1=N|-a^YgL5z2AZSBhcovlkH3u_!`Dr1b#l_9Rk0E z@imOwI$6!@WwVfHadnB1-^zJT3;esR@J)d)<9+Pg0=K_Ijtcx$mj8jkdwAUA0zbw3 z(z61$_FoiuH_N{!aBKe^fuF(o`BNGEV}a+{PX`I6X7gAv%3s_ znZO@p`-w969)ZWXezIk7yUtJs{&VelTNeVK&-sw@Tz0yCct{Mlxj7*4rXR76EBTY#b)TV+ zbuym+zvd4`JupTM^9SFh|ER$6#=nslcsup`o0PqbI>#G-{$itL^)WuCLXMB;A88Ys z$9VkZpAmn7WXBtS7mwczW7IHy4gHhjUqcwiw|)|-+xz&qLhUZGu&l54eiO-zr+@1- zt**{CH}7io?EMbb_XLgCf$>HWFC1;5|VV1$qQzBW|B!Vc~2&94S5ivL4;0Ech5|dneItH z@r%U-y1>>(;%uZdLt{KDcJ%TA$-6TO74q6*!A36`Wt7yENIQ#;LJt{n2vbZcwMT zZ(D!lgY{ScPw))_)*oG_t0S*GUIpTvZ))_KlSfYFV+C?YfxNIlcCSC$VmiO2K_27r zv!wUPnIF)IqaN$jZNtDHhR~wnBd0%g>1C%}YcwVL9$VJekU|%$y}86ZFX3 zco2vY|2&c9!4bz%1%eNdq|vWwEmPjO#fq1Y?{UcqIZKW>-3_v$EO2l&T!Wubbv+GQ z7Hnkph-OFBGkb$!t5jt?n^S?Knk^5g%4{a40yi4grz(dsNfr3KW_{3CRTjANG7M3j z*oR)9{RyC&*Kjeu1dh@0RVwiM7g3KQJn)+W`QLZB=x-kascIj^g}^#8U)7$(g&LS8 z?LTzcirT%LuO}km^UpO7UX+i&@Hz*++_9Uaqugwl3|H5b}9+EToheVqYRs4nMMuUGubjZ+WiJskvi>go#F>Qu% zG}CDqpJuuYQ>K~qhAG#~7Q>9t%nri@ows4(PQ#3J{sgAqFjWp2JY<+!&EyPI?_7(P zeTEt9(Aqs@m~qYqFozA(=zIiiR~zO$rv{?~Ff9({$gPG6YvxYFv})#l z!?bDUA;ZjdUPPZ0hMA{rJ878t&S;GDv>K0gRdJi1hQ^9J$w?E+yNG1^ZgQ8W;a>8# z7Ss78ut0FJ9~|v0WVT)mgwkwkw8^3kY667RM7mV0a0oYamxo@d>GMcto1}vKQRxnq6A7uk0~h*D!mfub<;JSzUjl|+lz`s{83;aw>txdQ zB8Vya@-is2ypMi?AoUIeX+Z~qRk-S4wN;0YVz1W0s&1pD$@E-GYZI*Mc|@C>t?nS& z4siRbd#Z%oCH17&`XJ)ZD_p_G#k&Vm%j-If@GkM zNX=xI9Mw!N)ZT-RPoh~*nPa4C?|9gDsJ)Zoq5Ia}MW=`%?=1-YQ$gUnB;ex%%p66b zuR)VDsRAyWGL{A7^3$KQra-FBc5K-S=bQdu&HarfUa`V+uCSEtvhEIaIsY2KO~@&(T#cwTMetj3SM_jhaD?hA&B=ye0y?G4+7US@}viFuh67}xOq zV49unuo-KC40NVY%G-igU7X`BRQtb7;q_BWgbh!^t;yaPn&{|h)hExFwTd>9@GUux ztDh!A_b@z@q>M@0E|uvqMfae48q+rA>#o?8Iml~9b&q!HM#X=XOV-VF$@;l2*^qI` znyD`7ztAN|H@jp_$R!(+E?M8=l66fkIVP-}I%h^rL#4lFVojY>AE?Dd`3<v&!9>pkA|KIL`sGb4dL~&h~Lu{rRLGs}0JLBt$mffN^|{ zH+92}tuPElAoK2>8hA#6|JN9D(+!nqV| zyMt-Bl0rW9w`E3}BaU>OqtEUW2!bw-+HT3YF0{>(w=-0x-f^~{qsvNlx*fMzQa`8y zcGNaYt|~}ba=i;}v*ach+G5FVF0{>(F&Elm$*;N4HcMLT9o&(Nf=Sh74%bCvFNNR? zi@TK+`D>w%bFV{O`&Gr+b7E?R4zf^1VJ;bQt3yoP!gW!7=L!Ww=M35m4Y=h&!FJ~< z-e+g;sW$W}yQzxkRQn8cRs+ zt`Uje5otJ^4P< z3#>~R>-))it-m)iKnigynM)3m!O%wyyL*$p)WC8>aIwI}(kU{Z+qfg{Dvd_A10LY9 z#Uv3Z|72(MP19~J^KC10{MEtwOIljzdVcd>FZ27KS2;93eDE1fF9m(#VDQ2IjhCR5 z`TVdh)$05*dod=c&ks&2TQZ3vDpC7qb;d zlr#*fNFo*227~TRWFozpL?V(&WYhT!%|5vp8I0~zy#vucum}l_C&l8?Ty)-Ct#fZC znM-J``BXO9mrBG#^va10RPjVM7m3E>(4ST7Hf;~BTC^y%Fg!op7HYvei&SD+Um}&r zBx7JH(Uu|MTNZSLTKYmQo3o)7n7#~Yk4`PUTQ;o1HJgjZcC`#;(z!$|m(D;UlTP(% zJNpv3NPdWBC6ZNn9`z|bRN;k;y!->c82t2Se!_o zPC6OlNQB02Ux2YaiLR2gO3h><68WJ>Pc#cY-P=opkhUb{w(f(_V&1VN@NP{{?CyLb zpCH@%a{UNV5)>qd29mi5k|+s}Ns&pU4wX$FNMQ81PB_Y{Od=ZR@w(IL0m`f-qNS&r z+D$49$U1L_%&wdXmV&3D9Zw7x!)aP#{ZZIVAXy&WKalL}NAwS* zqJze5Gi^Eo+8!E?(os)UC+zJ{XLGK!F-gZLW9OMnof~P7X!9eUiJ`ou2D3Ynahs!s(2>32Mb-tC=$VL&U;58gtR5VcXI+5LA|Nyg{)JS zB4g7AAz8a&l=hVox;Hx+$^u6X}8cV4}4T%R3cEB1Lo9H(GH_ z!Lin!d~zU8ivuZx)Z`R4GniGq8J)@G2>j-ex}byRDxb<{ z6LGWc!yU5~kS>w%YTc?;i$k-w_vBN#yxH$t=H)flepP#CxUFN3LFuTZGTKziIdGA3 z_SHHQs{+AeIA-bPjeeVi+TO1>f!0smsBgwkt*oiN*0-{z@oN9Nnvn0hnnnOCYl5V6 z2eqT<_d}~|YOkmXYMny{7B_hedMcQJ8|#jmQ1!O)|>n4Ht*cV9^jZ}OXWnZrSFe)rW|p@}T1 z_r%T4Da|p>wJh{pRj1xQ8{!5#?@Pdw9@}5%0kGBh71Oi51fD2?XG`FpD}f&?f!|gF zf1m_@0yz0)pV#br&7YKz|3wM>4<+y_UQ=iuR+>uS%Yl_sWft z&1=_gTXS*b;+5SvE8I<16Z*umdysp}MgSjku7EyITu$FWxSZ$o)8^>g9z(g?HnHN^ z5qp(KLT{GD7rh^&hGMtEgljX4C}wwxw755=I7|Ip?S4w*GH; zeFUONJ3nJ!Ek6OYmAC7d^my^RJ@T|ySo!-r_#_Yhpa-Aq!5{YEQ#|-%9z5j1|CMoR z|MMkqJWlE|5?4zTV0U1`@e)!!P9O@+H5H4`B z{cN%OrPVW;^({Px%Rw36NIwSR4)D;>)9&sFR=XO0`Fx!Ch#}N zL6p3yT>Z_g|FFP^SkH9={}Ic7QQ$)yXPYNB4zKcKyUhoSkLLyYq|h^#$9-1dDYpM5 zfnUM;&j{SEllKMAEdNuakPo|A&*eOhwe#QDp4|c;&Gvsr;8h%l>jZuc5B!Y4kFuT@ z1iqig^|4*no(CAO7WlKQr%~W18E+E!t*oa_;GblCsleMAUoY@(#&-&QEAxjX&VGJD z;EUMK+XTLm^X*=NzsmBD2>c|=|3Kh-dE6fh{2AtdC2+eBz9sPYS^rsq|CaGew#&}f zSsr(Zz(=tBI)Tq*`E3FZFdq^4$2k7G1iqK;+bi(%nZH`#x3K&_3j9XS+v5Vin)Cbt zfp@a}V*>vy^QQz}&g1?};J0ubekt(vjGqyB1KabSz&Eh|GLDm-mkBIiC-6TrKUv@x zv-|}Df1Stc6u7--UL)}5n7>HiW7y7!z#n1#0|I}Xal22resTP-74k9Gf3v_(vz|Kz z{$DKr9f2RyX%licW1PzLE*rSI@jUN^G42>%FC4p~X{5HnPY_juS#_tpOw;BIu zfj`9flLCK~@#h3??SGkZyN+JudHl7Ir*KV|0Hl5w{mvI##8_Q2=>$qe37;ie`FN+YQ~!dzM1hw z0*^DkiE*1ht9c#m5b`Xpb_w}!**FXQLGEz7z;EV#;5!1h&j}|4zKr*oQv&}6kNdp9 z%h~={1#b195%^l(-`*9t)$j1avGJM4`pZk;RRVvW?W`?A}GSzKn)b_&Y)v|8KzG5%9s2)h7D!U5vi<{r^h{DrgGqyjhK1OuS$Lu6ep# zl-?IpDt5VuA!gG{P!#)~hu#@eUp`j!J6>v^$vAHh1nDwb4#c>G>Arw;{$KkqKwqho zhO*;dV-t)(6e&y3ImP_{U5KQW+F5UE@}Jg&^uHUJ)JZ+QN-uL!?E4|Zoh!Q?4aNG; z!k=xa+(3)LQ>5$`v=y^|%RJL*J@+O1$#!W!<)G9_T^{BI-$sn5NZFleD>nYEJihHu zD3}_7D13tJPX;t3vgsRuI>k|2g-b^XBHxqi3K8>V^oN3S4ZhWNfwIX;tWw&R&dX`fj!%|qdeQyuK+DZ=JWcuBJPO{OLV#y05P<}>k{BYy;Y8UXG7}oR7 z=xe^}i##88W<2^d_P#grhBxwhr8ncTlI+yTpZdCm_uvVa_uz5&!GDaT8oWL4ECl7= zo?{E2N&uHtW;}YRGV=Pt{2IVkKoy?C4zJ`-mlIRWtuqH6o@NyvM;*YZB+O&8$_6fsZ0 z1Pc?uC*VvobWXepAV?&H6H&$mWG0Z;l%*$luQ^s29Uw75_r%wr^u%5ek9^Ye*M%?& z4<1YKMtYmQJG}1ZaT(v1r1W~XJ>Tq&c-@hs-W^rx2amaNY=7^seG5P7OL^KGsY>^5 zFB`O7j%V+7Z${5MIJuOh9PBw}SucCHl?^J~_GQY^gYP62ZabWE#Jg=%1~?yL0VZMT zjdGlh;m-r%?cK2{y*%>2B)+vbawuc#N-z*QHWNA)M^$((PSKI)y^*6kmZfjMa8Oy~ zpM~2uXH*_M;f4kjZu_>d_v0j(g9?v+gniueo*F=Mdf$&OJmd|B1MOX5Pq@?57z{Lo z1D;T4-sw=DC%oVy`IvJ#^5ID6T5cy82Uu^2l+}=2fEredD;RU>%uMAj=;t)@Ev%5 z99(l^`megAk`3?dfL`k80A}$0>*>sWC6bg%^9WtAkEYd>3Mv=5rWgQ}|E7&TMcFC**^ra^xU9kqL z7!=qDQdj*RAon|PP;E)N39C;RN$=kb=M2P?PDIHMeqy8l^B|BS^AR{8I2g?rnZ0np z0?MLxTpp-wN@mg@{|UJvfQqEIkRVJ&dXRO&4-`wZzFvhib7 z=|WigHtDOgfrQWyqCR>0NuXr~$upk8VnxryzHupf7SfrDo_#e0Le|jsaJNXF(+jvq z;d8NFV~2(}isX6Ni0q+3Am<~Qqc|2IJxS3EkI#lvT156z<=f!tP4B_-zs$xOYGWjy|pvp|KUIUr^ zDl=8u)~hnpt$U!JXT+IME>dro-H?@fCpJ>K`zJ^e{Zni%b;B>PwVBYJ%K=Mv9dSYq zr#m!Tj!;CgHzoR8Mu&>CfJvN7JiOe?O$G>x63Ww1~ zN(U`KJy098FE0XQvg<}TjzKH#0%EK@+yfMpd<$~Pa&}5~;lz~e8VpD2aF%)Q_VXaHT~9O^nL`|*2Vvh3Z_%EcLzutAx3fttNsWT~ReeLDe> z9g%q_dPk8z!3(4!e-UN)uPDO<_QiDYY>f1D&yZ{vOil6vG-Ui`pj43)kWtw?BFoeIy zDb+anS1LU2YP_`qPPG^T=@6t7ki}Xnjj(P7wj2V`{r?Fq-9xfy zAInNxR8yB*Y&i1O-~p1g_lz_)eYtfWI0}<$%5saFavp-#DyhM-`{MI4i>d1jXbH%V zw`v_5;8-OaH&GP|aRn3$RlBdBqZ^6C+S>(dWL2Bb!bW5Ick^r=^W(_G#CaUQm?q)D z^2v*jW4E2fV#jV5m!dYu?##)Od5MLFVN&@D+kCt2*FxjQ0@HY_F6pFI=juBXyZ}_K zq^f|bl2o7eqtJ(z_f|yLYc6#rD8>olM$fkBIOd* zy`yaZpo|9(kgUCz5900^WpwW-+rz56M%m%XdG6jkrA!D^22IBp16Qlzgb`QGK5!`? z8~{GmCYR;|m#lzsRGuFUgoQOinO-0bz8n3)>5!!;Yw!19cAtV7>uy|mVxlaMDazu7 zRx9NuObrBs!g9)Gmara{D`H@qj;vPnF+8rqgmtPHPmpHdvfuiwS7t;sc5a6d*y5JH zu=2qZDG&tlcpi<*15uU~5+&o7LA+LD7}+t2dcPu>Y5nvnnKCI;pBxek#<>=P_zECr zAsN;2bI>sYyoDi(v0Q8AM+>onxvJ1A=vP6M=Rx49u@yvdl)Z#y#Y}E6)`O#^7HWf; z7Gdiu?i9>jhX+X3-t z9X*(xFomm9QCH9W{leibSy!FjiO)f+PZC@Zb;e5or-E|q@>%hxtJ!FRV>C`P&MIJ? zqw;saiO44*l8MBd12GqeJf|y&u=Y+L0=KF=sA%4;Ox#7p{0D$opo?uxh1Y|bm>3XmK{M^S7$+L+37opCWdKI~f$=&4s)GPE2dS;>ec%yu@lwF)10t-w z3x|QJ*Hh8FTbS6##IKlmjEO@;6dqyXO(N#M4}=%Ho>LmvGtqhpeNswg^X3pyl!wFu z-L|zP^U+Wch_!>OpJy9n8_mtI{mZK6Uk8=XzYz|Fx4{8ZKQm#uCX?m0He#)8W)Ye> zPnwA3cF5v9{R3dcSpl!QwGLR1+ojkgy{gpc66!vi^Hbn_o%F2NIvjD-4Vb3)Ux1zi z-329QhQyV^<;iw=#)t4MGw0`6V))Q#*wA&1EL7KhylEvj2OY45iH?f?Ar0?Z_GreKe930)m2PvMYo*YbZ2n9y|d$dzxw+uq+&jz$gO18wxmQ z3}_miU@b^P53x@?IUsj7C>?W#HDRP`#@IyJjB|6Xg(IcU6R`yQq%iB&qLJ9r>_odd z2lUgp$QBE_uK-HMZ-<}K9a+1J;7x-G{WW-GFXTi;g*Y#2wgUvtXFXWQM92uGbW&6X z*(PgJP{?g)vsWZ6{7muIO=OzEuUHaZMLo|CRwK?>Y3El zSH)3Z#cKJ?>c4NRuV#{UTB4FkU43;N_0_DF&m$5Q1-&j4_>aj;2vUw_0Y0#ApRh^=cile(_@0d;XJEU|*gVYaR{OzOH;#OQjP?CG=Zs$??F)>Wgr zEP70$qEwrulF6vlMNxi5-Q!f}2j~o4&*TdP#qW9+{EaPG%jEMmRL`WYD>fQf7yfF5 z$r4pevI3YinACN}1_No1}K#RLd95P#!Urq?pb4ONpa z=bno)GRe(XjGW7{O{--x!?t5JlWdxjRW?MAY~Ag4rBzI_Jt$bUk8|=}G?0g2VUq2! z#2O|)imGFBtZmvFCUw(dLn_v^>UgGA+onBlS6a;^+k)qvN}T zC!9-d!Ad5%CWu8=ABl1?$<@S(SRNHC?TD>oGC+_rigQ1+8Ecs2D?@zixrTaMu$D>I ziGsEJIM)$nWb%hLw4BKw+fXf&Y!8fGCUw(dyPZwD*w$6WBpZXKRmCx_D%P~sv8GkU znzlNgX|YoytH0GYZ8i0)eTrp?nX+P8IF@WJH&O+A?22NhEWW(|(PpV*^4IoC>LMn2 z=^8&8Sl5@fu39D^vUT~H)OE#nU#zYw*2RKOv3vh!yRAgT%2l)6blZj+CRr7>C-%A# ztE--MJz(ov!=$b&cBvbyYX$4N-`2I7NnKa$Quj0RFDr11pct}A3?DX8KIq%WIJeR* zLSo33(Q?MQwhU~&&cFq1My6yqX|1rUFx~zYnUrO>rIN{N8;S|xVN^7l&M9E1dUzSL zyf<0ncD|SNY^Sqix`8r3(m~UHQ&I(lDH=aaOj%2;HU$Ctt{P$a6)UyoyQTcGQvUCj zx+qpE<}QaFb{9D=&J~8W+)6CT5Q(XMeP_mWpUDWVHI3xE?eE*SVs%XZgdjETaPCNy zk;!BI7&*7dehN{?BtM`~8V523-#xc% zuT(Rsn-V)S$C^?f&y;%Glqc-Q)-$Qs5IbMT*03U84J+&#xP|ZxgGp{4`hA7nSnhXV zWb#UCzeDV9VOlpY_7cG6y+-WLiL7p?fHa9c|LS{)r zu(8F&`aIm2xB=@1nEhnv=xsBMMP&f!1GW^Z3L8Z01HPDpXf}RR*>I#Gu z84AOWjqv1dICR)ZQ=l1WSYqJr6=nvfVb(ShI0y=c8`ic3qIukc0Xe81`~#NAIOj~OxtjbVtQ($fPI>;)WHsNn=_P3!N46<-*JJtdkP~fueKsRRLhlEg| zy`ih6Gl*Ge9+v75a45@Lu|6;hb1m%+jgW(g!Q94hpdp&Goe2>9B#jJfyPKN>LCAxB z@Lr?}H=vvamUCpYa3omk;NVEQDd`88*+&`IxP5cyPhIC4I(KPa&jr^Ou3vI$MfrnI zRJd-gKRxH#JY+4C0!htD&cUyJi2#u6t}A!lIc(0gn3YV3z}CxArcOjJa@hx;$`9nwR9va8y{%?wg!x^{;P5$=98!u6iV#DN656Nv^z& zs}MN=2W*cs-L+(H>rXzLKfho>%Yk8Y%CRu%4tde z)6%W3VdZnyFVElGvSO9%z?=oE4=gz)tEx}Bw?)UZuT80gT9!%VySDGZ>3|xh--&lxW_Shs3Q%=zZy9mumz>1 z6Cz&tLl8}2=yTE947;*~-`~~HG*tu}*ZW(8AsG;`w?J;}68^Gf5TT8if*1yh3`@V- zS|$M*Obv2JlD{hu3_;WfU>^?-5*VIM_@)@_F!Pr$D_$yfL9Kq+N2Mx}Bg^013LD7e z_ArT}s9#wjNu|u+-mp7K_iKd2d!_+BK+lF9kI3V?PcZ6Ekb-+d^7{LOYDs|y7 z@T*;60(PSLag50pD@{B$K!cobzz=e}8d_Xdv1plqT7#EDt3-Gsj_J-Icr0qEaz+zu zs)MmA-Paas5W&Fu)(~!vLoG#hix!nugNL!^%R4&)(k$GK7Vh*1aU+<($!Y2o@NanI z+D&1Y9nmT|U-;Vs>jQ0I98N$@vcaK-^{Tzdgq_sb5`cDr*-!^;DU*)3n~6udx}1UITMfEv;Ef*HW2O?u!W znB-MwgT`){T^d4=?`&=k!5fNbxSaK*Oa}%CLJf_Lfi4WirU2}(k`*fVs(o?-q6DZ; z5$bAd4f`Q}Tfv*CQ%dVmxWNyb6GNa0f_j?lgv#n=wabc^m5Wg8<=CVqc_qQfhAom! zWL{BcXB$RrtJ>9wz6En+Bq67Yw61Vas7``ydH!XUr4_Pz6|&?oe^+NnU~zHzvYJx= zh2FASffZr|``1FOg9DWgh(zqN_D<*k0UO6Um9n-@a93kXLlD9biqIzwo7!5}wLpkm z-qFw=5Fr>ats!V57^WgrlCm{uBJTN=!$bzxEbJdJt~(^4MjZAy(i^*#<55W9o=mAZ z+Em$T*fVMn!Zj7tw05Au#mg!xpmk-X6}1=)YG9z`6n}wVy3ntM8V*RU5KQnZ4bpvB zB7<7i2VI6+ETPG`PEn)Lj^@@5v>p3Ub#8$=O_5%cK}XYuqG?{6Zub!Eo8Ey0p zXBa%w8HBPR%nyPG9P}j4AB`=S`f)?8sv50q>hz--a*7gixXJ;iHX6$YEh;N7^>?*F zz+t3zz+|kZ3XDV?88s^^{52RoGUjA}H8r>SLuvqUx2t|_0vUM)l3D7Abuf{{&STAR zIm1a1_SFgqB-rQ-L!`5Y9l zYZJy&QxIYV2d}ztU>HTOjm_X17$-2{zy|HS_CQl>LtbEgLq}dkV8imxw(j;o-a5Ei zLB*&6E=hT?Vuh~DTie~*)`XLttb!*O?wRW1rHZQE0_TWz@GGVG+_rC*Tc2BT|mS(&?K&|Ahx`;y{5E!IbMvI{*9DaLUp}Zu0GGiJBZFfgEmx`{U z&i7(*aq%2aPTg9#I(MsaJb7xj%oSW+Fe^8I+Ib4aWjVZ|rcT1TyjoZrGp)1IlU+B# zia#6hv#Ct}K;(62Ugz+-vwEB*ZjWQTI|~4>+lBHa#3x^a!O{!dE|ld*iq~N|u=hBy zaI=&v2k1(~A<1n7rS8ld97XP|UCtu6XJ>-fopW8H*PY*!$%*fSwnnHh8@p&!BH7+IyYT>-NBsxl39MobV1G6n{ay z9y((i(xKg$KEMO0y%FuX!CC6|>`Ewd=j==@apzx`s_&!p^2=U~g7S&U7R zef1*oEP}i!b7$4KJ&m#u^8+LlNf7_+i&yN#TfaETskV*9lsMJBUL2er0vRPvyhn|b zoOqKNCpq!nGEQ=;4fQc4&e-n@NFJwvcTD3Xr;Lo)0;j-Nz56Hi-f(QY;QeYyiDE^6 zb{c1iqSL_P?M+CD;#LDchww)X{9MAnG;oZ6)HBHFvdM&p415aVI}Cg#;XgC*d4%^G zcoE^B8#uyFwdYfE@WBVf5G}6c+yWTJJB~{;;cw0H@b3+P-!K4v=K%OU1K^JjfIkB` z+Rt|LtA9rZ;D2WT{8Q5NE}SvRITFra!(Y7iV!vX&{Hg_Sy&460JpRc8;H9J|mwpf9 zJtGwZ@HY*BUq*WFAw3?j8`EaO`R7DAmjaHj*2J^(o&oURk{)FV4q90UoB{VJaS`;bA%+X5e8a z9%kWTHXaI;NP$#C%U8TU$G!PpT)wQxTkc=BXi-gRt-sb=1WVlhOJNk1YgzkFnGki4 zsum;KqmxE;qX$xS^NZ|?i=QdL>Lhj%F7McoxBvY=B6ugl>lDoE&p$Aa4+71H9V{ok zpdNObk7TeSRIMC^b=Y^S`klA_{0A!2*6LUXW#vj2^SUJ6vm=Zi#5*;l;hREgO@|q} z%Zifp`~<>)uMqg$64x^L;U`S+hPOVOfLjncV}NEon>2i^hCij@*&6AK~&`zD-r{TE2 zmg{ZMa9z*kgq!}kLBnx=U_JQZK1`;6?$h}7etBBM@oLR_{`UZS-q!e04|QW-HW~;C zPeb63^(-RXw5Lkr_h|eZHU9H7e2d19^|Jo$8a`CR@6d3a|85P(H8|^em~hk1=QSK- zmHA)R^yvEE(s0;ZWb+@_^yqQBgsuZvjCy#y)N1%}P0t#_O*=2waQvBy?cAa1!L<(K zw`=^k)?xg#hUaVeWULSp+Bp&anBS-2<2AfR!}WFrH5@i%*m|xe98bD`uG8=Wjep+& z_@6Xc5f;b?!Jh9}cf6pP1dxKG2gHM~K?^>KP7;buSHsNpyVvfpmg^yuwU@otym zTcA!h|KBNJYT&O?L(2`kmGo2@cn|SkWZ?VB4~+(1kB)`ZtxmQ*my-Qk4E$-*bG?Dr zlRY;Zcw34B?lbU*X`DZ5;9nDd(7Myv-%ozV^)x2NdH%Z6z+Wc+TyNlb|AC3$OlLj!;sAm4iou^t^*X5EnEzLV z4>9l$NzW()KSua@27Wu~nQq|t;VMjC1K&pY1qQx{@PL88NcrmxyqMZ~i-E5uJNFs* z6BM7nGVrsg-p34l5&8d+f&Y@~J!0TDQNO=$;Qv%^5T^`$59v=JIqsKjgmWA*-bwQ3 z8T`K|`==TBy;N_Zf#XM)FqIp4FX8;wG}k+d@Fs)*5yHC+d>Pq!rGYn7oNP1jdDLEh zGnnhe?|5Ol-{5~l!Q!ZatIuG;{%ZptLj85z!2eG9QwF}5{3#ctP#4=XocPiyz8IfK zd49>1arS$*!T%cBUtr*yY2I64;M<6Qse$jMe7%8plm7z-ewh5g>lwCl4&j>({*S0% zb{hCIr2mHoK8)=Dg@J!V{m3s{bG_#hf3LxRF8Tit2F}kEc)i4W4wC-&4gRfU=P3h! znerCZ!+PEz+-=|<@;}cL%>Nnbhn>$dG5!VVnQq{}rTBpjy#4sslOHM#e4b(x7aI5* zq^Hrq=Mdg$;G1cjUSZ(;(*ENH-cJ7Hbse{hBz&g94|~C7ns4Cq$UnsfUO?lb%)mDgzRbYKlAbyP z|Ay>YW#F5sU7ZG=P5ucR_yasn4V<##fPp_p_B?Okrzro5fsdtrJZ9kg$es@kyo2od z!oYi}UFs{o(fRW?|Amkj(0vh&XdzLnZ_!oXi5dpIt*e+QF)Eb<@Y6I8d0K?dGTaXZq$e@XR? zGw=_IzreuvQ@!&I+(Z5;Gw>wRQ)l2`65e3o7g4_5z)Q(Ln+*J7vVW_A^SbwD1J5Ua z-f!T$$e#U#V-}mlzf&AB`12_LCk-c4WDopB!|^!=&oBSbaOCIb0v~HQ^7DH8D-B2f zU%?-yJ`G3ybu@lcF%Tf(3Hej0T^WRPyPl#roTBlgp4FtM*uZ~Iep_bXt4Yr)1Lymt zbq4+x^<&7uxxJeWd^qv%FmP_~Z3g}hb;4bQb9?#ssmBd|z7KjY4l%U9Qhw2{&xxIc;K&>oSP0zkQj$o4rE$w;QU;41K}JG^@?3=GjO(lkAZW4-D%+5 zFZUTZ`+vWIv!92kAPMrs2Au&(Lt>A4K!pSPe)1GvN=@Bn?OY z+laqF!;zow|7Q`-{uxRAL;N`Ipc<{E~(vKR*xrTEmg`O5)GLALAjhANCVIMZ-}KzfUz! z!;zJrKi3-ghot9H15YJ?ZXuk<`$&qnod*BAXdI-w41OLj_iH%zi-iYBztM0#t`2B8 zvaToogBp(fJnoJV&i0~8~nsB?l$=O zI{q6CM>~H&c0Q)zXeayOpoSy=G;}Pa=Ll!}y$Tk8Ht-7wKV{%;gs0IDoUG?6!aaoB z{Yd`LH*o$PWv+q$hT?pYfxm|pL0V2Y*URsxU8eD4l{Zm)FE{W{3GXrRUFbYWyAA#P zobz6TKZma04;lDU!VegD2jK??(Epmjznl2qH2ANkI6rRS{Dlfe+3cczk~SaX#6-7`FdSPIJy!2{4m*hk%99%W}ShT)Ag^*z^^5IlYt*4 ze2amfP4o2*18*UGkAd_2{!_v^euh!JJ!$Y4&^&e6z*iIgnxTiko$;~3j~`OT^o4;x z!SmoyRnGqWobXfwpG@O$sDU>Uezt-Cknk~tb9>p&LWBPZ@#FVpF)=@X?;>FEe@grz z13!!6a+9H_ocw&Nf%EhKUu!tVC%;#GP{T0}x09YX44l91@v(vP_gqHP1_o{y|9)0t z;QaolpK$J%1=Ow<1Al?=%M84h`ulPN{|n(g27U?Iz0<&7B>ejZektYepfk7Y7&;Hq zV+Q|Sl<;=SK#>4;VPVU(!1O ze%Qe0(>n0?1K=+k_+n+gcx?du&j!AS_}>`-KW^Z8#Q)&{_(=oj`>f9gz`r%{!xTRb zdBgi`>wrcG!Rm=P<8uzS zulM6@fRBo-!>^HO((oCS0P}-#kqiG8w;exdklO*zCYIBES_+M4E;D%x zp&*|Bj@K!PZRj9K=s)Zu(|=WfnK}Uye%u@YX}#eXlh+SCCWdmaj>RL?_Z{|k0#7{o zKhKilB43^Cqse;-l*DU)*OmR{vHiS;z!Hw19-vK~SUzYr9^oB*S~sd(EbrA&5U>6_ zseY~p>&IIj)BiUDhV`5698DWIZl^c^7Ma*qKHm;#Jo(=)QvBzulYL}4KHo+1HUklV zBY6{NImY(`ftV5I;yB44Hw3u-EdLM?@%*=+{O2Nh^dBynS)TnGuWrY8?WMPpVGFf0E5wb#%Wemw=(QM94Slmz}!Vp|g ztF|u{t+rKbtzAT`z8XZuT3gZ2DlS#@ZAG*d6~wJI?>YCL^UUSW5ocq7$ zoO|xM=icW&%bjd3DO=*OEWybVi$pZXs1UVRMCk%a7Kk&%Fi}(G>;9Xo;MBo_@GxIb zB9>e^M}#|k*UduuMg^56P6)pxKU6Lm!{%JM}HpTB0^0WdAI!Pk>8 zAsb*{q&Ul!-|O4f*Oidp`|+8+o~@aX37?33?u&dNwe&sT^;cle^7WKuxf*;k(xhNG zQPtV~Oy&V>ZAKiGzJm!_ShrMN(!Djo@f+npE%Xm z*Oz|HE^w*o=wq7@-1bW3+tSEuU3sVRuZ5z>HzX1HdjCg5v46VXA1m8`Y#|f_e}X8D zob>ga9j@P5=>o1}L%ZJ_d*wHMk>|tC^nFibICvv(cq50)z3Gn>XQf2m?CTQV{l{G1 z{U5sbe>8&hd%NFT4641|M;1So0LGW6?>kT)IlTYFG368!zV2u8d_BXkVUfe$$l9#5 z{U46#J~B3a-{852x~@2Nz~$ZXZg_nDsj|pXY2mis@K7+&;zp-ma}~&byu^FzpcNh` zOTt5_dKqq1k+=Kkcf~utz4Ct&!r7XxQA(m9j>N}PdP+RdytP>=jZkZ1y13q65&8`GzW2qLc47r`69=qZkQE@`L65AD2p6FaZmaq>r%J? zLMt%VLy^-f6^P1wwr_|y7O-5nQsihOF@JO7FxwydP$R?jx3WN9jQ8m4Y2#Cm-7X zUQ)r1gUK&>cWgDyL;jnKmx(8D;$ z!t-&`jy&&;9O_w-wsY0M(#U58JGZ8n??2{-HWcjmuAujL5==)0hd#m1?*2dxCJd4T zkD@ORc*Eg9TW8o4?(ozH19jnmC)81YQ2>DEy09l0xVWn&7zlZaDvM@JpX%Ar74{TW zm3ubTg*^2gZJjNxfdXF``JJ8$!Zyg8dEixoB1 z^E_1mP4yJ3W2Zb-sZ)7S=9aX2P+)rPR8Q3 zQNV5gkGeeZ3?cA>Cxi=UJduV6J$;ZA%{eR=W*m+I@|2)XE_JdbqZ3P<6L10GaL5Ii zLMF`wBq1TOr9CVZGI>7oxHO(!TTvGNg!4Ki6J1Gr;55K>9~>P@zoaEkLS{K~!k8m0+}+T zr9mXUhsLE1ZH8lpQg4CT!=!h}#^b2cg|KvJ(l?`kgwTMc_JCO@fR+^uIOiEGR`hJ_ z8<(QzAf2J;xmQ3SWDaQycZmV>dI9$+d_J~o{E+ZwF<=2UB5Ozx$c0E|D~?4-PgV3{ zr1KPAfb>j7dy$@_=t86yD7pyg0!0@iT|A^Ec(E8zg0xTJOMU^Cl~W7<;e@8RuxYZH z8Lrvc07ypH+=nrihiq)A6E11Ci-h`S0FUI~k-X{w=1;C|$8jNLlUJ7louKIR(ecVf z$!laMDBQm%ncbCq!8v-tT&*&h*3F=;TV+OBcSB}}%1p3!1KW)%GtI)7 zyL|VnV`yAx= zDB0Oak5lvK-W zm@IpDta5SsRBTYj-JoU<7g?$(WA83NWJhG&iQZAD2| zD5>P^T)>%W3Qmi0m~yH$ru-ipOj5uhk4||^Al>QeS zi+h2F%Q~dw5~NiiBricaMd3@4PE)iGX}6+FkygQyd@fGHLlwRZX_~0ZkRGM*^N?0S zl)M~i6(GqgkXAvFT#mH5vL#mx0h`s8Ex8gW|8k|L3h7#EYxP6Gl!3?t&{&!X&H^RE zx>?RUNMc%|PQuzV1y(rnsSj`^t74+H8cx+1 z0cjAVlaR&QAdRqY1Ga1e(Ea}jE!{)1XdlZ;TU1k5T5LG-Rp9}WwP#o=o4(ST435I2 znzGX3rc6fAS|c?$c3*HdW-)aRgO-5&M624d362%AaZ^;G5SK!+P__F`b96m%SbI8Q zjjU?(S=eYy|8AbGV}2Z&m^hE)7t>TcSU!32aqPCUSnSyC;!@P+*qt#=GM{UqVVG2Y zxoy7P_G_SV}QPxmzSbyd>;)fuJ2sH$b&eB?w^<;j&2u(RdX^Cqbv`{PD60Ok?Yq zMn5r)PGH)^bD&IESyHj0C&&m;bfI#I>fX_|e^ADQ2T0bQO9paxj5fM=wC!QlU8C*r zT$!FP4Zaus z!Ra|mQP!TTV0NF58S7qLd19h0k15LHg;p!&Cd>!~gTivkWtOmhBUi-0HVav;=p%Yu zg$e6qFPw0{uma+>62r)j zN!0rd$;>=WuaYU1GPMIjV$lTGVh~>qu-gM00A9^9(e z%#n;+QQVy6K9E)8EEhHDaWLsSG8Ozd1*I{`X-}Eb#x)^ci3dp5o@;GW+IY%UrnGUy zC{wyn+%#n~2xEi$n{ZXl(^)ar_(MEEvi6J}#7>ybRjH_}W&YE`;cZ!0joyjRL90&? zoF8?@%K)c?YS5y8te(2x+`S> zM*V^DIti+S05u1xt?Vf9i1~Oa;PeR*)}F;f!PMD^CLUqp01*W*G4U1= z3y%Wf#jfX+%JodKUPhmkP}zccL=@&Cu}HTqKr){U0fAUMxcUXQLAKG{4BNk~YT>m| z`NA9EP;fgOFr8*5EZ1bRyw+x{mCYoTqOE#^|g7>v6jjyQEi@8eKx& zXLEiIoQFxzMyEB6 z>ptE$%*TZyr?c#f4=%D66jITGEc1GIMs6oGh$C)&%#E zRHyq)_aJNVfDCxpjvHo88ljpoK2bK~ ztQ>3c29|2V6Hib)Kl4PRX41OG#RjW?&%eKQfEph&WqLw z^H>hJ?=&ATNEG?fn1wTefa^*saiDV+r-Hu+!`*oS7NW`C(NtWUx;hbA3Q=B&q8xz% z(C${l2cAnu0f>k@Y4MHEi7;8BhRGuYB?!1x+siqA9RrL?B6?(9&)T}GnS9fRRx`;8 zQGInB_0>_uiemM@v2|52$vQ1j%cQQpB98is{?z}{R$s{^>$F5Ule+rKIO;1+^=Bt4 zayr@1Qm_8S<0D=O0AFbE9$pSb$*J@(Dh8dK~VgzXThg! z!D=QC+fXf&x~|x0U|rAKf)z}%0!vggsq2aj5Z1-qmZ)S>7mSUDE?Ont$E!tA^DvP| zqR??7OW~0tCh!-N=h;vdljSy4&ZOUls+hdThH9AnqYYJk#H8(Keby^%_KKeO}dVm*_6Q7$H@+NP~%Qa3F&q+(60jAvSQlm?$HY=i5*flk7?*t5ipiv6WV{`Yc;lHIoZ%DCVNg4{7$1Zm^!o#|TmuaPG+{ zBa>`Qd{bjIgj&d={)x?Qd9u*hb5nID#7eUG>&i%$_ ztYVU{4Dqe!8k%jvY9?7H3Rdss+!awqChxPMl}!HJhN_uldtmG`shbwt?QB}7t*e4b zHU>?rh+|qstZ8dwO{<7CZEZZ$Vy8w{|5MwvwbZZnDVAlWT}DJKOU%Vx5fp>B zh%<&xkq`RzGS01Zi;x(6S+tySt}Pu~uQPA~n~@ zoJB>sbWR3C)x*n}<-N%oxAQAV&kyM=neL*@gF0y1Z%V3wFh%2si79J|wWc6I|Efky ztc#Ue_phb=u~PnjEww&YD&{VS9k!1g7v~DYTJ9&70T78PeSITiy3b^U)|y80-S*Gy zTd^7@A0bFhJDmG4%E;u`r!jJFgZ&huhDm<@p)~eq3VsHL3GSnq}4y~l*)Lf zRK_u-GM*`wd)bu5wpS{d)J=(}b3emP9Fw|Dv0cuB9IKY7U{V*14OA904n)D?+;Fh2JtX&`$So%=9Xa*bpinpn8#4TjutBAz zu_e%u(~O=9Z|Mw#6d4M`j*alNE;zK?NJF3zXjq}*?iFSRr(xDM5;zD7hU+%82BLY~ zf&n?G9{dBA$U3niBw+xBwuJofflO;lD6Gm*Z$n^1R}*BFPMh$zH2Pan4hC7cr44HV z4JdGNSD*{C@FF1;XshdN?g(NQnun!21RTop7OW4 z-RE6Xu<_iJtIHmGe7WnU+Eeqc$wk&uDUj5dqcj4?F-vb@~|_- zwEzicveFw)a^-GbgUAzba3qD3oN2Ce=eOMT#lnU8i<&bYaX2E8XsJ<`ppD~^Q+4rgL-y49w>7aE?kxW^Z5(& zUE^G@cSF%%E_BPmfPfeN5Cl^gx?Hq0!lo?Y_jlGc%n-r)jsBKkNX7$fEs*=V zguiqJ1Ze$5Ack=wqtdT-mPtUyQk~q8Q`1sQYrJd)om7yt#wTy(NGtzn=xH#+Z1dG2c*8P z_E1YxJM43U0W7eoQWuT_zuFWgU?Z9zhZwea>GB#+(cHP7**UXv@;uYv!?gCm!lpob zAlOn5S)7j+!n`=`oSB|!O`d5hLY`^Rn1wJqg3z?a^3ozWhQgq7T4%5$3>&gKg1`~% zXm1jJWhDybZ{dzDB$gXJ( z)rnwWV@nA4-JzDknk7q0DxvqVRhM+M2V|3Rqg%McAH+Ro0_VLM)1mLen>TC;!^DeL z$*IWS8rT?U1>jRw_<_!VZx+N=A?p0gxpvPdlV0(uMb+)#I z{V+CKz?-O3O6w86$q)M;L!b!;%uLw{<&`U{R}`%%6QPz%ut^Q_B88&{c3(D-d4(Mv ztvDK5)P_m)Etn&t6ggECcZP#PbrS6O^RFl`SuU$r!+{*;@9YQ(EG{ZrQB~q!+Uwc^ zA_Rl6B?N5*!&HPyQnm(7#Ob%g}fh*JvABK2L$@hBv4yQkC~ZK~`v z>?}3F;c^XXTH4Xzq7}=RL+eUQmRDmisDXi!)BX8==|aC2YB<=nLNLLvG)VVhi41C4 zA9NY+-h?LO5=f0kJDOYC(RS=Z)w%iVG+la41|3aFil#Ypmfb@z1MpHs1|hCb>bk+67mutCrdeI(UGz`xmg&j;-LXP$B|y&e32h_)hZ^` z*U;fd0XdlnIk4o=P`iy~)k{jtO8lLz5E>X$?Jy;)L5(qkFfcffGH4XZoXQyG+?hc1fe%^n5iiqJ3M-YYy{UpM8nhoyR>uL z0u3#7xq*#!?YYYXn^tzTcC`g^o8YPDyVROw+Keul%fBLjPEOv; z$qL1_xqvS-WwI`*6xQYp>&&zPt{Y+1p9SbBDw8jXyzY!^9bR{4x3k#oaopn01iKJv35D+L zU5Q?I-nB_y_nhtl#qI*fO>W;(clk1RZN2+~Vt4Zrcjq!d|LC4m?9TJLvq22RK~13> z?o+Zs@7q$l5Le*2#GSDV?Z4LPb$ehT9g;1Oyzsp??MWBHgS?QiO{2gMnB;fIQTs}4 z`=Da7uiRbk*zcZG6l2L8kZ&M8^{5Q=T#xO%&Ix*UB^0}}uf=wDCppe_XM=yVHlT0s zBw6|T1l_mX4Rw-I-NxPrWR}d_M_A62xbH z@rs>zI~XT9)mE~Y5~sTVi-XgHA)~~J_pNb~6K_1@Bq!c)#z{`K$v&pU8T*?9lE*3F zyVE$y3EO4kC8xm8zfVu~Fw z*th-gW4~g({P_iM#~KZIJUgfLgO`vVej_dCN~m*rKm0hC#nXQ=>G>_as`Y>lOj`-( zSB!El1^fs7=)rHb;_3e_>EXA2axMiuhx*~ixexur-{tY^=VOHPGiu&RaFTF-vMuLK zYye(dQxm0Tt?RiSQxkmaRj}HgUrxYwF8>t?En$KylB2=v$g>~4snffiW{!j=i z)0Xa72W92L7xTI#-E1R_9>iNLq~Ujl)DjOfbbAyf>A?qtftttF){N1R{|Ed$5+?cM z2$08ToOl&sJO^k@xCun(pC?hpk2;yZi0}kB<6O`93Jo8t;SGeNevgI+2}eESG`w5G z$7}fSG(1bgKhW?A8a@xk2`1F9^H*y4Bq(G1FVb*bPlRyOKX((3{=|8J^*o^I(f#u$ zjUTVd%>O|@{IgIoBs>j>jd0TsJ2f0%A+bIGrQx{dVEld! z$2AAzNvIeSp7P+2@r4>bMZ;?~e4>VLA>3@&Ho~!8uvx;^zgyFz`{(-_p0Dx$svrFC z8a_kgPp73H7UydCNDUva;cGNJOT)t&K0(88B;0K8j|s>2!VVO>y$@=7^!C2ikDm86 zJ-7zte)+f`Ju{Mk2@=}lfj{OC5{`b*<7B6X>v8hBhR@RU{7H)+JsyZ%uJGYim7UUv zN`Z4K{0*k@&ntDto2WfFb}%viF)35)Z~1;x&Jl_WHZT!^{P@QSV;B?bsV6;Z-5kX) zbt%3@>SXi(h4Li^{x&tV%)mQHPlbU;h=09-4<)?bz1_lPCed=WEUq$$S1OEl}*NX=J4fXHq1|Fce`N+WeI>+}(++W0I z-~Th-N_y5)J&Zp|e!%rECdMnt{>u#fF!^V@fxo20#q$Q9MD2amz-Lmu4jkx^xL)45 zG}yp>q-V5&!)7y?CL1`fd-?jv`V*;MufhKp(!={AnEzA40|tLK`E$F0@1=I$Y~YWQ zKld8=eu~eZ8Tclu_YngxBmW;Ta3|$oGVs5VoktD)GvzjM(!hT}`V&Zw{ct_u83z7) zlAmnglgQ6A4g7wpx4^*HlOM_q{5it;y3h8UML1vg8GoE`{`{D6_U~nee*AqcOgjv` zklK5Tfj1F9e~--iA69C_A%ovd_PlN2?Gz^;8h8Q4$w>qMisFGEL2G z)4=x-KY!xM{I8My`3C@sisJ$l* zJcsmKbY?xXDDO6K5BdL01Fs-Iz;0!kSWh+OSs&xW$PU{tn@<8+bLf>wgUVTB`RG10PNC z#^0y0-!?0Ei3GBXar{|KOk)lFDZ*zP`1MrZLIW=({}dVcbu=zY4gCKQzQVw>Nl%S| z^L)C-z_%*%MTdc3N&X2Ncq+APtASHiJYnE3l0DBG_&1b))xfWyemr8}-;zClGw>J4 z4__I0FSSek@@{m!;U+y9WEc12CnP`0z~3Q$_AB$xAikLf|2&GH0t3H;`n}A+e@ykR zHt^Re-)P{6$Ukic&g+${4g47O*AET+GRog;;AfKlUmN&4!)`il3Ved>ZAyZ{QD6JnuDd{5e%jKQZtK z#Silpn*S4aXZ4m ze@=QQ7`Ttxn{VJlIZh1xGU6{a@Fc3Y#=vWczs|rLDBot_%g8@l47`!-=k*%+Nqe9Ql6+f0+6-9QhAWzoei8AmIu5Q>b0(gmb&zqBxwc@uQwcNl%f1TNH0A44gk! zUt{2W-`!;3?~@-w2F~r>YT$ew>M?L`@9hSDlse&V!nwWt{^&7-pYMa7)o@hNLVkNe z!*xIZNyCxoa6IZ0}p{NOouca>%E-n z{gZ|x>8Exb(QxGdHSzzIaE^!1i2tlKV1mT>5VC)*fsY}46X6^WwMty>&VGKzz}e4-416-#|F(hiIQr1Q`FYwG2F~-ofL|}f#D3%T$#BBi zKRjN>YdH4HG3u8|8jfAWew(i0$UmO?Yqo|XKiglZ;mF@k{7W?)`Pu)K8jk#r5&tT} zxn2BT{!)z}^_0;(zstbc{@V?l?Yzgp*`EJ4@M5|S9VDFX;qMvVG5Gm8)rT66?K(m2 z`n!hfe*03xk^fbSlYeM9^52UFKuW@wxR9`ak)PjZq-wbC=V2O-`~zuz8?WKWKN9{h zP1SJZzn%E=H5~c*{(KJM>>vIO5U;_{@7tDXIO=D=op0dygWs6^hW>}h4_h=GUDhGF z;lCYdI8Lb_5&sW09Qkh}{zo(%`Pa}q{IZ54KR*xrR>P5X7x8DND~0TbX9%CJ;i!kd zcUqv~$a68x00QYXgJ!*e%P;e2*-p5J zaPCLGFU>RX0Tk!+4V<5!E-~;ziieeibG`ii*u@$@w)aMA?x@IA8Jimg?U(MEM^i{&^Zdx}LAsHH4!Z(a*mjJJ%aHuVb1Fyo|1Yod$jl;ad#+ z5aCxF_$ZpMdknmp@LLR==l35G&hf+VSDrNZ^J$(sXy9uJf6dUtzjtxm;Kv_7#`Kke zKhE>u5LM3p{F3k#1D{6YaEO7|6F$nozfbr$!nwU{XMw^067l12!eV0nyJ%hw82q0T zf5^bkq`2H-=vhm8ZZq)j5&laJ$N1#$e)nrQ#v%WT$r}dFzsGUh!1*^=#;OmW?RI&o z-eLpi?=$^`bH6O2b~PLL?+Cxxz^kdhFEQ|U3GX)W3(4+X2L2-9-!t%wD1Qf?xxe`R z$0G*+-IVV&@ZV9M&)nX>6aI?9pG6*+L-%2>^WBo4?{yFip{Tpfh@1}Cb zuP1z}f&U7F1=11?N2nJCA(d-5#t;8CM5BfyKYurVG2v(@UJ`g++SLz!nSswIJFn~q z-)7+aJyxV2{6+&$qPV@KAN;=zoZlzy?FavffuDjlW4gZ|{FesK_e~G?gFj*5d2}7` z?FT<-;QYMh_x<3n7&xzIUh4<{vw`2Dnk(Mx2mjE(bBX_N{op4I{0>_0ec2EGoq_*> z;>U4@s)*x|aVnPgiA*CWO~>~9MrMj)@;8qo#yvz}F|kO*XW+cvzQDkbQ~pW==Xf|` z;Ji*tqjAag^79Rkf%AH!*}(bvAzvR@4?iz`!rD=`n>W3-AER{FxSVrz(Uaevgh*Qvv+xDX(1RcF;VHmot>bwIe3{b`;Y@_(PnQ zp9sk`k;V__`E1rd6$()2|EqjH$fC~a@TVuPzYGISOI$ynOQ4KtjZN_Ph{-gbxy_7)WLjPeOnf|K)%+v{xxD-F$hqTdfjLGW<9uq^k&&J~s>iZY=cK}a3 z`LE|larw=)qSVpky%6Ad?JuCsnt3FQ?dLTFLL5KcK$|+TeDYj8!oN!!-Z@?HT2 z@#^oS`nevgA8&a~|K9)@*3WhVDbu`#>U<~NuM=$B$~ON13gXGXxkO2v&4P4hIX>S_ z@&=no;0vNrz;X;fO7cdS3m3_MWe9NlS^n2R#Pi<{@}G<3(SNvPW_k827Mpbg1p7zj tQSf(CxLm}!#*|0*8X+zPvzN=0NHmli&5<_6lfUtDCI7TK*+*0Ue*wY6eH{P* diff --git a/Program/libcsp/build/src/csp_port.c.2.o b/Program/libcsp/build/src/csp_port.c.2.o deleted file mode 100755 index bca6310901f9291b9c937585593fd5fa8c4381cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14704 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 J6X~qC|35m#Q7`}i diff --git a/Program/libcsp/build/src/csp_promisc.c.2.o b/Program/libcsp/build/src/csp_promisc.c.2.o deleted file mode 100755 index 1a5e4c6e7265b67b95a5a36bc95ed6754c7c0eed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5080 zcmbVQU2IfE6rQ`cKMUKI)&@jDvm}b5?%fvJQc$o;5E>Ct1JM^RcXy}TD|heR+@D%_ z5Tfxn8Zky=NQ}sXKM(#qm}pFlKBy!{6GdZq!kFNT527(@A}XFUb7tF~?h`lJne%<; zXXc!lduQ6i+jrfTvn*jAOKcT$$go13UN$FBC~-pci)CVoEkuXHdF9qKXC_3>$|KC> zx>eVqyS(nKF0Jdt&hF^+!&Kz*3aNnB)4M^T#b;3L%y;Dz=yTe$8)c==on8-OSN;&R z-A_TIMm=r+u{KHmT_ujPMG?$`3aD6iD=e<&BVd;#TamqH_KVIdgO zz*1mbgPZ~r8gwYIQ-e+g_Gr+hz`Yvetvg_b`!!f<-2-4+gB}Yf+|;07fmDM_ti7O_ z)nJ8n6@VieTxx9s@UR9et@|L_BO0u>d;m{qaJ97`%#LbMvJL=vNdrfL;~JC|cte9B z1>V(Qy>%FTKG0x;n%gHDj9L+l^QkC+Uf9RfGOVY$31ZiFxuZO72I)j>mCKEj}?PKG_mG zFUN`W9EIiwupAKG-x-I_Rmk-G4GsPVU>ib5(Ym&tLtqV9SN9DT?7mff{g=W=tYme7`1x=r?{wF@!!CsKLsz(NG&MCg;-*RwORwh2uqG1!kRx3Rbcy<>9(bueKiILAPNpSTl`97AAf@l(iy$^LFgsTimv3Q*om+>I@Z2 zjWi48mbwgO>{kJLadmnN6tgroQY_Vrr8|>i2?pN+B?YI_RFZnt1EpphrLvkvG3eqb ztP9K{k&r|qs>%695N>ta^FvW?$eQn!<%}1WcgqL&MM2h(<$4@tVGU~GrG6Bap`=i* zawYSFno1$@W+>HG4iGL@1Hg=95y0TZmJahvrlUAz6qb4}9@ZCEA&9C6u*Q({0U0O4 zZAQ?{El-rCus&0PS5Kg>2^1Q)MiN(XTewhyhM!cOD&!v2TKQv86+}mc^t0HlVzzn) zwDd4{jO_<9jFdSpqh8Zc&cdW-Qm+z76SlR9+(6FA02UmzkOmrH4q2Eb5|$s93Z^Yo zkuVk9JZ>|{bYgnzsQsm?g!MwJ3an|?r14e4dLIqz`WiFsjyp>2vJu^l!e&*wOAmT$ z6a^}%+RHj6wI*0Uv18k|&Bbf?Rb-+01y8T@!N$q zDm*pY(ZK5u4OiNrY4_ObeO;`vg}O>CQrMz<5r>4WPoPCQTc~5K4Zq-4)6(1eple|z zEZmB%nPKGlvosNr$FuPW{O}pjotg>qA5rO+GyX5a@F7Vg2A$9Qx7oMF7AI7b-2mhg*=FA+Y$ z_~R7kZN|eZqMi>KZ|eRzD8;#+@dpWyGyXZk+Zq2Wje9ra3l!gF{5ymL#-Ac=#y5GLBmOaFzn0=Z&-mYo zKhF3wgx_NP_cZ?x8UH%PIm!5Y$^JXWyTt#<_|GWLFO2_^`16c6`y)?!Q-{5TS1{hx z|4qgxWd9!H?|=QP-Nx1*P-N8)i;`>$Lic4VfHIXKaz%BRY~bl-fw}DsV1s`hOu%pcvtRuoE5z5d_`RS+J9GA~BxC&E^O&f*gU0=o z>`cdP_keZwedGSp7ZVeFVL0lI^#&a@iRUCi^9nBP1l)3=aX%0(U(323oM7o uzevIH9}sw#Ght0#ahtF$rsC|O{bTMkiiC#G74L!V{CAS$v&NBn?*BhM^C)Qm diff --git a/Program/libcsp/build/src/csp_promisc.c.3.o b/Program/libcsp/build/src/csp_promisc.c.3.o deleted file mode 100755 index 611b04f20b55638132c55d0dda0fade020312038..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5080 zcmbVQU1(fI6rQ^`Kih7SCI)M3t878*@7_(?Bu&-SXs9*x$NE!Ie7L>4JK0=v_ul3H z#MTE}6o09xh*bok3W`2dd{B^rC@2bwsHG1TL=p5wLGeLFYt?gR&TO(L@ue3sbH4BV z%$zfG@66`V_FXsSEK8Wj65GTAGOQ4%S1rhsN}Lq^VwG573(=u)Ub*!wmTt=%xg{Ti&aZU-={L63zKZfel4K&ruc);`c2 z&|tN734p^ITwrYl@PGzuth*uFgBq;2d;pJXaH+K)%%0MqWX%D1UIRygV;Yndcuj*L z1>V$PlXVDu-qB#Qn%nytj9L+l^Pwn!Uf3_FWmsb$!z6VnUqX@OmoZ&hhF3A$eptfw zz;)%H1=NGfi_`AK#YGlZQ?Z8(J1F{4rM9Mhy@kA%Cl|>#D7haEJ08I?wfN|Q_*hHq zybveS^At4Sg5`kdK4ly_*CEsM7c}@c0NW5ciq^I57X;RTb!p#V!R}kv*M9+Q)JsI6 zuniy-gG4Av$7*5sT~oNWFg*x+dKH*Ja@Zm6-YBrk4_bC#p@3Evz!kkMmvOLONw9Nz z5MjXtgy~t<^dNflZh$ytQ1%Ui>ve0PFe5q!I9MM$+h zp8?8=kD;}!Gkv|#s;>vU{8l+j;<6uBgRCaY2gb+Tv5`{XhuMKrJ08`Q?yw7?{LmGy8_mp&jku{&#L}y|GOUTjzfTf()AX+GI50$2 zHuuJUD&2~gNChj|jPh{ZrdQhp@u1th5UiQTV#l6+#i^}Zi(8ygXQ)_eq**8@>N1qE zUj^vJ)!7NCUukTlSgIFGw-svf5lhmuum6~ys%4!ErO^zhn0ph z%*i+rZZm>rVUeONg;kmfym|uFO`zPkL6W$No5O{AH2kFMR3Z1E*2*7)svtTlq@TrZ z6|>bdpbY?X$Jl-#!$_IqV(OI*-riq?T-6O?X?lzjlz~y z`#=wRV-y7{BekP-N@`88eqzVe)HTJ+_f@hm&GfD;ZO#-LzJGY!85+4lvu$63Hh_nJ zhxqm1Hj)6Gn#<8}n(7Y?SK6Ri?y=STx>REeb(L76utoP04hdVIKudJCP{-IZeA}(2 zrMLA#*TPC@--NB1VdTZLG!c=neneuoHrN`FNbZa|H1gR#COm- znDyO7b_0wr6TX=7M=8!#j6Xzpobk^Q-p=^nY24cwKS1$a#=lKCVEk#q2O0kx;fEQ2 zHN}61@qZG3jPc(SKF;{BY5pe|f1Kic%=o*={uJX~;=g13rxfRB#-Akq4CBA2IC;{W z^}UDiYQ`TS|BD#^Bk@--ek0*g#=lGUH!$AR@i60?gdbu&OV(!3JCo zgah|5-Om~+#jAr;^HNVZl_U{PECbI`cTm?4XClzyebn_Tl~~TVslC_>>k?eF1>B~k zks-Qps!^jM;d`cdP_kx0RXgh#|!BbT2Lc?u$f@-<>579wt=85yiTN0l?e$RMJpu{kZ z|0RM&54XiFh}_U38x(U?H~W9;Z{pxNznp(3P4r3@*Z7$p|3zWs#inJG=wfmiTlA$@ zzRhxo{EHME{{ew_ITO~@6}JgXQN`Iy`^Vg86bTKVE8YW_^S_xKpEQotbN~MU8d@lJ diff --git a/Program/libcsp/build/src/csp_qfifo.c.2.o b/Program/libcsp/build/src/csp_qfifo.c.2.o deleted file mode 100755 index 60539f4ac6290f704a50baaa7bb161434c7b2d55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15288 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 z 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

  4. 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 XV1?!1j!jj*q*JJQMck~bTK<0keV(G} diff --git a/Program/libcsp/build/src/csp_service_handler.c.2.o b/Program/libcsp/build/src/csp_service_handler.c.2.o deleted file mode 100755 index 8a4b0f9f4a113b4a5f85599129114b521e4742cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27968 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 diff --git a/Program/libcsp/build/src/csp_service_handler.c.3.o b/Program/libcsp/build/src/csp_service_handler.c.3.o deleted file mode 100755 index 1dc4633b049a7232faac68bb0ebb39d3a331e544..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27808 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 c74jgy)HiW1m;X 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 diff --git a/Program/libcsp/build/src/csp_sfp.c.2.o b/Program/libcsp/build/src/csp_sfp.c.2.o deleted file mode 100755 index 13e0ec6769ded007120fd3f0bdb60f08aafafa68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21392 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 Jv#+N7{{y2Cs*(Tz diff --git a/Program/libcsp/build/src/drivers/can/can_socketcan.c.3.o b/Program/libcsp/build/src/drivers/can/can_socketcan.c.3.o deleted file mode 100755 index ffa13674939c7c06e0a7862f478720c5ad612d0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32976 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
    [/mask] [via] - - * address: is the destination address, the routing table will match it against the CSP header destination. - * mask (optional): determines how many MSB bits of address are to be matched. mask = 1 will only match the MSB bit, mask = 2 will match 2 MSB bits. Mask values different from 0 and 5, is only supported by the cidr rtable. - * interface name: name of the interface to route the packet on - * via (optional) address: if different from 255, route the packet to the `via` address, instead of the address in the CSP header. - -Here are some examples: - - - "10 I2C" route destination address 10 to the "I2C" interface and send it to address 10 (no `via`). - - "10 I2C 30" route destination address 10 to the "I2C" interface and send it to address 30 (`via`). The original destination address 10 is not changed in the CSP header of the packet. - - "16/1 CAN 4" (CIDR only) route all destinations addresses 16-31 to address 4 on the CAN interface. - - "0/0 CAN" default route, if no other matching route is found, route packet onto the CAN interface. - - -Interface ---------- - -The interface typically implements :ref:`layer2`, and uses drivers from :ref:`layer1` to send/receive data. -The interface is a generic struct, with no knowledge of any specific interface , protocol or driver: - -.. literalinclude:: ../include/csp/csp_interface.h - :language: c - :start-after: //doc-begin:csp_iface_s - :end-before: //doc-end:csp_iface_s - -If an interface implementation needs to store data, e.g. state information (KISS), it can use the pointer `interface_data` to reference any data structure needed. The driver implementation can use the pointer `driver_data` for storing data, e.g. device number. - -See function `csp_can_socketcan_open_and_add_interface()` in `src/drivers/can/can_socketcan.c` for an example of how to implement a CAN driver and hooking it into CSP, using the CSP standard CAN interface. - -Send -^^^^ - -When CSP needs to send a packet, it calls `nexthop` on the interface returned by route lookup. -If the interface succeeds in sending the packet, it must free the packet. -In case of failure, the packet must not be freed by the interface. The original idea was, that the packet could be retried later on, without having to re-create the packet again. However, the current implementation does not yet fully support this as some interfaces modifies header (endian conversion) or data (adding CRC32). - -Receive -^^^^^^^ - -When receiving data, the driver calls into the interface with the received data, e.g. `csp_can_rx()`. The interface will convert/copy the data into a packet (e.g. by assembling all CAN frames). Once a complete packet is received, the packet is queued for later CSP processing, by calling `csp_qfifo_write()`. - diff --git a/Program/libcsp/doc/example.rst b/Program/libcsp/doc/example.rst deleted file mode 100755 index 7871a73..0000000 --- a/Program/libcsp/doc/example.rst +++ /dev/null @@ -1,61 +0,0 @@ -Client and server example -========================= - -The example in `example/csp_server_client.c` provides a simple server/client setup, where the client sends a request to the server and receives a reply. The code can be compiled to an executable using `./examples/buildall.py`. - -The example supports the drivers and interfaces in CSP: - - - ZMQHUB: -z - - Requires no extra hardware, as it uses standard network. The zmqproxy will need to be started. - - - CAN: -c - - Requires a physical CAN interface. There are several CAN dongles on the market, for example https://www.peak-system.com/PCAN-USB.199.0.html. - - To achieve best performance and stabilty, following options can be set on the CAN device: - - .. code-block:: none - - linux: sudo ip link set dev can0 down - linux: sudo ip link set dev can0 up type can bitrate 1000000 restart-ms 100 - linux: sudo ip link set dev can0 txqueuelen 100 - - - KISS: -k - - Requires a serial interface, e.g. USB dongle. - - -Running the example -^^^^^^^^^^^^^^^^^^^ -If the example is started without any interfaces, it will use the loopback interface for communication between client and server:: - - ubuntu-18:~/libcsp$ ./build/csp_server_client - 1586816581.410181 Initialising CSP - Connection table - [00 0x55a00f7adee0] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [01 0x55a00f7adf68] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [02 0x55a00f7adff0] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [03 0x55a00f7ae078] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [04 0x55a00f7ae100] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [05 0x55a00f7ae188] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [06 0x55a00f7ae210] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [07 0x55a00f7ae298] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [08 0x55a00f7ae320] S:0, 0 -> 0, 0 -> 0, sock: (nil) - [09 0x55a00f7ae3a8] S:0, 0 -> 0, 0 -> 0, sock: (nil) - Interfaces - LOOP tx: 00000 rx: 00000 txe: 00000 rxe: 00000 - drop: 00000 autherr: 00000 frame: 00000 - txb: 0 (0.0B) rxb: 0 (0.0B) MTU: 0 - - Route table - 1/5 LOOP - 0/0 LOOP - 1586816581.410405 Server task started - 1586816581.410453 Binding socket 0x55a00f7adf68 to port 25 - 1586816581.410543 Client task started - 1586816582.410983 SERVICE: Ping received - 1586816582.411135 Ping address: 1, result 0 [mS] - 1586816582.411174 reboot system request sent to address: 1 - 1586816582.461341 csp_sys_reboot not supported - no user function set - 1586816582.512532 Packet received on MY_SERVER_PORT: Hello World (1) diff --git a/Program/libcsp/doc/history.rst b/Program/libcsp/doc/history.rst deleted file mode 100755 index ec3a92a..0000000 --- a/Program/libcsp/doc/history.rst +++ /dev/null @@ -1,21 +0,0 @@ -History -======= - -The idea was developed by a group of students from Aalborg University in 2008. In 2009 the main developer started working for GomSpace, and CSP became integrated into the GomSpace products. - -The three letter acronym CSP was originally an abbreviation for CAN Space Protocol because the first MAC-layer driver was written for CAN-bus. Now the physical layer has extended to include SpaceWire, I2C and RS232, the name was therefore extended to the more general CubeSat Space Protocol without changing the abbreviation. - -Satellites using CSP --------------------- - -Here is a list of some of the known satellites or organisations, that uses CSP: - - * GomSpace GATOSS GOMX-1 - * AAUSAT-3 - * EgyCubeSat - * EuroLuna - * NUTS - * Hawaiian Space Flight Laboratory - * GomSpace GOMX-3, GOMX-4 A & B - -See list of libcsp fork's here: https://github.com/libcsp/libcsp/network/members diff --git a/Program/libcsp/doc/libcsp.rst b/Program/libcsp/doc/libcsp.rst deleted file mode 100755 index 07efec7..0000000 --- a/Program/libcsp/doc/libcsp.rst +++ /dev/null @@ -1,21 +0,0 @@ -.. CSP Documentation master file. - -.. _libcsp: - -********************** -CubeSat Space Protocol -********************** - -.. toctree:: - :maxdepth: 3 - - ../README - history - structure - basic - memory - protocolstack - topology - mtu - example - diff --git a/Program/libcsp/doc/memory.rst b/Program/libcsp/doc/memory.rst deleted file mode 100755 index 85b5471..0000000 --- a/Program/libcsp/doc/memory.rst +++ /dev/null @@ -1,16 +0,0 @@ -How CSP uses memory -=================== - -CSP has been written for small microprocessor systems. The way memory is handled is therefore a tradeoff between the amount used and the code efficiency. - -The current libcsp implementation primarily uses dynamic memory allocation during initialization, where all structures are allocated: port tables, connection pools, buffer pools, message queues, semaphores, tasks, etc. - -Once the initiallization is complete, there are only a few functions that uses dynamic allocation, such as: - - * csp_sfp_recv() - sending larger memory chuncks than can fit into a single CSP message. - * csp_rtable (cidr only) - adding new elements may allocate memory. - -This means that there are no `alloc/free` after initialization, possibly causing fragmented memory which especially can be a problem on small systems with limited memory. -It also allows for a very simple memory allocator (implementation of `csp_malloc()`), as `free` can be avoided. - -Future versions of libcsp may provide a `pure` static memory layout, since newer FreeRTOS versions allows for specifying memory for queues, semaphores, tasks, etc. diff --git a/Program/libcsp/doc/mtu.rst b/Program/libcsp/doc/mtu.rst deleted file mode 100755 index eb8207d..0000000 --- a/Program/libcsp/doc/mtu.rst +++ /dev/null @@ -1,19 +0,0 @@ -Maximum Transfer Unit -===================== - -There are two things limiting the MTU of CSP. - - 1. The pre-allocated buffer pool’s allocation size - 2. The link layer protocol. - -So let’s assume that you have made a protocol called KISS with a MTU of 256. The 256 is the total amount of data that you can put into the CSP-packet. However, you need to take the overhead of the link layer into account. Typically this could consist of a length field and/or a start/stop flag. So the actual frame size on the link layer would for example be 256 bytes of data + 2 bytes sync flag + 2 bytes length field. - -This requires a buffer allocation of at lest 256 + 2 + 2. However, the CSP packet itself has some reserved bytes in the beginning of the packet (which you can see in csp.h) - so the recommended buffer allocation size is MAX MTU + 16 bytes. In this case the max MTU would be 256. - -If you try to pass data which is longer than the MTU, the chance is that you will also make a buffer overflow in the CSP buffer pool. However, lets assume that you have two interfaces one with an MTU of 200 bytes and another with an MTU of 100 bytes. In this case you might successfully transfer 150 bytes over the first interface, but the packet will be rejected once it comes to the second interface. - -If you want to increase your MTU of a specific link layer, it is up to the link layer protocol to implement its own fragmentation protocol. A good example is CAN-bus which only allows a frame size of 8 bytes. libcsp have a small protocol for this called the “CAN fragmentation protocol" or CFP for short. This allows data of much larger size to be transferred over the CAN bus. - -Okay, but what if you want to transfer 1000 bytes, and the network maximum MTU is 256? Well, since CSP does not include streaming sockets, only packet’s. Somebody will have to split that data up into chunks. It might be that your application have special knowledge about the datatype you are transmitting, and that it makes sense to split the 1000 byte content into 10 chunks of 100 byte status messages. This, application layer delimitation might be good if you have a situation with packet loss, because your receiver could still make good usage of the partially delivered chunks. - -But, what if you just want 1000 bytes transmitted, and you don’t care about the fragmentation unit, and also don’t want the hassle of writing the fragmentation code yourself? - In this case, libcsp provides SFP (small fragmentation protocol), designed to work on the application layer. For this purpose you will not use csp_send and csp_recv, but csp_sfp_send and csp_sfp_recv. This will split your data into chunks of a certain size, enumerate them and transfer over a given connection. If a chunk is missing the SFP client will abort the reception, because SFP does not provide retransmission. If you wish to also have retransmission and orderly delivery you will have to open an RDP connection and send your SFP message to that connection. diff --git a/Program/libcsp/doc/protocolstack.rst b/Program/libcsp/doc/protocolstack.rst deleted file mode 100755 index 8ae388d..0000000 --- a/Program/libcsp/doc/protocolstack.rst +++ /dev/null @@ -1,61 +0,0 @@ -The Protocol Stack -================== - -The CSP protocol stack includes functionality on all layers of the TCP/IP model: - -.. _layer1: - -Layer 1: Drivers ----------------- - -CSP is not designed for any specific processor or hardware peripheral, but yet these drivers are required in order to work. The intention of LibCSP is not to provide CAN, I2C or UART drivers for all platforms, however some drivers has only been included for some specific platforms. If you do not find your driver supported, it is quite simple to add a driver that conforms to the CSP interface. -For good stability and performance interrupt driven drivers are preferred in favor of polled drivers. Where applicable also DMA usage is recommended. - -.. _layer2: - -Layer 2: MAC interfaces ------------------------ - -CSP has interfaces for I2C, CAN, RS232 (KISS) and Loopback. The layer 2 protocol software defines a frame-format that is suitable for the media. CSP can be easily extended with implementations for even more links. For example a radio-link and IP-networks. The file `csp_interface.h` declares the rx and tx functions needed in order to define a network interface in CSP. During initialisation of CSP each interface will be inserted into a linked list of interfaces that is available to the router. In cases where link-layer addresses are required, such as I2C, the routing table supports specifying a `via` link-layer address directly. This avoids the need to implement an address resolution protocol to translate CSP addresses to I2C addresses. - -Layer 3: Network Router ------------------------ - -The router core is the backbone of the CSP implementation. The router works by looking at a 32-bit CSP header which contains the destination and source address together with port numbers for the connection. The router supports both local destination and forwarding to an external destination. Messages will never exit the router on the same interface that they arrives at, this concept is called split horizon, and helps prevent routing loops. - -The main purpose of the router is to accept incoming packets and deliver them to the right message queue. Therefore, in order to listen on a port-number on the network, a task must create a socket and call the accept() call. This will make the task block and wait for incoming traffic, just like a web-server or similar. When an incoming connection is opened, the task is woken. Depending on the task-priority, the task can even preempt another task and start execution immediately. - -There is no routing protocol for automatic route discovery, all routing tables are pre-programmed into the subsystems. The table itself contains a separate route to each of the possible 32 nodes in the network and the additional default route. This means that the overall topology must be decided before putting sub-systems together, as explained in the :ref:`topology` section. However CSP has an extension on port zero CMP (CSP management protocol), which allows for over-the-network routing table configuration. This has the advantage that default routes could be changed if for example the primary radio fails, and the secondary should be used instead. - -.. _layer4: - -Layer 4: Transport Layer ------------------------- - -LibCSP implements two different Transport Layer protocols, they are called UDP (unreliable datagram protocol) and RDP (reliable datagram protocol). The name UDP has not been chosen to be an exact replica of the UDP (user datagram protocol) known from the TCP/IP model, but they have certain similarities. - -The most important thing to notice is that CSP is entirely a datagram service. There is no stream based service like TCP. A datagram is a defined block of data with a specified size and structure. This block enters the transport layer as a single datagram and exits the transport layer in the other end as a single datagram. CSP preserves this structure all the way to the physical layer for I2C, KISS and Loopback interfaces. The CAN-bus interface has to fragment the datagram into CAN-frames of 8 bytes, however only a fully completed datagram will arrive at the receiver. - -UDP -^^^ - -UDP uses a simple transmission model without implicit hand-shaking dialogues for guaranteeing reliability, ordering, or data integrity. Thus, UDP provides an unreliable service and datagrams may arrive out of order, appear duplicated, or go missing without notice. UDP assumes that error checking and correction is either not necessary or performed in the application, avoiding the overhead of such processing at the network interface level. Time-sensitive applications often use UDP because dropping packets is preferable to waiting for delayed packets, which may not be an option in a real-time system. - -UDP is very practical to implement request/reply based communication where a single packet forms the request and a single packet forms the reply. In this case a typical request and wait protocol is used between the client and server, which will simply return an error if a reply is not received within a specified time limit. An error would normally lead to a retransmission of the request from the user or operator which sent the request. - -While UDP is very simple, it also has some limitations. Normally a human in the loop is a good thing when operating the satellite over UDP. But when it comes to larger file transfers, the human becomes the bottleneck. When a high-speed file transfer is initiated data acknowledgment should be done automatically in order to speed up the transfer. This is where the RDP protocol can help. - -RDP -^^^ -CSP provides a transport layer extension called RDP (reliable datagram protocol) which is an implementation of RFC908 and RFC1151. RDP provides a few additional features: - - * Three-way handshake - * Flow Control - * Data-buffering - * Packet re-ordering - * Retransmission - * Windowing - * Extended Acknowledgment - -For more information on this, please refer to RFC908 and RFC1151. - diff --git a/Program/libcsp/doc/structure.rst b/Program/libcsp/doc/structure.rst deleted file mode 100755 index b79c87b..0000000 --- a/Program/libcsp/doc/structure.rst +++ /dev/null @@ -1,29 +0,0 @@ -Structure -========= -The Cubesat Space Protocol library is structured as shown in the following table: - -============================= ========================================================================= -**Folder** **Description** -============================= ========================================================================= -libcsp/include/csp Public header files -libcsp/include/csp/arch Architecture (platform) -libcsp/include/csp/interfaces Interfaces -libcsp/include/csp/drivers Drivers -libcsp/src Source modules and internal header files -libcsp/src/arch Architecture (platform) specific code -libcsp/src/arch/freertos FreeRTOS -libcsp/src/arch/macosx Mac OS X -libcsp/src/arch/posix Posix (Linux) -libcsp/src/arch/windows Windows -libcsp/src/bindings/python Python3 wrapper for libcsp -libcsp/src/crypto HMAC, SHA and XTEA. -libcsp/src/drivers Drivers, mostly platform specific (Linux) -libcsp/src/drivers/can CAN -libcsp/src/drivers/usart USART -libcsp/src/interfaces Interfaces, CAN, I2C, KISS, LOOPBACK and ZMQHUB -libcsp/src/rtable Routing tables -libcsp/src/transport Transport layer: UDP, RDP -libcsp/utils Utilities, Python scripts for decoding CSP headers. -libcsp/examples CSP examples, C/Python, zmqproxy -libcsp/doc RST based documention (this documentation) -============================= ========================================================================= diff --git a/Program/libcsp/doc/topology.rst b/Program/libcsp/doc/topology.rst deleted file mode 100755 index 139caec..0000000 --- a/Program/libcsp/doc/topology.rst +++ /dev/null @@ -1,27 +0,0 @@ - -.. _topology: - -Network Topology -================ - -CSP uses a network oriented terminology similar to what is known from the Internet and the TCP/IP model. A CSP network can be configured for several different topologies. The most common topology is to create two segments, one for the Satellite and one for the Ground-Station. - -.. code-block:: none - - +-------+-------+-------+-------+ bus: I2C, CAN, KISS - | | | | | - +---+ +---+ +---+ +---+ +---+ - |OBC| |COM| |EPS| |PL1| |PL2| Nodes 0 - 15 (Space segment) - +---+ +---+ +---+ +---+ +---+ - ^ - | Radio - v - +---+ +----+ - |TNC| | PC | Nodes 16 - 31 (Ground segment) - +---+ +----+ - | | - +---------------+ bus: KISS, ZMQ - -The address range, from 0 to 31, has been segmented into two equal size segments. This allows for easy routing in the network. All addresses starting with binary 1 is on the ground-segment, and all addresses starting with 0 is on the space segment. - -The network is configured using static routes initialised at boot-up of each sub-system. This means that the basic routing table must be assigned compile-time of each subsystem. However each node supports assigning an individual route to every single node in the network and can be changed run-time. This means that the network topology can be easily reconfigured after startup. diff --git a/Program/libcsp/examples/buildall.py b/Program/libcsp/examples/buildall.py deleted file mode 100755 index 97cc7d1..0000000 --- a/Program/libcsp/examples/buildall.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -import subprocess -import sys - - -os = 'posix' # default OS -options = sys.argv[1:] -if (len(options) > 0) and not options[0].startswith('--'): - os = options[0] - options = options[1:] - -options += [ - '--with-os=' + os, - '--enable-rdp', - '--enable-promisc', - '--enable-crc32', - '--enable-hmac', - '--enable-xtea', - '--enable-dedup', - '--with-loglevel=debug', - '--enable-debug-timestamp' -] - -waf = ['./waf'] -if os in ['posix']: - options += [ - '--enable-python3-bindings', - '--enable-can-socketcan', - '--with-driver-usart=linux', - '--enable-if-zmqhub', - '--enable-shlib' - ] - -if os in ['macosx']: - options += [ - '--with-driver-usart=linux', - ] - -if os in ['windows']: - options += [ - '--with-driver-usart=windows', - ] - waf = ['python', '-x', 'waf'] - -# Build -waf += ['distclean', 'configure', 'build'] -print("Waf build command:", waf) -subprocess.check_call(waf + options + - ['--enable-qos', '--with-rtable=cidr', '--disable-stlib', '--disable-output']) -subprocess.check_call(waf + options + ['--enable-examples']) diff --git a/Program/libcsp/examples/csp_arch.c b/Program/libcsp/examples/csp_arch.c deleted file mode 100755 index 5c088e6..0000000 --- a/Program/libcsp/examples/csp_arch.c +++ /dev/null @@ -1,159 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#define CSP_USE_ASSERT 1 // always enable CSP assert - -#include -#include -#include -#include -#include -#include -#include - -#include - -static bool thread_executed = false; - -void csp_assert_fail_action(const char *assertion, const char *file, int line) { - printf("assertion: [%s], file: %s:%d\r\n", assertion, file, line); - exit(1); -} - -CSP_DEFINE_TASK(thread_func) { - csp_log_info("Thread started"); - thread_executed = true; - csp_sleep_ms(10000); // safty - ensure process terminates - exit(1); - return CSP_TASK_RETURN; -} - -int main(int argc, char * argv[]) { - - // debug/log - enable all levels - for (int i = 0; i <= CSP_LOCK; ++i) { - csp_debug_set_level(i, true); - } - csp_log_error("csp_log_error(...), level: %d", CSP_ERROR); - csp_log_warn("csp_log_warn(...), level: %d", CSP_WARN); - csp_log_info("csp_log_info((...), level: %d", CSP_INFO); - csp_log_buffer("csp_log_buffer(...), level: %d", CSP_BUFFER); - csp_log_packet("csp_log_packet(...), level: %d", CSP_PACKET); - csp_log_protocol("csp_log_protocol(...), level: %d", CSP_PROTOCOL); - csp_log_lock("csp_log_lock(...), level: %d", CSP_LOCK); - - // create a thread - csp_thread doesn't support join - csp_thread_handle_t thread = 0; - int res = csp_thread_create(thread_func, "thread", 0, NULL, 0, &thread); - csp_assert(res == CSP_ERR_NONE); - csp_assert(thread != 0); - - // clock - csp_timestamp_t csp_clock = {}; - csp_clock_get_time(&csp_clock); - csp_assert(csp_clock.tv_sec != 0); - csp_log_info("csp_clock_get_time(..) -> sec:nsec = %"PRIu32":%"PRIu32, csp_clock.tv_sec, csp_clock.tv_nsec); - - // relative time - const uint32_t msec1 = csp_get_ms(); - const uint32_t msec2 = csp_get_ms_isr(); - const uint32_t sec1 = csp_get_s(); - const uint32_t sec2 = csp_get_s_isr(); - csp_sleep_ms(2000); - csp_assert(csp_get_ms() >= (msec1 + 500)); - csp_assert(csp_get_ms_isr() >= (msec2 + 500)); - csp_assert(csp_get_s() >= (sec1 + 1)); - csp_assert(csp_get_s_isr() >= (sec2 + 1)); - - // malloc - uint32_t * ptr = csp_malloc(sizeof(*ptr)); - csp_assert(ptr != NULL); - ptr[0] = 10; - csp_free(ptr); - ptr = csp_calloc(1, sizeof(*ptr)); - csp_assert(ptr != NULL); - csp_assert(*ptr == 0); - ptr[0] = 20; - csp_free(ptr); - - // check thread actually executed - csp_assert(thread_executed != false); - - // queue handling - uint32_t value; - csp_queue_handle_t q = csp_queue_create(3, sizeof(value)); - csp_assert(csp_queue_size(q) == 0); - csp_assert(csp_queue_size_isr(q) == 0); - csp_assert(csp_queue_dequeue(q, &value, 0) == CSP_QUEUE_ERROR); - csp_assert(csp_queue_dequeue(q, &value, 200) == CSP_QUEUE_ERROR); - csp_assert(csp_queue_dequeue_isr(q, &value, NULL) == CSP_QUEUE_ERROR); - value = 1; - csp_assert(csp_queue_enqueue(q, &value, 0) == CSP_QUEUE_OK); - value = 2; - csp_assert(csp_queue_enqueue(q, &value, 200) == CSP_QUEUE_OK); - value = 3; - csp_assert(csp_queue_enqueue_isr(q, &value, NULL) == CSP_QUEUE_OK); - csp_assert(csp_queue_size(q) == 3); - csp_assert(csp_queue_size_isr(q) == 3); - value = 10; - csp_assert(csp_queue_enqueue(q, &value, 0) == CSP_QUEUE_ERROR); - value = 20; - csp_assert(csp_queue_enqueue(q, &value, 200) == CSP_QUEUE_ERROR); - value = 30; - csp_assert(csp_queue_enqueue_isr(q, &value, NULL) == CSP_QUEUE_ERROR); - value = 100; - csp_assert(csp_queue_dequeue(q, &value, 0) == CSP_QUEUE_OK); - csp_assert(value == 1); - csp_assert(csp_queue_dequeue(q, &value, 200) == CSP_QUEUE_OK); - csp_assert(value == 2); - csp_assert(csp_queue_dequeue_isr(q, &value, NULL) == CSP_QUEUE_OK); - csp_assert(value == 3); - csp_queue_remove(q); - - // mutex - the actual mutex lock can't be tested from a single thread - csp_mutex_t m; - csp_assert(csp_mutex_create(&m) == CSP_MUTEX_OK); - csp_assert(csp_mutex_lock(&m, 0) == CSP_MUTEX_OK); -#if (CSP_WINDOWS) // implementations differ in return value if already locked - csp_assert(csp_mutex_lock(&m, 200) == CSP_MUTEX_OK); -#else - csp_assert(csp_mutex_lock(&m, 200) == CSP_MUTEX_ERROR); -#endif - csp_assert(csp_mutex_unlock(&m) == CSP_MUTEX_OK); - csp_assert(csp_mutex_lock(&m, 200) == CSP_MUTEX_OK); - csp_assert(csp_mutex_unlock(&m) == CSP_MUTEX_OK); - csp_assert(csp_mutex_remove(&m) == CSP_MUTEX_OK); - - // semaphore - csp_bin_sem_handle_t s; - csp_assert(csp_bin_sem_create(&s) == CSP_SEMAPHORE_OK); - csp_assert(csp_bin_sem_wait(&s, 0) == CSP_SEMAPHORE_OK); - csp_assert(csp_bin_sem_post(&s) == CSP_SEMAPHORE_OK); -#if (CSP_POSIX) // implementations differ in return value if already posted/signaled - csp_assert(csp_bin_sem_post_isr(&s, NULL) == CSP_SEMAPHORE_OK); -#else - csp_assert(csp_bin_sem_post_isr(&s, NULL) == CSP_SEMAPHORE_ERROR); -#endif - csp_assert(csp_bin_sem_wait(&s, 200) == CSP_SEMAPHORE_OK); - csp_assert(csp_bin_sem_wait(&s, 200) == CSP_SEMAPHORE_ERROR); - csp_assert(csp_bin_sem_remove(&s) == CSP_SEMAPHORE_OK); - - return 0; -} diff --git a/Program/libcsp/examples/csp_server_client.c b/Program/libcsp/examples/csp_server_client.c deleted file mode 100755 index 9bd62b4..0000000 --- a/Program/libcsp/examples/csp_server_client.c +++ /dev/null @@ -1,316 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* Server port, the port the server listens on for incoming connections from the client. */ -#define MY_SERVER_PORT 10 - -/* Commandline options */ -static uint8_t server_address = 255; - -/* test mode, used for verifying that host & client can exchange packets over the loopback interface */ -static bool test_mode = false; -static unsigned int server_received = 0; - -/* Server task - handles requests from clients */ -CSP_DEFINE_TASK(task_server) { - - csp_log_info("Server task started"); - - /* Create socket with no specific socket options, e.g. accepts CRC32, HMAC, XTEA, etc. if enabled during compilation */ - csp_socket_t *sock = csp_socket(CSP_SO_NONE); - - /* Bind socket to all ports, e.g. all incoming connections will be handled here */ - csp_bind(sock, CSP_ANY); - - /* Create a backlog of 10 connections, i.e. up to 10 new connections can be queued */ - csp_listen(sock, 10); - - /* Wait for connections and then process packets on the connection */ - while (1) { - - /* Wait for a new connection, 10000 mS timeout */ - csp_conn_t *conn; - if ((conn = csp_accept(sock, 10000)) == NULL) { - /* timeout */ - continue; - } - - /* Read packets on connection, timout is 100 mS */ - csp_packet_t *packet; - while ((packet = csp_read(conn, 50)) != NULL) { - switch (csp_conn_dport(conn)) { - case MY_SERVER_PORT: - /* Process packet here */ - csp_log_info("Packet received on MY_SERVER_PORT: %s", (char *) packet->data); - csp_buffer_free(packet); - ++server_received; - break; - - default: - /* Call the default CSP service handler, handle pings, buffer use, etc. */ - csp_service_handler(conn, packet); - break; - } - } - - /* Close current connection */ - csp_close(conn); - - } - - return CSP_TASK_RETURN; - -} -/* End of server task */ - -/* Client task sending requests to server task */ -CSP_DEFINE_TASK(task_client) { - - csp_log_info("Client task started"); - - unsigned int count = 0; - - while (1) { - - csp_sleep_ms(test_mode ? 200 : 1000); - - /* Send ping to server, timeout 1000 mS, ping size 100 bytes */ - int result = csp_ping(server_address, 1000, 100, CSP_O_NONE); - csp_log_info("Ping address: %u, result %d [mS]", server_address, result); - - /* Send reboot request to server, the server has no actual implementation of csp_sys_reboot() and fails to reboot */ - csp_reboot(server_address); - csp_log_info("reboot system request sent to address: %u", server_address); - - /* Send data packet (string) to server */ - - /* 1. Connect to host on 'server_address', port MY_SERVER_PORT with regular UDP-like protocol and 1000 ms timeout */ - csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, server_address, MY_SERVER_PORT, 1000, CSP_O_NONE); - if (conn == NULL) { - /* Connect failed */ - csp_log_error("Connection failed"); - return CSP_TASK_RETURN; - } - - /* 2. Get packet buffer for message/data */ - csp_packet_t * packet = csp_buffer_get(100); - if (packet == NULL) { - /* Could not get buffer element */ - csp_log_error("Failed to get CSP buffer"); - return CSP_TASK_RETURN; - } - - /* 3. Copy data to packet */ - snprintf((char *) packet->data, csp_buffer_data_size(), "Hello World (%u)", ++count); - - /* 4. Set packet length */ - packet->length = (strlen((char *) packet->data) + 1); /* include the 0 termination */ - - /* 5. Send packet */ - if (!csp_send(conn, packet, 1000)) { - /* Send failed */ - csp_log_error("Send failed"); - csp_buffer_free(packet); - } - - /* 6. Close connection */ - csp_close(conn); - } - - return CSP_TASK_RETURN; -} -/* End of client task */ - -/* main - initialization of CSP and start of server/client tasks */ -int main(int argc, char * argv[]) { - - uint8_t address = 1; - csp_debug_level_t debug_level = CSP_INFO; -#if (CSP_HAVE_LIBSOCKETCAN) - const char * can_device = NULL; -#endif - const char * kiss_device = NULL; -#if (CSP_HAVE_LIBZMQ) - const char * zmq_device = NULL; -#endif - const char * rtable = NULL; - int opt; - while ((opt = getopt(argc, argv, "a:d:r:c:k:z:tR:h")) != -1) { - switch (opt) { - case 'a': - address = atoi(optarg); - break; - case 'd': - debug_level = atoi(optarg); - break; - case 'r': - server_address = atoi(optarg); - break; -#if (CSP_HAVE_LIBSOCKETCAN) - case 'c': - can_device = optarg; - break; -#endif - case 'k': - kiss_device = optarg; - break; -#if (CSP_HAVE_LIBZMQ) - case 'z': - zmq_device = optarg; - break; -#endif - case 't': - test_mode = true; - break; - case 'R': - rtable = optarg; - break; - default: - printf("Usage:\n" - " -a
    local CSP address\n" - " -d debug level, 0 - 6\n" - " -r
    run client against server address\n" - " -c add CAN device\n" - " -k add KISS device (serial)\n" - " -z add ZMQ device, e.g. \"localhost\"\n" - " -R set routing table\n" - " -t enable test mode\n"); - exit(1); - break; - } - } - - /* enable/disable debug levels */ - for (csp_debug_level_t i = 0; i <= CSP_LOCK; ++i) { - csp_debug_set_level(i, (i <= debug_level) ? true : false); - } - - csp_log_info("Initialising CSP"); - - /* Init CSP with address and default settings */ - csp_conf_t csp_conf; - csp_conf_get_defaults(&csp_conf); - csp_conf.address = address; - int error = csp_init(&csp_conf); - if (error != CSP_ERR_NONE) { - csp_log_error("csp_init() failed, error: %d", error); - exit(1); - } - - /* Start router task with 10000 bytes of stack (priority is only supported on FreeRTOS) */ - csp_route_start_task(500, 0); - - /* Add interface(s) */ - csp_iface_t * default_iface = NULL; - if (kiss_device) { - csp_usart_conf_t conf = { - .device = kiss_device, - .baudrate = 115200, /* supported on all platforms */ - .databits = 8, - .stopbits = 1, - .paritysetting = 0, - .checkparity = 0}; - error = csp_usart_open_and_add_kiss_interface(&conf, CSP_IF_KISS_DEFAULT_NAME, &default_iface); - if (error != CSP_ERR_NONE) { - csp_log_error("failed to add KISS interface [%s], error: %d", kiss_device, error); - exit(1); - } - } -#if (CSP_HAVE_LIBSOCKETCAN) - if (can_device) { - error = csp_can_socketcan_open_and_add_interface(can_device, CSP_IF_CAN_DEFAULT_NAME, 0, false, &default_iface); - if (error != CSP_ERR_NONE) { - csp_log_error("failed to add CAN interface [%s], error: %d", can_device, error); - exit(1); - } - } -#endif -#if (CSP_HAVE_LIBZMQ) - if (zmq_device) { - error = csp_zmqhub_init(csp_get_address(), zmq_device, 0, &default_iface); - if (error != CSP_ERR_NONE) { - csp_log_error("failed to add ZMQ interface [%s], error: %d", zmq_device, error); - exit(1); - } - } -#endif - - if (rtable) { - error = csp_rtable_load(rtable); - if (error < 1) { - csp_log_error("csp_rtable_load(%s) failed, error: %d", rtable, error); - exit(1); - } - } else if (default_iface) { - csp_rtable_set(CSP_DEFAULT_ROUTE, 0, default_iface, CSP_NO_VIA_ADDRESS); - } else { - /* no interfaces configured - run server and client in process, using loopback interface */ - server_address = address; - } - - printf("Connection table\r\n"); - csp_conn_print_table(); - - printf("Interfaces\r\n"); - csp_route_print_interfaces(); - - printf("Route table\r\n"); - csp_route_print_table(); - - /* Start server thread */ - if ((server_address == 255) || /* no server address specified, I must be server */ - (default_iface == NULL)) { /* no interfaces specified -> run server & client via loopback */ - csp_thread_create(task_server, "SERVER", 1000, NULL, 0, NULL); - } - - /* Start client thread */ - if ((server_address != 255) || /* server address specified, I must be client */ - (default_iface == NULL)) { /* no interfaces specified -> run server & client via loopback */ - csp_thread_create(task_client, "CLIENT", 1000, NULL, 0, NULL); - } - - /* Wait for execution to end (ctrl+c) */ - while(1) { - csp_sleep_ms(3000); - - if (test_mode) { - /* Test mode is intended for checking that host & client can exchange packets over loopback */ - if (server_received < 5) { - csp_log_error("Server received %u packets", server_received); - exit(1); - } - csp_log_info("Server received %u packets", server_received); - exit(0); - } - } - - return 0; -} diff --git a/Program/libcsp/examples/python_bindings_example_client.py b/Program/libcsp/examples/python_bindings_example_client.py deleted file mode 100755 index d87fc5e..0000000 --- a/Program/libcsp/examples/python_bindings_example_client.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/python3 - -# Build required code: -# $ ./examples/buildall.py -# -# Start zmqproxy (only one instance) -# $ ./build/zmqproxy -# -# Run client against server using ZMQ: -# $ LD_LIBRARY_PATH=build PYTHONPATH=build python3 examples/python_bindings_example_client.py -z localhost -# - -import os -import time -import sys -import argparse - -import libcsp_py3 as libcsp - - -def getOptions(): - parser = argparse.ArgumentParser(description="Parses command.") - parser.add_argument("-a", "--address", type=int, default=10, help="Local CSP address") - parser.add_argument("-c", "--can", help="Add CAN interface") - parser.add_argument("-z", "--zmq", help="Add ZMQ interface") - parser.add_argument("-s", "--server-address", type=int, default=27, help="Server address") - parser.add_argument("-R", "--routing-table", help="Routing table") - return parser.parse_args(sys.argv[1:]) - - -if __name__ == "__main__": - - options = getOptions() - - libcsp.init(options.address, "host", "model", "1.2.3", 10, 300) - - if options.can: - libcsp.can_socketcan_init(options.can) - if options.zmq: - libcsp.zmqhub_init(options.address, options.zmq) - libcsp.rtable_load("0/0 ZMQHUB") - if options.routing_table: - libcsp.rtable_load(options.routing_table) - - libcsp.route_start_task() - time.sleep(0.2) # allow router task startup - - print("Connections:") - libcsp.print_connections() - - print("Routes:") - libcsp.print_routes() - - print("CMP ident:", libcsp.cmp_ident(options.server_address)) - - print("Ping: %d mS" % libcsp.ping(options.server_address)) - - # transaction - outbuf = bytearray().fromhex('01') - inbuf = bytearray(1) - print ("Exchange data with server using csp_transaction ...") - libcsp.transaction(0, options.server_address, 10, 1000, outbuf, inbuf) - print (" got reply from server [%s]" % (''.join('{:02x}'.format(x) for x in inbuf))) diff --git a/Program/libcsp/examples/python_bindings_example_server.py b/Program/libcsp/examples/python_bindings_example_server.py deleted file mode 100755 index 8152455..0000000 --- a/Program/libcsp/examples/python_bindings_example_server.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/python3 - -# Build required code: -# $ ./examples/buildall.py -# -# Start zmqproxy (only one instance) -# $ ./build/zmqproxy -# -# Run server, default enabling ZMQ interface: -# $ LD_LIBRARY_PATH=build PYTHONPATH=build python3 examples/python_bindings_example_server.py -# - -import os -import time -import sys -import threading - -import libcsp_py3 as libcsp - - -def csp_server(): - sock = libcsp.socket() - libcsp.bind(sock, libcsp.CSP_ANY) - libcsp.listen(sock, 5) - while True: - # wait for incoming connection - conn = libcsp.accept(sock, libcsp.CSP_MAX_TIMEOUT) - if not conn: - continue - - print ("connection: source=%i:%i, dest=%i:%i" % (libcsp.conn_src(conn), - libcsp.conn_sport(conn), - libcsp.conn_dst(conn), - libcsp.conn_dport(conn))) - - while True: - # Read all packets on the connection - packet = libcsp.read(conn, 100) - if packet is None: - break - - if libcsp.conn_dport(conn) == 10: - # print request - data = bytearray(libcsp.packet_get_data(packet)) - length = libcsp.packet_get_length(packet) - print ("got packet, len=" + str(length) + ", data=" + ''.join('{:02x}'.format(x) for x in data)) - # send reply - data[0] = data[0] + 1 - reply = libcsp.buffer_get(1) - libcsp.packet_set_data(reply, data) - libcsp.sendto_reply(packet, reply, libcsp.CSP_O_NONE) - - else: - # pass request on to service handler - libcsp.service_handler(conn, packet) - - -if __name__ == "__main__": - - # init csp - libcsp.init(27, "test_service", "bindings", "1.2.3", 10, 300) - libcsp.zmqhub_init(27, "localhost") - libcsp.rtable_set(0, 0, "ZMQHUB") - libcsp.route_start_task() - - print("Hostname: %s" % libcsp.get_hostname()) - print("Model: %s" % libcsp.get_model()) - print("Revision: %s" % libcsp.get_revision()) - - print("Routes:") - libcsp.print_routes() - - # start CSP server - threading.Thread(target=csp_server).start() diff --git a/Program/libcsp/examples/zmqproxy.c b/Program/libcsp/examples/zmqproxy.c deleted file mode 100755 index 0c7c35c..0000000 --- a/Program/libcsp/examples/zmqproxy.c +++ /dev/null @@ -1,115 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include - -#include - -static void * task_capture(void *ctx) { - - /* Subscriber (RX) */ - void *subscriber = zmq_socket(ctx, ZMQ_SUB); - assert(zmq_connect(subscriber, "tcp://localhost:7000") == 0); - assert(zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0) == 0); - - /* Allocated 'raw' CSP packet */ - csp_packet_t * packet = malloc(1024); - assert(packet != NULL); - - while (1) { - zmq_msg_t msg; - zmq_msg_init_size(&msg, 1024); - - /* Receive data */ - if (zmq_msg_recv(&msg, subscriber, 0) < 0) { - zmq_msg_close(&msg); - csp_log_error("ZMQ: %s\r\n", zmq_strerror(zmq_errno())); - continue; - } - - int datalen = zmq_msg_size(&msg); - if (datalen < 5) { - csp_log_warn("ZMQ: Too short datalen: %u\r\n", datalen); - while(zmq_msg_recv(&msg, subscriber, ZMQ_NOBLOCK) > 0) - zmq_msg_close(&msg); - continue; - } - - /* Copy the data from zmq to csp */ - char * satidptr = ((char *) &packet->id) - 1; - memcpy(satidptr, zmq_msg_data(&msg), datalen); - packet->length = datalen - sizeof(packet->id) - 1; - - csp_log_packet("Input: Src %u, Dst %u, Dport %u, Sport %u, Pri %u, Flags 0x%02X, Size %"PRIu16, - packet->id.src, packet->id.dst, packet->id.dport, - packet->id.sport, packet->id.pri, packet->id.flags, packet->length); - - zmq_msg_close(&msg); - } -} - -int main(int argc, char ** argv) { - - csp_debug_level_t debug_level = CSP_PACKET; - int opt; - while ((opt = getopt(argc, argv, "d:h")) != -1) { - switch (opt) { - case 'd': - debug_level = atoi(optarg); - break; - default: - printf("Usage:\n" - " -d debug level, 0 - 6\n"); - exit(1); - break; - } - } - - /* enable/disable debug levels */ - for (csp_debug_level_t i = 0; i <= CSP_LOCK; ++i) { - csp_debug_set_level(i, (i <= debug_level) ? true : false); - } - - void * ctx = zmq_ctx_new(); - assert(ctx); - - void *frontend = zmq_socket(ctx, ZMQ_XSUB); - assert(frontend); - assert(zmq_bind (frontend, "tcp://*:6000") == 0); - - void *backend = zmq_socket(ctx, ZMQ_XPUB); - assert(backend); - assert(zmq_bind(backend, "tcp://*:7000") == 0); - - pthread_t capworker; - pthread_create(&capworker, NULL, task_capture, ctx); - - csp_log_info("Starting ZMQproxy"); - zmq_proxy(frontend, backend, NULL); - - csp_log_info("Closing ZMQproxy"); - zmq_ctx_destroy(ctx); - - return 0; -} diff --git a/Program/libcsp/include/csp/arch/csp_clock.h b/Program/libcsp/include/csp/arch/csp_clock.h deleted file mode 100755 index dc995df..0000000 --- a/Program/libcsp/include/csp/arch/csp_clock.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_ARCH_CLOCK_H_ -#define _CSP_ARCH_CLOCK_H_ - -/** - @file - - Clock interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Timestamp (cross platform). -*/ -typedef struct { - //! Seconds - uint32_t tv_sec; - //! Nano-seconds. - uint32_t tv_nsec; -} csp_timestamp_t; - -/** - Get time. - - This function is 'weak' in libcsp, providing a working implementation for following OS's: POSIX, Windows and Macosx. - This function is expected to be equivalent to standard POSIX clock_gettime(CLOCK_REALTIME, ...). - - @param[out] time current time. -*/ -void csp_clock_get_time(csp_timestamp_t * time); - -/** - Set time. - - This function is 'weak' in libcsp, providing a working implementation for following OS's: POSIX, Windows and Macosx. - This function is expected to be equivalent to standard POSIX clock_settime(CLOCK_REALTIME, ...). - - @param[in] time time to set. - @return #CSP_ERR_NONE on success. -*/ -int csp_clock_set_time(const csp_timestamp_t * time); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/csp_malloc.h b/Program/libcsp/include/csp/arch/csp_malloc.h deleted file mode 100755 index fe6eca9..0000000 --- a/Program/libcsp/include/csp/arch/csp_malloc.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_MALLOC_H_ -#define _CSP_MALLOC_H_ - -/** - @file - - Memory interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Allocate chunk of memory (POSIX). - @param[in] size size of memory chunk (bytes). - @return Pointer to allocated memory, or NULL on failure. -*/ -void * csp_malloc(size_t size); - -/** - Allocate chunk of memory and set it to zero (POSIX). - @param[in] nmemb number of members/chunks to allocate. - @param[in] size size of memory chunk (bytes). - @return Pointer to allocated memory, or NULL on failure. -*/ -void * csp_calloc(size_t nmemb, size_t size); - -/** - Free allocated memory (POSIX). - @param[in] ptr memory to free. NULL pointer is ignored. -*/ -void csp_free(void * ptr); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/csp_queue.h b/Program/libcsp/include/csp/arch/csp_queue.h deleted file mode 100755 index 716b3d2..0000000 --- a/Program/libcsp/include/csp/arch/csp_queue.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_ARCH_QUEUE_H_ -#define _CSP_ARCH_QUEUE_H_ - -/** - @file - - Queue interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - No error. - @note Value is 1! -*/ -#define CSP_QUEUE_OK 1 - -/** - Queue full. - @note Value is 0! -*/ -#define CSP_QUEUE_FULL 0 - -/** - Queue error. - @note Value is 0! -*/ -#define CSP_QUEUE_ERROR 0 - -/** - Queue handle. -*/ -typedef void * csp_queue_handle_t; - -/** - Create queue. - @param[in] length max length of queue, number of elements. - @param[in] item_size size of queue elements (bytes). - @return Create queue on success, otherwise NULL. -*/ -csp_queue_handle_t csp_queue_create(int length, size_t item_size); - -/** - Remove/delete queue. - @param[in] queue queue. -*/ -void csp_queue_remove(csp_queue_handle_t queue); - -/** - Enqueue (back) value. - @param[in] handle queue. - @param[in] value value to add (by copy) - @param[in] timeout timeout, time to wait for free space - @return #CSP_QUEUE_OK on success, otherwise a queue error code. -*/ -int csp_queue_enqueue(csp_queue_handle_t handle, const void *value, uint32_t timeout); - -/** - Enqueue (back) value from ISR. - @param[in] handle queue. - @param[in] value value to add (by copy) - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! - @return #CSP_QUEUE_OK on success, otherwise a queue error code. -*/ -int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * pxTaskWoken); - -/** - Dequeue value (front). - @param[in] handle queue. - @param[out] buf extracted element (by copy). - @param[in] timeout timeout, time to wait for element in queue. - @return #CSP_QUEUE_OK on success, otherwise a queue error code. -*/ -int csp_queue_dequeue(csp_queue_handle_t handle, void *buf, uint32_t timeout); - -/** - Dequeue value (front) from ISR. - @param[in] handle queue. - @param[out] buf extracted element (by copy). - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! - @return #CSP_QUEUE_OK on success, otherwise a queue error code. -*/ -int csp_queue_dequeue_isr(csp_queue_handle_t handle, void * buf, CSP_BASE_TYPE * pxTaskWoken); - -/** - Queue size. - @param[in] handle queue. - @return Number of elements in the queue. -*/ -int csp_queue_size(csp_queue_handle_t handle); - -/** - Queue size from ISR. - @param[in] handle queue. - @return Number of elements in the queue. -*/ -int csp_queue_size_isr(csp_queue_handle_t handle); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/csp_semaphore.h b/Program/libcsp/include/csp/arch/csp_semaphore.h deleted file mode 100755 index bbb2625..0000000 --- a/Program/libcsp/include/csp/arch/csp_semaphore.h +++ /dev/null @@ -1,206 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_SEMAPHORE_H_ -#define _CSP_SEMAPHORE_H_ - -/** - @file - - Semaphore and Mutex interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* POSIX interface */ -#if (CSP_POSIX || __DOXYGEN__) - -#include -#include - -/** - Semaphore (or mutex) call OK. - - @note Platform specific (this is Posix) and differs from standard CSP error codes. -*/ -#define CSP_SEMAPHORE_OK 1 -/** - Semaphore (or mutex) call failed. - - @note Platform specific (this is Posix) and differs from standard CSP error codes. -*/ -#define CSP_SEMAPHORE_ERROR 2 - -/** - Semaphore handle. - - @note Platform specific (this is Posix) -*/ -typedef sem_t csp_bin_sem_handle_t; -/** - Mutex handle. - - @note Platform specific (this is Posix) -*/ -typedef pthread_mutex_t csp_mutex_t; - -#endif // CSP_POSIX - -/* MAC OS X interface */ -#if (CSP_MACOSX) - -#include -#include "posix/pthread_queue.h" - -#define CSP_SEMAPHORE_OK PTHREAD_QUEUE_OK -#define CSP_SEMAPHORE_ERROR PTHREAD_QUEUE_EMPTY - -typedef pthread_queue_t * csp_bin_sem_handle_t; -typedef pthread_queue_t * csp_mutex_t; - -#endif // CSP_MACOSX - -#if (CSP_WINDOWS) - -#include - -#define CSP_SEMAPHORE_OK 1 -#define CSP_SEMAPHORE_ERROR 2 - -typedef HANDLE csp_bin_sem_handle_t; -typedef HANDLE csp_mutex_t; - -#endif // CSP_WINDOWS - -/* FreeRTOS interface */ -#if (CSP_FREERTOS) - -#include -#include - -#define CSP_SEMAPHORE_OK pdPASS -#define CSP_SEMAPHORE_ERROR pdFAIL - -typedef xSemaphoreHandle csp_bin_sem_handle_t; -typedef xSemaphoreHandle csp_mutex_t; - -#endif // CSP_FREERTOS - -/** - Mutex call OK. - - @note Value is different from standard CSP error codes, see #CSP_SEMAPHORE_OK -*/ -#define CSP_MUTEX_OK CSP_SEMAPHORE_OK - -/** - Mutex call failed. - - @note Value is different from standard CSP error codes, see #CSP_SEMAPHORE_ERROR -*/ -#define CSP_MUTEX_ERROR CSP_SEMAPHORE_ERROR - -/** - Create/initialize a mutex. - - @param[in] mutex mutex. - @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR -*/ -int csp_mutex_create(csp_mutex_t * mutex); - -/** - Free a mutex. - - @param[in] mutex mutex. - @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR -*/ -int csp_mutex_remove(csp_mutex_t * mutex); - -/** - Lock mutex. - - @param[in] mutex mutex - @param[in] timeout timeout in mS. Use #CSP_MAX_TIMEOUT for no timeout, e.g. wait forever until locked. - @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR -*/ -int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout); - -/** - Unlock mutex. - - @param[in] mutex mutex - @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR -*/ -int csp_mutex_unlock(csp_mutex_t * mutex); - -/** - Create/initialize a binary semaphore. - - The semaphore is created in state \a unlocked (value 1). - - On platforms supporting max values, the semaphore is created with a max value of 1, hence the naming \a binary. - - @param[in] sem semaphore - @return #CSP_SEMAPHORE_OK on success, otherwise #CSP_SEMAPHORE_ERROR -*/ -int csp_bin_sem_create(csp_bin_sem_handle_t * sem); - -/** - Free a semaphore. - - @param[in] sem semaphore. - @return #CSP_SEMAPHORE_OK on success, otherwise #CSP_SEMAPHORE_ERROR -*/ -int csp_bin_sem_remove(csp_bin_sem_handle_t * sem); - -/** - Wait/lock semaphore. - - @param[in] sem semaphore - @param[in] timeout timeout in mS. Use #CSP_MAX_TIMEOUT for no timeout, e.g. wait forever until locked. - @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR -*/ -int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout); - -/** - Signal/unlock semaphore. - - @param[in] sem semaphore - @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR -*/ -int csp_bin_sem_post(csp_bin_sem_handle_t * sem); - -/** - Signal/unlock semaphore from an ISR context. - - @param[in] sem semaphore - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! - @return #CSP_MUTEX_OK on success, otherwise #CSP_MUTEX_ERROR* -*/ -int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * pxTaskWoken); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/csp_system.h b/Program/libcsp/include/csp/arch/csp_system.h deleted file mode 100755 index 87eb506..0000000 --- a/Program/libcsp/include/csp/arch/csp_system.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_SYSTEM_H_ -#define _CSP_SYSTEM_H_ - -/** - @file - - System interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Color mask */ -#define COLOR_MASK_COLOR 0x0F -/** Color modifier mask */ -#define COLOR_MASK_MODIFIER 0xF0 - -/** - Color and color modifiers. -*/ -typedef enum { - /* Colors */ - COLOR_RESET = 0xF0, - COLOR_BLACK = 0x01, - COLOR_RED = 0x02, - COLOR_GREEN = 0x03, - COLOR_YELLOW = 0x04, - COLOR_BLUE = 0x05, - COLOR_MAGENTA = 0x06, - COLOR_CYAN = 0x07, - COLOR_WHITE = 0x08, - /* Modifiers */ - COLOR_NORMAL = 0x0F, - COLOR_BOLD = 0x10, - COLOR_UNDERLINE = 0x20, - COLOR_BLINK = 0x30, - COLOR_HIDE = 0x40, -} csp_color_t; - -/** - Get task list. - Write task list into a pre-allocate buffer. The buffer must be at least the size returned by csp_sys_tasklist_size(). - @param[out] out pre-allocate buffer for returning task. - @return #CSP_ERR_NONE on success. -*/ -int csp_sys_tasklist(char * out); - -/** - Get size of task buffer. - @return Size of task list buffer to allocate for the csp_sys_tasklist(). -*/ -int csp_sys_tasklist_size(void); - -/** - Free system memory. - - @return Free system memory (bytes) -*/ -uint32_t csp_sys_memfree(void); - -/** - Callback function for system reboot request. - @return #CSP_ERR_NONE on success (if function returns at all), or error code. -*/ -typedef int (*csp_sys_reboot_t)(void); - -/** - Set system reboot/reset function. - Function will be called by csp_sys_reboot(). - @param[in] reboot callback. - @see csp_sys_reboot_using_system(), csp_sys_reboot_using_reboot() -*/ -void csp_sys_set_reboot(csp_sys_reboot_t reboot); - -/** - Reboot/reset system. - Reboot/resets the system by calling the function set by csp_sys_set_reboot(). - @return #CSP_ERR_NONE on success (if function returns at all), or error code. -*/ -int csp_sys_reboot(void); - -/** - Callback function for system shutdown request. - @return #CSP_ERR_NONE on success (if function returns at all), or error code. -*/ -typedef int (*csp_sys_shutdown_t)(void); - -/** - Set system shutdown function. - Function will be called by csp_sys_shutdown(). - @param[in] shutdown callback. - @see csp_sys_shutdown_using_system(), csp_sys_shutdown_using_reboot() -*/ -void csp_sys_set_shutdown(csp_sys_shutdown_t shutdown); - -/** - Shutdown system. - Shuts down the system by calling the function set by csp_sys_set_shutdown(). - @return #CSP_ERR_NONE on success (if function returns at all), or error code. -*/ -int csp_sys_shutdown(void); - -/** - Set color on stdout. - @param[in] color color. -*/ -void csp_sys_set_color(csp_color_t color); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/csp_thread.h b/Program/libcsp/include/csp/arch/csp_thread.h deleted file mode 100755 index 6c2df59..0000000 --- a/Program/libcsp/include/csp/arch/csp_thread.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_THREAD_H_ -#define _CSP_THREAD_H_ - -/** - @file - - Thread (task) interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - POSIX interface -*/ -#if (CSP_POSIX || CSP_MACOSX || __DOXYGEN__) - -#include - -/** - Platform specific thread handle. -*/ -typedef pthread_t csp_thread_handle_t; - -/** - Platform specific thread return type. -*/ -typedef void * csp_thread_return_t; - -/** - Platform specific thread function. - @param[in] parameter parameter to thread function #csp_thread_return_t. -*/ -typedef csp_thread_return_t (* csp_thread_func_t)(void * parameter); - -/** - Macro for creating a thread. -*/ -#define CSP_DEFINE_TASK(task_name) csp_thread_return_t task_name(void * param) - -/** - Return value for a thread function. - Can be used as argument for normal return, eg "return CSP_TASK_RETURN"; -*/ -#define CSP_TASK_RETURN NULL - -#endif // CSP_POSIX - -/* - Windows interface -*/ -#if (CSP_WINDOWS) - -#include - -typedef HANDLE csp_thread_handle_t; -typedef unsigned int csp_thread_return_t; -typedef csp_thread_return_t (* csp_thread_func_t)(void *) __attribute__((stdcall)); - -#define CSP_DEFINE_TASK(task_name) csp_thread_return_t __attribute__((stdcall)) task_name(void * param) -#define CSP_TASK_RETURN 0 - -#endif // CSP_WINDOWS - -/* - FreeRTOS interface -*/ -#if (CSP_FREERTOS) - -#include -#include - -typedef xTaskHandle csp_thread_handle_t; -typedef void csp_thread_return_t; -typedef csp_thread_return_t (* csp_thread_func_t)(void *); - -#define CSP_DEFINE_TASK(task_name) csp_thread_return_t task_name(void * param) -#define CSP_TASK_RETURN - -#endif // CSP_FREERTOS - -/** - Create thread (task). - - @param[in] func thread function - @param[in] name name of thread, supported on: FreeRTOS. - @param[in] stack_size stack size, supported on: posix (bytes), FreeRTOS (words, word = 4 bytes). - @param[in] parameter parameter for thread function. - @param[in] priority thread priority, supported on: FreeRTOS. - @param[out] handle reference to created thread. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_thread_create(csp_thread_func_t func, const char * const name, unsigned int stack_size, void * parameter, unsigned int priority, csp_thread_handle_t * handle); - -/** - Exit current thread. - @note Not supported on all platforms. -*/ -void csp_thread_exit(void); - -/** - Sleep X mS. - @param[in] time_ms mS to sleep. -*/ -void csp_sleep_ms(unsigned int time_ms); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/csp_time.h b/Program/libcsp/include/csp/arch/csp_time.h deleted file mode 100755 index f0a3867..0000000 --- a/Program/libcsp/include/csp/arch/csp_time.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_TIME_H_ -#define _CSP_TIME_H_ - -/** - @file - - Relative time interface. - - @note The returned values will eventually wrap. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Return uptime in seconds. - The function uses csp_get_s() for relative time. First time the function is called (by csp_init()), it saves an offset - in case the platform doesn't start from 0, e.g. Linux. - @return uptime in seconds. -*/ -uint32_t csp_get_uptime_s(void); - -/** - Return current time in mS. - @return mS. -*/ -uint32_t csp_get_ms(void); - -/** - Return current time in mS (from ISR). - @return mS. -*/ -uint32_t csp_get_ms_isr(void); - -/** - Return current time in seconds. - @return seconds. -*/ -uint32_t csp_get_s(void); - -/** - Return current time in seconds (from ISR). - @return seconds. -*/ -uint32_t csp_get_s_isr(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/posix/csp_system.h b/Program/libcsp/include/csp/arch/posix/csp_system.h deleted file mode 100755 index 785941d..0000000 --- a/Program/libcsp/include/csp/arch/posix/csp_system.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_ARCH_POSIX_CSP_SYSTEM_H_ -#define _CSP_ARCH_POSIX_CSP_SYSTEM_H_ - -/** - @file - - Posix extension to system interface. -*/ - -#include - -#ifdef __cplusplus -yextern "C" { -#endif - -/** - Executes 'system("reboot")' for system reboot. -*/ -int csp_sys_reboot_using_system(void); - -/** - Executes 'sync() and reboot(LINUX_REBOOT_CMD_RESTART)' for system reboot. -*/ -int csp_sys_reboot_using_reboot(void); - -/** - Executes 'system("halt")' for system shutdown. -*/ -int csp_sys_shutdown_using_system(void); - -/** - Executes 'sync() and reboot(LINUX_REBOOT_CMD_HALT)' for system shutdown. -*/ -int csp_sys_shutdown_using_reboot(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/arch/posix/pthread_queue.h b/Program/libcsp/include/csp/arch/posix/pthread_queue.h deleted file mode 100755 index 19ac0c3..0000000 --- a/Program/libcsp/include/csp/arch/posix/pthread_queue.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _PTHREAD_QUEUE_H_ -#define _PTHREAD_QUEUE_H_ - -/** - @file - - Queue implemented using pthread locks and conds. - - Inspired by c-pthread-queue by Matthew Dickinson: http://code.google.com/p/c-pthread-queue/ -*/ - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Queue error codes. - @{ -*/ -/** - General error code - something went wrong. -*/ -#define PTHREAD_QUEUE_ERROR CSP_QUEUE_ERROR -/** - Queue is empty - cannot extract element. -*/ -#define PTHREAD_QUEUE_EMPTY CSP_QUEUE_ERROR -/** - Queue is full - cannot insert element. -*/ -#define PTHREAD_QUEUE_FULL CSP_QUEUE_ERROR -/** - Ok - no error. -*/ -#define PTHREAD_QUEUE_OK CSP_QUEUE_OK -/** @{ */ - -/** - Queue handle. -*/ -typedef struct pthread_queue_s { - //! Memory area. - void * buffer; - //! Memory size. - int size; - //! Item/element size. - int item_size; - //! Items/elements in queue. - int items; - //! Insert point. - int in; - //! Extract point. - int out; - //! Lock. - pthread_mutex_t mutex; - //! Wait because queue is full (insert). - pthread_cond_t cond_full; - //! Wait because queue is empty (extract). - pthread_cond_t cond_empty; -} pthread_queue_t; - -/** - Create queue. -*/ -pthread_queue_t * pthread_queue_create(int length, size_t item_size); - -/** - Delete queue. -*/ -void pthread_queue_delete(pthread_queue_t * q); - -/** - Enqueue/insert element. -*/ -int pthread_queue_enqueue(pthread_queue_t * queue, const void * value, uint32_t timeout); - -/** - Dequeue/extract element. -*/ -int pthread_queue_dequeue(pthread_queue_t * queue, void * buf, uint32_t timeout); - -/** - Return number of elements in the queue. -*/ -int pthread_queue_items(pthread_queue_t * queue); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/crypto/csp_hmac.h b/Program/libcsp/include/csp/crypto/csp_hmac.h deleted file mode 100755 index 31eabb4..0000000 --- a/Program/libcsp/include/csp/crypto/csp_hmac.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_CRYPTO_HMAC_H_ -#define _CSP_CRYPTO_HMAC_H_ - -/** - @file - HMAC support. - - Hash-based Message Authentication Code - based on code from libtom.org. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Number of bytes from the HMAC calculation, that is appended to the CSP message. -*/ -#define CSP_HMAC_LENGTH 4 - -/** - * Append HMAC to packet - * @param packet CSP packet, must be valid. - * @param include_header use header in hmac calculation (this will not modify the flags field) - * @return #CSP_ERR_NONE on success, otherwise an error code. - */ -int csp_hmac_append(csp_packet_t * packet, bool include_header); - -/** - * Verify HMAC of packet - * @param packet CSP packet, must be valid. - * @param include_header use header in hmac calculation (this will not modify the flags field) - * @return #CSP_ERR_NONE on success, otherwise an error code. - */ -int csp_hmac_verify(csp_packet_t * packet, bool include_header); - -/** - * Calculate HMAC on buffer - * - * This function is used by append/verify but cal also be called separately. - * @param key HMAC key - * @param keylen HMAC key length - * @param data pointer to data - * @param datalen lehgth of data - * @param[out] hmac calculated HMAC hash, minimum #CSP_SHA1_DIGESTSIZE bytes. - * @return #CSP_ERR_NONE on success, otherwise an error code. - */ -int csp_hmac_memory(const void * key, uint32_t keylen, const void * data, uint32_t datalen, uint8_t * hmac); - -/** - * Save a copy of the key string for use by the append/verify functions - * @param key HMAC key - * @param keylen HMAC key length - * @return #CSP_ERR_NONE on success, otherwise an error code. - */ -int csp_hmac_set_key(const void * key, uint32_t keylen); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/crypto/csp_sha1.h b/Program/libcsp/include/csp/crypto/csp_sha1.h deleted file mode 100755 index 43b4a67..0000000 --- a/Program/libcsp/include/csp/crypto/csp_sha1.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_CRYPTO_SHA1_H_ -#define _CSP_CRYPTO_SHA1_H_ - -/** - @file - SHA1 support. - - Code originally from Python's SHA1 Module, who based it on libtom.org. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** The SHA1 block size in bytes */ -#define CSP_SHA1_BLOCKSIZE 64 - -/** The SHA1 digest (hash) size in bytes */ -#define CSP_SHA1_DIGESTSIZE 20 - -/** - SHA1 state. -*/ -typedef struct { - //! Internal SHA1 state. - uint64_t length; - //! Internal SHA1 state. - uint32_t state[5]; - //! Internal SHA1 state. - uint32_t curlen; - //! Internal SHA1 state. - uint8_t buf[CSP_SHA1_BLOCKSIZE]; -} csp_sha1_state_t; - -/** - Initialize the hash state - @param[in] state hash state. -*/ -void csp_sha1_init(csp_sha1_state_t * state); - -/** - Process a block of memory through the hash. - @param[in] state hash state - @param[in] data data. - @param[in] length length of \a data. -*/ -void csp_sha1_process(csp_sha1_state_t * state, const void * data, uint32_t length); - -/** - Terminate the hash calculation and get the SHA1. - @param[in] state hash state - @param[out] sha1 user supplied buffer of minimum #CSP_SHA1_DIGESTSIZE bytes. -*/ -void csp_sha1_done(csp_sha1_state_t * state, uint8_t * sha1); - -/** - Calculate SHA1 hash of block of memory. - @param[in] data data. - @param[in] length length of \a data. - @param[out] sha1 user supplied buffer of minimum #CSP_SHA1_DIGESTSIZE bytes. -*/ -void csp_sha1_memory(const void * data, uint32_t length, uint8_t * sha1); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/crypto/csp_xtea.h b/Program/libcsp/include/csp/crypto/csp_xtea.h deleted file mode 100755 index 3324e62..0000000 --- a/Program/libcsp/include/csp/crypto/csp_xtea.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_CRYPTO_XTEA_H_ -#define _CSP_CRYPTO_XTEA_H_ - -/** - @file - XTEA support. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Set XTEA key - @param[in] key XTEA key - @param[in] keylen length of key - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_xtea_set_key(const void * key, uint32_t keylen); - -/** - XTEA encrypt byte array - @param[in] data data to be encrypted. - @param[in] len Length of \a data. - @param[in] iv Initialization vector - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_xtea_encrypt(void * data, uint32_t len, uint32_t iv[2]); - -/** - XTEA encrypt message. - @param packet CSP packet, must be valid. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_xtea_encrypt_packet(csp_packet_t * packet); - -/** - Decrypt XTEA encrypted byte array. - @param[in,out] encrypted data be decrypted. - @param[in] len length of \a encrypted data. - @param[in] iv Initialization vector. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_xtea_decrypt(void * encrypted, uint32_t len, uint32_t iv[2]); - -/** - XTEA decrypt message. - @param packet CSP packet, must be valid. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_xtea_decrypt_packet(csp_packet_t * packet); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp.h b/Program/libcsp/include/csp/csp.h deleted file mode 100755 index 959fbd2..0000000 --- a/Program/libcsp/include/csp/csp.h +++ /dev/null @@ -1,491 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_H_ -#define _CSP_H_ - -/** - @file - CSP. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - CSP configuration. - @see csp_init() -*/ -typedef struct csp_conf_s { - - uint8_t address; /**< CSP address of the system */ - - const char *hostname; /**< Host name, returned by the #CSP_CMP_IDENT request */ - const char *model; /**< Model, returned by the #CSP_CMP_IDENT request */ - const char *revision; /**< Revision, returned by the #CSP_CMP_IDENT request */ - - uint8_t conn_max; /**< Max number of connections. A fixed connection array is allocated by csp_init() */ - uint8_t conn_queue_length; /**< Max queue length (max queued Rx messages). */ - uint8_t fifo_length; /**< Length of incoming message queue, used for handover to router task. */ - uint8_t port_max_bind; /**< Max/highest port for use with csp_bind() */ - uint8_t rdp_max_window; /**< Max RDP window size */ - uint16_t buffers; /**< Number of CSP buffers */ - uint16_t buffer_data_size; /**< Data size of a CSP buffer. Total size will be sizeof(#csp_packet_t) + data_size. */ - uint32_t conn_dfl_so; /**< Default connection options. Options will always be or'ed onto new connections, see csp_connect() */ -} csp_conf_t; - -/** - Get default CSP configuration. -*/ -static inline void csp_conf_get_defaults(csp_conf_t * conf) { - conf->address = 1; - conf->hostname = "hostname"; - conf->model = "model"; - conf->revision = "resvision"; - conf->conn_max = 10; - conf->conn_queue_length = 10; - conf->fifo_length = 25; - conf->port_max_bind = 24; - conf->rdp_max_window = 20; - conf->buffers = 10; - conf->buffer_data_size = 256; - conf->conn_dfl_so = CSP_O_NONE; -} - -/** - Initialize CSP. - This will configure/allocate basic structures. - @param[in] conf configuration. A shallow copy will be done of the provided configuration, i.e. only copy references to strings/structers. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_init(const csp_conf_t * conf); - -/** - Free allocated resorces in CSP. - This is intended for testing of CSP, in order to be able re-initialize CSP by calling csp_init() again. -*/ -void csp_free_resources(void); - -/** - Get a \a read-only reference to the active CSP configuration. - @return Active CSP configuration (read-only). -*/ -const csp_conf_t * csp_get_conf(void); - -/** - Get the system's own address. - @return system's own address -*/ -uint8_t csp_get_address(void); - -/** - Create a CSP socket endpoint. - @param[in] opts socket options, see @ref CSP_SOCKET_OPTIONS. - @return Socket on success, NULL on failure -*/ -csp_socket_t *csp_socket(uint32_t opts); - -/** - Wait/accept a new connection. - @param[in] socket socket to accept connections on, created by calling csp_socket(). - @param[in] timeout timeout in mS to wait for a connection, use #CSP_MAX_TIMEOUT for infinite timeout. - @return New connection on success, NULL on failure or timeout. -*/ -csp_conn_t *csp_accept(csp_socket_t *socket, uint32_t timeout); - -/** - Read packet from a connection. - This fuction will wait on the connection's RX queue for the specified timeout. - @param[in] conn connection - @param[in] timeout timeout in mS to wait for a packet, use #CSP_MAX_TIMEOUT for infinite timeout. - @return Packet or NULL in case of failure or timeout. -*/ -csp_packet_t *csp_read(csp_conn_t *conn, uint32_t timeout); - -/** - Send packet on a connection. - @param[in] conn connection - @param[in] packet packet to send - @param[in] timeout unused as of CSP version 1.6 - @return 1 on success, 0 on failure and the packet must be freed by calling csp_buffer_free() -*/ -int csp_send(csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout); - -/** - Change the default priority of the connection and send a packet. - @note The priority of the connection will be changed. If you need to change it back, call csp_send_prio() again. - - @param[in] prio priority to set on the connection - @param[in] conn connection - @param[in] packet packet to send - @param[in] timeout unused as of CSP version 1.6 - @return 1 on success, 0 on failure and the packet must be freed by calling csp_buffer_free() - */ -int csp_send_prio(uint8_t prio, csp_conn_t *conn, csp_packet_t *packet, uint32_t timeout); - -/** - Perform an entire request & reply transaction. - Creates a connection, send \a outbuf, wait for reply, copy reply to \a inbuf and close the connection. - @param[in] prio priority, see #csp_prio_t - @param[in] dst destination address - @param[in] dst_port destination port - @param[in] timeout timeout in mS to wait for a reply - @param[in] outbuf outgoing data (request) - @param[in] outlen length of data in \a outbuf (request) - @param[out] inbuf user provided buffer for receiving data (reply) - @param[in] inlen length of expected reply, -1 for unknown size (inbuf MUST be large enough), 0 for no reply. - @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. - @return 1 or reply size on success, 0 on failure (error, incoming length does not match, timeout) -*/ -int csp_transaction_w_opts(uint8_t prio, uint8_t dst, uint8_t dst_port, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen, uint32_t opts); - -/** - Perform an entire request & reply transaction. - Creates a connection, send \a outbuf, wait for reply, copy reply to \a inbuf and close the connection. - @param[in] prio priority, see #csp_prio_t - @param[in] dest destination address - @param[in] port destination port - @param[in] timeout timeout in mS to wait for a reply - @param[in] outbuf outgoing data (request) - @param[in] outlen length of data in \a outbuf (request) - @param[out] inbuf user provided buffer for receiving data (reply) - @param[in] inlen length of expected reply, -1 for unknown size (inbuf MUST be large enough), 0 for no reply. - @return 1 or reply size on success, 0 on failure (error, incoming length does not match, timeout) -*/ -static inline int csp_transaction(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void * outbuf, int outlen, void * inbuf, int inlen) { - return csp_transaction_w_opts(prio, dest, port, timeout, outbuf, outlen, inbuf, inlen, 0); -} - -/** - Perform an entire request & reply transaction on an existing connection. - Send \a outbuf, wait for reply and copy reply to \a inbuf. - @param[in] conn connection - @param[in] timeout timeout in mS to wait for a reply - @param[in] outbuf outgoing data (request) - @param[in] outlen length of data in \a outbuf (request) - @param[out] inbuf user provided buffer for receiving data (reply) - @param[in] inlen length of expected reply, -1 for unknown size (inbuf MUST be large enough), 0 for no reply. - @return 1 or reply size on success, 0 on failure (error, incoming length does not match, timeout) -*/ -int csp_transaction_persistent(csp_conn_t *conn, uint32_t timeout, void *outbuf, int outlen, void *inbuf, int inlen); - -/** - Read data from a connection-less server socket. - @param[in] socket connection-less socket. - @param[in] timeout timeout in mS to wait for a packet, use #CSP_MAX_TIMEOUT for infinite timeout. - @return Packet on success, or NULL on failure or timeout. -*/ -csp_packet_t *csp_recvfrom(csp_socket_t *socket, uint32_t timeout); - -/** - Send a packet (without connection). - @param[in] prio packet priority, see #csp_prio_t - @param[in] dst destination address - @param[in] dst_port destination port - @param[in] src_port source port - @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. - @param[in] packet packet to send - @param[in] timeout unused as of CSP version 1.6 - @return #CSP_ERR_NONE on success, otherwise an error code and the packet must be freed by calling csp_buffer_free(). -*/ -int csp_sendto(uint8_t prio, uint8_t dst, uint8_t dst_port, uint8_t src_port, uint32_t opts, csp_packet_t *packet, uint32_t timeout); - -/** - Send a packet as a reply to a request (without a connection). - Calls csp_sendto() with the source address and port from the request. - @param[in] request incoming request - @param[in] reply reply packet - @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. - @param[in] timeout unused as of CSP version 1.6 - @return #CSP_ERR_NONE on success, otherwise an error code and the reply must be freed by calling csp_buffer_free(). -*/ -int csp_sendto_reply(const csp_packet_t * request, csp_packet_t * reply, uint32_t opts, uint32_t timeout); - -/** - Establish outgoing connection. - The call will return immediately, unless it is a RDP connection (#CSP_O_RDP) in which case it will wait until the other - end acknowleges the connection (timeout is determined by the current connection timeout set by csp_rdp_set_opt()). - @param[in] prio priority, see #csp_prio_t - @param[in] dst Destination address - @param[in] dst_port Destination port - @param[in] timeout unused. - @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. - @return Established connection or NULL on failure (no free connections, timeout). -*/ -csp_conn_t *csp_connect(uint8_t prio, uint8_t dst, uint8_t dst_port, uint32_t timeout, uint32_t opts); - -/** - Close an open connection. - Any packets in the RX queue will be freed. - @param[in] conn connection. Closing a NULL connection is acceptable. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_close(csp_conn_t *conn); - -/** - Return destination port of connection. - @param[in] conn connection - @return destination port of an incoming connection -*/ -int csp_conn_dport(csp_conn_t *conn); - -/** - Return source port of connection. - @param conn connection - @return source port of an incoming connection -*/ -int csp_conn_sport(csp_conn_t *conn); - -/** - Return destination address of connection. - @param[in] conn connection - @return destination address of an incoming connection -*/ -int csp_conn_dst(csp_conn_t *conn); - -/** - Return source address of connection. - @param conn connection - @return source address of an incoming connection -*/ -int csp_conn_src(csp_conn_t *conn); - -/** - Return flags of connection. - @param[in] conn connection - @return flags of an incoming connection, see @ref CSP_HEADER_FLAGS -*/ -int csp_conn_flags(csp_conn_t *conn); - -/** - Set socket to listen for incoming connections. - @param[in] socket socket - @param[in] backlog max length of backlog queue. The backlog queue holds incoming connections, waiting to be returned by call to csp_accept(). - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_listen(csp_socket_t *socket, size_t backlog); - -/** - Bind port to socket. - @param[in] socket socket to bind port to - @param[in] port port number to bind, use #CSP_ANY for all ports. Bindnig to a specific will take precedence over #CSP_ANY. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_bind(csp_socket_t *socket, uint8_t port); - -/** - Start the router task. - The router task calls csp_route_work() to do the actual work. - @param[in] task_stack_size stack size for the task, see csp_thread_create() for details on the stack size parameter. - @param[in] task_priority priority for the task, see csp_thread_create() for details on the stack size parameter. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_route_start_task(unsigned int task_stack_size, unsigned int task_priority); - -/** - Route packet from the incoming router queue and check RDP timeouts. - In order for incoming packets to routed and RDP timeouts to be checked, this function must be called reguarly. - If the router task is started by calling csp_route_start_task(), there function should not be called. - @param[in] timeout timeout in mS to wait for an incoming packet. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_route_work(uint32_t timeout); - -/** - Start the bridge task. - The bridge will copy packets between interfaces, i.e. packets received on A will be sent on B, and vice versa. - @param[in] task_stack_size stack size for the task, see csp_thread_create() for details on the stack size parameter. - @param[in] task_priority priority for the task, see csp_thread_create() for details on the stack size parameter. - @param[in] if_a interface/side A - @param[in] if_b interface/side B - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_bridge_start(unsigned int task_stack_size, unsigned int task_priority, csp_iface_t * if_a, csp_iface_t * if_b); - -/** - Handle CSP service request. - If the given packet is a service-request (the destination port matches one of CSP service ports #csp_service_port_t), - the packet will be processed by the specific CSP service handler. - The packet will either process it or free it, so this function is typically called in the last "default" clause of - a switch/case statement in a CSP listener task. - In order to listen to csp service ports, bind your listener to the specific services ports #csp_service_port_t or - use #CSP_ANY to all ports. - @param[in] conn connection - @param[in] packet first packet, obtained by using csp_read() -*/ -void csp_service_handler(csp_conn_t *conn, csp_packet_t *packet); - -/** - Send a single ping/echo packet. - @param[in] node address of subsystem. - @param[in] timeout timeout in ms to wait for reply. - @param[in] size payload size in bytes. - @param[in] opts connection options, see @ref CSP_CONNECTION_OPTIONS. - @return >0 = echo time in mS on success, otherwise -1 for error. -*/ -int csp_ping(uint8_t node, uint32_t timeout, unsigned int size, uint8_t opts); - -/** - Send a single ping/echo packet without waiting for reply. - Payload is 1 byte. - @param[in] node address of subsystem. -*/ -void csp_ping_noreply(uint8_t node); - -/** - Request process list. - @note This is currently only supported on FreeRTOS systems. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for replies. The function will not return until the timeout occurrs. -*/ -void csp_ps(uint8_t node, uint32_t timeout); - -/** - Request free memory. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply. - @param[out] size free memory on subsystem. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_get_memfree(uint8_t node, uint32_t timeout, uint32_t * size); - -/** - Request free memory and print to stdout. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply. -*/ -void csp_memfree(uint8_t node, uint32_t timeout); - -/** - Request free buffers. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply. - @param[out] size free buffers. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_get_buf_free(uint8_t node, uint32_t timeout, uint32_t * size); - -/** - Request free buffers and print to stdout. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply. -*/ -void csp_buf_free(uint8_t node, uint32_t timeout); - -/** - Reboot subsystem. - If handled by the standard CSP service handler, the reboot handler set by csp_sys_set_reboot() on the subsystem, will be invoked. - @param[in] node address of subsystem. -*/ -void csp_reboot(uint8_t node); - -/** - Shutdown subsystem. - If handled by the standard CSP service handler, the shutdown handler set by csp_sys_set_shutdown() on the subsystem, will be invoked. - @param[in] node address of subsystem. -*/ -void csp_shutdown(uint8_t node); - -/** - Request uptime and print to stdout. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply. -*/ -void csp_uptime(uint8_t node, uint32_t timeout); - -/** - Request uptime - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply. - @param[out] uptime uptime in seconds. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_get_uptime(uint8_t node, uint32_t timeout, uint32_t * uptime); - -/** - Set RDP options. - The RDP options are used from the connecting/client side. When a RDP connection is established, the client tranmits the options to the server. - @param[in] window_size window size - @param[in] conn_timeout_ms connection timeout in mS - @param[in] packet_timeout_ms packet timeout in mS. - @param[in] delayed_acks enable/disable delayed acknowledgements. - @param[in] ack_timeout acknowledgement timeout when delayed ACKs is enabled - @param[in] ack_delay_count send acknowledgement for every ack_delay_count packets. -*/ -void csp_rdp_set_opt(unsigned int window_size, unsigned int conn_timeout_ms, - unsigned int packet_timeout_ms, unsigned int delayed_acks, - unsigned int ack_timeout, unsigned int ack_delay_count); - -/** - Get RDP options. - @see csp_rdp_set_opt() - @param[out] window_size Window size - @param[out] conn_timeout_ms connection timeout in ms - @param[out] packet_timeout_ms packet timeout in ms - @param[out] delayed_acks enable/disable delayed acknowledgements - @param[out] ack_timeout acknowledgement timeout when delayed ACKs is enabled - @param[out] ack_delay_count send acknowledgement for every ack_delay_count packets -*/ -void csp_rdp_get_opt(unsigned int *window_size, unsigned int *conn_timeout_ms, - unsigned int *packet_timeout_ms, unsigned int *delayed_acks, - unsigned int *ack_timeout, unsigned int *ack_delay_count); - -/** - Print connection table to stdout. -*/ -void csp_conn_print_table(void); - -/** - Print connection table to string. -*/ -int csp_conn_print_table_str(char * str_buf, int str_size); - -/** - Print buffer usage table to stdout. -*/ -void csp_buffer_print_table(void); - -/** - Hex dump memory to stdout. - @param[in] desc description printed on first line. - @param[in] addr memory address. - @param[in] len number of bytes to dump, starting from \a addr. -*/ -void csp_hex_dump(const char *desc, void *addr, int len); - -/** - Set platform specific memory copy function. -*/ -void csp_cmp_set_memcpy(csp_memcpy_fnc_t fnc); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_buffer.h b/Program/libcsp/include/csp/csp_buffer.h deleted file mode 100755 index d8d9752..0000000 --- a/Program/libcsp/include/csp/csp_buffer.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_BUFFER_H_ -#define _CSP_BUFFER_H_ - -/** - @file - Message buffer. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Get free buffer (from task context). - - @param[in] data_size minimum data size of requested buffer. - @return Buffer (pointer to #csp_packet_t) or NULL if no buffers available or size too big. -*/ -void * csp_buffer_get(size_t data_size); - -/** - Get free buffer (from ISR context). - - @param[in] data_size minimum data size of requested buffer. - @return Buffer (pointer to #csp_packet_t) or NULL if no buffers available or size too big. -*/ -void * csp_buffer_get_isr(size_t data_size); - -/** - Free buffer (from task context). - @param[in] buffer buffer to free. NULL is handled gracefully. -*/ -void csp_buffer_free(void *buffer); - -/** - Free buffer (from ISR context). - @param[in] buffer buffer to free. NULL is handled gracefully. -*/ -void csp_buffer_free_isr(void *buffer); - -/** - Clone an existing buffer. - The existing \a buffer content is copied to the new buffer. - @param[in] buffer buffer to clone. - @return cloned buffer on success, or NULL on failure. -*/ -void * csp_buffer_clone(void *buffer); - -/** - Return number of remaining/free buffers. - The number of buffers is set by csp_init(). - @return number of remaining/free buffers -*/ -int csp_buffer_remaining(void); - -/** - Return the size of a CSP buffer. - @return size of a CSP buffer, sizeof(#csp_packet_t) + data_size. -*/ -size_t csp_buffer_size(void); - -/** - Return the data size of a CSP buffer. - The data size is set by csp_init(). - @return data size of a CSP buffer -*/ -size_t csp_buffer_data_size(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_cmp.h b/Program/libcsp/include/csp/csp_cmp.h deleted file mode 100755 index 58d5b57..0000000 --- a/Program/libcsp/include/csp/csp_cmp.h +++ /dev/null @@ -1,214 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_CMP_H_ -#define _CSP_CMP_H_ - -/** - @file - CSP Management Protocol (CMP). -*/ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - CMP type. - @{ -*/ -/** - CMP request. -*/ -#define CSP_CMP_REQUEST 0x00 -/** - CMP reply. -*/ -#define CSP_CMP_REPLY 0xff -/**@}*/ - -/** - CMP requests. - @{ -*/ -/** - CMP request codes. -*/ -/** - Request identification, compile time, revision, hostname and model. -*/ -#define CSP_CMP_IDENT 1 -/** - Set/configure routing. -*/ -#define CSP_CMP_ROUTE_SET 2 -/** - Request interface statistics. -*/ -#define CSP_CMP_IF_STATS 3 -/** - Peek/read data from memory. -*/ -#define CSP_CMP_PEEK 4 -/** - Poke/write data from memory. -*/ -#define CSP_CMP_POKE 5 -/** - Get/set clock. -*/ -#define CSP_CMP_CLOCK 6 -/**@}*/ - -/** - CMP identification - max revision length. -*/ -#define CSP_CMP_IDENT_REV_LEN 20 -/** - CMP identification - max date length. -*/ -#define CSP_CMP_IDENT_DATE_LEN 12 -/** - CMP identification - max time length. -*/ -#define CSP_CMP_IDENT_TIME_LEN 9 - -/** - CMP interface statistics - max interface name length. -*/ -#define CSP_CMP_ROUTE_IFACE_LEN 11 - -/** - CMP peek/read memeory - max read length. -*/ -#define CSP_CMP_PEEK_MAX_LEN 200 - -/** - CMP poke/write memeory - max write length. -*/ -#define CSP_CMP_POKE_MAX_LEN 200 - -/** - CSP management protocol description. -*/ -struct csp_cmp_message { - //! CMP request type. - uint8_t type; - //! CMP request code. - uint8_t code; - union { - struct { - char hostname[CSP_HOSTNAME_LEN]; - char model[CSP_MODEL_LEN]; - char revision[CSP_CMP_IDENT_REV_LEN]; - char date[CSP_CMP_IDENT_DATE_LEN]; - char time[CSP_CMP_IDENT_TIME_LEN]; - } ident; - struct { - uint8_t dest_node; - uint8_t next_hop_via; - char interface[CSP_CMP_ROUTE_IFACE_LEN]; - } route_set; - struct __attribute__((__packed__)) { - char interface[CSP_CMP_ROUTE_IFACE_LEN]; - uint32_t tx; - uint32_t rx; - uint32_t tx_error; - uint32_t rx_error; - uint32_t drop; - uint32_t autherr; - uint32_t frame; - uint32_t txbytes; - uint32_t rxbytes; - uint32_t irq; - } if_stats; - struct { - uint32_t addr; - uint8_t len; - char data[CSP_CMP_PEEK_MAX_LEN]; - } peek; - struct { - uint32_t addr; - uint8_t len; - char data[CSP_CMP_POKE_MAX_LEN]; - } poke; - csp_timestamp_t clock; - }; -} __attribute__ ((packed)); - -/** - Macro for calculating total size of management message. -*/ -#define CMP_SIZE(_memb) (sizeof(((struct csp_cmp_message *)0)->type) + sizeof(((struct csp_cmp_message *)0)->code) + sizeof(((struct csp_cmp_message *)0)->_memb)) - -/** - Generic send management message request. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply.. - @param[in] code request code. - @param[in] msg_size size of \a msg. - @param[in,out] msg data. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_cmp(uint8_t node, uint32_t timeout, uint8_t code, int msg_size, struct csp_cmp_message *msg); - -/** - Macro for defining management handling function. -*/ -#define CMP_MESSAGE(_code, _memb) \ -static inline int csp_cmp_##_memb(uint8_t node, uint32_t timeout, struct csp_cmp_message *msg) { \ - return csp_cmp(node, timeout, _code, CMP_SIZE(_memb), msg); \ -} - -CMP_MESSAGE(CSP_CMP_IDENT, ident) -CMP_MESSAGE(CSP_CMP_ROUTE_SET, route_set) -CMP_MESSAGE(CSP_CMP_IF_STATS, if_stats) -CMP_MESSAGE(CSP_CMP_CLOCK, clock) - -/** - Peek (read) memory on remote node. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply.. - @param[in] msg memory address and number of bytes to peek. - @param[out] msg peeked/read memory. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -static inline int csp_cmp_peek(uint8_t node, uint32_t timeout, struct csp_cmp_message *msg) { - return csp_cmp(node, timeout, CSP_CMP_PEEK, CMP_SIZE(peek) - sizeof(msg->peek.data) + msg->peek.len, msg); -} - -/** - Poke (write) memory on remote node. - @param[in] node address of subsystem. - @param[in] timeout timeout in mS to wait for reply.. - @param[in] msg memory address, number of bytes and the actual bytes to poke/write. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -static inline int csp_cmp_poke(uint8_t node, uint32_t timeout, struct csp_cmp_message *msg) { - return csp_cmp(node, timeout, CSP_CMP_POKE, CMP_SIZE(poke) - sizeof(msg->poke.data) + msg->poke.len, msg); -} - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_crc32.h b/Program/libcsp/include/csp/csp_crc32.h deleted file mode 100755 index 5ff92eb..0000000 --- a/Program/libcsp/include/csp/csp_crc32.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_CRC32_H_ -#define _CSP_CRC32_H_ - -/** - @file - CRC32 support. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Append CRC32 checksum to packet - @param[in] packet CSP packet, must be valid. - @param[in] include_header include the CSP header in the CRC32, otherwise just the data part. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_crc32_append(csp_packet_t * packet, bool include_header); - -/** - Verify CRC32 checksum on packet. - @param[in] packet CSP packet, must be valid. - @param[in] include_header include the CSP header in the CRC32, otherwise just the data part. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_crc32_verify(csp_packet_t * packet, bool include_header); - -/** - Calculate checksum for a given memory area. - @param[in] addr memory address - @param[in] length length of memory to do checksum on - @return checksum -*/ -uint32_t csp_crc32_memory(const uint8_t * addr, uint32_t length); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_debug.h b/Program/libcsp/include/csp/csp_debug.h deleted file mode 100755 index f01b547..0000000 --- a/Program/libcsp/include/csp/csp_debug.h +++ /dev/null @@ -1,226 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_DEBUG_H_ -#define _CSP_DEBUG_H_ - -/** - @file - Debug and log. -*/ - -#include -#include -#include -#include - -#include - -#if (CSP_USE_EXTERNAL_DEBUG) -/* Use external csp_debug API */ -#include - -#else - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Debug levels. -*/ -typedef enum { - CSP_ERROR = 0, //!< Error - CSP_WARN = 1, //!< Warning - CSP_INFO = 2, //!< Informational - CSP_BUFFER = 3, //!< Buffer, e.g. csp_packet get/free - CSP_PACKET = 4, //!< Packet routing - CSP_PROTOCOL = 5, //!< Protocol, i.e. RDP - CSP_LOCK = 6, //!< Locking, i.e. semaphore -} csp_debug_level_t; - -/** - Debug level enabled/disabled. -*/ -extern bool csp_debug_level_enabled[]; - -/** - Extract filename component from path -*/ -#define BASENAME(_file) ((strrchr(_file, '/') ? : (strrchr(_file, '\\') ? : _file)) + 1) - -/** - Implement csp_assert_fail_action to override default failure action -*/ -extern void __attribute__((weak)) csp_assert_fail_action(const char *assertion, const char *file, int line); - -/** - CSP assert. -*/ -#if (!defined(NDEBUG) || CSP_USE_ASSERT) -#define csp_assert(exp) { \ - if (!(exp)) { \ - const char *assertion = #exp; \ - const char *file = BASENAME(__FILE__); \ - int line = __LINE__; \ - printf("\E[1;31mAssertion \'%s\' failed in %s:%d\E[0m\r\n", \ - assertion, file, line); \ - if (csp_assert_fail_action) \ - csp_assert_fail_action(assertion, file, line); \ - } \ - } -#else -#define csp_assert(...) {} -#endif - -#if !(__DOXYGEN__) -/* Ensure defines are 'defined' */ -#if !defined(CSP_DEBUG) -#define CSP_DEBUG 0 -#endif - -#if !defined(CSP_LOG_LEVEL_DEBUG) -#define CSP_LOG_LEVEL_DEBUG 0 -#endif - -#if !defined(CSP_LOG_LEVEL_INFO) -#define CSP_LOG_LEVEL_INFO 0 -#endif - -#if !defined(CSP_LOG_LEVEL_WARN) -#define CSP_LOG_LEVEL_WARN 0 -#endif - -#if !defined(CSP_LOG_LEVEL_ERROR) -#define CSP_LOG_LEVEL_ERROR 0 -#endif -#endif // __DOXYGEN__ - -#ifdef __AVR__ - #include - #include - #define CONSTSTR(data) PSTR(data) - #undef printf - #undef sscanf - #undef scanf - #undef sprintf - #undef snprintf - #define printf(s, ...) printf_P(PSTR(s), ## __VA_ARGS__) - #define sscanf(buf, s, ...) sscanf_P(buf, PSTR(s), ## __VA_ARGS__) - #define scanf(s, ...) scanf_P(PSTR(s), ## __VA_ARGS__) - #define sprintf(buf, s, ...) sprintf_P(buf, PSTR(s), ## __VA_ARGS__) - #define snprintf(buf, size, s, ...) snprintf_P(buf, size, PSTR(s), ## __VA_ARGS__) -#define csp_debug(level, format, ...) { if (CSP_DEBUG && csp_debug_level_enabled[level]) do_csp_debug(level, PSTR(format), ##__VA_ARGS__); } -#else -/** - * Log message with specific level. - * @param level log level - * @param format log message, printf syntax. - */ -#define csp_debug(level, format, ...) { if (CSP_DEBUG && csp_debug_level_enabled[level]) do_csp_debug(level, format, ##__VA_ARGS__); } -#endif - -/** - * Log message with level #CSP_ERROR. - * @param format log message, printf syntax. - */ -#define csp_log_error(format, ...) { if (CSP_LOG_LEVEL_ERROR) csp_debug(CSP_ERROR, format, ##__VA_ARGS__); } - -/** - * Log message with level #CSP_WARN. - * @param format log message, printf syntax. - */ -#define csp_log_warn(format, ...) { if (CSP_LOG_LEVEL_WARN) csp_debug(CSP_WARN, format, ##__VA_ARGS__); } - -/** - * Log message with level #CSP_INFO. - * @param format log message, printf syntax. - */ -#define csp_log_info(format, ...) { if (CSP_LOG_LEVEL_INFO) csp_debug(CSP_INFO, format, ##__VA_ARGS__); } - -/** - * Log message with level #CSP_BUFFER. - * @param format log message, printf syntax. - */ -#define csp_log_buffer(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_BUFFER, format, ##__VA_ARGS__); } - -/** - * Log message with level #CSP_PACKET. - * @param format log message, printf syntax. - */ -#define csp_log_packet(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_PACKET, format, ##__VA_ARGS__); } - -/** - * Log message with level #CSP_PROTOCOL. - * @param format log message, printf syntax. - */ -#define csp_log_protocol(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_PROTOCOL, format, ##__VA_ARGS__); } - -/** - * Log message with level #CSP_LOCK. - * @param format log message, printf syntax. - */ -#define csp_log_lock(format, ...) { if (CSP_LOG_LEVEL_DEBUG) csp_debug(CSP_LOCK, format, ##__VA_ARGS__); } - -/** - * Do the actual logging (don't use directly). - * @note Use the csp_log_() macros instead. - * @param level log level - * @param format log message, printf syntax. - */ -void do_csp_debug(csp_debug_level_t level, const char *format, ...) __attribute__ ((format (__printf__, 2, 3))); - -/** - * Toggle debug level on/off - * @param level Level to toggle - */ -void csp_debug_toggle_level(csp_debug_level_t level); - -/** - * Set debug level - * @param level Level to set - * @param value New level value - */ -void csp_debug_set_level(csp_debug_level_t level, bool value); - -/** - * Get current debug level value - * @param level Level to get - * @return Level value - */ -int csp_debug_get_level(csp_debug_level_t level); - -/** - * Debug hook function. - */ -typedef void (*csp_debug_hook_func_t)(csp_debug_level_t level, const char *format, va_list args); - -/** - * Set debug/log hook function. - */ -void csp_debug_hook_set(csp_debug_hook_func_t f); - -#ifdef __cplusplus -} -#endif - -#endif // CSP_USE_EXTERNAL_DEBUG - -#endif // _CSP_DEBUG_H_ diff --git a/Program/libcsp/include/csp/csp_endian.h b/Program/libcsp/include/csp/csp_endian.h deleted file mode 100755 index 6ffe1d4..0000000 --- a/Program/libcsp/include/csp/csp_endian.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_ENDIAN_H_ -#define _CSP_ENDIAN_H_ - -/** - @file - Endian support. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Convert from host order to network order. -*/ -uint16_t csp_hton16(uint16_t h16); - -/** - Convert from network order to host order. -*/ -uint16_t csp_ntoh16(uint16_t n16); - -/** - Convert from host order to network order. -*/ -uint32_t csp_hton32(uint32_t h32); - -/** - Convert from network order to host order. -*/ -uint32_t csp_ntoh32(uint32_t n32); - -/** - Convert from host order to network order. -*/ -uint64_t csp_hton64(uint64_t h64); - -/** - Convert from network order to host order. -*/ -uint64_t csp_ntoh64(uint64_t n64); - -/** - Convert from host order to big endian. -*/ -uint16_t csp_htobe16(uint16_t h16); - -/** - Convert from host order to little endian. -*/ -uint16_t csp_htole16(uint16_t h16); - -/** - Convert from big endian to host order. -*/ -uint16_t csp_betoh16(uint16_t be16); - -/** - Convert from little endian to host order. -*/ -uint16_t csp_letoh16(uint16_t le16); - -/** - Convert from host order to big endian. - */ -uint32_t csp_htobe32(uint32_t h32); - -/** - Convert from host order to little endian. -*/ -uint32_t csp_htole32(uint32_t h32); - -/** - Convert from big endian to host order. -*/ -uint32_t csp_betoh32(uint32_t be32); - -/** - Convert from little endian to host order. -*/ -uint32_t csp_letoh32(uint32_t le32); - -/** - Convert from host order to big endian. -*/ -uint64_t csp_htobe64(uint64_t h64); - -/** - Convert from host order to little endian. -*/ -uint64_t csp_htole64(uint64_t h64); - -/** - Convert from big endian to host order. -*/ -uint64_t csp_betoh64(uint64_t be64); - -/** - Convert from little endian to host order. -*/ -uint64_t csp_letoh64(uint64_t le64); - -/** - Convert from host order to network order. -*/ -float csp_htonflt(float f); - -/** - Convert from network order to host order. -*/ -float csp_ntohflt(float f); - -/** - Convert from host order to network order. -*/ -double csp_htondbl(double d); - -/** - Convert from network order to host order. -*/ -double csp_ntohdbl(double d); - -#ifdef __cplusplus -} -#endif -#endif // _CSP_ENDIAN_H_ diff --git a/Program/libcsp/include/csp/csp_error.h b/Program/libcsp/include/csp/csp_error.h deleted file mode 100755 index 28c07c0..0000000 --- a/Program/libcsp/include/csp/csp_error.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_ERROR_H_ -#define _CSP_ERROR_H_ - -/** - @file - - Error codes. -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - @defgroup CSP_ERR CSP error codes. - @{ -*/ -#define CSP_ERR_NONE 0 /**< No error */ -#define CSP_ERR_NOMEM -1 /**< Not enough memory */ -#define CSP_ERR_INVAL -2 /**< Invalid argument */ -#define CSP_ERR_TIMEDOUT -3 /**< Operation timed out */ -#define CSP_ERR_USED -4 /**< Resource already in use */ -#define CSP_ERR_NOTSUP -5 /**< Operation not supported */ -#define CSP_ERR_BUSY -6 /**< Device or resource busy */ -#define CSP_ERR_ALREADY -7 /**< Connection already in progress */ -#define CSP_ERR_RESET -8 /**< Connection reset */ -#define CSP_ERR_NOBUFS -9 /**< No more buffer space available */ -#define CSP_ERR_TX -10 /**< Transmission failed */ -#define CSP_ERR_DRIVER -11 /**< Error in driver layer */ -#define CSP_ERR_AGAIN -12 /**< Resource temporarily unavailable */ -#define CSP_ERR_HMAC -100 /**< HMAC failed */ -#define CSP_ERR_XTEA -101 /**< XTEA failed */ -#define CSP_ERR_CRC32 -102 /**< CRC32 failed */ -#define CSP_ERR_SFP -103 /**< SFP protocol error or inconsistency */ -/**@}*/ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_iflist.h b/Program/libcsp/include/csp/csp_iflist.h deleted file mode 100755 index 2cc0419..0000000 --- a/Program/libcsp/include/csp/csp_iflist.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_IFLIST_H_ -#define CSP_IFLIST_H_ - -/** - @file - - Interface list. - - Linked-list of interfaces in the system. - - This API is not thread-safe. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Add interface to the list. - - @param[in] iface interface. The interface must remain valid as long as the application is running. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_iflist_add(csp_iface_t * iface); - -/** - Get interface by name. - - @param[in] name interface name. - @return Interface or NULL if not found. -*/ -csp_iface_t * csp_iflist_get_by_name(const char *name); - -/** - Print list of interfaces to stdout. -*/ -void csp_iflist_print(void); - -/** - Return list of interfaces. - - @return First interface or NULL, if no interfaces added. -*/ -csp_iface_t * csp_iflist_get(void); - -/** - Convert bytes to readable string. -*/ -int csp_bytesize(char *buffer, int buffer_len, unsigned long int bytes); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_interface.h b/Program/libcsp/include/csp/csp_interface.h deleted file mode 100755 index fcdd8d7..0000000 --- a/Program/libcsp/include/csp/csp_interface.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_INTERFACE_H_ -#define _CSP_INTERFACE_H_ - -/** - @file - Interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Max unique length of interface name, when matching names. -*/ -#define CSP_IFLIST_NAME_MAX 10 - -/** - Interface Tx function. - - @param[in] ifroute contains the interface and the \a mac adddress. - @param[in] packet CSP packet to send. On success, the packet must be freed using csp_buffer_free(). - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -typedef int (*nexthop_t)(const csp_route_t * ifroute, csp_packet_t *packet); - -//doc-begin:csp_iface_s -/** - CSP interface. -*/ -struct csp_iface_s { - const char *name; //!< Name, max compare length is #CSP_IFLIST_NAME_MAX - void * interface_data; //!< Interface data, only known/used by the interface layer, e.g. state information. - void * driver_data; //!< Driver data, only known/used by the driver layer, e.g. device/channel references. - nexthop_t nexthop; //!< Next hop (Tx) function - uint16_t mtu; //!< Maximum Transmission Unit of interface - uint8_t split_horizon_off; //!< Disable the route-loop prevention - uint32_t tx; //!< Successfully transmitted packets - uint32_t rx; //!< Successfully received packets - uint32_t tx_error; //!< Transmit errors (packets) - uint32_t rx_error; //!< Receive errors, e.g. too large message - uint32_t drop; //!< Dropped packets - uint32_t autherr; //!< Authentication errors (packets) - uint32_t frame; //!< Frame format errors (packets) - uint32_t txbytes; //!< Transmitted bytes - uint32_t rxbytes; //!< Received bytes - uint32_t irq; //!< Interrupts - struct csp_iface_s *next; //!< Internal, interfaces are stored in a linked list -}; -//doc-end:csp_iface_s - -/** - Inputs a new packet into the system. - - This function can be called from interface drivers (ISR) or tasks, to route and accept packets. - - @note EXTREMELY IMPORTANT: \a pxTaskWoken must ALWAYS be NULL if called from task, and ALWAYS - be NON NULL if called from ISR. If this condition is met, this call is completely thread-safe - - This function is fire and forget, it returns void, meaning that the \a packet will always be - either accepted or dropped, so the memory will always be freed. - - @param[in] packet A pointer to the incoming packet - @param[in] iface A pointer to the incoming interface TX function. - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! -*/ -void csp_qfifo_write(csp_packet_t *packet, csp_iface_t *iface, CSP_BASE_TYPE *pxTaskWoken); - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/Program/libcsp/include/csp/csp_platform.h b/Program/libcsp/include/csp/csp_platform.h deleted file mode 100755 index 345df56..0000000 --- a/Program/libcsp/include/csp/csp_platform.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_PLATFORM_H_ -#define _CSP_PLATFORM_H_ - -/** - @file - Platform support. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Set OS */ -#if (CSP_POSIX || CSP_WINDOWS || CSP_MACOSX || __DOXYGEN__) - /** Base type. Mainly used for FreeRTOS calls to trigger task re-scheduling. */ - #define CSP_BASE_TYPE int - /** Max timeout time. On platforms supporting no timeouts (e.g. Linux), the timeout will be converted to \a forever. */ - #define CSP_MAX_TIMEOUT (UINT32_MAX) - /** Declare critical lock. */ - #define CSP_DEFINE_CRITICAL(lock) static csp_bin_sem_handle_t lock - /** Initialize critical lock. */ - #define CSP_INIT_CRITICAL(lock) ({(csp_bin_sem_create(&lock) == CSP_SEMAPHORE_OK) ? CSP_ERR_NONE : CSP_ERR_NOMEM;}) - /** Enter/take critical lock. */ - #define CSP_ENTER_CRITICAL(lock) do { csp_bin_sem_wait(&lock, CSP_MAX_DELAY); } while(0) - /** Exit/release critical lock. */ - #define CSP_EXIT_CRITICAL(lock) do { csp_bin_sem_post(&lock); } while(0) -#elif (CSP_FREERTOS) - #include "FreeRTOS.h" - #define CSP_BASE_TYPE portBASE_TYPE - #define CSP_MAX_TIMEOUT portMAX_DELAY - #define CSP_DEFINE_CRITICAL(lock) - #define CSP_INIT_CRITICAL(lock) ({CSP_ERR_NONE;}) - #define CSP_ENTER_CRITICAL(lock) do { portENTER_CRITICAL(); } while (0) - #define CSP_EXIT_CRITICAL(lock) do { portEXIT_CRITICAL(); } while (0) -#else - #error "OS must be either CSP_POSIX, CSP_MACOSX, CSP_FREERTOS or CSP_WINDOWS" -#endif - -/** Legacy definition for #CSP_MAX_TIMEOUT. */ -#define CSP_MAX_DELAY CSP_MAX_TIMEOUT - -/** Legacy definition for #CSP_MAX_TIMEOUT. */ -#define CSP_INFINITY CSP_MAX_TIMEOUT - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_promisc.h b/Program/libcsp/include/csp/csp_promisc.h deleted file mode 100755 index 59e2ae5..0000000 --- a/Program/libcsp/include/csp/csp_promisc.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_CSP_PROMISC_H_ -#define _CSP_CSP_PROMISC_H_ - -/** - #file - - Promiscuous packet queue. - - This function is used to enable promiscuous mode for incoming packets, e.g. router, bridge. - If enabled, a copy of all incoming packets are cloned (using csp_buffer_clone()) and placed in a - FIFO queue, that can be read using csp_promisc_read(). -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Enable promiscuous packet queue. - @param[in] queue_size Size (max length) of queue for incoming packets. - @return #CSP_ERR_NONE on success, otherwise an error code. - */ -int csp_promisc_enable(unsigned int queue_size); - -/** - Disable promiscuous mode. -*/ -void csp_promisc_disable(void); - -/** - Get/dequeue packet from promiscuous packet queue. - - Returns the first packet from the promiscuous packet queue. - @param[in] timeout Timeout in ms to wait for a packet. - @return Packet (free with csp_buffer_free() or re-use packet), NULL on error or timeout. -*/ -csp_packet_t *csp_promisc_read(uint32_t timeout); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_rtable.h b/Program/libcsp/include/csp/csp_rtable.h deleted file mode 100755 index 60307f1..0000000 --- a/Program/libcsp/include/csp/csp_rtable.h +++ /dev/null @@ -1,172 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_RTABLE_H_ -#define CSP_RTABLE_H_ - -/** - @file - - Routing table. - - The routing table maps a CSP destination address to an interface (and optional a via address). - - Normal routing: If the route's via address is set to #CSP_NO_VIA_ADDRESS, the packet will be sent directly to the destination address - specified in the CSP header, otherwise the packet will be sent the to the route's via address. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - No via address specified for the route, use CSP header destination. -*/ -#define CSP_NO_VIA_ADDRESS 0xFF - -/** - Legacy definition for #CSP_NO_VIA_ADDRESS. -*/ -#define CSP_NODE_MAC CSP_NO_VIA_ADDRESS - -/** - Route entry. - @see csp_rtable_find_route(). -*/ -struct csp_route_s { - /** Which interface to route packet on */ - csp_iface_t * iface; - /** If different from #CSP_NO_VIA_ADDRESS, send packet to this address, instead of the destination address in the CSP header. */ - uint8_t via; -}; - -/** - Find route to address/node. - @param[in] dest_address destination address. - @return Route or NULL if no route found. -*/ -const csp_route_t * csp_rtable_find_route(uint8_t dest_address); - -/** - Set route to destination address/node. - @param[in] dest_address destination address. - @param[in] mask number of bits in netmask - @param[in] ifc interface. - @param[in] via assosicated via address. - @return #CSP_ERR_NONE on success, or an error code. -*/ -int csp_rtable_set(uint8_t dest_address, uint8_t mask, csp_iface_t *ifc, uint8_t via); - -/** - Save routing table as a string (readable format). - @see csp_rtable_load() for additional information, e.g. format. - @param[out] buffer user supplied buffer. - @param[in] buffer_size size of \a buffer. - @return #CSP_ERR_NONE on success, or an error code. -*/ -int csp_rtable_save(char * buffer, size_t buffer_size); - -/** - Load routing table from a string. - Table will be loaded on-top of existing routes, possibly overwriting existing entries. - Format: \[/mask] \ [via][, next entry] - Example: "0/0 CAN, 8 KISS, 10 I2C 10", same as "0/0 CAN, 8/5 KISS, 10/5 I2C 10". - @see csp_rtable_save(), csp_rtable_clear(), csp_rtable_free() - @param[in] rtable routing table (nul terminated) - @return @ref CSP_ERR or number of entries. -*/ -int csp_rtable_load(const char * rtable); - -/** - Load routing table from a string. - Table will be loaded on-top of existing routes, possibly overwriting existing entries. - Format: \[/mask] \ [via][, next entry] - Example: "0/0 CAN, 8 KISS, 10 I2C 10", same as "0/0 CAN, 8/5 KISS, 10/5 I2C 10". - @see csp_rtable_save(), csp_rtable_clear(), csp_rtable_free() - @param[in] rtable routing table (nul terminated) - @return @ref CSP_ERR or number of entries. -*/ -int csp_rtable_load(const char * rtable); - -/** - Check string for valid routing elements. - @param[in] rtable routing table (nul terminated) - @return @ref CSP_ERR or number of entries. -*/ -int csp_rtable_check(const char * rtable); - -/** - Clear routing table and add loopback route. - @see csp_rtable_free() -*/ -void csp_rtable_clear(void); - -/** - Clear/free all entries in the routing table. -*/ -void csp_rtable_free(void); - -/** - Print routing table -*/ -void csp_rtable_print(void); - -/** Iterator for looping through the routing table. */ -typedef bool (*csp_rtable_iterator_t)(void * ctx, uint8_t address, uint8_t mask, const csp_route_t * route); - -/** - Iterate routing table. -*/ -void csp_rtable_iterate(csp_rtable_iterator_t iter, void * ctx); - -/** - Set route to destination address/node. - @deprecated Use csp_rtable_set() instead. - @param[in] dest_address destination address. - @param[in] ifc interface. - @param[in] via assosicated via address. - @return #CSP_ERR_NONE on success, or an error code. -*/ -static inline int csp_route_set(uint8_t dest_address, csp_iface_t *ifc, uint8_t via) { - return csp_rtable_set(dest_address, CSP_ID_HOST_SIZE, ifc, via); -} - -/** - Print routing table. - @deprecated Use csp_rtable_print() instead. -*/ -static inline void csp_route_print_table() { - csp_rtable_print(); -} - -/** - Print list of interfaces. - @deprecated Use csp_iflist_print() instead. -*/ -static inline void csp_route_print_interfaces(void) { - csp_iflist_print(); -} - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_sfp.h b/Program/libcsp/include/csp/csp_sfp.h deleted file mode 100755 index 1fc5d31..0000000 --- a/Program/libcsp/include/csp/csp_sfp.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_SFP_H_ -#define _CSP_SFP_H_ - -/** - @file - - Simple Fragmentation Protocol (SFP). - - The SFP API can transfer a blob of data across an established CSP connection, by chopping the data into smaller chuncks of data, that - can fit into a single CSP message. - - SFP will add a small header to each packet, containing information about the transfer. - SFP is usually sent over a RDP connection (which also adds a header), -*/ - -#include // memcpy() - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Send data over a CSP connection. - - Data will be send in chunks of \a mtu bytes. The MTU must be small enough to fit into a CSP packat + SFP header + other transport headers. - - csp_sfp_recv() or csp_sfp_recv_fp() can be used at the other end to receive data. - - This is usefull if you wish to send data stored in flash memory or another location, where standard memcpy() doesn't work. - - @param[in] conn established connection for sending SFP packets. - @param[in] data data to send - @param[in] datasize size of \a data - @param[in] mtu maximum transfer unit (bytes), max data chunk to send. - @param[in] timeout unused as of CSP version 1.6 - @param[in] memcpyfcn memory copy function. - @return #CSP_ERR_NONE on success, otherwise an error. -*/ -int csp_sfp_send_own_memcpy(csp_conn_t * conn, const void * data, unsigned int datasize, unsigned int mtu, uint32_t timeout, csp_memcpy_fnc_t memcpyfcn); - -/** - Send data over a CSP connection. - - Uses csp_sfp_send_own_memcpy() with standard memcpy(). - - @param[in] conn established connection for sending SFP packets. - @param[in] data data to send - @param[in] datasize size of \a data - @param[in] mtu maximum transfer unit (bytes), max data chunk to send. - @param[in] timeout unused as of CSP version 1.6 - @return #CSP_ERR_NONE on success, otherwise an error. -*/ -static inline int csp_sfp_send(csp_conn_t * conn, const void * data, unsigned int datasize, unsigned int mtu, uint32_t timeout) { - return csp_sfp_send_own_memcpy(conn, data, datasize, mtu, timeout, (csp_memcpy_fnc_t) &memcpy); -} - -/** - Receive data over a CSP connection. - - This is the counterpart to the csp_sfp_send() and csp_sfp_send_own_memcpy(). - - @param[in] conn established connection for receiving SFP packets. - @param[out] dataout received data on success. Allocated with csp_malloc(), so should be freed with csp_free(). The pointer will be NULL on failure. - @param[out] datasize size of received data. - @param[in] timeout timeout in ms to wait for csp_read() - @param[in] first_packet First packet of a SFP transfer. Use NULL to receive first packet on the connection. - @return #CSP_ERR_NONE on success, otherwise an error. -*/ -int csp_sfp_recv_fp(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout, csp_packet_t * first_packet); - -/** - Receive data over a CSP connection. - - This is the counterpart to the csp_sfp_send() and csp_sfp_send_own_memcpy(). - - @param[in] conn established connection for receiving SFP packets. - @param[out] dataout received data on success. Allocated with csp_malloc(), so should be freed with csp_free(). The pointer will be NULL on failure. - @param[out] datasize size of received data. - @param[in] timeout timeout in ms to wait for csp_read() - @return #CSP_ERR_NONE on success, otherwise an error. -*/ -static inline int csp_sfp_recv(csp_conn_t * conn, void ** dataout, int * datasize, uint32_t timeout) { - return csp_sfp_recv_fp(conn, dataout, datasize, timeout, NULL); -} - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/csp_types.h b/Program/libcsp/include/csp/csp_types.h deleted file mode 100755 index 1a0f492..0000000 --- a/Program/libcsp/include/csp/csp_types.h +++ /dev/null @@ -1,292 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_TYPES_H_ -#define CSP_TYPES_H_ - -/** - @file - Basic types. -*/ - -#include -#include -#include - -#include // -> CSP_X defines (compile configuration) -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if (CSP_BIG_ENDIAN && CSP_LITTLE_ENDIAN) -#error "Only define/set either CSP_BIG_ENDIAN or CSP_LITTLE_ENDIAN" -#endif - -/** - Reserved ports for CSP services. -*/ -typedef enum { - CSP_CMP = 0, //!< CSP management, e.g. memory, routes, stats - CSP_PING = 1, //!< Ping - return ping - CSP_PS = 2, //!< Current process list - CSP_MEMFREE = 3, //!< Free memory - CSP_REBOOT = 4, //!< Reboot, see #CSP_REBOOT_MAGIC and #CSP_REBOOT_SHUTDOWN_MAGIC - CSP_BUF_FREE = 5, //!< Free CSP buffers - CSP_UPTIME = 6, //!< Uptime -} csp_service_port_t; - -/** Listen on all ports, primarily used with csp_bind() */ -#define CSP_ANY 255 - -/** - Message priority. -*/ -typedef enum { - CSP_PRIO_CRITICAL = 0, //!< Critical - CSP_PRIO_HIGH = 1, //!< High - CSP_PRIO_NORM = 2, //!< Normal (default) - CSP_PRIO_LOW = 3, //!< Low -} csp_prio_t; - -#define CSP_PRIORITIES (1 << CSP_ID_PRIO_SIZE) //!< Number of CSP message priorities. - -#if (CSP_USE_QOS || __DOXYGEN__) -#define CSP_ROUTE_FIFOS CSP_PRIORITIES //!< Number of fifos for incoming messages (handover to router) -#define CSP_RX_QUEUES CSP_PRIORITIES //!< Number of fifos for incoming message per message-queue -#else -#define CSP_ROUTE_FIFOS 1 -#define CSP_RX_QUEUES 1 -#endif - -/** - @defgroup CSP_HEADER_DEF CSP header definition. - @{ -*/ -#define CSP_ID_PRIO_SIZE 2 //!< Bits for priority, see #csp_prio_t -#define CSP_ID_HOST_SIZE 5 //!< Bits for host (destination/source address) -#define CSP_ID_PORT_SIZE 6 //!< Bits for port (destination/source port) -#define CSP_ID_FLAGS_SIZE 8 //!< Bits for flags, see @ref CSP_HEADER_FLAGS - -/** Number of bits in CSP header */ -#define CSP_HEADER_BITS (CSP_ID_PRIO_SIZE + (2 * CSP_ID_HOST_SIZE) + (2 * CSP_ID_PORT_SIZE) + CSP_ID_FLAGS_SIZE) -/** CSP header size in bytes */ -#define CSP_HEADER_LENGTH (CSP_HEADER_BITS / 8) - -#if CSP_HEADER_BITS != 32 && __GNUC__ -#error "Header length must be 32 bits" -#endif - -#define CSP_ID_PRIO_MAX ((1 << (CSP_ID_PRIO_SIZE)) - 1) //!< Max priority value in header -#define CSP_ID_HOST_MAX ((1 << (CSP_ID_HOST_SIZE)) - 1) //!< Max host value in header -#define CSP_ID_PORT_MAX ((1 << (CSP_ID_PORT_SIZE)) - 1) //!< Max port value in header -#define CSP_ID_FLAGS_MAX ((1 << (CSP_ID_FLAGS_SIZE)) - 1) //!< Max flag(s) value in header - -/** CSP identifier/header - priority mask */ -#define CSP_ID_PRIO_MASK ((uint32_t) CSP_ID_PRIO_MAX << (CSP_ID_FLAGS_SIZE + (2 * CSP_ID_PORT_SIZE) + (2 * CSP_ID_HOST_SIZE))) -/** CSP identifier/header - source address mask */ -#define CSP_ID_SRC_MASK ((uint32_t) CSP_ID_HOST_MAX << (CSP_ID_FLAGS_SIZE + (2 * CSP_ID_PORT_SIZE) + (1 * CSP_ID_HOST_SIZE))) -/** CSP identifier/header - destination address mask */ -#define CSP_ID_DST_MASK ((uint32_t) CSP_ID_HOST_MAX << (CSP_ID_FLAGS_SIZE + (2 * CSP_ID_PORT_SIZE))) -/** CSP identifier/header - destination port mask */ -#define CSP_ID_DPORT_MASK ((uint32_t) CSP_ID_PORT_MAX << (CSP_ID_FLAGS_SIZE + (1 * CSP_ID_PORT_SIZE))) -/** CSP identifier/header - source port mask */ -#define CSP_ID_SPORT_MASK ((uint32_t) CSP_ID_PORT_MAX << (CSP_ID_FLAGS_SIZE)) -/** CSP identifier/header - flag mask */ -#define CSP_ID_FLAGS_MASK ((uint32_t) CSP_ID_FLAGS_MAX << (0)) -/** CSP identifier/header - connection mask (source & destination address + source & destination ports) */ -#define CSP_ID_CONN_MASK (CSP_ID_SRC_MASK | CSP_ID_DST_MASK | CSP_ID_DPORT_MASK | CSP_ID_SPORT_MASK) -/**@}*/ - -/** - CSP identifier/header. - This union is sent directly on the wire, hence the big/little endian definitions -*/ -typedef union { - /** Entire identifier. */ - uint32_t ext; - /** Individual fields. */ - struct __attribute__((__packed__)) { -#if (CSP_BIG_ENDIAN || __DOXYGEN__) - unsigned int pri : CSP_ID_PRIO_SIZE; //!< Priority - unsigned int src : CSP_ID_HOST_SIZE; //!< Source address - unsigned int dst : CSP_ID_HOST_SIZE; //!< Destination address - unsigned int dport : CSP_ID_PORT_SIZE; //!< Destination port - unsigned int sport : CSP_ID_PORT_SIZE; //!< Source port - unsigned int flags : CSP_ID_FLAGS_SIZE; //!< Flags, see @ref CSP_HEADER_FLAGS -#elif (CSP_LITTLE_ENDIAN) - unsigned int flags : CSP_ID_FLAGS_SIZE; - unsigned int sport : CSP_ID_PORT_SIZE; - unsigned int dport : CSP_ID_PORT_SIZE; - unsigned int dst : CSP_ID_HOST_SIZE; - unsigned int src : CSP_ID_HOST_SIZE; - unsigned int pri : CSP_ID_PRIO_SIZE; -#endif - }; -} csp_id_t; - -/** Broadcast address */ -#define CSP_BROADCAST_ADDR CSP_ID_HOST_MAX - -/** Default routing address */ -#define CSP_DEFAULT_ROUTE (CSP_ID_HOST_MAX + 1) - -/** - @defgroup CSP_HEADER_FLAGS CSP header flags. - @{ -*/ -#define CSP_FRES1 0x80 //!< Reserved for future use -#define CSP_FRES2 0x40 //!< Reserved for future use -#define CSP_FRES3 0x20 //!< Reserved for future use -#define CSP_FFRAG 0x10 //!< Use fragmentation -#define CSP_FHMAC 0x08 //!< Use HMAC verification -#define CSP_FXTEA 0x04 //!< Use XTEA encryption -#define CSP_FRDP 0x02 //!< Use RDP protocol -#define CSP_FCRC32 0x01 //!< Use CRC32 checksum -/**@}*/ - -/** - @defgroup CSP_SOCKET_OPTIONS CSP Socket options. - @{ -*/ -#define CSP_SO_NONE 0x0000 //!< No socket options -#define CSP_SO_RDPREQ 0x0001 //!< Require RDP -#define CSP_SO_RDPPROHIB 0x0002 //!< Prohibit RDP -#define CSP_SO_HMACREQ 0x0004 //!< Require HMAC -#define CSP_SO_HMACPROHIB 0x0008 //!< Prohibit HMAC -#define CSP_SO_XTEAREQ 0x0010 //!< Require XTEA -#define CSP_SO_XTEAPROHIB 0x0020 //!< Prohibit HMAC -#define CSP_SO_CRC32REQ 0x0040 //!< Require CRC32 -#define CSP_SO_CRC32PROHIB 0x0080 //!< Prohibit CRC32 -#define CSP_SO_CONN_LESS 0x0100 //!< Enable Connection Less mode -#define CSP_SO_INTERNAL_LISTEN 0x1000 //!< Internal flag: listen called on socket -/**@}*/ - -/** - @defgroup CSP_CONNECTION_OPTIONS CSP Connect options. - @{ -*/ -#define CSP_O_NONE CSP_SO_NONE //!< No connection options -#define CSP_O_RDP CSP_SO_RDPREQ //!< Enable RDP -#define CSP_O_NORDP CSP_SO_RDPPROHIB //!< Disable RDP -#define CSP_O_HMAC CSP_SO_HMACREQ //!< Enable HMAC -#define CSP_O_NOHMAC CSP_SO_HMACPROHIB //!< Disable HMAC -#define CSP_O_XTEA CSP_SO_XTEAREQ //!< Enable XTEA -#define CSP_O_NOXTEA CSP_SO_XTEAPROHIB //!< Disable XTEA -#define CSP_O_CRC32 CSP_SO_CRC32REQ //!< Enable CRC32 -#define CSP_O_NOCRC32 CSP_SO_CRC32PROHIB //!< Disable CRC32 -/**@}*/ - -/** - Padding size in #csp_packet_t. - 10 bytes ensure correct aligned \a id and \a data in #csp_packet_t. -*/ -#define CSP_PADDING_BYTES 10 - -//doc-begin:csp_packet_t -/** - CSP Packet. - - This structure is constructed to fit with all interface and protocols to prevent the - need to copy data (zero copy). - - @note In most cases a CSP packet cannot be reused in case of send failure, because the - lower layers may add additional data causing increased length (e.g. CRC32), convert - the CSP id to different endian (e.g. I2C), etc. -*/ -typedef struct { - /** - Padding. These bytes are intended for use by protocols, which want to prepend - data before sending it, without having to copy/reorganize the entire message. - */ - uint8_t padding[CSP_PADDING_BYTES]; - /** Data length. Must be just before CSP ID.*/ - uint16_t length; - /** CSP id. Must be just before data, as it allows the interface to id and data - in a single operation. */ - csp_id_t id; - /** - Data part of packet. - When using the csp_buffer API, the size of the data part is set by - csp_buffer_init(), and can later be accessed by csp_buffer_data_size() - */ - union { - /** Access data as uint8_t. */ - uint8_t data[0]; - /** Access data as uint16_t */ - uint16_t data16[0]; - /** Access data as uint32_t */ - uint32_t data32[0]; - }; -} csp_packet_t; -//doc-end:csp_packet_t - -/** - Size of the packet overhead in #csp_packet_t. - The overhead is the difference between the total buffer size (returned by csp_buffer_size()) and the data part - of the #csp_packet_t (returned by csp_buffer_data_size()). -*/ -#define CSP_BUFFER_PACKET_OVERHEAD (sizeof(csp_packet_t) - sizeof(((csp_packet_t *)0)->data)) - -/** Forward declaration of CSP interface, see #csp_iface_s for details. */ -typedef struct csp_iface_s csp_iface_t; -/** Forward declaration of outgoing CSP route, see #csp_route_s for details. */ -typedef struct csp_route_s csp_route_t; - -/** Forward declaration of socket structure */ -typedef struct csp_conn_s csp_socket_t; -/** Forward declaration of connection structure */ -typedef struct csp_conn_s csp_conn_t; - -/** Max length of host name - including zero termination */ -#define CSP_HOSTNAME_LEN 20 -/** Max length of model name - including zero termination */ -#define CSP_MODEL_LEN 30 - -/** Magic number for reboot request, for service-code #CSP_REBOOT */ -#define CSP_REBOOT_MAGIC 0x80078007 -/** Magic number for shutdown request, for service-code #CSP_REBOOT */ -#define CSP_REBOOT_SHUTDOWN_MAGIC 0xD1E5529A - -#ifdef __AVR__ -typedef uint32_t csp_memptr_t; -typedef const uint32_t csp_const_memptr_t; -#else -/** Memory pointer */ -typedef void * csp_memptr_t; -/** Const memory pointer */ -typedef const void * csp_const_memptr_t; -#endif - -/** - Platform specific memory copy function. -*/ -typedef csp_memptr_t (*csp_memcpy_fnc_t)(csp_memptr_t, csp_const_memptr_t, size_t); - -/** - Compile check/asserts. -*/ -#define CSP_STATIC_ASSERT(condition, name) typedef char name[(condition) ? 1 : -1] - -#ifdef __cplusplus -} -#endif -#endif /* CSP_TYPES_H_ */ diff --git a/Program/libcsp/include/csp/drivers/can_socketcan.h b/Program/libcsp/include/csp/drivers/can_socketcan.h deleted file mode 100755 index e33b711..0000000 --- a/Program/libcsp/include/csp/drivers/can_socketcan.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef LIB_CSP_INCLUDE_CSP_DRIVERS_CAN_SOCKETCAN_H_ -#define LIB_CSP_INCLUDE_CSP_DRIVERS_CAN_SOCKETCAN_H_ - -/** - @file - - Socket CAN driver (Linux). - - This driver requires the libsocketcan library. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Open CAN socket and add CSP interface. - - @param[in] device CAN device name (Linux device). - @param[in] ifname CSP interface name, use #CSP_IF_CAN_DEFAULT_NAME for default name. - @param[in] bitrate if different from 0, it will be attempted to change the bitrate on the CAN device - this may require increased OS privileges. - @param[in] promisc if \a true, receive all CAN frames. If \a false a filter is set on the CAN device, using csp_get_address(). - @param[out] return_iface the added interface. - @return The added interface, or NULL in case of failure. -*/ -int csp_can_socketcan_open_and_add_interface(const char * device, const char * ifname, int bitrate, bool promisc, csp_iface_t ** return_iface); - -/** - Initialize socketcan and add CSP interface. - - @deprecated version 1.6, use csp_can_socketcan_open_and_add_interface() - @param[in] device CAN device name (Linux device). - @param[in] bitrate if different from 0, it will be attempted to change the bitrate on the CAN device - this may require increased OS privileges. - @param[in] promisc if \a true, receive all CAN frames. If \a false a filter is set on the CAN device, using csp_get_address(). - @return The added interface, or NULL in case of failure. -*/ -csp_iface_t * csp_can_socketcan_init(const char * device, int bitrate, bool promisc); - -/** - Stop the Rx thread and free resources (testing). - - @note This will invalidate CSP, because an interface can't be removed. This is primarily for testing. - - @param[in] iface interface to stop. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_can_socketcan_stop(csp_iface_t * iface); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/drivers/usart.h b/Program/libcsp/include/csp/drivers/usart.h deleted file mode 100755 index d5af368..0000000 --- a/Program/libcsp/include/csp/drivers/usart.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_DRIVERS_USART_H -#define CSP_DRIVERS_USART_H - -/** - @file - - USART driver. - - @note This interface implementation only support ONE open UART connection. -*/ - -#include - -#if (CSP_WINDOWS) -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - OS file handle. -*/ -#if (CSP_WINDOWS) - typedef HANDLE csp_usart_fd_t; -#else - typedef int csp_usart_fd_t; -#endif - -/** - Usart configuration. - @see csp_usart_open() -*/ -typedef struct csp_usart_conf { - //! USART device. - const char *device; - //! bits per second. - uint32_t baudrate; - //! Number of data bits. - uint8_t databits; - //! Number of stop bits. - uint8_t stopbits; - //! Parity setting. - uint8_t paritysetting; - //! Enable parity checking (Windows only). - uint8_t checkparity; -} csp_usart_conf_t; - -/** - Callback for returning data to application. - - @param[in] buf data received. - @param[in] len data length (number of bytes in \a buf). - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! -*/ -typedef void (*csp_usart_callback_t) (void * user_data, uint8_t *buf, size_t len, void *pxTaskWoken); - -/** - Opens an UART device. - - Opens the UART device and creates a thread for reading/returning data to the application. - - @note On read failure, exit() will be called - terminating the process. - - @param[in] conf UART configuration. - @param[in] rx_callback receive data callback. - @param[in] user_data reference forwarded to the \a rx_callback function. - @param[out] fd the opened file descriptor. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_usart_open(const csp_usart_conf_t *conf, csp_usart_callback_t rx_callback, void * user_data, csp_usart_fd_t * fd); - -/** - Write data on open UART. - - @param[in] fd file descriptor. - @param[in] data data to write. - @param[in] data_length length of \a data. - @return number of bytes written on success, a negative value on failure. -*/ -int csp_usart_write(csp_usart_fd_t fd, const void * data, size_t data_length); - -/** - Opens UART device and add KISS interface. - - This is a convience function for opening an UART device and adding it as an interface with a given name. - - @note On read failures, exit() will be called - terminating the process. - - @param[in] conf UART configuration. - @param[in] ifname internface name (will be copied), or use NULL for default name. - @param[out] return_iface the added interface. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_usart_open_and_add_kiss_interface(const csp_usart_conf_t *conf, const char * ifname, csp_iface_t ** return_iface); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_can.h b/Program/libcsp/include/csp/interfaces/csp_if_can.h deleted file mode 100755 index bfe4be3..0000000 --- a/Program/libcsp/include/csp/interfaces/csp_if_can.h +++ /dev/null @@ -1,178 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_INTERFACES_CSP_IF_CAN_H -#define CSP_INTERFACES_CSP_IF_CAN_H - -/** - @file - - CAN interface. - - CAN frames contains at most 8 bytes of data, so in order to transmit CSP - packets larger than this, a fragmentation protocol is required. - The CAN Fragmentation Protocol (CFP) is based on CAN2.0B, using all 29 bits of the - identifier. The CAN identifier is divided into these fields: - - - Source: 5 bits - - Destination: 5 bits - - Type: 1 bit - - Remain: 8 bits - - Identifier: 10 bits - - The \b Source and \b Destination fields must match the source and destiantion addressses in the CSP packet. - The \b Type field is used to distinguish the first and subsequent frames in a fragmented CSP - packet. Type is BEGIN (0) for the first fragment and MORE (1) for all other fragments. - The \b Remain field indicates number of remaining fragments, and must be decremented by one for each fragment sent. - The \b identifier field serves the same purpose as in the Internet Protocol, and should be an auto incrementing - integer to uniquely separate sessions. - - Other CAN communication using a standard 11 bit identifier, can co-exist on the wire. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - @defgroup CFP_SIZE CAN message id field size. - @{ -*/ -/** Host - source/destination address. */ -#define CFP_HOST_SIZE 5 -/** Type - \a begin fragment or \a more fragments. */ -#define CFP_TYPE_SIZE 1 -/** Remaining fragments */ -#define CFP_REMAIN_SIZE 8 -/** CFP identification. */ -#define CFP_ID_SIZE 10 -/** @} */ - -/** - @defgroup CFP_FIELDS Macros for extracting fields from CAN message id. - @{ -*/ -/** Helper macro */ -#define CFP_FIELD(id,rsiz,fsiz) ((uint32_t)((uint32_t)((id) >> (rsiz)) & (uint32_t)((1 << (fsiz)) - 1))) -/** Extract source address */ -#define CFP_SRC(id) CFP_FIELD(id, CFP_HOST_SIZE + CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_HOST_SIZE) -/** Extract destination address */ -#define CFP_DST(id) CFP_FIELD(id, CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_HOST_SIZE) -/** Extract type (begin or more) */ -#define CFP_TYPE(id) CFP_FIELD(id, CFP_REMAIN_SIZE + CFP_ID_SIZE, CFP_TYPE_SIZE) -/** Extract remaining fragments */ -#define CFP_REMAIN(id) CFP_FIELD(id, CFP_ID_SIZE, CFP_REMAIN_SIZE) -/** Extract CFP identification */ -#define CFP_ID(id) CFP_FIELD(id, 0, CFP_ID_SIZE) -/** @} */ - -/** - @defgroup CFP_MAKE Macros for building CAN message id. - @{ -*/ -/** Helper macro */ -#define CFP_MAKE_FIELD(id,fsiz,rsiz) ((uint32_t)(((id) & (uint32_t)((uint32_t)(1 << (fsiz)) - 1)) << (rsiz))) -/** Make source */ -#define CFP_MAKE_SRC(id) CFP_MAKE_FIELD(id, CFP_HOST_SIZE, CFP_HOST_SIZE + CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE) -/** Make destination */ -#define CFP_MAKE_DST(id) CFP_MAKE_FIELD(id, CFP_HOST_SIZE, CFP_TYPE_SIZE + CFP_REMAIN_SIZE + CFP_ID_SIZE) -/** Make type */ -#define CFP_MAKE_TYPE(id) CFP_MAKE_FIELD(id, CFP_TYPE_SIZE, CFP_REMAIN_SIZE + CFP_ID_SIZE) -/** Make remaining fragments */ -#define CFP_MAKE_REMAIN(id) CFP_MAKE_FIELD(id, CFP_REMAIN_SIZE, CFP_ID_SIZE) -/** Make CFP id */ -#define CFP_MAKE_ID(id) CFP_MAKE_FIELD(id, CFP_ID_SIZE, 0) -/** @} */ - -/** Mask to uniquely separate connections */ -#define CFP_ID_CONN_MASK (CFP_MAKE_SRC((uint32_t)(1 << CFP_HOST_SIZE) - 1) | \ - CFP_MAKE_DST((uint32_t)(1 << CFP_HOST_SIZE) - 1) | \ - CFP_MAKE_ID((uint32_t)(1 << CFP_ID_SIZE) - 1)) - -/** - Default interface name. -*/ -#define CSP_IF_CAN_DEFAULT_NAME "CAN" - -/** - Send CAN frame (implemented by driver). - - Used by csp_can_tx() to send CAN frames. - - @param[in] driver_data driver data from #csp_iface_t - @param[in] id CAM message id. - @param[in] data CAN data - @param[in] dlc data length of \a data. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -typedef int (*csp_can_driver_tx_t)(void * driver_data, uint32_t id, const uint8_t * data, uint8_t dlc); - -/** - Interface data (state information). -*/ -typedef struct { - /** CFP Identification number - same number on all fragments from same CSP packet. */ - uint32_t cfp_frame_id; - /** Tx function */ - csp_can_driver_tx_t tx_func; -} csp_can_interface_data_t; - -/** - Add interface. - - If the MTU is not set, it will be set to the maximum value of 2042 bytes (max length when using CFP). - - @param[in] iface CSP interface, initialized with name and inteface_data pointing to a valid #csp_can_interface_data_t structure. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_can_add_interface(csp_iface_t * iface); - -/** - Send CSP packet over CAN (nexthop). - - This function will split the CSP packet into several fragments and call csp_can_tx_fram() for sending each fragment. - - @param[in] ifroute route. - @param[in] packet CSP packet to send. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_can_tx(const csp_route_t * ifroute, csp_packet_t *packet); - -/** - Process received CAN frame. - - Called from driver when a single CAN frame (up to 8 bytes) has been received. The function will gather the fragments into a single - CSP packet and route it on when complete. - - @param[in] iface incoming interface. - @param[in] id received CAN message identifier. - @param[in] data received CAN data. - @param[in] dlc length of received \a data. - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_can_rx(csp_iface_t * iface, uint32_t id, const uint8_t * data, uint8_t dlc, CSP_BASE_TYPE *pxTaskWoken); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_i2c.h b/Program/libcsp/include/csp/interfaces/csp_if_i2c.h deleted file mode 100755 index 5aa2e52..0000000 --- a/Program/libcsp/include/csp/interfaces/csp_if_i2c.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_IF_I2C_H_ -#define _CSP_IF_I2C_H_ - -/** - @file - - I2C interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Default name of I2C interface. -*/ -#define CSP_IF_I2C_DEFAULT_NAME "I2C" - -//doc-begin:csp_i2c_frame_t -/** - I2C frame. - This struct fits on top of a #csp_packet_t, removing the need for copying data. -*/ -typedef struct i2c_frame_s { - //! Not used (-> csp_packet_t.padding) - uint8_t padding[3]; - //! Cleared before Tx (-> csp_packet_t.padding) - uint8_t retries; - //! Not used (-> csp_packet_t.padding) - uint32_t reserved; - //! Destination address (-> csp_packet_t.padding) - uint8_t dest; - //! Cleared before Tx (-> csp_packet_t.padding) - uint8_t len_rx; - //! Length of \a data part (-> csp_packet_t.length) - uint16_t len; - //! CSP id + data (-> csp_packet_t.id) - uint8_t data[0]; -} csp_i2c_frame_t; -//doc-end:csp_i2c_frame_t - -/** - Send I2C frame (implemented by driver). - - Used by csp_i2c_tx() to send a frame. - - The function must free the frame/packet using csp_buffer_free(), if the send succeeds (returning #CSP_ERR_NONE). - - @param[in] driver_data driver data from #csp_iface_t - @param[in] frame destination, length and data. This is actually a #csp_packet_t buffer, casted to #csp_i2c_frame_t. - @return #CSP_ERR_NONE on success, or an error code. -*/ -typedef int (*csp_i2c_driver_tx_t)(void * driver_data, csp_i2c_frame_t * frame); - -/** - Interface data (state information). -*/ -typedef struct { - /** Tx function */ - csp_i2c_driver_tx_t tx_func; -} csp_i2c_interface_data_t; - -/** - Add interface. - - @param[in] iface CSP interface, initialized with name and inteface_data pointing to a valid #csp_i2c_interface_data_t. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_i2c_add_interface(csp_iface_t * iface); - -/** - Send CSP packet over I2C (nexthop). - - @param[in] ifroute route. - @param[in] packet CSP packet to send. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_i2c_tx(const csp_route_t * ifroute, csp_packet_t * packet); - -/** - Process received I2C frame. - - @note The received #csp_i2c_frame_t must actually be pointing to an #csp_packet_t. - - Called from driver, when a frame has been received. - - @param[in] iface incoming interface. - @param[in] frame received data, routed on as a #csp_packet_t. - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! -*/ -void csp_i2c_rx(csp_iface_t * iface, csp_i2c_frame_t * frame, void * pxTaskWoken); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_kiss.h b/Program/libcsp/include/csp/interfaces/csp_if_kiss.h deleted file mode 100755 index e931107..0000000 --- a/Program/libcsp/include/csp/interfaces/csp_if_kiss.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_INTERFACES_CSP_IF_KISS_H -#define CSP_INTERFACES_CSP_IF_KISS_H - -/** - @file - - KISS interface (serial). -*/ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Default name of KISS interface. -*/ -#define CSP_IF_KISS_DEFAULT_NAME "KISS" - -/** - Send KISS frame (implemented by driver). - - @param[in] driver_data driver data from #csp_iface_t - @param[in] data data to send - @param[in] len length of \a data. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -typedef int (*csp_kiss_driver_tx_t)(void *driver_data, const uint8_t * data, size_t len); - -/** - KISS Rx mode/state. -*/ -typedef enum { - KISS_MODE_NOT_STARTED, //!< No start detected - KISS_MODE_STARTED, //!< Started on a KISS frame - KISS_MODE_ESCAPED, //!< Rx escape character - KISS_MODE_SKIP_FRAME, //!< Skip remaining frame, wait for end character -} csp_kiss_mode_t; - -/** - KISS interface data (state information). -*/ -typedef struct { - /** Max Rx length */ - unsigned int max_rx_length; - /** Tx function */ - csp_kiss_driver_tx_t tx_func; - /** Tx lock. Current implementation doesn't transfer data to driver in a single 'write', hence locking is necessary. */ - csp_mutex_t lock; - /** Rx mode/state. */ - csp_kiss_mode_t rx_mode; - /** Rx length */ - unsigned int rx_length; - /** Rx first - if set, waiting for first character (== TNC_DATA) after start */ - bool rx_first; - /** CSP packet for storing Rx data. */ - csp_packet_t * rx_packet; -} csp_kiss_interface_data_t; - -/** - Add interface. - - If the MTU is not set, it will be set to the csp_buffer_data_size() - sizeof(uint32_t), to make room for the CRC32 added to the packet. - - @param[in] iface CSP interface, initialized with name and inteface_data pointing to a valid #csp_kiss_interface_data_t. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_kiss_add_interface(csp_iface_t * iface); - -/** - Send CSP packet over KISS (nexthop). - - @param[in] ifroute route. - @param[in] packet CSP packet to send. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_kiss_tx(const csp_route_t * ifroute, csp_packet_t * packet); - -/** - Process received CAN frame. - - Called from driver when a chunk of data has been received. Once a complete frame has been received, the CSP packet will be routed on. - - @param[in] iface incoming interface. - @param[in] buf reveived data. - @param[in] len length of \a buf. - @param[out] pxTaskWoken Valid reference if called from ISR, otherwise NULL! -*/ -void csp_kiss_rx(csp_iface_t * iface, const uint8_t * buf, size_t len, void * pxTaskWoken); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_lo.h b/Program/libcsp/include/csp/interfaces/csp_if_lo.h deleted file mode 100755 index 865d299..0000000 --- a/Program/libcsp/include/csp/interfaces/csp_if_lo.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_IF_LO_H_ -#define _CSP_IF_LO_H_ - -/** - @file - - Loopback interface. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Name of loopback interface. -*/ -#define CSP_IF_LOOPBACK_NAME "LOOP" - -/** - Loopback interface. -*/ -extern csp_iface_t csp_if_lo; - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h b/Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h deleted file mode 100755 index c61f83f..0000000 --- a/Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef CSP_IF_ZMQHUB_H_ -#define CSP_IF_ZMQHUB_H_ - -/** - @file - - ZMQ (ZeroMQ) interface. - - The ZMQ interface is designed to connect to a ZMQ hub, also refered to as \a zmqproxy. The zmqproxy can be found under examples, - and is based on zmq_proxy() - provided by the ZMQ API. - - For further details on ZMQ, see http://www.zeromq.org. -*/ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - zmqproxy default subscribe (rx) port. - The client must connect it's publish endpoint to the zmqproxy's subscribe port. -*/ -#define CSP_ZMQPROXY_SUBSCRIBE_PORT 6000 - -/** - zmqproxy default publish (tx) port. - The client must connect it's subscribe endpoint to the zmqproxy's publish port. -*/ -#define CSP_ZMQPROXY_PUBLISH_PORT 7000 - -/** - Default ZMQ interface name. -*/ -#define CSP_ZMQHUB_IF_NAME "ZMQHUB" - -/** - Format endpoint connection string for ZMQ. - - @param[in] host host name of IP. - @param[in] port IP port. - @param[out] buf user allocated buffer for receiving formatted string. - @param[in] buf_size size of \a buf. - @return #CSP_ERR_NONE on succcess. - @return #CSP_ERR_NOMEM if supplied buffer too small. -*/ -int csp_zmqhub_make_endpoint(const char * host, uint16_t port, char * buf, size_t buf_size); - -/** - Setup ZMQ interface. - @param[in] addr only receive messages matching this address (255 means all). This is set as \a rx_filter in call to - @param[in] host host name or IP of zmqproxy host. Endpoints are created using the \a host and the default subscribe/publish ports. - @param[in] flags flags for controlling features on the connection. - @param[out] return_interface created CSP interface. - @return #CSP_ERR_NONE on succcess - else assert. -*/ -int csp_zmqhub_init(uint8_t addr, - const char * host, - uint32_t flags, - csp_iface_t ** return_interface); - -/** - Setup ZMQ interface. - @param[in] addr only receive messages matching this address (255 means all). This is set as a \a rx_filter. - @param[in] publish_endpoint publish (tx) endpoint -> connect to zmqproxy's subscribe port #CSP_ZMQPROXY_SUBSCRIBE_PORT. - @param[in] subscribe_endpoint subscribe (rx) endpoint -> connect to zmqproxy's publish port #CSP_ZMQPROXY_PUBLISH_PORT. - @param[in] flags flags for controlling features on the connection. - @param[out] return_interface created CSP interface. - @return #CSP_ERR_NONE on succcess - else assert. -*/ -int csp_zmqhub_init_w_endpoints(uint8_t addr, - const char * publish_endpoint, - const char * subscribe_endpoint, - uint32_t flags, - csp_iface_t ** return_interface); - -/** - Setup ZMQ interface. - @param[in] ifname Name of CSP interface, use NULL for default name #CSP_ZMQHUB_IF_NAME. - @param[in] rx_filter Rx filters, use NULL for no filters - receive all messages. - @param[in] rx_filter_count Number of Rx filters in \a rx_filter. - @param[in] publish_endpoint publish (tx) endpoint -> connect to zmqproxy's subscribe port #CSP_ZMQPROXY_SUBSCRIBE_PORT. - @param[in] subscribe_endpoint subscribe (rx) endpoint -> connect to zmqproxy's publish port #CSP_ZMQPROXY_PUBLISH_PORT. - @param[in] flags flags for controlling features on the connection. - @param[out] return_interface created CSP interface. - @return #CSP_ERR_NONE on succcess - else assert. -*/ -int csp_zmqhub_init_w_name_endpoints_rxfilter(const char * ifname, - const uint8_t rx_filter[], unsigned int rx_filter_count, - const char * publish_endpoint, - const char * subscribe_endpoint, - uint32_t flags, - csp_iface_t ** return_interface); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/arch/csp_system.c b/Program/libcsp/src/arch/csp_system.c deleted file mode 100755 index 8094cb2..0000000 --- a/Program/libcsp/src/arch/csp_system.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -static csp_sys_reboot_t csp_sys_reboot_callback = NULL; -static csp_sys_shutdown_t csp_sys_shutdown_callback = NULL; - -void csp_sys_set_reboot(csp_sys_reboot_t reboot) { - - csp_sys_reboot_callback = reboot; - -} - -int csp_sys_reboot(void) { - - if (csp_sys_reboot_callback) { - return (csp_sys_reboot_callback)(); - } - csp_log_warn("%s not supported - no user function set", __FUNCTION__); - return CSP_ERR_NOTSUP; - -} - -void csp_sys_set_shutdown(csp_sys_shutdown_t shutdown) { - - csp_sys_shutdown_callback = shutdown; - -} - -int csp_sys_shutdown(void) { - - if (csp_sys_shutdown_callback) { - return (csp_sys_shutdown_callback)(); - } - csp_log_warn("%s not supported - no user function set", __FUNCTION__); - return CSP_ERR_NOTSUP; - -} diff --git a/Program/libcsp/src/arch/csp_time.c b/Program/libcsp/src/arch/csp_time.c deleted file mode 100755 index b8423f3..0000000 --- a/Program/libcsp/src/arch/csp_time.c +++ /dev/null @@ -1,32 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -static uint32_t uptime_s_offset = 0; - -uint32_t csp_get_uptime_s(void) { - - uint32_t seconds = csp_get_s(); - if (uptime_s_offset == 0) { - uptime_s_offset = seconds; - } - return (seconds - uptime_s_offset); -} diff --git a/Program/libcsp/src/arch/freertos/csp_clock.c b/Program/libcsp/src/arch/freertos/csp_clock.c deleted file mode 100755 index ff261d0..0000000 --- a/Program/libcsp/src/arch/freertos/csp_clock.c +++ /dev/null @@ -1,32 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -__attribute__((weak)) void csp_clock_get_time(csp_timestamp_t * time) { - time->tv_sec = 0; - time->tv_nsec = 0; -} - -__attribute__((weak)) int csp_clock_set_time(const csp_timestamp_t * time) { - csp_log_warn("csp_clock_set_time() not supported"); - return CSP_ERR_NOTSUP; -} diff --git a/Program/libcsp/src/arch/freertos/csp_malloc.c b/Program/libcsp/src/arch/freertos/csp_malloc.c deleted file mode 100755 index e346aab..0000000 --- a/Program/libcsp/src/arch/freertos/csp_malloc.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -#include - -void * csp_malloc(size_t size) { - return pvPortMalloc(size); -} - -void * csp_calloc(size_t nmemb, size_t size) { - size = (nmemb * size); - void * ptr = csp_malloc(size); - if (ptr) { - memset(ptr, 0, size); - } - return ptr; -} - -void csp_free(void *ptr) { - vPortFree(ptr); -} diff --git a/Program/libcsp/src/arch/freertos/csp_queue.c b/Program/libcsp/src/arch/freertos/csp_queue.c deleted file mode 100755 index 14ed7cb..0000000 --- a/Program/libcsp/src/arch/freertos/csp_queue.c +++ /dev/null @@ -1,60 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include // FreeRTOS - -csp_queue_handle_t csp_queue_create(int length, size_t item_size) { - return xQueueCreate(length, item_size); -} - -void csp_queue_remove(csp_queue_handle_t queue) { - vQueueDelete(queue); -} - -int csp_queue_enqueue(csp_queue_handle_t handle, const void * value, uint32_t timeout) { - if (timeout != CSP_MAX_TIMEOUT) - timeout = timeout / portTICK_RATE_MS; - return xQueueSendToBack(handle, value, timeout); -} - -int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * task_woken) { - return xQueueSendToBackFromISR(handle, value, task_woken); -} - -int csp_queue_dequeue(csp_queue_handle_t handle, void * buf, uint32_t timeout) { - if (timeout != CSP_MAX_TIMEOUT) - timeout = timeout / portTICK_RATE_MS; - return xQueueReceive(handle, buf, timeout); -} - -int csp_queue_dequeue_isr(csp_queue_handle_t handle, void * buf, CSP_BASE_TYPE * task_woken) { - return xQueueReceiveFromISR(handle, buf, task_woken); -} - -int csp_queue_size(csp_queue_handle_t handle) { - return uxQueueMessagesWaiting(handle); -} - -int csp_queue_size_isr(csp_queue_handle_t handle) { - return uxQueueMessagesWaitingFromISR(handle); -} diff --git a/Program/libcsp/src/arch/freertos/csp_semaphore.c b/Program/libcsp/src/arch/freertos/csp_semaphore.c deleted file mode 100755 index 2ecaeae..0000000 --- a/Program/libcsp/src/arch/freertos/csp_semaphore.c +++ /dev/null @@ -1,84 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -int csp_mutex_create(csp_mutex_t * mutex) { - *mutex = xSemaphoreCreateMutex(); - if (*mutex) { - return CSP_SEMAPHORE_OK; - } else { - return CSP_SEMAPHORE_ERROR; - } -} - -int csp_mutex_remove(csp_mutex_t * mutex) { - return csp_bin_sem_remove(mutex); -} - -int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { - return csp_bin_sem_wait(mutex, timeout); -} - -int csp_mutex_unlock(csp_mutex_t * mutex) { - return csp_bin_sem_post(mutex); -} - -int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { - vSemaphoreCreateBinary(*sem); - return CSP_SEMAPHORE_OK; -} - -int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { - if ((sem != NULL) && (*sem != NULL)) { - vSemaphoreDelete(*sem); - } - return CSP_SEMAPHORE_OK; -} - -int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { - csp_log_lock("Wait: %p", sem); - if (timeout != CSP_MAX_TIMEOUT) { - timeout = timeout / portTICK_RATE_MS; - } - if (xSemaphoreTake(*sem, timeout) == pdPASS) { - return CSP_SEMAPHORE_OK; - } - return CSP_SEMAPHORE_ERROR; -} - -int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { - csp_log_lock("Post: %p", sem); - if (xSemaphoreGive(*sem) == pdPASS) { - return CSP_SEMAPHORE_OK; - } - return CSP_SEMAPHORE_ERROR; -} - -int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * pxTaskWoken) { - csp_log_lock("Post: %p", sem); - if (xSemaphoreGiveFromISR(*sem, pxTaskWoken) == pdPASS) { - return CSP_SEMAPHORE_OK; - } else { - return CSP_SEMAPHORE_ERROR; - } -} - diff --git a/Program/libcsp/src/arch/freertos/csp_system.c b/Program/libcsp/src/arch/freertos/csp_system.c deleted file mode 100755 index cafe5f5..0000000 --- a/Program/libcsp/src/arch/freertos/csp_system.c +++ /dev/null @@ -1,88 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include // FreeRTOS - -#include - -int csp_sys_tasklist(char * out) { -#if (tskKERNEL_VERSION_MAJOR < 8) - vTaskList((signed portCHAR *) out); -#else - vTaskList(out); -#endif - return CSP_ERR_NONE; -} - -int csp_sys_tasklist_size(void) { - - return 40 * uxTaskGetNumberOfTasks(); -} - -uint32_t csp_sys_memfree(void) { - - return (uint32_t) xPortGetFreeHeapSize(); - -} - -void csp_sys_set_color(csp_color_t color) { - - unsigned int color_code, modifier_code; - switch (color & COLOR_MASK_COLOR) { - case COLOR_BLACK: - color_code = 30; break; - case COLOR_RED: - color_code = 31; break; - case COLOR_GREEN: - color_code = 32; break; - case COLOR_YELLOW: - color_code = 33; break; - case COLOR_BLUE: - color_code = 34; break; - case COLOR_MAGENTA: - color_code = 35; break; - case COLOR_CYAN: - color_code = 36; break; - case COLOR_WHITE: - color_code = 37; break; - case COLOR_RESET: - default: - color_code = 0; break; - } - - switch (color & COLOR_MASK_MODIFIER) { - case COLOR_BOLD: - modifier_code = 1; break; - case COLOR_UNDERLINE: - modifier_code = 2; break; - case COLOR_BLINK: - modifier_code = 3; break; - case COLOR_HIDE: - modifier_code = 4; break; - case COLOR_NORMAL: - default: - modifier_code = 0; break; - } - - printf("\033[%u;%um", modifier_code, color_code); -} diff --git a/Program/libcsp/src/arch/freertos/csp_thread.c b/Program/libcsp/src/arch/freertos/csp_thread.c deleted file mode 100755 index 4c6a45d..0000000 --- a/Program/libcsp/src/arch/freertos/csp_thread.c +++ /dev/null @@ -1,48 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { - - csp_thread_handle_t handle; -#if (tskKERNEL_VERSION_MAJOR >= 8) - portBASE_TYPE ret = xTaskCreate(routine, thread_name, stack_size, parameters, priority, &handle); -#else - portBASE_TYPE ret = xTaskCreate(routine, (signed char *) thread_name, stack_size, parameters, priority, &handle); -#endif - if (ret != pdTRUE) { - return CSP_ERR_NOMEM; - } - if (return_handle) { - *return_handle = handle; - } - return CSP_ERR_NONE; -} - -void csp_thread_exit(void) { - - vTaskDelete(NULL); // Function must exist, otherwise code wont behave the same on all platforms. -} - -void csp_sleep_ms(unsigned int time_ms) { - - vTaskDelay(time_ms / portTICK_RATE_MS); -} diff --git a/Program/libcsp/src/arch/freertos/csp_time.c b/Program/libcsp/src/arch/freertos/csp_time.c deleted file mode 100755 index 4b2c21f..0000000 --- a/Program/libcsp/src/arch/freertos/csp_time.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include // FreeRTOS - -uint32_t csp_get_ms(void) { - return (uint32_t)(xTaskGetTickCount() * (1000/configTICK_RATE_HZ)); -} - -uint32_t csp_get_ms_isr(void) { - return (uint32_t)(xTaskGetTickCountFromISR() * (1000/configTICK_RATE_HZ)); -} - -uint32_t csp_get_s(void) { - return (uint32_t)(xTaskGetTickCount()/configTICK_RATE_HZ); -} - -uint32_t csp_get_s_isr(void) { - return (uint32_t)(xTaskGetTickCountFromISR()/configTICK_RATE_HZ); -} diff --git a/Program/libcsp/src/arch/macosx/csp_clock.c b/Program/libcsp/src/arch/macosx/csp_clock.c deleted file mode 100755 index 5734a9e..0000000 --- a/Program/libcsp/src/arch/macosx/csp_clock.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -// Use POSIX implementation -#include "../posix/csp_clock.c" diff --git a/Program/libcsp/src/arch/macosx/csp_malloc.c b/Program/libcsp/src/arch/macosx/csp_malloc.c deleted file mode 100755 index b948e50..0000000 --- a/Program/libcsp/src/arch/macosx/csp_malloc.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -// Use POSIX implementation -#include "../posix/csp_malloc.c" diff --git a/Program/libcsp/src/arch/macosx/csp_queue.c b/Program/libcsp/src/arch/macosx/csp_queue.c deleted file mode 100755 index 621bf89..0000000 --- a/Program/libcsp/src/arch/macosx/csp_queue.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -// Use POSIX implementation -#include "../posix/csp_queue.c" diff --git a/Program/libcsp/src/arch/macosx/csp_semaphore.c b/Program/libcsp/src/arch/macosx/csp_semaphore.c deleted file mode 100755 index b35e6f9..0000000 --- a/Program/libcsp/src/arch/macosx/csp_semaphore.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include - -#include - -int csp_mutex_create(csp_mutex_t * mutex) { - csp_log_lock("Mutex init: %p", mutex); - *mutex = pthread_queue_create(1, sizeof(int)); - if (*mutex) { - int dummy = 0; - pthread_queue_enqueue(*mutex, &dummy, 0); - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} - -int csp_mutex_remove(csp_mutex_t * mutex) { - pthread_queue_delete(*mutex); - return CSP_SEMAPHORE_OK; -} - -int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { - - csp_log_lock("Wait: %p timeout %"PRIu32, mutex, timeout); - - int dummy = 0; - if (pthread_queue_dequeue(*mutex, &dummy, timeout) == PTHREAD_QUEUE_OK) { - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} - -int csp_mutex_unlock(csp_mutex_t * mutex) { - int dummy = 0; - if (pthread_queue_enqueue(*mutex, &dummy, 0) == PTHREAD_QUEUE_OK) { - return CSP_SEMAPHORE_OK; - } - return CSP_SEMAPHORE_ERROR; -} - -int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { - return csp_mutex_create(sem); -} - -int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { - return csp_mutex_remove(sem); -} - -int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { - return csp_mutex_lock(sem, timeout); -} - -int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { - return csp_mutex_unlock(sem); -} - -int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * task_woken) { - return csp_mutex_unlock(sem); -} diff --git a/Program/libcsp/src/arch/macosx/csp_system.c b/Program/libcsp/src/arch/macosx/csp_system.c deleted file mode 100755 index fb03f9f..0000000 --- a/Program/libcsp/src/arch/macosx/csp_system.c +++ /dev/null @@ -1,87 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include - -#include - -int csp_sys_tasklist(char * out) { - - strcpy(out, "Tasklist not available on OSX"); - return CSP_ERR_NONE; - -} - -int csp_sys_tasklist_size(void) { - - return 100; - -} - -uint32_t csp_sys_memfree(void) { - - return 0; // not implemented - -} - -void csp_sys_set_color(csp_color_t color) { - - unsigned int color_code, modifier_code; - switch (color & COLOR_MASK_COLOR) { - case COLOR_BLACK: - color_code = 30; break; - case COLOR_RED: - color_code = 31; break; - case COLOR_GREEN: - color_code = 32; break; - case COLOR_YELLOW: - color_code = 33; break; - case COLOR_BLUE: - color_code = 34; break; - case COLOR_MAGENTA: - color_code = 35; break; - case COLOR_CYAN: - color_code = 36; break; - case COLOR_WHITE: - color_code = 37; break; - case COLOR_RESET: - default: - color_code = 0; break; - } - - switch (color & COLOR_MASK_MODIFIER) { - case COLOR_BOLD: - modifier_code = 1; break; - case COLOR_UNDERLINE: - modifier_code = 2; break; - case COLOR_BLINK: - modifier_code = 3; break; - case COLOR_HIDE: - modifier_code = 4; break; - case COLOR_NORMAL: - default: - modifier_code = 0; break; - } - - printf("\033[%u;%um", modifier_code, color_code); -} diff --git a/Program/libcsp/src/arch/macosx/csp_thread.c b/Program/libcsp/src/arch/macosx/csp_thread.c deleted file mode 100755 index 6a51bb4..0000000 --- a/Program/libcsp/src/arch/macosx/csp_thread.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include - -int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { - - pthread_t handle; - int res = pthread_create(&handle, NULL, routine, parameters); - if (res) { - return CSP_ERR_NOMEM; - } - if (return_handle) { - *return_handle = handle; - } - - return CSP_ERR_NONE; -} - -void csp_thread_exit(void) { - - pthread_exit(CSP_TASK_RETURN); -} - -void csp_sleep_ms(unsigned int time_ms) { - - - struct timespec req, rem; - req.tv_sec = (time_ms / 1000U); - req.tv_nsec = ((time_ms % 1000U) * 1000000U); - - while ((nanosleep(&req, &rem) < 0) && (errno == EINTR)) { - req = rem; - } -} diff --git a/Program/libcsp/src/arch/macosx/csp_time.c b/Program/libcsp/src/arch/macosx/csp_time.c deleted file mode 100755 index 8b67d5c..0000000 --- a/Program/libcsp/src/arch/macosx/csp_time.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -// Use POSIX implementation -#include "../posix/csp_time.c" diff --git a/Program/libcsp/src/arch/macosx/pthread_queue.c b/Program/libcsp/src/arch/macosx/pthread_queue.c deleted file mode 100755 index 6e9ea98..0000000 --- a/Program/libcsp/src/arch/macosx/pthread_queue.c +++ /dev/null @@ -1,178 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* -Inspired by c-pthread-queue by Matthew Dickinson -http://code.google.com/p/c-pthread-queue/ -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include - -pthread_queue_t * pthread_queue_create(int length, size_t item_size) { - - pthread_queue_t * q = malloc(sizeof(pthread_queue_t)); - - if (q != NULL) { - q->buffer = malloc(length*item_size); - if (q->buffer != NULL) { - q->size = length; - q->item_size = item_size; - q->items = 0; - q->in = 0; - q->out = 0; - if (pthread_mutex_init(&(q->mutex), NULL) || pthread_cond_init(&(q->cond_full), NULL) || pthread_cond_init(&(q->cond_empty), NULL)) { - free(q->buffer); - free(q); - q = NULL; - } - } else { - free(q); - q = NULL; - } - } - - return q; - -} - -void pthread_queue_delete(pthread_queue_t * q) { - - if (q == NULL) - return; - - free(q->buffer); - free(q); - - return; - -} - -int pthread_queue_enqueue(pthread_queue_t * queue, const void * value, uint32_t timeout) { - - int ret; - - /* Calculate timeout */ - struct timespec ts; - - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; - - uint32_t sec = timeout / 1000; - uint32_t nsec = (timeout - 1000 * sec) * 1000000; - - ts.tv_sec += sec; - - if (ts.tv_nsec + nsec > 1000000000) - ts.tv_sec++; - - ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; - - /* Get queue lock */ - pthread_mutex_lock(&(queue->mutex)); - while (queue->items == queue->size) { - ret = pthread_cond_timedwait(&(queue->cond_full), &(queue->mutex), &ts); - if (ret != 0) { - pthread_mutex_unlock(&(queue->mutex)); - return PTHREAD_QUEUE_FULL; - } - } - - /* Coby object from input buffer */ - memcpy(queue->buffer+(queue->in * queue->item_size), value, queue->item_size); - queue->items++; - queue->in = (queue->in + 1) % queue->size; - pthread_mutex_unlock(&(queue->mutex)); - - /* Nofify blocked threads */ - pthread_cond_broadcast(&(queue->cond_empty)); - - return PTHREAD_QUEUE_OK; - -} - -int pthread_queue_dequeue(pthread_queue_t * queue, void * buf, uint32_t timeout) { - - int ret; - - /* Calculate timeout */ - struct timespec ts; - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; - - uint32_t sec = timeout / 1000; - uint32_t nsec = (timeout - 1000 * sec) * 1000000; - - ts.tv_sec += sec; - - if (ts.tv_nsec + nsec > 1000000000) - ts.tv_sec++; - - ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; - - /* Get queue lock */ - pthread_mutex_lock(&(queue->mutex)); - while (queue->items == 0) { - ret = pthread_cond_timedwait(&(queue->cond_empty), &(queue->mutex), &ts); - if (ret != 0) { - pthread_mutex_unlock(&(queue->mutex)); - return PTHREAD_QUEUE_EMPTY; - } - } - - /* Coby object to output buffer */ - memcpy(buf, queue->buffer+(queue->out * queue->item_size), queue->item_size); - queue->items--; - queue->out = (queue->out + 1) % queue->size; - pthread_mutex_unlock(&(queue->mutex)); - - /* Nofify blocked threads */ - pthread_cond_broadcast(&(queue->cond_full)); - - return PTHREAD_QUEUE_OK; - -} - -int pthread_queue_items(pthread_queue_t * queue) { - - pthread_mutex_lock(&(queue->mutex)); - int items = queue->items; - pthread_mutex_unlock(&(queue->mutex)); - - return items; - -} diff --git a/Program/libcsp/src/arch/posix/csp_clock.c b/Program/libcsp/src/arch/posix/csp_clock.c deleted file mode 100755 index 2661cda..0000000 --- a/Program/libcsp/src/arch/posix/csp_clock.c +++ /dev/null @@ -1,45 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -__attribute__((weak)) void csp_clock_get_time(csp_timestamp_t * time) { - - struct timespec ts; - if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { - time->tv_sec = ts.tv_sec; - time->tv_nsec = ts.tv_nsec; - } else { - time->tv_sec = 0; - time->tv_nsec = 0; - } -} - -__attribute__((weak)) int csp_clock_set_time(const csp_timestamp_t * time) { - - struct timespec ts = {.tv_sec = time->tv_sec, .tv_nsec = time->tv_nsec}; - if (clock_settime(CLOCK_REALTIME, &ts) == 0) { - return CSP_ERR_NONE; - } - return CSP_ERR_INVAL; // CSP doesn't have any matching error codes - -} diff --git a/Program/libcsp/src/arch/posix/csp_malloc.c b/Program/libcsp/src/arch/posix/csp_malloc.c deleted file mode 100755 index 6fa9c1f..0000000 --- a/Program/libcsp/src/arch/posix/csp_malloc.c +++ /dev/null @@ -1,36 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -void * csp_malloc(size_t size) { - return malloc(size); -} - -void * csp_calloc(size_t nmemb, size_t size) { - return calloc(nmemb, size); -} - -void csp_free(void *ptr) { - free(ptr); -} - diff --git a/Program/libcsp/src/arch/posix/csp_queue.c b/Program/libcsp/src/arch/posix/csp_queue.c deleted file mode 100755 index b40443f..0000000 --- a/Program/libcsp/src/arch/posix/csp_queue.c +++ /dev/null @@ -1,60 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -csp_queue_handle_t csp_queue_create(int length, size_t item_size) { - return pthread_queue_create(length, item_size); -} - -void csp_queue_remove(csp_queue_handle_t queue) { - return pthread_queue_delete(queue); -} - -int csp_queue_enqueue(csp_queue_handle_t handle, const void *value, uint32_t timeout) { - return pthread_queue_enqueue(handle, value, timeout); -} - -int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * task_woken) { - if (task_woken != NULL) { - *task_woken = 0; - } - return csp_queue_enqueue(handle, value, 0); -} - -int csp_queue_dequeue(csp_queue_handle_t handle, void *buf, uint32_t timeout) { - return pthread_queue_dequeue(handle, buf, timeout); -} - -int csp_queue_dequeue_isr(csp_queue_handle_t handle, void *buf, CSP_BASE_TYPE * task_woken) { - if (task_woken != NULL) { - *task_woken = 0; - } - return csp_queue_dequeue(handle, buf, 0); -} - -int csp_queue_size(csp_queue_handle_t handle) { - return pthread_queue_items(handle); -} - -int csp_queue_size_isr(csp_queue_handle_t handle) { - return pthread_queue_items(handle); -} diff --git a/Program/libcsp/src/arch/posix/csp_semaphore.c b/Program/libcsp/src/arch/posix/csp_semaphore.c deleted file mode 100755 index 00e9cd5..0000000 --- a/Program/libcsp/src/arch/posix/csp_semaphore.c +++ /dev/null @@ -1,155 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include - -int csp_mutex_create(csp_mutex_t * mutex) { - csp_log_lock("Mutex init: %p", mutex); - if (pthread_mutex_init(mutex, NULL) == 0) { - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} - -int csp_mutex_remove(csp_mutex_t * mutex) { - if (pthread_mutex_destroy(mutex) == 0) { - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} - -int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { - - int ret; - - csp_log_lock("Wait: %p timeout %"PRIu32, mutex, timeout); - - if (timeout == CSP_MAX_TIMEOUT) { - ret = pthread_mutex_lock(mutex); - } else { - struct timespec ts; - if (clock_gettime(CLOCK_REALTIME, &ts)) { - return CSP_SEMAPHORE_ERROR; - } - - uint32_t sec = timeout / 1000; - uint32_t nsec = (timeout - 1000 * sec) * 1000000; - - ts.tv_sec += sec; - - if (ts.tv_nsec + nsec >= 1000000000) { - ts.tv_sec++; - } - - ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; - - ret = pthread_mutex_timedlock(mutex, &ts); - } - - if (ret != 0) - return CSP_SEMAPHORE_ERROR; - - return CSP_SEMAPHORE_OK; -} - -int csp_mutex_unlock(csp_mutex_t * mutex) { - if (pthread_mutex_unlock(mutex) == 0) { - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} - -int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { - csp_log_lock("Semaphore init: %p", sem); - if (sem_init(sem, 0, 1) == 0) { - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} - -int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { - if (sem_destroy(sem) == 0) { - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} - -int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { - - int ret; - - csp_log_lock("Wait: %p timeout %"PRIu32, sem, timeout); - - if (timeout == CSP_MAX_TIMEOUT) { - ret = sem_wait(sem); - } else { - struct timespec ts; - if (clock_gettime(CLOCK_REALTIME, &ts)) { - return CSP_SEMAPHORE_ERROR; - } - - uint32_t sec = timeout / 1000; - uint32_t nsec = (timeout - 1000 * sec) * 1000000; - - ts.tv_sec += sec; - - if (ts.tv_nsec + nsec >= 1000000000) { - ts.tv_sec++; - } - - ts.tv_nsec = (ts.tv_nsec + nsec) % 1000000000; - - ret = sem_timedwait(sem, &ts); - } - - if (ret != 0) - return CSP_SEMAPHORE_ERROR; - - return CSP_SEMAPHORE_OK; -} - -int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * task_woken) { - if (task_woken) { - *task_woken = 0; - } - return csp_bin_sem_post(sem); -} - -int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { - csp_log_lock("Post: %p", sem); - - int value; - sem_getvalue(sem, &value); - if (value > 0) { - return CSP_SEMAPHORE_OK; - } - - if (sem_post(sem) == 0) { - return CSP_SEMAPHORE_OK; - } - - return CSP_SEMAPHORE_ERROR; -} diff --git a/Program/libcsp/src/arch/posix/csp_system.c b/Program/libcsp/src/arch/posix/csp_system.c deleted file mode 100755 index 6f20833..0000000 --- a/Program/libcsp/src/arch/posix/csp_system.c +++ /dev/null @@ -1,135 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -int csp_sys_tasklist(char * out) { - - strcpy(out, "Tasklist not available on POSIX"); - return CSP_ERR_NONE; - -} - -int csp_sys_tasklist_size(void) { - - return 100; - -} - -uint32_t csp_sys_memfree(void) { - - uint32_t total = 0; - struct sysinfo info; - sysinfo(&info); - total = info.freeram * info.mem_unit; - return total; - -} - -// helper for doing log and mapping result to CSP_ERR -static int csp_sys_log_and_return(const char * function, int res) { - - if (res != 0) { - csp_log_warn("%s: failed to execute, returned error: %d, errno: %d", function, res, errno); - return CSP_ERR_INVAL; // no real suitable error code - } - csp_log_info("%s: executed", function); - return CSP_ERR_NONE; - -} - -int csp_sys_reboot_using_system(void) { - - return csp_sys_log_and_return(__FUNCTION__, system("reboot")); - -} - -int csp_sys_reboot_using_reboot(void) { - - sync(); // Sync filesystem - return csp_sys_log_and_return(__FUNCTION__, reboot(LINUX_REBOOT_CMD_RESTART)); - -} - -int csp_sys_shutdown_using_system(void) { - - return csp_sys_log_and_return(__FUNCTION__, system("halt")); - -} - -int csp_sys_shutdown_using_reboot(void) { - - sync(); // Sync filesystem - return csp_sys_log_and_return(__FUNCTION__, reboot(LINUX_REBOOT_CMD_HALT)); - -} - -void csp_sys_set_color(csp_color_t color) { - - unsigned int color_code, modifier_code; - switch (color & COLOR_MASK_COLOR) { - case COLOR_BLACK: - color_code = 30; break; - case COLOR_RED: - color_code = 31; break; - case COLOR_GREEN: - color_code = 32; break; - case COLOR_YELLOW: - color_code = 33; break; - case COLOR_BLUE: - color_code = 34; break; - case COLOR_MAGENTA: - color_code = 35; break; - case COLOR_CYAN: - color_code = 36; break; - case COLOR_WHITE: - color_code = 37; break; - case COLOR_RESET: - default: - color_code = 0; break; - } - - switch (color & COLOR_MASK_MODIFIER) { - case COLOR_BOLD: - modifier_code = 1; break; - case COLOR_UNDERLINE: - modifier_code = 2; break; - case COLOR_BLINK: - modifier_code = 3; break; - case COLOR_HIDE: - modifier_code = 4; break; - case COLOR_NORMAL: - default: - modifier_code = 0; break; - } - - printf("\033[%u;%um", modifier_code, color_code); -} diff --git a/Program/libcsp/src/arch/posix/csp_thread.c b/Program/libcsp/src/arch/posix/csp_thread.c deleted file mode 100755 index 621c1b9..0000000 --- a/Program/libcsp/src/arch/posix/csp_thread.c +++ /dev/null @@ -1,72 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include - -int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { - - pthread_attr_t attributes; - if (pthread_attr_init(&attributes) != 0) { - return CSP_ERR_NOMEM; - } - // if stack size is 0, use default stack size - if (stack_size) { - unsigned int min_stack_size = PTHREAD_STACK_MIN;// use at least one memory - while (min_stack_size < stack_size) { // must reach at least the provided size - min_stack_size += PTHREAD_STACK_MIN;// keep memory page boundary (some systems may fail otherwise)) - } - pthread_attr_setstacksize(&attributes, min_stack_size); - } - pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);// no need to join with thread to free its resources - - pthread_t handle; - int return_code = pthread_create(&handle, &attributes, routine, parameters); - pthread_attr_destroy(&attributes); - - if (return_code != 0) { - return CSP_ERR_NOMEM; - } - if (return_handle) { - *return_handle = handle; - } - - return CSP_ERR_NONE; -} - -void csp_thread_exit(void) { - - pthread_exit(CSP_TASK_RETURN); -} - -void csp_sleep_ms(unsigned int time_ms) { - - struct timespec req, rem; - req.tv_sec = (time_ms / 1000U); - req.tv_nsec = ((time_ms % 1000U) * 1000000U); - - while ((nanosleep(&req, &rem) < 0) && (errno == EINTR)) { - req = rem; - } -} diff --git a/Program/libcsp/src/arch/posix/csp_time.c b/Program/libcsp/src/arch/posix/csp_time.c deleted file mode 100755 index 9485447..0000000 --- a/Program/libcsp/src/arch/posix/csp_time.c +++ /dev/null @@ -1,57 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include - -uint32_t csp_get_ms(void) { - - struct timespec ts; - if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { - return (uint32_t)((ts.tv_sec*1000) + (ts.tv_nsec/1000000)); - } - return 0; - -} - -uint32_t csp_get_ms_isr(void) { - - return csp_get_ms(); - -} - -uint32_t csp_get_s(void) { - - struct timespec ts; - if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { - return (uint32_t)ts.tv_sec; - } - return 0; - -} - -uint32_t csp_get_s_isr(void) { - - return csp_get_s(); - -} diff --git a/Program/libcsp/src/arch/posix/pthread_queue.c b/Program/libcsp/src/arch/posix/pthread_queue.c deleted file mode 100755 index 066620b..0000000 --- a/Program/libcsp/src/arch/posix/pthread_queue.c +++ /dev/null @@ -1,239 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* -Inspired by c-pthread-queue by Matthew Dickinson -http://code.google.com/p/c-pthread-queue/ -*/ - -#include - -#include -#include - -#include - -static inline int get_deadline(struct timespec *ts, uint32_t timeout_ms) -{ - int ret = clock_gettime(CLOCK_MONOTONIC, ts); - - if (ret < 0) { - return ret; - } - - uint32_t sec = timeout_ms / 1000; - uint32_t nsec = (timeout_ms - 1000 * sec) * 1000000; - - ts->tv_sec += sec; - - if (ts->tv_nsec + nsec >= 1000000000) { - ts->tv_sec++; - } - - ts->tv_nsec = (ts->tv_nsec + nsec) % 1000000000; - - return ret; -} - -static inline int init_cond_clock_monotonic(pthread_cond_t * cond) -{ - - int ret; - pthread_condattr_t attr; - - pthread_condattr_init(&attr); - ret = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); - - if (ret == 0) { - ret = pthread_cond_init(cond, &attr); - } - - pthread_condattr_destroy(&attr); - return ret; - -} - -pthread_queue_t * pthread_queue_create(int length, size_t item_size) { - - pthread_queue_t * q = csp_malloc(sizeof(pthread_queue_t)); - - if (q != NULL) { - q->buffer = csp_malloc(length*item_size); - if (q->buffer != NULL) { - q->size = length; - q->item_size = item_size; - q->items = 0; - q->in = 0; - q->out = 0; - if (pthread_mutex_init(&(q->mutex), NULL) || init_cond_clock_monotonic(&(q->cond_full)) || init_cond_clock_monotonic(&(q->cond_empty))) { - csp_free(q->buffer); - csp_free(q); - q = NULL; - } - } else { - csp_free(q); - q = NULL; - } - } - - return q; - -} - -void pthread_queue_delete(pthread_queue_t * q) { - - if (q == NULL) - return; - - csp_free(q->buffer); - csp_free(q); - - return; - -} - - -static inline int wait_slot_available(pthread_queue_t * queue, struct timespec *ts) { - - int ret; - - while (queue->items == queue->size) { - - if (ts != NULL) { - ret = pthread_cond_timedwait(&(queue->cond_full), &(queue->mutex), ts); - } else { - ret = pthread_cond_wait(&(queue->cond_full), &(queue->mutex)); - } - - if (ret != 0 && errno != EINTR) { - return PTHREAD_QUEUE_FULL; //Timeout - } - } - - return PTHREAD_QUEUE_OK; - -} - -int pthread_queue_enqueue(pthread_queue_t * queue, const void * value, uint32_t timeout) { - - int ret; - struct timespec ts; - struct timespec *pts = NULL; - - /* Calculate timeout */ - if (timeout != CSP_MAX_TIMEOUT) { - if (get_deadline(&ts, timeout) != 0) { - return PTHREAD_QUEUE_ERROR; - } - pts = &ts; - } else { - pts = NULL; - } - - /* Get queue lock */ - pthread_mutex_lock(&(queue->mutex)); - - ret = wait_slot_available(queue, pts); - if (ret == PTHREAD_QUEUE_OK) { - /* Copy object from input buffer */ - memcpy(queue->buffer+(queue->in * queue->item_size), value, queue->item_size); - queue->items++; - queue->in = (queue->in + 1) % queue->size; - } - - pthread_mutex_unlock(&(queue->mutex)); - - if (ret == PTHREAD_QUEUE_OK) { - /* Nofify blocked threads */ - pthread_cond_broadcast(&(queue->cond_empty)); - } - - return ret; - -} - -static inline int wait_item_available(pthread_queue_t * queue, struct timespec *ts) { - - int ret; - - while (queue->items == 0) { - - if (ts != NULL) { - ret = pthread_cond_timedwait(&(queue->cond_empty), &(queue->mutex), ts); - } else { - ret = pthread_cond_wait(&(queue->cond_empty), &(queue->mutex)); - } - - if (ret != 0 && errno != EINTR) { - return PTHREAD_QUEUE_EMPTY; //Timeout - } - } - - return PTHREAD_QUEUE_OK; - -} - -int pthread_queue_dequeue(pthread_queue_t * queue, void * buf, uint32_t timeout) { - - int ret; - struct timespec ts; - struct timespec *pts; - - /* Calculate timeout */ - if (timeout != CSP_MAX_TIMEOUT) { - if (get_deadline(&ts, timeout) != 0) { - return PTHREAD_QUEUE_ERROR; - } - pts = &ts; - } else { - pts = NULL; - } - - /* Get queue lock */ - pthread_mutex_lock(&(queue->mutex)); - - ret = wait_item_available(queue, pts); - if (ret == PTHREAD_QUEUE_OK) { - /* Coby object to output buffer */ - memcpy(buf, queue->buffer+(queue->out * queue->item_size), queue->item_size); - queue->items--; - queue->out = (queue->out + 1) % queue->size; - } - - pthread_mutex_unlock(&(queue->mutex)); - - if (ret == PTHREAD_QUEUE_OK) { - /* Nofify blocked threads */ - pthread_cond_broadcast(&(queue->cond_full)); - } - - return ret; - -} - -int pthread_queue_items(pthread_queue_t * queue) { - - pthread_mutex_lock(&(queue->mutex)); - int items = queue->items; - pthread_mutex_unlock(&(queue->mutex)); - - return items; - -} diff --git a/Program/libcsp/src/arch/windows/README b/Program/libcsp/src/arch/windows/README deleted file mode 100755 index b97ce7f..0000000 --- a/Program/libcsp/src/arch/windows/README +++ /dev/null @@ -1,18 +0,0 @@ -This directory contains files specific to the windows port of libcsp. - -To compile and create a static library, execute: - - python waf configure --with-os=windows build - -from the root of this project. Note python must be in PATH. - -The build requirements are: - * Windows Vista SP1 - * A recent version of MinGW _or_ MinGW-w64 - * Windows API headers - * cPython 2.5 or newer - -What provides the Windows API headers depends on the development environment: -Using MinGW: Headers provided by w32api package. windows_glue.h header is needed because these headers do not declare condition variables. -Using MinGW-w64: Headers should be available in the default configuration. You may have to compile the distribution from source. windows_glue.h should not be needed. - diff --git a/Program/libcsp/src/arch/windows/csp_clock.c b/Program/libcsp/src/arch/windows/csp_clock.c deleted file mode 100755 index a398a61..0000000 --- a/Program/libcsp/src/arch/windows/csp_clock.c +++ /dev/null @@ -1,42 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -#include - -//__attribute__((weak)) void csp_clock_get_time(csp_timestamp_t * time) { -void csp_clock_get_time(csp_timestamp_t * time) { - - FILETIME ftime; // 64-bit, representing the number of 100-nanosecond intervals since January 1, 1601 (UTC). - GetSystemTimeAsFileTime(&ftime); - ULARGE_INTEGER itime = {.LowPart = ftime.dwLowDateTime, .HighPart = ftime.dwHighDateTime}; - itime.QuadPart -= 116444736000000000ULL; // 1 jan 1601 to 1 jan 1970 - time->tv_sec = itime.QuadPart / (1000ULL * 1000ULL * 10ULL); - time->tv_nsec = (itime.QuadPart % (1000ULL * 1000ULL * 10ULL)) * 100ULL; -} - -//__attribute__((weak)) int csp_clock_set_time(const csp_timestamp_t * time) { -int csp_clock_set_time(const csp_timestamp_t * time) { - csp_log_warn("csp_clock_set_time() not supported"); - return CSP_ERR_NOTSUP; -} diff --git a/Program/libcsp/src/arch/windows/csp_malloc.c b/Program/libcsp/src/arch/windows/csp_malloc.c deleted file mode 100755 index 03faca7..0000000 --- a/Program/libcsp/src/arch/windows/csp_malloc.c +++ /dev/null @@ -1,35 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -void * csp_malloc(size_t size) { - return malloc(size); -} - -void * csp_calloc(size_t nmemb, size_t size) { - return calloc(nmemb, size); -} - -void csp_free(void * ptr) { - free(ptr); -} diff --git a/Program/libcsp/src/arch/windows/csp_queue.c b/Program/libcsp/src/arch/windows/csp_queue.c deleted file mode 100755 index eb49738..0000000 --- a/Program/libcsp/src/arch/windows/csp_queue.c +++ /dev/null @@ -1,59 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "windows_queue.h" - -csp_queue_handle_t csp_queue_create(int length, size_t item_size) { - return windows_queue_create(length, item_size); -} - -void csp_queue_remove(csp_queue_handle_t queue) { - windows_queue_delete(queue); -} - -int csp_queue_enqueue(csp_queue_handle_t handle, const void *value, uint32_t timeout) { - return windows_queue_enqueue(handle, value, timeout); -} - -int csp_queue_enqueue_isr(csp_queue_handle_t handle, const void * value, CSP_BASE_TYPE * task_woken) { - if( task_woken != NULL ) - *task_woken = 0; - return windows_queue_enqueue(handle, value, 0); -} - -int csp_queue_dequeue(csp_queue_handle_t handle, void *buf, uint32_t timeout) { - return windows_queue_dequeue(handle, buf, timeout); -} - -int csp_queue_dequeue_isr(csp_queue_handle_t handle, void * buf, CSP_BASE_TYPE * task_woken) { - if (task_woken != NULL) { - *task_woken = 0; - } - return windows_queue_dequeue(handle, buf, 0); -} - -int csp_queue_size(csp_queue_handle_t handle) { - return windows_queue_items(handle); -} - -int csp_queue_size_isr(csp_queue_handle_t handle) { - return windows_queue_items(handle); -} diff --git a/Program/libcsp/src/arch/windows/csp_semaphore.c b/Program/libcsp/src/arch/windows/csp_semaphore.c deleted file mode 100755 index 7f44478..0000000 --- a/Program/libcsp/src/arch/windows/csp_semaphore.c +++ /dev/null @@ -1,100 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -int csp_mutex_create(csp_mutex_t * mutex) { - - HANDLE mutexHandle = CreateMutex(NULL, FALSE, FALSE); - if( mutexHandle == NULL ) { - return CSP_MUTEX_ERROR; - } - *mutex = mutexHandle; - return CSP_MUTEX_OK; -} - -int csp_mutex_remove(csp_mutex_t * mutex) { - - if( !CloseHandle(*mutex) ) { - return CSP_MUTEX_ERROR; - } - return CSP_MUTEX_OK; -} - -int csp_mutex_lock(csp_mutex_t * mutex, uint32_t timeout) { - - if(WaitForSingleObject(*mutex, timeout) == WAIT_OBJECT_0) { - return CSP_MUTEX_OK; - } - return CSP_MUTEX_ERROR; -} - -int csp_mutex_unlock(csp_mutex_t * mutex) { - - if( !ReleaseMutex(*mutex) ) { - return CSP_MUTEX_ERROR; - } - return CSP_MUTEX_OK; -} - -int csp_bin_sem_create(csp_bin_sem_handle_t * sem) { - - HANDLE semHandle = CreateSemaphore(NULL, 1, 1, NULL); - if( semHandle == NULL ) { - return CSP_SEMAPHORE_ERROR; - } - *sem = semHandle; - return CSP_SEMAPHORE_OK; -} - -int csp_bin_sem_remove(csp_bin_sem_handle_t * sem) { - - if( !CloseHandle(*sem) ) { - return CSP_SEMAPHORE_ERROR; - } - return CSP_SEMAPHORE_OK; -} - -int csp_bin_sem_wait(csp_bin_sem_handle_t * sem, uint32_t timeout) { - - if( WaitForSingleObject(*sem, timeout) == WAIT_OBJECT_0 ) { - return CSP_SEMAPHORE_OK; - } - return CSP_SEMAPHORE_ERROR; -} - -int csp_bin_sem_post(csp_bin_sem_handle_t * sem) { - - if( !ReleaseSemaphore(*sem, 1, NULL) ) { - return CSP_SEMAPHORE_ERROR; - } - return CSP_SEMAPHORE_OK; -} - -int csp_bin_sem_post_isr(csp_bin_sem_handle_t * sem, CSP_BASE_TYPE * task_woken) { - - if( task_woken != NULL ) { - *task_woken = 0; - } - return csp_bin_sem_post(sem); -} - diff --git a/Program/libcsp/src/arch/windows/csp_system.c b/Program/libcsp/src/arch/windows/csp_system.c deleted file mode 100755 index a88ae48..0000000 --- a/Program/libcsp/src/arch/windows/csp_system.c +++ /dev/null @@ -1,54 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include - -#include - -int csp_sys_tasklist(char * out) { - - strcpy(out, "Tasklist not available on Windows"); - return CSP_ERR_NONE; - -} - -int csp_sys_tasklist_size(void) { - - return 100; - -} - -uint32_t csp_sys_memfree(void) { - - MEMORYSTATUSEX statex; - statex.dwLength = sizeof(statex); - GlobalMemoryStatusEx(&statex); - DWORDLONG freePhysicalMem = statex.ullAvailPhys; - size_t total = (size_t) freePhysicalMem; - return (uint32_t)total; - -} - -void csp_sys_set_color(csp_color_t color) { - // not implemented -} diff --git a/Program/libcsp/src/arch/windows/csp_thread.c b/Program/libcsp/src/arch/windows/csp_thread.c deleted file mode 100755 index af01945..0000000 --- a/Program/libcsp/src/arch/windows/csp_thread.c +++ /dev/null @@ -1,46 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -int csp_thread_create(csp_thread_func_t routine, const char * const thread_name, unsigned int stack_size, void * parameters, unsigned int priority, csp_thread_handle_t * return_handle) { - - HANDLE handle = (HANDLE) _beginthreadex(NULL, 0, routine, parameters, 0, 0); - if (handle == 0) { - return CSP_ERR_NOMEM; - } - if (return_handle) { - *return_handle = handle; - } - - return CSP_ERR_NONE; -} - -void csp_thread_exit(void) { - - _endthreadex(CSP_TASK_RETURN); -} - -void csp_sleep_ms(unsigned int time_ms) { - - Sleep(time_ms); -} diff --git a/Program/libcsp/src/arch/windows/csp_time.c b/Program/libcsp/src/arch/windows/csp_time.c deleted file mode 100755 index 7ca919d..0000000 --- a/Program/libcsp/src/arch/windows/csp_time.c +++ /dev/null @@ -1,44 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -uint32_t csp_get_ms(void) { - - return (uint32_t)GetTickCount(); -} - -uint32_t csp_get_ms_isr(void) { - - return csp_get_ms(); -} - -uint32_t csp_get_s(void) { - - uint32_t time_ms = csp_get_ms(); - return time_ms/1000; -} - -uint32_t csp_get_s_isr(void) { - - return csp_get_s(); -} diff --git a/Program/libcsp/src/arch/windows/windows_queue.c b/Program/libcsp/src/arch/windows/windows_queue.c deleted file mode 100755 index 815aa33..0000000 --- a/Program/libcsp/src/arch/windows/windows_queue.c +++ /dev/null @@ -1,127 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "windows_queue.h" -#include -#include - -struct windows_queue_s { - void * buffer; - int size; - int item_size; - int items; - int head_idx; - CRITICAL_SECTION mutex; - CONDITION_VARIABLE cond_full; - CONDITION_VARIABLE cond_empty; -}; - -static int queueFull(windows_queue_t * queue) { - return queue->items == queue->size; -} - -static int queueEmpty(windows_queue_t * queue) { - return queue->items == 0; -} - -windows_queue_t * windows_queue_create(int length, size_t item_size) { - - windows_queue_t *queue = (windows_queue_t*)malloc(sizeof(windows_queue_t)); - if(queue == NULL) - goto queue_malloc_failed; - - queue->buffer = malloc(length*item_size); - if(queue->buffer == NULL) - goto buffer_malloc_failed; - - queue->size = length; - queue->item_size = item_size; - queue->items = 0; - queue->head_idx = 0; - - InitializeCriticalSection(&(queue->mutex)); - InitializeConditionVariable(&(queue->cond_full)); - InitializeConditionVariable(&(queue->cond_empty)); - goto queue_init_success; - -buffer_malloc_failed: - free(queue); - queue = NULL; -queue_malloc_failed: -queue_init_success: - return queue; -} - -void windows_queue_delete(windows_queue_t * q) { - - if(q==NULL) return; - DeleteCriticalSection(&(q->mutex)); - free(q->buffer); - free(q); -} - -int windows_queue_enqueue(windows_queue_t * queue, const void * value, int timeout) { - - int offset; - EnterCriticalSection(&(queue->mutex)); - while(queueFull(queue)) { - int ret = SleepConditionVariableCS(&(queue->cond_full), &(queue->mutex), timeout); - if( !ret ) { - LeaveCriticalSection(&(queue->mutex)); - return ret == WAIT_TIMEOUT ? WINDOWS_QUEUE_FULL : WINDOWS_QUEUE_ERROR; - } - } - offset = ((queue->head_idx+queue->items) % queue->size) * queue->item_size; - memcpy((unsigned char*)queue->buffer + offset, value, queue->item_size); - queue->items++; - - LeaveCriticalSection(&(queue->mutex)); - WakeAllConditionVariable(&(queue->cond_empty)); - return WINDOWS_QUEUE_OK; -} - -int windows_queue_dequeue(windows_queue_t * queue, void * buf, int timeout) { - - EnterCriticalSection(&(queue->mutex)); - while(queueEmpty(queue)) { - int ret = SleepConditionVariableCS(&(queue->cond_empty), &(queue->mutex), timeout); - if( !ret ) { - LeaveCriticalSection(&(queue->mutex)); - return ret == WAIT_TIMEOUT ? WINDOWS_QUEUE_EMPTY : WINDOWS_QUEUE_ERROR; - } - } - memcpy(buf, (unsigned char*)queue->buffer+(queue->head_idx%queue->size*queue->item_size), queue->item_size); - queue->items--; - queue->head_idx = (queue->head_idx + 1) % queue->size; - - LeaveCriticalSection(&(queue->mutex)); - WakeAllConditionVariable(&(queue->cond_full)); - return WINDOWS_QUEUE_OK; -} - -int windows_queue_items(windows_queue_t * queue) { - - int items; - EnterCriticalSection(&(queue->mutex)); - items = queue->items; - LeaveCriticalSection(&(queue->mutex)); - - return items; -} diff --git a/Program/libcsp/src/arch/windows/windows_queue.h b/Program/libcsp/src/arch/windows/windows_queue.h deleted file mode 100755 index 1bee749..0000000 --- a/Program/libcsp/src/arch/windows/windows_queue.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _WINDOWS_QUEUE_H_ -#define _WINDOWS_QUEUE_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define WINDOWS_QUEUE_ERROR CSP_QUEUE_ERROR -#define WINDOWS_QUEUE_EMPTY CSP_QUEUE_ERROR -#define WINDOWS_QUEUE_FULL CSP_QUEUE_ERROR -#define WINDOWS_QUEUE_OK CSP_QUEUE_OK - -typedef struct windows_queue_s windows_queue_t; - -windows_queue_t * windows_queue_create(int length, size_t item_size); -void windows_queue_delete(windows_queue_t * q); -int windows_queue_enqueue(windows_queue_t * queue, const void * value, int timeout); -int windows_queue_dequeue(windows_queue_t * queue, void * buf, int timeout); -int windows_queue_items(windows_queue_t * queue); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/bindings/python/pycsp.c b/Program/libcsp/src/bindings/python/pycsp.c deleted file mode 100755 index 9f909c3..0000000 --- a/Program/libcsp/src/bindings/python/pycsp.c +++ /dev/null @@ -1,1121 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include -#include -#include -#include -#include -#include -// #include -#include - -#include - -#define SOCKET_CAPSULE "csp_socket_t" -#define CONNECTION_CAPSULE "csp_conn_t" -#define PACKET_CAPSULE "csp_packet_t" - -static PyObject *Error = NULL; - -static int CSP_POINTER_HAS_BEEN_FREED = 0; // used to indicate pointer has been freed, because a NULL pointer can't be set. - -static void * get_capsule_pointer(PyObject* capsule, const char* expected_type, bool allow_null) { - const char* capsule_name = PyCapsule_GetName(capsule); - if (strcmp(capsule_name, expected_type) != 0) { - PyErr_Format(PyExc_TypeError, - "capsule contains unexpected type, expected=%s, got=%s", - expected_type, capsule_name); // TypeError is thrown - return NULL; - } - void * ptr = PyCapsule_GetPointer(capsule, expected_type); - if (ptr == &CSP_POINTER_HAS_BEEN_FREED) { - ptr = NULL; - } - if ((ptr == NULL) && !allow_null) { - PyErr_Format(PyExc_TypeError, - "capsule: type=%s - already freed", - expected_type); // TypeError is thrown - return NULL; - } - return ptr; -} - -static csp_packet_t * get_obj_as_packet(PyObject* obj, bool allow_null) { - return get_capsule_pointer(obj, PACKET_CAPSULE, allow_null); -} - -static csp_conn_t * get_obj_as_conn(PyObject* obj, bool allow_null) { - return get_capsule_pointer(obj, CONNECTION_CAPSULE, allow_null); -} - -static csp_socket_t * get_obj_as_socket(PyObject* obj, bool allow_null) { - return get_capsule_pointer(obj, SOCKET_CAPSULE, allow_null); -} - -static PyObject* PyErr_Error(const char * message, int error) { - PyErr_Format(Error, "%s, result/error: %d", message, error); // should set error as member - return NULL; -} - -static void pycsp_free_csp_buffer(PyObject *obj) { - csp_packet_t * packet = get_obj_as_packet(obj, true); - if (packet) { - csp_buffer_free(packet); - } - PyCapsule_SetPointer(obj, &CSP_POINTER_HAS_BEEN_FREED); -} - -static void pycsp_free_csp_conn(PyObject *obj) { - csp_conn_t * conn = get_obj_as_conn(obj, true); - if (conn) { - csp_close(conn); - } - PyCapsule_SetPointer(obj, &CSP_POINTER_HAS_BEEN_FREED); -} - -static void pycsp_free_csp_socket(PyObject *obj) { - csp_conn_t * socket = get_obj_as_socket(obj, true); - if (socket) { - csp_close(socket); - } - PyCapsule_SetPointer(obj, &CSP_POINTER_HAS_BEEN_FREED); -} - -static PyObject* pycsp_service_handler(PyObject *self, PyObject *args) { - PyObject* conn_capsule; - PyObject* packet_capsule; - if (!PyArg_ParseTuple(args, "OO", &conn_capsule, &packet_capsule)) { - return NULL; // TypeError is thrown - } - csp_conn_t* conn = get_obj_as_conn(conn_capsule, false); - if (conn == NULL) { - return NULL; - } - csp_packet_t* packet = get_obj_as_packet(packet_capsule, false); - if (packet == NULL) { - return NULL; - } - - csp_service_handler(conn, packet); - PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); - Py_RETURN_NONE; -} - -static void copy_string(const char * from, char * to, size_t size_to) { - memset(to, 0, size_to); - if (from && from[0]) { - strncpy(to, from, size_to - 1); - } -} - -static PyObject* pycsp_init(PyObject *self, PyObject *args) { - - csp_conf_t conf; - csp_conf_get_defaults(&conf); - - if (!PyArg_ParseTuple(args, "bsssHH", &conf.address, &conf.hostname, &conf.model, &conf.revision, &conf.buffers, &conf.buffer_data_size)) { - return NULL; // TypeError is thrown - } - - // csp_conf only saves the pointer, so the strings needs to be stored somewhere - static char hostname[CSP_HOSTNAME_LEN + 1]; - static char model[CSP_MODEL_LEN + 1]; - static char revision[CSP_CMP_IDENT_REV_LEN + 1]; - - copy_string(conf.hostname, hostname, sizeof(hostname)); - copy_string(conf.model, model, sizeof(model)); - copy_string(conf.revision, revision, sizeof(revision)); - - conf.hostname = hostname; - conf.model = model; - conf.revision = revision; - - int res = csp_init(&conf); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_init()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_get_hostname(PyObject *self, PyObject *args) { - return Py_BuildValue("s", csp_get_conf()->hostname); -} - -static PyObject* pycsp_get_model(PyObject *self, PyObject *args) { - return Py_BuildValue("s", csp_get_conf()->model); -} - -static PyObject* pycsp_get_revision(PyObject *self, PyObject *args) { - return Py_BuildValue("s", csp_get_conf()->revision); -} - -static PyObject* pycsp_socket(PyObject *self, PyObject *args) { - uint32_t opts = CSP_SO_NONE; - if (!PyArg_ParseTuple(args, "|I", &opts)) { - return NULL; // TypeError is thrown - } - - csp_socket_t * socket = csp_socket(opts); - if (socket == NULL) { - return PyErr_Error("csp_socket() - no free sockets/connections", CSP_ERR_NOBUFS); - } - return PyCapsule_New(socket, SOCKET_CAPSULE, pycsp_free_csp_socket); -} - -static PyObject* pycsp_accept(PyObject *self, PyObject *args) { - PyObject* socket_capsule; - uint32_t timeout = CSP_MAX_TIMEOUT; - if (!PyArg_ParseTuple(args, "O|I", &socket_capsule, &timeout)) { - return NULL; // TypeError is thrown - } - csp_socket_t* socket = get_obj_as_socket(socket_capsule, false); - if (socket == NULL) { - return NULL; - } - csp_conn_t* conn; - Py_BEGIN_ALLOW_THREADS; - conn = csp_accept(socket, timeout); - Py_END_ALLOW_THREADS; - if (conn == NULL) { - Py_RETURN_NONE; // timeout -> None - } - - return PyCapsule_New(conn, CONNECTION_CAPSULE, pycsp_free_csp_conn); -} - -static PyObject* pycsp_read(PyObject *self, PyObject *args) { - PyObject* conn_capsule; - uint32_t timeout = 500; - if (!PyArg_ParseTuple(args, "O|I", &conn_capsule, &timeout)) { - return NULL; // TypeError is thrown - } - csp_conn_t* conn = get_obj_as_conn(conn_capsule, false); - if (conn == NULL) { - return NULL; - } - csp_packet_t* packet; - Py_BEGIN_ALLOW_THREADS; - packet = csp_read(conn, timeout); - Py_END_ALLOW_THREADS; - if (packet == NULL) { - Py_RETURN_NONE; // timeout -> None - } - - return PyCapsule_New(packet, PACKET_CAPSULE, pycsp_free_csp_buffer); -} - -static PyObject* pycsp_send(PyObject *self, PyObject *args) { - PyObject* conn_capsule; - PyObject* packet_capsule; - uint32_t timeout = 1000; - if (!PyArg_ParseTuple(args, "OO|I", &conn_capsule, &packet_capsule, &timeout)) { - return NULL; // TypeError is thrown - } - csp_conn_t* conn = get_obj_as_conn(conn_capsule, false); - if (conn == NULL) { - return NULL; - } - csp_packet_t* packet = get_obj_as_packet(packet_capsule, false); - if (packet == NULL) { - return NULL; - } - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_send(conn, packet, timeout); - Py_END_ALLOW_THREADS; - if (res != 1) { - return PyErr_Error("csp_send()", res); - } - PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); - - Py_RETURN_NONE; -} - -static PyObject* pycsp_transaction(PyObject *self, PyObject *args) { - uint8_t prio; - uint8_t dest; - uint8_t port; - uint32_t timeout; - Py_buffer inbuf; - Py_buffer outbuf; - if (!PyArg_ParseTuple(args, "bbbIw*w*", &prio, &dest, &port, &timeout, &outbuf, &inbuf)) { - return NULL; // TypeError is thrown - } - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_transaction(prio, dest, port, timeout, outbuf.buf, outbuf.len, inbuf.buf, inbuf.len); - Py_END_ALLOW_THREADS; - if (res < 1) { - return PyErr_Error("csp_transaction()", res); - } - - return Py_BuildValue("i", res); -} - -static PyObject* pycsp_sendto(PyObject *self, PyObject *args) { - uint8_t prio; - uint8_t dest; - uint8_t dport; - uint8_t src_port; - uint32_t opts; - PyObject* packet_capsule; - uint32_t timeout = 1000; - if (!PyArg_ParseTuple(args, "bbbbIO|I", &prio, &dest, &dport, &src_port, &opts, &packet_capsule, &timeout)) { - Py_RETURN_NONE; - } - csp_packet_t* packet = get_obj_as_packet(packet_capsule, false); - if (packet == NULL) { - return NULL; - } - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_sendto(prio, dest, dport, src_port, opts, packet, timeout); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_sendto()", res); - } - PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); - - Py_RETURN_NONE; -} - -static PyObject* pycsp_sendto_reply(PyObject *self, PyObject *args) { - PyObject* request_packet_capsule; - PyObject* reply_packet_capsule; - uint32_t opts = CSP_O_NONE; - uint32_t timeout = 1000; - if (!PyArg_ParseTuple(args, "OO|II", &request_packet_capsule, &reply_packet_capsule, &opts, &timeout)) { - return NULL; // TypeError is thrown - } - csp_packet_t* request = get_obj_as_packet(request_packet_capsule, false); - if (request == NULL) { - return NULL; - } - csp_packet_t* reply = get_obj_as_packet(reply_packet_capsule, false); - if (reply == NULL) { - return NULL; - } - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_sendto_reply(request, reply, opts, timeout); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_sendto_reply()", res); - } - - PyCapsule_SetPointer(reply_packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); - Py_RETURN_NONE; -} - -static PyObject* pycsp_connect(PyObject *self, PyObject *args) { - uint8_t prio; - uint8_t dest; - uint8_t dport; - uint32_t timeout; - uint32_t opts; - if (!PyArg_ParseTuple(args, "bbbII", &prio, &dest, &dport, &timeout, &opts)) { - return NULL; // TypeError is thrown - } - - csp_conn_t *conn; - Py_BEGIN_ALLOW_THREADS; - conn = csp_connect(prio, dest, dport, timeout, opts); - Py_END_ALLOW_THREADS; - if (conn == NULL) { - return PyErr_Error("csp_connect() timeout or failed", CSP_ERR_TIMEDOUT); - } - - return PyCapsule_New(conn, CONNECTION_CAPSULE, pycsp_free_csp_conn); -} - -static PyObject* pycsp_close(PyObject *self, PyObject *conn_capsule) { - csp_conn_t * conn = get_obj_as_conn(conn_capsule, true); - if (conn) { - csp_close(conn); - PyCapsule_SetPointer(conn_capsule, &CSP_POINTER_HAS_BEEN_FREED); - } - - return Py_BuildValue("i", CSP_ERR_NONE); -} - -static PyObject* pycsp_conn_dport(PyObject *self, PyObject *conn_capsule) { - csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); - if (conn == NULL) { - return NULL; // TypeError is thrown - } - return Py_BuildValue("i", csp_conn_dport(conn)); -} - -static PyObject* pycsp_conn_sport(PyObject *self, PyObject *conn_capsule) { - csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); - if (conn == NULL) { - return NULL; // TypeError is thrown - } - return Py_BuildValue("i", csp_conn_sport(conn)); -} - -static PyObject* pycsp_conn_dst(PyObject *self, PyObject *conn_capsule) { - csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); - if (conn == NULL) { - return NULL; // TypeError is thrown - } - return Py_BuildValue("i", csp_conn_dst(conn)); -} - -static PyObject* pycsp_conn_src(PyObject *self, PyObject *conn_capsule) { - csp_conn_t * conn = get_obj_as_conn(conn_capsule, false); - if (conn == NULL) { - return NULL; // TypeError is thrown - } - return Py_BuildValue("i", csp_conn_src(conn)); -} - -static PyObject* pycsp_listen(PyObject *self, PyObject *args) { - PyObject* socket_capsule; - size_t conn_queue_len = 10; - if (!PyArg_ParseTuple(args, "O|n", &socket_capsule, &conn_queue_len)) { - return NULL; // TypeError is thrown - } - - csp_socket_t * sock = get_obj_as_socket(socket_capsule, false); - if (sock == NULL) { - return NULL; // TypeError is thrown - } - - int res = csp_listen(sock, conn_queue_len); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_listen()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_bind(PyObject *self, PyObject *args) { - PyObject* socket_capsule; - uint8_t port; - if (!PyArg_ParseTuple(args, "Ob", &socket_capsule, &port)) { - return NULL; // TypeError is thrown - } - - csp_socket_t * sock = get_obj_as_socket(socket_capsule, false); - if (sock == NULL) { - return NULL; // TypeError is thrown - } - - int res = csp_bind(sock, port); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_bind()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_route_start_task(PyObject *self, PyObject *args) { - unsigned int priority = CSP_PRIO_NORM; - if (!PyArg_ParseTuple(args, "|I", &priority)) { - return NULL; // TypeError is thrown - } - - int res = csp_route_start_task(0, priority); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_route_start_task()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_ping(PyObject *self, PyObject *args) { - uint8_t node; - uint32_t timeout = 1000; - unsigned int size = 10; - uint8_t conn_options = CSP_O_NONE; - if (!PyArg_ParseTuple(args, "b|IIb", &node, &timeout, &size, &conn_options)) { - return NULL; // TypeError is thrown - } - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_ping(node, timeout, size, conn_options); - Py_END_ALLOW_THREADS; - - if (res < 0) { - return PyErr_Error("csp_ping()", res); - } - - return Py_BuildValue("i", res); -} - -static PyObject* pycsp_reboot(PyObject *self, PyObject *args) { - uint8_t node; - if (!PyArg_ParseTuple(args, "b", &node)) { - return NULL; // TypeError is thrown - } - - csp_reboot(node); - Py_RETURN_NONE; -} - -static PyObject* pycsp_shutdown(PyObject *self, PyObject *args) { - uint8_t node; - if (!PyArg_ParseTuple(args, "b", &node)) { - return NULL; // TypeError is thrown - } - - csp_shutdown(node); - Py_RETURN_NONE; -} - -static PyObject* pycsp_rdp_set_opt(PyObject *self, PyObject *args) { - unsigned int window_size; - unsigned int conn_timeout_ms; - unsigned int packet_timeout_ms; - unsigned int delayed_acks; - unsigned int ack_timeout; - unsigned int ack_delay_count; - if (!PyArg_ParseTuple(args, "IIIIII", &window_size, &conn_timeout_ms, - &packet_timeout_ms, &delayed_acks, - &ack_timeout, &ack_delay_count)) { - return NULL; // TypeError is thrown - } -#if (CSP_USE_RDP) - csp_rdp_set_opt(window_size, conn_timeout_ms, packet_timeout_ms, - delayed_acks, ack_timeout, ack_delay_count); -#endif - Py_RETURN_NONE; -} - -static PyObject* pycsp_rdp_get_opt(PyObject *self, PyObject *args) { - - unsigned int window_size = 0; - unsigned int conn_timeout_ms = 0; - unsigned int packet_timeout_ms = 0; - unsigned int delayed_acks = 0; - unsigned int ack_timeout = 0; - unsigned int ack_delay_count = 0; -#if (CSP_USE_RDP) - csp_rdp_get_opt(&window_size, - &conn_timeout_ms, - &packet_timeout_ms, - &delayed_acks, - &ack_timeout, - &ack_delay_count); -#endif - return Py_BuildValue("IIIIII", - window_size, - conn_timeout_ms, - packet_timeout_ms, - delayed_acks, - ack_timeout, - ack_delay_count); -} - -static PyObject* pycsp_xtea_set_key(PyObject *self, PyObject *args) { - char* key; - uint32_t keylen; - if (!PyArg_ParseTuple(args, "si", &key, &keylen)) { - return NULL; // TypeError is thrown - } - - int res = csp_xtea_set_key(key, keylen); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_xtea_set_key()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_rtable_set(PyObject *self, PyObject *args) { - uint8_t node; - uint8_t mask; - char* interface_name; - uint8_t via = CSP_NO_VIA_ADDRESS; - if (!PyArg_ParseTuple(args, "bbs|b", &node, &mask, &interface_name, &via)) { - return NULL; // TypeError is thrown - } - - int res = csp_rtable_set(node, mask, csp_iflist_get_by_name(interface_name), via); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_rtable_set()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_rtable_clear(PyObject *self, PyObject *args) { - csp_rtable_clear(); - Py_RETURN_NONE; -} - -static PyObject* pycsp_rtable_check(PyObject *self, PyObject *args) { - char* buffer; - if (!PyArg_ParseTuple(args, "s", &buffer)) { - return NULL; // TypeError is thrown - } - - int res = csp_rtable_check(buffer); - if (res <= 0) { - return PyErr_Error("csp_rtable_check()", res); - } - return Py_BuildValue("i", res); -} - -static PyObject* pycsp_rtable_load(PyObject *self, PyObject *args) { - char* buffer; - if (!PyArg_ParseTuple(args, "s", &buffer)) { - return NULL; // TypeError is thrown - } - - int res = csp_rtable_load(buffer); - if (res <= 0) { - return PyErr_Error("csp_rtable_load()", res); - } - return Py_BuildValue("i", res); -} - -static PyObject* pycsp_buffer_get(PyObject *self, PyObject *args) { - size_t size; - if (!PyArg_ParseTuple(args, "n", &size)) { - return NULL; // TypeError is thrown - } - - void* packet = csp_buffer_get(size); - if (packet == NULL) { - return PyErr_Error("csp_buffer_get() - no free buffers or data overrun", CSP_ERR_NOMEM); - } - - return PyCapsule_New(packet, PACKET_CAPSULE, pycsp_free_csp_buffer); -} - -static PyObject* pycsp_buffer_free(PyObject *self, PyObject *args) { - PyObject* packet_capsule; - if (!PyArg_ParseTuple(args, "O", &packet_capsule)) { - return NULL; // TypeError is thrown - } - - csp_packet_t * packet = get_obj_as_packet(packet_capsule, true); - if (packet) { - csp_buffer_free(packet); - } - PyCapsule_SetPointer(packet_capsule, &CSP_POINTER_HAS_BEEN_FREED); - Py_RETURN_NONE; -} - -static PyObject* pycsp_buffer_remaining(PyObject *self, PyObject *args) { - return Py_BuildValue("i", csp_buffer_remaining()); -} - -static PyObject* pycsp_cmp_ident(PyObject *self, PyObject *args) { - uint8_t node; - uint32_t timeout = 1000; - if (!PyArg_ParseTuple(args, "b|i", &node, &timeout)) { - return NULL; // TypeError is thrown - } - - struct csp_cmp_message msg; - memset(&msg, 0, sizeof(msg)); - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_cmp_ident(node, timeout, &msg); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_cmp_ident()", res); - } - return Py_BuildValue("isssss", - res, - msg.ident.hostname, - msg.ident.model, - msg.ident.revision, - msg.ident.date, - msg.ident.time); -} - -static PyObject* pycsp_cmp_route_set(PyObject *self, PyObject *args) { - uint8_t node; - uint32_t timeout = 1000; - uint8_t addr; - uint8_t via; - char* ifstr; - if (!PyArg_ParseTuple(args, "bibbs", &node, &timeout, &addr, &via, &ifstr)) { - return NULL; // TypeError is thrown - } - - struct csp_cmp_message msg; - memset(&msg, 0, sizeof(msg)); - msg.route_set.dest_node = addr; - msg.route_set.next_hop_via = via; - strncpy(msg.route_set.interface, ifstr, sizeof(msg.route_set.interface) - 1); - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_cmp_route_set(node, timeout, &msg); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_cmp_route_set()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_cmp_peek(PyObject *self, PyObject *args) { - uint8_t node; - uint32_t timeout; - uint32_t addr; - uint8_t len; - Py_buffer outbuf; - if (!PyArg_ParseTuple(args, "biIbw*", &node, &timeout, &addr, &len, &outbuf)) { - Py_RETURN_NONE; - } - - if ((len > CSP_CMP_PEEK_MAX_LEN) || (len > outbuf.len)) { - return PyErr_Error("csp_cmp_peek() - exceeding max size", CSP_ERR_INVAL); - } - - struct csp_cmp_message msg; - memset(&msg, 0, sizeof(msg)); - msg.peek.addr = csp_hton32(addr); - msg.peek.len = len; - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_cmp_peek(node, timeout, &msg); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_cmp_peek()", res); - } - memcpy(outbuf.buf, msg.peek.data, len); - outbuf.len = len; - - Py_RETURN_NONE; -} - -static PyObject* pycsp_cmp_poke(PyObject *self, PyObject *args) { - uint8_t node; - uint32_t timeout; - uint8_t len; - uint32_t addr; - Py_buffer inbuf; - - if (!PyArg_ParseTuple(args, "biIbw*", &node, &timeout, &addr, &len, &inbuf)) { - Py_RETURN_NONE; - } - - if (len > CSP_CMP_POKE_MAX_LEN) { - return PyErr_Error("csp_cmp_poke() - exceeding max size", CSP_ERR_INVAL); - } - struct csp_cmp_message msg; - msg.poke.addr = csp_hton32(addr); - msg.poke.len = len; - memcpy(msg.poke.data, inbuf.buf, len); - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_cmp_poke(node, timeout, &msg); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_cmp_poke()", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_cmp_clock_set(PyObject *self, PyObject *args) { - uint8_t node; - uint32_t sec; - uint32_t nsec; - uint32_t timeout = 1000; - if (!PyArg_ParseTuple(args, "bII|I", &node, &sec, &nsec, &timeout)) { - Py_RETURN_NONE; - } - - if (sec == 0) { - return PyErr_Error("csp_cmp_clock(set) - seconds are 0", CSP_ERR_INVAL); - } - - struct csp_cmp_message msg; - memset(&msg, 0, sizeof(msg)); - msg.clock.tv_sec = csp_hton32(sec); - msg.clock.tv_nsec = csp_hton32(nsec); - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_cmp_clock(node, timeout, &msg); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_cmp_clock(set)", res); - } - - Py_RETURN_NONE; -} - -static PyObject* pycsp_cmp_clock_get(PyObject *self, PyObject *args) { - uint8_t node; - uint32_t timeout = 1000; - if (!PyArg_ParseTuple(args, "b|I", &node, &timeout)) { - Py_RETURN_NONE; - } - - struct csp_cmp_message msg; - memset(&msg, 0, sizeof(msg)); - - int res; - Py_BEGIN_ALLOW_THREADS; - res = csp_cmp_clock(node, timeout, &msg); - Py_END_ALLOW_THREADS; - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_cmp_clock(get)", res); - } - - return Py_BuildValue("II", - csp_ntoh32(msg.clock.tv_sec), - csp_ntoh32(msg.clock.tv_nsec)); -} - -static PyObject* pycsp_zmqhub_init(PyObject *self, PyObject *args) { - char addr; - char* host; - if (!PyArg_ParseTuple(args, "bs", &addr, &host)) { - return NULL; // TypeError is thrown - } - - int res = csp_zmqhub_init(addr, host, 0, NULL); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_zmqhub_init()", res); - } - - Py_RETURN_NONE; -} - -// static PyObject* pycsp_can_socketcan_init(PyObject *self, PyObject *args) { -// char* ifc; -// int bitrate = 1000000; -// int promisc = 0; -// if (!PyArg_ParseTuple(args, "s|ii", &ifc, &bitrate, &promisc)) { -// return NULL; -// } -// -// int res = csp_can_socketcan_open_and_add_interface(ifc, CSP_IF_CAN_DEFAULT_NAME, bitrate, promisc, NULL); -// if (res != CSP_ERR_NONE) { -// return PyErr_Error("csp_can_socketcan_open_and_add_interface()", res); -// } -// -// Py_RETURN_NONE; -// } - -static PyObject* pycsp_kiss_init(PyObject *self, PyObject *args) { - char* device; - uint32_t baudrate = 500000; - uint32_t mtu = 512; - const char* if_name = CSP_IF_KISS_DEFAULT_NAME; - if (!PyArg_ParseTuple(args, "s|IIs", &device, &baudrate, &mtu, &if_name)) { - return NULL; // TypeError is thrown - } - - csp_usart_conf_t conf = {.device = device, .baudrate = baudrate}; - int res = csp_usart_open_and_add_kiss_interface(&conf, if_name, NULL); - if (res != CSP_ERR_NONE) { - return PyErr_Error("csp_usart_open_and_add_kiss_interface()", res); - } - - Py_RETURN_NONE; -} - -/* FIFO INTERFACE */ -pthread_t rx_thread; -int rx_channel, tx_channel; -#define BUF_SIZE 250 - -int csp_fifo_tx(const csp_route_t * ifroute, csp_packet_t *packet); - -csp_iface_t csp_if_fifo = { - .name = "fifo", - .nexthop = csp_fifo_tx, - .mtu = BUF_SIZE, -}; - -int csp_fifo_tx(const csp_route_t * ifroute, csp_packet_t *packet) { - /* Write packet to fifo */ - if (write(tx_channel, &packet->length, packet->length + sizeof(uint32_t) + sizeof(uint16_t)) < 0) - printf("Failed to write frame\r\n"); - fsync(tx_channel); - csp_buffer_free(packet); - - return CSP_ERR_NONE; -} - -void * fifo_rx(void * parameters) { - csp_packet_t *buf = csp_buffer_get(BUF_SIZE); - /* Wait for packet on fifo */ - while (read(rx_channel, &buf->length, BUF_SIZE) > 0) { - csp_qfifo_write(buf, &csp_if_fifo, NULL); - buf = csp_buffer_get(BUF_SIZE); - } - - return NULL; -} -/** FIFO INTERFACE ENDS **/ - -static PyObject* csp_init_fifo_iface(PyObject *self, PyObject *args) { - char *tx_channel_name, *rx_channel_name; - tx_channel_name = "/datavolume1/ground_to_sat"; - rx_channel_name = "/datavolume1/sat_to_ground"; - tx_channel = open(tx_channel_name, O_RDWR); - if (tx_channel < 0) { - printf("Failed to open TX channel\r\n"); - return NULL; - } - - rx_channel = open(rx_channel_name, O_RDWR); - if (rx_channel < 0) { - printf("Failed to open RX channel\r\n"); - return NULL; - } - pthread_create(&rx_thread, NULL, fifo_rx, NULL); - csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_fifo, CSP_NODE_MAC); - Py_RETURN_NONE; -} - - -static PyObject* pycsp_packet_set_data(PyObject *self, PyObject *args) { - PyObject* packet_capsule; - Py_buffer data; - if (!PyArg_ParseTuple(args, "Ow*", &packet_capsule, &data)) { - return NULL; // TypeError is thrown - } - - csp_packet_t * packet = get_obj_as_packet(packet_capsule, false); - if (packet == NULL) { - return NULL; // TypeError is thrown - } - if (data.len > (int)csp_buffer_data_size()) { - return PyErr_Error("packet_set_data() - exceeding data size", CSP_ERR_INVAL); - } - - memcpy(packet->data, data.buf, data.len); - packet->length = data.len; - - Py_RETURN_NONE; -} - -static PyObject* pycsp_packet_get_data(PyObject *self, PyObject *packet_capsule) { - csp_packet_t * packet = get_obj_as_packet(packet_capsule, false); - if (packet == NULL) { - return NULL; // TypeError is thrown - } - return Py_BuildValue("y#", packet->data, packet->length); -} - -static PyObject* pycsp_packet_get_length(PyObject *self, PyObject *packet_capsule) { - csp_packet_t * packet = get_obj_as_packet(packet_capsule, false); - if (packet == NULL) { - return NULL; // TypeError is thrown - } - return Py_BuildValue("H", packet->length); -} - -static PyObject* pycsp_print_connections(PyObject *self, PyObject *args) { -#if (CSP_DEBUG) - csp_conn_print_table(); -#endif - Py_RETURN_NONE; -} - -static PyObject* pycsp_print_routes(PyObject *self, PyObject *args) { -#if (CSP_DEBUG) - csp_rtable_print(); -#endif - Py_RETURN_NONE; -} - -static PyObject* pycsp_get_buffer_stats(PyObject *self, PyObject *args) { - return Py_BuildValue("iii", (int)csp_buffer_remaining(), (int)csp_buffer_size(), (int)csp_buffer_data_size()); -} - -static PyMethodDef methods[] = { - - /* csp/csp.h */ - {"service_handler", pycsp_service_handler, METH_VARARGS, ""}, - {"init", pycsp_init, METH_VARARGS, ""}, - {"get_hostname", pycsp_get_hostname, METH_NOARGS, ""}, - {"get_model", pycsp_get_model, METH_NOARGS, ""}, - {"get_revision", pycsp_get_revision, METH_NOARGS, ""}, - {"socket", pycsp_socket, METH_VARARGS, ""}, - {"accept", pycsp_accept, METH_VARARGS, ""}, - {"read", pycsp_read, METH_VARARGS, ""}, - {"send", pycsp_send, METH_VARARGS, ""}, - {"transaction", pycsp_transaction, METH_VARARGS, ""}, - {"sendto_reply", pycsp_sendto_reply, METH_VARARGS, ""}, - {"sendto", pycsp_sendto, METH_VARARGS, ""}, - {"connect", pycsp_connect, METH_VARARGS, ""}, - {"close", pycsp_close, METH_O, ""}, - {"conn_dport", pycsp_conn_dport, METH_O, ""}, - {"conn_sport", pycsp_conn_sport, METH_O, ""}, - {"conn_dst", pycsp_conn_dst, METH_O, ""}, - {"conn_src", pycsp_conn_src, METH_O, ""}, - {"listen", pycsp_listen, METH_VARARGS, ""}, - {"bind", pycsp_bind, METH_VARARGS, ""}, - {"route_start_task", pycsp_route_start_task, METH_VARARGS, ""}, - {"ping", pycsp_ping, METH_VARARGS, ""}, - {"reboot", pycsp_reboot, METH_VARARGS, ""}, - {"shutdown", pycsp_shutdown, METH_VARARGS, ""}, - {"rdp_set_opt", pycsp_rdp_set_opt, METH_VARARGS, ""}, - {"rdp_get_opt", pycsp_rdp_get_opt, METH_NOARGS, ""}, - {"xtea_set_key", pycsp_xtea_set_key, METH_VARARGS, ""}, - - /* csp/csp_rtable.h */ - {"rtable_set", pycsp_rtable_set, METH_VARARGS, ""}, - {"rtable_clear", pycsp_rtable_clear, METH_NOARGS, ""}, - {"rtable_check", pycsp_rtable_check, METH_VARARGS, ""}, - {"rtable_load", pycsp_rtable_load, METH_VARARGS, ""}, - - /* csp/csp_buffer.h */ - {"buffer_free", pycsp_buffer_free, METH_VARARGS, ""}, - {"buffer_get", pycsp_buffer_get, METH_VARARGS, ""}, - {"buffer_remaining", pycsp_buffer_remaining, METH_NOARGS, ""}, - - /* csp/csp_cmp.h */ - {"cmp_ident", pycsp_cmp_ident, METH_VARARGS, ""}, - {"cmp_route_set", pycsp_cmp_route_set, METH_VARARGS, ""}, - {"cmp_peek", pycsp_cmp_peek, METH_VARARGS, ""}, - {"cmp_poke", pycsp_cmp_poke, METH_VARARGS, ""}, - {"cmp_clock_set", pycsp_cmp_clock_set, METH_VARARGS, ""}, - {"cmp_clock_get", pycsp_cmp_clock_get, METH_VARARGS, ""}, - - /* csp/interfaces/csp_if_zmqhub.h */ - {"zmqhub_init", pycsp_zmqhub_init, METH_VARARGS, ""}, - {"kiss_init", pycsp_kiss_init, METH_VARARGS, ""}, - {"fifo_init", csp_init_fifo_iface, METH_VARARGS, ""}, - - /* csp/drivers/can_socketcan.h */ - // {"can_socketcan_init", pycsp_can_socketcan_init, METH_VARARGS, ""}, - - /* helpers */ - {"packet_get_length", pycsp_packet_get_length, METH_O, ""}, - {"packet_get_data", pycsp_packet_get_data, METH_O, ""}, - {"packet_set_data", pycsp_packet_set_data, METH_VARARGS, ""}, - {"print_connections", pycsp_print_connections, METH_NOARGS, ""}, - {"print_routes", pycsp_print_routes, METH_NOARGS, ""}, - {"get_buffer_stats", pycsp_get_buffer_stats, METH_NOARGS, ""}, - - /* sentinel */ - {NULL, NULL, 0, NULL} -}; - -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "libcsp_py3", - NULL, - -1, - methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PyInit_libcsp_py3(void) { - - PyObject * m = PyModule_Create(&moduledef); - - /* Exceptions */ - Error = PyErr_NewException((char*)"csp.Error", NULL, NULL); - Py_INCREF(Error); - - /* Add exception object to your module */ - PyModule_AddObject(m, "Error", Error); - - /* RESERVED PORTS */ - PyModule_AddIntConstant(m, "CSP_CMP", CSP_CMP); - PyModule_AddIntConstant(m, "CSP_PING", CSP_PING); - PyModule_AddIntConstant(m, "CSP_PS", CSP_PS); - PyModule_AddIntConstant(m, "CSP_MEMFREE", CSP_MEMFREE); - PyModule_AddIntConstant(m, "CSP_REBOOT", CSP_REBOOT); - PyModule_AddIntConstant(m, "CSP_BUF_FREE", CSP_BUF_FREE); - PyModule_AddIntConstant(m, "CSP_UPTIME", CSP_UPTIME); - PyModule_AddIntConstant(m, "CSP_ANY", CSP_ANY); - - /* PRIORITIES */ - PyModule_AddIntConstant(m, "CSP_PRIO_CRITICAL", CSP_PRIO_CRITICAL); - PyModule_AddIntConstant(m, "CSP_PRIO_HIGH", CSP_PRIO_HIGH); - PyModule_AddIntConstant(m, "CSP_PRIO_NORM", CSP_PRIO_NORM); - PyModule_AddIntConstant(m, "CSP_PRIO_LOW", CSP_PRIO_LOW); - - /* FLAGS */ - PyModule_AddIntConstant(m, "CSP_FFRAG", CSP_FFRAG); - PyModule_AddIntConstant(m, "CSP_FHMAC", CSP_FHMAC); - PyModule_AddIntConstant(m, "CSP_FXTEA", CSP_FXTEA); - PyModule_AddIntConstant(m, "CSP_FRDP", CSP_FRDP); - PyModule_AddIntConstant(m, "CSP_FCRC32", CSP_FCRC32); - - /* SOCKET OPTIONS */ - PyModule_AddIntConstant(m, "CSP_SO_NONE", CSP_SO_NONE); - PyModule_AddIntConstant(m, "CSP_SO_RDPREQ", CSP_SO_RDPREQ); - PyModule_AddIntConstant(m, "CSP_SO_RDPPROHIB", CSP_SO_RDPPROHIB); - PyModule_AddIntConstant(m, "CSP_SO_HMACREQ", CSP_SO_HMACREQ); - PyModule_AddIntConstant(m, "CSP_SO_HMACPROHIB", CSP_SO_HMACPROHIB); - PyModule_AddIntConstant(m, "CSP_SO_XTEAREQ", CSP_SO_XTEAREQ); - PyModule_AddIntConstant(m, "CSP_SO_XTEAPROHIB", CSP_SO_XTEAPROHIB); - PyModule_AddIntConstant(m, "CSP_SO_CRC32REQ", CSP_SO_CRC32REQ); - PyModule_AddIntConstant(m, "CSP_SO_CRC32PROHIB", CSP_SO_CRC32PROHIB); - PyModule_AddIntConstant(m, "CSP_SO_CONN_LESS", CSP_SO_CONN_LESS); - - /* CONNECT OPTIONS */ - PyModule_AddIntConstant(m, "CSP_O_NONE", CSP_O_NONE); - PyModule_AddIntConstant(m, "CSP_O_RDP", CSP_O_RDP); - PyModule_AddIntConstant(m, "CSP_O_NORDP", CSP_O_NORDP); - PyModule_AddIntConstant(m, "CSP_O_HMAC", CSP_O_HMAC); - PyModule_AddIntConstant(m, "CSP_O_NOHMAC", CSP_O_NOHMAC); - PyModule_AddIntConstant(m, "CSP_O_XTEA", CSP_O_XTEA); - PyModule_AddIntConstant(m, "CSP_O_NOXTEA", CSP_O_NOXTEA); - PyModule_AddIntConstant(m, "CSP_O_CRC32", CSP_O_CRC32); - PyModule_AddIntConstant(m, "CSP_O_NOCRC32", CSP_O_NOCRC32); - - /* csp/csp_error.h */ - PyModule_AddIntConstant(m, "CSP_ERR_NONE", CSP_ERR_NONE); - PyModule_AddIntConstant(m, "CSP_ERR_NOMEM", CSP_ERR_NOMEM); - PyModule_AddIntConstant(m, "CSP_ERR_INVAL", CSP_ERR_INVAL); - PyModule_AddIntConstant(m, "CSP_ERR_TIMEDOUT", CSP_ERR_TIMEDOUT); - PyModule_AddIntConstant(m, "CSP_ERR_USED", CSP_ERR_USED); - PyModule_AddIntConstant(m, "CSP_ERR_NOTSUP", CSP_ERR_NOTSUP); - PyModule_AddIntConstant(m, "CSP_ERR_BUSY", CSP_ERR_BUSY); - PyModule_AddIntConstant(m, "CSP_ERR_ALREADY", CSP_ERR_ALREADY); - PyModule_AddIntConstant(m, "CSP_ERR_RESET", CSP_ERR_RESET); - PyModule_AddIntConstant(m, "CSP_ERR_NOBUFS", CSP_ERR_NOBUFS); - PyModule_AddIntConstant(m, "CSP_ERR_TX", CSP_ERR_TX); - PyModule_AddIntConstant(m, "CSP_ERR_DRIVER", CSP_ERR_DRIVER); - PyModule_AddIntConstant(m, "CSP_ERR_AGAIN", CSP_ERR_AGAIN); - PyModule_AddIntConstant(m, "CSP_ERR_HMAC", CSP_ERR_HMAC); - PyModule_AddIntConstant(m, "CSP_ERR_XTEA", CSP_ERR_XTEA); - PyModule_AddIntConstant(m, "CSP_ERR_CRC32", CSP_ERR_CRC32); - PyModule_AddIntConstant(m, "CSP_ERR_SFP", CSP_ERR_SFP); - - /* misc */ - PyModule_AddIntConstant(m, "CSP_NODE_MAC", CSP_NODE_MAC); - PyModule_AddIntConstant(m, "CSP_NO_VIA_ADDRESS", CSP_NO_VIA_ADDRESS); - PyModule_AddIntConstant(m, "CSP_MAX_TIMEOUT", CSP_MAX_TIMEOUT); - - return m; -} diff --git a/Program/libcsp/src/crypto/csp_hmac.c b/Program/libcsp/src/crypto/csp_hmac.c deleted file mode 100755 index 8d29880..0000000 --- a/Program/libcsp/src/crypto/csp_hmac.c +++ /dev/null @@ -1,194 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* Hash-based Message Authentication Code - based on code from libtom.org */ - -#include - -#include - -#include -#include - -#define HMAC_KEY_LENGTH 16 - -/* HMAC key */ -static uint8_t csp_hmac_key[HMAC_KEY_LENGTH]; - -/* HMAC state structure */ -typedef struct { - csp_sha1_state_t md; - uint8_t key[CSP_SHA1_BLOCKSIZE]; -} hmac_state; - -static int csp_hmac_init(hmac_state * hmac, const uint8_t * key, uint32_t keylen) { - uint32_t i; - uint8_t buf[CSP_SHA1_BLOCKSIZE]; - - /* NULL pointer and key check */ - if (!hmac || !key || keylen < 1) - return CSP_ERR_INVAL; - - /* Make sure we have a large enough key */ - if(keylen > CSP_SHA1_BLOCKSIZE) { - csp_sha1_memory(key, keylen, hmac->key); - if(CSP_SHA1_DIGESTSIZE < CSP_SHA1_BLOCKSIZE) - memset((hmac->key) + CSP_SHA1_DIGESTSIZE, 0, (CSP_SHA1_BLOCKSIZE - CSP_SHA1_DIGESTSIZE)); - } else { - memcpy(hmac->key, key, keylen); - if(keylen < CSP_SHA1_BLOCKSIZE) - memset((hmac->key) + keylen, 0, (CSP_SHA1_BLOCKSIZE - keylen)); - } - - /* Create the initial vector */ - for(i = 0; i < CSP_SHA1_BLOCKSIZE; i++) { - buf[i] = hmac->key[i] ^ 0x36; - } - - /* Prepend to the hash data */ - csp_sha1_init(&hmac->md); - csp_sha1_process(&hmac->md, buf, CSP_SHA1_BLOCKSIZE); - - return CSP_ERR_NONE; -} - -static int csp_hmac_process(hmac_state * hmac, const uint8_t * in, uint32_t inlen) { - - /* NULL pointer check */ - if (!hmac || !in) - return CSP_ERR_INVAL; - - /* Process data */ - csp_sha1_process(&hmac->md, in, inlen); - - return CSP_ERR_NONE; -} - -static int csp_hmac_done(hmac_state * hmac, uint8_t * out) { - - if (!hmac || !out) - return CSP_ERR_INVAL; - - /* Get the hash of the first HMAC vector plus the data */ - uint8_t isha[CSP_SHA1_DIGESTSIZE]; - csp_sha1_done(&hmac->md, isha); - - /* Create the second HMAC vector vector */ - uint8_t buf[CSP_SHA1_BLOCKSIZE]; - for(unsigned int i = 0; i < sizeof(buf); i++) { - buf[i] = hmac->key[i] ^ 0x5C; - } - - /* Now calculate the outer hash */ - csp_sha1_init(&hmac->md); - csp_sha1_process(&hmac->md, buf, sizeof(buf)); - csp_sha1_process(&hmac->md, isha, sizeof(isha)); - csp_sha1_done(&hmac->md, buf); - - /* Copy to output */ - memcpy(out, buf, CSP_SHA1_DIGESTSIZE); - - return CSP_ERR_NONE; -} - -int csp_hmac_memory(const void * key, uint32_t keylen, const void * data, uint32_t datalen, uint8_t * hmac) { - hmac_state state; - - /* NULL pointer check */ - if (!key || !data || !hmac) - return CSP_ERR_INVAL; - - /* Init HMAC state */ - if (csp_hmac_init(&state, key, keylen) != 0) - return CSP_ERR_INVAL; - - /* Process data */ - if (csp_hmac_process(&state, data, datalen) != 0) - return CSP_ERR_INVAL; - - /* Output HMAC */ - if (csp_hmac_done(&state, hmac) != 0) - return CSP_ERR_INVAL; - - return CSP_ERR_NONE; -} - -int csp_hmac_set_key(const void * key, uint32_t keylen) { - - /* Use SHA1 as KDF */ - uint8_t hash[CSP_SHA1_DIGESTSIZE]; - csp_sha1_memory(key, keylen, hash); - - /* Copy key */ - memcpy(csp_hmac_key, hash, sizeof(csp_hmac_key)); - - return CSP_ERR_NONE; - -} - -int csp_hmac_append(csp_packet_t * packet, bool include_header) { - - if ((packet->length + (unsigned int)CSP_HMAC_LENGTH) > csp_buffer_data_size()) { - return CSP_ERR_NOMEM; - } - - /* Calculate HMAC */ - uint8_t hmac[CSP_SHA1_DIGESTSIZE]; - if (include_header) { - csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), &packet->id, packet->length + sizeof(packet->id), hmac); - } else { - csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), packet->data, packet->length, hmac); - } - - /* Truncate hash and copy to packet */ - memcpy(&packet->data[packet->length], hmac, CSP_HMAC_LENGTH); - packet->length += CSP_HMAC_LENGTH; - - return CSP_ERR_NONE; - -} - -int csp_hmac_verify(csp_packet_t * packet, bool include_header) { - - if (packet->length < (unsigned int)CSP_HMAC_LENGTH) { - return CSP_ERR_HMAC; - } - - uint8_t hmac[CSP_SHA1_DIGESTSIZE]; - - /* Calculate HMAC */ - if (include_header) { - csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), &packet->id, packet->length + sizeof(packet->id) - CSP_HMAC_LENGTH, hmac); - } else { - csp_hmac_memory(csp_hmac_key, sizeof(csp_hmac_key), packet->data, packet->length - CSP_HMAC_LENGTH, hmac); - } - - /* Compare calculated HMAC with packet header */ - if (memcmp(&packet->data[packet->length] - CSP_HMAC_LENGTH, hmac, CSP_HMAC_LENGTH) != 0) { - /* HMAC failed */ - return CSP_ERR_HMAC; - } - - /* Strip HMAC */ - packet->length -= CSP_HMAC_LENGTH; - return CSP_ERR_NONE; - -} - diff --git a/Program/libcsp/src/crypto/csp_sha1.c b/Program/libcsp/src/crypto/csp_sha1.c deleted file mode 100755 index 55c2516..0000000 --- a/Program/libcsp/src/crypto/csp_sha1.c +++ /dev/null @@ -1,211 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* Code originally from Python's SHA1 Module, who based it on libtom.org */ - -#include - -#include - -/* Rotate left macro */ -#define ROL(x,y) (((x) << (y)) | ((x) >> (32-y))) - -/* Endian Neutral macros that work on all platforms */ -#define STORE32H(x, y) do { (y)[0] = (uint8_t)(((x) >> 24) & 0xff); \ - (y)[1] = (uint8_t)(((x) >> 16) & 0xff); \ - (y)[2] = (uint8_t)(((x) >> 8) & 0xff); \ - (y)[3] = (uint8_t)(((x) >> 0) & 0xff); } while (0) - -#define LOAD32H(x, y) do { (x) = ((uint32_t)((y)[0] & 0xff) << 24) | \ - ((uint32_t)((y)[1] & 0xff) << 16) | \ - ((uint32_t)((y)[2] & 0xff) << 8) | \ - ((uint32_t)((y)[3] & 0xff) << 0); } while (0) - -#define STORE64H(x, y) do { (y)[0] = (uint8_t)(((x) >> 56) & 0xff); \ - (y)[1] = (uint8_t)(((x) >> 48) & 0xff); \ - (y)[2] = (uint8_t)(((x) >> 40) & 0xff); \ - (y)[3] = (uint8_t)(((x) >> 32) & 0xff); \ - (y)[4] = (uint8_t)(((x) >> 24) & 0xff); \ - (y)[5] = (uint8_t)(((x) >> 16) & 0xff); \ - (y)[6] = (uint8_t)(((x) >> 8) & 0xff); \ - (y)[7] = (uint8_t)(((x) >> 0) & 0xff); } while (0) - -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) - -/* SHA1 macros */ -#define F0(x,y,z) (z ^ (x & (y ^ z))) -#define F1(x,y,z) (x ^ y ^ z) -#define F2(x,y,z) ((x & y) | (z & (x | y))) -#define F3(x,y,z) (x ^ y ^ z) - -#define FF_0(a, b, c, d, e, i) do {e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);} while (0) -#define FF_1(a, b, c, d, e, i) do {e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);} while (0) -#define FF_2(a, b, c, d, e, i) do {e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);} while (0) -#define FF_3(a, b, c, d, e, i) do {e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);} while (0) - -static void csp_sha1_compress(csp_sha1_state_t * sha1, const uint8_t * buf) { - - uint32_t a, b, c, d, e, W[80], i; - - /* Copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) - LOAD32H(W[i], buf + (4*i)); - - /* Copy state */ - a = sha1->state[0]; - b = sha1->state[1]; - c = sha1->state[2]; - d = sha1->state[3]; - e = sha1->state[4]; - - /* Expand it */ - for (i = 16; i < 80; i++) - W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); - - /* Compress */ - i = 0; - - /* Round one */ - for (; i < 20;) { - FF_0(a, b, c, d, e, i++); - FF_0(e, a, b, c, d, i++); - FF_0(d, e, a, b, c, i++); - FF_0(c, d, e, a, b, i++); - FF_0(b, c, d, e, a, i++); - } - - /* Round two */ - for (; i < 40;) { - FF_1(a, b, c, d, e, i++); - FF_1(e, a, b, c, d, i++); - FF_1(d, e, a, b, c, i++); - FF_1(c, d, e, a, b, i++); - FF_1(b, c, d, e, a, i++); - } - - /* Round three */ - for (; i < 60;) { - FF_2(a, b, c, d, e, i++); - FF_2(e, a, b, c, d, i++); - FF_2(d, e, a, b, c, i++); - FF_2(c, d, e, a, b, i++); - FF_2(b, c, d, e, a, i++); - } - - /* Round four */ - for (; i < 80;) { - FF_3(a, b, c, d, e, i++); - FF_3(e, a, b, c, d, i++); - FF_3(d, e, a, b, c, i++); - FF_3(c, d, e, a, b, i++); - FF_3(b, c, d, e, a, i++); - } - - /* Store */ - sha1->state[0] += a; - sha1->state[1] += b; - sha1->state[2] += c; - sha1->state[3] += d; - sha1->state[4] += e; - -} - -void csp_sha1_init(csp_sha1_state_t * sha1) { - - sha1->state[0] = 0x67452301UL; - sha1->state[1] = 0xefcdab89UL; - sha1->state[2] = 0x98badcfeUL; - sha1->state[3] = 0x10325476UL; - sha1->state[4] = 0xc3d2e1f0UL; - sha1->curlen = 0; - sha1->length = 0; - -} - -void csp_sha1_process(csp_sha1_state_t * sha1, const void * data, uint32_t inlen) { - - const uint8_t * in = data; - uint32_t n; - while (inlen > 0) { - if (sha1->curlen == 0 && inlen >= CSP_SHA1_BLOCKSIZE) { - csp_sha1_compress(sha1, in); - sha1->length += (CSP_SHA1_BLOCKSIZE * 8); - in += CSP_SHA1_BLOCKSIZE; - inlen -= CSP_SHA1_BLOCKSIZE; - } else { - n = MIN(inlen, (CSP_SHA1_BLOCKSIZE - sha1->curlen)); - memcpy(sha1->buf + sha1->curlen, in, (size_t)n); - sha1->curlen += n; - in += n; - inlen -= n; - if (sha1->curlen == CSP_SHA1_BLOCKSIZE) { - csp_sha1_compress(sha1, sha1->buf); - sha1->length += (CSP_SHA1_BLOCKSIZE * 8); - sha1->curlen = 0; - } - } - } - -} - -void csp_sha1_done(csp_sha1_state_t * sha1, uint8_t * out) { - - uint32_t i; - - /* Increase the length of the message */ - sha1->length += sha1->curlen * 8; - - /* Append the '1' bit */ - sha1->buf[sha1->curlen++] = 0x80; - - /* If the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (sha1->curlen > 56) { - while (sha1->curlen < 64) - sha1->buf[sha1->curlen++] = 0; - csp_sha1_compress(sha1, sha1->buf); - sha1->curlen = 0; - } - - /* Pad up to 56 bytes of zeroes */ - while (sha1->curlen < 56) - sha1->buf[sha1->curlen++] = 0; - - /* Store length */ - STORE64H(sha1->length, sha1->buf + 56); - csp_sha1_compress(sha1, sha1->buf); - - /* Copy output */ - for (i = 0; i < 5; i++) - STORE32H(sha1->state[i], out + (4 * i)); - -} - -void csp_sha1_memory(const void * msg, uint32_t len, uint8_t * hash) { - - csp_sha1_state_t md; - csp_sha1_init(&md); - csp_sha1_process(&md, msg, len); - csp_sha1_done(&md, hash); - -} - diff --git a/Program/libcsp/src/crypto/csp_xtea.c b/Program/libcsp/src/crypto/csp_xtea.c deleted file mode 100755 index cd03941..0000000 --- a/Program/libcsp/src/crypto/csp_xtea.c +++ /dev/null @@ -1,181 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* Simple implementation of XTEA in CTR mode */ - -#include - -#include -#include - -#include -#include -#include - -#define XTEA_BLOCKSIZE 8 -#define XTEA_ROUNDS 32 -#define XTEA_KEY_LENGTH 16 - -/* XTEA key */ -static uint32_t csp_xtea_key[XTEA_KEY_LENGTH/sizeof(uint32_t)] __attribute__ ((aligned(sizeof(uint32_t)))); - -#define STORE32L(x, y) do { (y)[3] = (uint8_t)(((x) >> 24) & 0xff); \ - (y)[2] = (uint8_t)(((x) >> 16) & 0xff); \ - (y)[1] = (uint8_t)(((x) >> 8) & 0xff); \ - (y)[0] = (uint8_t)(((x) >> 0) & 0xff); } while (0) - -#define LOAD32L(x, y) do { (x) = ((uint32_t)((y)[3] & 0xff) << 24) | \ - ((uint32_t)((y)[2] & 0xff) << 16) | \ - ((uint32_t)((y)[1] & 0xff) << 8) | \ - ((uint32_t)((y)[0] & 0xff) << 0); } while (0) - -/* This function takes 64 bits of data in block and the 128 bits key in key */ -static inline void csp_xtea_encrypt_block(uint8_t *block, uint8_t const *key) { - - uint32_t i, v0, v1, delta = 0x9E3779B9, sum = 0, k[4]; - - LOAD32L(k[0], &key[0]); - LOAD32L(k[1], &key[4]); - LOAD32L(k[2], &key[8]); - LOAD32L(k[3], &key[12]); - - LOAD32L(v0, &block[0]); - LOAD32L(v1, &block[4]); - - for (i = 0; i < XTEA_ROUNDS; i++) { - v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); - sum += delta; - v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]); - } - - STORE32L(v0, &block[0]); - STORE32L(v1, &block[4]); - -} - -static inline void csp_xtea_xor_byte(uint8_t * dst, uint8_t * src, uint32_t len) { - - unsigned int i; - for (i = 0; i < len; i++) - dst[i] ^= src[i]; - -} - -int csp_xtea_set_key(const void * key, uint32_t keylen) { - - /* Use SHA1 as KDF */ - uint8_t hash[CSP_SHA1_DIGESTSIZE]; - csp_sha1_memory(key, keylen, hash); - - /* Copy key */ - memcpy(csp_xtea_key, hash, XTEA_KEY_LENGTH); - - return CSP_ERR_NONE; - -} - -int csp_xtea_encrypt(void * plain, const uint32_t len, uint32_t iv[2]) { - - unsigned int i; - uint32_t stream[2]; - - uint32_t blocks = (len + XTEA_BLOCKSIZE - 1)/ XTEA_BLOCKSIZE; - uint32_t remain; - - /* Initialize stream */ - stream[0] = csp_htobe32(iv[0]); - stream[1] = csp_htobe32(iv[1]); - - for (i = 0; i < blocks; i++) { - /* Create stream */ - csp_xtea_encrypt_block((uint8_t *)stream, (uint8_t *)csp_xtea_key); - - /* Calculate remaining bytes */ - remain = len - i * XTEA_BLOCKSIZE; - - /* XOR plain text with stream to generate cipher text */ - csp_xtea_xor_byte(&((uint8_t*)plain)[len - remain], (uint8_t *)stream, remain < XTEA_BLOCKSIZE ? remain : XTEA_BLOCKSIZE); - - /* Increment counter */ - stream[0] = csp_htobe32(iv[0]); - stream[1] = csp_htobe32(iv[1]++); - } - - return CSP_ERR_NONE; - -} - -int csp_xtea_encrypt_packet(csp_packet_t * packet) { - - /* Create nonce */ - const uint32_t nonce = (uint32_t)rand(); - const uint32_t nonce_n = csp_hton32(nonce); - - if ((packet->length + sizeof(nonce_n)) > csp_buffer_data_size()) { - return CSP_ERR_NOMEM; - } - - /* Create initialization vector */ - uint32_t iv[2] = {nonce, 1}; - - /* Encrypt data */ - if (csp_xtea_encrypt(packet->data, packet->length, iv) != CSP_ERR_NONE) { - return CSP_ERR_XTEA; - } - - memcpy(&packet->data[packet->length], &nonce_n, sizeof(nonce_n)); - packet->length += sizeof(nonce_n); - - return CSP_ERR_NONE; - -} - -int csp_xtea_decrypt(void * cipher, const uint32_t len, uint32_t iv[2]) { - - /* Since we use counter mode, we can reuse the encryption function */ - return csp_xtea_encrypt(cipher, len, iv); - -} - -int csp_xtea_decrypt_packet(csp_packet_t * packet) { - - /* Read nonce */ - uint32_t nonce; - - if (packet->length < sizeof(nonce)) { - return CSP_ERR_XTEA; - } - - memcpy(&nonce, &packet->data[packet->length - sizeof(nonce)], sizeof(nonce)); - nonce = csp_ntoh32(nonce); - - /* Create initialization vector */ - uint32_t iv[2] = {nonce, 1}; - - /* Decrypt data */ - if (csp_xtea_decrypt(packet->data, packet->length, iv) != CSP_ERR_NONE) { - return CSP_ERR_XTEA; - } - - packet->length -= sizeof(nonce); - - return CSP_ERR_NONE; - -} diff --git a/Program/libcsp/src/csp_bridge.c b/Program/libcsp/src/csp_bridge.c deleted file mode 100755 index 0801cfe..0000000 --- a/Program/libcsp/src/csp_bridge.c +++ /dev/null @@ -1,96 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include "csp_qfifo.h" -#include "csp_io.h" -#include "csp_promisc.h" - -typedef struct { - csp_iface_t* iface; -} bridge_interface_t; - -static bridge_interface_t bif_a; -static bridge_interface_t bif_b; - -static CSP_DEFINE_TASK(csp_bridge) { - - /* Here there be bridging */ - while (1) { - - /* Get next packet to route */ - csp_qfifo_t input; - if (csp_qfifo_read(&input) != CSP_ERR_NONE) { - continue; - } - - csp_packet_t * packet = input.packet; - - csp_log_packet("Input: Src %u, Dst %u, Dport %u, Sport %u, Pri %u, Flags 0x%02X, Size %"PRIu16, - packet->id.src, packet->id.dst, packet->id.dport, - packet->id.sport, packet->id.pri, packet->id.flags, packet->length); - - /* Here there be promiscuous mode */ -#if (CSP_USE_PROMISC) - csp_promisc_add(packet); -#endif - - /* Find the opposing interface */ - csp_route_t route; - if (input.iface == bif_a.iface) { - route.iface = bif_b.iface; - route.via = CSP_NO_VIA_ADDRESS; - } else { - route.iface = bif_a.iface; - route.via = CSP_NO_VIA_ADDRESS; - } - - /* Send to the interface directly, no hassle */ - if (csp_send_direct(packet->id, packet, &route, 0) != CSP_ERR_NONE) { - csp_log_warn("Router failed to send"); - csp_buffer_free(packet); - } - } - - return CSP_TASK_RETURN; - -} - -int csp_bridge_start(unsigned int task_stack_size, unsigned int task_priority, csp_iface_t * if_a, csp_iface_t * if_b) { - - /* Set static references to A/B side of bridge */ - bif_a.iface = if_a; - bif_b.iface = if_b; - - static csp_thread_handle_t handle; - int ret = csp_thread_create(csp_bridge, "BRIDGE", task_stack_size, NULL, task_priority, &handle); - - if (ret != 0) { - csp_log_error("Failed to start task"); - return CSP_ERR_NOMEM; - } - - return CSP_ERR_NONE; - -} diff --git a/Program/libcsp/src/csp_buffer.c b/Program/libcsp/src/csp_buffer.c deleted file mode 100755 index ebc9154..0000000 --- a/Program/libcsp/src/csp_buffer.c +++ /dev/null @@ -1,224 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include "csp_init.h" - -#ifndef CSP_BUFFER_ALIGN -#define CSP_BUFFER_ALIGN (sizeof(int *)) -#endif - -/** Internal buffer header */ -typedef struct csp_skbf_s { - unsigned int refcount; - void * skbf_addr; - char skbf_data[]; // -> csp_packet_t -} csp_skbf_t; - -// Queue of free CSP buffers -static csp_queue_handle_t csp_buffers; -// Chunk of memory allocated for CSP buffers -static char * csp_buffer_pool; - -// Ensure the csp_packet is correctly aligned (as it is not packed) -CSP_STATIC_ASSERT(CSP_HEADER_LENGTH == sizeof(csp_id_t), csp_header_length); -CSP_STATIC_ASSERT(sizeof(csp_packet_t) == 16, csp_packet); -CSP_STATIC_ASSERT(offsetof(csp_packet_t, length) == 10, length_field_misaligned); -CSP_STATIC_ASSERT(offsetof(csp_packet_t, id) == 12, csp_id_field_misaligned); -CSP_STATIC_ASSERT(offsetof(csp_packet_t, data) == 16, data_field_misaligned); - -int csp_buffer_init(void) { - - // calculate total size and ensure correct alignment (int *) for buffers - const unsigned int skbfsize = CSP_BUFFER_ALIGN * ((sizeof(csp_skbf_t) + csp_buffer_size() + (CSP_BUFFER_ALIGN - 1)) / CSP_BUFFER_ALIGN); - - csp_buffer_pool = csp_malloc(csp_conf.buffers * skbfsize); - if (csp_buffer_pool == NULL) - goto fail_malloc; - - csp_buffers = csp_queue_create(csp_conf.buffers, sizeof(void *)); - if (!csp_buffers) - goto fail_queue; - - for (unsigned int i = 0; i < csp_conf.buffers; i++) { - csp_skbf_t * buf = (void *) &csp_buffer_pool[i * skbfsize]; - buf->skbf_addr = buf; - csp_queue_enqueue(csp_buffers, &buf, 0); - } - - return CSP_ERR_NONE; - -fail_queue: - csp_buffer_free_resources(); -fail_malloc: - return CSP_ERR_NOMEM; - -} - -void csp_buffer_free_resources(void) { - - if (csp_buffers) { - csp_queue_remove(csp_buffers); - csp_buffers = NULL; - } - csp_free(csp_buffer_pool); - csp_buffer_pool = NULL; - -} - -void *csp_buffer_get_isr(size_t _data_size) { - - if (_data_size > csp_conf.buffer_data_size) - return NULL; - - csp_skbf_t * buffer = NULL; - CSP_BASE_TYPE task_woken = 0; - csp_queue_dequeue_isr(csp_buffers, &buffer, &task_woken); - if (buffer == NULL) - return NULL; - - if (buffer != buffer->skbf_addr) - return NULL; - - buffer->refcount = 1; - return buffer->skbf_data; - -} - -void *csp_buffer_get(size_t _data_size) { - - if (_data_size > csp_conf.buffer_data_size) { - csp_log_error("GET: Attempt to allocate too large data size %u > max %u", (unsigned int) _data_size, (unsigned int) csp_conf.buffer_data_size); - return NULL; - } - - csp_skbf_t * buffer = NULL; - csp_queue_dequeue(csp_buffers, &buffer, 0); - if (buffer == NULL) { - csp_log_error("GET: Out of buffers"); - return NULL; - } - - if (buffer != buffer->skbf_addr) { - csp_log_error("GET: Corrupt CSP buffer %p != %p", buffer, buffer->skbf_addr); - return NULL; - } - - csp_log_buffer("GET: %p", buffer); - - buffer->refcount = 1; - return buffer->skbf_data; -} - -void csp_buffer_free_isr(void *packet) { - - if (packet == NULL) { - // freeing a NULL pointer is OK, e.g. standard free() - return; - } - - csp_skbf_t * buf = (void*)(((uint8_t*)packet) - sizeof(csp_skbf_t)); - - if (((uintptr_t) buf % CSP_BUFFER_ALIGN) > 0) { - return; - } - - if (buf->skbf_addr != buf) { - return; - } - - if (buf->refcount == 0) { - return; - } - - if (--(buf->refcount) > 0) { - return; - } - - CSP_BASE_TYPE task_woken = 0; - csp_queue_enqueue_isr(csp_buffers, &buf, &task_woken); - -} - -void csp_buffer_free(void *packet) { - - if (packet == NULL) { - /* freeing a NULL pointer is OK, e.g. standard free() */ - return; - } - - csp_skbf_t * buf = (void*)(((uint8_t*)packet) - sizeof(csp_skbf_t)); - - if (((uintptr_t) buf % CSP_BUFFER_ALIGN) > 0) { - csp_log_error("FREE: Unaligned CSP buffer pointer %p", packet); - return; - } - - if (buf->skbf_addr != buf) { - csp_log_error("FREE: Invalid CSP buffer pointer %p", packet); - return; - } - - if (buf->refcount == 0) { - csp_log_error("FREE: Buffer already free %p", buf); - return; - } - - if (--(buf->refcount) > 0) { - csp_log_error("FREE: Buffer %p in use by %u users", buf, buf->refcount); - return; - } - - csp_log_buffer("FREE: %p", buf); - csp_queue_enqueue(csp_buffers, &buf, 0); - -} - -void *csp_buffer_clone(void *buffer) { - - csp_packet_t *packet = (csp_packet_t *) buffer; - if (!packet) { - return NULL; - } - - csp_packet_t *clone = csp_buffer_get(packet->length); - if (clone) { - memcpy(clone, packet, csp_buffer_size()); - } - - return clone; - -} - -int csp_buffer_remaining(void) { - return csp_queue_size(csp_buffers); -} - -size_t csp_buffer_size(void) { - return (csp_conf.buffer_data_size + CSP_BUFFER_PACKET_OVERHEAD); -} - -size_t csp_buffer_data_size(void) { - return csp_conf.buffer_data_size; -} diff --git a/Program/libcsp/src/csp_conn.c b/Program/libcsp/src/csp_conn.c deleted file mode 100755 index 472f6ca..0000000 --- a/Program/libcsp/src/csp_conn.c +++ /dev/null @@ -1,527 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_conn.h" - -#include -#include - -#include -#include -#include -#include -#include -#include "csp_init.h" -#include "transport/csp_transport.h" - -/* Connection pool */ -static csp_conn_t * arr_conn; - -/* Connection pool lock */ -static csp_bin_sem_handle_t conn_lock; - -/* Last used 'source' port */ -static uint8_t sport; - -/* Source port lock */ -static csp_bin_sem_handle_t sport_lock; - -void csp_conn_check_timeouts(void) { -#if (CSP_USE_RDP) - for (int i = 0; i < csp_conf.conn_max; i++) { - if (arr_conn[i].state == CONN_OPEN) { - if (arr_conn[i].idin.flags & CSP_FRDP) { - csp_rdp_check_timeouts(&arr_conn[i]); - } - } - } -#endif -} - -int csp_conn_get_rxq(int prio) { - -#if (CSP_USE_QOS) - return prio; -#else - return 0; -#endif - -} - -int csp_conn_enqueue_packet(csp_conn_t * conn, csp_packet_t * packet) { - - if (!conn) - return CSP_ERR_INVAL; - - int rxq; - if (packet != NULL) { - rxq = csp_conn_get_rxq(packet->id.pri); - } else { - rxq = CSP_RX_QUEUES - 1; - } - - if (csp_queue_enqueue(conn->rx_queue[rxq], &packet, 0) != CSP_QUEUE_OK) { - csp_log_error("RX queue %p full with %u items", conn->rx_queue[rxq], csp_queue_size(conn->rx_queue[rxq])); - return CSP_ERR_NOMEM; - } - -#if (CSP_USE_QOS) - int event = 0; - if (csp_queue_enqueue(conn->rx_event, &event, 0) != CSP_QUEUE_OK) { - csp_log_error("QOS event queue full"); - return CSP_ERR_NOMEM; - } -#endif - - return CSP_ERR_NONE; -} - -int csp_conn_init(void) { - - arr_conn = csp_calloc(csp_conf.conn_max, sizeof(*arr_conn)); - if (arr_conn == NULL) { - csp_log_error("Allocation for %u connections failed", csp_conf.conn_max); - return CSP_ERR_NOMEM; - } - - if (csp_bin_sem_create(&conn_lock) != CSP_SEMAPHORE_OK) { - csp_log_error("csp_bin_sem_create(&conn_lock) failed"); - return CSP_ERR_NOMEM; - } - - /* Initialize source port */ - srand(csp_get_ms()); - sport = (rand() % (CSP_ID_PORT_MAX - csp_conf.port_max_bind)) + (csp_conf.port_max_bind + 1); - - if (csp_bin_sem_create(&sport_lock) != CSP_SEMAPHORE_OK) { - csp_log_error("csp_bin_sem_create(&sport_lock) failed"); - return CSP_ERR_NOMEM; - } - - for (int i = 0; i < csp_conf.conn_max; i++) { - csp_conn_t * conn = &arr_conn[i]; - for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { - conn->rx_queue[prio] = csp_queue_create(csp_conf.conn_queue_length, sizeof(csp_packet_t *)); - if (conn->rx_queue[prio] == NULL) { - csp_log_error("rx_queue = csp_queue_create() failed"); - return CSP_ERR_NOMEM; - } - } - -#if (CSP_USE_QOS) - conn->rx_event = csp_queue_create(csp_conf.conn_queue_length, sizeof(int)); - if (conn->rx_event == NULL) { - csp_log_error("rx_event = csp_queue_create() failed"); - return CSP_ERR_NOMEM; - } -#endif - -#if (CSP_USE_RDP) - if (csp_rdp_init(conn) != CSP_ERR_NONE) { - csp_log_error("csp_rdp_allocate(conn) failed"); - return CSP_ERR_NOMEM; - } -#endif - } - - return CSP_ERR_NONE; - -} - -void csp_conn_free_resources(void) { - - if (arr_conn) { - - for (unsigned int i = 0; i < csp_conf.conn_max; i++) { - csp_conn_t * conn = &arr_conn[i]; - - for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { - if (conn->rx_queue[prio]) { - csp_queue_remove(conn->rx_queue[prio]); - } - } - -#if (CSP_USE_QOS) - if (conn->rx_event) { - csp_queue_remove(conn->rx_event); - } -#endif - -#if (CSP_USE_RDP) - csp_rdp_free_resources(conn); -#endif - } - - csp_free(arr_conn); - arr_conn = NULL; - - //csp_bin_sem_remove(&conn_lock); - memset(&conn_lock, 0, sizeof(conn_lock)); - - //csp_bin_sem_remove(&sport_lock); - memset(&sport_lock, 0, sizeof(sport_lock)); - - sport = 0; - } -} - -csp_conn_t * csp_conn_find(uint32_t id, uint32_t mask) { - - /* Search for matching connection */ - id = (id & mask); - for (int i = 0; i < csp_conf.conn_max; i++) { - csp_conn_t * conn = &arr_conn[i]; - if ((conn->state == CONN_OPEN) && (conn->type == CONN_CLIENT) && ((conn->idin.ext & mask) == id)) { - return conn; - } - } - - return NULL; - -} - -static int csp_conn_flush_rx_queue(csp_conn_t * conn) { - - csp_packet_t * packet; - - int prio; - - /* Flush packet queues */ - for (prio = 0; prio < CSP_RX_QUEUES; prio++) { - while (csp_queue_dequeue(conn->rx_queue[prio], &packet, 0) == CSP_QUEUE_OK) - if (packet != NULL) - csp_buffer_free(packet); - } - - /* Flush event queue */ -#if (CSP_USE_QOS) - int event; - while (csp_queue_dequeue(conn->rx_event, &event, 0) == CSP_QUEUE_OK); -#endif - - return CSP_ERR_NONE; - -} - -csp_conn_t * csp_conn_allocate(csp_conn_type_t type) { - - static uint8_t csp_conn_last_given = 0; - - if (csp_bin_sem_wait(&conn_lock, CSP_MAX_TIMEOUT) != CSP_SEMAPHORE_OK) { - csp_log_error("Failed to lock conn array"); - return NULL; - } - - /* Search for free connection */ - csp_conn_t * conn = NULL; - int i = csp_conn_last_given; - for (int j = 0; j < csp_conf.conn_max; j++) { - i = (i + 1) % csp_conf.conn_max; - conn = &arr_conn[i]; - if (conn->state == CONN_CLOSED) { - break; - } - } - - if (conn && (conn->state == CONN_CLOSED)) { - conn->idin.ext = 0; - conn->idout.ext = 0; - conn->socket = NULL; - conn->timestamp = 0; - conn->type = type; - conn->state = CONN_OPEN; - csp_conn_last_given = i; - } else { - // no free connections - conn = NULL; - } - - csp_bin_sem_post(&conn_lock); - - if (conn == NULL) { - csp_log_error("No free connections, max %u", csp_conf.conn_max); - } - - return conn; - -} - -csp_conn_t * csp_conn_new(csp_id_t idin, csp_id_t idout) { - - /* Allocate connection structure */ - csp_conn_t * conn = csp_conn_allocate(CONN_CLIENT); - - if (conn) { - /* No lock is needed here, because nobody else * - * has a reference to this connection yet. */ - conn->idin.ext = idin.ext; - conn->idout.ext = idout.ext; - conn->timestamp = csp_get_ms(); - - /* Ensure connection queue is empty */ - csp_conn_flush_rx_queue(conn); - } - - return conn; - -} - -int csp_close(csp_conn_t * conn) { - return csp_conn_close(conn, CSP_RDP_CLOSED_BY_USERSPACE); -} - -int csp_conn_close(csp_conn_t * conn, uint8_t closed_by) { - - if (conn == NULL) { - return CSP_ERR_NONE; - } - - if (conn->state == CONN_CLOSED) { - csp_log_protocol("Conn already closed"); - return CSP_ERR_NONE; - } - -#if (CSP_USE_RDP) - /* Ensure RDP knows this connection is closing */ - if ((conn->idin.flags & CSP_FRDP) || (conn->idout.flags & CSP_FRDP)) { - if (csp_rdp_close(conn, closed_by) == CSP_ERR_AGAIN) { - return CSP_ERR_NONE; - } - } -#endif - - /* Lock connection array while closing connection */ - if (csp_bin_sem_wait(&conn_lock, CSP_MAX_TIMEOUT) != CSP_SEMAPHORE_OK) { - csp_log_error("Failed to lock conn array"); - return CSP_ERR_TIMEDOUT; - } - - /* Set to closed */ - conn->state = CONN_CLOSED; - - /* Ensure connection queue is empty */ - csp_conn_flush_rx_queue(conn); - - if (conn->socket && (conn->type == CONN_SERVER) && (conn->opts & (CSP_SO_CONN_LESS | CSP_SO_INTERNAL_LISTEN))) { - csp_queue_remove(conn->socket); - conn->socket = NULL; - } - - /* Reset RDP state */ -#if (CSP_USE_RDP) - if (conn->idin.flags & CSP_FRDP) { - csp_rdp_flush_all(conn); - } -#endif - - /* Unlock connection array */ - csp_bin_sem_post(&conn_lock); - - return CSP_ERR_NONE; -} - -csp_conn_t * csp_connect(uint8_t prio, uint8_t dest, uint8_t dport, uint32_t timeout, uint32_t opts) { - - /* Force options on all connections */ - opts |= csp_conf.conn_dfl_so; - - /* Generate identifier */ - csp_id_t incoming_id, outgoing_id; - incoming_id.pri = prio; - incoming_id.dst = csp_conf.address; - incoming_id.src = dest; - incoming_id.sport = dport; - incoming_id.flags = 0; - outgoing_id.pri = prio; - outgoing_id.dst = dest; - outgoing_id.src = csp_conf.address; - outgoing_id.dport = dport; - outgoing_id.flags = 0; - - /* Set connection options */ - if (opts & CSP_O_NOCRC32) { - opts &= ~CSP_O_CRC32; - } - - if (opts & CSP_O_RDP) { -#if (CSP_USE_RDP) - incoming_id.flags |= CSP_FRDP; - outgoing_id.flags |= CSP_FRDP; -#else - csp_log_error("Attempt to create RDP connection, but CSP was compiled without RDP support"); - return NULL; -#endif - } - - if (opts & CSP_O_HMAC) { -#if (CSP_USE_HMAC) - outgoing_id.flags |= CSP_FHMAC; - incoming_id.flags |= CSP_FHMAC; -#else - csp_log_error("Attempt to create HMAC authenticated connection, but CSP was compiled without HMAC support"); - return NULL; -#endif - } - - if (opts & CSP_O_XTEA) { -#if (CSP_USE_XTEA) - outgoing_id.flags |= CSP_FXTEA; - incoming_id.flags |= CSP_FXTEA; -#else - csp_log_error("Attempt to create XTEA encrypted connection, but CSP was compiled without XTEA support"); - return NULL; -#endif - } - - if (opts & CSP_O_CRC32) { -#if (CSP_USE_CRC32) - outgoing_id.flags |= CSP_FCRC32; - incoming_id.flags |= CSP_FCRC32; -#else - csp_log_error("Attempt to create CRC32 validated connection, but CSP was compiled without CRC32 support"); - return NULL; -#endif - } - - /* Find an unused ephemeral port */ - csp_conn_t * conn = NULL; - - /* Wait for sport lock - note that csp_conn_new(..) is called inside the lock! */ - if (csp_bin_sem_wait(&sport_lock, CSP_MAX_TIMEOUT) != CSP_SEMAPHORE_OK) { - return NULL; - } - - const uint8_t start = sport; - while (++sport != start) { - if (sport > CSP_ID_PORT_MAX) - sport = csp_conf.port_max_bind + 1; - - outgoing_id.sport = sport; - incoming_id.dport = sport; - - /* Match on destination port of _incoming_ identifier */ - if (csp_conn_find(incoming_id.ext, CSP_ID_DPORT_MASK) == NULL) { - /* Break - we found an unused ephemeral port - allocate connection while locked to mark port in use */ - conn = csp_conn_new(incoming_id, outgoing_id); - break; - } - } - - /* Post sport lock */ - csp_bin_sem_post(&sport_lock); - - if (conn == NULL) { - return NULL; - } - - /* Set connection options */ - conn->opts = opts; - -#if (CSP_USE_RDP) - /* Call Transport Layer connect */ - if (outgoing_id.flags & CSP_FRDP) { - /* If the transport layer has failed to connect - * deallocate connection structure again and return NULL */ - if (csp_rdp_connect(conn) != CSP_ERR_NONE) { - csp_close(conn); - return NULL; - } - } -#endif - - /* We have a successful connection */ - return conn; - -} - -int csp_conn_dport(csp_conn_t * conn) { - - return conn->idin.dport; - -} - -int csp_conn_sport(csp_conn_t * conn) { - - return conn->idin.sport; - -} - -int csp_conn_dst(csp_conn_t * conn) { - - return conn->idin.dst; - -} - -int csp_conn_src(csp_conn_t * conn) { - - return conn->idin.src; - -} - -int csp_conn_flags(csp_conn_t * conn) { - - return conn->idin.flags; - -} - -#if (CSP_DEBUG) -void csp_conn_print_table(void) { - - for (unsigned int i = 0; i < csp_conf.conn_max; i++) { - csp_conn_t * conn = &arr_conn[i]; - printf("[%02u %p] S:%u, %u -> %u, %u -> %u, sock: %p\r\n", - i, conn, conn->state, conn->idin.src, conn->idin.dst, - conn->idin.dport, conn->idin.sport, conn->socket); -#if (CSP_USE_RDP) - if (conn->idin.flags & CSP_FRDP) { - csp_rdp_conn_print(conn); - } -#endif - } -} - -int csp_conn_print_table_str(char * str_buf, int str_size) { - - /* Display up to 10 connections */ - unsigned int start = (csp_conf.conn_max > 10) ? (csp_conf.conn_max - 10) : 0; - - for (unsigned int i = start; i < csp_conf.conn_max; i++) { - csp_conn_t * conn = &arr_conn[i]; - char buf[100]; - snprintf(buf, sizeof(buf), "[%02u %p] S:%u, %u -> %u, %u -> %u, sock: %p\n", - i, conn, conn->state, conn->idin.src, conn->idin.dst, - conn->idin.dport, conn->idin.sport, conn->socket); - - strncat(str_buf, buf, str_size); - if ((str_size -= strlen(buf)) <= 0) { - break; - } - } - - return CSP_ERR_NONE; -} -#endif - -const csp_conn_t * csp_conn_get_array(size_t * size) -{ - *size = csp_conf.conn_max; - return arr_conn; -} diff --git a/Program/libcsp/src/csp_conn.h b/Program/libcsp/src/csp_conn.h deleted file mode 100755 index 60cdc41..0000000 --- a/Program/libcsp/src/csp_conn.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_CONN_H_ -#define _CSP_CONN_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CSP_USE_RDP_FAST_CLOSE -#define CSP_USE_RDP_FAST_CLOSE 0 -#endif - -/** Connection states */ -typedef enum { - CONN_CLOSED = 0, - CONN_OPEN = 1, -} csp_conn_state_t; - -/** Connection types */ -typedef enum { - CONN_CLIENT = 0, - CONN_SERVER = 1, -} csp_conn_type_t; - -/** RDP Connection states */ -typedef enum { - RDP_CLOSED = 0, - RDP_SYN_SENT, - RDP_SYN_RCVD, - RDP_OPEN, - RDP_CLOSE_WAIT, -} csp_rdp_state_t; - -#define CSP_RDP_CLOSED_BY_USERSPACE 0x01 -#define CSP_RDP_CLOSED_BY_PROTOCOL 0x02 -#define CSP_RDP_CLOSED_BY_TIMEOUT 0x04 -#define CSP_RDP_CLOSED_BY_ALL (CSP_RDP_CLOSED_BY_USERSPACE | CSP_RDP_CLOSED_BY_PROTOCOL | CSP_RDP_CLOSED_BY_TIMEOUT) - -/** - * RDP Connection - */ -typedef struct { - csp_rdp_state_t state; /**< Connection state */ - uint8_t closed_by; /**< Tracks 'who' have closed the RDP connection */ - uint16_t snd_nxt; /**< The sequence number of the next segment that is to be sent */ - uint16_t snd_una; /**< The sequence number of the oldest unacknowledged segment */ - uint16_t snd_iss; /**< The initial send sequence number */ - uint16_t rcv_cur; /**< The sequence number of the last segment received correctly and in sequence */ - uint16_t rcv_irs; /**< The initial receive sequence number */ - uint16_t rcv_lsa; /**< The last sequence number acknowledged by the receiver */ - uint32_t window_size; - uint32_t conn_timeout; - uint32_t packet_timeout; - uint32_t delayed_acks; - uint32_t ack_timeout; - uint32_t ack_delay_count; - uint32_t ack_timestamp; - csp_bin_sem_handle_t tx_wait; - csp_queue_handle_t tx_queue; - csp_queue_handle_t rx_queue; -} csp_rdp_t; - -/** @brief Connection struct */ -struct csp_conn_s { - csp_conn_type_t type; /* Connection type (CONN_CLIENT or CONN_SERVER) */ - csp_conn_state_t state; /* Connection state (CONN_OPEN or CONN_CLOSED) */ - csp_id_t idin; /* Identifier received */ - csp_id_t idout; /* Identifier transmitted */ -#if (CSP_USE_QOS) - csp_queue_handle_t rx_event; /* Event queue for RX packets */ -#endif - csp_queue_handle_t rx_queue[CSP_RX_QUEUES]; /* Queue for RX packets */ - csp_queue_handle_t socket; /* Socket to be "woken" when first packet is ready */ - uint32_t timestamp; /* Time the connection was opened */ - uint32_t opts; /* Connection or socket options */ -#if (CSP_USE_RDP) - csp_rdp_t rdp; /* RDP state */ -#endif -}; - -int csp_conn_enqueue_packet(csp_conn_t * conn, csp_packet_t * packet); -int csp_conn_init(void); -csp_conn_t * csp_conn_allocate(csp_conn_type_t type); -csp_conn_t * csp_conn_find(uint32_t id, uint32_t mask); -csp_conn_t * csp_conn_new(csp_id_t idin, csp_id_t idout); -void csp_conn_check_timeouts(void); -int csp_conn_get_rxq(int prio); -int csp_conn_close(csp_conn_t * conn, uint8_t closed_by); - -const csp_conn_t * csp_conn_get_array(size_t * size); // for test purposes only! -void csp_conn_free_resources(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/csp_crc32.c b/Program/libcsp/src/csp_crc32.c deleted file mode 100755 index 85301fa..0000000 --- a/Program/libcsp/src/csp_crc32.c +++ /dev/null @@ -1,130 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -#ifdef __AVR__ -#include -static const uint32_t crc_tab[256] PROGMEM = { -#else -static const uint32_t crc_tab[256] = { -#endif - 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, - 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, - 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, - 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, - 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, - 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, - 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, - 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, - 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, - 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, - 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, - 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, - 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, - 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, - 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, - 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, - 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, - 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, - 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, - 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, - 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, - 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, - 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, - 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, - 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, - 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, - 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, - 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, - 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, - 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, - 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, - 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 }; - -uint32_t csp_crc32_memory(const uint8_t * data, uint32_t length) { - uint32_t crc; - - crc = 0xFFFFFFFF; - while (length--) -#ifdef __AVR__ - crc = pgm_read_dword(&crc_tab[(crc ^ *data++) & 0xFFL]) ^ (crc >> 8); -#else - crc = crc_tab[(crc ^ *data++) & 0xFFL] ^ (crc >> 8); -#endif - - return (crc ^ 0xFFFFFFFF); -} - -int csp_crc32_append(csp_packet_t * packet, bool include_header) { - - uint32_t crc; - - if ((packet->length + sizeof(crc)) > csp_buffer_data_size()) { - return CSP_ERR_NOMEM; - } - - /* Calculate CRC32, convert to network byte order */ - if (include_header) { - crc = csp_crc32_memory((uint8_t *) &packet->id, packet->length + sizeof(packet->id)); - } else { - crc = csp_crc32_memory(packet->data, packet->length); - } - /* Convert to network byte order */ - crc = csp_hton32(crc); - - /* Copy checksum to packet */ - memcpy(&packet->data[packet->length], &crc, sizeof(crc)); - packet->length += sizeof(crc); - - return CSP_ERR_NONE; - -} - -int csp_crc32_verify(csp_packet_t * packet, bool include_header) { - - uint32_t crc; - - if (packet->length < sizeof(crc)) { - return CSP_ERR_CRC32; - } - - /* Calculate CRC32, convert to network byte order */ - if (include_header) { - crc = csp_crc32_memory((uint8_t *) &packet->id, packet->length + sizeof(packet->id) - sizeof(crc)); - } else { - crc = csp_crc32_memory(packet->data, packet->length - sizeof(crc)); - } - crc = csp_hton32(crc); - - /* Compare calculated checksum with packet header */ - if (memcmp(&packet->data[packet->length] - sizeof(crc), &crc, sizeof(crc)) != 0) { - /* CRC32 failed */ - return CSP_ERR_CRC32; - } - - /* Strip CRC32 */ - packet->length -= sizeof(crc); - return CSP_ERR_NONE; - -} - diff --git a/Program/libcsp/src/csp_debug.c b/Program/libcsp/src/csp_debug.c deleted file mode 100755 index 74f0bd7..0000000 --- a/Program/libcsp/src/csp_debug.c +++ /dev/null @@ -1,138 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include - -#ifdef __AVR__ -#include -#endif - -#include -#include -#include - -#if (CSP_DEBUG) && (CSP_USE_EXTERNAL_DEBUG == 0) - -/* Custom debug function */ -csp_debug_hook_func_t csp_debug_hook_func = NULL; - -/* Debug levels */ -bool csp_debug_level_enabled[] = { - [CSP_ERROR] = true, - [CSP_WARN] = true, - [CSP_INFO] = false, - [CSP_BUFFER] = false, - [CSP_PACKET] = false, - [CSP_PROTOCOL] = false, - [CSP_LOCK] = false, -}; - -void csp_debug_hook_set(csp_debug_hook_func_t f) { - - csp_debug_hook_func = f; -} - -void do_csp_debug(csp_debug_level_t level, const char *format, ...) { - - int color = COLOR_RESET; - va_list args; - - /* Don't print anything if log level is disabled */ - if (level > CSP_LOCK || !csp_debug_level_enabled[level]) - return; - - switch(level) { - case CSP_INFO: - color = COLOR_GREEN | COLOR_BOLD; - break; - case CSP_ERROR: - color = COLOR_RED | COLOR_BOLD; - break; - case CSP_WARN: - color = COLOR_YELLOW | COLOR_BOLD; - break; - case CSP_BUFFER: - color = COLOR_MAGENTA; - break; - case CSP_PACKET: - color = COLOR_GREEN; - break; - case CSP_PROTOCOL: - color = COLOR_BLUE; - break; - case CSP_LOCK: - color = COLOR_CYAN; - break; - default: - return; - } - - va_start(args, format); - - /* If csp_debug_hook symbol is defined, pass on the message. - * Otherwise, just print with pretty colors ... */ - if (csp_debug_hook_func) { - csp_debug_hook_func(level, format, args); - } else { - csp_sys_set_color(color); -#if (CSP_DEBUG_TIMESTAMP) - csp_timestamp_t ts; - csp_clock_get_time(&ts); - printf("%u.%06u ", ts.tv_sec, ts.tv_nsec / 1000U); -#endif -#ifdef __AVR__ - vfprintf_P(stdout, format, args); -#else - vprintf(format, args); -#endif - printf("\r\n"); - csp_sys_set_color(COLOR_RESET); - } - - va_end(args); -} - -void csp_debug_set_level(csp_debug_level_t level, bool value) { - - if (level <= CSP_LOCK) { - csp_debug_level_enabled[level] = value; - } -} - -int csp_debug_get_level(csp_debug_level_t level) { - - if (level <= CSP_LOCK) { - return csp_debug_level_enabled[level]; - } - return 0; -} - -void csp_debug_toggle_level(csp_debug_level_t level) { - - if (level <= CSP_LOCK) { - csp_debug_level_enabled[level] = (csp_debug_level_enabled[level]) ? false : true; - } -} - -#endif // (CSP_DEBUG) && !(CSP_USE_EXTERNAL_DEBUG) diff --git a/Program/libcsp/src/csp_dedup.c b/Program/libcsp/src/csp_dedup.c deleted file mode 100755 index 0190e7c..0000000 --- a/Program/libcsp/src/csp_dedup.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_dedup.h" - -#include - -#include -#include - -/* Check the last CSP_DEDUP_COUNT packets for duplicates */ -#define CSP_DEDUP_COUNT 16 - -/* Only consider packet a duplicate if received under CSP_DEDUP_WINDOW_MS ago */ -#define CSP_DEDUP_WINDOW_MS 1000 - -/* Store packet CRC's in a ringbuffer */ -static uint32_t csp_dedup_array[CSP_DEDUP_COUNT] = {}; -static uint32_t csp_dedup_timestamp[CSP_DEDUP_COUNT] = {}; -static int csp_dedup_in = 0; - -bool csp_dedup_is_duplicate(csp_packet_t *packet) -{ - /* Calculate CRC32 for packet */ - uint32_t crc = csp_crc32_memory((const uint8_t *) &packet->id, packet->length + sizeof(packet->id)); - - /* Check if we have received this packet before */ - for (int i = 0; i < CSP_DEDUP_COUNT; i++) { - - /* Check for match */ - if (crc == csp_dedup_array[i]) { - - /* Check the timestamp */ - if (csp_get_ms() < csp_dedup_timestamp[i] + CSP_DEDUP_WINDOW_MS) - return true; - } - } - - /* If not, insert packet into duplicate list */ - csp_dedup_array[csp_dedup_in] = crc; - csp_dedup_timestamp[csp_dedup_in] = csp_get_ms(); - csp_dedup_in = (csp_dedup_in + 1) % CSP_DEDUP_COUNT; - - return false; -} diff --git a/Program/libcsp/src/csp_dedup.h b/Program/libcsp/src/csp_dedup.h deleted file mode 100755 index 3d08a2b..0000000 --- a/Program/libcsp/src/csp_dedup.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_DEDUP_H_ -#define CSP_DEDUP_H_ - -#include - -/** - * Check for a duplicate packet - * @param packet pointer to packet - * @return false if not a duplicate, true if duplicate - */ -bool csp_dedup_is_duplicate(csp_packet_t *packet); - -#endif /* CSP_DEDUP_H_ */ diff --git a/Program/libcsp/src/csp_endian.c b/Program/libcsp/src/csp_endian.c deleted file mode 100755 index ee6f99a..0000000 --- a/Program/libcsp/src/csp_endian.c +++ /dev/null @@ -1,200 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -/* Convert 16-bit number from host byte order to network byte order */ -inline uint16_t __attribute__ ((__const__)) csp_hton16(uint16_t h16) { -#if (CSP_BIG_ENDIAN) - return h16; -#else - return (((h16 & 0xff00) >> 8) | - ((h16 & 0x00ff) << 8)); -#endif -} - -/* Convert 16-bit number from network byte order to host byte order */ -inline uint16_t __attribute__ ((__const__)) csp_ntoh16(uint16_t n16) { - return csp_hton16(n16); -} - -/* Convert 32-bit number from host byte order to network byte order */ -inline uint32_t __attribute__ ((__const__)) csp_hton32(uint32_t h32) { -#if (CSP_BIG_ENDIAN) - return h32; -#else - return (((h32 & 0xff000000) >> 24) | - ((h32 & 0x000000ff) << 24) | - ((h32 & 0x0000ff00) << 8) | - ((h32 & 0x00ff0000) >> 8)); -#endif -} - -/* Convert 32-bit number from network byte order to host byte order */ -inline uint32_t __attribute__ ((__const__)) csp_ntoh32(uint32_t n32) { - return csp_hton32(n32); -} - -/* Convert 64-bit number from host byte order to network byte order */ -inline uint64_t __attribute__ ((__const__)) csp_hton64(uint64_t h64) { -#if (CSP_BIG_ENDIAN) - return h64; -#else - return (((h64 & 0xff00000000000000LL) >> 56) | - ((h64 & 0x00000000000000ffLL) << 56) | - ((h64 & 0x00ff000000000000LL) >> 40) | - ((h64 & 0x000000000000ff00LL) << 40) | - ((h64 & 0x0000ff0000000000LL) >> 24) | - ((h64 & 0x0000000000ff0000LL) << 24) | - ((h64 & 0x000000ff00000000LL) >> 8) | - ((h64 & 0x00000000ff000000LL) << 8)); -#endif -} - -/* Convert 64-bit number from host byte order to network byte order */ -inline uint64_t __attribute__ ((__const__)) csp_ntoh64(uint64_t n64) { - return csp_hton64(n64); -} - -/* Convert 16-bit number from host byte order to big endian byte order */ -inline uint16_t __attribute__ ((__const__)) csp_htobe16(uint16_t h16) { - return csp_hton16(h16); -} - -/* Convert 16-bit number from host byte order to little endian byte order */ -inline uint16_t __attribute__ ((__const__)) csp_htole16(uint16_t h16) { -#if (CSP_LITTLE_ENDIAN) - return h16; -#else - return (((h16 & 0xff00) >> 8) | - ((h16 & 0x00ff) << 8)); -#endif -} - -/* Convert 16-bit number from big endian byte order to little endian byte order */ -inline uint16_t __attribute__ ((__const__)) csp_betoh16(uint16_t be16) { - return csp_ntoh16(be16); -} - -/* Convert 16-bit number from little endian byte order to host byte order */ -inline uint16_t __attribute__ ((__const__)) csp_letoh16(uint16_t le16) { - return csp_htole16(le16); -} - -/* Convert 32-bit number from host byte order to big endian byte order */ -inline uint32_t __attribute__ ((__const__)) csp_htobe32(uint32_t h32) { - return csp_hton32(h32); -} - -/* Convert 32-bit number from little endian byte order to host byte order */ -inline uint32_t __attribute__ ((__const__)) csp_htole32(uint32_t h32) { -#if (CSP_LITTLE_ENDIAN) - return h32; -#else - return (((h32 & 0xff000000) >> 24) | - ((h32 & 0x000000ff) << 24) | - ((h32 & 0x0000ff00) << 8) | - ((h32 & 0x00ff0000) >> 8)); -#endif -} - -/* Convert 32-bit number from big endian byte order to host byte order */ -inline uint32_t __attribute__ ((__const__)) csp_betoh32(uint32_t be32) { - return csp_ntoh32(be32); -} - -/* Convert 32-bit number from little endian byte order to host byte order */ -inline uint32_t __attribute__ ((__const__)) csp_letoh32(uint32_t le32) { - return csp_htole32(le32); -} - -/* Convert 64-bit number from host byte order to big endian byte order */ -inline uint64_t __attribute__ ((__const__)) csp_htobe64(uint64_t h64) { - return csp_hton64(h64); -} - -/* Convert 64-bit number from host byte order to little endian byte order */ -inline uint64_t __attribute__ ((__const__)) csp_htole64(uint64_t h64) { -#if (CSP_LITTLE_ENDIAN) - return h64; -#else - return (((h64 & 0xff00000000000000LL) >> 56) | - ((h64 & 0x00000000000000ffLL) << 56) | - ((h64 & 0x00ff000000000000LL) >> 40) | - ((h64 & 0x000000000000ff00LL) << 40) | - ((h64 & 0x0000ff0000000000LL) >> 24) | - ((h64 & 0x0000000000ff0000LL) << 24) | - ((h64 & 0x000000ff00000000LL) >> 8) | - ((h64 & 0x00000000ff000000LL) << 8)); -#endif -} - -/* Convert 64-bit number from big endian byte order to host byte order */ -inline uint64_t __attribute__ ((__const__)) csp_betoh64(uint64_t be64) { - return csp_ntoh64(be64); -} - -/* Convert 64-bit number from little endian byte order to host byte order */ -inline uint64_t __attribute__ ((__const__)) csp_letoh64(uint64_t le64) { - return csp_htole64(le64); -} - - -/* Convert float from host byte order to network byte order */ -inline float __attribute__ ((__const__)) csp_htonflt(float f) { -#if (CSP_BIG_ENDIAN) - return f; -#else - union v { - float f; - uint32_t i; - }; - union v val; - val.f = f; - val.i = csp_hton32(val.i); - return val.f; -#endif -} - -/* Convert float from host byte order to network byte order */ -inline float __attribute__ ((__const__)) csp_ntohflt(float f) { - return csp_htonflt(f); -} - -/* Convert double from host byte order to network byte order */ -inline double __attribute__ ((__const__)) csp_htondbl(double d) { -#if (CSP_BIG_ENDIAN) - return d; -#else - union v { - double d; - uint64_t i; - }; - union v val; - val.d = d; - val.i = csp_hton64(val.i); - return val.d; -#endif -} - -/* Convert float from host byte order to network byte order */ -inline double __attribute__ ((__const__)) csp_ntohdbl(double d) { - return csp_htondbl(d); -} diff --git a/Program/libcsp/src/csp_hex_dump.c b/Program/libcsp/src/csp_hex_dump.c deleted file mode 100755 index a31fd39..0000000 --- a/Program/libcsp/src/csp_hex_dump.c +++ /dev/null @@ -1,76 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -void csp_hex_dump(const char *desc, void *addr, int len) -{ - int i; - unsigned char buff[17]; - unsigned char *pc = (unsigned char*)addr; - - // Output description if given. - if (desc != NULL) - printf ("%s:\r\n", desc); - - if (len == 0) { - printf(" ZERO LENGTH\r\n"); - return; - } - if (len < 0) { - printf(" NEGATIVE LENGTH: %i\r\n",len); - return; - } - - // Process every byte in the data. - for (i = 0; i < len; i++) { - // Multiple of 16 means new line (with line offset). - - if ((i % 16) == 0) { - // Just don't print ASCII for the zeroth line. - if (i != 0) - printf (" %s\r\n", buff); - - // Output the offset. - printf (" %p ", ((uint8_t*)addr) + i); - } - - // Now the hex code for the specific character. - printf (" %02x", pc[i]); - - // And store a printable ASCII character for later. - if ((pc[i] < 0x20) || (pc[i] > 0x7e)) - buff[i % 16] = '.'; - else - buff[i % 16] = pc[i]; - buff[(i % 16) + 1] = '\0'; - } - - // Pad out last line if not exactly 16 characters. - while ((i % 16) != 0) { - printf (" "); - i++; - } - - // And print the final ASCII bit. - printf (" %s\r\n", buff); -} diff --git a/Program/libcsp/src/csp_iflist.c b/Program/libcsp/src/csp_iflist.c deleted file mode 100755 index 7accd8e..0000000 --- a/Program/libcsp/src/csp_iflist.c +++ /dev/null @@ -1,106 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include - -#include - -/* Interfaces are stored in a linked list */ -static csp_iface_t * interfaces = NULL; - -csp_iface_t * csp_iflist_get_by_name(const char *name) { - csp_iface_t *ifc = interfaces; - while(ifc) { - if (strncasecmp(ifc->name, name, CSP_IFLIST_NAME_MAX) == 0) { - break; - } - ifc = ifc->next; - } - return ifc; -} - -int csp_iflist_add(csp_iface_t *ifc) { - - ifc->next = NULL; - - /* Add interface to pool */ - if (interfaces == NULL) { - /* This is the first interface to be added */ - interfaces = ifc; - } else { - /* Insert interface last if not already in pool */ - csp_iface_t * last = NULL; - for (csp_iface_t * i = interfaces; i != NULL; i = i->next) { - if ((i == ifc) || (strncasecmp(ifc->name, i->name, CSP_IFLIST_NAME_MAX) == 0)) { - return CSP_ERR_ALREADY; - } - last = i; - } - - last->next = ifc; - } - - return CSP_ERR_NONE; -} - -csp_iface_t * csp_iflist_get(void) -{ - return interfaces; -} - -#if (CSP_DEBUG) -int csp_bytesize(char *buffer, int buffer_len, unsigned long int bytes) { - char postfix; - double size; - - if (bytes >= 1048576) { - size = bytes/1048576.0; - postfix = 'M'; - } else if (bytes >= 1024) { - size = bytes/1024.0; - postfix = 'K'; - } else { - size = bytes; - postfix = 'B'; - } - - return snprintf(buffer, buffer_len, "%.1f%c", size, postfix); -} - -void csp_iflist_print(void) { - csp_iface_t * i = interfaces; - char txbuf[25], rxbuf[25]; - - while (i) { - csp_bytesize(txbuf, sizeof(txbuf), i->txbytes); - csp_bytesize(rxbuf, sizeof(rxbuf), i->rxbytes); - printf("%-10s tx: %05"PRIu32" rx: %05"PRIu32" txe: %05"PRIu32" rxe: %05"PRIu32"\r\n" - " drop: %05"PRIu32" autherr: %05"PRIu32 " frame: %05"PRIu32"\r\n" - " txb: %"PRIu32" (%s) rxb: %"PRIu32" (%s) MTU: %u\r\n\r\n", - i->name, i->tx, i->rx, i->tx_error, i->rx_error, i->drop, - i->autherr, i->frame, i->txbytes, txbuf, i->rxbytes, rxbuf, i->mtu); - i = i->next; - } -} -#endif - diff --git a/Program/libcsp/src/csp_init.c b/Program/libcsp/src/csp_init.c deleted file mode 100755 index 94be820..0000000 --- a/Program/libcsp/src/csp_init.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_init.h" - -#include -#include -#include "csp_conn.h" -#include "csp_qfifo.h" -#include "csp_port.h" - -csp_conf_t csp_conf; - -uint8_t csp_get_address(void) { - - return csp_conf.address; -} - -int csp_init(const csp_conf_t * conf) { - - /* make offset first time, so uptime is counted from process/task boot */ - csp_get_uptime_s(); - - /* Make a copy of the configuration - * The copy is kept hidden for the user in csp_init.h - * Configuration cannot be changed after calling init - * unless specific get/set functions are made */ - memcpy(&csp_conf, conf, sizeof(csp_conf)); - - int ret = csp_buffer_init(); - if (ret != CSP_ERR_NONE) { - return ret; - } - - ret = csp_conn_init(); - if (ret != CSP_ERR_NONE) { - return ret; - } - - ret = csp_port_init(); - if (ret != CSP_ERR_NONE) { - return ret; - } - - ret = csp_qfifo_init(); - if (ret != CSP_ERR_NONE) { - return ret; - } - - /* Loopback */ - csp_iflist_add(&csp_if_lo); - - /* Register loopback route */ - csp_route_set(csp_conf.address, &csp_if_lo, CSP_NO_VIA_ADDRESS); - - /* Also register loopback as default, until user redefines default route */ - csp_route_set(CSP_DEFAULT_ROUTE, &csp_if_lo, CSP_NO_VIA_ADDRESS); - - return CSP_ERR_NONE; - -} - -void csp_free_resources(void) { - - csp_rtable_free(); - csp_qfifo_free_resources(); - csp_port_free_resources(); - csp_conn_free_resources(); - csp_buffer_free_resources(); - memset(&csp_conf, 0, sizeof(csp_conf)); - -} - -const csp_conf_t * csp_get_conf(void) { - - return &csp_conf; - -} diff --git a/Program/libcsp/src/csp_init.h b/Program/libcsp/src/csp_init.h deleted file mode 100755 index 5e3c9c4..0000000 --- a/Program/libcsp/src/csp_init.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef LIB_CSP_SRC_CSP_INIT_H_ -#define LIB_CSP_SRC_CSP_INIT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern csp_conf_t csp_conf; - -int csp_buffer_init(void); -void csp_buffer_free_resources(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/csp_io.c b/Program/libcsp/src/csp_io.c deleted file mode 100755 index 9dbded6..0000000 --- a/Program/libcsp/src/csp_io.c +++ /dev/null @@ -1,408 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_io.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "csp_init.h" -#include "csp_port.h" -#include "csp_conn.h" -#include "csp_promisc.h" -#include "csp_qfifo.h" -#include "transport/csp_transport.h" - -#if (CSP_USE_PROMISC) -extern csp_queue_handle_t csp_promisc_queue; -#endif - -csp_socket_t * csp_socket(uint32_t opts) { - - /* Validate socket options */ -#if (CSP_USE_RDP == 0) - if (opts & CSP_SO_RDPREQ) { - csp_log_error("Attempt to create socket that requires RDP, but CSP was compiled without RDP support"); - return NULL; - } -#endif - -#if (CSP_USE_XTEA == 0) - if (opts & CSP_SO_XTEAREQ) { - csp_log_error("Attempt to create socket that requires XTEA, but CSP was compiled without XTEA support"); - return NULL; - } -#endif - -#if (CSP_USE_HMAC == 0) - if (opts & CSP_SO_HMACREQ) { - csp_log_error("Attempt to create socket that requires HMAC, but CSP was compiled without HMAC support"); - return NULL; - } -#endif - -#if (CSP_USE_CRC32 == 0) - if (opts & CSP_SO_CRC32REQ) { - csp_log_error("Attempt to create socket that requires CRC32, but CSP was compiled without CRC32 support"); - return NULL; - } -#endif - - /* Drop packet if reserved flags are set */ - if (opts & ~(CSP_SO_RDPREQ | CSP_SO_XTEAREQ | CSP_SO_HMACREQ | CSP_SO_CRC32REQ | CSP_SO_CONN_LESS)) { - csp_log_error("Invalid socket option"); - return NULL; - } - - /* Use CSP buffers instead? */ - csp_socket_t * sock = csp_conn_allocate(CONN_SERVER); - if (sock == NULL) - return NULL; - - /* If connectionless, init the queue to a pre-defined size - * if not, the user must init the queue using csp_listen */ - if (opts & CSP_SO_CONN_LESS) { - sock->socket = csp_queue_create(csp_conf.conn_queue_length, sizeof(csp_packet_t *)); - if (sock->socket == NULL) { - csp_close(sock); - return NULL; - } - } else { - sock->socket = NULL; - } - sock->opts = opts; - - return sock; - -} - -csp_conn_t * csp_accept(csp_socket_t * sock, uint32_t timeout) { - - if (sock == NULL) - return NULL; - - if (sock->socket == NULL) - return NULL; - - csp_conn_t * conn; - if (csp_queue_dequeue(sock->socket, &conn, timeout) == CSP_QUEUE_OK) - return conn; - - return NULL; - -} - -csp_packet_t * csp_read(csp_conn_t * conn, uint32_t timeout) { - - csp_packet_t * packet = NULL; - - if ((conn == NULL) || (conn->state != CONN_OPEN)) { - return NULL; - } - -#if (CSP_USE_RDP) - // RDP: timeout can either be 0 (for no hang poll/check) or minimum the "connection timeout" - if (timeout && (conn->idin.flags & CSP_FRDP) && (timeout < conn->rdp.conn_timeout)) { - timeout = conn->rdp.conn_timeout; - } -#endif - -#if (CSP_USE_QOS) - int event; - if (csp_queue_dequeue(conn->rx_event, &event, timeout) != CSP_QUEUE_OK) { - return NULL; - } - - for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { - if (csp_queue_dequeue(conn->rx_queue[prio], &packet, 0) == CSP_QUEUE_OK) { - break; - } - } -#else - if (csp_queue_dequeue(conn->rx_queue[0], &packet, timeout) != CSP_QUEUE_OK) { - return NULL; - } -#endif - -#if (CSP_USE_RDP) - /* Packet read could trigger ACK transmission */ - if ((conn->idin.flags & CSP_FRDP) && conn->rdp.delayed_acks) { - csp_rdp_check_ack(conn); - } -#endif - - return packet; - -} - -int csp_send_direct(csp_id_t idout, csp_packet_t * packet, const csp_route_t * ifroute, uint32_t timeout) { - - if (packet == NULL) { - csp_log_error("csp_send_direct called with NULL packet"); - goto err; - } - - if (ifroute == NULL) { - csp_log_error("No route to host: %u (0x%08"PRIx32")", idout.dst, idout.ext); - goto err; - } - - csp_iface_t * ifout = ifroute->iface; - - csp_log_packet("OUT: S %u, D %u, Dp %u, Sp %u, Pr %u, Fl 0x%02X, Sz %u VIA: %s (%u)", - idout.src, idout.dst, idout.dport, idout.sport, idout.pri, idout.flags, packet->length, ifout->name, (ifroute->via != CSP_NO_VIA_ADDRESS) ? ifroute->via : idout.dst); - - /* Copy identifier to packet (before crc, xtea and hmac) */ - packet->id.ext = idout.ext; - -#if (CSP_USE_PROMISC) - /* Loopback traffic is added to promisc queue by the router */ - if (idout.dst != csp_get_address() && idout.src == csp_get_address()) { - packet->id.ext = idout.ext; - csp_promisc_add(packet); - } -#endif - - /* Only encrypt packets from the current node */ - if (idout.src == csp_conf.address) { - /* Append HMAC */ - if (idout.flags & CSP_FHMAC) { -#if (CSP_USE_HMAC) - /* Calculate and add HMAC (does not include header for backwards compatability with csp1.x) */ - if (csp_hmac_append(packet, false) != CSP_ERR_NONE) { - /* HMAC append failed */ - csp_log_warn("HMAC append failed!"); - goto tx_err; - } -#else - csp_log_warn("Attempt to send packet with HMAC, but CSP was compiled without HMAC support. Discarding packet"); - goto tx_err; -#endif - } - - /* Append CRC32 */ - if (idout.flags & CSP_FCRC32) { -#if (CSP_USE_CRC32) - /* Calculate and add CRC32 (does not include header for backwards compatability with csp1.x) */ - if (csp_crc32_append(packet, false) != CSP_ERR_NONE) { - /* CRC32 append failed */ - csp_log_warn("CRC32 append failed!"); - goto tx_err; - } -#else - csp_log_warn("Attempt to send packet with CRC32, but CSP was compiled without CRC32 support. Sending without CRC32r"); - idout.flags &= ~(CSP_FCRC32); -#endif - } - - if (idout.flags & CSP_FXTEA) { -#if (CSP_USE_XTEA) - /* Encrypt data */ - if (csp_xtea_encrypt_packet(packet) != CSP_ERR_NONE) { - /* Encryption failed */ - csp_log_warn("XTEA Encryption failed!"); - goto tx_err; - } -#else - csp_log_warn("Attempt to send XTEA encrypted packet, but CSP was compiled without XTEA support. Discarding packet"); - goto tx_err; -#endif - } - } - - /* Store length before passing to interface */ - uint16_t bytes = packet->length; - uint16_t mtu = ifout->mtu; - - if (mtu > 0 && bytes > mtu) - goto tx_err; - - if ((*ifout->nexthop)(ifroute, packet) != CSP_ERR_NONE) - goto tx_err; - - ifout->tx++; - ifout->txbytes += bytes; - return CSP_ERR_NONE; - -tx_err: - ifout->tx_error++; -err: - return CSP_ERR_TX; - -} - -int csp_send(csp_conn_t * conn, csp_packet_t * packet, uint32_t timeout) { - - if ((conn == NULL) || (packet == NULL) || (conn->state != CONN_OPEN)) { - csp_log_error("Invalid call to csp_send"); - return 0; - } - -#if (CSP_USE_RDP) - if (conn->idout.flags & CSP_FRDP) { - if (csp_rdp_send(conn, packet) != CSP_ERR_NONE) { - return 0; - } - } -#endif - - int ret = csp_send_direct(conn->idout, packet, csp_rtable_find_route(conn->idout.dst), timeout); - - return (ret == CSP_ERR_NONE) ? 1 : 0; - -} - -int csp_send_prio(uint8_t prio, csp_conn_t * conn, csp_packet_t * packet, uint32_t timeout) { - conn->idout.pri = prio; - return csp_send(conn, packet, timeout); -} - -int csp_transaction_persistent(csp_conn_t * conn, uint32_t timeout, void * outbuf, int outlen, void * inbuf, int inlen) { - - int size = (inlen > outlen) ? inlen : outlen; - csp_packet_t * packet = csp_buffer_get(size); - if (packet == NULL) - return 0; - - /* Copy the request */ - if (outlen > 0 && outbuf != NULL) - memcpy(packet->data, outbuf, outlen); - packet->length = outlen; - - if (!csp_send(conn, packet, timeout)) { - csp_buffer_free(packet); - return 0; - } - - /* If no reply is expected, return now */ - if (inlen == 0) - return 1; - - packet = csp_read(conn, timeout); - if (packet == NULL) - return 0; - - if ((inlen != -1) && ((int)packet->length != inlen)) { - csp_log_error("Reply length %u expected %u", packet->length, inlen); - csp_buffer_free(packet); - return 0; - } - - memcpy(inbuf, packet->data, packet->length); - int length = packet->length; - csp_buffer_free(packet); - return length; - -} - -int csp_transaction_w_opts(uint8_t prio, uint8_t dest, uint8_t port, uint32_t timeout, void * outbuf, int outlen, void * inbuf, int inlen, uint32_t opts) { - - csp_conn_t * conn = csp_connect(prio, dest, port, 0, opts); - if (conn == NULL) - return 0; - - int status = csp_transaction_persistent(conn, timeout, outbuf, outlen, inbuf, inlen); - - csp_close(conn); - - return status; - -} - -csp_packet_t * csp_recvfrom(csp_socket_t * socket, uint32_t timeout) { - - if ((socket == NULL) || (!(socket->opts & CSP_SO_CONN_LESS))) - return NULL; - - csp_packet_t * packet = NULL; - csp_queue_dequeue(socket->socket, &packet, timeout); - - return packet; - -} - -int csp_sendto(uint8_t prio, uint8_t dest, uint8_t dport, uint8_t src_port, uint32_t opts, csp_packet_t * packet, uint32_t timeout) { - - packet->id.flags = 0; - - if (opts & CSP_O_RDP) { - csp_log_error("Attempt to create RDP packet on connection-less socket"); - return CSP_ERR_INVAL; - } - - if (opts & CSP_O_HMAC) { -#if (CSP_USE_HMAC) - packet->id.flags |= CSP_FHMAC; -#else - csp_log_error("Attempt to create HMAC authenticated packet, but CSP was compiled without HMAC support"); - return CSP_ERR_NOTSUP; -#endif - } - - if (opts & CSP_O_XTEA) { -#if (CSP_USE_XTEA) - packet->id.flags |= CSP_FXTEA; -#else - csp_log_error("Attempt to create XTEA encrypted packet, but CSP was compiled without XTEA support"); - return CSP_ERR_NOTSUP; -#endif - } - - if (opts & CSP_O_CRC32) { -#if (CSP_USE_CRC32) - packet->id.flags |= CSP_FCRC32; -#else - csp_log_error("Attempt to create CRC32 validated packet, but CSP was compiled without CRC32 support"); - return CSP_ERR_NOTSUP; -#endif - } - - packet->id.dst = dest; - packet->id.dport = dport; - packet->id.src = csp_conf.address; - packet->id.sport = src_port; - packet->id.pri = prio; - - if (csp_send_direct(packet->id, packet, csp_rtable_find_route(dest), timeout) != CSP_ERR_NONE) - return CSP_ERR_NOTSUP; - - return CSP_ERR_NONE; - -} - -int csp_sendto_reply(const csp_packet_t * request_packet, csp_packet_t * reply_packet, uint32_t opts, uint32_t timeout) { - if (request_packet == NULL) - return CSP_ERR_INVAL; - - return csp_sendto(request_packet->id.pri, request_packet->id.src, request_packet->id.sport, request_packet->id.dport, opts, reply_packet, timeout); -} diff --git a/Program/libcsp/src/csp_io.h b/Program/libcsp/src/csp_io.h deleted file mode 100755 index 57bfa77..0000000 --- a/Program/libcsp/src/csp_io.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_IO_H_ -#define _CSP_IO_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Send CSP packet via route (no existing connection). - - @param idout 32bit CSP identifier - @param packet packet to send - this will not be freed. - @param ifroute route to destination - @param timeout timeout to wait for TX to complete. NOTE: not all underlying drivers supports flow-control. - @return #CSP_ERR_NONE on success, otherwise an error code. -*/ -int csp_send_direct(csp_id_t idout, csp_packet_t * packet, const csp_route_t * ifroute, uint32_t timeout); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/csp_port.c b/Program/libcsp/src/csp_port.c deleted file mode 100755 index b3913e4..0000000 --- a/Program/libcsp/src/csp_port.c +++ /dev/null @@ -1,115 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_port.h" - -#include -#include -#include - -#include -#include -#include - -#include "csp_conn.h" -#include "csp_init.h" - -/* Dynamic allocated port array */ -static csp_port_t * ports; - -csp_socket_t * csp_port_get_socket(unsigned int port) { - - if (port > csp_conf.port_max_bind) { - return NULL; - } - - /* Match dport to socket or local "catch all" port number */ - if (ports[port].state == PORT_OPEN) { - return ports[port].socket; - } - - if (ports[csp_conf.port_max_bind + 1].state == PORT_OPEN) { - return ports[csp_conf.port_max_bind + 1].socket; - } - - return NULL; - -} - -int csp_port_init(void) { - - ports = csp_calloc(csp_conf.port_max_bind + 2, sizeof(*ports)); // +2 for max port and CSP_ANY - if (ports == NULL) { - return CSP_ERR_NOMEM; - } - - return CSP_ERR_NONE; - -} - -void csp_port_free_resources(void) { - - csp_free(ports); - ports = NULL; -} - -int csp_listen(csp_socket_t * socket, size_t backlog) { - - if (socket == NULL) - return CSP_ERR_INVAL; - - socket->socket = csp_queue_create(backlog, sizeof(csp_conn_t *)); - if (socket->socket == NULL) - return CSP_ERR_NOMEM; - - socket->opts |= CSP_SO_INTERNAL_LISTEN; - - return CSP_ERR_NONE; - -} - -int csp_bind(csp_socket_t * socket, uint8_t port) { - - if (socket == NULL) - return CSP_ERR_INVAL; - - if (port == CSP_ANY) { - port = csp_conf.port_max_bind + 1; - } else if (port > csp_conf.port_max_bind) { - csp_log_error("csp_bind: invalid port %u, only ports from 0-%u (+ CSP_ANY for default) are available for incoming ports", port, csp_conf.port_max_bind); - return CSP_ERR_INVAL; - } - - if (ports[port].state != PORT_CLOSED) { - csp_log_error("Port %d is already in use", port); - return CSP_ERR_USED; - } - - csp_log_info("Binding socket %p to port %u", socket, port); - - /* Save listener */ - ports[port].socket = socket; - ports[port].state = PORT_OPEN; - - return CSP_ERR_NONE; - -} - - diff --git a/Program/libcsp/src/csp_port.h b/Program/libcsp/src/csp_port.h deleted file mode 100755 index ba0f909..0000000 --- a/Program/libcsp/src/csp_port.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_PORT_H_ -#define _CSP_PORT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief Port states */ -typedef enum { - PORT_CLOSED = 0, - PORT_OPEN = 1, -} csp_port_state_t; - -/** @brief Port struct */ -typedef struct { - csp_port_state_t state; // Port state - csp_socket_t * socket; // New connections are added to this socket's conn queue -} csp_port_t; - -/** - * Init ports array - */ -int csp_port_init(void); - -/** - * Free all allocatged resources (testing) - */ -void csp_port_free_resources(void); - -csp_socket_t * csp_port_get_socket(unsigned int dport); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/csp_promisc.c b/Program/libcsp/src/csp_promisc.c deleted file mode 100755 index 1e53cfe..0000000 --- a/Program/libcsp/src/csp_promisc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_promisc.h" - -#include -#include - -#if (CSP_USE_PROMISC) - -static csp_queue_handle_t csp_promisc_queue = NULL; -static int csp_promisc_enabled = 0; - -int csp_promisc_enable(unsigned int queue_size) { - - /* If queue already initialised */ - if (csp_promisc_queue != NULL) { - csp_promisc_enabled = 1; - return CSP_ERR_NONE; - } - - /* Create packet queue */ - csp_promisc_queue = csp_queue_create(queue_size, sizeof(csp_packet_t *)); - - if (csp_promisc_queue == NULL) - return CSP_ERR_INVAL; - - csp_promisc_enabled = 1; - return CSP_ERR_NONE; - -} - -void csp_promisc_disable(void) { - csp_promisc_enabled = 0; -} - -csp_packet_t * csp_promisc_read(uint32_t timeout) { - - if (csp_promisc_queue == NULL) - return NULL; - - csp_packet_t * packet = NULL; - csp_queue_dequeue(csp_promisc_queue, &packet, timeout); - - return packet; - -} - -void csp_promisc_add(csp_packet_t * packet) { - - if (csp_promisc_enabled == 0) - return; - - if (csp_promisc_queue != NULL) { - /* Make a copy of the message and queue it to the promiscuous task */ - csp_packet_t *packet_copy = csp_buffer_clone(packet); - if (packet_copy != NULL) { - if (csp_queue_enqueue(csp_promisc_queue, &packet_copy, 0) != CSP_QUEUE_OK) { - csp_log_error("Promiscuous mode input queue full"); - csp_buffer_free(packet_copy); - } - } - } - -} - -#endif diff --git a/Program/libcsp/src/csp_promisc.h b/Program/libcsp/src/csp_promisc.h deleted file mode 100755 index 80c57fa..0000000 --- a/Program/libcsp/src/csp_promisc.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 Gomspace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _SRC_CSP_PROMISC_H_ -#define _SRC_CSP_PROMISC_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Add packet to promiscuous mode packet queue - * @param packet Packet to add to the queue - */ -void csp_promisc_add(csp_packet_t * packet); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/csp_qfifo.c b/Program/libcsp/src/csp_qfifo.c deleted file mode 100755 index 37709f1..0000000 --- a/Program/libcsp/src/csp_qfifo.c +++ /dev/null @@ -1,168 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_qfifo.h" - -#include - -#include "csp_init.h" - -static csp_queue_handle_t qfifo[CSP_ROUTE_FIFOS]; -#if (CSP_USE_QOS) -static csp_queue_handle_t qfifo_events; -#endif - -int csp_qfifo_init(void) { - - /* Create router fifos for each priority */ - for (int prio = 0; prio < CSP_ROUTE_FIFOS; prio++) { - if (qfifo[prio] == NULL) { - qfifo[prio] = csp_queue_create(csp_conf.fifo_length, sizeof(csp_qfifo_t)); - if (!qfifo[prio]) - return CSP_ERR_NOMEM; - } - } - -#if (CSP_USE_QOS) - /* Create QoS fifo notification queue */ - qfifo_events = csp_queue_create(csp_conf.fifo_length, sizeof(int)); - if (!qfifo_events) { - return CSP_ERR_NOMEM; - } -#endif - - return CSP_ERR_NONE; - -} - -void csp_qfifo_free_resources(void) { - - for (int prio = 0; prio < CSP_ROUTE_FIFOS; prio++) { - if (qfifo[prio]) { - csp_queue_remove(qfifo[prio]); - qfifo[prio] = NULL; - } - } - -#if (CSP_USE_QOS) - if (qfifo_events) { - csp_queue_remove(qfifo_events); - qfifo_events = NULL; - } -#endif - -} - -int csp_qfifo_read(csp_qfifo_t * input) { - -#if (CSP_USE_QOS) - int prio, found, event; - - /* Wait for packet in any queue */ - if (csp_queue_dequeue(qfifo_events, &event, FIFO_TIMEOUT) != CSP_QUEUE_OK) - return CSP_ERR_TIMEDOUT; - - /* Find packet with highest priority */ - found = 0; - for (prio = 0; prio < CSP_ROUTE_FIFOS; prio++) { - if (csp_queue_dequeue(qfifo[prio], input, 0) == CSP_QUEUE_OK) { - found = 1; - break; - } - } - - if (!found) { - csp_log_warn("Spurious wakeup: No packet found"); - return CSP_ERR_TIMEDOUT; - } -#else - if (csp_queue_dequeue(qfifo[0], input, FIFO_TIMEOUT) != CSP_QUEUE_OK) - return CSP_ERR_TIMEDOUT; -#endif - - return CSP_ERR_NONE; - -} - -void csp_qfifo_write(csp_packet_t * packet, csp_iface_t * iface, CSP_BASE_TYPE * pxTaskWoken) { - - int result; - - if (packet == NULL) { - if (pxTaskWoken == NULL) { // Only do logging in non-ISR context - csp_log_warn("csp_new packet called with NULL packet"); - } - return; - } - - if (iface == NULL) { - if (pxTaskWoken == NULL) { // Only do logging in non-ISR context - csp_log_warn("csp_new packet called with NULL interface"); - } - if (pxTaskWoken == NULL) - csp_buffer_free(packet); - else - csp_buffer_free_isr(packet); - return; - } - - csp_qfifo_t queue_element; - queue_element.iface = iface; - queue_element.packet = packet; - -#if (CSP_USE_QOS) - int fifo = packet->id.pri; -#else - int fifo = 0; -#endif - - if (pxTaskWoken == NULL) - result = csp_queue_enqueue(qfifo[fifo], &queue_element, 0); - else - result = csp_queue_enqueue_isr(qfifo[fifo], &queue_element, pxTaskWoken); - -#if (CSP_USE_QOS) - static int event = 0; - - if (result == CSP_QUEUE_OK) { - if (pxTaskWoken == NULL) - csp_queue_enqueue(qfifo_events, &event, 0); - else - csp_queue_enqueue_isr(qfifo_events, &event, pxTaskWoken); - } -#endif - - if (result != CSP_QUEUE_OK) { - if (pxTaskWoken == NULL) { // Only do logging in non-ISR context - csp_log_warn("ERROR: Routing input FIFO is FULL. Dropping packet."); - } - iface->drop++; - if (pxTaskWoken == NULL) - csp_buffer_free(packet); - else - csp_buffer_free_isr(packet); - } - -} - -void csp_qfifo_wake_up(void) { - const csp_qfifo_t queue_element = {.iface = NULL, .packet = NULL}; - csp_queue_enqueue(qfifo[0], &queue_element, 0); -} diff --git a/Program/libcsp/src/csp_qfifo.h b/Program/libcsp/src/csp_qfifo.h deleted file mode 100755 index bf9214a..0000000 --- a/Program/libcsp/src/csp_qfifo.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef CSP_QFIFO_H_ -#define CSP_QFIFO_H_ - -#include - -#if (CSP_USE_RDP) -#define FIFO_TIMEOUT 100 //! If RDP is enabled, the router needs to awake some times to check timeouts -#else -#define FIFO_TIMEOUT CSP_MAX_TIMEOUT //! If no RDP, the router can sleep untill data arrives -#endif - -/** - * Init FIFO/QOS queues - * @return CSP_ERR type - */ -int csp_qfifo_init(void); - -void csp_qfifo_free_resources(void); - -typedef struct { - csp_iface_t * iface; - csp_packet_t * packet; -} csp_qfifo_t; - -/** - * Read next packet from router input queue - * @param input pointer to router queue item element - * @return CSP_ERR type - */ -int csp_qfifo_read(csp_qfifo_t * input); - -/** - * Wake up any task (e.g. router) waiting on messages. - * For testing. - */ -void csp_qfifo_wake_up(void); - -#endif /* CSP_QFIFO_H_ */ diff --git a/Program/libcsp/src/csp_route.c b/Program/libcsp/src/csp_route.c deleted file mode 100755 index 6e919c2..0000000 --- a/Program/libcsp/src/csp_route.c +++ /dev/null @@ -1,337 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "csp_init.h" -#include "csp_port.h" -#include "csp_conn.h" -#include "csp_io.h" -#include "csp_promisc.h" -#include "csp_qfifo.h" -#include "csp_dedup.h" -#include "transport/csp_transport.h" - -/** - * Check supported packet options - * @param iface pointer to incoming interface - * @param packet pointer to packet - * @return CSP_ERR_NONE is all options are supported, CSP_ERR_NOTSUP if not - */ -static int csp_route_check_options(csp_iface_t *iface, csp_packet_t *packet) -{ -#if (CSP_USE_XTEA == 0) - /* Drop XTEA packets */ - if (packet->id.flags & CSP_FXTEA) { - csp_log_error("Received XTEA encrypted packet, but CSP was compiled without XTEA support. Discarding packet"); - iface->autherr++; - return CSP_ERR_NOTSUP; - } -#endif - -#if (CSP_USE_HMAC == 0) - /* Drop HMAC packets */ - if (packet->id.flags & CSP_FHMAC) { - csp_log_error("Received packet with HMAC, but CSP was compiled without HMAC support. Discarding packet"); - iface->autherr++; - return CSP_ERR_NOTSUP; - } -#endif - -#if (CSP_USE_RDP == 0) - /* Drop RDP packets */ - if (packet->id.flags & CSP_FRDP) { - csp_log_error("Received RDP packet, but CSP was compiled without RDP support. Discarding packet"); - iface->rx_error++; - return CSP_ERR_NOTSUP; - } -#endif - return CSP_ERR_NONE; -} - -/** - * Helper function to decrypt, check auth and CRC32 - * @param security_opts either socket_opts or conn_opts - * @param iface pointer to incoming interface - * @param packet pointer to packet - * @return #CSP_ERR_NONE on success, otherwise an error code. - */ -static int csp_route_security_check(uint32_t security_opts, csp_iface_t * iface, csp_packet_t * packet) { - -#if (CSP_USE_XTEA) - /* XTEA encrypted packet */ - if (packet->id.flags & CSP_FXTEA) { - /* Decrypt data */ - if (csp_xtea_decrypt_packet(packet) != CSP_ERR_NONE) { - csp_log_error("XTEA Decryption failed! Discarding packet"); - iface->autherr++; - return CSP_ERR_XTEA; - } - } else if (security_opts & CSP_SO_XTEAREQ) { - csp_log_warn("Received packet without XTEA encryption. Discarding packet"); - iface->autherr++; - return CSP_ERR_XTEA; - } -#endif - - /* CRC32 verified packet */ - if (packet->id.flags & CSP_FCRC32) { -#if (CSP_USE_CRC32) - /* Verify CRC32 (does not include header for backwards compatability with csp1.x) */ - if (csp_crc32_verify(packet, false) != CSP_ERR_NONE) { - csp_log_error("CRC32 verification error! Discarding packet"); - iface->rx_error++; - return CSP_ERR_CRC32; - } -#else - /* No CRC32 validation - but size must be checked and adjusted */ - if (packet->length < sizeof(uint32_t)) { - csp_log_error("CRC32 verification error! Discarding packet"); - iface->rx_error++; - return CSP_ERR_CRC32; - } - packet->length -= sizeof(uint32_t); -#endif - } else if (security_opts & CSP_SO_CRC32REQ) { - csp_log_warn("Received packet with CRC32, but CSP was compiled without CRC32 support. Accepting packet"); - } - -#if (CSP_USE_HMAC) - /* HMAC authenticated packet */ - if (packet->id.flags & CSP_FHMAC) { - /* Verify HMAC (does not include header for backwards compatability with csp1.x) */ - if (csp_hmac_verify(packet, false) != CSP_ERR_NONE) { - /* HMAC failed */ - csp_log_error("HMAC verification error! Discarding packet"); - iface->autherr++; - return CSP_ERR_HMAC; - } - } else if (security_opts & CSP_SO_HMACREQ) { - csp_log_warn("Received packet without HMAC. Discarding packet"); - iface->autherr++; - return CSP_ERR_HMAC; - } -#endif - -#if (CSP_USE_RDP) - /* RDP packet */ - if (!(packet->id.flags & CSP_FRDP)) { - if (security_opts & CSP_SO_RDPREQ) { - csp_log_warn("Received packet without RDP header. Discarding packet"); - iface->rx_error++; - return CSP_ERR_INVAL; - } - } -#endif - - return CSP_ERR_NONE; - -} - -int csp_route_work(uint32_t timeout) { - - csp_qfifo_t input; - csp_packet_t * packet; - csp_conn_t * conn; - csp_socket_t * socket; - -#if (CSP_USE_RDP) - /* Check connection timeouts (currently only for RDP) */ - csp_conn_check_timeouts(); -#endif - - /* Get next packet to route */ - if (csp_qfifo_read(&input) != CSP_ERR_NONE) { - return CSP_ERR_TIMEDOUT; - } - - packet = input.packet; - if (packet == NULL) { - return CSP_ERR_TIMEDOUT; - } - - csp_log_packet("INP: S %u, D %u, Dp %u, Sp %u, Pr %u, Fl 0x%02X, Sz %"PRIu16" VIA: %s", - packet->id.src, packet->id.dst, packet->id.dport, - packet->id.sport, packet->id.pri, packet->id.flags, packet->length, input.iface->name); - - /* Here there be promiscuous mode */ -#if (CSP_USE_PROMISC) - csp_promisc_add(packet); -#endif - -#if (CSP_USE_DEDUP) - /* Check for duplicates */ - if (csp_dedup_is_duplicate(packet)) { - /* Discard packet */ - csp_log_packet("Duplicate packet discarded"); - input.iface->drop++; - csp_buffer_free(packet); - return CSP_ERR_NONE; - } -#endif - - /* Now we count the message (since its deduplicated) */ - input.iface->rx++; - input.iface->rxbytes += packet->length; - - /* If the message is not to me, route the message to the correct interface */ - if ((packet->id.dst != csp_conf.address) && (packet->id.dst != CSP_BROADCAST_ADDR)) { - - /* Find the destination interface */ - const csp_route_t * ifroute = csp_rtable_find_route(packet->id.dst); - - /* If the message resolves to the input interface, don't loop it back out */ - if ((ifroute == NULL) || ((ifroute->iface == input.iface) && (input.iface->split_horizon_off == 0))) { - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - - /* Otherwise, actually send the message */ - if (csp_send_direct(packet->id, packet, ifroute, 0) != CSP_ERR_NONE) { - csp_log_warn("Router failed to send"); - csp_buffer_free(packet); - } - - /* Next message, please */ - return CSP_ERR_NONE; - } - - /* Discard packets with unsupported options */ - if (csp_route_check_options(input.iface, packet) != CSP_ERR_NONE) { - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - - /* The message is to me, search for incoming socket */ - socket = csp_port_get_socket(packet->id.dport); - - /* If the socket is connection-less, deliver now */ - if (socket && (socket->opts & CSP_SO_CONN_LESS)) { - if (csp_route_security_check(socket->opts, input.iface, packet) < 0) { - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - if (csp_queue_enqueue(socket->socket, &packet, 0) != CSP_QUEUE_OK) { - csp_log_error("Conn-less socket queue full"); - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - return CSP_ERR_NONE; - } - - /* Search for an existing connection */ - conn = csp_conn_find(packet->id.ext, CSP_ID_CONN_MASK); - - /* If this is an incoming packet on a new connection */ - if (conn == NULL) { - - /* Reject packet if no matching socket is found */ - if (!socket) { - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - - /* Run security check on incoming packet */ - if (csp_route_security_check(socket->opts, input.iface, packet) < 0) { - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - - /* New incoming connection accepted */ - csp_id_t idout; - idout.pri = packet->id.pri; - idout.src = csp_conf.address; - - idout.dst = packet->id.src; - idout.dport = packet->id.sport; - idout.sport = packet->id.dport; - idout.flags = packet->id.flags; - - /* Create connection */ - conn = csp_conn_new(packet->id, idout); - - if (!conn) { - csp_log_error("No more connections available"); - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - - /* Store the socket queue and options */ - conn->socket = socket->socket; - conn->opts = socket->opts; - - /* Packet to existing connection */ - } else { - - /* Run security check on incoming packet */ - if (csp_route_security_check(conn->opts, input.iface, packet) < 0) { - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - - } - -#if (CSP_USE_RDP) - /* Pass packet to RDP module */ - if (packet->id.flags & CSP_FRDP) { - bool close_connection = csp_rdp_new_packet(conn, packet); - if (close_connection) { - csp_close(conn); - } - return CSP_ERR_NONE; - } -#endif - - /* Pass packet to UDP module */ - csp_udp_new_packet(conn, packet); - return CSP_ERR_NONE; -} - -static CSP_DEFINE_TASK(csp_task_router) { - - /* Here there be routing */ - while (1) { - csp_route_work(FIFO_TIMEOUT); - } - - return CSP_TASK_RETURN; - -} - -int csp_route_start_task(unsigned int task_stack_size, unsigned int task_priority) { - - int ret = csp_thread_create(csp_task_router, "RTE", task_stack_size, NULL, task_priority, NULL); - if (ret != 0) { - csp_log_error("Failed to start router task, error: %d", ret); - return ret; - } - - return CSP_ERR_NONE; - -} diff --git a/Program/libcsp/src/csp_service_handler.c b/Program/libcsp/src/csp_service_handler.c deleted file mode 100755 index e020fb8..0000000 --- a/Program/libcsp/src/csp_service_handler.c +++ /dev/null @@ -1,338 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "csp_init.h" - -#define CSP_RPS_MTU 196 - -/** - * The CSP CMP mempy function is used to, override the function used to - * read/write memory by peek and poke. - */ -#ifdef __AVR__ -static uint32_t wrap_32bit_memcpy(uint32_t to, const uint32_t from, size_t size) { - return (uint32_t) (uintptr_t) memcpy((void *) (uintptr_t) to, (const void *) (uintptr_t) from, size); -} -static csp_memcpy_fnc_t csp_cmp_memcpy_fnc = wrap_32bit_memcpy; -#else -static csp_memcpy_fnc_t csp_cmp_memcpy_fnc = (csp_memcpy_fnc_t) memcpy; -#endif - - -void csp_cmp_set_memcpy(csp_memcpy_fnc_t fnc) { - csp_cmp_memcpy_fnc = fnc; -} - -static int do_cmp_ident(struct csp_cmp_message *cmp) { - - /* Copy revision */ - strncpy(cmp->ident.revision, csp_conf.revision, CSP_CMP_IDENT_REV_LEN); - cmp->ident.revision[CSP_CMP_IDENT_REV_LEN - 1] = '\0'; - - /* Copy compilation date */ - strncpy(cmp->ident.date, __DATE__, CSP_CMP_IDENT_DATE_LEN); - cmp->ident.date[CSP_CMP_IDENT_DATE_LEN - 1] = '\0'; - - /* Copy compilation time */ - strncpy(cmp->ident.time, __TIME__, CSP_CMP_IDENT_TIME_LEN); - cmp->ident.time[CSP_CMP_IDENT_TIME_LEN - 1] = '\0'; - - /* Copy hostname */ - strncpy(cmp->ident.hostname, csp_conf.hostname, CSP_HOSTNAME_LEN); - cmp->ident.hostname[CSP_HOSTNAME_LEN - 1] = '\0'; - - /* Copy model name */ - strncpy(cmp->ident.model, csp_conf.model, CSP_MODEL_LEN); - cmp->ident.model[CSP_MODEL_LEN - 1] = '\0'; - - return CSP_ERR_NONE; - -} - -static int do_cmp_route_set(struct csp_cmp_message *cmp) { - - csp_iface_t *ifc = csp_iflist_get_by_name(cmp->route_set.interface); - if (ifc == NULL) { - return CSP_ERR_INVAL; - } - - if (csp_route_set(cmp->route_set.dest_node, ifc, cmp->route_set.next_hop_via) != CSP_ERR_NONE) { - return CSP_ERR_INVAL; - } - - return CSP_ERR_NONE; - -} - -static int do_cmp_if_stats(struct csp_cmp_message *cmp) { - - csp_iface_t *ifc = csp_iflist_get_by_name(cmp->if_stats.interface); - if (ifc == NULL) - return CSP_ERR_INVAL; - - cmp->if_stats.tx = csp_hton32(ifc->tx); - cmp->if_stats.rx = csp_hton32(ifc->rx); - cmp->if_stats.tx_error = csp_hton32(ifc->tx_error); - cmp->if_stats.rx_error = csp_hton32(ifc->rx_error); - cmp->if_stats.drop = csp_hton32(ifc->drop); - cmp->if_stats.autherr = csp_hton32(ifc->autherr); - cmp->if_stats.frame = csp_hton32(ifc->frame); - cmp->if_stats.txbytes = csp_hton32(ifc->txbytes); - cmp->if_stats.rxbytes = csp_hton32(ifc->rxbytes); - cmp->if_stats.irq = csp_hton32(ifc->irq); - - return CSP_ERR_NONE; -} - -static int do_cmp_peek(struct csp_cmp_message *cmp) { - - cmp->peek.addr = csp_hton32(cmp->peek.addr); - if (cmp->peek.len > CSP_CMP_PEEK_MAX_LEN) - return CSP_ERR_INVAL; - - /* Dangerous, you better know what you are doing */ - csp_cmp_memcpy_fnc((csp_memptr_t) (uintptr_t) cmp->peek.data, (csp_memptr_t) (uintptr_t) cmp->peek.addr, cmp->peek.len); - - return CSP_ERR_NONE; - -} - -static int do_cmp_poke(struct csp_cmp_message *cmp) { - - cmp->poke.addr = csp_hton32(cmp->poke.addr); - if (cmp->poke.len > CSP_CMP_POKE_MAX_LEN) - return CSP_ERR_INVAL; - - /* Extremely dangerous, you better know what you are doing */ - csp_cmp_memcpy_fnc((csp_memptr_t) (uintptr_t) cmp->poke.addr, (csp_memptr_t) (uintptr_t) cmp->poke.data, cmp->poke.len); - - return CSP_ERR_NONE; - -} - -static int do_cmp_clock(struct csp_cmp_message *cmp) { - - csp_timestamp_t clock; - clock.tv_sec = csp_ntoh32(cmp->clock.tv_sec); - clock.tv_nsec = csp_ntoh32(cmp->clock.tv_nsec); - - int res = CSP_ERR_NONE; - if (clock.tv_sec != 0) { - // set time - res = csp_clock_set_time(&clock); - if (res != CSP_ERR_NONE) { - csp_log_warn("csp_clock_set_time(sec=%"PRIu32", nsec=%"PRIu32") failed, error: %d", clock.tv_sec, clock.tv_nsec, res); - } - } - - csp_clock_get_time(&clock); - - cmp->clock.tv_sec = csp_hton32(clock.tv_sec); - cmp->clock.tv_nsec = csp_hton32(clock.tv_nsec); - - return res; - -} - -/* CSP Management Protocol handler */ -static int csp_cmp_handler(csp_conn_t * conn, csp_packet_t * packet) { - - int ret = CSP_ERR_INVAL; - struct csp_cmp_message * cmp = (struct csp_cmp_message *) packet->data; - - /* Ignore everything but requests */ - if (cmp->type != CSP_CMP_REQUEST) - return ret; - - switch (cmp->code) { - case CSP_CMP_IDENT: - ret = do_cmp_ident(cmp); - packet->length = CMP_SIZE(ident); - break; - - case CSP_CMP_ROUTE_SET: - ret = do_cmp_route_set(cmp); - packet->length = CMP_SIZE(route_set); - break; - - case CSP_CMP_IF_STATS: - ret = do_cmp_if_stats(cmp); - packet->length = CMP_SIZE(if_stats); - break; - - case CSP_CMP_PEEK: - ret = do_cmp_peek(cmp); - break; - - case CSP_CMP_POKE: - ret = do_cmp_poke(cmp); - break; - - case CSP_CMP_CLOCK: - ret = do_cmp_clock(cmp); - break; - - default: - ret = CSP_ERR_INVAL; - break; - } - - cmp->type = CSP_CMP_REPLY; - - return ret; -} - -void csp_service_handler(csp_conn_t * conn, csp_packet_t * packet) { - - switch (csp_conn_dport(conn)) { - - case CSP_CMP: - /* Pass to CMP handler */ - if (csp_cmp_handler(conn, packet) != CSP_ERR_NONE) { - csp_buffer_free(packet); - return; - } - break; - - case CSP_PING: - /* A ping means, just echo the packet, so no changes */ - csp_log_info("SERVICE: Ping received"); - break; - - case CSP_PS: { - /* Sanity check on request */ - if ((packet->length != 1) || (packet->data[0] != 0x55)) { - /* Sanity check failed */ - csp_buffer_free(packet); - /* Clear the packet, it has been freed */ - packet = NULL; - break; - } - /* Start by allocating just the right amount of memory */ - int task_list_size = csp_sys_tasklist_size(); - char * pslist = csp_malloc(task_list_size); - /* Check for malloc fail */ - if (pslist == NULL) { - /* Send out the data */ - strcpy((char *)packet->data, "Not enough memory"); - packet->length = strlen((char *)packet->data); - /* Break and let the default handling send packet */ - break; - } - - /* Retrieve the tasklist */ - csp_sys_tasklist(pslist); - int pslen = strnlen(pslist, task_list_size); - - /* Split the potentially very long string into packets */ - int i = 0; - while(i < pslen) { - - /* Allocate packet buffer, if need be */ - if (packet == NULL) - packet = csp_buffer_get(CSP_RPS_MTU); - if (packet == NULL) - break; - - /* Calculate length, either full MTU or the remainder */ - packet->length = (pslen - i > CSP_RPS_MTU) ? CSP_RPS_MTU : (pslen - i); - - /* Send out the data */ - memcpy(packet->data, &pslist[i], packet->length); - i += packet->length; - if (!csp_send(conn, packet, 0)) - csp_buffer_free(packet); - - /* Clear the packet reference when sent */ - packet = NULL; - - } - csp_free(pslist); - break; - } - - case CSP_MEMFREE: { - uint32_t total = csp_sys_memfree(); - - total = csp_hton32(total); - memcpy(packet->data, &total, sizeof(total)); - packet->length = sizeof(total); - - break; - } - - case CSP_REBOOT: { - uint32_t magic_word; - memcpy(&magic_word, packet->data, sizeof(magic_word)); - - magic_word = csp_ntoh32(magic_word); - - /* If the magic word is valid, reboot */ - if (magic_word == CSP_REBOOT_MAGIC) { - csp_sys_reboot(); - } else if (magic_word == CSP_REBOOT_SHUTDOWN_MAGIC) { - csp_sys_shutdown(); - } - - csp_buffer_free(packet); - return; - } - - case CSP_BUF_FREE: { - uint32_t size = csp_buffer_remaining(); - size = csp_hton32(size); - memcpy(packet->data, &size, sizeof(size)); - packet->length = sizeof(size); - break; - } - - case CSP_UPTIME: { - uint32_t time = csp_get_uptime_s(); - time = csp_hton32(time); - memcpy(packet->data, &time, sizeof(time)); - packet->length = sizeof(time); - break; - } - - default: - csp_buffer_free(packet); - return; - } - - if (packet != NULL) { - if (!csp_send(conn, packet, 0)) - csp_buffer_free(packet); - } - -} diff --git a/Program/libcsp/src/csp_services.c b/Program/libcsp/src/csp_services.c deleted file mode 100755 index 9c29861..0000000 --- a/Program/libcsp/src/csp_services.c +++ /dev/null @@ -1,254 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -#include -#include -#include - -int csp_ping(uint8_t node, uint32_t timeout, unsigned int size, uint8_t conn_options) { - - unsigned int i; - uint32_t start, time, status = 0; - - /* Counter */ - start = csp_get_ms(); - - /* Open connection */ - csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, node, CSP_PING, timeout, conn_options); - if (conn == NULL) - return -1; - - /* Prepare data */ - csp_packet_t * packet = csp_buffer_get(size); - if (packet == NULL) - goto out; - - /* Set data to increasing numbers */ - packet->length = size; - for (i = 0; i < size; i++) - packet->data[i] = i; - - /* Try to send frame */ - if (!csp_send(conn, packet, 0)) - goto out; - - /* Read incoming frame */ - packet = csp_read(conn, timeout); - if (packet == NULL) - goto out; - - /* Ensure that the data was actually echoed */ - for (i = 0; i < size; i++) { - if (packet->data[i] != i % (0xff + 1)) { - goto out; - } - } - status = 1; - -out: - /* Clean up */ - csp_buffer_free(packet); - csp_close(conn); - - /* We have a reply */ - time = (csp_get_ms() - start); - - if (status) { - return time; - } - - return -1; -} - -void csp_ping_noreply(uint8_t node) { - - /* Prepare data */ - csp_packet_t * packet = csp_buffer_get(1); - if (packet == NULL) - return; - - /* Open connection */ - csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, node, CSP_PING, 0, 0); - if (conn == NULL) { - csp_buffer_free(packet); - return; - } - - packet->data[0] = 0x55; - packet->length = 1; - - printf("Ping ignore reply node %u.\r\n", (unsigned int) node); - - /* Try to send frame */ - if (!csp_send(conn, packet, 0)) - csp_buffer_free(packet); - - csp_close(conn); - -} - -void csp_reboot(uint8_t node) { - uint32_t magic_word = csp_hton32(CSP_REBOOT_MAGIC); - csp_transaction(CSP_PRIO_NORM, node, CSP_REBOOT, 0, &magic_word, sizeof(magic_word), NULL, 0); -} - -void csp_shutdown(uint8_t node) { - uint32_t magic_word = csp_hton32(CSP_REBOOT_SHUTDOWN_MAGIC); - csp_transaction(CSP_PRIO_NORM, node, CSP_REBOOT, 0, &magic_word, sizeof(magic_word), NULL, 0); -} - -void csp_ps(uint8_t node, uint32_t timeout) { - - /* Open connection */ - csp_conn_t * conn = csp_connect(CSP_PRIO_NORM, node, CSP_PS, 0, 0); - if (conn == NULL) { - return; - } - - /* Prepare data */ - csp_packet_t * packet = csp_buffer_get(95); - - /* Check malloc */ - if (packet == NULL) { - goto out; - } - - packet->data[0] = 0x55; - packet->length = 1; - - printf("PS node %u: \r\n", node); - - /* Try to send frame */ - if (!csp_send(conn, packet, 0)) { - goto out; - } - - while(1) { - - /* Read incoming frame */ - packet = csp_read(conn, timeout); - if (packet == NULL) { - break; - } - - /* We have a reply, ensure data is 0 (zero) termianted */ - const unsigned int length = (packet->length < csp_buffer_data_size()) ? packet->length : (csp_buffer_data_size() - 1); - packet->data[length] = 0; - printf("%s", packet->data); - - /* Each packet from csp_read must to be freed by user */ - csp_buffer_free(packet); - } - - printf("\r\n"); - - /* Clean up */ -out: - csp_buffer_free(packet); - csp_close(conn); - -} - -int csp_get_memfree(uint8_t node, uint32_t timeout, uint32_t * size) { - - int status = csp_transaction(CSP_PRIO_NORM, node, CSP_MEMFREE, timeout, NULL, 0, size, sizeof(*size)); - if (status == sizeof(*size)) { - *size = csp_ntoh32(*size); - return CSP_ERR_NONE; - } - *size = 0; - return CSP_ERR_TIMEDOUT; - -} - -void csp_memfree(uint8_t node, uint32_t timeout) { - - uint32_t memfree; - int err = csp_get_memfree(node, timeout, &memfree); - if (err == CSP_ERR_NONE) { - printf("Free Memory at node %u is %"PRIu32" bytes\r\n", node, memfree); - } else { - printf("Network error\r\n"); - } - -} - -int csp_get_buf_free(uint8_t node, uint32_t timeout, uint32_t * size) { - - int status = csp_transaction(CSP_PRIO_NORM, node, CSP_BUF_FREE, timeout, NULL, 0, size, sizeof(*size)); - if (status == sizeof(*size)) { - *size = csp_ntoh32(*size); - return CSP_ERR_NONE; - } - *size = 0; - return CSP_ERR_TIMEDOUT; - -} - -void csp_buf_free(uint8_t node, uint32_t timeout) { - - uint32_t size; - int err = csp_get_buf_free(node, timeout, &size); - if (err == CSP_ERR_NONE) { - printf("Free buffers at node %u is %"PRIu32"\r\n", node, size); - } else { - printf("Network error\r\n"); - } - -} - -int csp_get_uptime(uint8_t node, uint32_t timeout, uint32_t * uptime) { - - int status = csp_transaction(CSP_PRIO_NORM, node, CSP_UPTIME, timeout, NULL, 0, uptime, sizeof(*uptime)); - if (status == sizeof(*uptime)) { - *uptime = csp_ntoh32(*uptime); - return CSP_ERR_NONE; - } - *uptime = 0; - return CSP_ERR_TIMEDOUT; -} - -void csp_uptime(uint8_t node, uint32_t timeout) { - - uint32_t uptime; - int err = csp_get_uptime(node, timeout, &uptime); - if (err == CSP_ERR_NONE) { - printf("Uptime of node %u is %"PRIu32" s\r\n", node, uptime); - } else { - printf("Network error\r\n"); - } - -} - -int csp_cmp(uint8_t node, uint32_t timeout, uint8_t code, int msg_size, struct csp_cmp_message * msg) { - msg->type = CSP_CMP_REQUEST; - msg->code = code; - int status = csp_transaction(CSP_PRIO_NORM, node, CSP_CMP, timeout, msg, msg_size, msg, msg_size); - if (status == 0) { - return CSP_ERR_TIMEDOUT; - } - - return CSP_ERR_NONE; -} - diff --git a/Program/libcsp/src/csp_sfp.c b/Program/libcsp/src/csp_sfp.c deleted file mode 100755 index 54e3504..0000000 --- a/Program/libcsp/src/csp_sfp.c +++ /dev/null @@ -1,229 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include - -#include "csp_conn.h" - -typedef struct __attribute__((__packed__)) { - uint32_t offset; - uint32_t totalsize; -} sfp_header_t; - -/** - * SFP Headers: - * The following functions are helper functions that handles the extra SFP - * information that needs to be appended to all data packets. - */ -static inline sfp_header_t * csp_sfp_header_add(csp_packet_t * packet) { - - sfp_header_t * header = (sfp_header_t *) &packet->data[packet->length]; - packet->length += sizeof(*header); - return header; -} - -static inline sfp_header_t * csp_sfp_header_remove(csp_packet_t * packet) { - - if ((packet->id.flags & CSP_FFRAG) == 0) { - return NULL; - } - sfp_header_t * header; - if (packet->length < sizeof(*header)) { - return NULL; - } - header = (sfp_header_t *) &packet->data[packet->length - sizeof(*header)]; - packet->length -= sizeof(*header); - - header->offset = csp_ntoh32(header->offset); - header->totalsize = csp_ntoh32(header->totalsize); - - if (header->offset > header->totalsize) { - return NULL; - } - - return header; -} - -int csp_sfp_send_own_memcpy(csp_conn_t * conn, const void * data, unsigned int totalsize, unsigned int mtu, uint32_t timeout, csp_memcpy_fnc_t memcpyfcn) { - if (mtu == 0) { - return CSP_ERR_INVAL; - } - - unsigned int count = 0; - while(count < totalsize) { - - sfp_header_t * sfp_header; - - /* Allocate packet */ - csp_packet_t * packet = csp_buffer_get(mtu + sizeof(*sfp_header)); - if (packet == NULL) { - return CSP_ERR_NOMEM; - } - - /* Calculate sending size */ - unsigned int size = totalsize - count; - if (size > mtu) { - size = mtu; - } - - /* Print debug */ - csp_log_protocol("%s: %d:%d, sending at %p size %u", - __FUNCTION__, csp_conn_src(conn), csp_conn_sport(conn), - ((uint8_t*)data) + count, size); - - /* Copy data */ - (memcpyfcn)((csp_memptr_t)(uintptr_t)packet->data, (csp_memptr_t)(uintptr_t)(((uint8_t*)data) + count), size); - packet->length = size; - - /* Set fragment flag */ - conn->idout.flags |= CSP_FFRAG; - - /* Add SFP header */ - sfp_header = csp_sfp_header_add(packet); // no check, because buffer was allocated with extra size. - sfp_header->totalsize = csp_hton32(totalsize); - sfp_header->offset = csp_hton32(count); - - /* Send data */ - if (!csp_send(conn, packet, timeout)) { - csp_buffer_free(packet); - return CSP_ERR_TX; - } - - /* Increment count */ - count += size; - - } - - return CSP_ERR_NONE; - -} - -int csp_sfp_recv_fp(csp_conn_t * conn, void ** return_data, int * return_datasize, uint32_t timeout, csp_packet_t * first_packet) { - - *return_data = NULL; /* Allow caller to assume csp_free() can always be called when dataout is non-NULL */ - *return_datasize = 0; - - /* Get first packet from user, or from connection */ - csp_packet_t * packet; - if (first_packet == NULL) { - packet = csp_read(conn, timeout); - if (packet == NULL) { - return CSP_ERR_TIMEDOUT; - } - } else { - packet = first_packet; - } - - uint8_t * data = NULL; - uint32_t datasize = 0; - uint32_t data_offset = 0; - int error = CSP_ERR_TIMEDOUT; - do { - /* Read SFP header */ - sfp_header_t * sfp_header = csp_sfp_header_remove(packet); - if (sfp_header == NULL) { - csp_log_warn("%s: %u:%u, invalid message, id.flags: 0x%x, length: %u", - __FUNCTION__, packet->id.src, packet->id.sport, - packet->id.flags, packet->length); - csp_buffer_free(packet); - - error = CSP_ERR_SFP; - goto error; - } - - csp_log_protocol("%s: %u:%u, fragment %"PRIu32"/%"PRIu32, - __FUNCTION__, packet->id.src, packet->id.sport, - sfp_header->offset + packet->length, sfp_header->totalsize); - - /* Consistency check */ - if (sfp_header->offset != data_offset) { - csp_log_warn("%s: %u:%u, invalid message, offset %"PRIu32" (expected %"PRIu32"), length: %u, totalsize %"PRIu32, - __FUNCTION__, packet->id.src, packet->id.sport, - sfp_header->offset, data_offset, packet->length, sfp_header->totalsize); - csp_buffer_free(packet); - - error = CSP_ERR_SFP; - goto error; - } - - /* Allocate memory */ - if (data == NULL) { - datasize = sfp_header->totalsize; - data = csp_malloc(datasize); - if (data == NULL) { - csp_log_warn("%s: %u:%u, csp_malloc(%"PRIu32") failed", - __FUNCTION__, packet->id.src, packet->id.sport, - datasize); - csp_buffer_free(packet); - - error = CSP_ERR_NOMEM; - goto error; - } - } - - /* Consistency check */ - if (((data_offset + packet->length) > datasize) || (datasize != sfp_header->totalsize)) { - csp_log_warn("%s: %u:%u, invalid size, sfp.offset: %"PRIu32", length: %u, total: %"PRIu32" / %"PRIu32"", - __FUNCTION__, packet->id.src, packet->id.sport, - sfp_header->offset, packet->length, datasize, sfp_header->totalsize); - csp_buffer_free(packet); - - error = CSP_ERR_SFP; - goto error; - } - - /* Copy data to output */ - memcpy(data + data_offset, packet->data, packet->length); - data_offset += packet->length; - - if (data_offset >= datasize) { - // transfer complete - csp_buffer_free(packet); - - *return_data = data; // must be freed by csp_free() - *return_datasize = datasize; - return CSP_ERR_NONE; - } - - /* Consistency check */ - if (packet->length == 0) { - csp_log_warn("%s: %u:%u, invalid size, sfp.offset: %"PRIu32", length: %u, total: %"PRIu32" / %"PRIu32"", - __FUNCTION__, packet->id.src, packet->id.sport, - sfp_header->offset, packet->length, datasize, sfp_header->totalsize); - csp_buffer_free(packet); - - error = CSP_ERR_SFP; - goto error; - } - - csp_buffer_free(packet); - - } while((packet = csp_read(conn, timeout)) != NULL); - -error: - csp_free(data); - return error; - -} diff --git a/Program/libcsp/src/drivers/can/can_socketcan.c b/Program/libcsp/src/drivers/can/can_socketcan.c deleted file mode 100755 index 5a554e3..0000000 --- a/Program/libcsp/src/drivers/can/can_socketcan.c +++ /dev/null @@ -1,237 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#if (CSP_HAVE_LIBSOCKETCAN) -#include -#endif - -#include -#include - -// CAN interface data, state, etc. -typedef struct { - char name[CSP_IFLIST_NAME_MAX + 1]; - csp_iface_t iface; - csp_can_interface_data_t ifdata; - pthread_t rx_thread; - int socket; -} can_context_t; - -static void socketcan_free(can_context_t * ctx) { - - if (ctx) { - if (ctx->socket >= 0) { - close(ctx->socket); - } - free(ctx); - } -} - -static void * socketcan_rx_thread(void * arg) -{ - can_context_t * ctx = arg; - - while (1) { - /* Read CAN frame */ - struct can_frame frame; - int nbytes = read(ctx->socket, &frame, sizeof(frame)); - if (nbytes < 0) { - csp_log_error("%s[%s]: read() failed, errno %d: %s", __FUNCTION__, ctx->name, errno, strerror(errno)); - continue; - } - - if (nbytes != sizeof(frame)) { - csp_log_warn("%s[%s]: Read incomplete CAN frame, size: %d, expected: %u bytes", __FUNCTION__, ctx->name, nbytes, (unsigned int) sizeof(frame)); - continue; - } - - /* Drop frames with standard id (CSP uses extended) */ - if (!(frame.can_id & CAN_EFF_FLAG)) { - continue; - } - - /* Drop error and remote frames */ - if (frame.can_id & (CAN_ERR_FLAG | CAN_RTR_FLAG)) { - csp_log_warn("%s[%s]: discarding ERR/RTR/SFF frame", __FUNCTION__, ctx->name); - continue; - } - - /* Strip flags */ - frame.can_id &= CAN_EFF_MASK; - - /* Call RX callbacsp_can_rx_frameck */ - csp_can_rx(&ctx->iface, frame.can_id, frame.data, frame.can_dlc, NULL); - } - - /* We should never reach this point */ - pthread_exit(NULL); -} - - -static int csp_can_tx_frame(void * driver_data, uint32_t id, const uint8_t * data, uint8_t dlc) -{ - if (dlc > 8) { - return CSP_ERR_INVAL; - } - - struct can_frame frame = {.can_id = id | CAN_EFF_FLAG, - .can_dlc = dlc}; - memcpy(frame.data, data, dlc); - - uint32_t elapsed_ms = 0; - can_context_t * ctx = driver_data; - while (write(ctx->socket, &frame, sizeof(frame)) != sizeof(frame)) { - if ((errno != ENOBUFS) || (elapsed_ms >= 1000)) { - csp_log_warn("%s[%s]: write() failed, errno %d: %s", __FUNCTION__, ctx->name, errno, strerror(errno)); - return CSP_ERR_TX; - } - csp_sleep_ms(5); - elapsed_ms += 5; - } - - return CSP_ERR_NONE; -} - -int csp_can_socketcan_open_and_add_interface(const char * device, const char * ifname, int bitrate, bool promisc, csp_iface_t ** return_iface) -{ - if (ifname == NULL) { - ifname = CSP_IF_CAN_DEFAULT_NAME; - } - - csp_log_info("INIT %s: device: [%s], bitrate: %d, promisc: %d", - ifname, device, bitrate, promisc); - -#if (CSP_HAVE_LIBSOCKETCAN) - /* Set interface up - this may require increased OS privileges */ - if (bitrate > 0) { - can_do_stop(device); - can_set_bitrate(device, bitrate); - can_set_restart_ms(device, 100); - can_do_start(device); - } -#endif - - can_context_t * ctx = calloc(1, sizeof(*ctx)); - if (ctx == NULL) { - return CSP_ERR_NOMEM; - } - ctx->socket = -1; - - strncpy(ctx->name, ifname, sizeof(ctx->name) - 1); - ctx->iface.name = ctx->name; - ctx->iface.interface_data = &ctx->ifdata; - ctx->iface.driver_data = ctx; - ctx->ifdata.tx_func = csp_can_tx_frame; - - /* Create socket */ - if ((ctx->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { - csp_log_error("%s[%s]: socket() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); - socketcan_free(ctx); - return CSP_ERR_INVAL; - } - - /* Locate interface */ - struct ifreq ifr; - strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); - if (ioctl(ctx->socket, SIOCGIFINDEX, &ifr) < 0) { - csp_log_error("%s[%s]: device: [%s], ioctl() failed, error: %s", __FUNCTION__, ctx->name, device, strerror(errno)); - socketcan_free(ctx); - return CSP_ERR_INVAL; - } - struct sockaddr_can addr; - memset(&addr, 0, sizeof(addr)); - /* Bind the socket to CAN interface */ - addr.can_family = AF_CAN; - addr.can_ifindex = ifr.ifr_ifindex; - if (bind(ctx->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - csp_log_error("%s[%s]: bind() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); - socketcan_free(ctx); - return CSP_ERR_INVAL; - } - - /* Set filter mode */ - if (promisc == false) { - - struct can_filter filter = {.can_id = CFP_MAKE_DST(csp_get_address()), - .can_mask = CFP_MAKE_DST((1 << CFP_HOST_SIZE) - 1)}; - - if (setsockopt(ctx->socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) { - csp_log_error("%s[%s]: setsockopt() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); - socketcan_free(ctx); - return CSP_ERR_INVAL; - } - } - - /* Add interface to CSP */ - int res = csp_can_add_interface(&ctx->iface); - if (res != CSP_ERR_NONE) { - csp_log_error("%s[%s]: csp_can_add_interface() failed, error: %d", __FUNCTION__, ctx->name, res); - socketcan_free(ctx); - return res; - } - - /* Create receive thread */ - if (pthread_create(&ctx->rx_thread, NULL, socketcan_rx_thread, ctx) != 0) { - csp_log_error("%s[%s]: pthread_create() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); - //socketcan_free(ctx); // we already added it to CSP (no way to remove it) - return CSP_ERR_NOMEM; - } - - if (return_iface) { - *return_iface = &ctx->iface; - } - - return CSP_ERR_NONE; -} - -csp_iface_t * csp_can_socketcan_init(const char * device, int bitrate, bool promisc) -{ - csp_iface_t * return_iface; - int res = csp_can_socketcan_open_and_add_interface(device, CSP_IF_CAN_DEFAULT_NAME, bitrate, promisc, &return_iface); - return (res == CSP_ERR_NONE) ? return_iface : NULL; -} - -int csp_can_socketcan_stop(csp_iface_t *iface) -{ - can_context_t * ctx = iface->driver_data; - - int error = pthread_cancel(ctx->rx_thread); - if (error != 0) { - csp_log_error("%s[%s]: pthread_cancel() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); - return CSP_ERR_DRIVER; - } - error = pthread_join(ctx->rx_thread, NULL); - if (error != 0) { - csp_log_error("%s[%s]: pthread_join() failed, error: %s", __FUNCTION__, ctx->name, strerror(errno)); - return CSP_ERR_DRIVER; - } - socketcan_free(ctx); - return CSP_ERR_NONE; -} diff --git a/Program/libcsp/src/drivers/usart/usart_kiss.c b/Program/libcsp/src/drivers/usart/usart_kiss.c deleted file mode 100755 index c57fae8..0000000 --- a/Program/libcsp/src/drivers/usart/usart_kiss.c +++ /dev/null @@ -1,86 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -#include -#include -#include - -typedef struct { - char name[CSP_IFLIST_NAME_MAX + 1]; - csp_iface_t iface; - csp_kiss_interface_data_t ifdata; - csp_usart_fd_t fd; -} kiss_context_t; - -static int kiss_driver_tx(void *driver_data, const unsigned char * data, size_t data_length) { - - kiss_context_t * ctx = driver_data; - if (csp_usart_write(ctx->fd, data, data_length) == (int) data_length) { - return CSP_ERR_NONE; - } - return CSP_ERR_TX; -} - -static void kiss_driver_rx(void * user_data, uint8_t * data, size_t data_size, void * pxTaskWoken) { - - kiss_context_t * ctx = user_data; - csp_kiss_rx(&ctx->iface, data, data_size, NULL); -} - -int csp_usart_open_and_add_kiss_interface(const csp_usart_conf_t *conf, const char * ifname, csp_iface_t ** return_iface) { - - if (ifname == NULL) { - ifname = CSP_IF_KISS_DEFAULT_NAME; - } - - csp_log_info("INIT %s: device: [%s], bitrate: %d", - ifname, conf->device, conf->baudrate); - - kiss_context_t * ctx = csp_calloc(1, sizeof(*ctx)); - if (ctx == NULL) { - return CSP_ERR_NOMEM; - } - - strncpy(ctx->name, ifname, sizeof(ctx->name) - 1); - ctx->iface.name = ctx->name; - ctx->iface.driver_data = ctx; - ctx->iface.interface_data = &ctx->ifdata; - ctx->ifdata.tx_func = kiss_driver_tx; -#if (CSP_WINDOWS) - ctx->fd = NULL; -#else - ctx->fd = -1; -#endif - - int res = csp_kiss_add_interface(&ctx->iface); - if (res == CSP_ERR_NONE) { - res = csp_usart_open(conf, kiss_driver_rx, ctx, &ctx->fd); - } - - if (return_iface) { - *return_iface = &ctx->iface; - } - - return res; -} diff --git a/Program/libcsp/src/drivers/usart/usart_linux.c b/Program/libcsp/src/drivers/usart/usart_linux.c deleted file mode 100755 index 6196a6a..0000000 --- a/Program/libcsp/src/drivers/usart/usart_linux.c +++ /dev/null @@ -1,271 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -typedef struct { - csp_usart_callback_t rx_callback; - void * user_data; - csp_usart_fd_t fd; - csp_thread_handle_t rx_thread; -} usart_context_t; - -static void * usart_rx_thread(void * arg) { - - usart_context_t * ctx = arg; - const unsigned int CBUF_SIZE = 400; - uint8_t * cbuf = malloc(CBUF_SIZE); - - // Receive loop - while (1) { - int length = read(ctx->fd, cbuf, CBUF_SIZE); - if (length <= 0) { - csp_log_error("%s: read() failed, returned: %d", __FUNCTION__, length); - exit(1); - } - ctx->rx_callback(ctx->user_data, cbuf, length, NULL); - } - return NULL; -} - -#if (0) // Unused function and no prototype in public heaaders -int getbaud(int ifd) { - struct termios termAttr; - int inputSpeed = -1; - speed_t baudRate; - tcgetattr(ifd, &termAttr); - /* Get the input speed. */ - baudRate = cfgetispeed(&termAttr); - switch (baudRate) { - case B0: - inputSpeed = 0; - break; - case B50: - inputSpeed = 50; - break; - case B110: - inputSpeed = 110; - break; - case B134: - inputSpeed = 134; - break; - case B150: - inputSpeed = 150; - break; - case B200: - inputSpeed = 200; - break; - case B300: - inputSpeed = 300; - break; - case B600: - inputSpeed = 600; - break; - case B1200: - inputSpeed = 1200; - break; - case B1800: - inputSpeed = 1800; - break; - case B2400: - inputSpeed = 2400; - break; - case B4800: - inputSpeed = 4800; - break; - case B9600: - inputSpeed = 9600; - break; - case B19200: - inputSpeed = 19200; - break; - case B38400: - inputSpeed = 38400; - break; - case B57600: - inputSpeed = 57600; - break; - case B115200: - inputSpeed = 115200; - break; - case B230400: - inputSpeed = 230400; - break; -#if (CSP_MACOSX == 0) - case B460800: - inputSpeed = 460800; - break; - case B500000: - inputSpeed = 500000; - break; - case B576000: - inputSpeed = 576000; - break; - case B921600: - inputSpeed = 921600; - break; - case B1000000: - inputSpeed = 1000000; - break; - case B1152000: - inputSpeed = 1152000; - break; - case B1500000: - inputSpeed = 1500000; - break; - case B2000000: - inputSpeed = 2000000; - break; - case B2500000: - inputSpeed = 2500000; - break; - case B3000000: - inputSpeed = 3000000; - break; - case B3500000: - inputSpeed = 3500000; - break; - case B4000000: - inputSpeed = 4000000; - break; -#endif - } - - return inputSpeed; - -} -#endif - -int csp_usart_write(csp_usart_fd_t fd, const void * data, size_t data_length) { - - if (fd >= 0) { - int res = write(fd, data, data_length); - if (res >= 0) { - return res; - } - } - return CSP_ERR_TX; // best matching CSP error code. - -} - -int csp_usart_open(const csp_usart_conf_t *conf, csp_usart_callback_t rx_callback, void * user_data, csp_usart_fd_t * return_fd) { - - int brate = 0; - switch(conf->baudrate) { - case 4800: brate=B4800; break; - case 9600: brate=B9600; break; - case 19200: brate=B19200; break; - case 38400: brate=B38400; break; - case 57600: brate=B57600; break; - case 115200: brate=B115200; break; - case 230400: brate=B230400; break; -#if (CSP_MACOSX == 0) - case 460800: brate=B460800; break; - case 500000: brate=B500000; break; - case 576000: brate=B576000; break; - case 921600: brate=B921600; break; - case 1000000: brate=B1000000; break; - case 1152000: brate=B1152000; break; - case 1500000: brate=B1500000; break; - case 2000000: brate=B2000000; break; - case 2500000: brate=B2500000; break; - case 3000000: brate=B3000000; break; - case 3500000: brate=B3500000; break; - case 4000000: brate=B4000000; break; -#endif - default: - csp_log_error("%s: Unsupported baudrate: %u", __FUNCTION__, conf->baudrate); - return CSP_ERR_INVAL; - } - - int fd = open(conf->device, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (fd < 0) { - csp_log_error("%s: failed to open device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); - return CSP_ERR_INVAL; - } - - struct termios options; - tcgetattr(fd, &options); - cfsetispeed(&options, brate); - cfsetospeed(&options, brate); - options.c_cflag |= (CLOCAL | CREAD); - options.c_cflag &= ~PARENB; - options.c_cflag &= ~CSTOPB; - options.c_cflag &= ~CSIZE; - options.c_cflag |= CS8; - options.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); - options.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON); - options.c_oflag &= ~(OCRNL | ONLCR | ONLRET | ONOCR | OFILL | OPOST); - options.c_cc[VTIME] = 0; - options.c_cc[VMIN] = 1; - /* tcsetattr() succeeds if just one attribute was changed, should read back attributes and check all has been changed */ - if (tcsetattr(fd, TCSANOW, &options) != 0) { - csp_log_error("%s: Failed to set attributes on device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); - close(fd); - return CSP_ERR_DRIVER; - } - fcntl(fd, F_SETFL, 0); - - /* Flush old transmissions */ - if (tcflush(fd, TCIOFLUSH) != 0) { - csp_log_error("%s: Error flushing device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); - close(fd); - return CSP_ERR_DRIVER; - } - - usart_context_t * ctx = calloc(1, sizeof(*ctx)); - if (ctx == NULL) { - csp_log_error("%s: Error allocating context, device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); - close(fd); - return CSP_ERR_NOMEM; - } - ctx->rx_callback = rx_callback; - ctx->user_data = user_data; - ctx->fd = fd; - - if (rx_callback) { - if (csp_thread_create(usart_rx_thread, "usart_rx", 0, ctx, 0, &ctx->rx_thread) != CSP_ERR_NONE) { - csp_log_error("%s: csp_thread_create() failed to create Rx thread for device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); - free(ctx); - close(fd); - return CSP_ERR_NOMEM; - } - } - - if (return_fd) { - *return_fd = fd; - } - - return CSP_ERR_NONE; -} diff --git a/Program/libcsp/src/drivers/usart/usart_windows.c b/Program/libcsp/src/drivers/usart/usart_windows.c deleted file mode 100755 index ff59ab7..0000000 --- a/Program/libcsp/src/drivers/usart/usart_windows.c +++ /dev/null @@ -1,173 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include -#include - -#include -#include -#include - -typedef struct { - csp_usart_callback_t rx_callback; - void * user_data; - csp_usart_fd_t fd; - HANDLE rx_thread; - LONG isListening; -} usart_context_t; - -static int openPort(const char * device, csp_usart_fd_t * return_fd) { - - *return_fd = CreateFileA(device, - GENERIC_READ|GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL); - if (*return_fd == INVALID_HANDLE_VALUE) { - csp_log_error("Failed to open port: [%s], error: %lu", device, GetLastError()); - return CSP_ERR_INVAL; - } - - return CSP_ERR_NONE; -} - -static int configurePort(csp_usart_fd_t fd, const csp_usart_conf_t * conf) { - - DCB portSettings = {0}; - portSettings.DCBlength = sizeof(portSettings); - if(!GetCommState(fd, &portSettings) ) { - csp_log_error("Could not get default settings for open COM port, error: %lu", GetLastError()); - return CSP_ERR_INVAL; - } - portSettings.BaudRate = conf->baudrate; - portSettings.Parity = conf->paritysetting; - portSettings.StopBits = conf->stopbits; - portSettings.fParity = conf->checkparity; - portSettings.fBinary = TRUE; - portSettings.ByteSize = conf->databits; - if (!SetCommState(fd, &portSettings)) { - csp_log_error("Could not configure COM port, error: %lu", GetLastError()); - return CSP_ERR_INVAL; - } - - return CSP_ERR_NONE; -} - -static int setPortTimeouts(csp_usart_fd_t fd) { - - COMMTIMEOUTS timeouts = {0}; - - if (!GetCommTimeouts(fd, &timeouts)) { - csp_log_error("Error gettings current timeout settings, error: %lu", GetLastError()); - return CSP_ERR_INVAL; - } - - timeouts.ReadIntervalTimeout = 5; - timeouts.ReadTotalTimeoutMultiplier = 1; - timeouts.ReadTotalTimeoutConstant = 5; - timeouts.WriteTotalTimeoutMultiplier = 1; - timeouts.WriteTotalTimeoutConstant = 5; - - if(!SetCommTimeouts(fd, &timeouts)) { - csp_log_error("Error setting timeout settings, error: %lu", GetLastError()); - return CSP_ERR_INVAL; - } - - return CSP_ERR_NONE; -} - -static unsigned WINAPI usart_rx_thread(void* params) { - - usart_context_t * ctx = params; - DWORD eventStatus; - uint8_t cbuf[100]; - DWORD bytesRead; - SetCommMask(ctx->fd, EV_RXCHAR); - - while (ctx->isListening) { - WaitCommEvent(ctx->fd, &eventStatus, NULL); - if (eventStatus & EV_RXCHAR) { - if (ReadFile(ctx->fd, cbuf, sizeof(cbuf), &bytesRead, NULL)) { - ctx->rx_callback(ctx->user_data, cbuf, bytesRead, NULL); - } else { - csp_log_warn("Error receiving data, error: %lu", GetLastError()); - } - } - } - return 0; -} - -int csp_usart_write(csp_usart_fd_t fd, const void * data, size_t data_length) { - - DWORD bytesActual; - if (!WriteFile(fd, data, data_length, &bytesActual, NULL)) { - return CSP_ERR_TX; - } - if( !FlushFileBuffers(fd) ) { - csp_log_warn("Could not flush write buffer. Code: %lu", GetLastError()); - } - return (int) bytesActual; -} - -int csp_usart_open(const csp_usart_conf_t *conf, csp_usart_callback_t rx_callback, void * user_data, csp_usart_fd_t * return_fd) { - - csp_usart_fd_t fd; - int res = openPort(conf->device, &fd); - if (res != CSP_ERR_NONE) { - return res; - } - - res = configurePort(fd, conf); - if (res != CSP_ERR_NONE) { - CloseHandle(fd); - return res; - } - - res = setPortTimeouts(fd); - if (res) { - CloseHandle(fd); - return res; - } - - usart_context_t * ctx = csp_calloc(1, sizeof(*ctx)); - if (ctx == NULL) { - csp_log_error("%s: Error allocating context, device: [%s], errno: %s", __FUNCTION__, conf->device, strerror(errno)); - CloseHandle(fd); - return CSP_ERR_NOMEM; - } - ctx->rx_callback = rx_callback; - ctx->user_data = user_data; - ctx->fd = fd; - ctx->isListening = 1; - - res = csp_thread_create(usart_rx_thread, "usart_rx", 0, ctx, 0, &ctx->rx_thread); - if (res) { - CloseHandle(ctx->fd); - csp_free(ctx); - return res; - } - - return CSP_ERR_NONE; -} diff --git a/Program/libcsp/src/interfaces/csp_if_can.c b/Program/libcsp/src/interfaces/csp_if_can.c deleted file mode 100755 index 5ef13e7..0000000 --- a/Program/libcsp/src/interfaces/csp_if_can.c +++ /dev/null @@ -1,275 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include - -#include -#include -#include - -#include "csp_if_can_pbuf.h" - -/* Max number of bytes per CAN frame */ -#define MAX_BYTES_IN_CAN_FRAME 8 -#define CFP_OVERHEAD (sizeof(csp_id_t) + sizeof(uint16_t)) -#define MAX_CAN_DATA_SIZE (((1 << CFP_REMAIN_SIZE) * MAX_BYTES_IN_CAN_FRAME) - CFP_OVERHEAD) - -/* CFP type */ -enum cfp_frame_t { - /* First CFP fragment of a CSP packet */ - CFP_BEGIN = 0, - /* Remaining CFP fragment(s) of a CSP packet */ - CFP_MORE = 1 -}; - -int csp_can_rx(csp_iface_t *iface, uint32_t id, const uint8_t *data, uint8_t dlc, CSP_BASE_TYPE *task_woken) -{ - /* Test: random packet loss */ - if (0) { - int random = rand(); - if (random < RAND_MAX * 0.00005) { - csp_log_warn("Dropping frame"); - return CSP_ERR_DRIVER; - } - } - - /* Bind incoming frame to a packet buffer */ - csp_can_pbuf_element_t * buf = csp_can_pbuf_find(id, CFP_ID_CONN_MASK, task_woken); - if (buf == NULL) { - if (CFP_TYPE(id) == CFP_BEGIN) { - buf = csp_can_pbuf_new(id, task_woken); - if (buf == NULL) { - //csp_log_warn("No available packet buffer for CAN"); - iface->rx_error++; - return CSP_ERR_NOMEM; - } - } else { - //csp_log_warn("Out of order id 0x%X remain %u", CFP_ID(id), CFP_REMAIN(id)); - iface->frame++; - return CSP_ERR_INVAL; - } - } - - /* Reset frame data offset */ - uint8_t offset = 0; - - switch (CFP_TYPE(id)) { - - case CFP_BEGIN: - - /* Discard packet if DLC is less than CSP id + CSP length fields */ - if (dlc < (sizeof(csp_id_t) + sizeof(uint16_t))) { - //csp_log_warn("Short BEGIN frame received"); - iface->frame++; - csp_can_pbuf_free(buf, task_woken); - break; - } - - /* Check for incomplete frame */ - if (buf->packet != NULL) { - /* Reuse the buffer */ - //csp_log_warn("Incomplete frame"); - iface->frame++; - } else { - /* Get free buffer for frame */ - buf->packet = task_woken ? csp_buffer_get_isr(0) : csp_buffer_get(0); // CSP only supports one size - if (buf->packet == NULL) { - //csp_log_error("Failed to get buffer for CSP_BEGIN packet"); - iface->frame++; - csp_can_pbuf_free(buf, task_woken); - break; - } - } - - /* Copy CSP identifier (header) */ - memcpy(&(buf->packet->id), data, sizeof(buf->packet->id)); - buf->packet->id.ext = csp_ntoh32(buf->packet->id.ext); - - /* Copy CSP length (of data) */ - memcpy(&(buf->packet->length), data + sizeof(csp_id_t), sizeof(buf->packet->length)); - buf->packet->length = csp_ntoh16(buf->packet->length); - - /* Check length against max */ - if ((buf->packet->length > MAX_CAN_DATA_SIZE) || (buf->packet->length > csp_buffer_data_size())) { - iface->rx_error++; - csp_can_pbuf_free(buf, task_woken); - break; - } - - /* Reset RX count */ - buf->rx_count = 0; - - /* Set offset to prevent CSP header from being copied to CSP data */ - offset = sizeof(csp_id_t) + sizeof(uint16_t); - - /* Set remain field - increment to include begin packet */ - buf->remain = CFP_REMAIN(id) + 1; - - /* FALLTHROUGH */ - - case CFP_MORE: - - /* Check 'remain' field match */ - if (CFP_REMAIN(id) != buf->remain - 1) { - //csp_log_error("CAN frame lost in CSP packet"); - csp_can_pbuf_free(buf, task_woken); - iface->frame++; - break; - } - - /* Decrement remaining frames */ - buf->remain--; - - /* Check for overflow */ - if ((buf->rx_count + dlc - offset) > buf->packet->length) { - //csp_log_error("RX buffer overflow"); - iface->frame++; - csp_can_pbuf_free(buf, task_woken); - break; - } - - /* Copy dlc bytes into buffer */ - memcpy(&buf->packet->data[buf->rx_count], data + offset, dlc - offset); - buf->rx_count += dlc - offset; - - /* Check if more data is expected */ - if (buf->rx_count != buf->packet->length) - break; - - /* Data is available */ - csp_qfifo_write(buf->packet, iface, task_woken); - - /* Drop packet buffer reference */ - buf->packet = NULL; - - /* Free packet buffer */ - csp_can_pbuf_free(buf, task_woken); - - break; - - default: - //csp_log_warn("Received unknown CFP message type"); - csp_can_pbuf_free(buf, task_woken); - break; - } - - return CSP_ERR_NONE; -} - -int csp_can_tx(const csp_route_t * ifroute, csp_packet_t *packet) -{ - csp_iface_t * iface = ifroute->iface; - csp_can_interface_data_t * ifdata = iface->interface_data; - - /* Get an unique CFP id - this should be locked to prevent access from multiple tasks */ - const uint32_t ident = ifdata->cfp_frame_id++; - - /* Check protocol's max length - limit is 1 (first) frame + as many frames that can be specified in 'remain' */ - if (packet->length > MAX_CAN_DATA_SIZE) { - return CSP_ERR_TX; - } - - /* Insert destination node/via address into the CFP destination field */ - const uint8_t dest = (ifroute->via != CSP_NO_VIA_ADDRESS) ? ifroute->via : packet->id.dst; - - /* Create CAN identifier */ - uint32_t id = (CFP_MAKE_SRC(packet->id.src) | - CFP_MAKE_DST(dest) | - CFP_MAKE_ID(ident) | - CFP_MAKE_TYPE(CFP_BEGIN) | - CFP_MAKE_REMAIN((packet->length + CFP_OVERHEAD - 1) / MAX_BYTES_IN_CAN_FRAME)); - - /* Calculate first frame data bytes */ - const uint8_t avail = MAX_BYTES_IN_CAN_FRAME - CFP_OVERHEAD; - uint8_t bytes = (packet->length <= avail) ? packet->length : avail; - - /* Copy CSP headers and data */ - const uint32_t csp_id_be = csp_hton32(packet->id.ext); - const uint16_t csp_length_be = csp_hton16(packet->length); - - uint8_t frame_buf[MAX_BYTES_IN_CAN_FRAME]; - memcpy(frame_buf, &csp_id_be, sizeof(csp_id_be)); - memcpy(frame_buf + sizeof(csp_id_be), &csp_length_be, sizeof(csp_length_be)); - memcpy(frame_buf + CFP_OVERHEAD, packet->data, bytes); - - /* Increment tx counter */ - uint16_t tx_count = bytes; - - const csp_can_driver_tx_t tx_func = ifdata->tx_func; - - /* Send first frame */ - if ((tx_func)(iface->driver_data, id, frame_buf, CFP_OVERHEAD + bytes) != CSP_ERR_NONE) { - //csp_log_warn("Failed to send CAN frame in csp_tx_can"); - iface->tx_error++; - return CSP_ERR_DRIVER; - } - - /* Send next frames if not complete */ - while (tx_count < packet->length) { - /* Calculate frame data bytes */ - bytes = (packet->length - tx_count >= MAX_BYTES_IN_CAN_FRAME) ? MAX_BYTES_IN_CAN_FRAME : packet->length - tx_count; - - /* Prepare identifier */ - id = (CFP_MAKE_SRC(packet->id.src) | - CFP_MAKE_DST(dest) | - CFP_MAKE_ID(ident) | - CFP_MAKE_TYPE(CFP_MORE) | - CFP_MAKE_REMAIN((packet->length - tx_count - bytes + MAX_BYTES_IN_CAN_FRAME - 1) / MAX_BYTES_IN_CAN_FRAME)); - - /* Increment tx counter */ - tx_count += bytes; - - /* Send frame */ - if ((tx_func)(iface->driver_data, id, packet->data + tx_count - bytes, bytes) != CSP_ERR_NONE) { - //csp_log_warn("Failed to send CAN frame in Tx callback"); - iface->tx_error++; - return CSP_ERR_DRIVER; - } - } - - csp_buffer_free(packet); - - return CSP_ERR_NONE; -} - -int csp_can_add_interface(csp_iface_t * iface) { - - if ((iface == NULL) || (iface->name == NULL) || (iface->interface_data == NULL)) { - return CSP_ERR_INVAL; - } - - csp_can_interface_data_t * ifdata = iface->interface_data; - if (ifdata->tx_func == NULL) { - return CSP_ERR_INVAL; - } - - if ((iface->mtu == 0) || (iface->mtu > MAX_CAN_DATA_SIZE)) { - iface->mtu = MAX_CAN_DATA_SIZE; - } - - ifdata->cfp_frame_id = 0; - - iface->nexthop = csp_can_tx; - - return csp_iflist_add(iface); -} diff --git a/Program/libcsp/src/interfaces/csp_if_can_pbuf.c b/Program/libcsp/src/interfaces/csp_if_can_pbuf.c deleted file mode 100755 index db65170..0000000 --- a/Program/libcsp/src/interfaces/csp_if_can_pbuf.c +++ /dev/null @@ -1,93 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "csp_if_can_pbuf.h" - -#include -#include -#include - -/* Number of packet buffer elements */ -#define PBUF_ELEMENTS 5 - -/* Buffer element timeout in ms */ -#define PBUF_TIMEOUT_MS 1000 - -static csp_can_pbuf_element_t csp_can_pbuf[PBUF_ELEMENTS] = {}; - -int csp_can_pbuf_free(csp_can_pbuf_element_t *buf, CSP_BASE_TYPE *task_woken) -{ - /* Free CSP packet */ - if (buf->packet != NULL) { - if (task_woken == NULL) { - csp_buffer_free(buf->packet); - } else { - csp_buffer_free_isr(buf->packet); - } - } - - /* Mark buffer element free */ - buf->packet = NULL; - buf->rx_count = 0; - buf->cfpid = 0; - buf->last_used = 0; - buf->remain = 0; - buf->state = BUF_FREE; - - return CSP_ERR_NONE; -} - -csp_can_pbuf_element_t *csp_can_pbuf_new(uint32_t id, CSP_BASE_TYPE *task_woken) -{ - uint32_t now = (task_woken) ? csp_get_ms_isr() : csp_get_ms(); - - for (int i = 0; i < PBUF_ELEMENTS; i++) { - - /* Perform cleanup in used pbufs */ - if (csp_can_pbuf[i].state == BUF_USED) { - if (now - csp_can_pbuf[i].last_used > PBUF_TIMEOUT_MS) - csp_can_pbuf_free(&csp_can_pbuf[i], task_woken); - } - - if (csp_can_pbuf[i].state == BUF_FREE) { - csp_can_pbuf[i].state = BUF_USED; - csp_can_pbuf[i].cfpid = id; - csp_can_pbuf[i].remain = 0; - csp_can_pbuf[i].last_used = now; - return &csp_can_pbuf[i]; - } - - } - - return NULL; - -} - -csp_can_pbuf_element_t *csp_can_pbuf_find(uint32_t id, uint32_t mask, CSP_BASE_TYPE *task_woken) -{ - for (int i = 0; i < PBUF_ELEMENTS; i++) { - if ((csp_can_pbuf[i].state == BUF_USED) && ((csp_can_pbuf[i].cfpid & mask) == (id & mask))) { - csp_can_pbuf[i].last_used = (task_woken) ? csp_get_ms_isr() : csp_get_ms(); - return &csp_can_pbuf[i]; - } - } - return NULL; -} - diff --git a/Program/libcsp/src/interfaces/csp_if_can_pbuf.h b/Program/libcsp/src/interfaces/csp_if_can_pbuf.h deleted file mode 100755 index 155ac8b..0000000 --- a/Program/libcsp/src/interfaces/csp_if_can_pbuf.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef LIB_CSP_SRC_INTERFACES_CSP_IF_CAN_PBUF_H_ -#define LIB_CSP_SRC_INTERFACES_CSP_IF_CAN_PBUF_H_ - -#include - -/* Packet buffers */ -typedef enum { - BUF_FREE = 0, /* Buffer element free */ - BUF_USED = 1, /* Buffer element used */ -} csp_can_pbuf_state_t; - -typedef struct { - uint16_t rx_count; /* Received bytes */ - uint32_t remain; /* Remaining packets */ - uint32_t cfpid; /* Connection CFP identification number */ - csp_packet_t *packet; /* Pointer to packet buffer */ - csp_can_pbuf_state_t state; /* Element state */ - uint32_t last_used; /* Timestamp in ms for last use of buffer */ -} csp_can_pbuf_element_t; - -int csp_can_pbuf_free(csp_can_pbuf_element_t *buf, CSP_BASE_TYPE *task_woken); -csp_can_pbuf_element_t *csp_can_pbuf_new(uint32_t id, CSP_BASE_TYPE *task_woken); -csp_can_pbuf_element_t *csp_can_pbuf_find(uint32_t id, uint32_t mask, CSP_BASE_TYPE *task_woken); -void csp_can_pbuf_cleanup(CSP_BASE_TYPE *task_woken); - -#endif diff --git a/Program/libcsp/src/interfaces/csp_if_i2c.c b/Program/libcsp/src/interfaces/csp_if_i2c.c deleted file mode 100755 index d019014..0000000 --- a/Program/libcsp/src/interfaces/csp_if_i2c.c +++ /dev/null @@ -1,112 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include -#include - -// Ensure certain fields in the csp_i2c_frame_t matches the fields in the csp_packet_t -CSP_STATIC_ASSERT(offsetof(csp_i2c_frame_t, len) == offsetof(csp_packet_t, length), len_field_misaligned); -CSP_STATIC_ASSERT(offsetof(csp_i2c_frame_t, data) == offsetof(csp_packet_t, id), data_field_misaligned); - -int csp_i2c_tx(const csp_route_t * ifroute, csp_packet_t * packet) { - - /* Cast the CSP packet buffer into an i2c frame */ - csp_i2c_frame_t * frame = (csp_i2c_frame_t *) packet; - - /* Insert destination node into the i2c destination field */ - frame->dest = (ifroute->via != CSP_NO_VIA_ADDRESS) ? ifroute->via : packet->id.dst; - - /* Save the outgoing id in the buffer */ - packet->id.ext = csp_hton32(packet->id.ext); - - /* Add the CSP header to the I2C length field */ - frame->len += sizeof(packet->id); - frame->len_rx = 0; - - /* Some I2C drivers support X number of retries - * CSP don't care about this. If it doesn't work the first - * time, don't use time on it. - */ - frame->retries = 0; - - /* send frame */ - csp_i2c_interface_data_t * ifdata = ifroute->iface->interface_data; - return (ifdata->tx_func)(ifroute->iface->driver_data, frame); - -} - -/** - * When a frame is received, cast it to a csp_packet - * and send it directly to the CSP new packet function. - * Context: ISR only - */ -void csp_i2c_rx(csp_iface_t * iface, csp_i2c_frame_t * frame, void * pxTaskWoken) { - - /* Validate input */ - if (frame == NULL) { - return; - } - - if (frame->len < sizeof(csp_id_t)) { - iface->frame++; - (pxTaskWoken != NULL) ? csp_buffer_free_isr(frame) : csp_buffer_free(frame); - return; - } - - /* Strip the CSP header off the length field before converting to CSP packet */ - frame->len -= sizeof(csp_id_t); - - if (frame->len > csp_buffer_data_size()) { // consistency check, should never happen - iface->rx_error++; - (pxTaskWoken != NULL) ? csp_buffer_free_isr(frame) : csp_buffer_free(frame); - return; - } - - /* Convert the packet from network to host order */ - csp_packet_t * packet = (csp_packet_t *) frame; - packet->id.ext = csp_ntoh32(packet->id.ext); - - /* Receive the packet in CSP */ - csp_qfifo_write(packet, iface, pxTaskWoken); - -} - -int csp_i2c_add_interface(csp_iface_t * iface) { - - if ((iface == NULL) || (iface->name == NULL) || (iface->interface_data == NULL)) { - return CSP_ERR_INVAL; - } - - csp_i2c_interface_data_t * ifdata = iface->interface_data; - if (ifdata->tx_func == NULL) { - return CSP_ERR_INVAL; - } - - const unsigned int max_data_size = csp_buffer_data_size(); - if ((iface->mtu == 0) || (iface->mtu > max_data_size)) { - iface->mtu = max_data_size; - } - - iface->nexthop = csp_i2c_tx; - - return csp_iflist_add(iface); -} diff --git a/Program/libcsp/src/interfaces/csp_if_kiss.c b/Program/libcsp/src/interfaces/csp_if_kiss.c deleted file mode 100755 index ea2e7d9..0000000 --- a/Program/libcsp/src/interfaces/csp_if_kiss.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include - -#include -#include - -#define FEND 0xC0 -#define FESC 0xDB -#define TFEND 0xDC -#define TFESC 0xDD -#define TNC_DATA 0x00 - -int csp_kiss_tx(const csp_route_t * ifroute, csp_packet_t * packet) { - - csp_kiss_interface_data_t * ifdata = ifroute->iface->interface_data; - void * driver = ifroute->iface->driver_data; - - /* Add CRC32 checksum - the MTU setting ensures there are space */ - csp_crc32_append(packet, false); - - /* Lock */ - if (csp_mutex_lock(&ifdata->lock, 1000) != CSP_MUTEX_OK) { - return CSP_ERR_TIMEDOUT; - } - - /* Save the outgoing id in the buffer */ - packet->id.ext = csp_hton32(packet->id.ext); - packet->length += sizeof(packet->id.ext); - - /* Transmit data */ - const unsigned char start[] = {FEND, TNC_DATA}; - const unsigned char esc_end[] = {FESC, TFEND}; - const unsigned char esc_esc[] = {FESC, TFESC}; - const unsigned char * data = (unsigned char *) &packet->id.ext; - ifdata->tx_func(driver, start, sizeof(start)); - for (unsigned int i = 0; i < packet->length; i++, ++data) { - if (*data == FEND) { - ifdata->tx_func(driver, esc_end, sizeof(esc_end)); - continue; - } - if (*data == FESC) { - ifdata->tx_func(driver, esc_esc, sizeof(esc_esc)); - continue; - } - ifdata->tx_func(driver, data, 1); - } - const unsigned char stop[] = {FEND}; - ifdata->tx_func(driver, stop, sizeof(stop)); - - /* Free data */ - csp_buffer_free(packet); - - /* Unlock */ - csp_mutex_unlock(&ifdata->lock); - - return CSP_ERR_NONE; -} - -/** - * Decode received data and eventually route the packet. - */ -void csp_kiss_rx(csp_iface_t * iface, const uint8_t * buf, size_t len, void * pxTaskWoken) { - - csp_kiss_interface_data_t * ifdata = iface->interface_data; - - while (len--) { - - /* Input */ - uint8_t inputbyte = *buf++; - - /* If packet was too long */ - if (ifdata->rx_length > ifdata->max_rx_length) { - //csp_log_warn("KISS RX overflow"); - iface->rx_error++; - ifdata->rx_mode = KISS_MODE_NOT_STARTED; - ifdata->rx_length = 0; - } - - switch (ifdata->rx_mode) { - - case KISS_MODE_NOT_STARTED: - - /* Skip any characters until End char detected */ - if (inputbyte != FEND) { - break; - } - - /* Try to allocate new buffer */ - if (ifdata->rx_packet == NULL) { - ifdata->rx_packet = pxTaskWoken ? csp_buffer_get_isr(0) : csp_buffer_get(0); // CSP only supports one size - } - - /* If no more memory, skip frame */ - if (ifdata->rx_packet == NULL) { - ifdata->rx_mode = KISS_MODE_SKIP_FRAME; - break; - } - - /* Start transfer */ - ifdata->rx_length = 0; - ifdata->rx_mode = KISS_MODE_STARTED; - ifdata->rx_first = true; - break; - - case KISS_MODE_STARTED: - - /* Escape char */ - if (inputbyte == FESC) { - ifdata->rx_mode = KISS_MODE_ESCAPED; - break; - } - - /* End Char */ - if (inputbyte == FEND) { - - /* Accept message */ - if (ifdata->rx_length > 0) { - - /* Check for valid length */ - if (ifdata->rx_length < CSP_HEADER_LENGTH + sizeof(uint32_t)) { - //csp_log_warn("KISS short frame skipped, len: %u", ifdata->rx_length); - iface->rx_error++; - ifdata->rx_mode = KISS_MODE_NOT_STARTED; - break; - } - - /* Count received frame */ - iface->frame++; - - /* The CSP packet length is without the header */ - ifdata->rx_packet->length = ifdata->rx_length - CSP_HEADER_LENGTH; - - /* Convert the packet from network to host order */ - ifdata->rx_packet->id.ext = csp_ntoh32(ifdata->rx_packet->id.ext); - - /* Validate CRC */ - if (csp_crc32_verify(ifdata->rx_packet, false) != CSP_ERR_NONE) { - //csp_log_warn("KISS invalid crc frame skipped, len: %u", ifdata->rx_packet->length); - iface->rx_error++; - ifdata->rx_mode = KISS_MODE_NOT_STARTED; - break; - } - - /* Send back into CSP, notice calling from task so last argument must be NULL! */ - csp_qfifo_write(ifdata->rx_packet, iface, pxTaskWoken); - ifdata->rx_packet = NULL; - ifdata->rx_mode = KISS_MODE_NOT_STARTED; - break; - - } - - /* Break after the end char */ - break; - } - - /* Skip the first char after FEND which is TNC_DATA (0x00) */ - if (ifdata->rx_first) { - ifdata->rx_first = false; - break; - } - - /* Valid data char */ - ((char *) &ifdata->rx_packet->id.ext)[ifdata->rx_length++] = inputbyte; - - break; - - case KISS_MODE_ESCAPED: - - /* Escaped escape char */ - if (inputbyte == TFESC) - ((char *) &ifdata->rx_packet->id.ext)[ifdata->rx_length++] = FESC; - - /* Escaped fend char */ - if (inputbyte == TFEND) - ((char *) &ifdata->rx_packet->id.ext)[ifdata->rx_length++] = FEND; - - /* Go back to started mode */ - ifdata->rx_mode = KISS_MODE_STARTED; - break; - - case KISS_MODE_SKIP_FRAME: - - /* Just wait for end char */ - if (inputbyte == FEND) - ifdata->rx_mode = KISS_MODE_NOT_STARTED; - - break; - - } - - } - -} - -int csp_kiss_add_interface(csp_iface_t * iface) { - - if ((iface == NULL) || (iface->name == NULL) || (iface->interface_data == NULL)) { - return CSP_ERR_INVAL; - } - - csp_kiss_interface_data_t * ifdata = iface->interface_data; - if (ifdata->tx_func == NULL) { - return CSP_ERR_INVAL; - } - - if (csp_mutex_create(&ifdata->lock) != CSP_MUTEX_OK) { - return CSP_ERR_NOMEM; - } - - ifdata->max_rx_length = CSP_HEADER_LENGTH + csp_buffer_data_size(); // CSP header + CSP data - ifdata->rx_length = 0; - ifdata->rx_mode = KISS_MODE_NOT_STARTED; - ifdata->rx_first = false; - ifdata->rx_packet = NULL; - - const unsigned int max_data_size = csp_buffer_data_size() - sizeof(uint32_t); // compensate for the added CRC32 - if ((iface->mtu == 0) || (iface->mtu > max_data_size)) { - iface->mtu = max_data_size; - } - - iface->nexthop = csp_kiss_tx; - - return csp_iflist_add(iface); -} diff --git a/Program/libcsp/src/interfaces/csp_if_lo.c b/Program/libcsp/src/interfaces/csp_if_lo.c deleted file mode 100755 index b0f4d5d..0000000 --- a/Program/libcsp/src/interfaces/csp_if_lo.c +++ /dev/null @@ -1,53 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#include "../csp_init.h" - -/** - * Loopback interface transmit function - * @param packet Packet to transmit - * @return 1 if packet was successfully transmitted, 0 on error - */ -static int csp_lo_tx(const csp_route_t * ifroute, csp_packet_t * packet) { - - /* Drop packet silently if not destined for us. This allows - * blackhole routing addresses by setting their nexthop to - * the loopback interface. - */ - if (packet->id.dst != csp_conf.address) { - /* Consume and drop packet */ - csp_buffer_free(packet); - return CSP_ERR_NONE; - } - - /* Send back into CSP, notice calling from task so last argument must be NULL! */ - csp_qfifo_write(packet, &csp_if_lo, NULL); - - return CSP_ERR_NONE; - -} - -/* Interface definition */ -csp_iface_t csp_if_lo = { - .name = CSP_IF_LOOPBACK_NAME, - .nexthop = csp_lo_tx, -}; diff --git a/Program/libcsp/src/interfaces/csp_if_zmqhub.c b/Program/libcsp/src/interfaces/csp_if_zmqhub.c deleted file mode 100755 index 1952dd3..0000000 --- a/Program/libcsp/src/interfaces/csp_if_zmqhub.c +++ /dev/null @@ -1,238 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -#if (CSP_HAVE_LIBZMQ) - -#include -#include - -#include -#include -#include -#include -#include - -#define CSP_ZMQ_MTU 1024 // max payload data, see documentation - -/* ZMQ driver & interface */ -typedef struct { - csp_thread_handle_t rx_thread; - void * context; - void * publisher; - void * subscriber; - csp_bin_sem_handle_t tx_wait; - char name[CSP_IFLIST_NAME_MAX + 1]; - csp_iface_t iface; -} zmq_driver_t; - -/** - * Interface transmit function - * @param packet Packet to transmit - * @return 1 if packet was successfully transmitted, 0 on error - */ -int csp_zmqhub_tx(const csp_route_t * route, csp_packet_t * packet) { - - zmq_driver_t * drv = route->iface->driver_data; - - const uint8_t dest = (route->via != CSP_NO_VIA_ADDRESS) ? route->via : packet->id.dst; - - uint16_t length = packet->length; - uint8_t * destptr = ((uint8_t *) &packet->id) - sizeof(dest); - memcpy(destptr, &dest, sizeof(dest)); - csp_bin_sem_wait(&drv->tx_wait, 1000); /* Using ZMQ in thread safe manner*/ - int result = zmq_send(drv->publisher, destptr, length + sizeof(packet->id) + sizeof(dest), 0); - csp_bin_sem_post(&drv->tx_wait); /* Release tx semaphore */ - if (result < 0) { - csp_log_error("ZMQ send error: %u %s\r\n", result, zmq_strerror(zmq_errno())); - } - - csp_buffer_free(packet); - - return CSP_ERR_NONE; - -} - -CSP_DEFINE_TASK(csp_zmqhub_task) { - - zmq_driver_t * drv = param; - csp_packet_t * packet; - const uint32_t HEADER_SIZE = (sizeof(packet->id) + sizeof(uint8_t)); - - //csp_log_info("RX %s started", drv->iface.name); - - while(1) { - zmq_msg_t msg; - assert(zmq_msg_init_size(&msg, CSP_ZMQ_MTU + HEADER_SIZE) == 0); - - // Receive data - if (zmq_msg_recv(&msg, drv->subscriber, 0) < 0) { - csp_log_error("RX %s: %s", drv->iface.name, zmq_strerror(zmq_errno())); - continue; - } - - unsigned int datalen = zmq_msg_size(&msg); - if (datalen < HEADER_SIZE) { - csp_log_warn("RX %s: Too short datalen: %u - expected min %u bytes", drv->iface.name, datalen, HEADER_SIZE); - zmq_msg_close(&msg); - continue; - } - - // Create new csp packet - packet = csp_buffer_get(datalen - HEADER_SIZE); - if (packet == NULL) { - csp_log_warn("RX %s: Failed to get csp_buffer(%u)", drv->iface.name, datalen); - zmq_msg_close(&msg); - continue; - } - - // Copy the data from zmq to csp - const uint8_t * rx_data = zmq_msg_data(&msg); - - // First byte is the "via" address - ++rx_data; - --datalen; - - // Remaining is CSP header and payload - memcpy(&packet->id, rx_data, datalen); - packet->length = (datalen - sizeof(packet->id)); - - // Route packet - csp_qfifo_write(packet, &drv->iface, NULL); - - zmq_msg_close(&msg); - } - - return CSP_TASK_RETURN; - -} - -int csp_zmqhub_make_endpoint(const char * host, uint16_t port, char * buf, size_t buf_size) { - int res = snprintf(buf, buf_size, "tcp://%s:%u", host, port); - if ((res < 0) || (res >= (int)buf_size)) { - buf[0] = 0; - return CSP_ERR_NOMEM; - } - return CSP_ERR_NONE; -} - -int csp_zmqhub_init(uint8_t addr, - const char * host, - uint32_t flags, - csp_iface_t ** return_interface) { - - char pub[100]; - csp_zmqhub_make_endpoint(host, CSP_ZMQPROXY_SUBSCRIBE_PORT, pub, sizeof(pub)); - - char sub[100]; - csp_zmqhub_make_endpoint(host, CSP_ZMQPROXY_PUBLISH_PORT, sub, sizeof(sub)); - - return csp_zmqhub_init_w_endpoints(addr, pub, sub, flags, return_interface); -} - -int csp_zmqhub_init_w_endpoints(uint8_t addr, - const char * publisher_endpoint, - const char * subscriber_endpoint, - uint32_t flags, - csp_iface_t ** return_interface) { - - uint8_t * rxfilter = NULL; - unsigned int rxfilter_count = 0; - - if (addr != CSP_NO_VIA_ADDRESS) { // != 255 - rxfilter = &addr; - rxfilter_count = 1; - } - - return csp_zmqhub_init_w_name_endpoints_rxfilter(NULL, - rxfilter, rxfilter_count, - publisher_endpoint, - subscriber_endpoint, - flags, - return_interface); -} - -int csp_zmqhub_init_w_name_endpoints_rxfilter(const char * ifname, - const uint8_t rxfilter[], unsigned int rxfilter_count, - const char * publish_endpoint, - const char * subscribe_endpoint, - uint32_t flags, - csp_iface_t ** return_interface) { - - zmq_driver_t * drv = csp_calloc(1, sizeof(*drv)); - assert(drv); - - if (ifname == NULL) { - ifname = CSP_ZMQHUB_IF_NAME; - } - - strncpy(drv->name, ifname, sizeof(drv->name) - 1); - drv->iface.name = drv->name; - drv->iface.driver_data = drv; - drv->iface.nexthop = csp_zmqhub_tx; - drv->iface.mtu = CSP_ZMQ_MTU; // there is actually no 'max' MTU on ZMQ, but assuming the other end is based on the same code - - drv->context = zmq_ctx_new(); - assert(drv->context); - - csp_log_info("INIT %s: pub(tx): [%s], sub(rx): [%s], rx filters: %u", - drv->iface.name, publish_endpoint, subscribe_endpoint, rxfilter_count); - - /* Publisher (TX) */ - drv->publisher = zmq_socket(drv->context, ZMQ_PUB); - assert(drv->publisher); - - /* Subscriber (RX) */ - drv->subscriber = zmq_socket(drv->context, ZMQ_SUB); - assert(drv->subscriber); - - if (rxfilter && rxfilter_count) { - // subscribe to all 'rx_filters' -> subscribe to all packets, where the first byte (address/via) matches a rx_filter - for (unsigned int i = 0; i < rxfilter_count; ++i, ++rxfilter) { - assert(zmq_setsockopt(drv->subscriber, ZMQ_SUBSCRIBE, rxfilter, 1) == 0); - } - } else { - // subscribe to all packets - no filter - assert(zmq_setsockopt(drv->subscriber, ZMQ_SUBSCRIBE, NULL, 0) == 0); - } - - /* Connect to server */ - assert(zmq_connect(drv->publisher, publish_endpoint) == 0); - assert(zmq_connect(drv->subscriber, subscribe_endpoint) == 0); - - /* ZMQ isn't thread safe, so we add a binary semaphore to wait on for tx */ - assert(csp_bin_sem_create(&drv->tx_wait) == CSP_SEMAPHORE_OK); - - /* Start RX thread */ - assert(csp_thread_create(csp_zmqhub_task, drv->iface.name, 20000, drv, 0, &drv->rx_thread) == 0); - - /* Register interface */ - csp_iflist_add(&drv->iface); - - if (return_interface) { - *return_interface = &drv->iface; - } - - return CSP_ERR_NONE; - -} - -#endif // CSP_HAVE_LIBZMQ diff --git a/Program/libcsp/src/rtable/csp_rtable.c b/Program/libcsp/src/rtable/csp_rtable.c deleted file mode 100755 index 7fcd443..0000000 --- a/Program/libcsp/src/rtable/csp_rtable.c +++ /dev/null @@ -1,180 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_rtable_internal.h" - -#include - -#include -#include -#include - -#include "../csp_init.h" - -static int csp_rtable_parse(const char * rtable, int dry_run) { - - int valid_entries = 0; - - /* Copy string before running strtok */ - const size_t str_len = strnlen(rtable, 100); - char rtable_copy[str_len + 1]; - strncpy(rtable_copy, rtable, str_len); - rtable_copy[str_len] = 0; - - /* Get first token */ - char * saveptr; - char * str = strtok_r(rtable_copy, ",", &saveptr); - while ((str) && (strlen(str) > 1)) { - unsigned int address, netmask, via; - char name[15]; - if (sscanf(str, "%u/%u %14s %u", &address, &netmask, name, &via) == 4) { - } else if (sscanf(str, "%u/%u %14s", &address, &netmask, name) == 3) { - via = CSP_NO_VIA_ADDRESS; - } else if (sscanf(str, "%u %14s %u", &address, name, &via) == 3) { - netmask = CSP_ID_HOST_SIZE; - } else if (sscanf(str, "%u %14s", &address, name) == 2) { - netmask = CSP_ID_HOST_SIZE; - via = CSP_NO_VIA_ADDRESS; - } else { - // invalid entry - name[0] = 0; - } - name[sizeof(name) - 1] = 0; - - csp_iface_t * ifc = csp_iflist_get_by_name(name); - if ((address > CSP_ID_HOST_MAX) || (netmask > CSP_ID_HOST_SIZE) || (via > UINT8_MAX) || (ifc == NULL)) { - csp_log_error("%s: invalid entry [%s]", __FUNCTION__, str); - return CSP_ERR_INVAL; - } - - if (dry_run == 0) { - int res = csp_rtable_set(address, netmask, ifc, via); - if (res != CSP_ERR_NONE) { - csp_log_error("%s: failed to add [%s], error: %d", __FUNCTION__, str, res); - return res; - } - } - valid_entries++; - str = strtok_r(NULL, ",", &saveptr); - } - - return valid_entries; -} - -int csp_rtable_load(const char * rtable) { - return csp_rtable_parse(rtable, 0); -} - -int csp_rtable_check(const char * rtable) { - return csp_rtable_parse(rtable, 1); -} - -int csp_rtable_set(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via) { - - /* Legacy reference to default route (the old way) */ - if (address == CSP_DEFAULT_ROUTE) { - netmask = 0; - address = 0; - } - - /* Validates options */ - if (((address > CSP_ID_HOST_MAX) && (address != 255)) || (ifc == NULL) || (netmask > CSP_ID_HOST_SIZE)) { - csp_log_error("%s: invalid route: address %u, netmask %u, interface %p (%s), via %u", - __FUNCTION__, address, netmask, ifc, (ifc != NULL) ? ifc->name : "", via); - return CSP_ERR_INVAL; - } - - return csp_rtable_set_internal(address, netmask, ifc, via); -} - -typedef struct { - char * buffer; - size_t len; - size_t maxlen; - int error; -} csp_rtable_save_ctx_t; - -static bool csp_rtable_save_route(void * vctx, uint8_t address, uint8_t mask, const csp_route_t * route) -{ - csp_rtable_save_ctx_t * ctx = vctx; - - // Do not save loop back interface - if (strcasecmp(route->iface->name, CSP_IF_LOOPBACK_NAME) == 0) { - return true; - } - - const char * sep = (ctx->len == 0) ? "" : ","; - - char mask_str[10]; - if (mask != CSP_ID_HOST_SIZE) { - snprintf(mask_str, sizeof(mask_str), "/%u", mask); - } else { - mask_str[0] = 0; - } - char via_str[10]; - if (route->via != CSP_NO_VIA_ADDRESS) { - snprintf(via_str, sizeof(via_str), " %u", route->via); - } else { - via_str[0] = 0; - } - size_t remain_buf_size = ctx->maxlen - ctx->len; - int res = snprintf(ctx->buffer + ctx->len, remain_buf_size, - "%s%u%s %s%s", sep, address, mask_str, route->iface->name, via_str); - if ((res < 0) || (res >= (int)(remain_buf_size))) { - ctx->error = CSP_ERR_NOMEM; - return false; - } - ctx->len += res; - return true; -} - -int csp_rtable_save(char * buffer, size_t maxlen) -{ - csp_rtable_save_ctx_t ctx = {.len = 0, .buffer = buffer, .maxlen = maxlen, .error = CSP_ERR_NONE}; - buffer[0] = 0; - csp_rtable_iterate(csp_rtable_save_route, &ctx); - return ctx.error; -} - -void csp_rtable_clear(void) { - csp_rtable_free(); - - /* Set loopback up again */ - csp_rtable_set(csp_conf.address, CSP_ID_HOST_SIZE, &csp_if_lo, CSP_NO_VIA_ADDRESS); -} - -#if (CSP_DEBUG) - -static bool csp_rtable_print_route(void * ctx, uint8_t address, uint8_t mask, const csp_route_t * route) -{ - if (route->via == CSP_NO_VIA_ADDRESS) { - printf("%u/%u %s\r\n", address, mask, route->iface->name); - } else { - printf("%u/%u %s %u\r\n", address, mask, route->iface->name, route->via); - } - return true; -} - -void csp_rtable_print(void) -{ - csp_rtable_iterate(csp_rtable_print_route, NULL); -} - -#endif diff --git a/Program/libcsp/src/rtable/csp_rtable_cidr.c b/Program/libcsp/src/rtable/csp_rtable_cidr.c deleted file mode 100755 index 70a9e51..0000000 --- a/Program/libcsp/src/rtable/csp_rtable_cidr.c +++ /dev/null @@ -1,147 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_rtable_internal.h" - -#include -#include - -/* Definition of routing table */ -typedef struct csp_rtable_s { - csp_route_t route; - uint8_t address; - uint8_t netmask; - struct csp_rtable_s * next; -} csp_rtable_t; - -/* Routing table (linked list) */ -static csp_rtable_t * rtable = NULL; - -static csp_rtable_t * csp_rtable_find(uint8_t addr, uint8_t netmask, uint8_t exact) { - - /* Remember best result */ - csp_rtable_t * best_result = NULL; - uint8_t best_result_mask = 0; - - /* Start search */ - csp_rtable_t * i = rtable; - while(i) { - - /* Look for exact match */ - if (i->address == addr && i->netmask == netmask) { - best_result = i; - break; - } - - /* Try a CIDR netmask match */ - if (!exact) { - uint8_t hostbits = (1 << (CSP_ID_HOST_SIZE - i->netmask)) - 1; - uint8_t netbits = ~hostbits; - //printf("Netbits %x Hostbits %x\r\n", netbits, hostbits); - - /* Match network addresses */ - uint8_t net_a = i->address & netbits; - uint8_t net_b = addr & netbits; - //printf("A: %hhx, B: %hhx\r\n", net_a, net_b); - - /* We have a match */ - if (net_a == net_b) { - if (i->netmask >= best_result_mask) { - //printf("Match best result %u %u\r\n", best_result_mask, i->netmask); - best_result = i; - best_result_mask = i->netmask; - } - } - - } - - i = i->next; - - } - - if (0 && best_result) { - csp_log_packet("Using routing entry: %u/%u if %s mtu %u", - best_result->address, best_result->netmask, best_result->route.iface->name, best_result->route.via); - } - - return best_result; - -} - -const csp_route_t * csp_rtable_find_route(uint8_t dest_address) -{ - csp_rtable_t * entry = csp_rtable_find(dest_address, CSP_ID_HOST_SIZE, 0); - if (entry) { - return &entry->route; - } - return NULL; -} - -int csp_rtable_set_internal(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via) { - - /* First see if the entry exists */ - csp_rtable_t * entry = csp_rtable_find(address, netmask, 1); - - /* If not, create a new one */ - if (!entry) { - entry = csp_malloc(sizeof(*entry)); - if (entry == NULL) { - return CSP_ERR_NOMEM; - } - - entry->next = NULL; - /* Add entry to linked-list */ - if (rtable == NULL) { - /* This is the first interface to be added */ - rtable = entry; - } else { - /* One or more interfaces were already added */ - csp_rtable_t * i = rtable; - while (i->next) { - i = i->next; - } - i->next = entry; - } - } - - /* Fill in the data */ - entry->address = address; - entry->netmask = netmask; - entry->route.iface = ifc; - entry->route.via = via; - - return CSP_ERR_NONE; -} - -void csp_rtable_free(void) { - for (csp_rtable_t * i = rtable; (i);) { - void * freeme = i; - i = i->next; - csp_free(freeme); - } - rtable = NULL; -} - -void csp_rtable_iterate(csp_rtable_iterator_t iter, void * ctx) -{ - for (csp_rtable_t * route = rtable; - route && iter(ctx, route->address, route->netmask, &route->route); - route = route->next); -} diff --git a/Program/libcsp/src/rtable/csp_rtable_internal.h b/Program/libcsp/src/rtable/csp_rtable_internal.h deleted file mode 100755 index e8a236b..0000000 --- a/Program/libcsp/src/rtable/csp_rtable_internal.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include - -/* Internal set route - after common validation by csp_rtable_set(...) */ -int csp_rtable_set_internal(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via); diff --git a/Program/libcsp/src/rtable/csp_rtable_static.c b/Program/libcsp/src/rtable/csp_rtable_static.c deleted file mode 100755 index c89ee53..0000000 --- a/Program/libcsp/src/rtable/csp_rtable_static.c +++ /dev/null @@ -1,73 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_rtable_internal.h" - -#include - -/* Routing table (static array) */ -static csp_route_t rtable[CSP_DEFAULT_ROUTE + 1] = {}; - -const csp_route_t * csp_rtable_find_route(uint8_t dest_address) { - - if (rtable[dest_address].iface != NULL) { - return &rtable[dest_address]; - } - if (rtable[CSP_DEFAULT_ROUTE].iface != NULL) { - return &rtable[CSP_DEFAULT_ROUTE]; - } - return NULL; - -} - -int csp_rtable_set_internal(uint8_t address, uint8_t netmask, csp_iface_t *ifc, uint8_t via) { - - /* Validates options */ - if ((netmask != 0) && (netmask != CSP_ID_HOST_SIZE)) { - csp_log_error("%s: invalid netmask in route: address %u, netmask %u, interface %p, via %u", __FUNCTION__, address, netmask, ifc, via); - return CSP_ERR_INVAL; - } - - /* Set route */ - const unsigned int ri = (netmask == 0) ? CSP_DEFAULT_ROUTE : address; - rtable[ri].iface = ifc; - rtable[ri].via = via; - - return CSP_ERR_NONE; -} - -void csp_rtable_free(void) { - - memset(rtable, 0, sizeof(rtable)); -} - -void csp_rtable_iterate(csp_rtable_iterator_t iter, void * ctx) { - - for (unsigned int i = 0; i < CSP_DEFAULT_ROUTE; ++i) { - if (rtable[i].iface != NULL) { - if (iter(ctx, i, CSP_ID_HOST_SIZE, &rtable[i]) == false) { - return; // stopped by user - } - } - } - if (rtable[CSP_DEFAULT_ROUTE].iface) { - iter(ctx, 0, 0, &rtable[CSP_DEFAULT_ROUTE]); - } -} diff --git a/Program/libcsp/src/transport/csp_rdp.c b/Program/libcsp/src/transport/csp_rdp.c deleted file mode 100755 index bd63f96..0000000 --- a/Program/libcsp/src/transport/csp_rdp.c +++ /dev/null @@ -1,1157 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * This is a implementation of the seq/ack handling taken from the Reliable Datagram Protocol (RDP) - * For more information read RFC 908/1151. The implementation has been extended to include support for - * delayed acknowledgments, to improve performance over half-duplex links. - */ - -#include "csp_transport.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "../csp_port.h" -#include "../csp_conn.h" -#include "../csp_io.h" -#include "../csp_init.h" - -#define RDP_SYN 0x01 -#define RDP_ACK 0x02 -#define RDP_EAK 0x04 -#define RDP_RST 0x08 - -#if (CSP_USE_RDP) - -static uint32_t csp_rdp_window_size = 4; -static uint32_t csp_rdp_conn_timeout = 10000; -static uint32_t csp_rdp_packet_timeout = 1000; -static uint32_t csp_rdp_delayed_acks = 1; -static uint32_t csp_rdp_ack_timeout = 1000 / 4; -static uint32_t csp_rdp_ack_delay_count = 4 / 2; - -/* Used for queue calls */ -static CSP_BASE_TYPE pdTrue = 1; - -/* RDP header - on top of csp_packet_t */ -typedef struct { - uint32_t quarantine; // EACK quarantine period (-> csp_packet_t.padding) - uint32_t timestamp; // Time the message was sent (-> csp_packet_t.padding) - uint8_t padding[CSP_PADDING_BYTES - (2 * sizeof(uint32_t))]; - uint16_t length; // Overlay length member in csp_packet_t - csp_id_t id; // Overlay id member in csp_packet_t - uint8_t data[]; // Overlay data member in csp_packet_t -} rdp_packet_t; - -// Ensure certain fields in the rdp_packet_t matches the fields in the csp_packet_t -CSP_STATIC_ASSERT(offsetof(rdp_packet_t, length) == offsetof(csp_packet_t, length), length_field_misaligned); -CSP_STATIC_ASSERT(offsetof(rdp_packet_t, id) == offsetof(csp_packet_t, id), id_field_misaligned); -CSP_STATIC_ASSERT(offsetof(rdp_packet_t, data) == offsetof(csp_packet_t, data), data_field_misaligned); - -typedef struct __attribute__((__packed__)) { - union __attribute__((__packed__)) { - uint8_t flags; - struct __attribute__((__packed__)) { -#if (CSP_BIG_ENDIAN) - unsigned int res : 4; - unsigned int syn : 1; - unsigned int ack : 1; - unsigned int eak : 1; - unsigned int rst : 1; -#elif (CSP_LITTLE_ENDIAN) - unsigned int rst : 1; - unsigned int eak : 1; - unsigned int ack : 1; - unsigned int syn : 1; - unsigned int res : 4; -#endif - }; - }; - uint16_t seq_nr; - uint16_t ack_nr; -} rdp_header_t; - -static int csp_rdp_close_internal(csp_conn_t * conn, uint8_t closed_by, bool send_rst); - -/** - * RDP Headers: - * The following functions are helper functions that handles the extra RDP - * information that needs to be appended to all data packets. - */ -static rdp_header_t * csp_rdp_header_add(csp_packet_t * packet) { - rdp_header_t * header; - if ((packet->length + sizeof(*header)) > csp_buffer_data_size()) { - return NULL; - } - header = (rdp_header_t *) &packet->data[packet->length]; - packet->length += sizeof(*header); - memset(header, 0, sizeof(*header)); - return header; -} - -static rdp_header_t * csp_rdp_header_remove(csp_packet_t * packet) { - rdp_header_t * header = (rdp_header_t *) &packet->data[packet->length - sizeof(*header)]; - packet->length -= sizeof(*header); - return header; -} - -static rdp_header_t * csp_rdp_header_ref(csp_packet_t * packet) { - rdp_header_t * header = (rdp_header_t *) &packet->data[packet->length - sizeof(*header)]; - return header; -} - -/* Functions for comparing wrapping sequence numbers and timestamps */ - -/* Return 1 if seq is between start and end (both inclusive) */ -static inline int csp_rdp_seq_between(uint16_t seq, uint16_t start, uint16_t end) { - return (uint16_t)(end - start) >= (uint16_t)(seq - start); -} - -/* Return 1 if seq is before cmp */ -static inline int csp_rdp_seq_before(uint16_t seq, uint16_t cmp) { - return (int16_t)(seq - cmp) < 0; -} - -/* Return 1 if seq is after cmp */ -static inline int csp_rdp_seq_after(uint16_t seq, uint16_t cmp) { - return csp_rdp_seq_before(cmp, seq); -} - -/* Return 1 if time is between start and end (both inclusive) */ -//static inline int csp_rdp_time_between(uint32_t time, uint32_t start, uint32_t end) { -// return (uint32_t)(end - start) >= (uint32_t)(time - start); -//} - -/* Return 1 if time is before cmp */ -static inline int csp_rdp_time_before(uint32_t time, uint32_t cmp) { - return (int32_t)(time - cmp) < 0; -} - -/* Return 1 if time is after cmp */ -static inline int csp_rdp_time_after(uint32_t time, uint32_t cmp) { - return csp_rdp_time_before(cmp, time); -} - -/** - * CONTROL MESSAGES - * The following function is used to send empty messages, - * with ACK, SYN or RST flag. - */ -static int csp_rdp_send_cmp(csp_conn_t * conn, csp_packet_t * packet, int flags, int seq_nr, int ack_nr) { - - /* Generate message */ - if (!packet) { - packet = csp_buffer_get(20); - if (!packet) - return CSP_ERR_NOMEM; - packet->length = 0; - } - - /* Add RDP header */ - rdp_header_t * header = csp_rdp_header_add(packet); - if (header == NULL) { - csp_log_error("RDP %p: No space for RDP header (cmp)", conn); - csp_buffer_free(packet); - return CSP_ERR_NOMEM; - } - header->seq_nr = csp_hton16(seq_nr); - header->ack_nr = csp_hton16(ack_nr); - header->ack = (flags & RDP_ACK) ? 1 : 0; - header->eak = (flags & RDP_EAK) ? 1 : 0; - header->syn = (flags & RDP_SYN) ? 1 : 0; - header->rst = (flags & RDP_RST) ? 1 : 0; - - /* Send copy to tx_queue, before sending packet to IF */ - if (flags & RDP_SYN) { - rdp_packet_t * rdp_packet = csp_buffer_clone(packet); - if (rdp_packet == NULL) return CSP_ERR_NOMEM; - rdp_packet->timestamp = csp_get_ms(); - if (csp_queue_enqueue(conn->rdp.tx_queue, &rdp_packet, 0) != CSP_QUEUE_OK) - csp_buffer_free(rdp_packet); - } - - /* Send control messages with high priority */ - csp_id_t idout = conn->idout; - idout.pri = conn->idout.pri < CSP_PRIO_HIGH ? conn->idout.pri : CSP_PRIO_HIGH; - - csp_log_protocol("RDP %p: Send CMP S %u: syn %u, ack %u, eack %u, rst %u, seq_nr %5u, ack_nr %5u, packet_len %u (%u)", - conn, conn->rdp.state, header->syn, header->ack, header->eak, - header->rst, csp_ntoh16(header->seq_nr), csp_ntoh16(header->ack_nr), - packet->length, (unsigned int)(packet->length - sizeof(rdp_header_t))); - - /* Send packet to IF */ - if (csp_send_direct(idout, packet, csp_rtable_find_route(idout.dst), 0) != CSP_ERR_NONE) { - csp_log_error("RDP %p: INTERFACE ERROR: not possible to send", conn); - csp_buffer_free(packet); - return CSP_ERR_BUSY; - } - - /* Update last ACK time stamp */ - if (flags & RDP_ACK) { - conn->rdp.rcv_lsa = ack_nr; - conn->rdp.ack_timestamp = csp_get_ms(); - } - - return CSP_ERR_NONE; - -} - -/** - * EXTENDED ACKNOWLEDGEMENTS - * The following function sends an extended ACK packet - */ -static int csp_rdp_send_eack(csp_conn_t * conn) { - - /* Allocate message */ - csp_packet_t * packet_eack = csp_buffer_get(100); - if (packet_eack == NULL) return CSP_ERR_NOMEM; - packet_eack->length = 0; - - /* Loop through RX queue */ - int i, count; - csp_packet_t * packet; - count = csp_queue_size(conn->rdp.rx_queue); - for (i = 0; i < count; i++) { - - if (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) { - csp_log_error("RDP %p: Cannot dequeue from rx_queue in queue deliver", conn); - break; - } - - /* Add seq nr to EACK packet */ - rdp_header_t * header = csp_rdp_header_ref(packet); - packet_eack->data16[packet_eack->length/sizeof(uint16_t)] = csp_hton16(header->seq_nr); - packet_eack->length += sizeof(uint16_t); - csp_log_protocol("RDP %p: Added EACK nr %u", conn, header->seq_nr); - - /* Requeue */ - csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); - - } - - return csp_rdp_send_cmp(conn, packet_eack, RDP_ACK | RDP_EAK, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - -} - - -/** - * SYN Packet - * The following function sends a SYN packet - */ -static int csp_rdp_send_syn(csp_conn_t * conn) { - - /* Allocate message */ - csp_packet_t * packet = csp_buffer_get(100); - if (packet == NULL) return CSP_ERR_NOMEM; - - /* Generate contents */ - packet->data32[0] = csp_hton32(csp_rdp_window_size); - packet->data32[1] = csp_hton32(csp_rdp_conn_timeout); - packet->data32[2] = csp_hton32(csp_rdp_packet_timeout); - packet->data32[3] = csp_hton32(csp_rdp_delayed_acks); - packet->data32[4] = csp_hton32(csp_rdp_ack_timeout); - packet->data32[5] = csp_hton32(csp_rdp_ack_delay_count); - packet->length = 6 * sizeof(uint32_t); - - return csp_rdp_send_cmp(conn, packet, RDP_SYN, conn->rdp.snd_iss, 0); - -} - -static inline int csp_rdp_receive_data(csp_conn_t * conn, csp_packet_t * packet) { - - /* Remove RDP header before passing to userspace */ - csp_rdp_header_remove(packet); - - /* Enqueue data */ - if (csp_conn_enqueue_packet(conn, packet) < 0) { - csp_log_warn("RDP %p: Conn RX buffer full", conn); - return CSP_ERR_NOBUFS; - } - - return CSP_ERR_NONE; - -} - -static inline void csp_rdp_rx_queue_flush(csp_conn_t * conn) { - - /* Loop through RX queue */ - int i, count; - csp_packet_t * packet; - -front: - count = csp_queue_size(conn->rdp.rx_queue); - for (i = 0; i < count; i++) { - - if (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) { - csp_log_error("RDP %p: Cannot dequeue from rx_queue in queue deliver", conn); - break; - } - - rdp_header_t * header = csp_rdp_header_ref(packet); - csp_log_protocol("RDP %p: RX Queue deliver matching Element, seq %u", conn, header->seq_nr); - - /* If the matching packet was found: */ - if (header->seq_nr == (uint16_t)(conn->rdp.rcv_cur + 1)) { - csp_log_protocol("RDP %p: Deliver seq %u", conn, header->seq_nr); - csp_rdp_receive_data(conn, packet); - conn->rdp.rcv_cur++; - /* Loop from first element again */ - goto front; - - /* Otherwise, requeue */ - } else { - csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); - } - - } - -} - -static inline bool csp_rdp_seq_in_rx_queue(csp_conn_t * conn, uint16_t seq_nr) { - - /* Loop through RX queue */ - int i, count; - rdp_packet_t * packet; - count = csp_queue_size(conn->rdp.rx_queue); - for (i = 0; i < count; i++) { - - if (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) { - csp_log_error("RDP %p: Cannot dequeue from rx_queue in queue exists", conn); - break; - } - - csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); - - rdp_header_t * header = csp_rdp_header_ref((csp_packet_t *) packet); - csp_log_protocol("RDP %p: RX Queue exists matching Element, seq %u", conn, header->seq_nr); - - /* If the matching packet was found, deliver */ - if (header->seq_nr == seq_nr) { - csp_log_protocol("RDP %p: We have a match", conn); - return true; - } - - } - - return false; - -} - -static inline int csp_rdp_rx_queue_add(csp_conn_t * conn, csp_packet_t * packet, uint16_t seq_nr) { - - if (csp_rdp_seq_in_rx_queue(conn, seq_nr)) - return CSP_QUEUE_ERROR; - return csp_queue_enqueue_isr(conn->rdp.rx_queue, &packet, &pdTrue); - -} - -static void csp_rdp_flush_eack(csp_conn_t * conn, csp_packet_t * eack_packet) { - - /* Loop through TX queue */ - int i, j, count; - rdp_packet_t * packet; - count = csp_queue_size(conn->rdp.tx_queue); - for (i = 0; i < count; i++) { - - if (csp_queue_dequeue(conn->rdp.tx_queue, &packet, 0) != CSP_QUEUE_OK) { - csp_log_error("RDP %p: Cannot dequeue from tx_queue in flush EACK", conn); - break; - } - - rdp_header_t * header = csp_rdp_header_ref((csp_packet_t *) packet); - csp_log_protocol("RDP %p: EACK compare element, time %"PRIu32", seq %u", conn, packet->timestamp, csp_ntoh16(header->seq_nr)); - - /* Look for this element in EACKs */ - int match = 0; - for (j = 0; j < (int)((eack_packet->length - sizeof(rdp_header_t)) / sizeof(uint16_t)); j++) { - if (csp_ntoh16(eack_packet->data16[j]) == csp_ntoh16(header->seq_nr)) - match = 1; - - /* Enable this if you want EACK's to trigger retransmission */ - if (csp_ntoh16(eack_packet->data16[j]) > csp_ntoh16(header->seq_nr)) { - uint32_t time_now = csp_get_ms(); - if (csp_rdp_time_after(time_now, packet->quarantine)) { - packet->timestamp = time_now - conn->rdp.packet_timeout - 1; - packet->quarantine = time_now + conn->rdp.packet_timeout / 2; - } - } - } - - if (match == 0) { - /* If not found, put back on tx queue */ - csp_queue_enqueue(conn->rdp.tx_queue, &packet, 0); - } else { - /* Found, free */ - csp_log_protocol("RDP %p: TX Element %u freed", conn, csp_ntoh16(header->seq_nr)); - csp_buffer_free(packet); - } - - } - -} - -static inline bool csp_rdp_should_ack(csp_conn_t * conn) { - - /* If delayed ACKs are not used, always ACK */ - if (!conn->rdp.delayed_acks) { - return true; - } - - /* ACK if time since last ACK is greater than ACK timeout */ - uint32_t time_now = csp_get_ms(); - if (csp_rdp_time_after(time_now, conn->rdp.ack_timestamp + conn->rdp.ack_timeout)) - return true; - - /* ACK if number of unacknowledged packets is greater than delay count */ - if (csp_rdp_seq_after(conn->rdp.rcv_cur, conn->rdp.rcv_lsa + conn->rdp.ack_delay_count)) - return true; - - return false; - -} - -void csp_rdp_flush_all(csp_conn_t * conn) { - - if ((conn == NULL) || conn->rdp.tx_queue == NULL) { - csp_log_error("RDP %p: Null pointer passed to rdp flush all", conn); - return; - } - - rdp_packet_t * packet; - - /* Empty TX queue */ - while (csp_queue_dequeue_isr(conn->rdp.tx_queue, &packet, &pdTrue) == CSP_QUEUE_OK) { - if (packet != NULL) { - csp_log_protocol("RDP %p: Flush TX Element, time %"PRIu32", seq %u", conn, packet->timestamp, csp_ntoh16(csp_rdp_header_ref((csp_packet_t *) packet)->seq_nr)); - csp_buffer_free(packet); - } - } - - /* Empty RX queue */ - while (csp_queue_dequeue_isr(conn->rdp.rx_queue, &packet, &pdTrue) == CSP_QUEUE_OK) { - if (packet != NULL) { - csp_log_protocol("RDP %p: Flush RX Element, time %"PRIu32", seq %u", conn, packet->timestamp, csp_ntoh16(csp_rdp_header_ref((csp_packet_t *) packet)->seq_nr)); - csp_buffer_free(packet); - } - } - -} - - -int csp_rdp_check_ack(csp_conn_t * conn) { - - /* Check all RX queues for spare capacity */ - int avail = 1; - for (int prio = 0; prio < CSP_RX_QUEUES; prio++) { - if (csp_conf.conn_queue_length - csp_queue_size(conn->rx_queue[prio]) <= 2 * (int32_t)conn->rdp.window_size) { - avail = 0; - break; - } - } - - /* If more space available, only send after ack timeout or immediately if delay_acks is zero */ - if (avail && csp_rdp_should_ack(conn)) { - csp_rdp_send_cmp(conn, NULL, RDP_ACK, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - } - - return CSP_ERR_NONE; - -} - -static inline bool csp_rdp_is_conn_ready_for_tx(csp_conn_t * conn) -{ - // Check Tx window (messages waiting for acks) - if (csp_rdp_seq_after(conn->rdp.snd_nxt, conn->rdp.snd_una + conn->rdp.window_size - 1)) { - return false; - } - return true; -} - -/** - * This function must be called with regular intervals for the - * RDP protocol to work as expected. This takes care of closing - * stale connections and retransmitting traffic. A good place to - * call this function is from the CSP router task. - */ -void csp_rdp_check_timeouts(csp_conn_t * conn) { - - const uint32_t time_now = csp_get_ms(); - - /** - * CONNECTION TIMEOUT: - * Check that connection has not timed out inside the network stack - */ - if (conn->socket != NULL) { - if (csp_rdp_time_after(time_now, conn->timestamp + conn->rdp.conn_timeout)) { - csp_log_warn("RDP %p: Found a lost connection (now: %"PRIu32", ts: %"PRIu32", to: %"PRIu32"), closing", - conn, time_now, conn->timestamp, conn->rdp.conn_timeout); - csp_conn_close(conn, CSP_RDP_CLOSED_BY_USERSPACE | CSP_RDP_CLOSED_BY_PROTOCOL | CSP_RDP_CLOSED_BY_TIMEOUT); - return; - } - } - - /** - * CLOSE-WAIT TIMEOUT: - * After waiting a while in CLOSE-WAIT, the connection should be closed. - */ - if (conn->rdp.state == RDP_CLOSE_WAIT) { - if (csp_rdp_time_after(time_now, conn->timestamp + conn->rdp.conn_timeout)) { - csp_conn_close(conn, CSP_RDP_CLOSED_BY_PROTOCOL | CSP_RDP_CLOSED_BY_TIMEOUT); - } - return; - } - - /** - * MESSAGE TIMEOUT: - * Check each outgoing message for TX timeout - */ - int count = csp_queue_size(conn->rdp.tx_queue); - for (int i = 0; i < count; i++) { - - rdp_packet_t * packet; - if ((csp_queue_dequeue_isr(conn->rdp.tx_queue, &packet, &pdTrue) != CSP_QUEUE_OK) || packet == NULL) { - csp_log_warn("RDP %p: Cannot dequeue from tx_queue in check timeout", conn); - break; - } - - /* Get header */ - rdp_header_t * header = csp_rdp_header_ref((csp_packet_t *) packet); - - /* If acked, do not retransmit */ - if (csp_rdp_seq_before(csp_ntoh16(header->seq_nr), conn->rdp.snd_una)) { - csp_log_protocol("RDP %p: TX Element Free, time %"PRIu32", seq %u, una %u", conn, packet->timestamp, csp_ntoh16(header->seq_nr), conn->rdp.snd_una); - csp_buffer_free(packet); - continue; - } - - /* Check timestamp and retransmit if needed */ - if (csp_rdp_time_after(time_now, packet->timestamp + conn->rdp.packet_timeout)) { - csp_log_protocol("RDP %p: TX Element timed out, retransmitting seq %u", conn, csp_ntoh16(header->seq_nr)); - - /* Update to latest outgoing ACK */ - header->ack_nr = csp_hton16(conn->rdp.rcv_cur); - - /* Send copy to tx_queue */ - packet->timestamp = csp_get_ms(); - csp_packet_t * new_packet = csp_buffer_clone(packet); - if (csp_send_direct(conn->idout, new_packet, csp_rtable_find_route(conn->idout.dst), 0) != CSP_ERR_NONE) { - csp_log_warn("RDP %p: Retransmission failed", conn); - csp_buffer_free(new_packet); - } - - } - - /* Requeue the TX element */ - csp_queue_enqueue_isr(conn->rdp.tx_queue, &packet, &pdTrue); - - } - - if (conn->rdp.state == RDP_OPEN) { - - /* Check if we have unacknowledged segments */ - if (conn->rdp.delayed_acks) { - csp_rdp_check_ack(conn); - } - - /* Wake user task if additional Tx can be done */ - if (csp_rdp_is_conn_ready_for_tx(conn)) { - csp_log_protocol("RDP %p: Wake Tx task (check timeouts)", conn); - csp_bin_sem_post(&conn->rdp.tx_wait); - } - } -} - -bool csp_rdp_new_packet(csp_conn_t * conn, csp_packet_t * packet) { - - bool close_connection = false; - - /* Get RX header and convert to host byte-order */ - rdp_header_t * rx_header = csp_rdp_header_ref(packet); - rx_header->ack_nr = csp_ntoh16(rx_header->ack_nr); - rx_header->seq_nr = csp_ntoh16(rx_header->seq_nr); - - uint8_t closed_by = CSP_RDP_CLOSED_BY_PROTOCOL; - - csp_log_protocol("RDP %p: Received in S %u: syn %u, ack %u, eack %u, " - "rst %u, seq_nr %5u, ack_nr %5u, packet_len %u (%u)", - conn, conn->rdp.state, rx_header->syn, rx_header->ack, rx_header->eak, - rx_header->rst, rx_header->seq_nr, rx_header->ack_nr, - packet->length, (unsigned int)(packet->length - sizeof(rdp_header_t))); - - /* If a RESET was received. */ - if (rx_header->rst) { - - if (rx_header->ack) { - /* Store current ack'ed sequence number */ - conn->rdp.snd_una = rx_header->ack_nr + 1; - } - - if (conn->rdp.state == RDP_CLOSED) { - csp_log_protocol("RDP %p: RST received in CLOSED - ignored", conn); - close_connection = (conn->socket != NULL); - goto discard_open; - } - - if (conn->rdp.state == RDP_CLOSE_WAIT) { - csp_log_protocol("RDP %p: RST received in CLOSE_WAIT, ack: %d - closing", conn, rx_header->ack); - if (rx_header->ack && CSP_USE_RDP_FAST_CLOSE) { - // skip timeout - the other end has acknowledged the RST - closed_by |= CSP_RDP_CLOSED_BY_TIMEOUT; - } - goto discard_close; - } - - if (rx_header->seq_nr == (conn->rdp.rcv_cur + 1)) { - csp_log_protocol("RDP %p: Received RST in sequence, no more data incoming, reply with RST", conn); - conn->rdp.state = RDP_CLOSE_WAIT; - conn->timestamp = csp_get_ms(); - csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - if (CSP_USE_RDP_FAST_CLOSE) { - closed_by |= CSP_RDP_CLOSED_BY_TIMEOUT; - } - goto discard_close; - } - - csp_log_protocol("RDP %p: RST out of sequence, keep connection open", conn); - goto discard_open; - } - - /* The BIG FAT switch (state-machine) */ - switch(conn->rdp.state) { - - /** - * STATE == CLOSED - */ - case RDP_CLOSED: { - - /* No SYN flag set while in closed. Inform by sending back RST */ - if (!rx_header->syn) { - csp_log_protocol("RDP %p: Not SYN received in CLOSED state. Discarding packet", conn); - csp_rdp_send_cmp(conn, NULL, RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - goto discard_close; - } - - csp_log_protocol("RDP %p: SYN-Received", conn); - - /* Setup TX seq. */ - conn->rdp.snd_iss = (uint16_t)rand(); - conn->rdp.snd_nxt = conn->rdp.snd_iss + 1; - conn->rdp.snd_una = conn->rdp.snd_iss; - - /* Store RX seq. */ - conn->rdp.rcv_cur = rx_header->seq_nr; - conn->rdp.rcv_irs = rx_header->seq_nr; - conn->rdp.rcv_lsa = rx_header->seq_nr; - - /* Store RDP options */ - conn->rdp.window_size = csp_ntoh32(packet->data32[0]); - conn->rdp.conn_timeout = csp_ntoh32(packet->data32[1]); - conn->rdp.packet_timeout = csp_ntoh32(packet->data32[2]); - conn->rdp.delayed_acks = csp_ntoh32(packet->data32[3]); - conn->rdp.ack_timeout = csp_ntoh32(packet->data32[4]); - conn->rdp.ack_delay_count = csp_ntoh32(packet->data32[5]); - csp_log_protocol("RDP %p: window size %"PRIu32", conn timeout %"PRIu32", packet timeout %"PRIu32", delayed acks: %"PRIu32", ack timeout %"PRIu32", ack each %"PRIu32" packet", - conn, conn->rdp.window_size, conn->rdp.conn_timeout, conn->rdp.packet_timeout, - conn->rdp.delayed_acks, conn->rdp.ack_timeout, conn->rdp.ack_delay_count); - - /* Connection accepted */ - conn->rdp.state = RDP_SYN_RCVD; - - /* Send SYN/ACK */ - csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_SYN, conn->rdp.snd_iss, conn->rdp.rcv_irs); - - goto discard_open; - - } - break; - - /** - * STATE == SYN-SENT - */ - case RDP_SYN_SENT: { - - /* First check SYN/ACK */ - if (rx_header->syn && rx_header->ack) { - - conn->rdp.rcv_cur = rx_header->seq_nr; - conn->rdp.rcv_irs = rx_header->seq_nr; - conn->rdp.rcv_lsa = rx_header->seq_nr - 1; - conn->rdp.snd_una = rx_header->ack_nr + 1; - conn->rdp.ack_timestamp = csp_get_ms(); - conn->rdp.state = RDP_OPEN; - - csp_log_protocol("RDP %p: NP: Connection OPEN", conn); - - /* Send ACK */ - csp_rdp_send_cmp(conn, NULL, RDP_ACK, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - - /* Wake TX task */ - csp_log_protocol("RDP %p: Wake Tx task (ack)", conn); - csp_bin_sem_post(&conn->rdp.tx_wait); - - goto discard_open; - } - - /* If there was no SYN in the reply, our SYN message hit an already open connection - * This is handled by sending a RST. - * Normally this would be followed up by a new connection attempt, however - * we don't have a method for signaling this to the user space. - */ - if (rx_header->ack) { - csp_log_error("RDP %p: Half-open connection found, send RST and wake Tx task", conn); - csp_rdp_send_cmp(conn, NULL, RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - csp_bin_sem_post(&conn->rdp.tx_wait); - - goto discard_open; - } - - /* Otherwise we have an invalid command, such as a SYN reply to a SYN command, - * indicating simultaneous connections, which is not possible in the way CSP - * reserves some ports for server and some for clients. - */ - csp_log_error("RDP %p: Invalid reply to SYN request", conn); - goto discard_close; - - } - break; - - /** - * STATE == OPEN - */ - case RDP_SYN_RCVD: - case RDP_OPEN: - { - - /* SYN or !ACK is invalid */ - if (rx_header->syn || !rx_header->ack) { - if (rx_header->seq_nr != conn->rdp.rcv_irs) { - csp_log_error("RDP %p: Invalid SYN or no ACK, resetting!", conn); - goto discard_close; - } else { - csp_log_protocol("RDP %p: Ignoring duplicate SYN packet!", conn); - goto discard_open; - } - } - - /* Check sequence number */ - if (!csp_rdp_seq_between(rx_header->seq_nr, conn->rdp.rcv_cur + 1, conn->rdp.rcv_cur + (conn->rdp.window_size * 2))) { - csp_log_protocol("RDP %p: Invalid sequence number! %u not between %u and %"PRIu32, - conn, rx_header->seq_nr, conn->rdp.rcv_cur + 1U, conn->rdp.rcv_cur + (conn->rdp.window_size * 2U)); - /* If duplicate SYN received, send another SYN/ACK */ - if (conn->rdp.state == RDP_SYN_RCVD) - csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_SYN, conn->rdp.snd_iss, conn->rdp.rcv_irs); - /* If duplicate data packet received, send EACK back */ - if (conn->rdp.state == RDP_OPEN) - csp_rdp_send_eack(conn); - - goto discard_open; - } - - /* Check ACK number */ - if (!csp_rdp_seq_between(rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1)) { - csp_log_error("RDP %p: Invalid ACK number! %u not between %"PRIu32" and %u", - conn, rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1); - goto discard_open; - } - - /* Check SYN_RCVD ACK */ - if (conn->rdp.state == RDP_SYN_RCVD) { - if (rx_header->ack_nr != conn->rdp.snd_iss) { - csp_log_error("RDP %p: SYN-RCVD: Wrong ACK number", conn); - goto discard_close; - } - csp_log_protocol("RDP %p: NC: Connection OPEN", conn); - conn->rdp.state = RDP_OPEN; - - /* If a socket is set, this message is the first in a new connection - * so the connection must be queued to the socket. */ - if (conn->socket != NULL) { - - /* Try queueing */ - if (csp_queue_enqueue(conn->socket, &conn, 0) == CSP_QUEUE_FULL) { - csp_log_error("RDP %p: ERROR socket cannot accept more connections", conn); - goto discard_close; - } - - /* Ensure that this connection will not be posted to this socket again - * and remember that the connection handle has been passed to userspace - * by setting the socket = NULL */ - conn->socket = NULL; - } - - } - - /* Store current ack'ed sequence number */ - conn->rdp.snd_una = rx_header->ack_nr + 1; - - /* We have an EACK */ - if (rx_header->eak) { - if (packet->length > sizeof(rdp_header_t)) - csp_rdp_flush_eack(conn, packet); - goto discard_open; - } - - /* If no data, return here */ - if (packet->length <= sizeof(rdp_header_t)) - goto discard_open; - - /* If message is not in sequence, send EACK and store packet */ - if (rx_header->seq_nr != (uint16_t)(conn->rdp.rcv_cur + 1)) { - if (csp_rdp_rx_queue_add(conn, packet, rx_header->seq_nr) != CSP_QUEUE_OK) { - csp_log_protocol("RDP %p: Duplicate sequence number", conn); - csp_rdp_check_ack(conn); - goto discard_open; - } - csp_rdp_send_eack(conn); - goto accepted_open; - } - - /* Store sequence number before stripping RDP header */ - uint16_t seq_nr = rx_header->seq_nr; - - /* Receive data */ - if (csp_rdp_receive_data(conn, packet) != CSP_ERR_NONE) - goto discard_open; - - /* Update last received packet */ - conn->rdp.rcv_cur = seq_nr; - - /* Only ACK the message if there is room for a full window in the RX buffer. - * Unacknowledged segments are ACKed by csp_rdp_check_timeouts when the buffer is - * no longer full. */ - csp_rdp_check_ack(conn); - - /* Flush RX queue */ - csp_rdp_rx_queue_flush(conn); - - goto accepted_open; - - } - break; - - case RDP_CLOSE_WAIT: - - /* Ignore SYN or !ACK */ - if (rx_header->syn || !rx_header->ack) { - csp_log_protocol("RDP %p: Invalid SYN or no ACK in CLOSE-WAIT", conn); - goto discard_open; - } - - /* Check ACK number */ - if (!csp_rdp_seq_between(rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1)) { - csp_log_error("RDP %p: Invalid ACK number! %u not between %"PRIu32" and %u", - conn, rx_header->ack_nr, conn->rdp.snd_una - 1 - (conn->rdp.window_size * 2), conn->rdp.snd_nxt - 1); - goto discard_open; - } - - /* Store current ack'ed sequence number */ - conn->rdp.snd_una = rx_header->ack_nr + 1; - - /* Send back a reset */ - csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - - goto discard_open; - - default: - csp_log_error("RDP %p: ERROR default state!", conn); - goto discard_close; - } - -discard_close: - /* If user-space has received the connection handle, wake it up, - * by sending a NULL pointer, user-space must close connection */ - if (conn->socket == NULL) { - csp_conn_close(conn, closed_by); - csp_conn_enqueue_packet(conn, NULL); - } else { - /* New connection, userspace doesn't know anything about it yet - so it can be completely closed */ - csp_conn_close(conn, closed_by | CSP_RDP_CLOSED_BY_USERSPACE); - } - -discard_open: - csp_buffer_free(packet); -accepted_open: - return close_connection; - -} - -int csp_rdp_connect(csp_conn_t * conn) { - - int retry = 1; - - conn->rdp.window_size = csp_rdp_window_size; - conn->rdp.conn_timeout = csp_rdp_conn_timeout; - conn->rdp.packet_timeout = csp_rdp_packet_timeout; - conn->rdp.delayed_acks = csp_rdp_delayed_acks; - conn->rdp.ack_timeout = csp_rdp_ack_timeout; - conn->rdp.ack_delay_count = csp_rdp_ack_delay_count; - conn->rdp.ack_timestamp = csp_get_ms(); - -retry: - csp_log_protocol("RDP %p: Active connect, conn state %u", conn, conn->rdp.state); - - if (conn->rdp.state == RDP_OPEN) { - csp_log_error("RDP %p: Connection already open", conn); - return CSP_ERR_ALREADY; - } - - /* Randomize ISS */ - conn->rdp.snd_iss = (uint16_t)rand(); - conn->rdp.snd_nxt = conn->rdp.snd_iss + 1; - conn->rdp.snd_una = conn->rdp.snd_iss; - - csp_log_protocol("RDP %p: AC: Sending SYN", conn); - - /* Ensure semaphore is busy, so router task can release it */ - csp_bin_sem_wait(&conn->rdp.tx_wait, 0); - - /* Send SYN message */ - conn->rdp.state = RDP_SYN_SENT; - if (csp_rdp_send_syn(conn) != CSP_ERR_NONE) - goto error; - - /* Wait for router task to release semaphore */ - csp_log_protocol("RDP %p: AC: Waiting for SYN/ACK reply...", conn); - int result = csp_bin_sem_wait(&conn->rdp.tx_wait, conn->rdp.conn_timeout); - - if (result == CSP_SEMAPHORE_OK) { - if (conn->rdp.state == RDP_OPEN) { - csp_log_protocol("RDP %p: AC: Connection OPEN", conn); - return CSP_ERR_NONE; - } - if (conn->rdp.state == RDP_SYN_SENT) { - if (retry) { - csp_log_warn("RDP %p: Half-open connection detected, RST sent, now retrying", conn); - csp_rdp_flush_all(conn); - retry = 0; - goto retry; - } - csp_log_error("RDP %p: Connection stayed half-open, even after RST and retry!", conn); - goto error; - } - } - -error: - csp_log_protocol("RDP %p: AC: Connection Failed", conn); - csp_rdp_close_internal(conn, CSP_RDP_CLOSED_BY_PROTOCOL, false); - return CSP_ERR_TIMEDOUT; - -} - -int csp_rdp_send(csp_conn_t * conn, csp_packet_t * packet) { - - if (conn->rdp.state != RDP_OPEN) { - csp_log_error("RDP %p: ERROR cannot send, connection not open (%d)", conn, conn->rdp.state); - return CSP_ERR_RESET; - } - - while ((conn->rdp.state == RDP_OPEN) && (csp_rdp_is_conn_ready_for_tx(conn) == false)) { - csp_log_protocol("RDP %p: Waiting for window update before sending seq %u", conn, conn->rdp.snd_nxt); - if ((csp_bin_sem_wait(&conn->rdp.tx_wait, conn->rdp.conn_timeout)) != CSP_SEMAPHORE_OK) { - csp_log_error("RDP %p: Timeout during send", conn); - return CSP_ERR_TIMEDOUT; - } - } - - if (conn->rdp.state != RDP_OPEN) { - csp_log_error("RDP %p: ERROR cannot send, connection not open (%d) -> reset", conn, conn->rdp.state); - return CSP_ERR_RESET; - } - - /* Add RDP header */ - rdp_header_t * tx_header = csp_rdp_header_add(packet); - if (tx_header == NULL) { - csp_log_error("RDP %p: No space for RDP header (send)", conn); - return CSP_ERR_NOMEM; - } - tx_header->ack_nr = csp_hton16(conn->rdp.rcv_cur); - tx_header->seq_nr = csp_hton16(conn->rdp.snd_nxt); - tx_header->ack = 1; - - /* Send copy to tx_queue */ - rdp_packet_t * rdp_packet = csp_buffer_clone(packet); - if (rdp_packet == NULL) { - csp_log_error("RDP %p: Failed to allocate packet buffer", conn); - return CSP_ERR_NOMEM; - } - - rdp_packet->timestamp = csp_get_ms(); - rdp_packet->quarantine = 0; - if (csp_queue_enqueue(conn->rdp.tx_queue, &rdp_packet, 0) != CSP_QUEUE_OK) { - csp_log_error("RDP %p: No more space in RDP retransmit queue", conn); - csp_buffer_free(rdp_packet); - return CSP_ERR_NOBUFS; - } - - csp_log_protocol("RDP %p: Sending in S %u: syn %u, ack %u, eack %u, " - "rst %u, seq_nr %5u, ack_nr %5u, packet_len %u (%u)", - conn, conn->rdp.state, tx_header->syn, tx_header->ack, tx_header->eak, - tx_header->rst, csp_ntoh16(tx_header->seq_nr), csp_ntoh16(tx_header->ack_nr), - packet->length, (unsigned int)(packet->length - sizeof(rdp_header_t))); - - conn->rdp.snd_nxt++; - return CSP_ERR_NONE; - -} - -int csp_rdp_init(csp_conn_t * conn) { - - csp_log_protocol("RDP %p: Creating RDP queues", conn); - - /* Set initial state */ - conn->rdp.state = RDP_CLOSED; - conn->rdp.conn_timeout = csp_rdp_conn_timeout; - conn->rdp.packet_timeout = csp_rdp_packet_timeout; - - /* Create a binary semaphore to wait on for tasks */ - if (csp_bin_sem_create(&conn->rdp.tx_wait) != CSP_SEMAPHORE_OK) { - csp_log_error("RDP %p: Failed to initialize semaphore", conn); - return CSP_ERR_NOMEM; - } - - /* Create TX queue */ - conn->rdp.tx_queue = csp_queue_create(csp_conf.rdp_max_window, sizeof(csp_packet_t *)); - if (conn->rdp.tx_queue == NULL) { - csp_log_error("RDP %p: Failed to create TX queue for conn", conn); - csp_bin_sem_remove(&conn->rdp.tx_wait); - return CSP_ERR_NOMEM; - } - - /* Create RX queue */ - conn->rdp.rx_queue = csp_queue_create(csp_conf.rdp_max_window * 2, sizeof(csp_packet_t *)); - if (conn->rdp.rx_queue == NULL) { - csp_log_error("RDP %p: Failed to create RX queue for conn", conn); - csp_bin_sem_remove(&conn->rdp.tx_wait); - csp_queue_remove(conn->rdp.tx_queue); - return CSP_ERR_NOMEM; - } - - return CSP_ERR_NONE; - -} - -void csp_rdp_free_resources(csp_conn_t * conn) { - - csp_bin_sem_remove(&conn->rdp.tx_wait); - csp_queue_remove(conn->rdp.tx_queue); - csp_queue_remove(conn->rdp.rx_queue); -} - -/** - * @note This function may only be called from csp_close, and is therefore - * without any checks for null pointers. - */ -int csp_rdp_close(csp_conn_t * conn, uint8_t closed_by) { - return csp_rdp_close_internal(conn, closed_by, true); -} - -static int csp_rdp_close_internal(csp_conn_t * conn, uint8_t closed_by, bool send_rst) { - - if (conn->rdp.state == RDP_CLOSED) { - return CSP_ERR_NONE; - } - - conn->rdp.closed_by |= closed_by; - - /* If connection is open, send reset */ - if (conn->rdp.state != RDP_CLOSE_WAIT) { - conn->rdp.state = RDP_CLOSE_WAIT; - conn->timestamp = csp_get_ms(); - if (send_rst) { - csp_rdp_send_cmp(conn, NULL, RDP_ACK | RDP_RST, conn->rdp.snd_nxt, conn->rdp.rcv_cur); - } - csp_log_protocol("RDP %p: csp_rdp_close(0x%x)%s -> CLOSE_WAIT", conn, closed_by, send_rst ? ", sent RST" : ""); - csp_bin_sem_post(&conn->rdp.tx_wait); // wake up any pendng Tx - } - - if (conn->rdp.closed_by != CSP_RDP_CLOSED_BY_ALL) { - csp_log_protocol("RDP %p: csp_rdp_close(0x%x), waiting for:%s%s%s", - conn, closed_by, - (conn->rdp.closed_by & CSP_RDP_CLOSED_BY_USERSPACE) ? "" : " userspace", - (conn->rdp.closed_by & CSP_RDP_CLOSED_BY_PROTOCOL) ? "" : " protocol", - (conn->rdp.closed_by & CSP_RDP_CLOSED_BY_TIMEOUT) ? "" : " timeout"); - return CSP_ERR_AGAIN; - } - - csp_log_protocol("RDP %p: csp_rdp_close(0x%x) -> CLOSED", conn, closed_by); - conn->rdp.state = RDP_CLOSED; - conn->rdp.closed_by = 0; - return CSP_ERR_NONE; - -} - -/** - * RDP Set socket options - * Controls important parameters of the RDP protocol. - * These settings will be applied to all new outgoing connections. - * The settings are global, so be sure no other task are conflicting with your settings. - */ -void csp_rdp_set_opt(unsigned int window_size, unsigned int conn_timeout_ms, - unsigned int packet_timeout_ms, unsigned int delayed_acks, - unsigned int ack_timeout, unsigned int ack_delay_count) { - csp_rdp_window_size = window_size; - csp_rdp_conn_timeout = conn_timeout_ms; - csp_rdp_packet_timeout = packet_timeout_ms; - csp_rdp_delayed_acks = delayed_acks; - csp_rdp_ack_timeout = ack_timeout; - csp_rdp_ack_delay_count = ack_delay_count; -} - -void csp_rdp_get_opt(unsigned int * window_size, unsigned int * conn_timeout_ms, - unsigned int * packet_timeout_ms, unsigned int * delayed_acks, - unsigned int * ack_timeout, unsigned int * ack_delay_count) { - - if (window_size) - *window_size = csp_rdp_window_size; - if (conn_timeout_ms) - *conn_timeout_ms = csp_rdp_conn_timeout; - if (packet_timeout_ms) - *packet_timeout_ms = csp_rdp_packet_timeout; - if (delayed_acks) - *delayed_acks = csp_rdp_delayed_acks; - if (ack_timeout) - *ack_timeout = csp_rdp_ack_timeout; - if (ack_delay_count) - *ack_delay_count = csp_rdp_ack_delay_count; -} - -#if (CSP_DEBUG) -void csp_rdp_conn_print(csp_conn_t * conn) { - - if (conn == NULL) - return; - - printf("\tRDP: S:%d (closed by 0x%x), rcv %u, snd %u, win %"PRIu32"\r\n", - conn->rdp.state, conn->rdp.closed_by, conn->rdp.rcv_cur, conn->rdp.snd_una, conn->rdp.window_size); - -} -#endif // CSP_DEBUG - -#endif // CSP_USE_RDP diff --git a/Program/libcsp/src/transport/csp_transport.h b/Program/libcsp/src/transport/csp_transport.h deleted file mode 100755 index 431deac..0000000 --- a/Program/libcsp/src/transport/csp_transport.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _CSP_TRANSPORT_H_ -#define _CSP_TRANSPORT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** ARRIVING SEGMENT */ -void csp_udp_new_packet(csp_conn_t * conn, csp_packet_t * packet); -bool csp_rdp_new_packet(csp_conn_t * conn, csp_packet_t * packet); - -/** RDP: USER REQUESTS */ -int csp_rdp_connect(csp_conn_t * conn); -int csp_rdp_init(csp_conn_t * conn); -int csp_rdp_close(csp_conn_t * conn, uint8_t closed_by); -void csp_rdp_conn_print(csp_conn_t * conn); -int csp_rdp_send(csp_conn_t * conn, csp_packet_t * packet); -int csp_rdp_check_ack(csp_conn_t * conn); -void csp_rdp_check_timeouts(csp_conn_t * conn); -void csp_rdp_flush_all(csp_conn_t * conn); -void csp_rdp_free_resources(csp_conn_t * conn); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Program/libcsp/src/transport/csp_udp.c b/Program/libcsp/src/transport/csp_udp.c deleted file mode 100755 index c989619..0000000 --- a/Program/libcsp/src/transport/csp_udp.c +++ /dev/null @@ -1,50 +0,0 @@ -/* -Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "csp_transport.h" - -#include -#include - -#include "../csp_conn.h" - -void csp_udp_new_packet(csp_conn_t * conn, csp_packet_t * packet) { - - /* Enqueue */ - if (csp_conn_enqueue_packet(conn, packet) < 0) { - csp_log_error("Connection buffer queue full!"); - csp_buffer_free(packet); - return; - } - - /* Try to queue up the new connection pointer */ - if (conn->socket != NULL) { - if (csp_queue_enqueue(conn->socket, &conn, 0) != CSP_QUEUE_OK) { - csp_log_warn("Warning socket connection queue full"); - csp_close(conn); - return; - } - - /* Ensure that this connection will not be posted to this socket again */ - conn->socket = NULL; - } - -} - diff --git a/Program/libcsp/utils/cfpsplit.py b/Program/libcsp/utils/cfpsplit.py deleted file mode 100755 index 985c98c..0000000 --- a/Program/libcsp/utils/cfpsplit.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -# Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -# Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -# Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -# Split CFP header in protocol fields - -import sys - - -def usage(): - print("usage: cfpsplit.py HEADER") - - -def main(): - if len(sys.argv) != 2: - usage() - sys.exit(-1) - - try: - hdrhex = int(sys.argv[1], 16) - except Exception: - print("HEADER must be in hexadecimal format") - sys.exit(-1) - - if hdrhex > 0x1fffffff: - print("HEADER is not a valid CFP header") - sys.exit(-1) - - print("Source: {0}".format((hdrhex >> 24) & 0x1f)) - print("Destination: {0}".format((hdrhex >> 19) & 0x1f)) - print("Type: {0}".format("MORE" if ((hdrhex >> 18) & 0x01) else "BEGIN")) - print("Remain: {0}".format((hdrhex >> 10) & 0xff)) - print("Identifier: {0}".format((hdrhex >> 0) & 0x3ff)) - - -if __name__ == "__main__": - main() diff --git a/Program/libcsp/utils/cspsplit.py b/Program/libcsp/utils/cspsplit.py deleted file mode 100755 index 037871d..0000000 --- a/Program/libcsp/utils/cspsplit.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -# Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -# Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -# Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -# Split CSP header in protocol fields - -import sys - - -def usage(): - print("usage: cspsplit.py HEADER") - - -def main(): - if len(sys.argv) != 2: - usage() - sys.exit(-1) - - try: - hdrhex = int(sys.argv[1], 16) - except Exception: - print("HEADER must be in hexadecimal format") - sys.exit(-1) - - print("Priotity: {0}".format((hdrhex >> 30) & 0x03)) - print("Source: {0}".format((hdrhex >> 25) & 0x1f)) - print("Destination: {0}".format((hdrhex >> 20) & 0x1f)) - print("Destination port: {0}".format((hdrhex >> 14) & 0x3f)) - print("Source port: {0}".format((hdrhex >> 8) & 0x3f)) - print("HMAC: {0}".format("Yes" if ((hdrhex >> 3) & 0x01) else "No")) - print("XTEA: {0}".format("Yes" if ((hdrhex >> 2) & 0x01) else "No")) - print("RDP: {0}".format("Yes" if ((hdrhex >> 1) & 0x01) else "No")) - print("CRC32: {0}".format("Yes" if ((hdrhex >> 0) & 0x01) else "No")) - - -if __name__ == "__main__": - main() diff --git a/Program/libcsp/waf b/Program/libcsp/waf deleted file mode 100755 index 4df5cdd..0000000 --- a/Program/libcsp/waf +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env python -# encoding: latin-1 -# Thomas Nagy, 2005-2018 -# -""" -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -""" - -import os, sys, inspect - -VERSION="2.0.18" -REVISION="96675f149f50dab16c9e2e6aaf5e787b" -GIT="ea17399be6950863390fb7bf25b747b67afe0ce3" -INSTALL='' -C1='#/' -C2='#-' -C3='#)' -cwd = os.getcwd() -join = os.path.join - - -WAF='waf' -def b(x): - return x -if sys.hexversion>0x300000f: - WAF='waf3' - def b(x): - return x.encode() - -def err(m): - print(('\033[91mError: %s\033[0m' % m)) - sys.exit(1) - -def unpack_wafdir(dir, src): - f = open(src,'rb') - c = 'corrupt archive (%d)' - while 1: - line = f.readline() - if not line: err('run waf-light from a folder containing waflib') - if line == b('#==>\n'): - txt = f.readline() - if not txt: err(c % 1) - if f.readline() != b('#<==\n'): err(c % 2) - break - if not txt: err(c % 3) - txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) - - import shutil, tarfile - try: shutil.rmtree(dir) - except OSError: pass - try: - for x in ('Tools', 'extras'): - os.makedirs(join(dir, 'waflib', x)) - except OSError: - err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) - - os.chdir(dir) - tmp = 't.bz2' - t = open(tmp,'wb') - try: t.write(txt) - finally: t.close() - - try: - t = tarfile.open(tmp) - except: - try: - os.system('bunzip2 t.bz2') - t = tarfile.open('t') - tmp = 't' - except: - os.chdir(cwd) - try: shutil.rmtree(dir) - except OSError: pass - err("Waf cannot be unpacked, check that bzip2 support is present") - - try: - for x in t: t.extract(x) - finally: - t.close() - - for x in ('Tools', 'extras'): - os.chmod(join('waflib',x), 493) - - if sys.hexversion<0x300000f: - sys.path = [join(dir, 'waflib')] + sys.path - import fixpy2 - fixpy2.fixdir(dir) - - os.remove(tmp) - os.chdir(cwd) - - try: dir = unicode(dir, 'mbcs') - except: pass - try: - from ctypes import windll - windll.kernel32.SetFileAttributesW(dir, 2) - except: - pass - -def test(dir): - try: - os.stat(join(dir, 'waflib')) - return os.path.abspath(dir) - except OSError: - pass - -def find_lib(): - src = os.path.abspath(inspect.getfile(inspect.getmodule(err))) - base, name = os.path.split(src) - - #devs use $WAFDIR - w=test(os.environ.get('WAFDIR', '')) - if w: return w - - #waf-light - if name.endswith('waf-light'): - w = test(base) - if w: return w - for dir in sys.path: - if test(dir): - return dir - err('waf-light requires waflib -> export WAFDIR=/folder') - - dirname = '%s-%s-%s' % (WAF, VERSION, REVISION) - for i in (INSTALL,'/usr','/usr/local','/opt'): - w = test(i + '/lib/' + dirname) - if w: return w - - #waf-local - dir = join(base, (sys.platform != 'win32' and '.' or '') + dirname) - w = test(dir) - if w: return w - - #unpack - unpack_wafdir(dir, src) - return dir - -wafdir = find_lib() -sys.path.insert(0, wafdir) - -if __name__ == '__main__': - - from waflib import Scripting - Scripting.waf_entry_point(cwd, VERSION, wafdir) - -#==> -#BZh91AY&SY���[����P�����������e�(¬#)0�Z0e#)�b�AG�PvmͰteN�`;6�Ti���Ҋ�#)i��:��G#/�w`N�#/��E=��FA �JQJ ���IJ$�@#)*�����#/R��gy�>�ǵU=W��w�^�n�&gsTTv��%%�����ts�ꏠ�n��w������ ׺��z��t���϶�}�|�����M}�{���;�<��Gp�\�a )귖y�`0=�#-d;`��t�Oy�����w�w:�hP��#0�[2H�����0PIE)@�zz#)͢����Y����jT_w�������{��@�h��[N�jQrƁ�{�3`7޽��tP��m��kwn�b�9В�����M����:Ӡ"���I���������3m�:�{�=�[�n�;�j���=������I9��;��v�[����؎��y[c��T�n���{�=����{g�h�lt�����u�V�<)M���lm�ٯn�{7mZ��6�kn&=��_f������^�<��87m�s�wZo#)�OW�������ޫ�8z�#)TJ�d%-A�������l�;짼�뻔� 3��guُS��p�n�����i����4 ���s]��#)�λH#)(�]�^^��٘�׶eZ�i���w���nh��'iN��}���s}ۏf��3b�M��s�gh�qo/]�]n����zs;mWVǷ����[�y�71ϗ��ϳ#-��w��a�.������w��|�Ӳ`������ћXd��P^�Y4r�/i���`��l����z���fq���uy��g�#)0��US��i�����Ѧh��\���ױ�N�}m��Wn���˧���ke��r ��}Ϫ���h��=d(�o07tׯ:�m��eb�uA8q���]��k�{����a�:W�0{�#)wb&�����>�7���P5����{b�����Oq���ֻ�K��*�o���ix��]���n�wZ�l�)ݶ�}W51�N���c�/@��^�|w���컛 w}!}�2i�}�=�k��#i�ݛ��^�^�[��ɾ���d+���x�}�}��}�#-�_�  �#)�#)��&LF��'�b���C@4d4�56I�~�%4A �����h��<"53P�@#)�#)#)�DAi�6�&��������S�O�x�x���A�ꞣC�#)�2#)#)#)��)" �j`�h���?P�ѵ#)�C@dѠh�#)#-#)#)#)#)I  #)&��MmF�bdɩ2���#)#)$�D#)�44(�&��T�ҟ�=�?J7�mM��DѠ��#)#)>_�G�UV�0�Z檊��]����.�D�3�U�R�Eb�,���k�mU���ɤ?A����m�?N����vq�e31=��LV �2�z� x�U�T�1��E�?�{���#/�G8#@��{ho����"�4r���AT �,y��]�eJ���y�x�S���>"걉&țZ���eλ�?��r����A� 4�R�uv�M�������"��#)�p���'9�YBD��h���b*�PE #)��#)=���aim�Wt[���j�U��V���2J35#-3M�4`�I��D��"X�ԥQM��#/&h �A(�jj5F��m��i�F�h�5�M�4#)m�404ŕ6�I�Z6�(JYiM5�!e�6h& �31�I�F�d�#-)�E ��%a�K-#Jm�l�m6��VѦbK�3!4D�2ɶ�m4�Ԕl����Z�l͙i2L�PTE��E��#/dQ�$m�E�F�I��Q ��b���TD)���B�DIb��$mH���A#-�42H�� fAK+,��Idb)d�M��4L*E�,�$h���&Ĕ�ehɡ�&$%D�4�Y64I"��KH"��lk$3b$�436 ��ڒ�$���X$���%����$���(�E"��(0 �2JaL�2�Rj,͍�F�RD��KJl�!E�؀�Y�R6d�M��؉�")Fl��2��$�YJ#-��d�M461�Y,��D� �M$�R0٦@��BMI,�(1��f��PE4�D֠X L��Idd#JL���e"Th�&m(i1Pl���B@E&c$�h"Y!��L���1F�KbQ2�LB���B��*H��I�M�1���4�L�b�e$)30)def� X��D��jd�2#/CDR4b��jT�%4R#&2dSi#/,��Q���E*�I1$�Sh�j4�4��1�L��L��63Y ��14���" M���(�B�2�l���`2Hi,��j���&��I���bA�e����H�M�R�P(�0Г2�He�dFS�Y�Jcj#- d�DHh�mMmh�2���L�M(���Z#-Jm�K4Y�M#(K,��DZ�X[(Ć)��4�F����#k���a�͢�lVƶ*6L�4�R��44����F�5Y���c(�S*H�D���[%�Q�IKQ���&�D�5���cR#/e��2eI�*�4T�B+d�"�T�T›63��,Y��L��S,��J��JSL�l����)��%�2R�Z���!�գ%AEVMd�j��EH�kD�$m�hŊ�l2ѵ����0�U@i��R �F2�&���ƍ�&��d�i ժ���* ��KY4IR1!M�lY"��Y�1Jm*�R�YaZ�DF��K"e5MM����k,Xl�k+,�l�  ��D��b�4��!��-�T%��KQY&�6L�J,�&��l�#-"+,�E1��J�l�4 AE��$&Fm6�F6��S��cE%bH��#!4L�Q�JdR��P5BT�4�� J��Bj-#/36�)F̤����!Hb�k�i4F5&�a $YP�-4) Ě4Y�ٔ����d�a�,�� jE��5�4ECF�4�#-1R�fQj4  2�A�&ĕ%I�1R�cd���a)ME`�0٤�lf�E���CJ2Zf��hT�2�H�lق!�M#b�5�M������JHH-�a*5�1Xţ2�i0�I�Bɑ��QlQ�%���b�fQ�FCd���2"�6��cTj�4P�eQAb� 5&��0�,#�(j��iM2�QF�"��Z �Qb,FR�ȩEQ�i0DY4E3(Z�R��*lJ"eZ�ՃEL�J��#/b�(�L��kI�J�m�-�chh�$�A���� ���(�4I��m�$5�0A�2`�B�Jl͉����*ed�di#/i&��(���ԕ�e$��b(Ѡ�& ��"4ZYh�j$�Z��e(�Ml�!Tm�IE�E4&E23#1��F#S6I��Ib�5%K*ɭ6� [�(���QL�iV6��cm�[Rf2�BY��KQ�ŚTmDm*TR����f���#-,%F�lkeI���&�I��F�#-1h�ƍ���[V)*Q�`!�F�4�ja���m�lZf���ZJ�ke,�jjm����V&����I(��k5&���eDP!Q&$�)&Ddb2l��f[F/�||��!)���#/r� g�ᬌ�S�R�o~�+�#/���� {>#/������h�l��z����9���z���Sw*��7�ˋ���!��#/����#)�D(0\:8���p�I �m��'�cD���H���8g�?�֏�J���/e�+)#|����[s��*�l=�_���:� eC#����X���;��a�8�"��8��'%�����5'#/�-�����]�&�dƈ6?F�����d�;�&7�]��W�x�,�r��]y�fsW �a�B��M^,�2�ٍ.e�) ILM6 ��Ő�1�gQ�]� �-�#7���D��� ��k{���vXS#)��_?m��,�:.k�דG�X_��Kb1�O��.�{>��G���N�V�QL0�ФY;�d���4D��χ1�1��<�I�J<�r��F�X��ж (D0�V+��n{76\�W(�T�T��v�0����խ��,3ۼ��w���,���m���$�؟mF� i���=�@�Ⅷ�nE2�.E�7.C�M֯�zx#Q�~~� ���� ��y2�Fm���ꠊ�a=WR9r��2#-�!7�0mxNwDFԣ+ousF��k�Wyݍ�:W.d�.����d|���׌� ���<��\�#-�؇�&6�SC<6�]2rjł��)G֓Oܹ6��C�˵3�@�?��tiK�I�P�C��0 ��bV��MX ����_n q��C#-��fL��uB�w*-�dlA쯃#���{�rH�Ȧw�Ԋ�b���=�yn�9:�Y����i�aCG/���5 �y�u혬�?��>��95�ï�~�z_�;wkt��ΡITm S!�YS�7L���0�=��F�&�����K�>�)Z�M�`RtiP;襈�3����,T�Yˈr�$���e�q��&���2�}�4�:�ț�����ȱ��o��"����ETP�1��PX����+W�#c�R�Q4iї�E�U�9h1�R�m+�+_#/�N�2���h���W��&�xڹ�?��j��@�C(W� V?w���}�n�gunm(`�>?��k�YĦ���ݹ]���t�)���9]e)2%9JUS�梶/]���W�)VJ��ܱh�ݖ�����q���3�k�h:UP�SE��#'��cPi-��#|���ӓݾi����DF�q���J�� G~e��kf���L ���J$���:���д���e�u�X�4k��\��c�8��;j�<(��<�J)�"��)۾�do�S�B�#/�rr�Ӻ�5��_;�����W��夔|/ �d�(��F���lZj�ڔ�."��T��\x�[Ebua��X��@���ENHQ�T�}�~t��(O�9�lXtA)��\��s,1P����=��D9z��01�v�9�Ňo�)kG�A�kٯo���b�)3#/3#H3�T�/�dn ���bG�Ӻ����7�w�݆?�H�j�d$51���SZ�j�����}��y�]�\�3~��#/ᤎ������d��"Xܑ��4�,�X}Yn�0�g���g�k�8�.�|b���A��#{�S�<��#/t�����‰ɣ�JU;���x��S#-�L3�����v���+���T,�x���m���J}7�M���b�Z�����͆�y�ai-�j- ���1I�-��7b�e ��R�A�8{�Ɣ���L�|"=`k\K�^��t�6�TႰ��B;�'xo�^���֫��+�#7&�!{�]�\k�����r�C�Ŷ{�Cls��>v�s-u���}�:섒H���T��JS�ၶ,1��4�K���X�2}Ȳ�=9zC}N�ez��|��+J��E1yw�X�5 bw������( Ð��"I����X@�+[q�����f6�q6>�uX�dE���(��i�;�w�[9����u25�^/�Cd5DT�'������[7�Љ*U�!VT���օ�J+9]z�Ѹ���u5�&�]����_�B�R��#/QR>W�K������i��;�RW��W���Kb�"��QV�#AE�T�|����Ϳ��o�G�չV�l�ϩ�\�(/�r�H����c�Ѻ�#/�Ѩj�vYBw������d �E��^`^s������La>����f~�Ua����nq� �!_)���N��j'6ʴO�b\�R�u616�O��0�"A�lg8��@2��I�tӿ;������EEB`f�����H���X��E��':��jҦ�>;�1�.�����7��D�򳹢�2���I �ڔ2Ҹv����齇-�'���mv�#/cϼ����N'\�3 ��w��]!�P��W|T�W�&1QOŔ������ԛ�$v���B�}���������,�_U���c�*Ή���֏M�H���e(+vteFW=u�����/~.�e#gFY7'ǻ�����cMd_�?��2�e���m�&y�Y򯥳L�S~(��v��,��v�Qh�#�y���Ds��3�2L�J\95��kvv=D��/N��u��s-��e�1��g&���n.���1��� ��+Z+g1U 1�!Q ��Y�>�P�*�#-ʢ2,S�\&���N믯�M5^���]�1�T�LC���ׇ���T-�V��˂���¤X�#-��4����$�����~��a��c?�-������JIˎ��4ތ;:b�Ӡic��8E�7W��O�7�•�r�Jd���SB^sƪ�q��f��a��� �y�Z����N�G�^b^�:���3�y��f��)!�ls5S�X����1��ê��޻}$������(��W��7�"�I�IDp]��f���m�=�`�MF0T٧ܠ��1�ȥ>Ol5�Q��ת����F��_?��F^Ah�|Km�5=�-�,p��#-�nu�Uk� 2�(�5�Bʪ8�����X#/�U�a���ˎC�b� ֔^�=�x��P/o�#)>>3�3c�4�D��D���;L�w=P�u�7�V^-Eu�W���{�QSG� ����P��$���?p��U�R��EW�ɶ)օZv�q�[v>v=�_#��G��o2��~��ˌ�e�K�K�|q�+�����wp�Ώ�T\�z�G��<c��/Y������ YMh=ɿ�R)9:sI�Ǫ#� U� ��Kd�{k�#-��;�ݼno%���x9d{�M�xb�Z�� z�������iG�3F,E���6�%UD�l�;�)]q}(�d7r�:�f2�٨ Q#-�rA�fR#DT1�h���ʱAi��$h�Y�z ��ˍ ��w����D�`!gxe�K_<9aّ�ȷ�(�H���j��y%2,�o!#)�Gԏ�-��lu�X~u#-�r>2vcH�������Qp烄ݵ�Ҕ��mXt٬`���Ҍ&�eU WƂ�V"��Ԟ��f��L+��"�?S�mk�@���`O���@c�����-T�S�1��-9��;���Dw��V�o����ƪ�~�G]��d��y�mqK��zvu���d#/���/�x@�;+�[7ڎu�wm���#)Ct����8FP��#+�c*kma�n*���Q��N�L�^ph�&�����'�ӦK<�q֡����'�0�b'xH�1�3d����]�������'��)����M:f9�l� ���1_ t(��:8�c1�f�^r.u��� �"�%L��'mC�ѷ��o��V�������po'� �� G�g_�҉��ct�w~J��5�Z��s�D'K( ���T84�՘�-[���֢Pl�Pm65s��޺�k�]R��5x�ݹ�N�"�W\�u��fƬ&֘�������9O�㏇�����э���Z��ҫ��|v���Y��g���Ů! |� ~�5BB���h�#)#)�`#)�D;�cp�/��5~e�йB�ʴ��������ޣA�е�ȷ���k��d���}F��֯�*z ���#--�E���T�ouDv�Ll�6�'d�ì�ꄆk0yìf#-r��ldiɫW�m��-G� �z��4�]ŷщ!�w|�R貎]�^���6�����n����(E+�dX(�#/��bS1!�,�go�\���S�5�r����`����tS���L�кFe�U@/�=��Nu��ʍ �q�� m�|2d�߱�i����W&x��-SQ�u� �h���c��sد�ʝ/y�k��]*8�b�_�̼�=�\���da����O��Qӹ��j���3��I˸�}��;q�������x��Ҩ��?���q�{�% �h+�W �Hm�x'L�^I��Uo�XkF���t��A/|+�yVM!%���w��mi��%f���w夏ҵ�~�yn��B�'��k��Y?#-��Ɗ��F�H8Ν��I�����N��7��є�V��{�6@�`�ҏ6�����uqvL�ڵ� KJN��Nݛ�{iP%�1!��?`pfp9�}��/wN����a]Y��a���,\���B���R�����/!�rf$�(:?��s��"pc#/7��{`��9v���R�g�" %`��"��∱#/hY��iܖ��f�8L9�7�O��qۋ��I��fjا��6�}���.^lnk�����e�_��['E�Dx�����!�P�嵼P�����z� �~��iӜII�,V�.,�6>�:ה�yA�6��v��`�Ԥ�?j�����:�?O!�Ĕ�h�2{-���� �|��g��DA������A�/�h���;�&9(�}���t�!bՕ0Y��of�<(D>�#-�)#�K�Ž�NvT뎉�!#)�% y �ft�9���Ნ��%^��#D�l��ڃ:�T`�)6�3�V:7LwA�&�訜�`5�H���XʎZ_r D�8tNe�hi%�5�@YG���y��w�_�A=;'^�c��.����i`��ey>˥;zx��X%޽n���t҈�yo����\����1;P��9�ts����.ĵ������,1��X���qs����N�ǤҜ�4�j~�o�u>4� �#�ʢ.�(Y���s���1 �Y�[�e �h��^�$����0vѾ��lvr�yE������8J Ȭr����sk6hP�#)�d�����ƾ(6�͂���B�P�|�-�nwo����B���0��+���&7���d?\�����N�Dg5 �*�G/�?��F�i��m�Ö%��N)�8�����2�C��F��X 8�L��;�P���07X���ǏV�0���#)&�~��������H��=�νT@��rܧ+b��U�T=��$S\�<��(��E���PY�y���"�2n��ק����tz�#-� ��(��J���_�)��4�wE�##)���PR�DJ�^��mN�k[�PDR #)� $��e�~�%���lQ��t�o]҄��������,:OB�#)�����,;�Ǘ�CH��EXQ��6����בj>���ER=S�:�s|4jG���m�fտ.�4����j]����:;��.�>���:�v@0� )���f���۶_P�(>��qQ�+��~7�o��9�$#-Mk�S�#3��^E푻�����Ƌ�0Y��D����;�|Z�s�r����3��~���m�!&L�!BI@�4 -���)R`���a�ȥ�c.�gՋT� 8)������.�:�7B�zϻ���;#�l�� P���C�I�%�{ܥ�*����%�8���C�`�0u��^�J�4ZMI:�rl�Y�����T���T�ho�° �����)@���Ž�-�20��SBkM�>K^����[�g2,��̣K�/r��Pi+$�0�pq ��{ؑ��;��(��c���$�ה����7�#�o.���ۖ���93O~[#8I��8�U�3#)��#-Yz�B�K���̳x=~r�P=�dA��R�5�}j �VI�魳�Lg�1al�����!_�a�IH�tii`�ٞs���3���!�}#�v%6g#{`,d��>o�,�ô�bOr4����>��z崎P��@۩9�X aa���(�%���z�o����ݶt8���J���ݬ����~����i3[�%t��<��}C|W ���a� i鲇�1�@*RGW���0��^f��z�y���l�#-3�i�Hs@��E��#)�/ #)��{e�TV��Ձ�������Sa@�����he5E�Y�� �2�+c%�2��#/���l��/%WEϱ�4FҖX��ީ���nθ~�:�s�E�p���*(~�����s��ꆄ�4�u�y!�#-���l�B��I:��;�˦�849���BÜ�u��J�8�b��W8R�ʁ�� 2z�=��:׭�F7h�R8�c����SPx��#/hF�/x�! �0Y�=��3�1��wL�^܎��F��U�M����Ľ�n$Ǵ�k�@�:���M,���}#-�d�Jۂ��/?�C�\�>�=N�:�}h��復���|k�8ts�58s��ɮW�8���P��#/��(�"��;R���ɷ�tb/]���̻]�֞;#1���Jd����[Gk��:�m �WM�1�Å����c9|����y!� �aL"��D)$CT�V� m�D���n ��`ҡq)E�������rY8���H���eޡ�bIM-���D�$l;^�pjr�pBi����2N��ԯk���`ި���� К���I(\Pb�0�`C�[!������'��ߌ��~� �C�[��.8TT)�h7�xɐ��#/x!���1�q���ߗ� lU��Ã�9':���w|��-eMG�WO��_�ƣ�ʭ��6�Nv���Ͽ��䥧`p�+��O�Bםm���u��q�2��y��#/��c�V���f�DwT�)���Ȏih�o�9*b����a�1G�}"hL��͍��R�P��\�7�t1�z�B�m��Ա�0�����$cFv/�-�0���d@�#)���奉c�6P���aF��=���z��|4��~���ٿA�p����%0X�#�j�ū�W������"�X�2ѷ�J��xѰh,���J���'����.��= 28.9R�Y-��h�R�d��n�9.5�L�6W<<���kS�"dXK-]j�T�a��>�[;q|w�+R~3�}U�{�C�|F�lߒ��BB�|l$�#�Q�a��c�g %(�����g=H-�׫���52�NM��u#M�<42@� 6���Aҷ}m?�ه��_�����M��v]�4-����t5��2�ICq5���.� �i*~�a �����vz���,6��#-�ؙ�*����q��8��G����~�����Tvk��=��O�'�4���J-h�bX�0FKg����� ��Y��������>��:� ; �����P�I��\�)����#�3�����5޶�ܽ1��64�0��X�PII&�w�VDVA�N��L@�2,*�� 6�Jd ::�a#- �u��l#-d�Q��E�$6T�u <��� ���#-�V�#Yk�#-)$դo.؅)ڊ"0ѥb��Q�Ѹ&b�̴�0�V�܌�e2�eCSJ�"� �@���y~�w��s4$�_��xwKw�!(n�r��Z�|����~��cH�\4��zdJX��mu^k�'����T4A�U�L�;���E�Ri�\�Dyb9iȦa�=�4����lצ�!����F7��-+���[#-#\!����.����}|�C1�ٸ�C&ǣ�"<��Q��q��BK�`�v�r�[�y��vb�OS%,,`���"�W��^���ф��>(d�#�,�\E&�!>P�r��m�C�#/6^�t���m��k��T'g�3ppkb8:B�,�\X(h|H�%lŔc �,;[#-�#1��>N#5G+���N��Ɏ��4�$���;>)͙n$"���ص7�S�ըx�:)x��؋F�gA�����g%�9��R��qT�F;D}w��v}��X�t�`n#)�� ���l�U���L�zYf�u��gX�G�#q�Ks8f:�F�!�k���si3[#/��z��62mFnj�K$!Qh�� PV��#-RL`�i��a�dt���#/�#}�E�,� 0�P�k��Iׁt���2�P������޺:�� 5e=� �|ϙ�۲#)��(7�y��տ��e:�=������-�o@}p�!�=^������ �B���e.�:T8i���X14 ������7�z3�� �b�R�QH�W���I۸��%��_�����m�G�Pp��=x��G�1�l���r�VܮR�����냈q��� ����a|��2�>��"j�&��TWdB�����(&es�x�c쇎�n�\��g�X�,�Pb�v�|?_�]�#-çH�ن1����ۭ�լ�ٹYoO5ө�WOK���ϫ�7�06�-�#-��c/�^��������Őo7T0�l=�X z���VA�E�����$yɬn���y���K��w[��f"a*l gкH%�T�s*�`Af ��t�q��A���,7���5��`����+#/���W�8��Sn��*�AjJۖ�~_��� u�����=>6XRi��>-��#)':(@H#/����wE�B�u����yQ��ܝ��ĉ �y�pr#�����#/��g���E3jK&�1�*X�_��bh�b�엣��E�U4T��Z���80�����+��|s���P����8mȥ+���(#/;%��mW�+��������j񠋛u��R�ή�^�����������e`��ѩ����)".������i>��>鮾��/�bъ�ݵ�ͣ_��#-�4��$�(@�̌x�����Q{(�#-oR��m�$���H"�]�TUS!<��u��}�9���cui��b)f@h�H6)��7?�y�[�ϼvC�?�H�0�`ʟ�xi�u�C,��u/���R��4}��J%�]5�� a��I��Խ���~���(_�?�v@E`�������p�r\N$� �9B�%8O��F�x��N�����#-#-���=���$�6p��05aB(a~��T���5AҸ��\�/�#)��*0Q��--���lm�g/V�0��,~2�9���௮����Rb�a�Q��!?Ki#-ݝ(�$*�Rh!0�V��!H#)1I[�d\T(�#/N=>4o��~�Ž�>����|��w��[��C��#�}H���||�*z�<��i���#+`�1�y���z_�.�E�wC��!~#)|B��f�ӗ0^���f�x~9w(�5"��#-���@r �2F׷�t\.�g>6,dy��D��3�D�] �l�~����ܗ�c]�7�)��ߺA���:����߫�;��� �d:�vP4���s�����H�]�h����1�3���H�(#/���� xP��Խ�]�#-[��+�F����#-�-�@=_ީ3'R��A��3Jh$Pᙿ )c���墏��f�� �G=����5���.R�!�#/B����c!nb�l�yC(����Y�p���O� ����6�+�У���������=�#G�t=�W�鞫�+�lA�.* ��˨#�뷗���Hn��VF�G#-�6Ӱ�9��X\���k��f�_�x�����a����ج[x�_9}�6�!�����d�����@�߬}-���;HO䲡�P?�B@p�~ �*̅yPIBv�z>�-�[옶*�ĄǸ�$M���\?�$y�1mHҡ[��?����ʶ_�Cw�u���=���0��mS��H��V~�%�4���� �Cc�������u��K�V�W�[@�*9�ie��č��h`,���ZZ��W��R��j��_��`O��z~=��WԱ\�jy˨�*y��^QL�HNCC�i��=�q�؟،?��,���R�sC���K*�Q�������K�b�)#)��Wݟ�i�i�GH (�"D��2�����7U��?�Ow����OW���}&ݜ��������>�e�3|�M�W~�)u}M����W��G�cAKk���\ڬ�w��e������#���}�?=�;Ov��g�.[���z!�"�Zj����×[T�xϗ�y�I��Ž:�������:ݶ+�V���E���V�����]���y#-���.nYh��{���pm\\,3���_^����V�59���{#-��C������}�� qH#-�߽�E{3���t���/�>w��~/�㊛$%�C�yz1K��6�̶S�t[F<�k�f72tS�?��l�Q�α�@e��\����#-��ә9a���lc#-5m_+ƙ���k٢7Z�#-1����[x[N�s��J�lkB�wt5ze�wNN�6~_�?������T��pP6rz�R��������捃~�g�G�*as�'�x�\�b�lB�2.s�U�?���F�6e�2w?.��,<{����D�,w;�D�^��M���{��;u�hx(a�DY'w��������.~�-R�$8��@��4?���a���Xc�������G�ef�zu?|{O���GR��x��� �e����w�i���DZ�0��3쾓��Á�)�edF�#o�U�W~W����}�ߤ[V�ٳ�k����a��莀����ۥ�t��̾�j���;э1�}p�t�����d幽��G5>����#/(���H�~J�6+��۴���ӣ0����δ�?o�3����t���F1����wR���f=�#-~�$���^�Jj� �ZG���ݔ(>wZ�$W�q#/:��|+�0 5����������ss�����&�K2�5�;��M�s����j��_���#-�~Y�� 슜�K.q�����6��k������V����`�,= �����p���DZn���"������A��/�-#/~�#-?~;x���>��;�������#/>��`:�O�!���{L�!#/� ��DO��BlF�%Aho�N�eg�������x �stm��K�M�؃䳻�����{�2d�I���} ����YBA�<}�Tc��☾�Z��I/���Hl����<���X#)Q��92%|��U%�`��i�A\�2J����ԓ��2t[���?��"�̍H�+�V3���>��y�ߢu���wu���,)�w7\8�ClR�Du0`4>�#��Ԉ�p��M-�78��]�����fp$�:� yG@�%�}i��ߣg�z>oPM�+���������Y4��`�[����xh!�^',���R��+�1�d�ώ��ְV�� Nm\�_6�6�{�浗��"���F��VSaclb^b�V�?�=�7x񮯽E�|��WF�9 ��6?i��E��xS�* ���A'��!G��v�[}γ�LÐ�II�E#/$um|@p�)��,�Ck6�ZT������"�����Ȱ�H��� �,~Mu��7sj~�E��D��x�� dW`n�)W��/�#/�Ea'JN<�s=N��EG�s���ϭ��a�(�Ѡ#/ߦ���-���_��;1���}�*G7c���ӻL�Z'�"d�����Ks6OS��h�|���ɇ�koL8�����?��Sja�<]��;���oC?����6]��=�h@�ԧbI;6>����K�c!�����cɚ�y�[�g�$���>� ���o �%�{t)$�,F:���4���͒�NY�$xz7_�uD�)揓����a�#)Q�{Lk/��1V�ϔ������<쿥d����s#jX݄��jA��aO��Q�j#-U�#�#�5(�D�� #D49�ń����ih,�B��t��!�Y���ՙf�On `�a���-����Aȱ�a�ILA�"hhn�)"�4�[VW�c��'φ����đu`\�j�5���w\Q��s4*��"О�V�6�b/��[��"?�9�gA((>���?��)�Y���Ś��Z�9+����r� �c �F6�,# D�����o�ǹ���~�F��#�#�E4E�#��3Y����ޠ�A�aR�D�!#-Z���m�ZI*UP��P�Y�O�s���q�����r�ӛޙ�����A��F���i|�-'�l�D����j�Uuw��u�_���f���WV�����%�u[?O����c�tC��V��<"��1N�����r����e#�<�"�!�V�u���4����,�eVMq�eo���9#-��C ��ڇ #/0�>�G�I ����]uG�<�~����ק٣O���Z�x�F�#)8g#/5U6�[���>�aL~�Y�w?VP��w�u~uw��\�3ܮ��������k��>�&5)n�|_�{�}^M��\4���}�sY�O���1l�@L/���0A�^u`QH�:�Z.8��v���zs�14fׁ�܅QmZ$V҆A�X�)�%<��#- ��xAVb�ƕi��i�ɲ(�v�k��ж�J��R��"��Pm��b��"��� ��\�YJ�g���0�Uj�4cj2#/Z�j�[*�c86�FH2#-Ӥ����f�k�!(��AS(����2�-�L�õ�sj�S@��:�F1,Șa�aYҨ����q�Բ��3�HZ7��KkA#)ek�ݧ`2�zXUֻ]b�0Q",�&T8T�${�1�TGHM&D��b%��Ů�!h"�9���*�L��:�%#��� W:?�� �|��AI$�9�%!���Ņy- �E�d�c=� ý=1��&h2�_���e�q������x�ܾ�Rv���?2���/V��ꇻ���o1��*c#�������>'������=z9��#-�%�a٭��)��oz�L�юe�������s���+�5�P^��/��<"l���9�k�=T�ެڬ3����&�ͥ�&�~?��r|��P���������s ����v�A#)_��${׫�ԎV�6T>pMh4/��\ˡAU$�̪���(�����4#)�#e���� $#��1�����'�-��J'���{��� �x�|t�j�aҝ �����n�X��De��Fأ,-*�~4��#-8�|��ǻb"5#�\\axqiF4�S��>},Y%ө� Hȑ#u0���M�V��:EA����1�=!�D�����1m@�z��Q�4ޝ#/T��^�Ѭ#-#)i-�Z �A8�:plo1��cs�WJ��T"9m��^Y;5����|�R�(,,�-�H��`~wp��?�����0���q��y���V�vm=�2|؎�_��J��`CT<��2+rn�d��ɠ�rҴ�uF:;H#�+�`� ��˜�PJ(#�CcPq����BF<]i���24>�:ۍ��FRv�t]Y��XH�Q�����LE��U�A��Etn9R��cx��Bq�j�x�d1LYC�8x�j0<�D#-0� ����S*�4�i��)X�C7�2�(����U#-"�QB_�f$��E���X���Ў��7�[m/ ���u�L���A�LF���Kb�V4�� �=�٠�D�n$DN׳&h�HZ1,sI��JY��b�)�op+�X� (G�I�H���_L�����.�m���_��y�[߉����ߎ@5��0.�棾0C��JRs�8e����ϩӑ�'��{��6�A���7n|�P�l}��X�G~�9��w%Ů���kb���w[m���}�cFS�ˑ!�vr��䂪��P-��%�<��E�w���u�O��m�c�.����3Q�&䊕t���=Xڭa�&2 �6ǭW$�s����Xiz����m�E��M��b����4ӓH��J�l�1H,X��ư(:�x�TglB��!�A|�lY�#/A��T��b�×�w�De�6��Tp���R�Y¡�M^�8�-a��#/8�;\;�$3� �#/�|_Ĉ���a�m犁��;����:��l���f�=�<�(��a4! ��D��k@��m�&�#-�X�)��n�V(�<[wŔ��띯;�c�k[��!r�����R���8r���/R�y���o&UAw#-.��)ǎ�*�;����c���`�o�m��0C���n*6���-�d۶�ҹQ|��[�#-��;�tdl��w�iއ]�mGQ�gtAY7��J�p���`���gt��)u��B���,7m�o�ˎ�{�H�X���뫣��NL��S(ij���P;5K�M���1dፑXe� '91�#/�Fo��Nv�J) ssZ+�ݰ,+N���m����O$�Ԛa��69���q����~�V�L�fm������ ���!(eߜ~�t��LRe�uʒ�/�;�[I^U�t�~�嶜�n�� ��� rqB1��7מm[^�J��q�'�ؒ N�|�~���q���)�x��A���e׋���2ɉɿ�޻�H����5���F蛎�JYY1 D1�ʛt�c�ik IœTi#/uo�B������]�Om�R�oNYy�\#/w��Ʒ���`M㛢�?��ۧGt��J�L�L� k�8!�L��m?o�xt����a^���4@��e��n�8¹b��Uֵ�im;'�y�hz7,��+���ɫ�돼�!���M*K*7��:"ԛ ���.{A3�M��VF�Ӳ�o�k$,!�� b�hE����T�oE0��C�5vM3��^B�e,�/3��K����W�]-���ߜ�0�z(��sq��hS#/1p��fn��O=!�;p��#-΍gVs&���R����^Xm���*,U�w���+ͷ��M��Ø�I�����|��kҸ�0�ze�c�Z�z]zt�kh%1� ��B� �����N��[D�ߌv� h� "���{6��Q�x��#)�p�wE�(�l�&�=k �/K<F�C���#��;0s9,��ZK���u����l�"�G#)����Ҟ`�:_���M"B��y��S@#/�u���gx�".DH`�`����<&��K�'�;���$0���a@�M��(���·���ZW(ۋ���u���lvK�3��w��A�~�� kIW�]�^������|�>ߞ�\i_e�<�8I|� �d.���m�,��_�;:��v�b��3c�,�#)�B���� �P O�w�wvO���e�u��� ��<[�#�,j#)���E^�� )l����&.2���u�J �˲������w��'>8����2Ǐ�k�%� <#/O����9�yos&�ǡ8�.�}ƵT���us�E�/K��(����d���i��*KpxM���i�#/R���ј��W�Kc:�����h�p��`v���iq`Jg�^��&b���|�ἳ����vK.˗!B#/6�%X[q�kdŰ�#�-�`�Rb]�8�3��c����O��]�B�$�K��|\�ț|j��g}'�$j��a��T;�_I)T���ee��V#�.�6�®�j'��p�w�{�?��T���=�#/V!}�b�xGk��Έ�<*X�ƌ���A�h�1 �� �j��Dʪ\�9��[����2����� ݌�ne�q��$�ޘ�]�D��d{�>��M{f. t�>Hhp2vB�T�����)@�vl�џY�η~�n��7I?���oR7b����[Ox�8���y4��˰�JF��Q\�C���f��C�Jqi�xi?K\�ADc��H�Jz3r�P�D�P#���N�rc5�q� ݠ�bY#-ôc�mTst:{��fN����M�P�2@��Lj �s���pm<(��nd������Ü�i�m��Ďm�&�a$ǒ��fseXuaz�>x� L:- @~Zགྷ̈�?_צ���"�!4�~ks6��#*g-���M�/\Fd-�vC f�縅 �������d��1�����4 ��Vꗸ���4Q��!��Z��<�L��Q�E-���a H ���0�N�3\JܘrSs t U�R>\}[��������c�r��XZ.�,���#Ώfi?��N7�I�.��k�Sͨ#�z�G��Q��#h, ߛ���є`U���u�@� ����M�s���ϝC����mD��ىGQ�v�hf;C���;N* ��r4��+�f����|��L��1�dE���Dh>VAE�,�DD�[2cof�D��&#��trr�GZ�K0�WK���R#-��V�!�Ӧ#/�gkh���AC�;Z[�뮊V-�V��>Q��T� <ωՒ�'lļ��p�HU���V��o�������ф���r��g��s5;�G�µ9#�����Z��T#ܩ�1�ȱf\l���u�_ľ���Jl,W�a&�J/O�K3b^oB��:^��Y'������&�ն�����s��˙gyb���ϒ��mȎ���3'V߆2��� ��Ħ�j0q+J`�I�\��R���o�gDPрci�%ޔ!�a������N��`Ώrj�荏9�E�`o�db����T��[h|#-���^Ji5xx#��o�~�#)�Y{;���!��W)�����Lk��Y���sZ�I-�>s�x��%���R�"�gɐ5᝭t_�}��V;�.���&�uA�*$"��+A\�|��B�*�9��!��rn��m�G�#-L��Q�i�`Ђ oQ��@�J�*/F��vM,Dz�Gw)�[k��"��Q��zʧ(Xy���}&�r��~��տ�s�n�G?�F�����(��4ID��>_�T�A��3�����q{�Th���碧�G�����!�ueF՛AmRυ[��y@��G��s.|���o�����?�ċ�9�G��K��@��Y �� �����([�u�`��"�%K��'����l7L��<�t��D[߷�}g��1���K#/��u��+;��z��E��ko�.�Z�h���o�1���jۂ:��f\�1m���M�<�w]��7�����+��#/�~J���o�8�FC=��f.�� #)R:�Lq� sD_�+]��n�a��pZ�m��}�H�&Q��|Y)��׬N�J���WD ו�8_$e.n�?B<.��?w/�r��F�~�8\���E]�o�uqP�sphK%!k'0�ݞ��`�V�j���\C|&�r��ҤZ�@�4�jd$�ү�*,�3Z�CQ�d�v���/��������~�W#/1����o{��5dKօP�/�6b�l��M˰d$���� �a���c±^�K��:�]}��5�"�DP�Km��n�\۱���-LV�XF�f��[&��it^����!y���拼EC9H2����tflkA���M1�C,��`�l��ر��k��OIiN�}���#/n�#)���A^��(��l��!�.�o7B�[8fX�H�ڀWz�2��s�X(�� ���p�p�4Y�A��a���󒥃�X8~ =ޡO��ϒ�ӯt�q�8=�����=��-$�� ��Uma+#��1��-!%g���X��'g�1�� �U����Ei��l�G����<8�?^j*�_����n�S%�S(�^x�]c-M�zB��D�C� �k���>�;��k�N$og���$��[$v�.�Ȟ/j�k�n�u�VҨ�9�9�шd�~�4�t����i���&ϛ���/~��/�����[l��:unM�({-:�;�_��Q����cק��n:ǫ�o��ԙ�=C�k� ���M��Q���fS�pr��LK�8'R���#-���ص�Ɨ��˃�(�=�4D������SX��?��dK�1�����u��g����Ԏ��&xt�M(_K՟Ma��h��{/��\w�T�H-/Q4�V��(��-�M��?����|�]I�Y8�;��p�~g6T�##-%MP�p.��gZ��+m�l!���P���o`�Bb�=E�����;����{�H�Q�kz@�}����_�p1���#/����������Ե%�l\�F��i �H儖"��� B�r�ZZ��,Ya�}7�z�I����#/��V�^���8����s17��f;����[�P G�B����6+{N�iC�&:3:���r��/U/��!Yy �4�� R��&�O :��#/B��֠����|�g��:��-r������S1�q��Ȁ�Q#)�8guv���'�� 9%�G�r�Wt��j^��[dۉ�Ry���6�����޵��2��#)U)Q����U7��=f��{�|Gњ��h��C*�s@�y �q�IJ=�29�K?��b�m�4X'?��K����O���amDѨ�d��>v���yX�B���#�L�(훭`6�$�:��ܮ�M�á�d�x&���#/�X+�#-�<��D��U����n#-��qt�ġw@9(��X9��֙�`/���� D$�)���F�62�!*��>9�@u啕j��yF��8{�����'z=��ݳ� q#-k����CX��v�Ny��*�|N�ZY6 ��tӵ�X,#/1�D#-��aI0jl�=� ټ��•�vр�Wc� 9N�D��p�<���a�Z�~��$�#-#-#)"�-�S�+�+�e�PQ['(x��T��'7Z�@�en��Z���T��[-���/�%a^�R0~�#{����,��#/G3���G��B�q�� Pt���� �����!��@��Pv ��wn��)�%w�fsj�;�3�IB:���=.�"��Ie�kI�+�s�g�����Ń%�0(����2%@��h����( 2����� �1#)���I{��x̺��}����%c�K\i����qwUZ�����\�ڛ&�1T%��mϩD絥z����� �4��0��AM�FN ��O����s�;�5 ��9`�KJ � �Ais�>1�C9#-ʊ%,��J8����]$hӜV��ܮ�ٖaT�����d:2'��i��I]]�x�fM9���/�cO�ښ�rE=�|�-̇_V�[��~� Hs��s�c��|a%�s�EMe�=W����w���l�fg�4�ܢ�`�E��3Y(��3�=�nR�jR5�Lߊ���{v��#/��q��ւ�s`�WLÍVh�w�-��W8g{�m���qn��O<�-��9���֍, C��`�N��`[��™�y#/Z=�s'�W��H���.V|�W᪁wU�k>&�����#-���~9"���ֺN;�s4֎�Y#/�fx����}pr��r=q�Ėܾ7�Α�j��72����s��ڹ�V�{��TsA�FŰn�m� ������,����#)��(l�cr�gz��kK��k6w�;ŷK! �t]=�� �� [��������x�J.�����;�t�uY~T+��_:��>Hا��[�< �٧*�.�:'���v"�W���z&��+�G��|덱���*�1�E-��������v��`��#�k�cdۣ�r��Ȓ�R���4��� s6�@Q��m3�N +ߣl��� "XH;"��=Đ��W�#/���0��������c���M{��x|���V�f0R�5ֽ��3��؅3|�hk}���Iv(�"`��Ta��ߦ:b�d�B;o�P��hs��+�!�ϖ2�4j�f3�� (�;��t�i����pV2pv�|�Ӄm��v�K1�Yt���ܿJ������%�@�NWN��ދ��s������C��9_k�z�5���J�mc��v��F*�̆�M��ry$�%TD��R�'�������bfs�m�:���N<�^WH���^������u��@��Cye�N{t�V�zx�7����)� �&w� ݋Aթ��@�x�Z#-��n���P=�N�6 ��k��ؙ��Є�8��i#"�E---i}�'˂�#-;��<M ��;c�ox�#)$�|ʧ��]CI%���&���1�j�>6�����?_�5ݜ�+T�[�<9#/B7�6/ {{�Մ����*�8wV[�fv�0U#��m#/N�Jx��Q�S��D��;��j,0��.�o��j��X�U�X"�;������&0�3gU_|=�?D_zmP]F@��ģ���zGc���[��#-, #qGAI�^��vD�3d֠�E2����Ġ�#)��Ԡ�O����Es�k��q�Vs�L�� AD�������$���S��~��TWƮ��] ����o���C�#/uܶ$����W�tlJE�EaFDRAB�#-=������ץY��_��c�H���1l��g�OއGc�8v��:��Y#"�R(0`k! |��:��/W�S��m�Kv5���3T�Yų�e����2?�0ٰ}�W.YzH �M��#)7��ϻ�#�#/&-@���{�$C�̈~g���C �B���"�����%LC�B�IQ�]잿��r�_۬���*��0�_=Ö��W��y��Ε$NI�e���YU�`��r�,���e�,�r1#/�#/��r��96���U���-�Ѻ ܆������~��#-� T�^� ��ltT��lIh�Jk]�!��g�Tb�XF�+����?�}��/���Ca�8M�W08�'��#/�֢�Ժ�v��01G����:~�F������{�Y���W#/�Uf[�g�~��~����s<�7E�a�VN~fP�����Gն.2�������Z*��dم�2��Q��Jf� ������%��9��^�,�햝��7��C���P��E3�S�5@��؟zԙJ`r�#)���_):��y�� ��J��a�b��\��> �e��:V3B�x��5-J܁�/�Ԉ�� �ܰ�noG��^���q���04@�����<7;�,XO�#)�v�x���x���!/vo��n~tV:��B����C������v��|񙦖\υ���*2.%�H��X��/t<4���;h�ld�p�M]����_�����|L�F�<��k�@�w�t����)�yA~�H���u���,����C*��ri#-���w52x "�"7s���O��#�=�wÙU��:����T��*R�BԬ#/��~��s�f�4E�{QO6����X�{���5T�0��.{x��|`�]V�8�6��2��8���m4��f5�j[�~ �$���1���!blM1>`\�A�#-��.)��;�Y��}������c>��OD�Ƞ(&�]�#)��i�uQ���:v�ٮ��"��HLWQ��[�e�pue�֔U��^9��S���s�"V¶=�@���V��W|�裃 ��{�9������¡�lΏg�V����#/@�qP�,v��4� Xzy&e�s�-�~G�wbQ������3��n�q��  #-A%&N6��?������Č�b��I�G��K���VH(�ju�)9&�Qb/6���q��1�o�G}�.��+��*����`����hN�B���H�ϭןկ.�Mj�\��(�so�)g�� �#-4F̷e�`0��R�qQ����|�;���l� �%������#-������j��'G�����A�>��#-��G��N�W�Y�����w��/�9�D;z@bR���/���H�'�Y�Z�t�#���C,@y�Nr+(k�خ��3zL;,�" 썼B�N3$��>�q6�4Ҙ#-�&�� [$-�S�n�-��\���f�x,Ro�J R*��Op2�c�M' ���#�1�'ة���#-$n�E"#/� x�w� .O��m�~ի֑�B�zbF<%xk5�#�0��_3HW��w��=�����d�.��;��#/*d���"�, i�V��Z0l��@0��B��Q�30�[����Z�Q�v��rI{@�{"ϕr[x߼u� 9&j����7Js�B�� ��Z�l�X�`��a�z'��ﲡ���S�ᆟ,�X��JKDHK�]ܰ�Sɴ?����;���8��e.~x����$ �u��RfX�~�1�o�'�\8�`�-��# ��r���D\C��v�_����X�N�e���:w���Q\���+��(�M�-��c����3P������ڿ�]����d�aQ#����`�t�Ww7�4��|�^�,4�m�C�z‹�qtZC�U���6��у���#-�eLw� !N*R�ωlj� ���θJ�L�-�rj�~Ă=%���gJP2 q�#O��{xt����}�=}޺����lRp�Ln^|��æ��U�̧���#-yv{���G��>����laoa-3�=k{b�h���+�\ �Sa�����������B�pc=[1q%�~^QD�B�y�q�N6#�\��6o���F�:i�:O�#)Yz���L�{y�g�����f�waA�� &�A�7n�$���:T�9��o����ƚ�g88��oe����#-�#)S�v �FT2���@���z�5[{6��wܾ�ߢ�ר$��dW����6��#)��}k�ӛm���}dQ��� ��}@I�4�r���i�O�O�b�x���+i���M1f�tб��>s����W�0�zb��i'1(�ue�0o��n‡ l���1��4��D]@�u��n�Y�M׃\��E��b����R�AP���E� H1�5��4�#)���B�}Hגh�t�+w�n��0�oV�p�pYё��*tw@�#/g*�^|�b� )�C�U+<ߌO�Mf�j���o��HAJ#J��JV�ݿJv�^y�y��0���������|���y%#)k��]q~ʨ,��B�1F!#/�tW�>��Tu��US��!�_��~�G�S�3�x�%������o��F�K1_b�Z�&"��Zr�'�?��p#-����w�lc����z��t��O6u@���#)9�iH�_/V�k��r��Å£�笧HO�% ���d��r��I�5=[��#-qtܷK?>�F;Z9��f��^�"q�����,_ʩ���}��s�ke���r�'P�����F�T�ӏwz��f#[5R�Ȍ,��i��~�4�6���3��e��J�GZ ���<|q6'�P> ����Z���\�����IiD����ݿ�Yh7G�<�4=>4T�����g��Nb�����ʊ���"h(GO��_r���-c]�I>���k@�0��~�߯쳃������7`�*���d#)��!e���@·�ēZ��?�5?pW��8�/�v��,�� [2� �Z���B�#)N�â"a�b�e;"97�؂��#)� �J�� �� 3��#)@�����#ꂶHd�’�DT�K���GE�@��2��. �&c�}��� #a kJl��nx�X̬f �bXp�,�cnJR�bQ��%n}Z"#/��_�B��{O�J����������g�g.�u��Mŕ�T���;�k�������1@�#-A�W� ��3P��\���V5p�EM���`��Q:��s�D�*��23�l�R�N��o�)ϥ����Σ�M!+�E>�T�����s�Κ�?� �#)�`cnh>����+�BGG%om_u�� �M�Q' �wD��w,�Eͺ��J1�V��o��%�g�v���[LC(n��q����K9����6w��:�*��p���️�u��=Ь�+�Y�G�&͊���F!���:8i�5;<�@�FI4�?`Ց;��5F�(z��q�T����z$��۳�=f[������/0K���'N��-����?<�tz��� s?��#-�|lg���@l>�Y�/��w�R��$!�~�Q=����bX�,��d�P�i,��S4�f�̔�"���z��9*����*�g||p�����-pq �6����Hk�{+q�6�C"B^��J���aԐ�HE�{K"���ZSO�8m۾����4�v1������#k�g·MG��#/��}�P�&�7�D�J�ө�6�Ƣ�su���&Ȉ��#-ha����(lUeY�V�H�����aةFvt�G#-�m7[������Ri����rp�N:��7T%�#-a� ����3٨j�� ��vQ� ݉���5E�d�Cz�Nӹ��lJM*�y{:VF,O��&�0񜓹<�t�'�(v��(#/H�[�nkd�cV�:ʲZث\��m�j�U�ڽY�w�y��ֺ�U��t�Rh�^���ee�q2&��+�/7ɛ<Ԓu�����I릥�A3'K�0��G݊��Y�<,mKQ����g�ߓ��x ltH�h<��y�̯�y��|�G�Ru� H{ڿege�޴� &ѭ��V*�Z��l�pCoYlk����jq��0h��2/i��"��k"�b�w&��r�#-V�R�L�H�y�%%��B�$�dq�o�`�'�_}��<�3�͏�氁'�ܶ�lAġ#-��Dj�AdU�����k{�ן˽���V2!D B4�Nv�&�&G�o��n���vNޠw� �Ť*�^��U�ɵO%��!��7��\��3�1�=t:�����ьdP�Q�"��S@,Svu{7q���m�7s�`k�W�IS�.�~LY�bP�ו%� .� h�#),��7c���D<��xo�Q�Ē!���m�#�`{��S��S��^�ϲ�*���IhDJw���Y�&�tB��+0.��w�`�V_?����@�U!�7�yqF�s�ԁ=Gf�f Q�>{��~���y�m�LQ5Uy�ނ��B����,�(D�(�=yy��U�ҒX��nbĴP� Ӿj/�@{�|��9AWgy�~�,s�a���:�lG�io�p>3Bsp4���S�%y��9���|�4J�Ԓ�#)�kDκj�@�"� P�oCw�;�4���������D��p�Ӟ�}VN� 6�t f�L��Ft��+i��7�[���>�n�P�!Fda���/�c�)�9�|ۧ��i����3�Κ�¥k%�G�կ����;(��#/�\����(�Of�9#��������( �5Q����VbX�!ź/|�ll8@��G*��)�����q�pkՕ��8�L��A/�Q1�*P<�߷��9+�k�| �c`=x�|�l�ez9d�.�7#�FH�=o��z�&ԳX���};\RW����E].�Ko7M�^,%�A�|8���6���袐z7��R���{C a=�؉�A��b:*�J��㿆��ybi&z�6�c��H+X��r�H#-��E`�=��4j���#��Y�A�#-c�4~hy�Zn���<(����E7��x�?�MH�g������ ����4N��=֒����%���h�auuz����lF���“��e5ՌX���k������k7=ڙ�h�G~���fm’�Dn�5���X:��&�^Z�Ǿq}��N���GZtm�{�fN�}%��A"LKgD����0�1%S�}���/�2�=+�> ��(�B�Y�C#-��m�Y�Z�yQ2a�0H�'Ĥ�ȯM��z�R���I�3t�<�z ��62 tB�� #"T������*�Z�h~ݔ1!�$H�e�:��n� �����s�M��Cho��|~_糳�Kt�gz��D�GV#/�Dh�svCd�lx��.(P�Q��&³��X�|�����d�wL_�6�4����߈�:7�3`9s| �GW�cKr%�� ]vb�l ��F]J�*o���)Uf[(8?�B����^f��] tJ�M/�B)�����w�E��� �Ce��0��N�Ͼh�9�%@0�� ��ϣ���3��Ŧ,�k�^>R���t��&�:NO��n���P3�:��0�Qv�����J�7p�Zk\+��V���F��=fE�k���Hb䐈#���x�m�I�)���M�C �bph�6�4�R���&�w���� R�q81�sD�v��{�}���Ɇ�P��E6�%֙C�],Q�=�#):�:�WtRG-�M�-�����Ԕl�U~�u7aF*�thb����)�p <'���0k�9���]�dL�f�;�z��q����LIW8� \W�mzpMP�b�wO��ϑI�I����z�����,=H#/�<��S鷗f|�gY'#-� �m(#)@�~~9i�f;ia��b �v���)�D�+XV���������zfTO���xl��y�&Y#)&��� �TZ��@ z�tl;�ZLW�v�R�*zG�#)bt�#�6a��?#/J�3 ?6��>TwH���Y��9|L.�)* ����b��?}-�}�H��%���f�L؀� #-#)��}���kJ�/oەZS1�_�����P$�TRE� L�k�?���~�l�N^;��mYmΉa���t�,)#-��0V�®RS��2ΣӔ@�7���U�<�D���WVg��&{�녔������������g�.~����٧���B_V�� +���Vi�$�|"��{~4��[U�����������O�+#/��0��eߞW8��#) _���c#-�_����Kz����wUuUR�����9!�+15��G� 3/��'�p����}�9φ`�pEO��ߜ��?��pI (��/*�?_������\��r��Aj������ݾ��A����h�1 /1u?���-%+��+�1�~��f2��7I,$�?L���o�\����RpU�C�,d P�?2�LʢE���=[x���&z# �Q9���@�U�Et)��}��H��-4� J��W��H�q������7�]�rL]QN�)��Zf��/=�L�z3),(���K��О����Lb��=��n�u���*�-/�� �-�"�% n�"���@�D���_����_����y�:#-Z���,9���:$�ѩ�)F$�'�d������r�7��� ��?�<"n�P6��ClR�xT�"œV�t�����_cU^-���ʢ%$�H19��aY?�NN�ѯ�]�y�����`2�/ÈDϐ���>��#/m*��H�<\2��^�'��� �����;�v�$�T�+�����#/LL�g�lDa�J�� ���0�Z�@ ���7bd{��S_�wxo�~w#/g��}> |����'�v�4���t�������$��W��!b��s��Gk���o� �!L��}��=� �3/�V����9�y8�9M�\�z����#�`}�%S6a�5;��%�~����w�wh��_��#�~���g��v�s�+�Í<ն>B��b�����9=��b� Q$����DO�a����W��uy�`��̰�������!�"-��I��#-I�v���`w�`��<�Z�����%L�Q�6��_#-Zu�u��;[�$���@PX�i���SYo������6�8q���&#)_��}1a��yZ��r^[�{ޟ��H}k�c�m���%Q#/x�&E�f HV�7>ue��-!t:y�W��'�#/ &sW>NSM��ϓf�vB�y|�m������+�swy����ǂ"4Q�j�ykI���:f�LII�<&Db��U�#)6��΃� S�OP�{G�D9=��i�`M_��z�ҿ�:���8�C�Y���#/���W�s��&9��\�s(KW�6���#/R�_~�*�������ͣ?ǫ�0A�A�3)B�`I~����O�unc8��,��'���g�(���P���<4z�n�/#)#)A#/ �՘�"6�w���w����վ�g g�$d�����<���]���m�� ����m����VDդ���n9��o��J)��o��y�ݴ\����JL��R�W<����>��(B�_?C �)�0jQ^=W�8�<�ze�8k��/��ߩc4��9Fb�j��q� e�' VH��,l�z߷��y�2Yˍ_��f-{񍷣�*�I��8�9�!�Oo��-Ͷ�K��r������^�[�s;��;檫ʟU�?�X��T��i)��4b��ױ�o��Il����.�Ih�z������:+���Y��|o0fU���,&6��C�K��i�X�_Z���!�g1����Ϲ�|�M��b+���ęL��zdn���~4mF�TGm6�{��)@�vp�#)�*��<4 ������ݾ��C��Hcj�uP���xCugX�I��N���|�|���D�M9�`�Q�5�#/�S� /�Qʏ,�!���X� �Fe��g�v�Y�ϬQg�������qE�)ĸ��;t�+:�s�z���Q�VA�����L��!�O��i�֯�k_�,Xl�o[�](�kړ��L�鷦�]�UU��Qu���- �Ju����׭��3\Y��q���X���zl��+�Z�����P_�2�7HO^^jQ�D��URHG��`B�o>_��Sj�Ԥ��t��sP�cV�)�w���c�;��isga1N#�7�_�h➜���i�S��$���S�﹭Rw�Ѿw/k��[3���N�S����u���"}�͕S��-<4?>��W�,��on�Y<�n��ldԘ�s.9���#-a����H!)�_�,}x�=�E�֝a„�Q$��Ix� ��]�6����ywN�_#-x�B��a��[zQ��a))��a�ެȜ�-���aJ��O�j�������FCGz���3Ӳ�t��R�8�t}��˸�x�wY�1ˆ���#/���r@��{�h�a��~�����9��v� ��<7������0���Fpqu&÷��-&�4J���?��-wwow�A̺�i�g��k�;����|�%��4�P�mҤ'b��QbP�P.2��|Q#/�_OP�B���7�v��}pGv��KM.�25����#d��O�B�7k�Fh^Á#\ZnUF�"�qW:'h2,�8����'��ByQ�mk�G�x�CG�̋ ��4�َÅܤ}ޯSX5�HZ����l�#)�Yy)V#/J����%� b��x��7#�"QU֫�/#)�@NTx���Y�[�u�S��#-_g/k�?R���b́� �+�;�+�*󒺃m�����+7�=�#/�b�_wS�<3�zhv9�&�"�k����"���#)A?�9�����z��r�ܾ����jt��Kd��{���ƙ�8�����0m�}�������䀞��y���0$< ~�������I�"�cĤ�� )�y}^�?�<#���"��7���ZU#)�'�O8���s3����Bp~�U��!�5��{�B����?��a�MR��r�#)� ������o������M#)��1R04��)��;4�(4?Y�w�<�T�.d��=1�����^<>�%�H��8v�7H�֮}�����s�`��c�H�� �(߁����Ӧ���k�Mk��m���O��O����"o��Ža���[�@�b�0�>x�#)�O�cDF(���XH����y�9 �3#- }�{Dt>ñ#)3I��H��~���)q,(IO ���=Y�2�����$?T�j�P��]>B ��T�%K-���{��N\kl��^�?t�L��CH@����ρp�s���N�#�� �M`t�xN\���~�g#�$�}�+u�e�qN5s pҨ��� �(g*��Y�9p#/Ps�!���4$INr$&�3Y�i0�A�u*�8꘻���(#)X��˖Ĩ(u����#)Ԥ<��hz��z#/ ܇~�%�����P�=e�("�:� �/�Wؤ�O�^-�mfAaAr�B���&�N�0#/��zY*�Mt� �t���l,tg��g2�j�bO�N@��q7��&�#/SmLzP>:Q8�w76��NU�{j�!�^��;]��yUff#/�,#��tq��+����{�ޖK](ֽ#/���0�Q,+*�J���„e��ro�xnR�3���,��>Ŝ���w�n&��Y\MwRx=نS���q�\%O�����А�r:��я.8��"`i>ˤ:D��^�c'C�&���ˎ8]s����a�p�2.ZB��'>�;�'�"�4�IB8b�M�#-�ۖ�mO������j�hDp�ɓê��Кy�9�Sr�x��-�hv�d�#-Y{y�dž�ڧ��l�~��DNP����Vm�H!|�O��{�.�zOĨ�"R!�J!R��Z�������U#)��&yT!�Ѵ���]쭵���2����P�]ҽ�dRl/U��d�A�r�#/+�`£��ز���8��F��m��R��?�Ɯ�̠�q�)#)6�z���(^Ig{����� hQ����gܹީ��B����=.��lhk�̧q��$^1�e���2ht� �wシm��s��-�Ŕ��3� ���v����y��v��\7N���g#/m�v �9��f$z>W��BG'Pe�o�8f+nV�bk~�<��bdRt#/��z#�æM���e����^--� ��\gx��Ѹۙ [� �a��Vfb {��A. #-X�N��/����43�! 4�ߦ#��Qu���a�g�]ꇲ9t:�������lgi{9k+LA�ע-��4�yj�n�k|�ʻ[ql�:��>��0U����B�M>�ku�!ˁ�:q��o��=�� L�6i������_�FR��`����N�N��:�(����XN��߯�P����T�^p�\S��l6;5�*��xk�,(�Y$��n�!���xJ�c��H����~Ox��pQ\���%��1J��� �}���:]#-�}ꎽEGCf�����]q��[��ȇ+M��ν,�;q�k�ۿU�;#��w`�#)�X���&��"ǀ�~TBø�H=FA^�� #)�#jz���~>֕G��adػ#�פ�K�Pr�Ɩ.,��Y���>�����~�nZ�>i??�k|�9��E#-A���:N��0�����֝�&���S<Ljt�m̏�j�\B-�B�s���:��>�cS>�{�����v?�Bb�z����N�4k�<���V�*� �߄)�hfO5�?U{����~�%�0�#/���p�Mry~�E!X�e���p~�/��6�7�_?��cXl}52GZ,�\��D�JI<�� #)��KGl���߯e�am˞�h!Q�n��p�_���[�4���A���w@y{����- 2�TQ3��5��.�$��@a��� �������d��L'U�����xMr�d0�JD p᩻�%�BHod#-� �f����i�62Ӵ#/�X��fa��b:��:��-'��U���m�~~3j�0��H���\���*�Aȷ#]6,��8Hb�;:#-a��>Z�K���_o/���Mxm�yyfu�`06 �`�v��q�p�l��#-s\]�S��x�H�մw���Q�;� fXA]�@r�<��9 Œ�9��#=2��V�v�����!�m�-ZK�X�9���%d��J%A���LS#)��\TL��P/"r�>��537���m�v�{�?�R�Y��+h:�5K����""��#-��3v�)��a��Sh�0"���09��^%&��#-��<��z���Z��Tm��{Z�_�N�c~,�p.���5��88N����,�Nmoqƨ,��A����`2�\%��NN���ܻW$�r�������� �D�.x7��d�Rvm�O�W_lC_��x�dF�|ÐH��.{�X[YBB#/#-j#-�8��A=�zb��U{��S�5M����(]S#-���:��ƣȖ��_3܊o6��)!�6{����] ���̽9��>uR�#}�3va�g�v��m��ZU�#��q���V�X�*d=��ò��6�PHo7a[��yBE#-o�e_�]�: ��+!҇�#-����7b>�Wq��|<_+��y�[�' lW�}8�YD}�[ 9��PE[tH�!��5�=@Ѧ����p-P��E2D�gEg&�1r"m�xhh�Nf�Cc��&�Z��u��5��j��r"V˥�|���k#-�-�@1#-FDtt��mk^�%a�QOf;4=�Q��@�X>�B�-���})�V�Z ����k�����ӫ����� ����#-CB;�%?�l��[_�� �d���+�O�gJ7����Rg�\.�f�]%k�ْ�t<��#-c���tg��>G@^� Mu^q�`����m���إkNv�yÅ��N`���&�8y��I(������K��<�t��I�*��faHy/�"#y�#��`/�-*w��l��"������gfA�.�Ё�#)��h���ڳ�ۘ���cTq�)i8V�kjG1��x�dE ��u]D�7��f�;}�Q�k�S���Z&��3�LBc���"P�d#-�KCu���w�}%�� ��V��gF��đ��”�w��`�Q#-��߀��bzݟ��sDֺ�FG�}>�}v�o�v��E����Ot��QY�x�t�t4�W}�UAM! !�K�$�V��A�]&[����_R۴�T��Kÿy�����ӯ�������8��t��9~����(��� �K,���>FJتi�x �e��p��#)(tE�#�V�F�lj8�|2-MR�����C�����ků��#)$�?-mO��u�y0���}�W���;��hщ�N�rg��ק��~#���3��K�4?�n�n|-#-යY`�AAb'��A�N`t��@��`V����=��te��0*��o��q�g����Y��T�*�Bu��2�k���W���>v��yo���_�4$��?�(b��(0 3_@##8m��F��#-F��I�?��R�(��د�����x�v�bQ` ���A��G�-`a�ۨ���ķ�{��O�nw�Xm�t��tط�T#/?Xf��9�.}������� �N���2���+�y�LO.�F`�W�0�;.�$������#/���R�#-���Z���:�;��hy5�G�{�ܝ������gH������s�}ߘ�u6C#����+h��b�d_0��w���j�ZGF�s����_4�P�4�6�?{��#)r65#-�Nӯ��nf���/1؃�9" ���e�yw�Z�pN�O,@������V®��q|t�1f� w��}���^��qn.I!�2Uz��Y ����G��d(#)�C:�VW���o�?����#/���A��`����-I#G������`�nX�p&=7�i��\��ݠ�jB��B�1>���~�V�Ζ��#/���Ӵ���� \-���^��F��.4�$7W���;�m�6�Qh�,B��)Ս�p�m#w��#)����ka�(�r)�H�#-��Naj,d$�@Š�t���޲�٬iORy�� �|4�U���0/���?W�N��{S��%�t�m� �h ��M#-��j6�1���ol��� �yX["��K db�#"H� ��a�r���. �ⴥ�@��Kf�@�t�2�y�3#\�)ٮ�Âm0�rN� :��1��#/����d_� �@:O���WM)'����'������#�*��ނиx͉�M�s�5,h��#/�����T=|��� ];��`�$I��Q��++�]�Q�a�C*��hZ{0I�`�����_�M��\��D�Ł��Ř��B�� ��w�p��ڝ:��������m����%��l0hL̒�~y�y�'Q�IJ����=���o��)��������r�?��OD27GFkqU�/��i��]}�:� �PpF�{��q#-�?;��s�#-O�O��F���5���� �#v���b#-��m@���y- �>#I��7�u9D4��UH[�~ )K~��O����J��^���s{���4��eL��;d7�j\�q�_������Ւ�|����O���0���@�83�1n�%������I$�xw�%~~�3[#-�W^��B���8\?�{L�<������d@��A��F���6Pܷ?�tʛv!�ڰ-��EM=��?a�/���s�+�ڋ�rp�$�9�z�߀�Σ��H��Т%�m�.AYu>���nCFSl�]�5�i���ׅW� �x�&N��#/Qm��C#/#-�iMͬ�������#-#-��|�uO��fD��fq�0�hL����R����-�z?<#)܅��?�6WTj��8!IO��1k +'�iaC�QI�)2�۶H�E>��ם%����=�F�vKK�F�2��WYi���U9 �ć4�+dR���#/��܍�er��h�R:�I$�5Q��I��u��--m��5sVZ�\oL���:�P�^������k�h5b��SL�.������Q���Q�D.^�7��w������ٍ@NZ!$@y�_�5($���fVi?��܄�jTm�2sx��0�Bw ��O���ɨ�"$�h�r#/����W�Q��B(�cvU��y��P6� ���'؏�������D-5#-�&�喝D�Uw�,� D@9#/[(��>�2d�?�ۍc94,����I$�;�]���I��))���2��bZ ���m�ӽi��uq�w�oȧ��N���)"��~�]b�����/Kᒛ��o�Y���}�q�uo�0woo�6�F�+0?r�ӌݩM�"�\ܦR����o 33 ;��0��D��w�ǂ�����}4�|�����~���O�߭�[A%��/���={7��8~w�������n:���QRR��"�2m!�\��;��!���7�V�fIJ�x�1)@���)Q2?_��7�Ѯ��һ�?�Nd���3'�; ��d���B�QCF؉淩��DRѐN�(o@d�! K#p�����b`^A���5���p �F����`G� �,�[x�S��C�� #)B����}���y����W9o��������$�_��cX��W�j����װ%�o`�Y��"�D��r'��Q��ȹg����?յ�����_H��l����6�B �A�!��?����8烟t�XƜ������v�HCmS�]�`|�@{��|S�8sO�#/wR�$j��s�ܠ�)�Q�~��E ��:���z���#)����:�+P�<@����¥�?�˰=�ܡ��D<���FE#!�v���,�W���p��m���r|��#-�@f����C�@u���o$�T�`T>�΅�>^��W����/�+��c�a�o����+dh|�ew�-Nϲ ��C��*�ې�؇�L� 1 N#$�Oj�S�>�� �����.�`h�#)}^�_�"�}}��lv�jk�{� O{��J;=M�W��֣;[�mb"_݈��� $˛��$_ �|P+���pGhda\��=�%`p��?�4����.Bv���*�Tg���I>�F��v�����:`��br ��s�7����y� ��v#z۠�dB�V�#J���p2nD�,�pK��U4�pᱬ*蘑�)���Q8��gID�5//�L0 �t��R $�)Ks�w�h��a���-��G�-� %������q�&ޝNdS0��G�-fy�X)"�>�#)� l��V�|�'�<��T�(�/��{ L�S�`Z6KRD��kÀ� ���{Ob'����>����#)��Ì�+��n6wF?�[G�3#)��M�������O�}~��aR�������7Z�'�K{��s���*%1%U~�QG�IB��8��r����i���Y�i�b��mJ���j�fg����=G|������*;T���iO�z��z�+���o�uU[T�P1W0Q�����G���D6��#/��(rX�b���~Q�������h�$���4���5s���N��/͒.a8\㺔�� �zc~�I�W���+��w��e?���cO�9^�K"�/������ޢ��>�#/�z#/��Wr�L���2]�,gXi�=�]9��(�n� ��F�Oc�O���,��z�G���L�V���, �X�#)���v��E:�#-�S��Jw�5S3`Q��,K%'B �F��1���_�Z��ӕ�z�N�a�=>��v�}V�8U�!��RȬ��,JfQ�]���F�U�\7H���l�LAY$I*���6QM���X���'4אz>�Wۤ�� Ӏ�A�}����ռ��PPp_+���`��� k�|���g��6;R9�w��7?V�Sd?`4�lw!ikۻb��k&���׵b� �jC!��#-�)D@��rR��by)y=����o#)4��z2:o;s���G[�Qi^��4�����z~���I9W,����C� ӊC�Ga�۸�wtB��SIϘ;\�'��w[���msu"�2#C� i#/����}l����{{�ga�p'�Ve&$��$��G#-���)�#/(�߽d�������-+^^�C�O_�{.�T�D�m�}A��||���Ԩ~D/�C�6|��V���ޙ0�R��a X����*�$���V�|���ÿf�!@�.*� �˂^B�#-tUO���|�QH}$ �#�G<�:�G<�rB��J�<�#-�T��eBS\ �h>G��g��YRZFo����� ���c��gH���裼$�#�'��!������@����H�S�,�a]c�� J�99�|A�Y�%���!� �$��/?=ѳCq���G�3�#/�������/��#-��K!������,����?��=y���;q �@/b�#/�J�EQ�9�g#/ ���G�~{* ���Ξ��PO<����Ȁ�>��/�8Xc8���H��.ce �E �J�Ip��}n4��0��ǯKe��R��j�"��Y.. O��`��fo�X�A ��@��� �#-��ӫy��<�#)w��^���a��l��}�K�ET‚g����ӫ%:�'ٻѰ{T���/\#-�U:�$d��\U���A¦� luy+*O �X ES�#)0��8��Q %A�P0�Anߍl��/g��*|7*�5�^�w� ݒd0�oe*#�>1d���$�N ���b�Y"�#�f}�>+�x�"r!�#/��IH�����$�bL�Dh�b1"m0�F"^���o~.���-��mn~̨9��F�4c�wp�Πz�U*��dqEtO�QiN�K֡��l���8���k�� t��Xr�����h�#-��5��2{��"��;u�ͳ�;�R(X5I&���hӀ��kK��(L�}��$�ӽ9;Q:��K�gӧ]���n*��ep?�Ķ\A�N�9n#)��=A��6�oU�h�"�5CJ�����Ng�H�Fl!�IXB�F("G �Kr>P���<�;�:�օ��ݐq.�dH%VeU�-�Ëó�˔��m;MQ�]���!�V�U쒓��]�Q��g^�0P>����%'c��zѭ�X(����bbns5���a����Gqi���R��l��[}��4��u'�8�����MR��&7 �o��� ��~}�7�y�/�#���u�[Chfq �X�џ���c��~�j��3������l��+���X�#)s�,Z����ukgl+ �#�G*{�!D�ċh�"�(��#)�4�V]��աA�7@h#-�3#-z$G�d���S:B�l���~e��gY�b p,���C����0U�.��}��#-�,�Ӊ�@���b��v�p��䙃m����^�6xm*n`RHWO�<����<bH���+�?����ڗ��>�x�,x�u�݁��ʥ�"I��_�?~�*� Æ����-i�r~���lnns�,C@k���Ϭ#-�����[M�BA�"!���#-� &�H-�������+�|�j��B�z�^$D~aq���E��<ߣ�8P�Gʎy5nםh��r:��Ǹ��9<>�W��!Ju[��dyy�4�o�8���^巺�eX�U��Gr`����6C�0��z-�.�?NR�_��r=�5�Hi�P΀��t�:�#���3i�O�+~� coÄ��B�aR|r^(�J�i�������T,P@"X �,'eXuʐ��V��0�66��Kw�:�#�r=��[��>߼�#-d0M+�k�ߺV���B�%�TbL���r� B$`W���ҳ#-��{��™&H1O" ������T��}%��ڮ\c�����3?ݡF%~���[�N*Fn}�#/!FZ�o9�L�d��<�v�,�Z5`��*��~&D%���� ���t&c�NH���B��:xjai*f)\a+*y���mO��������� ��(kf:����،�� �DX���&4���2�]pMc=g�s9��B�lb[�5sA���E���V���T�i#/aOG1�A��bS��#�����wx���籵�À Cٕ��߂~�#)W�5:�J��X�$�l�*��d��Ϧr�X/�i���mV���o��v��[�F/��Z�q�|��#-#/KE��ZE�q������������zS��$��#)�#/�f˻��w�� N����J�#)M Ī-����m�*��-�=��@�`G���D#��5��c��~�B���O��{��7��e�8�ҍ,;��;��5�1�~漱y~-�~���#)m�r0�kFSH����� �ِ��V#/~���V��_� �}�ۓ>��OO����}de�ߔ�$#-_2�����]��O�^�0���#-��,�&����~�//�U��!��?��]�>B�7�@>;���~cFn��I�.�=�י6ɼ}O#)d��*6<�� <�=�͸�_��+��`��ޘ��r 7�,���?nj���g�b����S�}`���;��a�p�u;f,���2�P]S|�MBK��^#-�l�9<)d��E�'$^�s*��f��1,h?���+��6���G|EJm�U��w���'��E�(�� ��v�z�����N��^/Nt{� ��w�(�*7�䏄���I��T-C/ٖ����+��Y��t���vzqH~D�?G��y4� I~���C�p�Fb#/��(|��#�����_#)h�G��U�}�j)�'�������"�@��D��#e���;w�+�e�PJm�U#/��a�˲C߀�E!�I0�8 t �"��%U�|�olm��v0U��Ë ?���]j��Eʊ9�I�d�}�~7��X34m�4��v�ٟ���0������o|<�f�s�)p��{�~F�C�'y��H����G��aDP2t���otO�;)%nQ!;�Iߠ�������#/��pk��P��!Ύ���i+ިsT�XYz�%�zs,t�Uꛫ{�#-<%-u�Hi#-�3 �ء�b^�_�v�\1����c��b u�b`Pm���m#/�:�|���;5aCl|�<*:yo>zbM�u'Y��q3���#-�г>��K�x�7�i3Jc�;6S/gl�u��#{ֻ3���\�b#)xiG�g�����yb@3��:-0��W��o?���\=>�Q��fa��o֝��5��)�Y����kʻLӻϞ p���� DN&�6iQ-9z-�b�w��F�-�hȁ�^P)�Q*@KH���&��Dl6�#-cߦp~�j-�Q��G�c����O��zP3�����-�Tw�����������o���Q���<�4m|�z�U챔b��>��x����δ0�}ZQ^(9�#)�]= ��\�P�D�ߣ���$yAR�#))aN^�F#�H@e��U‚�Yӏ*li"4{�� i��z�v���~�<�|�Xm�<�O|Է0����D�E�FQ��O�Q�H�L�|���:c7���v��L���7 �Ƚ�����������=~��M���A限�p�ݤ�Ꙛ��s��� �g11g�>&��Fr IS"#/�Fv�1��8I�՟g#���;�n���Z���h����8�U���Q֫BFeR,#cqauY#ǘF �y��*���H`ص�I�贺�0j��ǟ��g��(�,���;���SP�)#/ �8#)$Q���yM��=\4~?�e��@2�z���N7��#/�ݸM/?�4��t����}�t4:�_��^w¥}�v9iDL�An ��u�v8~_XN#�~?jp��~�#)�$!!�1�oUUU��[�`�Nc#-��#)p��7@H;�A`6��&ۍ�ፁی�����o8F�BJD�P������6^ۤ�6<#/j�&�ث��,��tͤ#)�#/3��#/I-��y���Q�X2]�h�y�eȜ[�u�up*��Jn�*.�����[�Y�����-�Vq�@ƴ�oO��ǝ�aUk�¦��Sq��L�`��,�ݴ���ԏD���q3)(4�*$]��m���i���b�N:�#q� ��'��,�p:���!{��~�0�O9_Ʃ�g�ߩ�^��Y���l��$�/�#)0�<$�t����#-|9ߠ�9|@C���!T��#-=�Cr#-bl���@�!�4H,��!��#��������f��o �9�`�4�۲b)G�V�v�JH>#D��w#/K�ł��E .�e�EEb�,�������AX˸-�#Vy�Z��E�&F���,Y��Kb_Ni���ύa�c�����UM���e������#-dӒC��G)��AkotcC~^d#/2��#)����8I $�g��o�T�T��������pk������^{ IA��#s�_�Б�i�#H$zZDx#/�����o�.#5U��#��O9\��L:W�,y!O! e��=;�Z��w�(�[���,�Y��`']�L���5m��3�f��#�l���[}oM��M�.�j��V�@�#-���[�Yr�Yu0zk�P=�V%O2�(�����J(���Hk�2fd�q��D���y"�.�I5�ױ�]�#-�����0� V��蹼#-9�IE�����aښ��*v;�# �+ �(���T�]�V�d:U�Cϑ�˼�x��H�C�:��#ػ#)�2�Kbm �U��#-���b����#��#kkϲ#-���"+�S��5f#/4L��"��С��iH���Ԋ�Q�*c��O�$g/��u�v��Rb#)�4��Y�]�u��E��Q�� �S$��B!��c��5�H�7���FA��ÑMa!}��bȩ z 5��7#-E#�>bƁ �q�2&X`dF���`r83�keUF�^���Ӧ�u 顉 �7;�I��%�:1��q�� �5����X���T*v�Cr��`ܮ#)�"Ch�l�3��o��JW�������H8�1Y�3U�v�G��]E5�{$��#:��Z p#���{����"��#aCi#-����W��7ҹ��B�A�����\˕$�M�IAd���^��Zzl�,\� Lfx5��O�Z4sx���s˛H��*�"�xx�O+��74�#-X��o(hmIx��/ud��ߏ��]i��D�@��2 g˸5 ���m�7�nl�$�I�����r�A��듌O��(�?�ܦ��C$���M��;�q;#x6�P[�z���1wm�u�������d��lju?�zG�?dQ��黶�t�L�!=�H쾂z:��ӽ���l�[����q�dM�'Xvc=o��X�`���pedt�Ԫ�g��M�x�����؃�Z#/V����{�'e��BOXxشh�Xb���b0F͐�{6��#/F���H@�rq� x(�A���0>__uHՑpWZ�#/G��0s��H������,����:W��j��� AAO�TETd7���kS�T�.�(�f�(����(���y�����m�!��g�"�����~��z��"@��� B��JR&%o~�$��[v���"1)��%\�R矠��uT. V��pd����Z��ج�R�x�!��;�z��uo1^���鿀�u� �D�������;�Q���c�)��D�T#/�j-"��u�h�y�&��c��o��;�N#/��j�k�Tf���OJgH�T5����DA��`�6$-��&�M��c�"���0����pT�?&F2B���;�oT� �7D��_���y{C#)X��A�`��3;XE���!&l����ysM�7V��{ n�� _��ϷJ�8B�o�#�N�s׫hw��Q}!\��#)�V H������6���o�Xڹh�ZK�BG��;��;���TD5�U��m�kkt��Ul�8���!�OORI�;p�Y��e��(�0�ij��I� KVl�U�:�#-a�)�`�c4 �ő�#-� #��?�G���?� 0�k�R�L[�ݼzm��M�nk�(�ݠ����-���ͼ\�1���nY++�F�z% t�ѥ�J �L������|,���ξ�l�@�!$J�gps��̐�i�e#-��s�'����`{ �Of��O�������%������e����ݜ�c��i~i�;Ǟ{�b�]�dH�����vp���`Sۜ�>���8�}j1��P���$M��fZ&���؉�?.�\�۫B��0��J��rF]��1��4�r:��r��ؽC���1-�#)��@_�H��R��?�~���\;���0�[�,.؄�r�7V�%"�3� '�*H��BP†���}*pt0SK#/K���\�cr!�d#-��xrn��YZ�=�~�-������h�O�o������o#-"Bo��#-��Oy���~�������U���{a .��w���-$%�����6:(|���!���ӫ2�z�0ǒ��!;�DK%�����^N�$+f��1&�y��9�m*�`� �y���s�gbQ�L*�O�4��I?7˸��j�);�~����O&�(%�&���kK��z�^��@@�*�!��afj�� H"��9���W�Rt���Is-�P�BNڄ�p5���𽮖�[`�͟���x��6���*������#/�Z}�B��FS�?�-&���ZR�?����!$ kh-�J�[%�V4�eTb�YYmX�m��J�֓Z�ʍ3��)#)V1�S�~G���渖��9��vUuç҇TA�Q �� ���C�#),x#�#)�P}w���a�{���uX �Km~�s!Cᡱ�G5jа�,�X�ڊ�ȥ�b�aX9�;f��ސ����/�] $N �#)�il�6�M"iҾU744�dZ�8ab��_J� �&j��ν�t�#/�����ީJ�h��v3�N{�uqUC&�ݨ$[j]8l��]*�zD`So}����=]T�WUk���Z�?���gj䢖��,$�C��)#/�H�>̵��$���sd�kr���L���5&�6��d�TE�o�}��w��Wߖr����8��#) HAdA�N�U�G��8����^��g����T�G i �8�D��P �'��A�^��N�|.�$�P#-��y��m>�i�w���~���^���h�{�{��(F@��Y%��vx2�PX>��SwZ����U��~k?K����(��*�#u�}�qӧU��X�ʅ:4�x���(��$&߷M.��[��6u�D���~ZP�L}�����Fj${_��<�'g�Aē�Ћ���A#-�Zb ���i�0"$�X�ߘ���۰�:A��5S���2�u#-Ou� *}���9,���*_�^Y���5�6@A4�lK�0���i�|��m�n���ua��_����<��}v~�8Z?�j@�;H�_W����?�G�C���s���.g��r0N���8WN��ҋ}��#)��&ěF���!P��0@�=�2�pU�(�4G�w��?*� �=$6<��#-�o��__�a�j#)�(�{{#)f�\d]Ψ}|���C!�`�:�J f�2��F��<�8�]�F����br!m��lN�8��y��=h�*�k�r��gY��C$3�C�e&S���Wd+\s1�8�;�R� =�}#�#)��D�RTT=��tx�'{�t��)耆�Σ�f+n����xȐ������򆔅�����J5��oC��qH���UB�AdDd!����G#/�f�e� ����Oc��ӻ�TMP�b����7�q�B]��5}-,�F2"��Y�C#-�`�\��>! u��X�A3�d�4�e�7W�:z�Z�5��P9#-�Z�рx����x=�d�1"�w@;�i YY�_A`e��5�@�R�x �K��ߛzu�oj��G��̢|��z/���p��������oyЩV���Q0-�t��i��o��t@sz�G�����t�]�Ou���Üq���1в�f��[d�M� r��>��z�@�7��x��h����DP$S �x7�m��"�[lmp�胁7�l�s��y6��m\9�7�`�WpS�c��Ʀ���S���PV;V�YJE��Yͨ�R�ȵ��A�E A�WDG����St���|�C�CG��͇^�ϯe��O8!�5�o�}�5��&=�ÿ��9���! ��a����P#/!�h{��H��B���`%jBU�J�))B�=��џ'��X%��)W� �����@ua��p�dOľ�::�"lh���o��BB.��g�1m���~pT���F�y#-����C���H��z��E���m�]�=�) v�#����(���l|.�U�w�~����f@9�F�n��f�u��xgsbX��9�Љ`=��6Kٟ$�������Հ8i��}H@�m1�׸�f�ܱ1���P4ls��#��8���F�:�2UT�b B&�.�߿\ 1va��>w��Y�1٦�в���=��Ow���CԊ�z�org" �3�S$��Ξ��?3�ӷN��۴��Lu�zt��`eH�;o��t�x==��C��~��v.Ž���^�cj��Z��8������>*k� �٢�d�ʇ)ZRI֦�t�ԍ����ȏ#]IqB'}�_ *~�t�c�:V@�3c��d�E3T��� ��~"2)�ώ^����:���v{�kf�T���:�s��/#��Ū�&��V�b�F�l��K�);����rX�SKj/���F�!V����Td-6��HQ�#/���J]�.��dG ��Fm.� %�#)m!�@0��V��k��hjk�%Y�H#/�&��N�xPz9maM��Vw���q�_?�}�����~���x�JTA�JIP#-��*�X5�o�B��$���mP�B��:�*�|��|����v���?�]� /��R�Q[�ꫝ��K4�I�#gm����S�P��M�8�٢�� [3���R:M��#/�"����f[+����'�ʑ���Y��Uc��{��^[�=�x$����$��> 4�U������ ��L�#/"�D�R��h����[!)"��HQg�ݤ止��jx�>�g����(Qp�9��ȒH�E���� ��9�u4an��4��kˀ�I ��p�ξ���t�ϊ���Urp:k;d�&��(��`S'\DP ij�J��H���b�W�m)c[bf�UT����RD�#)����߄{���bv�#�:�������cn.��X��#/"�TC��#-�4:kz�L���`���x7H��#-���Y��&o�o�i�g[&4�S$.wy}�3��|ߦ"��m���}]��~��W��E���O�����#-k" �`���H���tc�ή��T�;��N"�}: $ 3Rk-+Yj6@|�D/�B���3W�(߶��* ��B�3�{��'@�/]�k��[��j���Hڍ�����m��@�s9w.p.˥��1�n'��$Ґ\��&qL���7k�S�"���yf��#���s��_#/����R��b���U [��iv#-�^� �<� ���r��2��/`P*#/��gYY�)�,Ѡ�o�yv1RAJ5�0#/!�F"��hi�"a�� �<�-h��-�<��3�ܱ���Аxش��8�X KV�F�Q ����uu��F�����e� ���s�<�s�l������D��#�4�d^M���k #)�o��F/w,���6���գ6�=�O���of����B<;�:����}��$ЋE��z�)�'���/�KY/٘�7鬛����#)I�P���2!D�*�Hm�|��\2,aʲ=�Z�Oor>�r_N���)d����o� S3A�w,~��yD���p��آ�U*�����@d �#-A�U:������s�A�C������N�9�[�#)Σ��7*UUzK"riqJ\Tb"���U`��b��eK�Lsש�w���=�J�QQ,,`��u���ˏ:��_�.�5�;^{:�z���au��lU��hhD4cJԞ��&$���D�#)B����r0*�Zb�#��ts�rׂ��' �وL2n���M��@y�iЪ)Q���#)�W;�Ν* I7�QC�Ƽtl��V|4��AF��#)#)�;�檦‰�SPXF@��.ˊBn�J�U�<�f�5g#H��}N�#-��#ξ��ml6�Qǧ,��2K�Q��&ј�\�*��01��<0�:�(�e'������&O#/!\4c���F�(���$1��������,Rޫ)Y4��Fr9V#-6)�����z5 [E"�QA҇���8�p�����f��r`�ƈ��� f�W�!FN�'1 Mc�djB~���)��Ycd)���Ƒ��x �d��FS��#-cot�,{)ٍ�0X���7#k�ͅt�W&�[˷����k��q����:�¿{ע�b=c���J`�z�BLQq���?����{ץ�ҢK���t�a�i���g��]a����BT�ts��C�y�G�Q�/�G�V�+&�5�6�-�y6 �i"H��#/�A$Ș�!�@�c�j��\U7�.J�Q�j� GR��O�|�ph���H!�T9@6\�f��r#�L�(6�2�b% mZ74I�Т�����MD&�0$ٰvt��#ń;�ô�m��w�G� �8k������QJ�l!�����L�U)hn��8T4-�" X #-#-��ȭ[&fV����.۹���9�ML��5#���#|���[�A����u��_k�A�:�QB3�e��'��8����`�t%�u����"U�JbCd���M�p��i�U#)l�v�5��!�Q =��~������86C�"4(4��5""��Co�@�6#�NQ�i@��> v���h�ca7��9��/�_���=L�[8q�Ú����׋ƺ�;q:X��t3�ۖ�=�ق�WD�-� bP@�-`�ܧ�&�e�Qd�t՟a5v��#-��jg���>q�c�C��9����o�mR��ڷF����3L���u��g)��;Y.E����#�`M�=�^C�?|;$�{'/��~�fY���4 �2#)�#-��o���N�}Mm�ac���@%XV"(���bs�hI��=���c���`͹�{�nP d�ƕ ��H�&�4 ���B���L,��fh#/l�#)��S�`��X g7C1 S�H0`�oa�F@�����M�!�ش���ȸ�2�|�m��B΃��e�����v��5�� ��گ$y��#�d�E�{5R�ɠӿ���̾'��1x? ���Ei�Tל���jJpc�,̸��[��|�����$"������OrZ��R��~e��A`V��E��W6���mEo���m�j��]-.� ��vw�\N�/��Ջ�rw�⫕H�#)��33���Y��4��\.z�ܼ�kZ�ReHВ L���+L�$�&����5�I���0b�i�C%4D�Eic^��C&���J%2�hS&&i�#0(Њ��%(�_uIdP�Jb�RYC#-PL��J�A2�E�2V���R(� ��5R�1�#-3i�i �Ai���rM��mN#�#/�_�)�b|�|X&A�~l�U_SBݘ���3fD~��w�9lY!,��A�׉�i3@���s����9`�� ��g�Ŋ1�%��q�.�G\ή�bv��F�$�F~�%���݋�}��%��<��,媗d/v%ۚ�����#�2�7D���#b! 9uf�T�`��c�������kuݹ���bm�� ��d� �����Z�^�o�_�bc5��#f�V*(��i�`B�Xy�ϗ�}����u�3aDPn� ;~�v{3�= ʩ��� =z�0�RS8H���թ��)��[8͏~�O�~�4�L�+�:�� 1�8��wR>���~��֟N��3�=N��%ڡ9�W2����A���g��ˈ�L��0=m� �p{"�>���N"/��C�)QR #/U$I#)�ܙ1� ���H��Q�~�~Yw�1�R�="(�2�F^#->�p}��1��J��x� nk�w��<���;Y���P4p���}Z�~�tI-��O>�oi����ȸ���*s�.#/mf�8�X�P���†���U����y�k�4₶���0�#)I�B�FM�w��p�$���76��[��j t@�B�Lv�Q��+�1�-��/�YӇ����:��w�hג]�mw3�FW�bT�����rC��s/ )X{N �L�'��&�BbP��{�2vN�#-��"!UE�eH���U����J���ʳK�h�#����Ħa i��F�����EL������Œ��tӃ{��m?���7���1csQ�t�Σ�CL�[l��͌�9�B� XgF�E5(Ԧ.3Z�H��X\o m.t�fں���-�`O6���)A-L����^%�$�t�/�����7���Qæ� ݦ� �2�8�?7\b.��&�e�=Y$�j,�B��9+Ҟ�.o(ާt��]iڃK�T� -������t���x3Fӕ��3��X��$0�7 $��l���lI9+H�IѰ~Z� �����!z/�,�7#/��R[�&*_������������4�To#-�>�02�!�n�6#-�Ω���с�Đ�Lc�:R7f��"7J�ՆB���h`����XD�����12v�2�t�џ���h�F9������ i�5�zY̳�~s��[i���cÓX�t��؂��v�&0#/ �����/#-�r��,�)N��4bц� I��.��s�П��{���Ɯ���$�.6�ވ����Y�����t|T�z�R3��L�N�v����Y��͔#|O�k� � �ݶ!>�3��O���N����X}�kQ���ǖ(#;cC�I4js��pumZ6�cx��b��.9�{���3#-����� P��I��=���s���Xݮ2P��qu=�th�s4��ZgV4BL��1�yRw"$�kfM�(}����%�meӊ�`�ݡ�)C��]��4Ȗ���d�z4��r���= aE�P�X�i�SW(�m���/ް�Ɇ%+a[��*ɾ�U�쌦�!2�(ƪ��cfz�9�Rw\��~9w2W�<��,��Q���!�9n�6�4��� kKc�2��������H���u��pU����rs)����H1��tî�p�\5NK��MzɵQ��4�P���\*[ �Qy��z#/i���u�%Hj����T�H���j&n��Ē޸7����f��g���6v��q�ΰ�tyYzL�k�,�]EƐ<�iQ!���Xlh���p��NV�Nځ]#- ��H.q���:��R�IFȡ�b�<�P���ԙ���)>�4=���#/Y����E�&)�+��a��f��C\ı�5F7w����#/�b��=2"��r\$d!�'tf�m��l�z�U}ؒ�J#/��^��n��%�"eB|�8��N�0j۬�}x7[5[sgWXf&�,.~�x}w8��WaN.ff11%3�9��n!��Mr�ë��\���k({{����lQU#ӨBY��r�㡭7���e���cs,�c/�Q��%���/���58Q��z�E��<�&e����Q��5�Tl� ���ܸ���*#-��O�1��W���� i�#\[eqp������UX6���k�C(WG12p��8�MMՃ�F9#��i��$�#-��ٜ]k��c�-��ޱ�&��#���)�X��Q:QTT�U!�D���)�E� ���H)W�<6��n�i'#-;&��CtH,wU�Ꝍ�yb��vv� ���-U\�)�ٞ�-8�b��;�J|��7o Ժ��|�&���"�P�&�zH�9�/F���P�9�#)�������i�i.�To^Ň&���ml�J�Z�5/Epf�Ǖ�7�Ll��V��[�̸��Gv�wif��b�]��V��j��X�]�&��� �%ސ �L����lM�(��GE�D�,���Y�ӌ��fp�Vmrt1��=D�.�Pa�ţ�#��wb��hTk�!Kႂ�����������`ȳ#�`9>�nqի��I��m�)��⁰��'&x�le,Tm�T� ����E/,-�û#-ұ�p��04@�!�J�Q�&�����\���,fn �&SS4�,����&��)�U).�:�Jp$�B�t�����m$FZ����jl��X����%�[Ja�kd�r&\�*N,��� ���jS�5@с�i��5͜#-8� �v�!>9�eV'���A� ��ء��6ʹt`��N�3�aTB�eq��=Fy�\�mC� D�0كi�t���A�;H�wn�!�l�}�q�o���]�q+���Y�L�F��j��fcO���:[!͎ �@:�4cC#C8-Aon�4>ɫ �Y�U��q��/���gg�'��KD�.��Y��������V��������g��砠�+�Ʉ�&tq�#-)"�[eb �T �r���E�[��= ��B�ԇ"�4�@AC�#/f ��.x�?"�[�R^���(e)#/�#/HZ@���p�[����R��XS8�#�K����4t���2��6�I l�]|/�����X�Z���5H���TX$Ga�Jt�ކ���%ҷ�ir(�CN���ng����7*C(Cb��[8Kb ��9b�dm�U�0&�22G��6�#���a�u���R"C���#)�a3dX]���������8�h��Ǝ�p�UC=�A���D� ����Fz���0F ����n�hg4g.3hn�" '[w: �c�@��sdh�قə<�I)F��P8�&#/f� i���v�2�lCnBd�j�23i��T�p#�&wM��+q*���.�v�#-0� ��lK9�00���#)�5N�tXk��J�Y3FL՚��|��C�7�?�$�B&�"hgx#-*nD�P�D}�H���6rQ��C������Ƕ��U�ѫ`��#)A>5F���d�u"##)DN�s�R~�9Ƥ�@�:@����TC8� � ��8�(� �rO�-�L�(C���$�S�URa�ϥ���V�C��N ~Qdp�q�}�8qispj�)�Ѽd���u�Qv"ì#5������b��ۨXE�0@�C�q�*G\�'I�eK�ZF�̓$��d!��#xF�##��Co�w`d�pC�p�"���o��� #-�H���RC�����F#/A���g�U֠mO�"�#-1#�`�B7 B*�#)BƊ!Cd^>qJʁ�m0��b��g�b4lF����F����-#/���^�!��\������C$&�X���7�^=���<,p?-dȸ|����A�r~����m���>Lr�=ٗ�F��wG*ɽ�f�&�y.U����1�������{|&3pZ5��[&��dB�b�oQ*�4#/:`�Z�0�4�Αs.7� � �ϖFiE�#-%�4x�{1�"�����.\���b��3#/٠�NG��Q�0�J��)5��XѨ��j$Ƣ&I�f���AE�,b�����ַ��>I����J�S�J�S�޿�2 ��t��h�o�@���A�0~��^�6�IfO�m�'��Z��y��@�%9DAʀ�0�O'W������2�����xL��Z�t.@�Iʁ�]ْ��4�U�Hm$�?#-�E��@!ۮ��I�@)��Ŵ���-���4�L�d��p��R�7��Q�zx�^w\�ߵ�^��ʺ@nɁ0ɅE�1 i Ь$�Ŗ]P)�-���j�d��a���e"f�83��T"�s{�F3�:�сYhx��rF������0#/��K{��oRC�f<�� ��(��z��#-s�dd�������2Րi���n��.���d��#��R�UC��uHq�#/D�-�Z�W����$!�F�&� !K���)l���^#)H�x �IJd+�Fk��L[//��H�yA�;��nQvId! D*�, JR��[?hk%��u����#/�^#/�� �`�0H�hsI`�_�#)�=��*��fV�}31�te���q#k'�*(��3��AŽc}"�aV��9+h��&E�ה|=uɟ"�Ӓ)�����9x֐�Ho�*#�|1)�7v��#H���Pފp�(e�\��#-!4��Y��w*\[���$�!��M`vhU#/���i!K�b�g��:�'5��bCJ��Z�ĭ�nj�%�N @��"r���+t﹵��+E�eG��p�0~=l��$�r/3 $P��c#-հ)†�6�eP��%*� �U�eYN�9#/3���l+M�r���j]�0ֹ��h�č('<���;X�B&�[M"���ս1���C!aa�} �Q�dB�c�2�۫��A���K-�n�Ĩ�Q4�I�F�����I8#)Z�H#/�����]y63��Y��� �@A]�x��?Xvה|ʤm�oz����i�"��@��?�[�"�(��O�Ά�|��l!��ֶ���C���7A�L�D>Qu��Jb`FC�+�d�& �I#^#)���vM��Y6Ս[I�j�m�i$� S�h}J��F�J�2�b�yC+Qk�>kyC���0Z�K�⸚�-�J���#-�Օ��U�ڎ[U��ȡ�ogM8k;ĭ�L��V�fFT�qK-fS�e�6�M�M��[��jZ���t�42aS��F�t�^&�5�� D#-�Q�nf�L2�a�$m�n������^�1�>ܑ$�SNDI�e�Rn���.�4A�Ά�p�T".�F�g[S��8�"�n)ʘ��;x\:1�����i��D�����*�n�%�#/�)���7`$��H�fn!��T<Οh��40�+��:IS�&�2l�HYzZ� ����<�]"��&B�����"�ƅN� �ȤHCޕK���6(�kj���4`u����` Ț���T/�|qucX�]�ʥ��f̡&�$�r����8ڥ���ER����.�R#-�]�^qc]nm��v�#-4��z� 9�ХJUr����1����:��G��'�\�A�A�lm!*��\��*���l]�鱀ܐ1�q�+V2�S$n��O'�qK�[��nj�U�Wi5�t���)7��]�L��<�w�W�bcJ�Mn�5F���v��{�4p�J)�lԁ��[E��#*�B�L��X��R)��Z�ZYKL��̩��O��^xME� *f�VЕlғm%�^S��oR��LljE�5����rL��$�(`@P�����AK�(�H��\TA�o��";����=�^x�����z���)a�� B�h=��0�� �bz;M��$$ <��,�E����qaߞ��P31b� �H�m�����\h��7�N�Td��9�Wtn��/Rm1J���"c��J�Q�! �#)��J����L2��#)�Hm-�8q�[ҖQ��,6S# ��E����l�)����р10�o��O��#/CʸZ��dW�r$#/�� �A�Q�6p�������{�<����#=C��h�p���׫��~,d�?L��7��/4^�t"�ˎ7G��+��#-�zb3z�Z"��C&ْU�/HUK�l���x3ݟb����L8]d��Gi��iZ���K�v$#/��&���m��П��K��B���~���"��0T����/���c]��u�[�?����M��2u �n����d������4m��߼��"F�)uQH{-����#/�nX�#/I�׍#)jm�)��ii���[F�F#)!��=�6�&#)j�EEV$�2��DTd�0����5so�u�)U��b�fDd�@!e"�aւ�SaMw��)E��PA�%�Q���Ķ�BQiI�Sm�6�3k&�SE*So�ܡ�e���%���eiI#/46�e)�MI�6f2�PX�4el��&I,� �V-R�AQR�*R�*��RU!�$mJ!��i�d(II�&Ra4�4�R�T��VD�����Rd�f�ԳY2hҒX�`�P�$�AH m��YjCIoymk�͛Z��Y+V�W�W�=�\ֽf��F�K`��j�B#)$(�"'2IF���פ9;C�r�h9�d���#�7����+�#-�\֫㨂��0{'~��,唢jd�C�^��o""y8i��gI*L�0��y�#���OGmKTI}Xq���(�g�Q~Q=w�z��;c� Y�w�E�g���Rk��^S%P�kf�2��Fy.���JQ�IC��K-ZZ��c�;^ݹ����@��+r��ˎ�tOݾ3��Hһ�1FI@Y�mW���##65�J�TAQ���`�v�=�k�#/ ��T�:��TI�[���6�'WPR�v*W��)AqM2S�b�`]/�����b��۫]%����}Aq �֪<�\��v��>�����h�yT �L~���#R�=��)�^ �~w�"HR�v�������G��B�Nн�����(�A�[JB�C<#-��X#V��͐����TF#/߯������C��>7V^ � �1��d�&yi�ؙ����c���,8�g�:16�0��b�`����v!h+�յu��z@Å/�Hv ����������� ��~2�&�¤�id-��,1� H1���@i�II��娊�hnP#/9�d�h�L�6��ڶ����^�خ�4�dX�k�F�Ȳ����z�E���<�QPi�Ӊƒ<�bz��̝:%�hԐ�8d�"L�;!O��D��ד���G��T;NA�x�%U/VTA(��2�3=j�8��J����D#)���� �-�*�8J&�&�M1�@b�@�B%�#-�����{P���g\�=�tY��u �(�4x,y�:I�bB�#-���0��RG����@��/>�>e����p�g��K�)��=��m��!��:D�#-� �5�wn BnC#���ݩ����ZrF�����!N��6�����ar%qu�j&d s��@9*�}(�^����zv�3���V��T.4�;�3sΌ�9�A�D��J��1��,�"�NU^��4>���I�&J��s0�8,"���N2��߸�C�^#)�^f��pT�Y#J��bW� @gU�J�fT(#-�2�p�`8��p��v3�{�rcy�ww��ƙ�1��>��5&7�"��H�*�1hҵ�%$Tҩ�Rl�TƆ���O����$�dM����k��L�p�ے�.y�Znj�#-�/;��]]ܠ@ $#8kX7 D�!�~^��Ҫ(��)��� ��By1g�a�xu�#/�{Wa��Ü��� �EHw�D�|g�{�{������ǟmk��XL��u#]��F�\h���̎NRM�ݢX���bb(z�&�Ɣp�wyzs�����a�������ZW��)�PN�M;����{p��݌�<��1!ON�-����ϡe���#/��SY}������Y����#/F��,0%�q.��F�i�ؒM��C2=9yr��6�[�&e�d��Т�#T(2�/"صk�S���)x�ݸ�&�\�/d��j��y�ۖ��Pc nκ�e�$�tw�}���ᮋ�G��}_f�C�r@F ���!��}�3�c;�.4��bE;Z��b�~�J�f^��5����f�)'�hwJM�0�����V�Y6���?Ґ,��S&Fl7$��&� 6��QkU�2���MJ���LIdlV-�oΫr1b+F���x\�%�PF _��j�VE"H����hb��.p+� ��b�4,�{�ˮ�g2�ZB[%%D(d� ��c:cgTF�G7��0A���ByͶEָH�p��2 M�X�bR�i �5+�?^����婰nXG��%���x����$��ECU�B9l����M�^.V������~N#/J�H���i�&,�&����2���P�5��H�E,�FEF�h�5;[m�Z����~�y���26@��,���2囑�q�8ޣ�#)!tH&A��zm�>O�8< ���`�"�i(� [`,n-g�d���(���?,}����s�M�p.E�.#)$���q���#)�%퉨7�{J�o���߭��w���Q����)#)8�T~ΠM�dL�d6�_#W�����f/��r��� �ΐ4K�^�n�&����Q��2�zi�#/�QV�$��q����9��?�"HC��]f\^ިo�У��x��T,���;:�xCA�x=Ƞu�Bk�)�)���g��G��_���H'����V+k�ʶ��\�ںYVA**TPE��`�^)QY�,�䢴�5����;��̸�j?G���0mM"�n5� [�~���"dw�����^�5?/�p�nV!���i&��'�(�� ��j/+9��A��:����:� C��[!�as%�E IH�^E�_c�|� �R���g����ىu(0�� �Rg�:� �^��z��-5�ʁ�6ٷ��(;�͡���d���T�5e���֟��;Ȩ��"tP#8~aϳ����$Q֐ޤ_�֚?;0�M���uCF� �QT*���qML�)�U$)���;�Vha��ԁ����/o��w�j��V���k���V<`]u#/��,���Ii���%s�t�t�`7l8`F��AFL�+]$�eݵ&B�)��Ɇޡ�L��DqI���lb-���F����̬��F��BjcU��F�%Q��T|Z�j�hŷ�j#-�PU���́�117�)� ]"W����6�m��o&��Ɩ�!��FFs��ؐ�b �ZM��F`L%���Yl��Bdo%���#-�*°�0�&�P��`N�Y%�G]C[�*�1^N�ۚ�\�Fһ��r���r�7�I�z���`��T�2,U�"$�md�6��gI�1�N�,f0�A��Τ]���a�XH�|8�#-j�Ǝ���CH��\��rCX�tj���4�ihre���-���Ԅ��ؗq��-��#-;�P��'Z@�FA@�/��C��Km�z*L\�6'�c�k��wl��f�S2��5��;l�jh�41#CՉ����t��1� ��ו���{��&���������U�g��JJ�!�BI<�5����-�fէtj7/+cR��QeWUҢL��t�lacX�媺��X�m���%���{�e� YPu7V-J� �*?�d�}����Xw"j@QHX�HE����~g��`5?l"R�<~�.V����c�/��h�!���1#)�RER� ���#/�$�#/���7G  'A�uє�e��:o���h��K�����zM5��M�O���7����"�ʫ4!x���,�aa��)Rʮk��6��[�2"�d�bl�Tz�Ŋ�#)،h4L�c2#/&"4F�T-cW���,�’[R`��`���*#)h�Y(UPTQ#�q�jV?>]F��h��ȵ��L���.X�ي4��`O܆�QK�@T�(^�`b8���2e� �bNI,a��"ƚ�#)x7�8#)ME�f����*A.BY�l���i��2՗�zÒؤ�a=��#)� �.>��~4�1�ڋ�L����Ŭ �UI�Ν�ConԈ��GeP�F��aX�#/�\���k���]��**}�"#)m��A�>ި�#-\�{#)�l�z.�;�4!�W��K^9��w�iKJT�cj�׼���U�k)�WQ���5��6�������`#-�w/ "Ѫ���~��R$ a*�h3]���l�)�T��!w�G����j3���sfӾ�֑�a�$9�ӪLM&M�S �M8���ܼ�s���8H�⭾ca�#GN�f��GK:��#���,1v�4" �y�bi����LH��>�#)F9[D$�x��l��C�=� 䞗��#/����}�l�4HD���@�\S���5$J P X��ֵ�n���*0g�)�C�l$qB'h���t�Wӯ���\�-nlQIu/�$#)�E?A����<������3��˺��r�y~���s�{���2&b���|�VG� �����E/i�A#/z|��:�#)����E**������:���#-�~B� ��C'�Il���*��܂%�Kt�D4��By���iS���~\��sþtP�#)E��0*d3�=;i�6BZR�_Ql��Et��̻ �M/Y��>��δH�OQ������zRX&p5p�s��t�o\�q4��Ph� #0�\�l�f�uN AX�%�T �76a�!e?��N�����B'i@��P!r F��RPئ��)a"�%0T$Iɠ����O%��'���K�pM�������vtG����"xUQ# 9�I�2*��<&���<)=��&yw�o#)Ú6�`ޘp�%�|��f;��`�B����*Y��J��;E�koo􍫆��Ed�(�Őb�Pa�Ϳ�g~'�%E ͐� �Rl��YX�"��QX��|�3���R玓yr�) ���}�Iz��y�E"��#-P���E�C��"{ʡH)E�: eݭ�gM� x���ɪDlQ#-#/��(�rQ5���$m�q�IηI2��h�Z^�k#)�T�U!�f���N/��TmĄi��\�J~������o���@N��BX�6m�ZPd-����9Y]�oD�y�P~�; #/�#-;�?J�H�[��b~�f�H#-�&Ⲝ*TNI��Fl�����S�]2����ɜ�Aۗ'G�g֤Hޒ�%?��F�����V�]TS�ĺ�+nj��B���~���9��Br��,��.���Vi�\�o�/�����}�����eȷ�i�k�#/"�1*��`�#)�#) AI#)�IE�[%�€�D�d�*@��������(<��AOq#),�P]�=S��W��n�C�A���L��Z�L���k�7�����lD28t5��T#)#)YD��У���QHi��'!�eV[�Z#)���u_�߅���׹#-wp;�̚���͜M�E�?[�ɞI�T�yJ`z$��B����S�m/;s\�<���]㶺ěi���R$������!ԅH�2��c,��C��zγqE�d?�B��[.�A���!$h1�@��m��ڱ��1�&+Dl� ZӬCa�c@F�"h}3�Z��aM���������i� Ʊ�1 ��#0��2�I��������껬sx� 9@kK-���m�*�E�h`�B��"ZK�ɶ!0Ĉ)��JZ�,#/�5� VP�C�i�%�� ��Fm���H��$l�x0����@�#-��h9�v�QM��#�E ;��Ɉf�l�p##-e�i�}����Jw�������,#/�#�#)eLe�N�>U�����!>�=-.r����O�^�ĺj��~�VʬE�3�L�LJ�w�u������U�-�Э�k̬�YQ���2ѲZM[�5�z���(�#)���ذ�IHR�D>���H/��c�0�������T���[�U����j�T>3P�)N]gW.i��,�#/��>q�l�#/;Z>j��D�b!���ޓ��Q�B�<��m�U�d�b�#-#-�+�K��C�c�Xi)ߖ�؝n6�I6M�A��yL���g^=G�p��s}�a�`3����@ު &�����'Rb��\q�8��ad�dɶ�'ӧ �1c(�Ef�xv완 ��5��j�LC�/��PJۚo��f h�Z%��5��"��]��m�s�6�H_���������G�� j� �"��q�Pcg��/|)��~z���"���k�;.�ݤ�oY���<�6lD}��>�� ��q�������Rw�@�� �!*�#-,!�������f�!���Li�x��ݤ�Κ��'U�.�Mhf����"�(�7��i�����/E �G��/�F��A�����b�<"~Y��P�U�P��&�P��!/js��l�2�,�s��g�|]��/ �B��A�b4�7-��mh��ۚ$������ۺ� �j,�������� ��ݭ��Q�tߪ��*�Y�MA�����_^ d���,s��m "�d�(�QbH$7X6( ؤpR8L��EQ�(7�%>D� ��!�.2��� �q��s8`�:��\�C�֜Ǭ�vjYV_�� ��(��U�X��j�)8!�E��O�i����ՎF���a��zT��k��CN�7t6a�\!yNHRe�L�Һ6y���]I�z i���0#N����$�[|��M���$V�Ւ�佈�އj>F����$ M���� fhv���c�!0�::UH��̪񫭰�Z��ܷWY�4Ք�i۶��؛[f��u[+����˻J�V��YF•*�mUc[W����Ɲ�O�b���JV����5 �9[���\�� ��j,#/I�=w�`e#����5�0u�>V��dd��{�#-�[�r�#- �0���v���#/�%�� �Э�����#�+��43���@��4j�a��w;��bE,����4�#-q�A��o#)��1#)�bL��z����(�ݠ�_�#-�pl�����ɕ������#/�7l!��OAsr>���b2nlj�����+���s#)o�E�~�'��>t�^���5����cEX��j�Ӯ�k@���5���*�f�>��*�5Ut�� (�̊x��;������O�ߺ�-����S�R��$��]'v5Âk�PX��.�KT� �GL���v�,6JB�#)��&���?I���-`����5���z�.�#m��l�AA�[� Z�ip0�];`R��Ö�$C�}��š���X>���(DI��?�X��8"�iѸtSH˥��@~R~Ԩ6(:*�@�U#/��/%���NtM�,�!�2ߍ�7C�k�~P�Y���0ّ��#-4�^)��`��)��`$b6{(4�7 p�p\�D!�k蚯��a��xA��ӥ��gLeXd�b����;`7�xd�5�Run���]3\�k�C�nx��VD&ٙ$����u�G�k��t0xa��JK-��C�0 ܗ�e�Elգ�z�б����}���bXF��9��sS�DUN繙���0���W���h�a�#-u�׼!幻Pmה��aФ�k����!��#/Yt��>{2��b�A�a#)��ꪄ!��s��3<���D�*�5��q�S�@$IjP*)D�-���j�j-���m�[cF�1�Mh�KL��h�VEJ����P���c����]�WJ�%Ȅ�%��PF��p8.U^� ��ZH1|�wN��.�� �&�"#-�8<ab��}{̅ �E&�g�Unq��g��ۻt&ʟ��}�Z�^��j�yC-��m�A�Hh��1��2L���̢�r|�#-&Ӿ5��� $a��Wѻ0���m(�#���\C�)+�oƧ�i��]��֎ )�D'��.͔B �qs��Y0�d��:�b��k�$)�Men*(� ��B��k��m�"Cݛ�H,�ZT�+f�[�׮�`�&#-�I+�P>S� 1�A�n��v3C/m#/|�5]$��(=�|䏟�^� �w2�t��T]"�#-�p�p�R�� "]lP�Wֱ�p�B�1]\�D@O�*EZ#/6�����=68��0-�M�"uA�#8��Č�CfUH&��P�;3�}>�}����é� � �i�f�WS��w]�վ4�FBj��؞���/�.��)�G�=Z��S(w��,9?3[T��K�DL%���C��Xѓ��2Ä�S#n��y�_[4z��J�8���AvKz(�z�$<�X%��1�b����κh7y:�O'huBl@&@��n���(���7Co�iu9���J���c�U%�[�0Ɋ�U��F�#-���FB�#/d�#-����_!��,�� �MI���ߺ뺛#�ݑO�i�]����u�ηLջ�ґ�33X�h�k���zj�Wy�C�qyz���b�$+^��QF���r��m|�4x��4��m��jBQG4ȋ�B�P2ČE��2D�v�h�d�(�#)�#�V+#-#-a%J�+�dEaF�b�7��H�1��J�Ї���D�(����T�&0��D1�~/���a��en�)��ᙐi��3aCwc�<�j[J\Mb0s.#-���֤2E������$�P�GG���G��Mٷ�2�T�n����OV���'�ڙ�4����#-/���#-8�+��skh�� gZF� V4�.#)�cKl���T�M��,A�B"G�k��I���/�=�e��F�%9�i� t��ɏ���=�����MM���%��}畅����e�=�<}��]8�F(������!_F+!�a 4c_1�q��ƌL�i*�l��K��M��jIN'�#- 0뜪�"ѳk#-*�ETrةB9jz1f�F [��=�����Ma�`&(n�YC���B�]�����&��$��,eeU�c�sp>iG�O8a�)� �P4-����[����y��*�6�T� 1��`�HXK�d�b�b��:&�I.%7� �GN'_a����@��noӫ�����/o����z���E��ň~�����F"G0��Ky�h��z�m6>�m����;�M����m�T(�X�bjD����M��d��֌R3=�����L��7����\��ܯ7M^�O7��ɫ��:�)eY��IN�.��C�m�c4���f������33nN�f��3na��wh�A���k�3W��X XA�1�;��T�XM�$+��[�� ޹���s;���"�~z���E��� 7��c@�Q�'DI ��#-����Syx����;:�M�n�Pjia�mW\տ]���0󂞉�7eDL�6�d �����j�+�Z�u�s)�?a:�+�#-�%��͈t��ᩯg D+�M����} ����D��lǩpO��|#)�!0�Ad��p���#/�aDl- u%�>� ���#�P, �&BY�5,�9"����j�����Xͭ�ktڤڻ�E��kιt��ۛwnd9uxڊxe�ŤZF*T��;���X�J�_��䭤� �%rء#/BKI�`��[�|6n��n���a�I}ا5�r�zrU-(�� QB�F�Zb��� � ]�V��o�7�/����填�')0��Đ���.�Y-Bz�[�5���#/��C, (��Jj�E�E6Qk�������jf*65���̬4cL�&�fQ3&%SE�3&����W�����DT���<3$�C@���b+O�j���M�+ R,�#���i�����z<��O������c|�,#��9�uw|�a�E�j:����EZߝ��֒�Z7�s}7��Y�U�k~5kp�^-t��i�n�#m;�:�]�JZۘ������sY��R��k+�n�f��U]�-4}��!��7�g"1&Y�}ERI�J#)�a��A4I& �P1���D��� Ij�#/BM�(��*��7���J��LC@]�ACS��]��1NX�ϼ>���v��v>�Mzf����cd�=���*!sWZ$2�,'�4�>��F·�"��^&m�#-�S3�Ϻ��Ws$�P��cLR+mM7G�a�#�ɷ��e8���x��JG?������! 5��1�<��t2b�t��V����8�U;�"Ǒ�C�}�t�ce�;�7�B��^l2�y�Gf��-��ń%��~s�5�mu�)]p�{eclOQi��=L0놙E�4�o/��f��W���B��O"t`):Cga��³���y\�j�3���Ս��x����Ⴄ91V-���S�V�J�\���4��Bh���h�`�Da�ձZ5Im�����?����\�I�\�"�ri[�=�F�*�6�m\�k�r9�EP ������Fn�ָ�䌿7`@i4 .zU��#?e�<đ�Z�[%��]��-lfmW �l,Bur���C BL�4��pH�S��`�̌ ��$\�m�V�Ж�ْc%[W4�/��J�;��'��v�d�Ye�$qN�`Y$c!` 8�4��2�v����B�m��lթJ q#/��D3Vi�!Q�� 10�RDIU�P�X�b�ix ��4��WeX~z���`Rಠh]������HT�Y���ϡ�o�b��Vdͺhd7np�E3i�9F1��KQ�v������� *��B֪+Z����$J��W��#�")������gȄ�T>���b����?��"�C�،"���� �s4?O�#)����s?����U"U0�U]#��K��e�cNA��@��~�[-]k>n���rgLp��#-x5�����]��r���\��O���N�Ζ �̀�QM2��ohDLJ��M���)��3��q����[��=��#/�x�-QU�14�Y�E#)غ"�P�)Z� 2H�!p���� �.I���0X<�D�_� �����;�����%���;��>ʤk��jl����F썶oV�#)ωT��#8I;ҧ��?�`���<� �� �USE2@� J���db�"a,�}�ƒ�*-@\���|�u�+�Cl���U�W���Y�Z���5�O��/�M��C �v�9d�6�-\4����ؔ��^n+6YI#a6T�6ݦ�4X������h0�6�r�ln��yv㮻e�\���"�x��%Q�6[��[��sY�4;w�T�FG���7-tڲ[F�,Vu�M�d�Ц��������Pt�PO���;Q��R����H�9�x �邲*#)HRAA'���*�}��Hx���u�)������i�j�S��L��Hu�A����q��]ݨ���&Gs؟� B$d��T�~��V����oεl������(_��9 �>̺�X�����Y��(�#-( m��|z�����S��,��z.�c�0k�cc#- ��k} 1�2�%AŶ(E�����39�-oLJ5/��i-4k�[a^��B����׀������d�MX�N3�.7u٥��c"�h�Y�f%2��K�I�U�j 3 &4hȉi <���S�D7�7�(�����z�ق#/�v쒀����;5#/����M$��/0a����J�S��[c�7�幅����a}ݑª�vsFٓwVN��1����nk���Ѥ}�,�jۄ�� {�r=�R�Zh�{��4��#-Ԛo��s���<ޕ��z���˫F��c� y<@0lA��C��-�F6���I�ъ�]��wd2,����%�ɭ�~�t�������PEɴg8�F[fkE(��=�����O4���֓ͳ`�W��W����I�7��`�;��g��ÖZ���m�#/r��xf�o�u�ԁ�mⰒ0�������uW��q`������-M�Cv�\����8�!��il�p��5 ��EE7��#-d�����t���r´B!�@6��R�|�(�:�U4�Fw�X��׈�@���] ���=�>z;�^�`����#)��s#��p���y�#)�Q#-� �b,���+��6��5�r^�>F��#-��)("m ��H�@-�+၎`ŒQL����sԱtY&ah#� �$����Q���襨$D3�2��|�q`���djڲp�9�!BP��Gʩh}l<X+3T#�����j2��J���G��&-@��#-#/1}δ�4�$CiDIi!B[���q��SV�.j��j�W��!=��r�MمKa�iGbg�3��En���_���a0��~����'m&���m�ƀd���N��c]c�02 J�p�l�Tg!A3��4 c$e�M��b��J;&��rߞ�Lΰ�Y7r�=sU��@��3�{�{4���թ�'~3���У��RCi�ƙU�cH��<-ݧBe#-�I��x��(%��Fd� du��kH��#-J�5�A�c� �}[A���=\��q� ׮İ�y��L���æt����y#/���O����8�d!���{d��O��#)���;�vY��oݕ^�P[W����_v����H�����ADI�!dH�(w�/WAک��Ղ�{k����=I����S�&�Ӌ���!ۏ��'t��}'���P��n��pD���}B�>ٸ��P��w�x��E#)��i�W�,����$�rdы>i���(Xt��9C�$Pt�!�'u#/�IL~U��#/�ϙ�� �wR"�tz7J.e �|ٱl��&#Q�1������lw*)��0�B'| B���<�l��V�3�/�ߟG�p }t/~��@)z�RЅ�1�V�9\�־��W��YI����4^�@JF��T-M-R��~��J�4�U :H�@,����i��P� ��'�d��9+cx�P;��4���(���Y�pۧ;_F��<��41��P_�W9���B0���*�h�Jn��?m�8�G[v1P1��K��������������9+\YhRB�����'�9�b�a싲�������dؼv8 �ʼn��h�V��z�U�Dc�CT$>v�/ٺ�!��6��*�#��[?CG�8�s����HH�?��U��9)$s"_f]bS��߰wM�UN80Xx�����u�1��p��3C���_�&��UT7[ .�e�S�&�I҆#�#)��T�d"gCB���y�`���0H���[b@���P��l�ytI:���1*2 �EF��/y馤��0�tI#/`����#/��p�T�5���l�i�Y�H"(gn��{�Z����s\�.^t�;� �2� �Ox�5}߽�޽I�~���#)�FeRDh��(&�D�j"��%��J����HI�d�P��Z�6�O�����R}$]"��H�!��Δl�厳�lK�6;]/i�y��5/s7F@�(�F����-��r1 �8p>hԄ���h��>���\b�C*l>�Kn,�.q2�Q#/�T�G���:��J�|''����G�8M2����= Lm���f7���l��I���C�ꊕ�y��FF��˃`�j��'eR��� ��ƛ#)�4�d�C�9�?b�ʦ���%��� a�k�h˜����&��9�T�/� ���l�G�8|�T�M�h0��$#-�ؕLd�+o3�s��Y�l-�-��^voBAX �# 6��c���wK���vG{^w����ѱ�U�k \��a[f1��F2�0���_@q�R�ĥB�&DC�ۢG�Y j���$�kEcRkL��\#/�p���i %���p|u�W:^ �Zb/��#/a"��iI��5�4���5�q8�$nD�Z�ї1� RE��D_�����Nw��F\M���`7�a.$��C<�'�5R_�|g5#-��#o!��#Ch%m� nT:)Ś�Pq�sN�jjhX��� �6�Z#)�Ą�z#/ju{.�ȄO�۹e]�!z��H�#)������Z$�P� @���9)��Q EA0�lqȚ�,e�ښmM��f1� �4����&�$J �+*�ܖ(5TN�UiҒ��F�]m��Cl"�- �J��Q�#/�Ymӭ���i��6T��J��T-1��X4���t�\��Ja��J�JU�.�*.��TZ%�n�5F,x#-��M=�-�,ȶ��g�B&%m]���*# ظkJE���\�)X*�q��e�$+$�� JdX�5ӃL�����]��*���h1����bȗ# �0mub���XZ�:���#-5M2:Y�"���mE����1�f�ጒ.�kRPn r��nbZ@�<(ӄ}2#-*�^*0R;����ê0���S��i8�Ң� �"�Ȯ�A��&liLUA�<_:/ a�0����A�Qq��kHꚭ��S�Z؊ �F�7i3���%0Uε ��eY2�i�n#/����L#MbAZ$��T�r �,h�������4���lU���!�̚px#�!�lU4M#/�DM����,�)F��H|3�H A���D��f�M�H}�cJ�f���zM�ͅ�A���J���@�!��s(��O+pkt�Cd|E<�km�Q+|�m^Tbl�|�_5 ��f��0�,;53��E�J�czƢ*�"CX�D��˶FlcY�b����dD��� �6.�w��D�KD#bi�L)�" KA�Bb\�c(P�#/$,IQAdT�0��1A�{If�E$C  M�5H�H��a��(�JS�mSJʪ����YC�%���������wN�w��[�_���j-�(Z"�# #��Z�!e��#/S����B�#-:��x�����b�DD$X ��#)�݁S�e�}ת�? R�։ꢍ�T�Y��>rEB@!���T�DޑB�i{9 ��RTC��^�#���� ��,��T"��N�+�`Y�/5Q��AƱ��#)�Ir��� ?�U��qb���ƷWWM���A�nH7A�=T���a����j�\l�$Qr��c > ��b�XC� ����:ha� �΂��$p��u#/.<_��V�#aa��͵61.��X� x�ۗ�f��s�,�`6���Z�9' A+6x��������n��k%�R;���G>�ә��k�W�A+p��#-�_�DdB��9O�׉���e�x(a�('h��N�������#Gy��n{�<"���#/d�hxC �dJ �_w����|�6v���̦7@�ge�ҏ�ve�(xQ��O�ݐ�픒���m�z@4��q̴Zo�űϼ��]��#-#��.�]^K�M�A���@�!�ي<�s�#-EP�@B�_�<�i5�O��y�M!!��;Z�;��T{�`l��v:ة����%AS{}k��Yn��P��)G�s���"�ԁ�l�?��X��:#-'4�U��x��������#i(I��C��G��0'�"�����dl 1#)5Q����ۭhkk��,DN�E��v�EB�!.��QQw�km��6�eMd�U(ȇ�<��B����t#��#)�����=t���Q�T+���L�=TR2��S�{ZPvqP����#);�f_yހ���$�<=F䬛��炾��9��=��l�8Ț�k���W[W�VR���$��A��K$e�I�f�ԔV,l�%$�M�B�[DZ���mEmKJ�-KF�T�Z�lH# K���Z��Q����(�0Zp�R��HW��`ł,EP�(e ����#-�'r ��`\j<� D*i@d�(���HI�7#/���#�+#)�&2KXH��P(�:0X����� 4ECJ�P*�B*Z�0$(�B�"��#/X��>�ݝ����RЁ���ˋD`K�@��r"(b��J�E�)��y�(� CT��|{�.�1�b=�#�٢��أ֩#�0��N)܇��5!D��㼻t���]J�̡}˽V�j6�- P�������8K�·�e�VF#/��Rh��m�H#/�2����g�a,�A�_)�����-�B�Q�����e�.͕)m1���b�c��h���iě������i�J����%�MY��S|��|���#/����oѼ����D�rC�"�l�ª<�ﴺ�{�9ܩ�e��:!�Vj��v��~;/dS���=E�h�&/������רu�r#)vAւX�/���2��犢}=�I�p��~�n��x�B�?�2�d'"N�>�il���YD�뢚���"�sm)����+���voK���SU�+���\&u���f�p�̺ԏ���#)�6A�^#)R&i#-�!5�T��q���ta�p{�Sc��bQz�j�`a # b�4�r��}i4o�~r�.�N;:�8��㢦�n��KX�w���o8#-�{�w�ij$��V/J������g�p\���>קL�wI��O�Q�;`p��Tq]8���R�|�:���C�t42���oߌ�y,�.m��"e7�J���xm�l�2a$3��@��#-xzk}&6+����bm���8��ř�5���I���y�ʪ�΁ �Xt��F���%��M���'Ce�nvгF����ͳ�;T؆ Eh�q!1D�l�0�c#)��~�#/']�Ŵf+2�� ڧ�+^$4R�w[A���i�3�������ĺގ7;BrIy$�^34ѼqM&������jT���&JTcvڧ��kP:���o�<��0{��Z����e��W���yϮb���V��4WK�N �3ĕ۬��ι��8(u�<�a$�������#-��yL~�{�&�%`��V��@J2���0�*�D���)�1b]*�՛�Ec��˻ω�*F��򪋭��lg�u��=���5�����ln�.���b�|��@��el���Y�x���Ƿ���p�ʘD��û�=1ow��+��]�!�;r��.L�ges->����� �#-�������G0�M���S{ )���N�?~H�j��G.P�P�����t1�fJ���eީ�t�vь3z8��Q�>8ğ�f �z3.�{S���P#m"��B������!�?��(E �e��wtl�pl�p�Lx�<��LFosC��Ћ�D��@ع�:���@�iB�74Jk���S 'c�n��#/ f���r�@�<�͌)F��v�ȅm l �P�q�۔�HO�n��=z��X�D���CAK.����#)�oց��U;1��bu���l!�#/42�&!��#/x�@ ��P0kD ��`0���z�a�9����ݹe��)������`rG>27q�:h��lSAC�#)l3X#/"�9{���L��Jњ\D��uV�6�Û�'(Q��Z�# � � ��Dv���bj�/.�q�h�aPcM��`�@�C� ��Ae��PL�">&9�L���~p]�[e�v5Λ\�6�K����x��;G3��?<�tT���<�!���P�*�҈���r7�AE�����l�v [ e����#�ֺ���h0�7''�(��w�T&�s��R�M<����r��z�J���fbZH���g"l�� x�KE���Zy��ނ�k��dv�xwu���JkZ-;h��F��|����i��iU�W�Gb�g���%��#u�Y�D����}��[��t���xl�c_Gk&h�,|E�閌�+�nWf�rï�OLM�3�\m�U�s2.����#-�`��5�.���f�S�o�p.�n[�S��Ѻ�Υ��U��GG<�t,�w��۞%����Ѫ�`�N�q^%��3�Ͷ �ExxԚ;%���ު|�17����x�7��=�Ǔ�x%� y����g��t��j�q��ʋ�;<��#-"5jZ� �R� ��'Tʂ�12������Y���u�SU��G���P;���'���" 1PК�]�/Cr̆��wG�ѓ�w�d������VNx+��S����\Bbp�z��ꉴ6<��P��,!ܽ�t�\�0�w,����w��(aK�2���v�x5����p�nP�jX,Y�c����ǧr�T�U�*�Q�[Og:C�b�u*�l�A]�P�a \�Hi+�A��Yp��t#$�s�B7�������dp�l��9�&����0A'�#)�Y"a���⫮��5;��0��� ���yħWX!��Y�x���ȷ<,GPAv�#/#-�#/�e�ĵ�k#)#ؠE��A r�0����:���+�]���5�U�����b�xtC����-�� ���/-�T�Q;x��+}:���h�Qˏ�N=�ԉ�a�:� ϵ��i�+j�E�Y|�Ti6������iY���kh�TЬ�Es�Ը���#I#/�K�J�1��m�&@�<ƅ�(�`�YF91!��"�T������u�Dma�Z5Xڷ�h���� �f��Ze"Ȋ v�X�k��Q�4��(�TQ��A0:Pc˛���_����!��#)ɀ�M��98) �m^N�AQ3��(_���zoxۑrlkJ�k�-�V�j�ʪ*��7 �D/zN��9�p���SUh�\��EJ�-��AKx�*�1��K+ud��/������i���o �#-h�Hi��ѳ��Q�+��_)�S�����5�1%Y��xk\0 R�k�1��K #/A�� �8�2�"4��q���.�k0��2$fP�14��AZkB�FS"œ ���u����� �h�� ��F�� �-�2��HU����?ڛ��ɺ���0ɬ&i���1۹pb��[�,M�(�cu�e�M2�u㝬�{���(�D$5k�Z֩�nˏ$�a�X�:��5l��ɂ6Ć61Aq�#-�#-�H�i�V,p^,m/"��]l�[l2L�-~[�Z��v�0���;Ĭ��8`�&4!�t�D#-A�j �8Ƙяv�U(dH�)��v�]�60bq׷>�<��a����ݝ ��F_��F��j�-v9�������*����Q��-�m�1���y��6��)51[��v����@�T��,%�w�� �aLQ ¥ ����d[3qe(T½�K�`ϙp�*#���4�F�v]�h�����P�QGJ�5$r�[l��b`�[�P�+#-0H�#)�A��s-IcAX�&@��$�- �,��*#Q�� ��k�oi^Ro4J̅��TZ�AG�<1��gx�PM�+B�A22+#훞4q�M'���i>N&}HNL�ʃ��"@�q"fZ���ҍn“17-q&�}����A�X#-l�Sb9׋��nF)T���E�B�X8�N���&!@0�I�"��8���0��EID��N��Ð).#�o6II$�T9�Qo{��8�#)M4L�)\tn)i�XH#)��l�����+�������=p3��d���Cfuއ��F)�ל|���t������g��#)A��u��:Q 5T:o�`��CH�O"���Y0�Lm�mjf�a�~�!�#)>��N%lh2FNa/j-�/��*�.S���D=}<�&�BB�,A��w$A�u|�=Ԍ���#��ƓS@��:��8ڶ�/@�Q'�Ks�r[���]���[�4�"S����i�*)�i�Q�Dn��-��vW�=V�A���_g���5����K�M��'RuZ�_I�J+� �缐�"Ⱦ'M��f[����]�hz�ro]�mT�d3�+w�K��O�E*�NG�ש?��ا��a�u�H=�β�{�-�_`d��Fz3��#/r�<#/77�V<�@M�Z���1#-݃�RfL~��n��#)9D��`~�)�Ad�UL}#н�J;��}�٭�$�)Nî�t�V.Z��϶d����8. r}#-p~Ll�=��Բ]4X`C$0a����OH�v'F��I�j &�g���>C�����#)p�Jr�`{�7s@�q{� �bQWIq靔�z�J�� I�s�c����Q�Fr�X72-���Y,FH� s���I![�.�y;H����|Y��Jwa�*����'*�ƦxN#/��%�J�"#)Q��d#)a��#)� �f� �_��|˳ ��gmȷz��Ԇ#)UCS+1�j4�t7�F�Gj�Ł1� Ie�s�F��P��y�@���p8�e����Ffǭ��l�&�s-R)UHT+ jg#-�#-����q��,-0�7k^�Y�9$7CɰMyQ�DT6�R"����?a�� �bS"&j�`p�b�H6h"�+�GӍ-h6gJ�-�2�yiQ睬�#/F*^)���`�^��P����n9�ɾL@Em#)@��$'��Ni�f���! �,��2�ox�?*��}��r����/����3p�& #w�0�d&E�ro5:�fbZH��@�� ��ؿ��4����%������)��Ӡ�� /=m�Rc��};�����]'ں%�[/P�A3P6�{.7o� � ��%#-HRA��]�|ըX$Y#-#/��J�VLREFL�R� ���ql�h��'����ˬ3R�7��y�v�h0��WW4w�"#/D�;�K�C���;�U�M#̢�F��#�����o XO��ѱ�[=��.3}�tͧzf4���x�Y�8��:�R�m:L4+eA,�>Y�8��;��f$�L����K1r=I tW:�1����cvL�4f\��zm���FD�$�p��ñ����4�S�4Z��� �'f������ܦ�g0�H6SD�K�;K�.��e�ψ[m0Zyk7���3�ky��L.�[����J�����®:ċu���[[��i���xȇ��-M�]�>����eY��,���9�� "z�M"ֳJ0�k�%L��Mb��]8�\��ᮛ�}qʼ\ɸ�D��&�k��� �CV^��s���mvn,���$�d�QŐ��_j��~E��0Vlh��<��ؘ#/���ˁ�z뜣�WC�]&�&�b�(�n�H�&l����3���yt�ҥ���g`q�����oP�8�����qA�q�HFϹ�ʎ�����[^,�-D$N)6��C c*�K�,��#)s�Հ�E%T`�ޥԭU9kC��#/�^Z��ň���I�A!'WU𣱬�5�K`�ِ���#/�͜�1�1�H��PmQ4,T��\q�4柁�����I���� �d�d�z������so��P���V���h����.��m#�I�o���{l��M��4|5�f��c�L���>"�Ā�&���v��͗�'X�Xx맑65;��v��K:#�r�ȧ=-1L}_.B5����QR�/�6XZA�l��p�h�o�X,.����̓���帰���0Fk#/`��Кփ�\߳},`nʈJHP+H*�4S��&��z��-��4D�6����s�8�� �9/s-�۪�h,�D℔%Ҕ3B�1�Hi�v�Z��7�ph�b)b4�"5� �ݖf|�ŧ0P�����mSM�\ �[_N�#)��!����5zc�+#��vMp�R����3j�2�3���;^PI��X�ga��;���]'� �;۲i�����9C4;���0�k0b����뚷�d���cx��b�4&�!�`�,f�R# 9�g"�Z�,�PjcUK�a�U8i�Eڊ#��2G7�1�A�R������{�l�[����&ɚ��4(� m�-#-�i6��Yb#-�uR%F�@bcá�Z�h�4&��a �BQ(d m�2k!��h�E"+�����\�¦���C]���@�M-4 uK���s��M^�L��D�6D��S*��vB]��4,�6"�vA�����pFÑT�l�i4�Ȃ��@ġ���dd�j��*�m��@��v F r� 126M�P*!�ըУC �\$[+�%0MK�bDfMw��<�׻�> �0!���laE jm)�8a��Y�0�l��5�U�E��$��Ϥ��{X��QEDE�ƽ4xs�7�-�� ��P�Ӵ@ �A�!"0E�*�Qd�x)oN��<�ß�j�P���e��;��EK���D��Ӧ7Y:(4��-*n�0��9O�;`q��jQthھH�Mw��]/��89��I�C5��F��#-�x3b[:�#/*�OwD#)6g��J�e������!���D��BH�UzR����Y�SAEB;4���0��k4A�v�M2p#-*�J�;��2;˕"p�`e"din@�#/Q-���yZE�4ɓ�'k�y��2æ��~Mi]HÀ�'9�������i�]¦�窫[��#��:����=�yY��g-1���ջ�n�c;ؾ��1��"ES�F\x�#�S�՗ *��}vǽ�UK?4@�d7����i��>#/HH�(�T�����#R��Д@�o�r''�QK���*v�Z0b#i`��+|����C"QoS���tCm&6�,I��al�%��#�bB@4��5*�h�#- J4?#/L��1���iHu���TMcwb��KD�a�*vmP�����͑f%Dp4p���������(c���f�i��N�� ���3P��e�'��m��5#)xA��G��؈\hh�J�1 �¼=�#-��G#/ iB#-�<���P��a6 �r��)���x2������g>�h��Q4eU=jbʯ,�_��Y�C\�N|=�Р~���' �ܣ�e�9/958�MH����z��Ѩ�pT��bb>.%����Ɯ.����D�;#)�#):�Ba9Ђ�`��1�n�k�$ D�¹���K������o�g��kLY�~�1��^H`1����-��(��0�(Q�3v^;��2�2�(=�}˲Q�M��Xk_��ݭE%�kZR�7��M�"��*8", �b,��(� �q�MP0@���ႄH "lz@hO~^���)RL��@=�"hm�ʷw��8����ج�A�0�"�!�����|ã�SUV o�3@�����H#)"��������-1S˕5��ݽp�4^3��`�]�bb�N��s�$xj��l�%8Ai!O�0Ѳ��h�L�$�#/�r��D�E��y��ve��ۓx���KA(�����&��@�*b#�iY'%:��C,�� �5*;1����,-"m��f���?2�wr���=\��a� 1V=����3 �7#-o�]&a#/�F^��|�C�sq��`���m���qK��$#)�.k׆��K�R|�>���E��c���:�*'õ�n����mt��v��A�P��EUjwM� �`���D(��'Ş��&;�`-#/�T���C��C��Z񚷙#/3h��F��TT(b- �e��DT�]W�c�C#)����lo�8�oI�a5��_N4&��=i�����|�PD�}�Q9��#)�M4Aj@�{�#-� {�\��N~��OQ��zF+d��#����"Db) F)�MK-1��)AUlZ�6�ؑEMi������+W�t4k6mu���_c�枸��WVF`l�؍���q<:NsW1�#)�>�47z�:�W?@�;\�ua�&�$� .l�H�=xǗ@�ڥ��@ �T��|.���QN�#/,�糤$��u��>^�,�ݾ�>�}�o�~����R��&�M#)�7�ƛh�mNCM�ԥ����ь;;�$i��L��� 57M'M�HƬ�r�K�DM��U��K����Z,pu�$nI22�n���<�vq��p��`@�H)4$�.#-Kl�E����W!$&��F�4�bs�YL#r�Ae��Kh�Yr8hM �#-�ױ�ꊜC�2!�8[�+P|FS+"�9��o�V�0X��Xpm/���Y��c"�hY�������C���;�\,����â��������Y �&G�$��Q���:t��sb]2�*'0�'�@����G5A*����t������ lT�dZa�z��g�)�)��~~�o�(b �#-(��C)@�R�]�>[o��V��F]�Ϻ��GB���nfr��KYL���~s�(���}^��f�"F�of /p�� ��������J���֍�p6�}SP!��Ǿ�͚�롣���5�򊇐7�b�H9�ȠP.�^tl�:�u�� H�$2c2<]F�F�$�����e};�>���U��z�y����Cd�)��(ļ����^E�ch�x��[�c��ż�� fP4�J��;UOڑM�@P�e�o��<��� @I���b�T�Q�7�b {��h��#/������ifJ�ͫ�~��o�����4���MFت6��+k�j��J^��ޛzjQ#)-3�a)ki��\]O"#a�$��H�N��A@�CeQL����-f�Q�l��c+�E�������kT(@�'e(�^#/4{rM���I�Ӽ�����ó"I⯈A6l!FOx�O?�ژ�s*kr���!f!�Ƀxv��,!��8�g:���I��*z3{����{�,E� ����|������4��T#/6�X�R �n�!ǻ��IK�8N�M�?N@4��S�{ը#/ �D(JsMZ#/$H�B *��Z�ړJMR�v��W���歶m&㔀��J��\/*S�R��m��/v�]~ӏuQ>�{<3��#-Y�tj� ��r�fn&ye���F5��и�� ���#)Z?�������v~����/��?�����[���������?壳O���?��������������w�����?����?���������_����ۄz?������ڿ���O���P�*��X��?˙����"��O0�lS ̫���|��yp��\��)��E��X�&�?��{�Ea����T����$�$�Ϧ���V�#-Wu\J#�{�՞�HAvi�C\y����b"6��l��{�e�����rd:n(.k��A�܀{?����e=�8�+�H1 �@Z�wf�xŏ`��G�(JU��h$�SgNt?���؈OU��7����K�=>=�#.��_��ѹhPQ`�X�Be :���v��Θ�ڳr�������ݞ.ɫK�.؍a���ܭ����� {R���o�dkۺ�1��٠��- :�� a����4h�S*�{F���~ZX4�C��k���Fvj��ٻ��VV�M ,��r���͙M�Gj#-[v�ZtGI�mƶ9T�����,���v�I��g�=�ͅ��H0Ha3Z��W�W��Zsx�l��: ��;�n� ��7��!��N�솃/�>�&kM�N˖(W3�$�$b1k��ؼ�@ˍ#)h���B#-�����xe:��սkȠ�]��u�i�64k��)�#/f��<�f����w���`'w�� ��č@���u��,v��j�+�%�'DPR#�$pB����%�)!��*�x��=�ٿ�p� k�ƕݘI3���������?�d���@���HII#)�) T/�w>�|7l3#)9�BFA6nwˆ�14���D�Y"���%�aCD#)�# C.�'�C�5ʊ�g�����LK3�/���\�� ��m�}�߶@X�D D�'V�T7�]o?/�’�ni5m)��q5����ҙ��j6�Tfi"b‚FqJ yЉ�#)����}�!����� x�7E[��)hȼ&�ĻR�"�>@p�sO�D�!�[�w3�R����tC�����Mʪb1E����í'_�8�᭺&��g�����>��8d������Cl�Fgot�g,r.;@}r�����#/�o���p !P�Ayt�韈q~���d�:sL����X@�Þ4��pL�a>�,5�Ez�«绵��pm�44~�/q��{.���m\Ђ�I�M�7e�x�$߁�cb��m���W����W�սM�,��#)�0� R�[�/7`��p �A�Ò܊1!�I#-#-!�@���῕�9I�̝B���za��X$26E�߸�g�f�Nu��##=�-ƒ��z��O�_�#/�h6I@$f��R�������ztz#�_wP�}E�rP�ѱA��,X�nw#���$�J�FP�bQ��!� �X�"\؀���H #/9 ���|�=`�?j�!xt�@�O)G��2˨�m�-�8�@����u`���9b ������b���{�D��>��N� gA�����X��7 ^[ c~�qQ-y[Na ��x�����(�w�.�[�̖)���k��y��l���B�t����W�P��AK#/��#IB��t��u?��zǼ\!�������w$S� #/^��p -#<== -#-----BEGIN PGP SIGNATURE-----\n\niQIzBAABCgAdFiEEivIt5aBoIuNHTzxwSbTGfAUneqoFAl0q7gwACgkQSbTGfAUn\neqqqtQ/8Dcj08eNGla/JnosmW3PPuCVlA7mYOPBCmdyW3qhmB4/HNniLgprucwMm\nVkkqPzGkTbRXGliDAK3HDFlZsgjcse5PU5/E75bmBAkTMw11YMemAb1E+Z3xbgZR\n2AlfGM6GkQJN5Svfr70LX2nV2S0+Ck+3h6DqPMmBb65Poshes5LvTKPKM2D2CXqs\ngZwDFM3w4b5OXgqeum8On4cM3fxwzJxhw5NBX2Po26t/P7tAxEy+soP3exbtMOtT\nEK6QC08nxLshTKNkVPcgsRnt0lDSYKVeGvSAjMnYrHdCIIGpdiucmWaz1rCZL5He\nB/mcGy+eFbaYZhP4OP5RgizvH+tVqrgPZhRhfuJcU6b4WmmHcowfM+kbxYcptedz\nUM3BTh5WmVUJ08WI2fNyMS1PlufCYpbb/ItO49EsVceoaMfWCW1P0+tN+ZnQmojn\n7wQ+9CQOpP7CI1b8GEabygmef7RkeFMfeGKSA5ptLE5oLwtwVm63pronC/ebg5QQ\nUYWRtpUDZ2oSibyN5Mq5We+9/n0NMEajkPfO1raaFVffYf/zd+q7LN/NK/jwrhSE\nDYGmaTauyVpLW1lkUn1dD1cQJm85GaeSGsq+dyGfSsWdDhkjmKafS16S/DdmozUM\nWL1vkFRMgDPRPzGjh8Bze+bepSvrqOJBErz/ZZNnYQ9SwAV46k0=\n=sEkX\n-----END PGP SIGNATURE-----\n diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py deleted file mode 100755 index 5270763..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py +++ /dev/null @@ -1,804 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,sys,errno,re,shutil,stat -try: - import cPickle -except ImportError: - import pickle as cPickle -from waflib import Node,Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors -CACHE_DIR='c4che' -CACHE_SUFFIX='_cache.py' -INSTALL=1337 -UNINSTALL=-1337 -SAVED_ATTRS='root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() -CFG_FILES='cfg_files' -POST_AT_ONCE=0 -POST_LAZY=1 -PROTOCOL=-1 -if sys.platform=='cli': - PROTOCOL=0 -class BuildContext(Context.Context): - '''executes the build''' - cmd='build' - variant='' - def __init__(self,**kw): - super(BuildContext,self).__init__(**kw) - self.is_install=0 - self.top_dir=kw.get('top_dir',Context.top_dir) - self.out_dir=kw.get('out_dir',Context.out_dir) - self.run_dir=kw.get('run_dir',Context.run_dir) - self.launch_dir=Context.launch_dir - self.post_mode=POST_LAZY - self.cache_dir=kw.get('cache_dir') - if not self.cache_dir: - self.cache_dir=os.path.join(self.out_dir,CACHE_DIR) - self.all_envs={} - self.node_sigs={} - self.task_sigs={} - self.imp_sigs={} - self.node_deps={} - self.raw_deps={} - self.task_gen_cache_names={} - self.jobs=Options.options.jobs - self.targets=Options.options.targets - self.keep=Options.options.keep - self.progress_bar=Options.options.progress_bar - self.deps_man=Utils.defaultdict(list) - self.current_group=0 - self.groups=[] - self.group_names={} - for v in SAVED_ATTRS: - if not hasattr(self,v): - setattr(self,v,{}) - def get_variant_dir(self): - if not self.variant: - return self.out_dir - return os.path.join(self.out_dir,os.path.normpath(self.variant)) - variant_dir=property(get_variant_dir,None) - def __call__(self,*k,**kw): - kw['bld']=self - ret=TaskGen.task_gen(*k,**kw) - self.task_gen_cache_names={} - self.add_to_group(ret,group=kw.get('group')) - return ret - def __copy__(self): - raise Errors.WafError('build contexts cannot be copied') - def load_envs(self): - node=self.root.find_node(self.cache_dir) - if not node: - raise Errors.WafError('The project was not configured: run "waf configure" first!') - lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True) - if not lst: - raise Errors.WafError('The cache directory is empty: reconfigure the project') - for x in lst: - name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/') - env=ConfigSet.ConfigSet(x.abspath()) - self.all_envs[name]=env - for f in env[CFG_FILES]: - newnode=self.root.find_resource(f) - if not newnode or not newnode.exists(): - raise Errors.WafError('Missing configuration file %r, reconfigure the project!'%f) - def init_dirs(self): - if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)): - raise Errors.WafError('The project was not configured: run "waf configure" first!') - self.path=self.srcnode=self.root.find_dir(self.top_dir) - self.bldnode=self.root.make_node(self.variant_dir) - self.bldnode.mkdir() - def execute(self): - self.restore() - if not self.all_envs: - self.load_envs() - self.execute_build() - def execute_build(self): - Logs.info("Waf: Entering directory `%s'",self.variant_dir) - self.recurse([self.run_dir]) - self.pre_build() - self.timer=Utils.Timer() - try: - self.compile() - finally: - if self.progress_bar==1 and sys.stderr.isatty(): - c=self.producer.processed or 1 - m=self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL) - Logs.info(m,extra={'stream':sys.stderr,'c1':Logs.colors.cursor_off,'c2':Logs.colors.cursor_on}) - Logs.info("Waf: Leaving directory `%s'",self.variant_dir) - try: - self.producer.bld=None - del self.producer - except AttributeError: - pass - self.post_build() - def restore(self): - try: - env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py')) - except EnvironmentError: - pass - else: - if env.version').ljust(cols) - msg=Logs.indicator%(left,bar,right) - return msg - def declare_chain(self,*k,**kw): - return TaskGen.declare_chain(*k,**kw) - def pre_build(self): - for m in getattr(self,'pre_funs',[]): - m(self) - def post_build(self): - for m in getattr(self,'post_funs',[]): - m(self) - def add_pre_fun(self,meth): - try: - self.pre_funs.append(meth) - except AttributeError: - self.pre_funs=[meth] - def add_post_fun(self,meth): - try: - self.post_funs.append(meth) - except AttributeError: - self.post_funs=[meth] - def get_group(self,x): - if not self.groups: - self.add_group() - if x is None: - return self.groups[self.current_group] - if x in self.group_names: - return self.group_names[x] - return self.groups[x] - def add_to_group(self,tgen,group=None): - assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.Task)) - tgen.bld=self - self.get_group(group).append(tgen) - def get_group_name(self,g): - if not isinstance(g,list): - g=self.groups[g] - for x in self.group_names: - if id(self.group_names[x])==id(g): - return x - return'' - def get_group_idx(self,tg): - se=id(tg) - for i,tmp in enumerate(self.groups): - for t in tmp: - if id(t)==se: - return i - return None - def add_group(self,name=None,move=True): - if name and name in self.group_names: - raise Errors.WafError('add_group: name %s already present',name) - g=[] - self.group_names[name]=g - self.groups.append(g) - if move: - self.current_group=len(self.groups)-1 - def set_group(self,idx): - if isinstance(idx,str): - g=self.group_names[idx] - for i,tmp in enumerate(self.groups): - if id(g)==id(tmp): - self.current_group=i - break - else: - self.current_group=idx - def total(self): - total=0 - for group in self.groups: - for tg in group: - try: - total+=len(tg.tasks) - except AttributeError: - total+=1 - return total - def get_targets(self): - to_post=[] - min_grp=0 - for name in self.targets.split(','): - tg=self.get_tgen_by_name(name) - m=self.get_group_idx(tg) - if m>min_grp: - min_grp=m - to_post=[tg] - elif m==min_grp: - to_post.append(tg) - return(min_grp,to_post) - def get_all_task_gen(self): - lst=[] - for g in self.groups: - lst.extend(g) - return lst - def post_group(self): - def tgpost(tg): - try: - f=tg.post - except AttributeError: - pass - else: - f() - if self.targets=='*': - for tg in self.groups[self.current_group]: - tgpost(tg) - elif self.targets: - if self.current_groupself.current_group: - for tg in g: - if is_post(tg,ln): - return True - if self.post_mode==POST_LAZY and ln!=self.srcnode: - if is_post_group(): - ln=self.srcnode - for tg in self.groups[self.current_group]: - if is_post(tg,ln): - tgpost(tg) - def get_tasks_group(self,idx): - tasks=[] - for tg in self.groups[idx]: - try: - tasks.extend(tg.tasks) - except AttributeError: - tasks.append(tg) - return tasks - def get_build_iterator(self): - if self.targets and self.targets!='*': - (self._min_grp,self._exact_tg)=self.get_targets() - if self.post_mode!=POST_LAZY: - for self.current_group,_ in enumerate(self.groups): - self.post_group() - for self.current_group,_ in enumerate(self.groups): - if self.post_mode!=POST_AT_ONCE: - self.post_group() - tasks=self.get_tasks_group(self.current_group) - Task.set_file_constraints(tasks) - Task.set_precedence_constraints(tasks) - self.cur_tasks=tasks - if tasks: - yield tasks - while 1: - yield[] - def install_files(self,dest,files,**kw): - assert(dest) - tg=self(features='install_task',install_to=dest,install_from=files,**kw) - tg.dest=tg.install_to - tg.type='install_files' - if not kw.get('postpone',True): - tg.post() - return tg - def install_as(self,dest,srcfile,**kw): - assert(dest) - tg=self(features='install_task',install_to=dest,install_from=srcfile,**kw) - tg.dest=tg.install_to - tg.type='install_as' - if not kw.get('postpone',True): - tg.post() - return tg - def symlink_as(self,dest,src,**kw): - assert(dest) - tg=self(features='install_task',install_to=dest,install_from=src,**kw) - tg.dest=tg.install_to - tg.type='symlink_as' - tg.link=src - if not kw.get('postpone',True): - tg.post() - return tg -@TaskGen.feature('install_task') -@TaskGen.before_method('process_rule','process_source') -def process_install_task(self): - self.add_install_task(**self.__dict__) -@TaskGen.taskgen_method -def add_install_task(self,**kw): - if not self.bld.is_install: - return - if not kw['install_to']: - return - if kw['type']=='symlink_as'and Utils.is_win32: - if kw.get('win32_install'): - kw['type']='install_as' - else: - return - tsk=self.install_task=self.create_task('inst') - tsk.chmod=kw.get('chmod',Utils.O644) - tsk.link=kw.get('link','')or kw.get('install_from','') - tsk.relative_trick=kw.get('relative_trick',False) - tsk.type=kw['type'] - tsk.install_to=tsk.dest=kw['install_to'] - tsk.install_from=kw['install_from'] - tsk.relative_base=kw.get('cwd')or kw.get('relative_base',self.path) - tsk.install_user=kw.get('install_user') - tsk.install_group=kw.get('install_group') - tsk.init_files() - if not kw.get('postpone',True): - tsk.run_now() - return tsk -@TaskGen.taskgen_method -def add_install_files(self,**kw): - kw['type']='install_files' - return self.add_install_task(**kw) -@TaskGen.taskgen_method -def add_install_as(self,**kw): - kw['type']='install_as' - return self.add_install_task(**kw) -@TaskGen.taskgen_method -def add_symlink_as(self,**kw): - kw['type']='symlink_as' - return self.add_install_task(**kw) -class inst(Task.Task): - def __str__(self): - return'' - def uid(self): - lst=self.inputs+self.outputs+[self.link,self.generator.path.abspath()] - return Utils.h_list(lst) - def init_files(self): - if self.type=='symlink_as': - inputs=[] - else: - inputs=self.generator.to_nodes(self.install_from) - if self.type=='install_as': - assert len(inputs)==1 - self.set_inputs(inputs) - dest=self.get_install_path() - outputs=[] - if self.type=='symlink_as': - if self.relative_trick: - self.link=os.path.relpath(self.link,os.path.dirname(dest)) - outputs.append(self.generator.bld.root.make_node(dest)) - elif self.type=='install_as': - outputs.append(self.generator.bld.root.make_node(dest)) - else: - for y in inputs: - if self.relative_trick: - destfile=os.path.join(dest,y.path_from(self.relative_base)) - else: - destfile=os.path.join(dest,y.name) - outputs.append(self.generator.bld.root.make_node(destfile)) - self.set_outputs(outputs) - def runnable_status(self): - ret=super(inst,self).runnable_status() - if ret==Task.SKIP_ME and self.generator.bld.is_install: - return Task.RUN_ME - return ret - def post_run(self): - pass - def get_install_path(self,destdir=True): - if isinstance(self.install_to,Node.Node): - dest=self.install_to.abspath() - else: - dest=os.path.normpath(Utils.subst_vars(self.install_to,self.env)) - if not os.path.isabs(dest): - dest=os.path.join(self.env.PREFIX,dest) - if destdir and Options.options.destdir: - dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep)) - return dest - def copy_fun(self,src,tgt): - if Utils.is_win32 and len(tgt)>259 and not tgt.startswith('\\\\?\\'): - tgt='\\\\?\\'+tgt - shutil.copy2(src,tgt) - self.fix_perms(tgt) - def rm_empty_dirs(self,tgt): - while tgt: - tgt=os.path.dirname(tgt) - try: - os.rmdir(tgt) - except OSError: - break - def run(self): - is_install=self.generator.bld.is_install - if not is_install: - return - for x in self.outputs: - if is_install==INSTALL: - x.parent.mkdir() - if self.type=='symlink_as': - fun=is_install==INSTALL and self.do_link or self.do_unlink - fun(self.link,self.outputs[0].abspath()) - else: - fun=is_install==INSTALL and self.do_install or self.do_uninstall - launch_node=self.generator.bld.launch_node() - for x,y in zip(self.inputs,self.outputs): - fun(x.abspath(),y.abspath(),x.path_from(launch_node)) - def run_now(self): - status=self.runnable_status() - if status not in(Task.RUN_ME,Task.SKIP_ME): - raise Errors.TaskNotReady('Could not process %r: status %r'%(self,status)) - self.run() - self.hasrun=Task.SUCCESS - def do_install(self,src,tgt,lbl,**kw): - if not Options.options.force: - try: - st1=os.stat(tgt) - st2=os.stat(src) - except OSError: - pass - else: - if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size: - if not self.generator.bld.progress_bar: - c1=Logs.colors.NORMAL - c2=Logs.colors.BLUE - Logs.info('%s- install %s%s%s (from %s)',c1,c2,tgt,c1,lbl) - return False - if not self.generator.bld.progress_bar: - c1=Logs.colors.NORMAL - c2=Logs.colors.BLUE - Logs.info('%s+ install %s%s%s (from %s)',c1,c2,tgt,c1,lbl) - try: - os.chmod(tgt,Utils.O644|stat.S_IMODE(os.stat(tgt).st_mode)) - except EnvironmentError: - pass - try: - os.remove(tgt) - except OSError: - pass - try: - self.copy_fun(src,tgt) - except EnvironmentError as e: - if not os.path.exists(src): - Logs.error('File %r does not exist',src) - elif not os.path.isfile(src): - Logs.error('Input %r is not a file',src) - raise Errors.WafError('Could not install the file %r'%tgt,e) - def fix_perms(self,tgt): - if not Utils.is_win32: - user=getattr(self,'install_user',None)or getattr(self.generator,'install_user',None) - group=getattr(self,'install_group',None)or getattr(self.generator,'install_group',None) - if user or group: - Utils.lchown(tgt,user or-1,group or-1) - if not os.path.islink(tgt): - os.chmod(tgt,self.chmod) - def do_link(self,src,tgt,**kw): - if os.path.islink(tgt)and os.readlink(tgt)==src: - if not self.generator.bld.progress_bar: - c1=Logs.colors.NORMAL - c2=Logs.colors.BLUE - Logs.info('%s- symlink %s%s%s (to %s)',c1,c2,tgt,c1,src) - else: - try: - os.remove(tgt) - except OSError: - pass - if not self.generator.bld.progress_bar: - c1=Logs.colors.NORMAL - c2=Logs.colors.BLUE - Logs.info('%s+ symlink %s%s%s (to %s)',c1,c2,tgt,c1,src) - os.symlink(src,tgt) - self.fix_perms(tgt) - def do_uninstall(self,src,tgt,lbl,**kw): - if not self.generator.bld.progress_bar: - c1=Logs.colors.NORMAL - c2=Logs.colors.BLUE - Logs.info('%s- remove %s%s%s',c1,c2,tgt,c1) - try: - os.remove(tgt) - except OSError as e: - if e.errno!=errno.ENOENT: - if not getattr(self,'uninstall_error',None): - self.uninstall_error=True - Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') - if Logs.verbose>1: - Logs.warn('Could not remove %s (error code %r)',e.filename,e.errno) - self.rm_empty_dirs(tgt) - def do_unlink(self,src,tgt,**kw): - try: - if not self.generator.bld.progress_bar: - c1=Logs.colors.NORMAL - c2=Logs.colors.BLUE - Logs.info('%s- remove %s%s%s',c1,c2,tgt,c1) - os.remove(tgt) - except OSError: - pass - self.rm_empty_dirs(tgt) -class InstallContext(BuildContext): - '''installs the targets on the system''' - cmd='install' - def __init__(self,**kw): - super(InstallContext,self).__init__(**kw) - self.is_install=INSTALL -class UninstallContext(InstallContext): - '''removes the targets installed''' - cmd='uninstall' - def __init__(self,**kw): - super(UninstallContext,self).__init__(**kw) - self.is_install=UNINSTALL -class CleanContext(BuildContext): - '''cleans the project''' - cmd='clean' - def execute(self): - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - try: - self.clean() - finally: - self.store() - def clean(self): - Logs.debug('build: clean called') - if hasattr(self,'clean_files'): - for n in self.clean_files: - n.delete() - elif self.bldnode!=self.srcnode: - lst=[] - for env in self.all_envs.values(): - lst.extend(self.root.find_or_declare(f)for f in env[CFG_FILES]) - excluded_dirs='.lock* *conf_check_*/** config.log %s/*'%CACHE_DIR - for n in self.bldnode.ant_glob('**/*',excl=excluded_dirs,quiet=True): - if n in lst: - continue - n.delete() - self.root.children={} - for v in SAVED_ATTRS: - if v=='root': - continue - setattr(self,v,{}) -class ListContext(BuildContext): - '''lists the targets to execute''' - cmd='list' - def execute(self): - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - self.pre_build() - self.timer=Utils.Timer() - for g in self.groups: - for tg in g: - try: - f=tg.post - except AttributeError: - pass - else: - f() - try: - self.get_tgen_by_name('') - except Errors.WafError: - pass - targets=sorted(self.task_gen_cache_names) - line_just=max(len(t)for t in targets)if targets else 0 - for target in targets: - tgen=self.task_gen_cache_names[target] - descript=getattr(tgen,'description','') - if descript: - target=target.ljust(line_just) - descript=': %s'%descript - Logs.pprint('GREEN',target,label=descript) -class StepContext(BuildContext): - '''executes tasks in a step-by-step fashion, for debugging''' - cmd='step' - def __init__(self,**kw): - super(StepContext,self).__init__(**kw) - self.files=Options.options.files - def compile(self): - if not self.files: - Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') - BuildContext.compile(self) - return - targets=[] - if self.targets and self.targets!='*': - targets=self.targets.split(',') - for g in self.groups: - for tg in g: - if targets and tg.name not in targets: - continue - try: - f=tg.post - except AttributeError: - pass - else: - f() - for pat in self.files.split(','): - matcher=self.get_matcher(pat) - for tg in g: - if isinstance(tg,Task.Task): - lst=[tg] - else: - lst=tg.tasks - for tsk in lst: - do_exec=False - for node in tsk.inputs: - if matcher(node,output=False): - do_exec=True - break - for node in tsk.outputs: - if matcher(node,output=True): - do_exec=True - break - if do_exec: - ret=tsk.run() - Logs.info('%s -> exit %r',tsk,ret) - def get_matcher(self,pat): - inn=True - out=True - if pat.startswith('in:'): - out=False - pat=pat.replace('in:','') - elif pat.startswith('out:'): - inn=False - pat=pat.replace('out:','') - anode=self.root.find_node(pat) - pattern=None - if not anode: - if not pat.startswith('^'): - pat='^.+?%s'%pat - if not pat.endswith('$'): - pat='%s$'%pat - pattern=re.compile(pat) - def match(node,output): - if output and not out: - return False - if not output and not inn: - return False - if anode: - return anode==node - else: - return pattern.match(node.abspath()) - return match -class EnvContext(BuildContext): - fun=cmd=None - def execute(self): - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py deleted file mode 100755 index be01a40..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py +++ /dev/null @@ -1,165 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import copy,re,os -from waflib import Logs,Utils -re_imp=re.compile(r'^(#)*?([^#=]*?)\ =\ (.*?)$',re.M) -class ConfigSet(object): - __slots__=('table','parent') - def __init__(self,filename=None): - self.table={} - if filename: - self.load(filename) - def __contains__(self,key): - if key in self.table: - return True - try: - return self.parent.__contains__(key) - except AttributeError: - return False - def keys(self): - keys=set() - cur=self - while cur: - keys.update(cur.table.keys()) - cur=getattr(cur,'parent',None) - keys=list(keys) - keys.sort() - return keys - def __iter__(self): - return iter(self.keys()) - def __str__(self): - return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in self.keys()]) - def __getitem__(self,key): - try: - while 1: - x=self.table.get(key) - if not x is None: - return x - self=self.parent - except AttributeError: - return[] - def __setitem__(self,key,value): - self.table[key]=value - def __delitem__(self,key): - self[key]=[] - def __getattr__(self,name): - if name in self.__slots__: - return object.__getattribute__(self,name) - else: - return self[name] - def __setattr__(self,name,value): - if name in self.__slots__: - object.__setattr__(self,name,value) - else: - self[name]=value - def __delattr__(self,name): - if name in self.__slots__: - object.__delattr__(self,name) - else: - del self[name] - def derive(self): - newenv=ConfigSet() - newenv.parent=self - return newenv - def detach(self): - tbl=self.get_merged_dict() - try: - delattr(self,'parent') - except AttributeError: - pass - else: - keys=tbl.keys() - for x in keys: - tbl[x]=copy.deepcopy(tbl[x]) - self.table=tbl - return self - def get_flat(self,key): - s=self[key] - if isinstance(s,str): - return s - return' '.join(s) - def _get_list_value_for_modification(self,key): - try: - value=self.table[key] - except KeyError: - try: - value=self.parent[key] - except AttributeError: - value=[] - else: - if isinstance(value,list): - value=value[:] - else: - value=[value] - self.table[key]=value - else: - if not isinstance(value,list): - self.table[key]=value=[value] - return value - def append_value(self,var,val): - if isinstance(val,str): - val=[val] - current_value=self._get_list_value_for_modification(var) - current_value.extend(val) - def prepend_value(self,var,val): - if isinstance(val,str): - val=[val] - self.table[var]=val+self._get_list_value_for_modification(var) - def append_unique(self,var,val): - if isinstance(val,str): - val=[val] - current_value=self._get_list_value_for_modification(var) - for x in val: - if x not in current_value: - current_value.append(x) - def get_merged_dict(self): - table_list=[] - env=self - while 1: - table_list.insert(0,env.table) - try: - env=env.parent - except AttributeError: - break - merged_table={} - for table in table_list: - merged_table.update(table) - return merged_table - def store(self,filename): - try: - os.makedirs(os.path.split(filename)[0]) - except OSError: - pass - buf=[] - merged_table=self.get_merged_dict() - keys=list(merged_table.keys()) - keys.sort() - try: - fun=ascii - except NameError: - fun=repr - for k in keys: - if k!='undo_stack': - buf.append('%s = %s\n'%(k,fun(merged_table[k]))) - Utils.writef(filename,''.join(buf)) - def load(self,filename): - tbl=self.table - code=Utils.readf(filename,m='r') - for m in re_imp.finditer(code): - g=m.group - tbl[g(2)]=eval(g(3)) - Logs.debug('env: %s',self.table) - def update(self,d): - self.table.update(d) - def stash(self): - orig=self.table - tbl=self.table=self.table.copy() - for x in tbl.keys(): - tbl[x]=copy.deepcopy(tbl[x]) - self.undo_stack=self.undo_stack+[orig] - def commit(self): - self.undo_stack.pop(-1) - def revert(self): - self.table=self.undo_stack.pop(-1) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py deleted file mode 100755 index 7c0afe1..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py +++ /dev/null @@ -1,377 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re,shlex,shutil,sys,time,traceback -from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors -WAF_CONFIG_LOG='config.log' -autoconfig=False -conf_template='''# project %(app)s configured on %(now)s by -# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) -# using %(args)s -#''' -class ConfigurationContext(Context.Context): - '''configures the project''' - cmd='configure' - error_handlers=[] - def __init__(self,**kw): - super(ConfigurationContext,self).__init__(**kw) - self.environ=dict(os.environ) - self.all_envs={} - self.top_dir=None - self.out_dir=None - self.tools=[] - self.hash=0 - self.files=[] - self.tool_cache=[] - self.setenv('') - def setenv(self,name,env=None): - if name not in self.all_envs or env: - if not env: - env=ConfigSet.ConfigSet() - self.prepare_env(env) - else: - env=env.derive() - self.all_envs[name]=env - self.variant=name - def get_env(self): - return self.all_envs[self.variant] - def set_env(self,val): - self.all_envs[self.variant]=val - env=property(get_env,set_env) - def init_dirs(self): - top=self.top_dir - if not top: - top=Options.options.top - if not top: - top=getattr(Context.g_module,Context.TOP,None) - if not top: - top=self.path.abspath() - top=os.path.abspath(top) - self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top) - assert(self.srcnode) - out=self.out_dir - if not out: - out=Options.options.out - if not out: - out=getattr(Context.g_module,Context.OUT,None) - if not out: - out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','') - out=os.path.realpath(out) - self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out) - self.bldnode.mkdir() - if not os.path.isdir(self.bldnode.abspath()): - self.fatal('Could not create the build directory %s'%self.bldnode.abspath()) - def execute(self): - self.init_dirs() - self.cachedir=self.bldnode.make_node(Build.CACHE_DIR) - self.cachedir.mkdir() - path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG) - self.logger=Logs.make_logger(path,'cfg') - app=getattr(Context.g_module,'APPNAME','') - if app: - ver=getattr(Context.g_module,'VERSION','') - if ver: - app="%s (%s)"%(app,ver) - params={'now':time.ctime(),'pyver':sys.hexversion,'systype':sys.platform,'args':" ".join(sys.argv),'wafver':Context.WAFVERSION,'abi':Context.ABI,'app':app} - self.to_log(conf_template%params) - self.msg('Setting top to',self.srcnode.abspath()) - self.msg('Setting out to',self.bldnode.abspath()) - if id(self.srcnode)==id(self.bldnode): - Logs.warn('Setting top == out') - elif id(self.path)!=id(self.srcnode): - if self.srcnode.is_child_of(self.path): - Logs.warn('Are you certain that you do not want to set top="." ?') - super(ConfigurationContext,self).execute() - self.store() - Context.top_dir=self.srcnode.abspath() - Context.out_dir=self.bldnode.abspath() - env=ConfigSet.ConfigSet() - env.argv=sys.argv - env.options=Options.options.__dict__ - env.config_cmd=self.cmd - env.run_dir=Context.run_dir - env.top_dir=Context.top_dir - env.out_dir=Context.out_dir - env.hash=self.hash - env.files=self.files - env.environ=dict(self.environ) - env.launch_dir=Context.launch_dir - if not(self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN')or getattr(Options.options,'no_lock_in_run')): - env.store(os.path.join(Context.run_dir,Options.lockfile)) - if not(self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP')or getattr(Options.options,'no_lock_in_top')): - env.store(os.path.join(Context.top_dir,Options.lockfile)) - if not(self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT')or getattr(Options.options,'no_lock_in_out')): - env.store(os.path.join(Context.out_dir,Options.lockfile)) - def prepare_env(self,env): - if not env.PREFIX: - if Options.options.prefix or Utils.is_win32: - env.PREFIX=Options.options.prefix - else: - env.PREFIX='/' - if not env.BINDIR: - if Options.options.bindir: - env.BINDIR=Options.options.bindir - else: - env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env) - if not env.LIBDIR: - if Options.options.libdir: - env.LIBDIR=Options.options.libdir - else: - env.LIBDIR=Utils.subst_vars('${PREFIX}/lib%s'%Utils.lib64(),env) - def store(self): - n=self.cachedir.make_node('build.config.py') - n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools)) - if not self.all_envs: - self.fatal('nothing to store in the configuration context!') - for key in self.all_envs: - tmpenv=self.all_envs[key] - tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX)) - def load(self,tool_list,tooldir=None,funs=None,with_sys_path=True,cache=False): - tools=Utils.to_list(tool_list) - if tooldir: - tooldir=Utils.to_list(tooldir) - for tool in tools: - if cache: - mag=(tool,id(self.env),tooldir,funs) - if mag in self.tool_cache: - self.to_log('(tool %s is already loaded, skipping)'%tool) - continue - self.tool_cache.append(mag) - module=None - try: - module=Context.load_tool(tool,tooldir,ctx=self,with_sys_path=with_sys_path) - except ImportError as e: - self.fatal('Could not load the Waf tool %r from %r\n%s'%(tool,getattr(e,'waf_sys_path',sys.path),e)) - except Exception as e: - self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs)) - self.to_log(traceback.format_exc()) - raise - if funs is not None: - self.eval_rules(funs) - else: - func=getattr(module,'configure',None) - if func: - if type(func)is type(Utils.readf): - func(self) - else: - self.eval_rules(func) - self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs}) - def post_recurse(self,node): - super(ConfigurationContext,self).post_recurse(node) - self.hash=Utils.h_list((self.hash,node.read('rb'))) - self.files.append(node.abspath()) - def eval_rules(self,rules): - self.rules=Utils.to_list(rules) - for x in self.rules: - f=getattr(self,x) - if not f: - self.fatal('No such configuration function %r'%x) - f() -def conf(f): - def fun(*k,**kw): - mandatory=kw.pop('mandatory',True) - try: - return f(*k,**kw) - except Errors.ConfigurationError: - if mandatory: - raise - fun.__name__=f.__name__ - setattr(ConfigurationContext,f.__name__,fun) - setattr(Build.BuildContext,f.__name__,fun) - return f -@conf -def add_os_flags(self,var,dest=None,dup=False): - try: - flags=shlex.split(self.environ[var]) - except KeyError: - return - if dup or''.join(flags)not in''.join(Utils.to_list(self.env[dest or var])): - self.env.append_value(dest or var,flags) -@conf -def cmd_to_list(self,cmd): - if isinstance(cmd,str): - if os.path.isfile(cmd): - return[cmd] - if os.sep=='/': - return shlex.split(cmd) - else: - try: - return shlex.split(cmd,posix=False) - except TypeError: - return shlex.split(cmd) - return cmd -@conf -def check_waf_version(self,mini='1.9.99',maxi='2.1.0',**kw): - self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)),**kw) - ver=Context.HEXVERSION - if Utils.num2ver(mini)>ver: - self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver)) - if Utils.num2ver(maxi) %r'%(filename,path_list,var,ret)) - if not ret: - self.fatal(kw.get('errmsg','')or'Could not find the program %r'%filename) - interpreter=kw.get('interpreter') - if interpreter is None: - if not Utils.check_exe(ret[0],env=environ): - self.fatal('Program %r is not executable'%ret) - self.env[var]=ret - else: - self.env[var]=self.env[interpreter]+ret - return ret -@conf -def find_binary(self,filenames,exts,paths): - for f in filenames: - for ext in exts: - exe_name=f+ext - if os.path.isabs(exe_name): - if os.path.isfile(exe_name): - return exe_name - else: - for path in paths: - x=os.path.expanduser(os.path.join(path,exe_name)) - if os.path.isfile(x): - return x - return None -@conf -def run_build(self,*k,**kw): - buf=[] - for key in sorted(kw.keys()): - v=kw[key] - if hasattr(v,'__call__'): - buf.append(Utils.h_fun(v)) - else: - buf.append(str(v)) - h=Utils.h_list(buf) - dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h) - cachemode=kw.get('confcache',getattr(Options.options,'confcache',None)) - if not cachemode and os.path.exists(dir): - shutil.rmtree(dir) - try: - os.makedirs(dir) - except OSError: - pass - try: - os.stat(dir) - except OSError: - self.fatal('cannot use the configuration test folder %r'%dir) - if cachemode==1: - try: - proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_build')) - except EnvironmentError: - pass - else: - ret=proj['cache_run_build'] - if isinstance(ret,str)and ret.startswith('Test does not build'): - self.fatal(ret) - return ret - bdir=os.path.join(dir,'testbuild') - if not os.path.exists(bdir): - os.makedirs(bdir) - cls_name=kw.get('run_build_cls')or getattr(self,'run_build_cls','build') - self.test_bld=bld=Context.create_context(cls_name,top_dir=dir,out_dir=bdir) - bld.init_dirs() - bld.progress_bar=0 - bld.targets='*' - bld.logger=self.logger - bld.all_envs.update(self.all_envs) - bld.env=kw['env'] - bld.kw=kw - bld.conf=self - kw['build_fun'](bld) - ret=-1 - try: - try: - bld.compile() - except Errors.WafError: - ret='Test does not build: %s'%traceback.format_exc() - self.fatal(ret) - else: - ret=getattr(bld,'retval',0) - finally: - if cachemode: - proj=ConfigSet.ConfigSet() - proj['cache_run_build']=ret - proj.store(os.path.join(dir,'cache_run_build')) - else: - shutil.rmtree(dir) - return ret -@conf -def ret_msg(self,msg,args): - if isinstance(msg,str): - return msg - return msg(args) -@conf -def test(self,*k,**kw): - if not'env'in kw: - kw['env']=self.env.derive() - if kw.get('validate'): - kw['validate'](kw) - self.start_msg(kw['msg'],**kw) - ret=None - try: - ret=self.run_build(*k,**kw) - except self.errors.ConfigurationError: - self.end_msg(kw['errmsg'],'YELLOW',**kw) - if Logs.verbose>1: - raise - else: - self.fatal('The configuration failed') - else: - kw['success']=ret - if kw.get('post_check'): - ret=kw['post_check'](kw) - if ret: - self.end_msg(kw['errmsg'],'YELLOW',**kw) - self.fatal('The configuration failed %r'%ret) - else: - self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) - return ret diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py deleted file mode 100755 index 9324fbe..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py +++ /dev/null @@ -1,406 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re,imp,sys -from waflib import Utils,Errors,Logs -import waflib.Node -HEXVERSION=0x2001200 -WAFVERSION="2.0.18" -WAFREVISION="314689b8994259a84f0de0aaef74d7ce91f541ad" -ABI=20 -DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI) -APPNAME='APPNAME' -VERSION='VERSION' -TOP='top' -OUT='out' -WSCRIPT_FILE='wscript' -launch_dir='' -run_dir='' -top_dir='' -out_dir='' -waf_dir='' -default_encoding=Utils.console_encoding() -g_module=None -STDOUT=1 -STDERR=-1 -BOTH=0 -classes=[] -def create_context(cmd_name,*k,**kw): - for x in classes: - if x.cmd==cmd_name: - return x(*k,**kw) - ctx=Context(*k,**kw) - ctx.fun=cmd_name - return ctx -class store_context(type): - def __init__(cls,name,bases,dct): - super(store_context,cls).__init__(name,bases,dct) - name=cls.__name__ - if name in('ctx','Context'): - return - try: - cls.cmd - except AttributeError: - raise Errors.WafError('Missing command for the context class %r (cmd)'%name) - if not getattr(cls,'fun',None): - cls.fun=cls.cmd - classes.insert(0,cls) -ctx=store_context('ctx',(object,),{}) -class Context(ctx): - errors=Errors - tools={} - def __init__(self,**kw): - try: - rd=kw['run_dir'] - except KeyError: - rd=run_dir - self.node_class=type('Nod3',(waflib.Node.Node,),{}) - self.node_class.__module__='waflib.Node' - self.node_class.ctx=self - self.root=self.node_class('',None) - self.cur_script=None - self.path=self.root.find_dir(rd) - self.stack_path=[] - self.exec_dict={'ctx':self,'conf':self,'bld':self,'opt':self} - self.logger=None - def finalize(self): - try: - logger=self.logger - except AttributeError: - pass - else: - Logs.free_logger(logger) - delattr(self,'logger') - def load(self,tool_list,*k,**kw): - tools=Utils.to_list(tool_list) - path=Utils.to_list(kw.get('tooldir','')) - with_sys_path=kw.get('with_sys_path',True) - for t in tools: - module=load_tool(t,path,with_sys_path=with_sys_path) - fun=getattr(module,kw.get('name',self.fun),None) - if fun: - fun(self) - def execute(self): - self.recurse([os.path.dirname(g_module.root_path)]) - def pre_recurse(self,node): - self.stack_path.append(self.cur_script) - self.cur_script=node - self.path=node.parent - def post_recurse(self,node): - self.cur_script=self.stack_path.pop() - if self.cur_script: - self.path=self.cur_script.parent - def recurse(self,dirs,name=None,mandatory=True,once=True,encoding=None): - try: - cache=self.recurse_cache - except AttributeError: - cache=self.recurse_cache={} - for d in Utils.to_list(dirs): - if not os.path.isabs(d): - d=os.path.join(self.path.abspath(),d) - WSCRIPT=os.path.join(d,WSCRIPT_FILE) - WSCRIPT_FUN=WSCRIPT+'_'+(name or self.fun) - node=self.root.find_node(WSCRIPT_FUN) - if node and(not once or node not in cache): - cache[node]=True - self.pre_recurse(node) - try: - function_code=node.read('r',encoding) - exec(compile(function_code,node.abspath(),'exec'),self.exec_dict) - finally: - self.post_recurse(node) - elif not node: - node=self.root.find_node(WSCRIPT) - tup=(node,name or self.fun) - if node and(not once or tup not in cache): - cache[tup]=True - self.pre_recurse(node) - try: - wscript_module=load_module(node.abspath(),encoding=encoding) - user_function=getattr(wscript_module,(name or self.fun),None) - if not user_function: - if not mandatory: - continue - raise Errors.WafError('No function %r defined in %s'%(name or self.fun,node.abspath())) - user_function(self) - finally: - self.post_recurse(node) - elif not node: - if not mandatory: - continue - try: - os.listdir(d) - except OSError: - raise Errors.WafError('Cannot read the folder %r'%d) - raise Errors.WafError('No wscript file in directory %s'%d) - def log_command(self,cmd,kw): - if Logs.verbose: - fmt=os.environ.get('WAF_CMD_FORMAT') - if fmt=='string': - if not isinstance(cmd,str): - cmd=Utils.shell_escape(cmd) - Logs.debug('runner: %r',cmd) - Logs.debug('runner_env: kw=%s',kw) - def exec_command(self,cmd,**kw): - subprocess=Utils.subprocess - kw['shell']=isinstance(cmd,str) - self.log_command(cmd,kw) - if self.logger: - self.logger.info(cmd) - if'stdout'not in kw: - kw['stdout']=subprocess.PIPE - if'stderr'not in kw: - kw['stderr']=subprocess.PIPE - if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]): - raise Errors.WafError('Program %s not found!'%cmd[0]) - cargs={} - if'timeout'in kw: - if sys.hexversion>=0x3030000: - cargs['timeout']=kw['timeout'] - if not'start_new_session'in kw: - kw['start_new_session']=True - del kw['timeout'] - if'input'in kw: - if kw['input']: - cargs['input']=kw['input'] - kw['stdin']=subprocess.PIPE - del kw['input'] - if'cwd'in kw: - if not isinstance(kw['cwd'],str): - kw['cwd']=kw['cwd'].abspath() - encoding=kw.pop('decode_as',default_encoding) - try: - ret,out,err=Utils.run_process(cmd,kw,cargs) - except Exception as e: - raise Errors.WafError('Execution failure: %s'%str(e),ex=e) - if out: - if not isinstance(out,str): - out=out.decode(encoding,errors='replace') - if self.logger: - self.logger.debug('out: %s',out) - else: - Logs.info(out,extra={'stream':sys.stdout,'c1':''}) - if err: - if not isinstance(err,str): - err=err.decode(encoding,errors='replace') - if self.logger: - self.logger.error('err: %s'%err) - else: - Logs.info(err,extra={'stream':sys.stderr,'c1':''}) - return ret - def cmd_and_log(self,cmd,**kw): - subprocess=Utils.subprocess - kw['shell']=isinstance(cmd,str) - self.log_command(cmd,kw) - quiet=kw.pop('quiet',None) - to_ret=kw.pop('output',STDOUT) - if Logs.verbose and not kw['shell']and not Utils.check_exe(cmd[0]): - raise Errors.WafError('Program %r not found!'%cmd[0]) - kw['stdout']=kw['stderr']=subprocess.PIPE - if quiet is None: - self.to_log(cmd) - cargs={} - if'timeout'in kw: - if sys.hexversion>=0x3030000: - cargs['timeout']=kw['timeout'] - if not'start_new_session'in kw: - kw['start_new_session']=True - del kw['timeout'] - if'input'in kw: - if kw['input']: - cargs['input']=kw['input'] - kw['stdin']=subprocess.PIPE - del kw['input'] - if'cwd'in kw: - if not isinstance(kw['cwd'],str): - kw['cwd']=kw['cwd'].abspath() - encoding=kw.pop('decode_as',default_encoding) - try: - ret,out,err=Utils.run_process(cmd,kw,cargs) - except Exception as e: - raise Errors.WafError('Execution failure: %s'%str(e),ex=e) - if not isinstance(out,str): - out=out.decode(encoding,errors='replace') - if not isinstance(err,str): - err=err.decode(encoding,errors='replace') - if out and quiet!=STDOUT and quiet!=BOTH: - self.to_log('out: %s'%out) - if err and quiet!=STDERR and quiet!=BOTH: - self.to_log('err: %s'%err) - if ret: - e=Errors.WafError('Command %r returned %r'%(cmd,ret)) - e.returncode=ret - e.stderr=err - e.stdout=out - raise e - if to_ret==BOTH: - return(out,err) - elif to_ret==STDERR: - return err - return out - def fatal(self,msg,ex=None): - if self.logger: - self.logger.info('from %s: %s'%(self.path.abspath(),msg)) - try: - logfile=self.logger.handlers[0].baseFilename - except AttributeError: - pass - else: - if os.environ.get('WAF_PRINT_FAILURE_LOG'): - msg='Log from (%s):\n%s\n'%(logfile,Utils.readf(logfile)) - else: - msg='%s\n(complete log in %s)'%(msg,logfile) - raise self.errors.ConfigurationError(msg,ex=ex) - def to_log(self,msg): - if not msg: - return - if self.logger: - self.logger.info(msg) - else: - sys.stderr.write(str(msg)) - sys.stderr.flush() - def msg(self,*k,**kw): - try: - msg=kw['msg'] - except KeyError: - msg=k[0] - self.start_msg(msg,**kw) - try: - result=kw['result'] - except KeyError: - result=k[1] - color=kw.get('color') - if not isinstance(color,str): - color=result and'GREEN'or'YELLOW' - self.end_msg(result,color,**kw) - def start_msg(self,*k,**kw): - if kw.get('quiet'): - return - msg=kw.get('msg')or k[0] - try: - if self.in_msg: - self.in_msg+=1 - return - except AttributeError: - self.in_msg=0 - self.in_msg+=1 - try: - self.line_just=max(self.line_just,len(msg)) - except AttributeError: - self.line_just=max(40,len(msg)) - for x in(self.line_just*'-',msg): - self.to_log(x) - Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='') - def end_msg(self,*k,**kw): - if kw.get('quiet'): - return - self.in_msg-=1 - if self.in_msg: - return - result=kw.get('result')or k[0] - defcolor='GREEN' - if result is True: - msg='ok' - elif not result: - msg='not found' - defcolor='YELLOW' - else: - msg=str(result) - self.to_log(msg) - try: - color=kw['color'] - except KeyError: - if len(k)>1 and k[1]in Logs.colors_lst: - color=k[1] - else: - color=defcolor - Logs.pprint(color,msg) - def load_special_tools(self,var,ban=[]): - if os.path.isdir(waf_dir): - lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var) - for x in lst: - if not x.name in ban: - load_tool(x.name.replace('.py','')) - else: - from zipfile import PyZipFile - waflibs=PyZipFile(waf_dir) - lst=waflibs.namelist() - for x in lst: - if not re.match('waflib/extras/%s'%var.replace('*','.*'),var): - continue - f=os.path.basename(x) - doban=False - for b in ban: - r=b.replace('*','.*') - if re.match(r,f): - doban=True - if not doban: - f=f.replace('.py','') - load_tool(f) -cache_modules={} -def load_module(path,encoding=None): - try: - return cache_modules[path] - except KeyError: - pass - module=imp.new_module(WSCRIPT_FILE) - try: - code=Utils.readf(path,m='r',encoding=encoding) - except EnvironmentError: - raise Errors.WafError('Could not read the file %r'%path) - module_dir=os.path.dirname(path) - sys.path.insert(0,module_dir) - try: - exec(compile(code,path,'exec'),module.__dict__) - finally: - sys.path.remove(module_dir) - cache_modules[path]=module - return module -def load_tool(tool,tooldir=None,ctx=None,with_sys_path=True): - if tool=='java': - tool='javaw' - else: - tool=tool.replace('++','xx') - if not with_sys_path: - back_path=sys.path - sys.path=[] - try: - if tooldir: - assert isinstance(tooldir,list) - sys.path=tooldir+sys.path - try: - __import__(tool) - except ImportError as e: - e.waf_sys_path=list(sys.path) - raise - finally: - for d in tooldir: - sys.path.remove(d) - ret=sys.modules[tool] - Context.tools[tool]=ret - return ret - else: - if not with_sys_path: - sys.path.insert(0,waf_dir) - try: - for x in('waflib.Tools.%s','waflib.extras.%s','waflib.%s','%s'): - try: - __import__(x%tool) - break - except ImportError: - x=None - else: - __import__(tool) - except ImportError as e: - e.waf_sys_path=list(sys.path) - raise - finally: - if not with_sys_path: - sys.path.remove(waf_dir) - ret=sys.modules[x%tool] - Context.tools[tool]=ret - return ret - finally: - if not with_sys_path: - sys.path+=back_path diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py deleted file mode 100755 index 3ef76fc..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py +++ /dev/null @@ -1,39 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import traceback,sys -class WafError(Exception): - def __init__(self,msg='',ex=None): - Exception.__init__(self) - self.msg=msg - assert not isinstance(msg,Exception) - self.stack=[] - if ex: - if not msg: - self.msg=str(ex) - if isinstance(ex,WafError): - self.stack=ex.stack - else: - self.stack=traceback.extract_tb(sys.exc_info()[2]) - self.stack+=traceback.extract_stack()[:-1] - self.verbose_msg=''.join(traceback.format_list(self.stack)) - def __str__(self): - return str(self.msg) -class BuildError(WafError): - def __init__(self,error_tasks=[]): - self.tasks=error_tasks - WafError.__init__(self,self.format_error()) - def format_error(self): - lst=['Build failed'] - for tsk in self.tasks: - txt=tsk.format_error() - if txt: - lst.append(txt) - return'\n'.join(lst) -class ConfigurationError(WafError): - pass -class TaskRescan(WafError): - pass -class TaskNotReady(WafError): - pass diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py deleted file mode 100755 index e23c4de..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py +++ /dev/null @@ -1,206 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re,traceback,sys -from waflib import Utils,ansiterm -if not os.environ.get('NOSYNC',False): - if sys.stdout.isatty()and id(sys.stdout)==id(sys.__stdout__): - sys.stdout=ansiterm.AnsiTerm(sys.stdout) - if sys.stderr.isatty()and id(sys.stderr)==id(sys.__stderr__): - sys.stderr=ansiterm.AnsiTerm(sys.stderr) -import logging -LOG_FORMAT=os.environ.get('WAF_LOG_FORMAT','%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s') -HOUR_FORMAT=os.environ.get('WAF_HOUR_FORMAT','%H:%M:%S') -zones=[] -verbose=0 -colors_lst={'USE':True,'BOLD':'\x1b[01;1m','RED':'\x1b[01;31m','GREEN':'\x1b[32m','YELLOW':'\x1b[33m','PINK':'\x1b[35m','BLUE':'\x1b[01;34m','CYAN':'\x1b[36m','GREY':'\x1b[37m','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',} -indicator='\r\x1b[K%s%s%s' -try: - unicode -except NameError: - unicode=None -def enable_colors(use): - if use==1: - if not(sys.stderr.isatty()or sys.stdout.isatty()): - use=0 - if Utils.is_win32 and os.name!='java': - term=os.environ.get('TERM','') - else: - term=os.environ.get('TERM','dumb') - if term in('dumb','emacs'): - use=0 - if use>=1: - os.environ['TERM']='vt100' - colors_lst['USE']=use -try: - get_term_cols=ansiterm.get_term_cols -except AttributeError: - def get_term_cols(): - return 80 -get_term_cols.__doc__=""" - Returns the console width in characters. - - :return: the number of characters per line - :rtype: int - """ -def get_color(cl): - if colors_lst['USE']: - return colors_lst.get(cl,'') - return'' -class color_dict(object): - def __getattr__(self,a): - return get_color(a) - def __call__(self,a): - return get_color(a) -colors=color_dict() -re_log=re.compile(r'(\w+): (.*)',re.M) -class log_filter(logging.Filter): - def __init__(self,name=''): - logging.Filter.__init__(self,name) - def filter(self,rec): - rec.zone=rec.module - if rec.levelno>=logging.INFO: - return True - m=re_log.match(rec.msg) - if m: - rec.zone=m.group(1) - rec.msg=m.group(2) - if zones: - return getattr(rec,'zone','')in zones or'*'in zones - elif not verbose>2: - return False - return True -class log_handler(logging.StreamHandler): - def emit(self,record): - try: - try: - self.stream=record.stream - except AttributeError: - if record.levelno>=logging.WARNING: - record.stream=self.stream=sys.stderr - else: - record.stream=self.stream=sys.stdout - self.emit_override(record) - self.flush() - except(KeyboardInterrupt,SystemExit): - raise - except: - self.handleError(record) - def emit_override(self,record,**kw): - self.terminator=getattr(record,'terminator','\n') - stream=self.stream - if unicode: - msg=self.formatter.format(record) - fs='%s'+self.terminator - try: - if(isinstance(msg,unicode)and getattr(stream,'encoding',None)): - fs=fs.decode(stream.encoding) - try: - stream.write(fs%msg) - except UnicodeEncodeError: - stream.write((fs%msg).encode(stream.encoding)) - else: - stream.write(fs%msg) - except UnicodeError: - stream.write((fs%msg).encode('utf-8')) - else: - logging.StreamHandler.emit(self,record) -class formatter(logging.Formatter): - def __init__(self): - logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT) - def format(self,rec): - try: - msg=rec.msg.decode('utf-8') - except Exception: - msg=rec.msg - use=colors_lst['USE'] - if(use==1 and rec.stream.isatty())or use==2: - c1=getattr(rec,'c1',None) - if c1 is None: - c1='' - if rec.levelno>=logging.ERROR: - c1=colors.RED - elif rec.levelno>=logging.WARNING: - c1=colors.YELLOW - elif rec.levelno>=logging.INFO: - c1=colors.GREEN - c2=getattr(rec,'c2',colors.NORMAL) - msg='%s%s%s'%(c1,msg,c2) - else: - msg=re.sub(r'\r(?!\n)|\x1B\[(K|.*?(m|h|l))','',msg) - if rec.levelno>=logging.INFO: - if rec.args: - try: - return msg%rec.args - except UnicodeDecodeError: - return msg.encode('utf-8')%rec.args - return msg - rec.msg=msg - rec.c1=colors.PINK - rec.c2=colors.NORMAL - return logging.Formatter.format(self,rec) -log=None -def debug(*k,**kw): - if verbose: - k=list(k) - k[0]=k[0].replace('\n',' ') - log.debug(*k,**kw) -def error(*k,**kw): - log.error(*k,**kw) - if verbose>2: - st=traceback.extract_stack() - if st: - st=st[:-1] - buf=[] - for filename,lineno,name,line in st: - buf.append(' File %r, line %d, in %s'%(filename,lineno,name)) - if line: - buf.append(' %s'%line.strip()) - if buf: - log.error('\n'.join(buf)) -def warn(*k,**kw): - log.warning(*k,**kw) -def info(*k,**kw): - log.info(*k,**kw) -def init_log(): - global log - log=logging.getLogger('waflib') - log.handlers=[] - log.filters=[] - hdlr=log_handler() - hdlr.setFormatter(formatter()) - log.addHandler(hdlr) - log.addFilter(log_filter()) - log.setLevel(logging.DEBUG) -def make_logger(path,name): - logger=logging.getLogger(name) - if sys.hexversion>0x3000000: - encoding=sys.stdout.encoding - else: - encoding=None - hdlr=logging.FileHandler(path,'w',encoding=encoding) - formatter=logging.Formatter('%(message)s') - hdlr.setFormatter(formatter) - logger.addHandler(hdlr) - logger.setLevel(logging.DEBUG) - return logger -def make_mem_logger(name,to_log,size=8192): - from logging.handlers import MemoryHandler - logger=logging.getLogger(name) - hdlr=MemoryHandler(size,target=to_log) - formatter=logging.Formatter('%(message)s') - hdlr.setFormatter(formatter) - logger.addHandler(hdlr) - logger.memhandler=hdlr - logger.setLevel(logging.DEBUG) - return logger -def free_logger(logger): - try: - for x in logger.handlers: - x.close() - logger.removeHandler(x) - except Exception: - pass -def pprint(col,msg,label='',sep='\n'): - info('%s%s%s %s',colors(col),msg,colors.NORMAL,label,extra={'terminator':sep}) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py deleted file mode 100755 index 4bdc7ec..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py +++ /dev/null @@ -1,477 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re,sys,shutil -from waflib import Utils,Errors -exclude_regs=''' -**/*~ -**/#*# -**/.#* -**/%*% -**/._* -**/*.swp -**/CVS -**/CVS/** -**/.cvsignore -**/SCCS -**/SCCS/** -**/vssver.scc -**/.svn -**/.svn/** -**/BitKeeper -**/.git -**/.git/** -**/.gitignore -**/.bzr -**/.bzrignore -**/.bzr/** -**/.hg -**/.hg/** -**/_MTN -**/_MTN/** -**/.arch-ids -**/{arch} -**/_darcs -**/_darcs/** -**/.intlcache -**/.DS_Store''' -def ant_matcher(s,ignorecase): - reflags=re.I if ignorecase else 0 - ret=[] - for x in Utils.to_list(s): - x=x.replace('\\','/').replace('//','/') - if x.endswith('/'): - x+='**' - accu=[] - for k in x.split('/'): - if k=='**': - accu.append(k) - else: - k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+') - k='^%s$'%k - try: - exp=re.compile(k,flags=reflags) - except Exception as e: - raise Errors.WafError('Invalid pattern: %s'%k,e) - else: - accu.append(exp) - ret.append(accu) - return ret -def ant_sub_filter(name,nn): - ret=[] - for lst in nn: - if not lst: - pass - elif lst[0]=='**': - ret.append(lst) - if len(lst)>1: - if lst[1].match(name): - ret.append(lst[2:]) - else: - ret.append([]) - elif lst[0].match(name): - ret.append(lst[1:]) - return ret -def ant_sub_matcher(name,pats): - nacc=ant_sub_filter(name,pats[0]) - nrej=ant_sub_filter(name,pats[1]) - if[]in nrej: - nacc=[] - return[nacc,nrej] -class Node(object): - dict_class=dict - __slots__=('name','parent','children','cache_abspath','cache_isdir') - def __init__(self,name,parent): - self.name=name - self.parent=parent - if parent: - if name in parent.children: - raise Errors.WafError('node %s exists in the parent files %r already'%(name,parent)) - parent.children[name]=self - def __setstate__(self,data): - self.name=data[0] - self.parent=data[1] - if data[2]is not None: - self.children=self.dict_class(data[2]) - def __getstate__(self): - return(self.name,self.parent,getattr(self,'children',None)) - def __str__(self): - return self.abspath() - def __repr__(self): - return self.abspath() - def __copy__(self): - raise Errors.WafError('nodes are not supposed to be copied') - def read(self,flags='r',encoding='latin-1'): - return Utils.readf(self.abspath(),flags,encoding) - def write(self,data,flags='w',encoding='latin-1'): - Utils.writef(self.abspath(),data,flags,encoding) - def read_json(self,convert=True,encoding='utf-8'): - import json - object_pairs_hook=None - if convert and sys.hexversion<0x3000000: - try: - _type=unicode - except NameError: - _type=str - def convert(value): - if isinstance(value,list): - return[convert(element)for element in value] - elif isinstance(value,_type): - return str(value) - else: - return value - def object_pairs(pairs): - return dict((str(pair[0]),convert(pair[1]))for pair in pairs) - object_pairs_hook=object_pairs - return json.loads(self.read(encoding=encoding),object_pairs_hook=object_pairs_hook) - def write_json(self,data,pretty=True): - import json - indent=2 - separators=(',',': ') - sort_keys=pretty - newline=os.linesep - if not pretty: - indent=None - separators=(',',':') - newline='' - output=json.dumps(data,indent=indent,separators=separators,sort_keys=sort_keys)+newline - self.write(output,encoding='utf-8') - def exists(self): - return os.path.exists(self.abspath()) - def isdir(self): - return os.path.isdir(self.abspath()) - def chmod(self,val): - os.chmod(self.abspath(),val) - def delete(self,evict=True): - try: - try: - if os.path.isdir(self.abspath()): - shutil.rmtree(self.abspath()) - else: - os.remove(self.abspath()) - except OSError: - if os.path.exists(self.abspath()): - raise - finally: - if evict: - self.evict() - def evict(self): - del self.parent.children[self.name] - def suffix(self): - k=max(0,self.name.rfind('.')) - return self.name[k:] - def height(self): - d=self - val=-1 - while d: - d=d.parent - val+=1 - return val - def listdir(self): - lst=Utils.listdir(self.abspath()) - lst.sort() - return lst - def mkdir(self): - if self.isdir(): - return - try: - self.parent.mkdir() - except OSError: - pass - if self.name: - try: - os.makedirs(self.abspath()) - except OSError: - pass - if not self.isdir(): - raise Errors.WafError('Could not create the directory %r'%self) - try: - self.children - except AttributeError: - self.children=self.dict_class() - def find_node(self,lst): - if isinstance(lst,str): - lst=[x for x in Utils.split_path(lst)if x and x!='.'] - if lst and lst[0].startswith('\\\\')and not self.parent: - node=self.ctx.root.make_node(lst[0]) - node.cache_isdir=True - return node.find_node(lst[1:]) - cur=self - for x in lst: - if x=='..': - cur=cur.parent or cur - continue - try: - ch=cur.children - except AttributeError: - cur.children=self.dict_class() - else: - try: - cur=ch[x] - continue - except KeyError: - pass - cur=self.__class__(x,cur) - if not cur.exists(): - cur.evict() - return None - if not cur.exists(): - cur.evict() - return None - return cur - def make_node(self,lst): - if isinstance(lst,str): - lst=[x for x in Utils.split_path(lst)if x and x!='.'] - cur=self - for x in lst: - if x=='..': - cur=cur.parent or cur - continue - try: - cur=cur.children[x] - except AttributeError: - cur.children=self.dict_class() - except KeyError: - pass - else: - continue - cur=self.__class__(x,cur) - return cur - def search_node(self,lst): - if isinstance(lst,str): - lst=[x for x in Utils.split_path(lst)if x and x!='.'] - cur=self - for x in lst: - if x=='..': - cur=cur.parent or cur - else: - try: - cur=cur.children[x] - except(AttributeError,KeyError): - return None - return cur - def path_from(self,node): - c1=self - c2=node - c1h=c1.height() - c2h=c2.height() - lst=[] - up=0 - while c1h>c2h: - lst.append(c1.name) - c1=c1.parent - c1h-=1 - while c2h>c1h: - up+=1 - c2=c2.parent - c2h-=1 - while not c1 is c2: - lst.append(c1.name) - up+=1 - c1=c1.parent - c2=c2.parent - if c1.parent: - lst.extend(['..']*up) - lst.reverse() - return os.sep.join(lst)or'.' - else: - return self.abspath() - def abspath(self): - try: - return self.cache_abspath - except AttributeError: - pass - if not self.parent: - val=os.sep - elif not self.parent.name: - val=os.sep+self.name - else: - val=self.parent.abspath()+os.sep+self.name - self.cache_abspath=val - return val - if Utils.is_win32: - def abspath(self): - try: - return self.cache_abspath - except AttributeError: - pass - if not self.parent: - val='' - elif not self.parent.name: - val=self.name+os.sep - else: - val=self.parent.abspath().rstrip(os.sep)+os.sep+self.name - self.cache_abspath=val - return val - def is_child_of(self,node): - p=self - diff=self.height()-node.height() - while diff>0: - diff-=1 - p=p.parent - return p is node - def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False): - dircont=self.listdir() - try: - lst=set(self.children.keys()) - except AttributeError: - self.children=self.dict_class() - else: - if remove: - for x in lst-set(dircont): - self.children[x].evict() - for name in dircont: - npats=accept(name,pats) - if npats and npats[0]: - accepted=[]in npats[0] - node=self.make_node([name]) - isdir=node.isdir() - if accepted: - if isdir: - if dir: - yield node - elif src: - yield node - if isdir: - node.cache_isdir=True - if maxdepth: - for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove,quiet=quiet): - yield k - def ant_glob(self,*k,**kw): - src=kw.get('src',True) - dir=kw.get('dir') - excl=kw.get('excl',exclude_regs) - incl=k and k[0]or kw.get('incl','**') - remove=kw.get('remove',True) - maxdepth=kw.get('maxdepth',25) - ignorecase=kw.get('ignorecase',False) - quiet=kw.get('quiet',False) - pats=(ant_matcher(incl,ignorecase),ant_matcher(excl,ignorecase)) - if kw.get('generator'): - return Utils.lazy_generator(self.ant_iter,(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet)) - it=self.ant_iter(ant_sub_matcher,maxdepth,pats,dir,src,remove,quiet) - if kw.get('flat'): - return' '.join(x.path_from(self)for x in it) - return list(it) - def is_src(self): - cur=self - x=self.ctx.srcnode - y=self.ctx.bldnode - while cur.parent: - if cur is y: - return False - if cur is x: - return True - cur=cur.parent - return False - def is_bld(self): - cur=self - y=self.ctx.bldnode - while cur.parent: - if cur is y: - return True - cur=cur.parent - return False - def get_src(self): - cur=self - x=self.ctx.srcnode - y=self.ctx.bldnode - lst=[] - while cur.parent: - if cur is y: - lst.reverse() - return x.make_node(lst) - if cur is x: - return self - lst.append(cur.name) - cur=cur.parent - return self - def get_bld(self): - cur=self - x=self.ctx.srcnode - y=self.ctx.bldnode - lst=[] - while cur.parent: - if cur is y: - return self - if cur is x: - lst.reverse() - return self.ctx.bldnode.make_node(lst) - lst.append(cur.name) - cur=cur.parent - lst.reverse() - if lst and Utils.is_win32 and len(lst[0])==2 and lst[0].endswith(':'): - lst[0]=lst[0][0] - return self.ctx.bldnode.make_node(['__root__']+lst) - def find_resource(self,lst): - if isinstance(lst,str): - lst=[x for x in Utils.split_path(lst)if x and x!='.'] - node=self.get_bld().search_node(lst) - if not node: - node=self.get_src().find_node(lst) - if node and node.isdir(): - return None - return node - def find_or_declare(self,lst): - if isinstance(lst,str)and os.path.isabs(lst): - node=self.ctx.root.make_node(lst) - else: - node=self.get_bld().make_node(lst) - node.parent.mkdir() - return node - def find_dir(self,lst): - if isinstance(lst,str): - lst=[x for x in Utils.split_path(lst)if x and x!='.'] - node=self.find_node(lst) - if node and not node.isdir(): - return None - return node - def change_ext(self,ext,ext_in=None): - name=self.name - if ext_in is None: - k=name.rfind('.') - if k>=0: - name=name[:k]+ext - else: - name=name+ext - else: - name=name[:-len(ext_in)]+ext - return self.parent.find_or_declare([name]) - def bldpath(self): - return self.path_from(self.ctx.bldnode) - def srcpath(self): - return self.path_from(self.ctx.srcnode) - def relpath(self): - cur=self - x=self.ctx.bldnode - while cur.parent: - if cur is x: - return self.bldpath() - cur=cur.parent - return self.srcpath() - def bld_dir(self): - return self.parent.bldpath() - def h_file(self): - return Utils.h_file(self.abspath()) - def get_bld_sig(self): - try: - cache=self.ctx.cache_sig - except AttributeError: - cache=self.ctx.cache_sig={} - try: - ret=cache[self] - except KeyError: - p=self.abspath() - try: - ret=cache[self]=self.h_file() - except EnvironmentError: - if self.isdir(): - st=os.stat(p) - ret=cache[self]=Utils.h_list([p,st.st_ino,st.st_mode]) - return ret - raise - return ret -pickle_lock=Utils.threading.Lock() -class Nod3(Node): - pass diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py deleted file mode 100755 index b61c60a..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py +++ /dev/null @@ -1,200 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,tempfile,optparse,sys,re -from waflib import Logs,Utils,Context,Errors -options=optparse.Values() -commands=[] -envvars=[] -lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform) -class opt_parser(optparse.OptionParser): - def __init__(self,ctx,allow_unknown=False): - optparse.OptionParser.__init__(self,conflict_handler='resolve',add_help_option=False,version='waf %s (%s)'%(Context.WAFVERSION,Context.WAFREVISION)) - self.formatter.width=Logs.get_term_cols() - self.ctx=ctx - self.allow_unknown=allow_unknown - def _process_args(self,largs,rargs,values): - while rargs: - try: - optparse.OptionParser._process_args(self,largs,rargs,values) - except(optparse.BadOptionError,optparse.AmbiguousOptionError)as e: - if self.allow_unknown: - largs.append(e.opt_str) - else: - self.error(str(e)) - def print_usage(self,file=None): - return self.print_help(file) - def get_usage(self): - cmds_str={} - for cls in Context.classes: - if not cls.cmd or cls.cmd=='options'or cls.cmd.startswith('_'): - continue - s=cls.__doc__ or'' - cmds_str[cls.cmd]=s - if Context.g_module: - for(k,v)in Context.g_module.__dict__.items(): - if k in('options','init','shutdown'): - continue - if type(v)is type(Context.create_context): - if v.__doc__ and not k.startswith('_'): - cmds_str[k]=v.__doc__ - just=0 - for k in cmds_str: - just=max(just,len(k)) - lst=[' %s: %s'%(k.ljust(just),v)for(k,v)in cmds_str.items()] - lst.sort() - ret='\n'.join(lst) - return'''waf [commands] [options] - -Main commands (example: ./waf build -j4) -%s -'''%ret -class OptionsContext(Context.Context): - cmd='options' - fun='options' - def __init__(self,**kw): - super(OptionsContext,self).__init__(**kw) - self.parser=opt_parser(self) - self.option_groups={} - jobs=self.jobs() - p=self.add_option - color=os.environ.get('NOCOLOR','')and'no'or'auto' - if os.environ.get('CLICOLOR','')=='0': - color='no' - elif os.environ.get('CLICOLOR_FORCE','')=='1': - color='yes' - p('-c','--color',dest='colors',default=color,action='store',help='whether to use colors (yes/no/auto) [default: auto]',choices=('yes','no','auto')) - p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs) - p('-k','--keep',dest='keep',default=0,action='count',help='continue despite errors (-kk to try harder)') - p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]') - p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)') - p('--profile',dest='profile',default=0,action='store_true',help=optparse.SUPPRESS_HELP) - p('--pdb',dest='pdb',default=0,action='store_true',help=optparse.SUPPRESS_HELP) - p('-h','--help',dest='whelp',default=0,action='store_true',help="show this help message and exit") - gr=self.add_option_group('Configuration options') - self.option_groups['configure options']=gr - gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out') - gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top') - gr.add_option('--no-lock-in-run',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_run') - gr.add_option('--no-lock-in-out',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_out') - gr.add_option('--no-lock-in-top',action='store_true',default='',help=optparse.SUPPRESS_HELP,dest='no_lock_in_top') - default_prefix=getattr(Context.g_module,'default_prefix',os.environ.get('PREFIX')) - if not default_prefix: - if Utils.unversioned_sys_platform()=='win32': - d=tempfile.gettempdir() - default_prefix=d[0].upper()+d[1:] - else: - default_prefix='/usr/local/' - gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix) - gr.add_option('--bindir',dest='bindir',help='bindir') - gr.add_option('--libdir',dest='libdir',help='libdir') - gr=self.add_option_group('Build and installation options') - self.option_groups['build and install options']=gr - gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output') - gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"') - gr=self.add_option_group('Step options') - self.option_groups['step options']=gr - gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"') - default_destdir=os.environ.get('DESTDIR','') - gr=self.add_option_group('Installation and uninstallation options') - self.option_groups['install/uninstall options']=gr - gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir') - gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation') - gr.add_option('--distcheck-args',metavar='ARGS',help='arguments to pass to distcheck',default=None,action='store') - def jobs(self): - count=int(os.environ.get('JOBS',0)) - if count<1: - if'NUMBER_OF_PROCESSORS'in os.environ: - count=int(os.environ.get('NUMBER_OF_PROCESSORS',1)) - else: - if hasattr(os,'sysconf_names'): - if'SC_NPROCESSORS_ONLN'in os.sysconf_names: - count=int(os.sysconf('SC_NPROCESSORS_ONLN')) - elif'SC_NPROCESSORS_CONF'in os.sysconf_names: - count=int(os.sysconf('SC_NPROCESSORS_CONF')) - if not count and os.name not in('nt','java'): - try: - tmp=self.cmd_and_log(['sysctl','-n','hw.ncpu'],quiet=0) - except Errors.WafError: - pass - else: - if re.match('^[0-9]+$',tmp): - count=int(tmp) - if count<1: - count=1 - elif count>1024: - count=1024 - return count - def add_option(self,*k,**kw): - return self.parser.add_option(*k,**kw) - def add_option_group(self,*k,**kw): - try: - gr=self.option_groups[k[0]] - except KeyError: - gr=self.parser.add_option_group(*k,**kw) - self.option_groups[k[0]]=gr - return gr - def get_option_group(self,opt_str): - try: - return self.option_groups[opt_str] - except KeyError: - for group in self.parser.option_groups: - if group.title==opt_str: - return group - return None - def sanitize_path(self,path,cwd=None): - if not cwd: - cwd=Context.launch_dir - p=os.path.expanduser(path) - p=os.path.join(cwd,p) - p=os.path.normpath(p) - p=os.path.abspath(p) - return p - def parse_cmd_args(self,_args=None,cwd=None,allow_unknown=False): - self.parser.allow_unknown=allow_unknown - (options,leftover_args)=self.parser.parse_args(args=_args) - envvars=[] - commands=[] - for arg in leftover_args: - if'='in arg: - envvars.append(arg) - elif arg!='options': - commands.append(arg) - for name in'top out destdir prefix bindir libdir'.split(): - if getattr(options,name,None): - path=self.sanitize_path(getattr(options,name),cwd) - setattr(options,name,path) - return options,commands,envvars - def init_module_vars(self,arg_options,arg_commands,arg_envvars): - options.__dict__.clear() - del commands[:] - del envvars[:] - options.__dict__.update(arg_options.__dict__) - commands.extend(arg_commands) - envvars.extend(arg_envvars) - for var in envvars: - (name,value)=var.split('=',1) - os.environ[name.strip()]=value - def init_logs(self,options,commands,envvars): - Logs.verbose=options.verbose - if options.verbose>=1: - self.load('errcheck') - colors={'yes':2,'auto':1,'no':0}[options.colors] - Logs.enable_colors(colors) - if options.zones: - Logs.zones=options.zones.split(',') - if not Logs.verbose: - Logs.verbose=1 - elif Logs.verbose>0: - Logs.zones=['runner'] - if Logs.verbose>2: - Logs.zones=['*'] - def parse_args(self,_args=None): - options,commands,envvars=self.parse_cmd_args() - self.init_logs(options,commands,envvars) - self.init_module_vars(options,commands,envvars) - def execute(self): - super(OptionsContext,self).execute() - self.parse_args() - Utils.alloc_process_pool(options.jobs) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py deleted file mode 100755 index bb0a64c..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py +++ /dev/null @@ -1,375 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import heapq,traceback -try: - from queue import Queue,PriorityQueue -except ImportError: - from Queue import Queue - try: - from Queue import PriorityQueue - except ImportError: - class PriorityQueue(Queue): - def _init(self,maxsize): - self.maxsize=maxsize - self.queue=[] - def _put(self,item): - heapq.heappush(self.queue,item) - def _get(self): - return heapq.heappop(self.queue) -from waflib import Utils,Task,Errors,Logs -GAP=5 -class PriorityTasks(object): - def __init__(self): - self.lst=[] - def __len__(self): - return len(self.lst) - def __iter__(self): - return iter(self.lst) - def __str__(self): - return'PriorityTasks: [%s]'%'\n '.join(str(x)for x in self.lst) - def clear(self): - self.lst=[] - def append(self,task): - heapq.heappush(self.lst,task) - def appendleft(self,task): - heapq.heappush(self.lst,task) - def pop(self): - return heapq.heappop(self.lst) - def extend(self,lst): - if self.lst: - for x in lst: - self.append(x) - else: - if isinstance(lst,list): - self.lst=lst - heapq.heapify(lst) - else: - self.lst=lst.lst -class Consumer(Utils.threading.Thread): - def __init__(self,spawner,task): - Utils.threading.Thread.__init__(self) - self.task=task - self.spawner=spawner - self.setDaemon(1) - self.start() - def run(self): - try: - if not self.spawner.master.stop: - self.spawner.master.process_task(self.task) - finally: - self.spawner.sem.release() - self.spawner.master.out.put(self.task) - self.task=None - self.spawner=None -class Spawner(Utils.threading.Thread): - def __init__(self,master): - Utils.threading.Thread.__init__(self) - self.master=master - self.sem=Utils.threading.Semaphore(master.numjobs) - self.setDaemon(1) - self.start() - def run(self): - try: - self.loop() - except Exception: - pass - def loop(self): - master=self.master - while 1: - task=master.ready.get() - self.sem.acquire() - if not master.stop: - task.log_display(task.generator.bld) - Consumer(self,task) -class Parallel(object): - def __init__(self,bld,j=2): - self.numjobs=j - self.bld=bld - self.outstanding=PriorityTasks() - self.postponed=PriorityTasks() - self.incomplete=set() - self.ready=PriorityQueue(0) - self.out=Queue(0) - self.count=0 - self.processed=0 - self.stop=False - self.error=[] - self.biter=None - self.dirty=False - self.revdeps=Utils.defaultdict(set) - self.spawner=None - if self.numjobs>1: - self.spawner=Spawner(self) - def get_next_task(self): - if not self.outstanding: - return None - return self.outstanding.pop() - def postpone(self,tsk): - self.postponed.append(tsk) - def refill_task_list(self): - while self.count>self.numjobs*GAP: - self.get_out() - while not self.outstanding: - if self.count: - self.get_out() - if self.outstanding: - break - elif self.postponed: - try: - cond=self.deadlock==self.processed - except AttributeError: - pass - else: - if cond: - lst=[] - for tsk in self.postponed: - deps=[id(x)for x in tsk.run_after if not x.hasrun] - lst.append('%s\t-> %r'%(repr(tsk),deps)) - if not deps: - lst.append('\n task %r dependencies are done, check its *runnable_status*?'%id(tsk)) - raise Errors.WafError('Deadlock detected: check the task build order%s'%''.join(lst)) - self.deadlock=self.processed - if self.postponed: - self.outstanding.extend(self.postponed) - self.postponed.clear() - elif not self.count: - if self.incomplete: - for x in self.incomplete: - for k in x.run_after: - if not k.hasrun: - break - else: - self.incomplete.remove(x) - self.outstanding.append(x) - break - else: - if self.stop or self.error: - break - raise Errors.WafError('Broken revdeps detected on %r'%self.incomplete) - else: - tasks=next(self.biter) - ready,waiting=self.prio_and_split(tasks) - self.outstanding.extend(ready) - self.incomplete.update(waiting) - self.total=self.bld.total() - break - def add_more_tasks(self,tsk): - if getattr(tsk,'more_tasks',None): - more=set(tsk.more_tasks) - groups_done=set() - def iteri(a,b): - for x in a: - yield x - for x in b: - yield x - for x in iteri(self.outstanding,self.incomplete): - for k in x.run_after: - if isinstance(k,Task.TaskGroup): - if k not in groups_done: - groups_done.add(k) - for j in k.prev&more: - self.revdeps[j].add(k) - elif k in more: - self.revdeps[k].add(x) - ready,waiting=self.prio_and_split(tsk.more_tasks) - self.outstanding.extend(ready) - self.incomplete.update(waiting) - self.total+=len(tsk.more_tasks) - def mark_finished(self,tsk): - def try_unfreeze(x): - if x in self.incomplete: - for k in x.run_after: - if not k.hasrun: - break - else: - self.incomplete.remove(x) - self.outstanding.append(x) - if tsk in self.revdeps: - for x in self.revdeps[tsk]: - if isinstance(x,Task.TaskGroup): - x.prev.remove(tsk) - if not x.prev: - for k in x.next: - k.run_after.remove(x) - try_unfreeze(k) - x.next=[] - else: - try_unfreeze(x) - del self.revdeps[tsk] - if hasattr(tsk,'semaphore'): - sem=tsk.semaphore - try: - sem.release(tsk) - except KeyError: - pass - else: - while sem.waiting and not sem.is_locked(): - x=sem.waiting.pop() - self._add_task(x) - def get_out(self): - tsk=self.out.get() - if not self.stop: - self.add_more_tasks(tsk) - self.mark_finished(tsk) - self.count-=1 - self.dirty=True - return tsk - def add_task(self,tsk): - self.ready.put(tsk) - def _add_task(self,tsk): - if hasattr(tsk,'semaphore'): - sem=tsk.semaphore - try: - sem.acquire(tsk) - except IndexError: - sem.waiting.add(tsk) - return - self.count+=1 - self.processed+=1 - if self.numjobs==1: - tsk.log_display(tsk.generator.bld) - try: - self.process_task(tsk) - finally: - self.out.put(tsk) - else: - self.add_task(tsk) - def process_task(self,tsk): - tsk.process() - if tsk.hasrun!=Task.SUCCESS: - self.error_handler(tsk) - def skip(self,tsk): - tsk.hasrun=Task.SKIPPED - self.mark_finished(tsk) - def cancel(self,tsk): - tsk.hasrun=Task.CANCELED - self.mark_finished(tsk) - def error_handler(self,tsk): - if not self.bld.keep: - self.stop=True - self.error.append(tsk) - def task_status(self,tsk): - try: - return tsk.runnable_status() - except Exception: - self.processed+=1 - tsk.err_msg=traceback.format_exc() - if not self.stop and self.bld.keep: - self.skip(tsk) - if self.bld.keep==1: - if Logs.verbose>1 or not self.error: - self.error.append(tsk) - self.stop=True - else: - if Logs.verbose>1: - self.error.append(tsk) - return Task.EXCEPTION - tsk.hasrun=Task.EXCEPTION - self.error_handler(tsk) - return Task.EXCEPTION - def start(self): - self.total=self.bld.total() - while not self.stop: - self.refill_task_list() - tsk=self.get_next_task() - if not tsk: - if self.count: - continue - else: - break - if tsk.hasrun: - self.processed+=1 - continue - if self.stop: - break - st=self.task_status(tsk) - if st==Task.RUN_ME: - self._add_task(tsk) - elif st==Task.ASK_LATER: - self.postpone(tsk) - elif st==Task.SKIP_ME: - self.processed+=1 - self.skip(tsk) - self.add_more_tasks(tsk) - elif st==Task.CANCEL_ME: - if Logs.verbose>1: - self.error.append(tsk) - self.processed+=1 - self.cancel(tsk) - while self.error and self.count: - self.get_out() - self.ready.put(None) - if not self.stop: - assert not self.count - assert not self.postponed - assert not self.incomplete - def prio_and_split(self,tasks): - for x in tasks: - x.visited=0 - reverse=self.revdeps - groups_done=set() - for x in tasks: - for k in x.run_after: - if isinstance(k,Task.TaskGroup): - if k not in groups_done: - groups_done.add(k) - for j in k.prev: - reverse[j].add(k) - else: - reverse[k].add(x) - def visit(n): - if isinstance(n,Task.TaskGroup): - return sum(visit(k)for k in n.next) - if n.visited==0: - n.visited=1 - if n in reverse: - rev=reverse[n] - n.prio_order=n.tree_weight+len(rev)+sum(visit(k)for k in rev) - else: - n.prio_order=n.tree_weight - n.visited=2 - elif n.visited==1: - raise Errors.WafError('Dependency cycle found!') - return n.prio_order - for x in tasks: - if x.visited!=0: - continue - try: - visit(x) - except Errors.WafError: - self.debug_cycles(tasks,reverse) - ready=[] - waiting=[] - for x in tasks: - for k in x.run_after: - if not k.hasrun: - waiting.append(x) - break - else: - ready.append(x) - return(ready,waiting) - def debug_cycles(self,tasks,reverse): - tmp={} - for x in tasks: - tmp[x]=0 - def visit(n,acc): - if isinstance(n,Task.TaskGroup): - for k in n.next: - visit(k,acc) - return - if tmp[n]==0: - tmp[n]=1 - for k in reverse.get(n,[]): - visit(k,[n]+acc) - tmp[n]=2 - elif tmp[n]==1: - lst=[] - for tsk in acc: - lst.append(repr(tsk)) - if tsk is n: - break - raise Errors.WafError('Task dependency cycle in "run_after" constraints: %s'%''.join(lst)) - for x in tasks: - visit(x,[]) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py deleted file mode 100755 index dde677b..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py +++ /dev/null @@ -1,415 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from __future__ import with_statement -import os,shlex,shutil,traceback,errno,sys,stat -from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node -build_dir_override=None -no_climb_commands=['configure'] -default_cmd="build" -def waf_entry_point(current_directory,version,wafdir): - Logs.init_log() - if Context.WAFVERSION!=version: - Logs.error('Waf script %r and library %r do not match (directory %r)',version,Context.WAFVERSION,wafdir) - sys.exit(1) - Context.waf_dir=wafdir - Context.run_dir=Context.launch_dir=current_directory - start_dir=current_directory - no_climb=os.environ.get('NOCLIMB') - if len(sys.argv)>1: - potential_wscript=os.path.join(current_directory,sys.argv[1]) - if os.path.basename(potential_wscript)==Context.WSCRIPT_FILE and os.path.isfile(potential_wscript): - path=os.path.normpath(os.path.dirname(potential_wscript)) - start_dir=os.path.abspath(path) - no_climb=True - sys.argv.pop(1) - ctx=Context.create_context('options') - (options,commands,env)=ctx.parse_cmd_args(allow_unknown=True) - if options.top: - start_dir=Context.run_dir=Context.top_dir=options.top - no_climb=True - if options.out: - Context.out_dir=options.out - if not no_climb: - for k in no_climb_commands: - for y in commands: - if y.startswith(k): - no_climb=True - break - cur=start_dir - while cur: - try: - lst=os.listdir(cur) - except OSError: - lst=[] - Logs.error('Directory %r is unreadable!',cur) - if Options.lockfile in lst: - env=ConfigSet.ConfigSet() - try: - env.load(os.path.join(cur,Options.lockfile)) - ino=os.stat(cur)[stat.ST_INO] - except EnvironmentError: - pass - else: - for x in(env.run_dir,env.top_dir,env.out_dir): - if not x: - continue - if Utils.is_win32: - if cur==x: - load=True - break - else: - try: - ino2=os.stat(x)[stat.ST_INO] - except OSError: - pass - else: - if ino==ino2: - load=True - break - else: - Logs.warn('invalid lock file in %s',cur) - load=False - if load: - Context.run_dir=env.run_dir - Context.top_dir=env.top_dir - Context.out_dir=env.out_dir - break - if not Context.run_dir: - if Context.WSCRIPT_FILE in lst: - Context.run_dir=cur - next=os.path.dirname(cur) - if next==cur: - break - cur=next - if no_climb: - break - wscript=os.path.normpath(os.path.join(Context.run_dir,Context.WSCRIPT_FILE)) - if not os.path.exists(wscript): - if options.whelp: - Logs.warn('These are the generic options (no wscript/project found)') - ctx.parser.print_help() - sys.exit(0) - Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)',Context.WSCRIPT_FILE) - sys.exit(1) - try: - os.chdir(Context.run_dir) - except OSError: - Logs.error('Waf: The folder %r is unreadable',Context.run_dir) - sys.exit(1) - try: - set_main_module(wscript) - except Errors.WafError as e: - Logs.pprint('RED',e.verbose_msg) - Logs.error(str(e)) - sys.exit(1) - except Exception as e: - Logs.error('Waf: The wscript in %r is unreadable',Context.run_dir) - traceback.print_exc(file=sys.stdout) - sys.exit(2) - if options.profile: - import cProfile,pstats - cProfile.runctx('from waflib import Scripting; Scripting.run_commands()',{},{},'profi.txt') - p=pstats.Stats('profi.txt') - p.sort_stats('time').print_stats(75) - else: - try: - try: - run_commands() - except: - if options.pdb: - import pdb - type,value,tb=sys.exc_info() - traceback.print_exc() - pdb.post_mortem(tb) - else: - raise - except Errors.WafError as e: - if Logs.verbose>1: - Logs.pprint('RED',e.verbose_msg) - Logs.error(e.msg) - sys.exit(1) - except SystemExit: - raise - except Exception as e: - traceback.print_exc(file=sys.stdout) - sys.exit(2) - except KeyboardInterrupt: - Logs.pprint('RED','Interrupted') - sys.exit(68) -def set_main_module(file_path): - Context.g_module=Context.load_module(file_path) - Context.g_module.root_path=file_path - def set_def(obj): - name=obj.__name__ - if not name in Context.g_module.__dict__: - setattr(Context.g_module,name,obj) - for k in(dist,distclean,distcheck): - set_def(k) - if not'init'in Context.g_module.__dict__: - Context.g_module.init=Utils.nada - if not'shutdown'in Context.g_module.__dict__: - Context.g_module.shutdown=Utils.nada - if not'options'in Context.g_module.__dict__: - Context.g_module.options=Utils.nada -def parse_options(): - ctx=Context.create_context('options') - ctx.execute() - if not Options.commands: - if isinstance(default_cmd,list): - Options.commands.extend(default_cmd) - else: - Options.commands.append(default_cmd) - if Options.options.whelp: - ctx.parser.print_help() - sys.exit(0) -def run_command(cmd_name): - ctx=Context.create_context(cmd_name) - ctx.log_timer=Utils.Timer() - ctx.options=Options.options - ctx.cmd=cmd_name - try: - ctx.execute() - finally: - ctx.finalize() - return ctx -def run_commands(): - parse_options() - run_command('init') - while Options.commands: - cmd_name=Options.commands.pop(0) - ctx=run_command(cmd_name) - Logs.info('%r finished successfully (%s)',cmd_name,ctx.log_timer) - run_command('shutdown') -def distclean_dir(dirname): - for(root,dirs,files)in os.walk(dirname): - for f in files: - if f.endswith(('.o','.moc','.exe')): - fname=os.path.join(root,f) - try: - os.remove(fname) - except OSError: - Logs.warn('Could not remove %r',fname) - for x in(Context.DBFILE,'config.log'): - try: - os.remove(x) - except OSError: - pass - try: - shutil.rmtree(Build.CACHE_DIR) - except OSError: - pass -def distclean(ctx): - '''removes build folders and data''' - def remove_and_log(k,fun): - try: - fun(k) - except EnvironmentError as e: - if e.errno!=errno.ENOENT: - Logs.warn('Could not remove %r',k) - if not Options.commands: - for k in os.listdir('.'): - for x in'.waf-2 waf-2 .waf3-2 waf3-2'.split(): - if k.startswith(x): - remove_and_log(k,shutil.rmtree) - cur='.' - if ctx.options.no_lock_in_top: - cur=ctx.options.out - try: - lst=os.listdir(cur) - except OSError: - Logs.warn('Could not read %r',cur) - return - if Options.lockfile in lst: - f=os.path.join(cur,Options.lockfile) - try: - env=ConfigSet.ConfigSet(f) - except EnvironmentError: - Logs.warn('Could not read %r',f) - return - if not env.out_dir or not env.top_dir: - Logs.warn('Invalid lock file %r',f) - return - if env.out_dir==env.top_dir: - distclean_dir(env.out_dir) - else: - remove_and_log(env.out_dir,shutil.rmtree) - env_dirs=[env.out_dir] - if not ctx.options.no_lock_in_top: - env_dirs.append(env.top_dir) - if not ctx.options.no_lock_in_run: - env_dirs.append(env.run_dir) - for k in env_dirs: - p=os.path.join(k,Options.lockfile) - remove_and_log(p,os.remove) -class Dist(Context.Context): - '''creates an archive containing the project source code''' - cmd='dist' - fun='dist' - algo='tar.bz2' - ext_algo={} - def execute(self): - self.recurse([os.path.dirname(Context.g_module.root_path)]) - self.archive() - def archive(self): - import tarfile - arch_name=self.get_arch_name() - try: - self.base_path - except AttributeError: - self.base_path=self.path - node=self.base_path.make_node(arch_name) - try: - node.delete() - except OSError: - pass - files=self.get_files() - if self.algo.startswith('tar.'): - tar=tarfile.open(node.abspath(),'w:'+self.algo.replace('tar.','')) - for x in files: - self.add_tar_file(x,tar) - tar.close() - elif self.algo=='zip': - import zipfile - zip=zipfile.ZipFile(node.abspath(),'w',compression=zipfile.ZIP_DEFLATED) - for x in files: - archive_name=self.get_base_name()+'/'+x.path_from(self.base_path) - zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED) - zip.close() - else: - self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip') - try: - from hashlib import sha256 - except ImportError: - digest='' - else: - digest=' (sha256=%r)'%sha256(node.read(flags='rb')).hexdigest() - Logs.info('New archive created: %s%s',self.arch_name,digest) - def get_tar_path(self,node): - return node.abspath() - def add_tar_file(self,x,tar): - p=self.get_tar_path(x) - tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path)) - tinfo.uid=0 - tinfo.gid=0 - tinfo.uname='root' - tinfo.gname='root' - if os.path.isfile(p): - with open(p,'rb')as f: - tar.addfile(tinfo,fileobj=f) - else: - tar.addfile(tinfo) - def get_tar_prefix(self): - try: - return self.tar_prefix - except AttributeError: - return self.get_base_name() - def get_arch_name(self): - try: - self.arch_name - except AttributeError: - self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo) - return self.arch_name - def get_base_name(self): - try: - self.base_name - except AttributeError: - appname=getattr(Context.g_module,Context.APPNAME,'noname') - version=getattr(Context.g_module,Context.VERSION,'1.0') - self.base_name=appname+'-'+version - return self.base_name - def get_excl(self): - try: - return self.excl - except AttributeError: - self.excl=Node.exclude_regs+' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' - if Context.out_dir: - nd=self.root.find_node(Context.out_dir) - if nd: - self.excl+=' '+nd.path_from(self.base_path) - return self.excl - def get_files(self): - try: - files=self.files - except AttributeError: - files=self.base_path.ant_glob('**/*',excl=self.get_excl()) - return files -def dist(ctx): - '''makes a tarball for redistributing the sources''' - pass -class DistCheck(Dist): - fun='distcheck' - cmd='distcheck' - def execute(self): - self.recurse([os.path.dirname(Context.g_module.root_path)]) - self.archive() - self.check() - def make_distcheck_cmd(self,tmpdir): - cfg=[] - if Options.options.distcheck_args: - cfg=shlex.split(Options.options.distcheck_args) - else: - cfg=[x for x in sys.argv if x.startswith('-')] - cmd=[sys.executable,sys.argv[0],'configure','build','install','uninstall','--destdir='+tmpdir]+cfg - return cmd - def check(self): - import tempfile,tarfile - with tarfile.open(self.get_arch_name())as t: - for x in t: - t.extract(x) - instdir=tempfile.mkdtemp('.inst',self.get_base_name()) - cmd=self.make_distcheck_cmd(instdir) - ret=Utils.subprocess.Popen(cmd,cwd=self.get_base_name()).wait() - if ret: - raise Errors.WafError('distcheck failed with code %r'%ret) - if os.path.exists(instdir): - raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir) - shutil.rmtree(self.get_base_name()) -def distcheck(ctx): - '''checks if the project compiles (tarball from 'dist')''' - pass -def autoconfigure(execute_method): - def execute(self): - if not Configure.autoconfig: - return execute_method(self) - env=ConfigSet.ConfigSet() - do_config=False - try: - env.load(os.path.join(Context.top_dir,Options.lockfile)) - except EnvironmentError: - Logs.warn('Configuring the project') - do_config=True - else: - if env.run_dir!=Context.run_dir: - do_config=True - else: - h=0 - for f in env.files: - try: - h=Utils.h_list((h,Utils.readf(f,'rb'))) - except EnvironmentError: - do_config=True - break - else: - do_config=h!=env.hash - if do_config: - cmd=env.config_cmd or'configure' - if Configure.autoconfig=='clobber': - tmp=Options.options.__dict__ - launch_dir_tmp=Context.launch_dir - if env.options: - Options.options.__dict__=env.options - Context.launch_dir=env.launch_dir - try: - run_command(cmd) - finally: - Options.options.__dict__=tmp - Context.launch_dir=launch_dir_tmp - else: - run_command(cmd) - run_command(self.cmd) - else: - return execute_method(self) - return execute -Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py deleted file mode 100755 index 845a24a..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py +++ /dev/null @@ -1,792 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re,sys,tempfile,traceback -from waflib import Utils,Logs,Errors -NOT_RUN=0 -MISSING=1 -CRASHED=2 -EXCEPTION=3 -CANCELED=4 -SKIPPED=8 -SUCCESS=9 -ASK_LATER=-1 -SKIP_ME=-2 -RUN_ME=-3 -CANCEL_ME=-4 -COMPILE_TEMPLATE_SHELL=''' -def f(tsk): - env = tsk.env - gen = tsk.generator - bld = gen.bld - cwdx = tsk.get_cwd() - p = env.get_flat - def to_list(xx): - if isinstance(xx, str): return [xx] - return xx - tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s - return tsk.exec_command(cmd, cwd=cwdx, env=env.env or None) -''' -COMPILE_TEMPLATE_NOSHELL=''' -def f(tsk): - env = tsk.env - gen = tsk.generator - bld = gen.bld - cwdx = tsk.get_cwd() - def to_list(xx): - if isinstance(xx, str): return [xx] - return xx - def merge(lst1, lst2): - if lst1 and lst2: - return lst1[:-1] + [lst1[-1] + lst2[0]] + lst2[1:] - return lst1 + lst2 - lst = [] - %s - if '' in lst: - lst = [x for x in lst if x] - tsk.last_cmd = lst - return tsk.exec_command(lst, cwd=cwdx, env=env.env or None) -''' -COMPILE_TEMPLATE_SIG_VARS=''' -def f(tsk): - sig = tsk.generator.bld.hash_env_vars(tsk.env, tsk.vars) - tsk.m.update(sig) - env = tsk.env - gen = tsk.generator - bld = gen.bld - cwdx = tsk.get_cwd() - p = env.get_flat - buf = [] - %s - tsk.m.update(repr(buf).encode()) -''' -classes={} -class store_task_type(type): - def __init__(cls,name,bases,dict): - super(store_task_type,cls).__init__(name,bases,dict) - name=cls.__name__ - if name!='evil'and name!='Task': - if getattr(cls,'run_str',None): - (f,dvars)=compile_fun(cls.run_str,cls.shell) - cls.hcode=Utils.h_cmd(cls.run_str) - cls.orig_run_str=cls.run_str - cls.run_str=None - cls.run=f - cls.vars=list(set(cls.vars+dvars)) - cls.vars.sort() - if cls.vars: - fun=compile_sig_vars(cls.vars) - if fun: - cls.sig_vars=fun - elif getattr(cls,'run',None)and not'hcode'in cls.__dict__: - cls.hcode=Utils.h_cmd(cls.run) - getattr(cls,'register',classes)[name]=cls -evil=store_task_type('evil',(object,),{}) -class Task(evil): - vars=[] - always_run=False - shell=False - color='GREEN' - ext_in=[] - ext_out=[] - before=[] - after=[] - hcode=Utils.SIG_NIL - keep_last_cmd=False - weight=0 - tree_weight=0 - prio_order=0 - __slots__=('hasrun','generator','env','inputs','outputs','dep_nodes','run_after') - def __init__(self,*k,**kw): - self.hasrun=NOT_RUN - try: - self.generator=kw['generator'] - except KeyError: - self.generator=self - self.env=kw['env'] - self.inputs=[] - self.outputs=[] - self.dep_nodes=[] - self.run_after=set() - def __lt__(self,other): - return self.priority()>other.priority() - def __le__(self,other): - return self.priority()>=other.priority() - def __gt__(self,other): - return self.priority()8192 - else: - too_long=len(cmd)>200000 - if too_long and getattr(self,'allow_argsfile',True): - cmd,args=self.split_argfile(cmd) - try: - (fd,tmp)=tempfile.mkstemp() - os.write(fd,'\r\n'.join(args).encode()) - os.close(fd) - if Logs.verbose: - Logs.debug('argfile: @%r -> %r',tmp,args) - return self.generator.bld.exec_command(cmd+['@'+tmp],**kw) - finally: - try: - os.remove(tmp) - except OSError: - pass - return self.generator.bld.exec_command(cmd,**kw) - def process(self): - try: - del self.generator.bld.task_sigs[self.uid()] - except KeyError: - pass - try: - ret=self.run() - except Exception: - self.err_msg=traceback.format_exc() - self.hasrun=EXCEPTION - else: - if ret: - self.err_code=ret - self.hasrun=CRASHED - else: - try: - self.post_run() - except Errors.WafError: - pass - except Exception: - self.err_msg=traceback.format_exc() - self.hasrun=EXCEPTION - else: - self.hasrun=SUCCESS - if self.hasrun!=SUCCESS and self.scan: - try: - del self.generator.bld.imp_sigs[self.uid()] - except KeyError: - pass - def log_display(self,bld): - if self.generator.bld.progress_bar==3: - return - s=self.display() - if s: - if bld.logger: - logger=bld.logger - else: - logger=Logs - if self.generator.bld.progress_bar==1: - c1=Logs.colors.cursor_off - c2=Logs.colors.cursor_on - logger.info(s,extra={'stream':sys.stderr,'terminator':'','c1':c1,'c2':c2}) - else: - logger.info(s,extra={'terminator':'','c1':'','c2':''}) - def display(self): - col1=Logs.colors(self.color) - col2=Logs.colors.NORMAL - master=self.generator.bld.producer - def cur(): - return master.processed-master.ready.qsize() - if self.generator.bld.progress_bar==1: - return self.generator.bld.progress_line(cur(),master.total,col1,col2) - if self.generator.bld.progress_bar==2: - ela=str(self.generator.bld.timer) - try: - ins=','.join([n.name for n in self.inputs]) - except AttributeError: - ins='' - try: - outs=','.join([n.name for n in self.outputs]) - except AttributeError: - outs='' - return'|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n'%(master.total,cur(),ins,outs,ela) - s=str(self) - if not s: - return None - total=master.total - n=len(str(total)) - fs='[%%%dd/%%%dd] %%s%%s%%s%%s\n'%(n,n) - kw=self.keyword() - if kw: - kw+=' ' - return fs%(cur(),total,kw,col1,s,col2) - def hash_constraints(self): - return(tuple(self.before),tuple(self.after),tuple(self.ext_in),tuple(self.ext_out),self.__class__.__name__,self.hcode) - def format_error(self): - if Logs.verbose: - msg=': %r\n%r'%(self,getattr(self,'last_cmd','')) - else: - msg=' (run with -v to display more information)' - name=getattr(self.generator,'name','') - if getattr(self,"err_msg",None): - return self.err_msg - elif not self.hasrun: - return'task in %r was not executed for some reason: %r'%(name,self) - elif self.hasrun==CRASHED: - try: - return' -> task in %r failed with exit status %r%s'%(name,self.err_code,msg) - except AttributeError: - return' -> task in %r failed%s'%(name,msg) - elif self.hasrun==MISSING: - return' -> missing files in %r%s'%(name,msg) - elif self.hasrun==CANCELED: - return' -> %r canceled because of missing dependencies'%name - else: - return'invalid status for task in %r: %r'%(name,self.hasrun) - def colon(self,var1,var2): - tmp=self.env[var1] - if not tmp: - return[] - if isinstance(var2,str): - it=self.env[var2] - else: - it=var2 - if isinstance(tmp,str): - return[tmp%x for x in it] - else: - lst=[] - for y in it: - lst.extend(tmp) - lst.append(y) - return lst - def __str__(self): - name=self.__class__.__name__ - if self.outputs: - if name.endswith(('lib','program'))or not self.inputs: - node=self.outputs[0] - return node.path_from(node.ctx.launch_node()) - if not(self.inputs or self.outputs): - return self.__class__.__name__ - if len(self.inputs)==1: - node=self.inputs[0] - return node.path_from(node.ctx.launch_node()) - src_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.inputs]) - tgt_str=' '.join([a.path_from(a.ctx.launch_node())for a in self.outputs]) - if self.outputs: - sep=' -> ' - else: - sep='' - return'%s: %s%s%s'%(self.__class__.__name__,src_str,sep,tgt_str) - def keyword(self): - name=self.__class__.__name__ - if name.endswith(('lib','program')): - return'Linking' - if len(self.inputs)==1 and len(self.outputs)==1: - return'Compiling' - if not self.inputs: - if self.outputs: - return'Creating' - else: - return'Running' - return'Processing' - def __repr__(self): - try: - ins=",".join([x.name for x in self.inputs]) - outs=",".join([x.name for x in self.outputs]) - except AttributeError: - ins=",".join([str(x)for x in self.inputs]) - outs=",".join([str(x)for x in self.outputs]) - return"".join(['\n\t{task %r: '%id(self),self.__class__.__name__," ",ins," -> ",outs,'}']) - def uid(self): - try: - return self.uid_ - except AttributeError: - m=Utils.md5(self.__class__.__name__) - up=m.update - for x in self.inputs+self.outputs: - up(x.abspath()) - self.uid_=m.digest() - return self.uid_ - def set_inputs(self,inp): - if isinstance(inp,list): - self.inputs+=inp - else: - self.inputs.append(inp) - def set_outputs(self,out): - if isinstance(out,list): - self.outputs+=out - else: - self.outputs.append(out) - def set_run_after(self,task): - assert isinstance(task,Task) - self.run_after.add(task) - def signature(self): - try: - return self.cache_sig - except AttributeError: - pass - self.m=Utils.md5(self.hcode) - self.sig_explicit_deps() - self.sig_vars() - if self.scan: - try: - self.sig_implicit_deps() - except Errors.TaskRescan: - return self.signature() - ret=self.cache_sig=self.m.digest() - return ret - def runnable_status(self): - bld=self.generator.bld - if bld.is_install<0: - return SKIP_ME - for t in self.run_after: - if not t.hasrun: - return ASK_LATER - elif t.hasrun0x3000000: - def uid(self): - try: - return self.uid_ - except AttributeError: - m=Utils.md5(self.__class__.__name__.encode('latin-1','xmlcharrefreplace')) - up=m.update - for x in self.inputs+self.outputs: - up(x.abspath().encode('latin-1','xmlcharrefreplace')) - self.uid_=m.digest() - return self.uid_ - uid.__doc__=Task.uid.__doc__ - Task.uid=uid -def is_before(t1,t2): - to_list=Utils.to_list - for k in to_list(t2.ext_in): - if k in to_list(t1.ext_out): - return 1 - if t1.__class__.__name__ in to_list(t2.after): - return 1 - if t2.__class__.__name__ in to_list(t1.before): - return 1 - return 0 -def set_file_constraints(tasks): - ins=Utils.defaultdict(set) - outs=Utils.defaultdict(set) - for x in tasks: - for a in x.inputs: - ins[a].add(x) - for a in x.dep_nodes: - ins[a].add(x) - for a in x.outputs: - outs[a].add(x) - links=set(ins.keys()).intersection(outs.keys()) - for k in links: - for a in ins[k]: - a.run_after.update(outs[k]) -class TaskGroup(object): - def __init__(self,prev,next): - self.prev=prev - self.next=next - self.done=False - def get_hasrun(self): - for k in self.prev: - if not k.hasrun: - return NOT_RUN - return SUCCESS - hasrun=property(get_hasrun,None) -def set_precedence_constraints(tasks): - cstr_groups=Utils.defaultdict(list) - for x in tasks: - h=x.hash_constraints() - cstr_groups[h].append(x) - keys=list(cstr_groups.keys()) - maxi=len(keys) - for i in range(maxi): - t1=cstr_groups[keys[i]][0] - for j in range(i+1,maxi): - t2=cstr_groups[keys[j]][0] - if is_before(t1,t2): - a=i - b=j - elif is_before(t2,t1): - a=j - b=i - else: - continue - a=cstr_groups[keys[a]] - b=cstr_groups[keys[b]] - if len(a)<2 or len(b)<2: - for x in b: - x.run_after.update(a) - else: - group=TaskGroup(set(a),set(b)) - for x in b: - x.run_after.add(group) -def funex(c): - dc={} - exec(c,dc) - return dc['f'] -re_cond=re.compile(r'(?P\w+)|(?P\|)|(?P&)') -re_novar=re.compile(r'^(SRC|TGT)\W+.*?$') -reg_act=re.compile(r'(?P\\)|(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})',re.M) -def compile_fun_shell(line): - extr=[] - def repl(match): - g=match.group - if g('dollar'): - return"$" - elif g('backslash'): - return'\\\\' - elif g('subst'): - extr.append((g('var'),g('code'))) - return"%s" - return None - line=reg_act.sub(repl,line)or line - dvars=[] - def add_dvar(x): - if x not in dvars: - dvars.append(x) - def replc(m): - if m.group('and'): - return' and ' - elif m.group('or'): - return' or ' - else: - x=m.group('var') - add_dvar(x) - return'env[%r]'%x - parm=[] - app=parm.append - for(var,meth)in extr: - if var=='SRC': - if meth: - app('tsk.inputs%s'%meth) - else: - app('" ".join([a.path_from(cwdx) for a in tsk.inputs])') - elif var=='TGT': - if meth: - app('tsk.outputs%s'%meth) - else: - app('" ".join([a.path_from(cwdx) for a in tsk.outputs])') - elif meth: - if meth.startswith(':'): - add_dvar(var) - m=meth[1:] - if m=='SRC': - m='[a.path_from(cwdx) for a in tsk.inputs]' - elif m=='TGT': - m='[a.path_from(cwdx) for a in tsk.outputs]' - elif re_novar.match(m): - m='[tsk.inputs%s]'%m[3:] - elif re_novar.match(m): - m='[tsk.outputs%s]'%m[3:] - else: - add_dvar(m) - if m[:3]not in('tsk','gen','bld'): - m='%r'%m - app('" ".join(tsk.colon(%r, %s))'%(var,m)) - elif meth.startswith('?'): - expr=re_cond.sub(replc,meth[1:]) - app('p(%r) if (%s) else ""'%(var,expr)) - else: - call='%s%s'%(var,meth) - add_dvar(call) - app(call) - else: - add_dvar(var) - app("p('%s')"%var) - if parm: - parm="%% (%s) "%(',\n\t\t'.join(parm)) - else: - parm='' - c=COMPILE_TEMPLATE_SHELL%(line,parm) - Logs.debug('action: %s',c.strip().splitlines()) - return(funex(c),dvars) -reg_act_noshell=re.compile(r"(?P\s+)|(?P\$\{(?P\w+)(?P.*?)\})|(?P([^$ \t\n\r\f\v]|\$\$)+)",re.M) -def compile_fun_noshell(line): - buf=[] - dvars=[] - merge=False - app=buf.append - def add_dvar(x): - if x not in dvars: - dvars.append(x) - def replc(m): - if m.group('and'): - return' and ' - elif m.group('or'): - return' or ' - else: - x=m.group('var') - add_dvar(x) - return'env[%r]'%x - for m in reg_act_noshell.finditer(line): - if m.group('space'): - merge=False - continue - elif m.group('text'): - app('[%r]'%m.group('text').replace('$$','$')) - elif m.group('subst'): - var=m.group('var') - code=m.group('code') - if var=='SRC': - if code: - app('[tsk.inputs%s]'%code) - else: - app('[a.path_from(cwdx) for a in tsk.inputs]') - elif var=='TGT': - if code: - app('[tsk.outputs%s]'%code) - else: - app('[a.path_from(cwdx) for a in tsk.outputs]') - elif code: - if code.startswith(':'): - add_dvar(var) - m=code[1:] - if m=='SRC': - m='[a.path_from(cwdx) for a in tsk.inputs]' - elif m=='TGT': - m='[a.path_from(cwdx) for a in tsk.outputs]' - elif re_novar.match(m): - m='[tsk.inputs%s]'%m[3:] - elif re_novar.match(m): - m='[tsk.outputs%s]'%m[3:] - else: - add_dvar(m) - if m[:3]not in('tsk','gen','bld'): - m='%r'%m - app('tsk.colon(%r, %s)'%(var,m)) - elif code.startswith('?'): - expr=re_cond.sub(replc,code[1:]) - app('to_list(env[%r] if (%s) else [])'%(var,expr)) - else: - call='%s%s'%(var,code) - add_dvar(call) - app('to_list(%s)'%call) - else: - app('to_list(env[%r])'%var) - add_dvar(var) - if merge: - tmp='merge(%s, %s)'%(buf[-2],buf[-1]) - del buf[-1] - buf[-1]=tmp - merge=True - buf=['lst.extend(%s)'%x for x in buf] - fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf) - Logs.debug('action: %s',fun.strip().splitlines()) - return(funex(fun),dvars) -def compile_fun(line,shell=False): - if isinstance(line,str): - if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0: - shell=True - else: - dvars_lst=[] - funs_lst=[] - for x in line: - if isinstance(x,str): - fun,dvars=compile_fun(x,shell) - dvars_lst+=dvars - funs_lst.append(fun) - else: - funs_lst.append(x) - def composed_fun(task): - for x in funs_lst: - ret=x(task) - if ret: - return ret - return None - return composed_fun,dvars_lst - if shell: - return compile_fun_shell(line) - else: - return compile_fun_noshell(line) -def compile_sig_vars(vars): - buf=[] - for x in sorted(vars): - if x[:3]in('tsk','gen','bld'): - buf.append('buf.append(%s)'%x) - if buf: - return funex(COMPILE_TEMPLATE_SIG_VARS%'\n\t'.join(buf)) - return None -def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None): - params={'vars':vars or[],'color':color,'name':name,'shell':shell,'scan':scan,} - if isinstance(func,str)or isinstance(func,tuple): - params['run_str']=func - else: - params['run']=func - cls=type(Task)(name,(Task,),params) - classes[name]=cls - if ext_in: - cls.ext_in=Utils.to_list(ext_in) - if ext_out: - cls.ext_out=Utils.to_list(ext_out) - if before: - cls.before=Utils.to_list(before) - if after: - cls.after=Utils.to_list(after) - return cls -def deep_inputs(cls): - def sig_explicit_deps(self): - Task.sig_explicit_deps(self) - Task.sig_deep_inputs(self) - cls.sig_explicit_deps=sig_explicit_deps - return cls -TaskBase=Task -class TaskSemaphore(object): - def __init__(self,num): - self.num=num - self.locking=set() - self.waiting=set() - def is_locked(self): - return len(self.locking)>=self.num - def acquire(self,tsk): - if self.is_locked(): - raise IndexError('Cannot lock more %r'%self.locking) - self.locking.add(tsk) - def release(self,tsk): - self.locking.remove(tsk) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py deleted file mode 100755 index c5cf6d7..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py +++ /dev/null @@ -1,471 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import copy,re,os,functools -from waflib import Task,Utils,Logs,Errors,ConfigSet,Node -feats=Utils.defaultdict(set) -HEADER_EXTS=['.h','.hpp','.hxx','.hh'] -class task_gen(object): - mappings=Utils.ordered_iter_dict() - prec=Utils.defaultdict(set) - def __init__(self,*k,**kw): - self.source=[] - self.target='' - self.meths=[] - self.features=[] - self.tasks=[] - if not'bld'in kw: - self.env=ConfigSet.ConfigSet() - self.idx=0 - self.path=None - else: - self.bld=kw['bld'] - self.env=self.bld.env.derive() - self.path=kw.get('path',self.bld.path) - path=self.path.abspath() - try: - self.idx=self.bld.idx[path]=self.bld.idx.get(path,0)+1 - except AttributeError: - self.bld.idx={} - self.idx=self.bld.idx[path]=1 - try: - self.tg_idx_count=self.bld.tg_idx_count=self.bld.tg_idx_count+1 - except AttributeError: - self.tg_idx_count=self.bld.tg_idx_count=1 - for key,val in kw.items(): - setattr(self,key,val) - def __str__(self): - return""%(self.name,self.path.abspath()) - def __repr__(self): - lst=[] - for x in self.__dict__: - if x not in('env','bld','compiled_tasks','tasks'): - lst.append("%s=%s"%(x,repr(getattr(self,x)))) - return"bld(%s) in %s"%(", ".join(lst),self.path.abspath()) - def get_cwd(self): - return self.bld.bldnode - def get_name(self): - try: - return self._name - except AttributeError: - if isinstance(self.target,list): - lst=[str(x)for x in self.target] - name=self._name=','.join(lst) - else: - name=self._name=str(self.target) - return name - def set_name(self,name): - self._name=name - name=property(get_name,set_name) - def to_list(self,val): - if isinstance(val,str): - return val.split() - else: - return val - def post(self): - if getattr(self,'posted',None): - return False - self.posted=True - keys=set(self.meths) - keys.update(feats['*']) - self.features=Utils.to_list(self.features) - for x in self.features: - st=feats[x] - if st: - keys.update(st) - elif not x in Task.classes: - Logs.warn('feature %r does not exist - bind at least one method to it?',x) - prec={} - prec_tbl=self.prec - for x in prec_tbl: - if x in keys: - prec[x]=prec_tbl[x] - tmp=[] - for a in keys: - for x in prec.values(): - if a in x: - break - else: - tmp.append(a) - tmp.sort(reverse=True) - out=[] - while tmp: - e=tmp.pop() - if e in keys: - out.append(e) - try: - nlst=prec[e] - except KeyError: - pass - else: - del prec[e] - for x in nlst: - for y in prec: - if x in prec[y]: - break - else: - tmp.append(x) - tmp.sort(reverse=True) - if prec: - buf=['Cycle detected in the method execution:'] - for k,v in prec.items(): - buf.append('- %s after %s'%(k,[x for x in v if x in prec])) - raise Errors.WafError('\n'.join(buf)) - self.meths=out - Logs.debug('task_gen: posting %s %d',self,id(self)) - for x in out: - try: - v=getattr(self,x) - except AttributeError: - raise Errors.WafError('%r is not a valid task generator method'%x) - Logs.debug('task_gen: -> %s (%d)',x,id(self)) - v() - Logs.debug('task_gen: posted %s',self.name) - return True - def get_hook(self,node): - name=node.name - for k in self.mappings: - try: - if name.endswith(k): - return self.mappings[k] - except TypeError: - if k.match(name): - return self.mappings[k] - keys=list(self.mappings.keys()) - raise Errors.WafError("File %r has no mapping in %r (load a waf tool?)"%(node,keys)) - def create_task(self,name,src=None,tgt=None,**kw): - task=Task.classes[name](env=self.env.derive(),generator=self) - if src: - task.set_inputs(src) - if tgt: - task.set_outputs(tgt) - task.__dict__.update(kw) - self.tasks.append(task) - return task - def clone(self,env): - newobj=self.bld() - for x in self.__dict__: - if x in('env','bld'): - continue - elif x in('path','features'): - setattr(newobj,x,getattr(self,x)) - else: - setattr(newobj,x,copy.copy(getattr(self,x))) - newobj.posted=False - if isinstance(env,str): - newobj.env=self.bld.all_envs[env].derive() - else: - newobj.env=env.derive() - return newobj -def declare_chain(name='',rule=None,reentrant=None,color='BLUE',ext_in=[],ext_out=[],before=[],after=[],decider=None,scan=None,install_path=None,shell=False): - ext_in=Utils.to_list(ext_in) - ext_out=Utils.to_list(ext_out) - if not name: - name=rule - cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell) - def x_file(self,node): - if ext_in: - _ext_in=ext_in[0] - tsk=self.create_task(name,node) - cnt=0 - ext=decider(self,node)if decider else cls.ext_out - for x in ext: - k=node.change_ext(x,ext_in=_ext_in) - tsk.outputs.append(k) - if reentrant!=None: - if cnt1: - self.to_log('Command failure: %s'%e) - self.fatal('The configuration failed') - else: - if not ret: - ret=True - kw['success']=ret - if'okmsg'in kw: - self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) - return ret -def build_fun(bld): - if bld.kw['compile_filename']: - node=bld.srcnode.make_node(bld.kw['compile_filename']) - node.write(bld.kw['code']) - o=bld(features=bld.kw['features'],source=bld.kw['compile_filename'],target='testprog') - for k,v in bld.kw.items(): - setattr(o,k,v) - if not bld.kw.get('quiet'): - bld.conf.to_log("==>\n%s\n<=="%bld.kw['code']) -@conf -def validate_c(self,kw): - for x in('type_name','field_name','function_name'): - if x in kw: - Logs.warn('Invalid argument %r in test'%x) - if not'build_fun'in kw: - kw['build_fun']=build_fun - if not'env'in kw: - kw['env']=self.env.derive() - env=kw['env'] - if not'compiler'in kw and not'features'in kw: - kw['compiler']='c' - if env.CXX_NAME and Task.classes.get('cxx'): - kw['compiler']='cxx' - if not self.env.CXX: - self.fatal('a c++ compiler is required') - else: - if not self.env.CC: - self.fatal('a c compiler is required') - if not'compile_mode'in kw: - kw['compile_mode']='c' - if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler')=='cxx': - kw['compile_mode']='cxx' - if not'type'in kw: - kw['type']='cprogram' - if not'features'in kw: - if not'header_name'in kw or kw.get('link_header_test',True): - kw['features']=[kw['compile_mode'],kw['type']] - else: - kw['features']=[kw['compile_mode']] - else: - kw['features']=Utils.to_list(kw['features']) - if not'compile_filename'in kw: - kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'') - def to_header(dct): - if'header_name'in dct: - dct=Utils.to_list(dct['header_name']) - return''.join(['#include <%s>\n'%x for x in dct]) - return'' - if'framework_name'in kw: - fwkname=kw['framework_name'] - if not'uselib_store'in kw: - kw['uselib_store']=fwkname.upper() - if not kw.get('no_header'): - fwk='%s/%s.h'%(fwkname,fwkname) - if kw.get('remove_dot_h'): - fwk=fwk[:-2] - val=kw.get('header_name',[]) - kw['header_name']=Utils.to_list(val)+[fwk] - kw['msg']='Checking for framework %s'%fwkname - kw['framework']=fwkname - elif'header_name'in kw: - if not'msg'in kw: - kw['msg']='Checking for header %s'%kw['header_name'] - l=Utils.to_list(kw['header_name']) - assert len(l),'list of headers in header_name is empty' - kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM - if not'uselib_store'in kw: - kw['uselib_store']=l[0].upper() - if not'define_name'in kw: - kw['define_name']=self.have_define(l[0]) - if'lib'in kw: - if not'msg'in kw: - kw['msg']='Checking for library %s'%kw['lib'] - if not'uselib_store'in kw: - kw['uselib_store']=kw['lib'].upper() - if'stlib'in kw: - if not'msg'in kw: - kw['msg']='Checking for static library %s'%kw['stlib'] - if not'uselib_store'in kw: - kw['uselib_store']=kw['stlib'].upper() - if'fragment'in kw: - kw['code']=kw['fragment'] - if not'msg'in kw: - kw['msg']='Checking for code snippet' - if not'errmsg'in kw: - kw['errmsg']='no' - for(flagsname,flagstype)in(('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')): - if flagsname in kw: - if not'msg'in kw: - kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname]) - if not'errmsg'in kw: - kw['errmsg']='no' - if not'execute'in kw: - kw['execute']=False - if kw['execute']: - kw['features'].append('test_exec') - kw['chmod']=Utils.O755 - if not'errmsg'in kw: - kw['errmsg']='not found' - if not'okmsg'in kw: - kw['okmsg']='yes' - if not'code'in kw: - kw['code']=SNIP_EMPTY_PROGRAM - if self.env[INCKEYS]: - kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code'] - if kw.get('merge_config_header')or env.merge_config_header: - kw['code']='%s\n\n%s'%(self.get_config_header(),kw['code']) - env.DEFINES=[] - if not kw.get('success'): - kw['success']=None - if'define_name'in kw: - self.undefine(kw['define_name']) - if not'msg'in kw: - self.fatal('missing "msg" in conf.check(...)') -@conf -def post_check(self,*k,**kw): - is_success=0 - if kw['execute']: - if kw['success']is not None: - if kw.get('define_ret'): - is_success=kw['success'] - else: - is_success=(kw['success']==0) - else: - is_success=(kw['success']==0) - if kw.get('define_name'): - comment=kw.get('comment','') - define_name=kw['define_name'] - if kw['execute']and kw.get('define_ret')and isinstance(is_success,str): - if kw.get('global_define',1): - self.define(define_name,is_success,quote=kw.get('quote',1),comment=comment) - else: - if kw.get('quote',1): - succ='"%s"'%is_success - else: - succ=int(is_success) - val='%s=%s'%(define_name,succ) - var='DEFINES_%s'%kw['uselib_store'] - self.env.append_value(var,val) - else: - if kw.get('global_define',1): - self.define_cond(define_name,is_success,comment=comment) - else: - var='DEFINES_%s'%kw['uselib_store'] - self.env.append_value(var,'%s=%s'%(define_name,int(is_success))) - if kw.get('add_have_to_env',1): - if kw.get('uselib_store'): - self.env[self.have_define(kw['uselib_store'])]=1 - elif kw['execute']and kw.get('define_ret'): - self.env[define_name]=is_success - else: - self.env[define_name]=int(is_success) - if'header_name'in kw: - if kw.get('auto_add_header_name'): - self.env.append_value(INCKEYS,Utils.to_list(kw['header_name'])) - if is_success and'uselib_store'in kw: - from waflib.Tools import ccroot - _vars=set() - for x in kw['features']: - if x in ccroot.USELIB_VARS: - _vars|=ccroot.USELIB_VARS[x] - for k in _vars: - x=k.lower() - if x in kw: - self.env.append_value(k+'_'+kw['uselib_store'],kw[x]) - return is_success -@conf -def check(self,*k,**kw): - self.validate_c(kw) - self.start_msg(kw['msg'],**kw) - ret=None - try: - ret=self.run_build(*k,**kw) - except self.errors.ConfigurationError: - self.end_msg(kw['errmsg'],'YELLOW',**kw) - if Logs.verbose>1: - raise - else: - self.fatal('The configuration failed') - else: - kw['success']=ret - ret=self.post_check(*k,**kw) - if not ret: - self.end_msg(kw['errmsg'],'YELLOW',**kw) - self.fatal('The configuration failed %r'%ret) - else: - self.end_msg(self.ret_msg(kw['okmsg'],kw),**kw) - return ret -class test_exec(Task.Task): - color='PINK' - def run(self): - cmd=[self.inputs[0].abspath()]+getattr(self.generator,'test_args',[]) - if getattr(self.generator,'rpath',None): - if getattr(self.generator,'define_ret',False): - self.generator.bld.retval=self.generator.bld.cmd_and_log(cmd) - else: - self.generator.bld.retval=self.generator.bld.exec_command(cmd) - else: - env=self.env.env or{} - env.update(dict(os.environ)) - for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'): - env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'') - if getattr(self.generator,'define_ret',False): - self.generator.bld.retval=self.generator.bld.cmd_and_log(cmd,env=env) - else: - self.generator.bld.retval=self.generator.bld.exec_command(cmd,env=env) -@feature('test_exec') -@after_method('apply_link') -def test_exec_fun(self): - self.create_task('test_exec',self.link_task.outputs[0]) -@conf -def check_cxx(self,*k,**kw): - kw['compiler']='cxx' - return self.check(*k,**kw) -@conf -def check_cc(self,*k,**kw): - kw['compiler']='c' - return self.check(*k,**kw) -@conf -def set_define_comment(self,key,comment): - coms=self.env.DEFINE_COMMENTS - if not coms: - coms=self.env.DEFINE_COMMENTS={} - coms[key]=comment or'' -@conf -def get_define_comment(self,key): - coms=self.env.DEFINE_COMMENTS or{} - return coms.get(key,'') -@conf -def define(self,key,val,quote=True,comment=''): - assert isinstance(key,str) - if not key: - return - if val is True: - val=1 - elif val in(False,None): - val=0 - if isinstance(val,int)or isinstance(val,float): - s='%s=%s' - else: - s=quote and'%s="%s"'or'%s=%s' - app=s%(key,str(val)) - ban=key+'=' - lst=self.env.DEFINES - for x in lst: - if x.startswith(ban): - lst[lst.index(x)]=app - break - else: - self.env.append_value('DEFINES',app) - self.env.append_unique(DEFKEYS,key) - self.set_define_comment(key,comment) -@conf -def undefine(self,key,comment=''): - assert isinstance(key,str) - if not key: - return - ban=key+'=' - lst=[x for x in self.env.DEFINES if not x.startswith(ban)] - self.env.DEFINES=lst - self.env.append_unique(DEFKEYS,key) - self.set_define_comment(key,comment) -@conf -def define_cond(self,key,val,comment=''): - assert isinstance(key,str) - if not key: - return - if val: - self.define(key,1,comment=comment) - else: - self.undefine(key,comment=comment) -@conf -def is_defined(self,key): - assert key and isinstance(key,str) - ban=key+'=' - for x in self.env.DEFINES: - if x.startswith(ban): - return True - return False -@conf -def get_define(self,key): - assert key and isinstance(key,str) - ban=key+'=' - for x in self.env.DEFINES: - if x.startswith(ban): - return x[len(ban):] - return None -@conf -def have_define(self,key): - return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key) -@conf -def write_config_header(self,configfile='',guard='',top=False,defines=True,headers=False,remove=True,define_prefix=''): - if not configfile: - configfile=WAF_CONFIG_H - waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile) - node=top and self.bldnode or self.path.get_bld() - node=node.make_node(configfile) - node.parent.mkdir() - lst=['/* WARNING! All changes made to this file will be lost! */\n'] - lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard)) - lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix)) - lst.append('\n#endif /* %s */\n'%waf_guard) - node.write('\n'.join(lst)) - self.env.append_unique(Build.CFG_FILES,[node.abspath()]) - if remove: - for key in self.env[DEFKEYS]: - self.undefine(key) - self.env[DEFKEYS]=[] -@conf -def get_config_header(self,defines=True,headers=False,define_prefix=''): - lst=[] - if self.env.WAF_CONFIG_H_PRELUDE: - lst.append(self.env.WAF_CONFIG_H_PRELUDE) - if headers: - for x in self.env[INCKEYS]: - lst.append('#include <%s>'%x) - if defines: - tbl={} - for k in self.env.DEFINES: - a,_,b=k.partition('=') - tbl[a]=b - for k in self.env[DEFKEYS]: - caption=self.get_define_comment(k) - if caption: - caption=' /* %s */'%caption - try: - txt='#define %s%s %s%s'%(define_prefix,k,tbl[k],caption) - except KeyError: - txt='/* #undef %s%s */%s'%(define_prefix,k,caption) - lst.append(txt) - return"\n".join(lst) -@conf -def cc_add_flags(conf): - conf.add_os_flags('CPPFLAGS',dup=False) - conf.add_os_flags('CFLAGS',dup=False) -@conf -def cxx_add_flags(conf): - conf.add_os_flags('CPPFLAGS',dup=False) - conf.add_os_flags('CXXFLAGS',dup=False) -@conf -def link_add_flags(conf): - conf.add_os_flags('LINKFLAGS',dup=False) - conf.add_os_flags('LDFLAGS',dup=False) -@conf -def cc_load_tools(conf): - if not conf.env.DEST_OS: - conf.env.DEST_OS=Utils.unversioned_sys_platform() - conf.load('c') -@conf -def cxx_load_tools(conf): - if not conf.env.DEST_OS: - conf.env.DEST_OS=Utils.unversioned_sys_platform() - conf.load('cxx') -@conf -def get_cc_version(conf,cc,gcc=False,icc=False,clang=False): - cmd=cc+['-dM','-E','-'] - env=conf.env.env or None - try: - out,err=conf.cmd_and_log(cmd,output=0,input='\n'.encode(),env=env) - except Errors.WafError: - conf.fatal('Could not determine the compiler version %r'%cmd) - if gcc: - if out.find('__INTEL_COMPILER')>=0: - conf.fatal('The intel compiler pretends to be gcc') - if out.find('__GNUC__')<0 and out.find('__clang__')<0: - conf.fatal('Could not determine the compiler type') - if icc and out.find('__INTEL_COMPILER')<0: - conf.fatal('Not icc/icpc') - if clang and out.find('__clang__')<0: - conf.fatal('Not clang/clang++') - if not clang and out.find('__clang__')>=0: - conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') - k={} - if icc or gcc or clang: - out=out.splitlines() - for line in out: - lst=shlex.split(line) - if len(lst)>2: - key=lst[1] - val=lst[2] - k[key]=val - def isD(var): - return var in k - if not conf.env.DEST_OS: - conf.env.DEST_OS='' - for i in MACRO_TO_DESTOS: - if isD(i): - conf.env.DEST_OS=MACRO_TO_DESTOS[i] - break - else: - if isD('__APPLE__')and isD('__MACH__'): - conf.env.DEST_OS='darwin' - elif isD('__unix__'): - conf.env.DEST_OS='generic' - if isD('__ELF__'): - conf.env.DEST_BINFMT='elf' - elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'): - conf.env.DEST_BINFMT='pe' - if not conf.env.IMPLIBDIR: - conf.env.IMPLIBDIR=conf.env.LIBDIR - conf.env.LIBDIR=conf.env.BINDIR - elif isD('__APPLE__'): - conf.env.DEST_BINFMT='mac-o' - if not conf.env.DEST_BINFMT: - conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS) - for i in MACRO_TO_DEST_CPU: - if isD(i): - conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i] - break - Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')])) - if icc: - ver=k['__INTEL_COMPILER'] - conf.env.CC_VERSION=(ver[:-2],ver[-2],ver[-1]) - else: - if isD('__clang__')and isD('__clang_major__'): - conf.env.CC_VERSION=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__']) - else: - conf.env.CC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k.get('__GNUC_PATCHLEVEL__','0')) - return k -@conf -def get_xlc_version(conf,cc): - cmd=cc+['-qversion'] - try: - out,err=conf.cmd_and_log(cmd,output=0) - except Errors.WafError: - conf.fatal('Could not find xlc %r'%cmd) - for v in(r"IBM XL C/C\+\+.* V(?P\d*)\.(?P\d*)",): - version_re=re.compile(v,re.I).search - match=version_re(out or err) - if match: - k=match.groupdict() - conf.env.CC_VERSION=(k['major'],k['minor']) - break - else: - conf.fatal('Could not determine the XLC version.') -@conf -def get_suncc_version(conf,cc): - cmd=cc+['-V'] - try: - out,err=conf.cmd_and_log(cmd,output=0) - except Errors.WafError as e: - if not(hasattr(e,'returncode')and hasattr(e,'stdout')and hasattr(e,'stderr')): - conf.fatal('Could not find suncc %r'%cmd) - out=e.stdout - err=e.stderr - version=(out or err) - version=version.splitlines()[0] - version_re=re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P\d*)\.(?P\d*)',re.I).search - match=version_re(version) - if match: - k=match.groupdict() - conf.env.CC_VERSION=(k['major'],k['minor']) - else: - conf.fatal('Could not determine the suncc version.') -@conf -def add_as_needed(self): - if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME): - self.env.append_unique('LINKFLAGS','-Wl,--as-needed') -class cfgtask(Task.Task): - def __init__(self,*k,**kw): - Task.Task.__init__(self,*k,**kw) - self.run_after=set() - def display(self): - return'' - def runnable_status(self): - for x in self.run_after: - if not x.hasrun: - return Task.ASK_LATER - return Task.RUN_ME - def uid(self): - return Utils.SIG_NIL - def signature(self): - return Utils.SIG_NIL - def run(self): - conf=self.conf - bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath()) - bld.env=conf.env - bld.init_dirs() - bld.in_msg=1 - bld.logger=self.logger - bld.multicheck_task=self - args=self.args - try: - if'func'in args: - bld.test(build_fun=args['func'],msg=args.get('msg',''),okmsg=args.get('okmsg',''),errmsg=args.get('errmsg',''),) - else: - args['multicheck_mandatory']=args.get('mandatory',True) - args['mandatory']=True - try: - bld.check(**args) - finally: - args['mandatory']=args['multicheck_mandatory'] - except Exception: - return 1 - def process(self): - Task.Task.process(self) - if'msg'in self.args: - with self.generator.bld.multicheck_lock: - self.conf.start_msg(self.args['msg']) - if self.hasrun==Task.NOT_RUN: - self.conf.end_msg('test cancelled','YELLOW') - elif self.hasrun!=Task.SUCCESS: - self.conf.end_msg(self.args.get('errmsg','no'),'YELLOW') - else: - self.conf.end_msg(self.args.get('okmsg','yes'),'GREEN') -@conf -def multicheck(self,*k,**kw): - self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)),**kw) - for var in('DEFINES',DEFKEYS): - self.env.append_value(var,[]) - self.env.DEFINE_COMMENTS=self.env.DEFINE_COMMENTS or{} - class par(object): - def __init__(self): - self.keep=False - self.task_sigs={} - self.progress_bar=0 - def total(self): - return len(tasks) - def to_log(self,*k,**kw): - return - bld=par() - bld.keep=kw.get('run_all_tests',True) - bld.imp_sigs={} - tasks=[] - id_to_task={} - for dct in k: - x=Task.classes['cfgtask'](bld=bld,env=None) - tasks.append(x) - x.args=dct - x.bld=bld - x.conf=self - x.args=dct - x.logger=Logs.make_mem_logger(str(id(x)),self.logger) - if'id'in dct: - id_to_task[dct['id']]=x - for x in tasks: - for key in Utils.to_list(x.args.get('before_tests',[])): - tsk=id_to_task[key] - if not tsk: - raise ValueError('No test named %r'%key) - tsk.run_after.add(x) - for key in Utils.to_list(x.args.get('after_tests',[])): - tsk=id_to_task[key] - if not tsk: - raise ValueError('No test named %r'%key) - x.run_after.add(tsk) - def it(): - yield tasks - while 1: - yield[] - bld.producer=p=Runner.Parallel(bld,Options.options.jobs) - bld.multicheck_lock=Utils.threading.Lock() - p.biter=it() - self.end_msg('started') - p.start() - for x in tasks: - x.logger.memhandler.flush() - self.start_msg('-> processing test results') - if p.error: - for x in p.error: - if getattr(x,'err_msg',None): - self.to_log(x.err_msg) - self.end_msg('fail',color='RED') - raise Errors.WafError('There is an error in the library, read config.log for more information') - failure_count=0 - for x in tasks: - if x.hasrun not in(Task.SUCCESS,Task.NOT_RUN): - failure_count+=1 - if failure_count: - self.end_msg(kw.get('errmsg','%s test failed'%failure_count),color='YELLOW',**kw) - else: - self.end_msg('all ok',**kw) - for x in tasks: - if x.hasrun!=Task.SUCCESS: - if x.args.get('mandatory',True): - self.fatal(kw.get('fatalmsg')or'One of the tests has failed, read config.log for more information') -@conf -def check_gcc_o_space(self,mode='c'): - if int(self.env.CC_VERSION[0])>4: - return - self.env.stash() - if mode=='c': - self.env.CCLNK_TGT_F=['-o',''] - elif mode=='cxx': - self.env.CXXLNK_TGT_F=['-o',''] - features='%s %sshlib'%(mode,mode) - try: - self.check(msg='Checking if the -o link must be split from arguments',fragment=SNIP_EMPTY_PROGRAM,features=features) - except self.errors.ConfigurationError: - self.env.revert() - else: - self.env.commit() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py deleted file mode 100755 index 847b433..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py +++ /dev/null @@ -1,121 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,shutil,platform -from waflib import Task,Utils -from waflib.TaskGen import taskgen_method,feature,after_method,before_method -app_info=''' - - - - - CFBundlePackageType - APPL - CFBundleGetInfoString - Created by Waf - CFBundleSignature - ???? - NOTE - THIS IS A GENERATED FILE, DO NOT MODIFY - CFBundleExecutable - {app_name} - - -''' -@feature('c','cxx') -def set_macosx_deployment_target(self): - if self.env.MACOSX_DEPLOYMENT_TARGET: - os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env.MACOSX_DEPLOYMENT_TARGET - elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ: - if Utils.unversioned_sys_platform()=='darwin': - os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2]) -@taskgen_method -def create_bundle_dirs(self,name,out): - dir=out.parent.find_or_declare(name) - dir.mkdir() - macos=dir.find_or_declare(['Contents','MacOS']) - macos.mkdir() - return dir -def bundle_name_for_output(out): - name=out.name - k=name.rfind('.') - if k>=0: - name=name[:k]+'.app' - else: - name=name+'.app' - return name -@feature('cprogram','cxxprogram') -@after_method('apply_link') -def create_task_macapp(self): - if self.env.MACAPP or getattr(self,'mac_app',False): - out=self.link_task.outputs[0] - name=bundle_name_for_output(out) - dir=self.create_bundle_dirs(name,out) - n1=dir.find_or_declare(['Contents','MacOS',out.name]) - self.apptask=self.create_task('macapp',self.link_task.outputs,n1) - inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name - self.add_install_files(install_to=inst_to,install_from=n1,chmod=Utils.O755) - if getattr(self,'mac_files',None): - mac_files_root=getattr(self,'mac_files_root',None) - if isinstance(mac_files_root,str): - mac_files_root=self.path.find_node(mac_files_root) - if not mac_files_root: - self.bld.fatal('Invalid mac_files_root %r'%self.mac_files_root) - res_dir=n1.parent.parent.make_node('Resources') - inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name - for node in self.to_nodes(self.mac_files): - relpath=node.path_from(mac_files_root or node.parent) - self.create_task('macapp',node,res_dir.make_node(relpath)) - self.add_install_as(install_to=os.path.join(inst_to,relpath),install_from=node) - if getattr(self.bld,'is_install',None): - self.install_task.hasrun=Task.SKIP_ME -@feature('cprogram','cxxprogram') -@after_method('apply_link') -def create_task_macplist(self): - if self.env.MACAPP or getattr(self,'mac_app',False): - out=self.link_task.outputs[0] - name=bundle_name_for_output(out) - dir=self.create_bundle_dirs(name,out) - n1=dir.find_or_declare(['Contents','Info.plist']) - self.plisttask=plisttask=self.create_task('macplist',[],n1) - plisttask.context={'app_name':self.link_task.outputs[0].name,'env':self.env} - plist_ctx=getattr(self,'plist_context',None) - if(plist_ctx): - plisttask.context.update(plist_ctx) - if getattr(self,'mac_plist',False): - node=self.path.find_resource(self.mac_plist) - if node: - plisttask.inputs.append(node) - else: - plisttask.code=self.mac_plist - else: - plisttask.code=app_info - inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name - self.add_install_files(install_to=inst_to,install_from=n1) -@feature('cshlib','cxxshlib') -@before_method('apply_link','propagate_uselib_vars') -def apply_bundle(self): - if self.env.MACBUNDLE or getattr(self,'mac_bundle',False): - self.env.LINKFLAGS_cshlib=self.env.LINKFLAGS_cxxshlib=[] - self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN - use=self.use=self.to_list(getattr(self,'use',[])) - if not'MACBUNDLE'in use: - use.append('MACBUNDLE') -app_dirs=['Contents','Contents/MacOS','Contents/Resources'] -class macapp(Task.Task): - color='PINK' - def run(self): - self.outputs[0].parent.mkdir() - shutil.copy2(self.inputs[0].srcpath(),self.outputs[0].abspath()) -class macplist(Task.Task): - color='PINK' - ext_in=['.bin'] - def run(self): - if getattr(self,'code',None): - txt=self.code - else: - txt=self.inputs[0].read() - context=getattr(self,'context',{}) - txt=txt.format(**context) - self.outputs[0].write(txt) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py deleted file mode 100755 index a183c66..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py +++ /dev/null @@ -1,672 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re,string,traceback -from waflib import Logs,Utils,Errors -class PreprocError(Errors.WafError): - pass -FILE_CACHE_SIZE=100000 -LINE_CACHE_SIZE=100000 -POPFILE='-' -recursion_limit=150 -go_absolute=False -standard_includes=['/usr/local/include','/usr/include'] -if Utils.is_win32: - standard_includes=[] -use_trigraphs=0 -strict_quotes=0 -g_optrans={'not':'!','not_eq':'!','and':'&&','and_eq':'&=','or':'||','or_eq':'|=','xor':'^','xor_eq':'^=','bitand':'&','bitor':'|','compl':'~',} -re_lines=re.compile('^[ \t]*(?:#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE) -re_mac=re.compile(r"^[a-zA-Z_]\w*") -re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]') -re_pragma_once=re.compile(r'^\s*once\s*',re.IGNORECASE) -re_nl=re.compile('\\\\\r*\n',re.MULTILINE) -re_cpp=re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL|re.MULTILINE) -trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')] -chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39} -NUM='i' -OP='O' -IDENT='T' -STR='s' -CHAR='c' -tok_types=[NUM,STR,IDENT,OP] -exp_types=[r"""0[xX](?P[a-fA-F0-9]+)(?P[uUlL]*)|L*?'(?P(\\.|[^\\'])+)'|(?P\d+)[Ee](?P[+-]*?\d+)(?P[fFlL]*)|(?P\d*\.\d+)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P\d+\.\d*)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P0*)(?P\d+)(?P[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',] -re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M) -accepted='a' -ignored='i' -undefined='u' -skipped='s' -def repl(m): - s=m.group() - if s[0]=='/': - return' ' - return s -prec={} -ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',','] -for x,syms in enumerate(ops): - for u in syms.split(): - prec[u]=x -def reduce_nums(val_1,val_2,val_op): - try: - a=0+val_1 - except TypeError: - a=int(val_1) - try: - b=0+val_2 - except TypeError: - b=int(val_2) - d=val_op - if d=='%': - c=a%b - elif d=='+': - c=a+b - elif d=='-': - c=a-b - elif d=='*': - c=a*b - elif d=='/': - c=a/b - elif d=='^': - c=a^b - elif d=='==': - c=int(a==b) - elif d=='|'or d=='bitor': - c=a|b - elif d=='||'or d=='or': - c=int(a or b) - elif d=='&'or d=='bitand': - c=a&b - elif d=='&&'or d=='and': - c=int(a and b) - elif d=='!='or d=='not_eq': - c=int(a!=b) - elif d=='^'or d=='xor': - c=int(a^b) - elif d=='<=': - c=int(a<=b) - elif d=='<': - c=int(a': - c=int(a>b) - elif d=='>=': - c=int(a>=b) - elif d=='<<': - c=a<>': - c=a>>b - else: - c=0 - return c -def get_num(lst): - if not lst: - raise PreprocError('empty list for get_num') - (p,v)=lst[0] - if p==OP: - if v=='(': - count_par=1 - i=1 - while i=prec[v]: - num2=reduce_nums(num,num2,v) - return get_term([(NUM,num2)]+lst) - else: - num3,lst=get_num(lst[1:]) - num3=reduce_nums(num2,num3,v2) - return get_term([(NUM,num),(p,v),(NUM,num3)]+lst) - raise PreprocError('cannot reduce %r'%lst) -def reduce_eval(lst): - num,lst=get_term(lst) - return(NUM,num) -def stringize(lst): - lst=[str(v2)for(p2,v2)in lst] - return"".join(lst) -def paste_tokens(t1,t2): - p1=None - if t1[0]==OP and t2[0]==OP: - p1=OP - elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM): - p1=IDENT - elif t1[0]==NUM and t2[0]==NUM: - p1=NUM - if not p1: - raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2)) - return(p1,t1[1]+t2[1]) -def reduce_tokens(lst,defs,ban=[]): - i=0 - while i=len(lst): - raise PreprocError('expected ( after %r (got nothing)'%v) - (p2,v2)=lst[i] - if p2!=OP or v2!='(': - raise PreprocError('expected ( after %r'%v) - del lst[i] - one_param=[] - count_paren=0 - while i1: - (p3,v3)=accu[-1] - (p4,v4)=accu[-2] - if v3=='##': - accu.pop() - if v4==','and pt1: - return(v,[[],t[1:]]) - else: - return(v,[[],[('T','')]]) -re_include=re.compile(r'^\s*(<(?:.*)>|"(?:.*)")') -def extract_include(txt,defs): - m=re_include.search(txt) - if m: - txt=m.group(1) - return txt[0],txt[1:-1] - toks=tokenize(txt) - reduce_tokens(toks,defs,['waf_include']) - if not toks: - raise PreprocError('could not parse include %r'%txt) - if len(toks)==1: - if toks[0][0]==STR: - return'"',toks[0][1] - else: - if toks[0][1]=='<'and toks[-1][1]=='>': - ret='<',stringize(toks).lstrip('<').rstrip('>') - return ret - raise PreprocError('could not parse include %r'%txt) -def parse_char(txt): - if not txt: - raise PreprocError('attempted to parse a null char') - if txt[0]!='\\': - return ord(txt) - c=txt[1] - if c=='x': - if len(txt)==4 and txt[3]in string.hexdigits: - return int(txt[2:],16) - return int(txt[2:],16) - elif c.isdigit(): - if c=='0'and len(txt)==2: - return 0 - for i in 3,2,1: - if len(txt)>i and txt[1:1+i].isdigit(): - return(1+i,int(txt[1:1+i],8)) - else: - try: - return chr_esc[c] - except KeyError: - raise PreprocError('could not parse char literal %r'%txt) -def tokenize(s): - return tokenize_private(s)[:] -def tokenize_private(s): - ret=[] - for match in re_clexer.finditer(s): - m=match.group - for name in tok_types: - v=m(name) - if v: - if name==IDENT: - if v in g_optrans: - name=OP - elif v.lower()=="true": - v=1 - name=NUM - elif v.lower()=="false": - v=0 - name=NUM - elif name==NUM: - if m('oct'): - v=int(v,8) - elif m('hex'): - v=int(m('hex'),16) - elif m('n0'): - v=m('n0') - else: - v=m('char') - if v: - v=parse_char(v) - else: - v=m('n2')or m('n4') - elif name==OP: - if v=='%:': - v='#' - elif v=='%:%:': - v='##' - elif name==STR: - v=v[1:-1] - ret.append((name,v)) - break - return ret -def format_defines(lst): - ret=[] - for y in lst: - if y: - pos=y.find('=') - if pos==-1: - ret.append(y) - elif pos>0: - ret.append('%s %s'%(y[:pos],y[pos+1:])) - else: - raise ValueError('Invalid define expression %r'%y) - return ret -class c_parser(object): - def __init__(self,nodepaths=None,defines=None): - self.lines=[] - if defines is None: - self.defs={} - else: - self.defs=dict(defines) - self.state=[] - self.count_files=0 - self.currentnode_stack=[] - self.nodepaths=nodepaths or[] - self.nodes=[] - self.names=[] - self.curfile='' - self.ban_includes=set() - self.listed=set() - def cached_find_resource(self,node,filename): - try: - cache=node.ctx.preproc_cache_node - except AttributeError: - cache=node.ctx.preproc_cache_node=Utils.lru_cache(FILE_CACHE_SIZE) - key=(node,filename) - try: - return cache[key] - except KeyError: - ret=node.find_resource(filename) - if ret: - if getattr(ret,'children',None): - ret=None - elif ret.is_child_of(node.ctx.bldnode): - tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode)) - if tmp and getattr(tmp,'children',None): - ret=None - cache[key]=ret - return ret - def tryfind(self,filename,kind='"',env=None): - if filename.endswith('.moc'): - self.names.append(filename) - return None - self.curfile=filename - found=None - if kind=='"': - if env.MSVC_VERSION: - for n in reversed(self.currentnode_stack): - found=self.cached_find_resource(n,filename) - if found: - break - else: - found=self.cached_find_resource(self.currentnode_stack[-1],filename) - if not found: - for n in self.nodepaths: - found=self.cached_find_resource(n,filename) - if found: - break - listed=self.listed - if found and not found in self.ban_includes: - if found not in listed: - listed.add(found) - self.nodes.append(found) - self.addlines(found) - else: - if filename not in listed: - listed.add(filename) - self.names.append(filename) - return found - def filter_comments(self,node): - code=node.read() - if use_trigraphs: - for(a,b)in trig_def: - code=code.split(a).join(b) - code=re_nl.sub('',code) - code=re_cpp.sub(repl,code) - return re_lines.findall(code) - def parse_lines(self,node): - try: - cache=node.ctx.preproc_cache_lines - except AttributeError: - cache=node.ctx.preproc_cache_lines=Utils.lru_cache(LINE_CACHE_SIZE) - try: - return cache[node] - except KeyError: - cache[node]=lines=self.filter_comments(node) - lines.append((POPFILE,'')) - lines.reverse() - return lines - def addlines(self,node): - self.currentnode_stack.append(node.parent) - self.count_files+=1 - if self.count_files>recursion_limit: - raise PreprocError('recursion limit exceeded') - if Logs.verbose: - Logs.debug('preproc: reading file %r',node) - try: - lines=self.parse_lines(node) - except EnvironmentError: - raise PreprocError('could not read the file %r'%node) - except Exception: - if Logs.verbose>0: - Logs.error('parsing %r failed %s',node,traceback.format_exc()) - else: - self.lines.extend(lines) - def start(self,node,env): - Logs.debug('preproc: scanning %s (in %s)',node.name,node.parent.name) - self.current_file=node - self.addlines(node) - if env.DEFINES: - lst=format_defines(env.DEFINES) - lst.reverse() - self.lines.extend([('define',x)for x in lst]) - while self.lines: - (token,line)=self.lines.pop() - if token==POPFILE: - self.count_files-=1 - self.currentnode_stack.pop() - continue - try: - state=self.state - if token[:2]=='if': - state.append(undefined) - elif token=='endif': - state.pop() - if token[0]!='e': - if skipped in self.state or ignored in self.state: - continue - if token=='if': - ret=eval_macro(tokenize(line),self.defs) - if ret: - state[-1]=accepted - else: - state[-1]=ignored - elif token=='ifdef': - m=re_mac.match(line) - if m and m.group()in self.defs: - state[-1]=accepted - else: - state[-1]=ignored - elif token=='ifndef': - m=re_mac.match(line) - if m and m.group()in self.defs: - state[-1]=ignored - else: - state[-1]=accepted - elif token=='include'or token=='import': - (kind,inc)=extract_include(line,self.defs) - self.current_file=self.tryfind(inc,kind,env) - if token=='import': - self.ban_includes.add(self.current_file) - elif token=='elif': - if state[-1]==accepted: - state[-1]=skipped - elif state[-1]==ignored: - if eval_macro(tokenize(line),self.defs): - state[-1]=accepted - elif token=='else': - if state[-1]==accepted: - state[-1]=skipped - elif state[-1]==ignored: - state[-1]=accepted - elif token=='define': - try: - self.defs[self.define_name(line)]=line - except AttributeError: - raise PreprocError('Invalid define line %r'%line) - elif token=='undef': - m=re_mac.match(line) - if m and m.group()in self.defs: - self.defs.__delitem__(m.group()) - elif token=='pragma': - if re_pragma_once.match(line.lower()): - self.ban_includes.add(self.current_file) - except Exception as e: - if Logs.verbose: - Logs.debug('preproc: line parsing failed (%s): %s %s',e,line,traceback.format_exc()) - def define_name(self,line): - return re_mac.match(line).group() -def scan(task): - try: - incn=task.generator.includes_nodes - except AttributeError: - raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator) - if go_absolute: - nodepaths=incn+[task.generator.bld.root.find_dir(x)for x in standard_includes] - else: - nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)] - tmp=c_parser(nodepaths) - tmp.start(task.inputs[0],task.env) - return(tmp.nodes,tmp.names) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py deleted file mode 100755 index e295753..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py +++ /dev/null @@ -1,152 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Task -from waflib.Configure import conf -from waflib.TaskGen import feature,before_method,after_method -LIB_CODE=''' -#ifdef _MSC_VER -#define testEXPORT __declspec(dllexport) -#else -#define testEXPORT -#endif -testEXPORT int lib_func(void) { return 9; } -''' -MAIN_CODE=''' -#ifdef _MSC_VER -#define testEXPORT __declspec(dllimport) -#else -#define testEXPORT -#endif -testEXPORT int lib_func(void); -int main(int argc, char **argv) { - (void)argc; (void)argv; - return !(lib_func() == 9); -} -''' -@feature('link_lib_test') -@before_method('process_source') -def link_lib_test_fun(self): - def write_test_file(task): - task.outputs[0].write(task.generator.code) - rpath=[] - if getattr(self,'add_rpath',False): - rpath=[self.bld.path.get_bld().abspath()] - mode=self.mode - m='%s %s'%(mode,mode) - ex=self.test_exec and'test_exec'or'' - bld=self.bld - bld(rule=write_test_file,target='test.'+mode,code=LIB_CODE) - bld(rule=write_test_file,target='main.'+mode,code=MAIN_CODE) - bld(features='%sshlib'%m,source='test.'+mode,target='test') - bld(features='%sprogram %s'%(m,ex),source='main.'+mode,target='app',use='test',rpath=rpath) -@conf -def check_library(self,mode=None,test_exec=True): - if not mode: - mode='c' - if self.env.CXX: - mode='cxx' - self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec) -INLINE_CODE=''' -typedef int foo_t; -static %s foo_t static_foo () {return 0; } -%s foo_t foo () { - return 0; -} -''' -INLINE_VALUES=['inline','__inline__','__inline'] -@conf -def check_inline(self,**kw): - self.start_msg('Checking for inline') - if not'define_name'in kw: - kw['define_name']='INLINE_MACRO' - if not'features'in kw: - if self.env.CXX: - kw['features']=['cxx'] - else: - kw['features']=['c'] - for x in INLINE_VALUES: - kw['fragment']=INLINE_CODE%(x,x) - try: - self.check(**kw) - except self.errors.ConfigurationError: - continue - else: - self.end_msg(x) - if x!='inline': - self.define('inline',x,quote=False) - return x - self.fatal('could not use inline functions') -LARGE_FRAGMENT='''#include -int main(int argc, char **argv) { - (void)argc; (void)argv; - return !(sizeof(off_t) >= 8); -} -''' -@conf -def check_large_file(self,**kw): - if not'define_name'in kw: - kw['define_name']='HAVE_LARGEFILE' - if not'execute'in kw: - kw['execute']=True - if not'features'in kw: - if self.env.CXX: - kw['features']=['cxx','cxxprogram'] - else: - kw['features']=['c','cprogram'] - kw['fragment']=LARGE_FRAGMENT - kw['msg']='Checking for large file support' - ret=True - try: - if self.env.DEST_BINFMT!='pe': - ret=self.check(**kw) - except self.errors.ConfigurationError: - pass - else: - if ret: - return True - kw['msg']='Checking for -D_FILE_OFFSET_BITS=64' - kw['defines']=['_FILE_OFFSET_BITS=64'] - try: - ret=self.check(**kw) - except self.errors.ConfigurationError: - pass - else: - self.define('_FILE_OFFSET_BITS',64) - return ret - self.fatal('There is no support for large files') -ENDIAN_FRAGMENT=''' -short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; -short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; -int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; -} -short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; -short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; -int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; -} -extern int foo; -''' -class grep_for_endianness(Task.Task): - color='PINK' - def run(self): - txt=self.inputs[0].read(flags='rb').decode('latin-1') - if txt.find('LiTTleEnDian')>-1: - self.generator.tmp.append('little') - elif txt.find('BIGenDianSyS')>-1: - self.generator.tmp.append('big') - else: - return-1 -@feature('grep_for_endianness') -@after_method('process_source') -def grep_for_endianness_fun(self): - self.create_task('grep_for_endianness',self.compiled_tasks[0].outputs[0]) -@conf -def check_endianness(self): - tmp=[] - def check_msg(self): - return tmp[0] - self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg='Checking for endianness',define='ENDIANNESS',tmp=tmp,okmsg=check_msg,confcache=None) - return tmp[0] diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py deleted file mode 100755 index 9d865bf..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py +++ /dev/null @@ -1,486 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re -from waflib import Task,Utils,Node,Errors,Logs -from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension -from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests -from waflib.Configure import conf -SYSTEM_LIB_PATHS=['/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib'] -USELIB_VARS=Utils.defaultdict(set) -USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH']) -USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH']) -USELIB_VARS['d']=set(['INCLUDES','DFLAGS']) -USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH']) -USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS']) -USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS']) -USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS']) -USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) -USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) -USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS']) -USELIB_VARS['asm']=set(['ASFLAGS']) -@taskgen_method -def create_compiled_task(self,name,node): - out='%s.%d.o'%(node.name,self.idx) - task=self.create_task(name,node,node.parent.find_or_declare(out)) - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks=[task] - return task -@taskgen_method -def to_incnodes(self,inlst): - lst=[] - seen=set() - for x in self.to_list(inlst): - if x in seen or not x: - continue - seen.add(x) - if isinstance(x,Node.Node): - lst.append(x) - else: - if os.path.isabs(x): - lst.append(self.bld.root.make_node(x)or x) - else: - if x[0]=='#': - p=self.bld.bldnode.make_node(x[1:]) - v=self.bld.srcnode.make_node(x[1:]) - else: - p=self.path.get_bld().make_node(x) - v=self.path.make_node(x) - if p.is_child_of(self.bld.bldnode): - p.mkdir() - lst.append(p) - lst.append(v) - return lst -@feature('c','cxx','d','asm','fc','includes') -@after_method('propagate_uselib_vars','process_source') -def apply_incpaths(self): - lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env.INCLUDES) - self.includes_nodes=lst - cwd=self.get_cwd() - self.env.INCPATHS=[x.path_from(cwd)for x in lst] -class link_task(Task.Task): - color='YELLOW' - weight=3 - inst_to=None - chmod=Utils.O755 - def add_target(self,target): - if isinstance(target,str): - base=self.generator.path - if target.startswith('#'): - target=target[1:] - base=self.generator.bld.bldnode - pattern=self.env[self.__class__.__name__+'_PATTERN'] - if not pattern: - pattern='%s' - folder,name=os.path.split(target) - if self.__class__.__name__.find('shlib')>0 and getattr(self.generator,'vnum',None): - nums=self.generator.vnum.split('.') - if self.env.DEST_BINFMT=='pe': - name=name+'-'+nums[0] - elif self.env.DEST_OS=='openbsd': - pattern='%s.%s'%(pattern,nums[0]) - if len(nums)>=2: - pattern+='.%s'%nums[1] - if folder: - tmp=folder+os.sep+pattern%name - else: - tmp=pattern%name - target=base.find_or_declare(tmp) - self.set_outputs(target) - def exec_command(self,*k,**kw): - ret=super(link_task,self).exec_command(*k,**kw) - if not ret and self.env.DO_MANIFEST: - ret=self.exec_mf() - return ret - def exec_mf(self): - if not self.env.MT: - return 0 - manifest=None - for out_node in self.outputs: - if out_node.name.endswith('.manifest'): - manifest=out_node.abspath() - break - else: - return 0 - mode='' - for x in Utils.to_list(self.generator.features): - if x in('cprogram','cxxprogram','fcprogram','fcprogram_test'): - mode=1 - elif x in('cshlib','cxxshlib','fcshlib'): - mode=2 - Logs.debug('msvc: embedding manifest in mode %r',mode) - lst=[]+self.env.MT - lst.extend(Utils.to_list(self.env.MTFLAGS)) - lst.extend(['-manifest',manifest]) - lst.append('-outputresource:%s;%s'%(self.outputs[0].abspath(),mode)) - return super(link_task,self).exec_command(lst) -class stlink_task(link_task): - run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}' - chmod=Utils.O644 -def rm_tgt(cls): - old=cls.run - def wrap(self): - try: - os.remove(self.outputs[0].abspath()) - except OSError: - pass - return old(self) - setattr(cls,'run',wrap) -rm_tgt(stlink_task) -@feature('skip_stlib_link_deps') -@before_method('process_use') -def apply_skip_stlib_link_deps(self): - self.env.SKIP_STLIB_LINK_DEPS=True -@feature('c','cxx','d','fc','asm') -@after_method('process_source') -def apply_link(self): - for x in self.features: - if x=='cprogram'and'cxx'in self.features: - x='cxxprogram' - elif x=='cshlib'and'cxx'in self.features: - x='cxxshlib' - if x in Task.classes: - if issubclass(Task.classes[x],link_task): - link=x - break - else: - return - objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])] - self.link_task=self.create_task(link,objs) - self.link_task.add_target(self.target) - try: - inst_to=self.install_path - except AttributeError: - inst_to=self.link_task.inst_to - if inst_to: - self.install_task=self.add_install_files(install_to=inst_to,install_from=self.link_task.outputs[:],chmod=self.link_task.chmod,task=self.link_task) -@taskgen_method -def use_rec(self,name,**kw): - if name in self.tmp_use_not or name in self.tmp_use_seen: - return - try: - y=self.bld.get_tgen_by_name(name) - except Errors.WafError: - self.uselib.append(name) - self.tmp_use_not.add(name) - return - self.tmp_use_seen.append(name) - y.post() - y.tmp_use_objects=objects=kw.get('objects',True) - y.tmp_use_stlib=stlib=kw.get('stlib',True) - try: - link_task=y.link_task - except AttributeError: - y.tmp_use_var='' - else: - objects=False - if not isinstance(link_task,stlink_task): - stlib=False - y.tmp_use_var='LIB' - else: - y.tmp_use_var='STLIB' - p=self.tmp_use_prec - for x in self.to_list(getattr(y,'use',[])): - if self.env["STLIB_"+x]: - continue - try: - p[x].append(name) - except KeyError: - p[x]=[name] - self.use_rec(x,objects=objects,stlib=stlib) -@feature('c','cxx','d','use','fc') -@before_method('apply_incpaths','propagate_uselib_vars') -@after_method('apply_link','process_source') -def process_use(self): - use_not=self.tmp_use_not=set() - self.tmp_use_seen=[] - use_prec=self.tmp_use_prec={} - self.uselib=self.to_list(getattr(self,'uselib',[])) - self.includes=self.to_list(getattr(self,'includes',[])) - names=self.to_list(getattr(self,'use',[])) - for x in names: - self.use_rec(x) - for x in use_not: - if x in use_prec: - del use_prec[x] - out=self.tmp_use_sorted=[] - tmp=[] - for x in self.tmp_use_seen: - for k in use_prec.values(): - if x in k: - break - else: - tmp.append(x) - while tmp: - e=tmp.pop() - out.append(e) - try: - nlst=use_prec[e] - except KeyError: - pass - else: - del use_prec[e] - for x in nlst: - for y in use_prec: - if x in use_prec[y]: - break - else: - tmp.append(x) - if use_prec: - raise Errors.WafError('Cycle detected in the use processing %r'%use_prec) - out.reverse() - link_task=getattr(self,'link_task',None) - for x in out: - y=self.bld.get_tgen_by_name(x) - var=y.tmp_use_var - if var and link_task: - if self.env.SKIP_STLIB_LINK_DEPS and isinstance(link_task,stlink_task): - pass - elif var=='LIB'or y.tmp_use_stlib or x in names: - self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]]) - self.link_task.dep_nodes.extend(y.link_task.outputs) - tmp_path=y.link_task.outputs[0].parent.path_from(self.get_cwd()) - self.env.append_unique(var+'PATH',[tmp_path]) - else: - if y.tmp_use_objects: - self.add_objects_from_tgen(y) - if getattr(y,'export_includes',None): - self.includes=self.includes+y.to_incnodes(y.export_includes) - if getattr(y,'export_defines',None): - self.env.append_value('DEFINES',self.to_list(y.export_defines)) - for x in names: - try: - y=self.bld.get_tgen_by_name(x) - except Errors.WafError: - if not self.env['STLIB_'+x]and not x in self.uselib: - self.uselib.append(x) - else: - for k in self.to_list(getattr(y,'use',[])): - if not self.env['STLIB_'+k]and not k in self.uselib: - self.uselib.append(k) -@taskgen_method -def accept_node_to_link(self,node): - return not node.name.endswith('.pdb') -@taskgen_method -def add_objects_from_tgen(self,tg): - try: - link_task=self.link_task - except AttributeError: - pass - else: - for tsk in getattr(tg,'compiled_tasks',[]): - for x in tsk.outputs: - if self.accept_node_to_link(x): - link_task.inputs.append(x) -@taskgen_method -def get_uselib_vars(self): - _vars=set() - for x in self.features: - if x in USELIB_VARS: - _vars|=USELIB_VARS[x] - return _vars -@feature('c','cxx','d','fc','javac','cs','uselib','asm') -@after_method('process_use') -def propagate_uselib_vars(self): - _vars=self.get_uselib_vars() - env=self.env - app=env.append_value - feature_uselib=self.features+self.to_list(getattr(self,'uselib',[])) - for var in _vars: - y=var.lower() - val=getattr(self,y,[]) - if val: - app(var,self.to_list(val)) - for x in feature_uselib: - val=env['%s_%s'%(var,x)] - if val: - app(var,val) -@feature('cshlib','cxxshlib','fcshlib') -@after_method('apply_link') -def apply_implib(self): - if not self.env.DEST_BINFMT=='pe': - return - dll=self.link_task.outputs[0] - if isinstance(self.target,Node.Node): - name=self.target.name - else: - name=os.path.split(self.target)[1] - implib=self.env.implib_PATTERN%name - implib=dll.parent.find_or_declare(implib) - self.env.append_value('LINKFLAGS',self.env.IMPLIB_ST%implib.bldpath()) - self.link_task.outputs.append(implib) - if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe': - node=self.path.find_resource(self.defs) - if not node: - raise Errors.WafError('invalid def file %r'%self.defs) - if self.env.def_PATTERN: - self.env.append_value('LINKFLAGS',self.env.def_PATTERN%node.path_from(self.get_cwd())) - self.link_task.dep_nodes.append(node) - else: - self.link_task.inputs.append(node) - if getattr(self,'install_task',None): - try: - inst_to=self.install_path_implib - except AttributeError: - try: - inst_to=self.install_path - except AttributeError: - inst_to='${IMPLIBDIR}' - self.install_task.install_to='${BINDIR}' - if not self.env.IMPLIBDIR: - self.env.IMPLIBDIR=self.env.LIBDIR - self.implib_install_task=self.add_install_files(install_to=inst_to,install_from=implib,chmod=self.link_task.chmod,task=self.link_task) -re_vnum=re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$') -@feature('cshlib','cxxshlib','dshlib','fcshlib','vnum') -@after_method('apply_link','propagate_uselib_vars') -def apply_vnum(self): - if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'): - return - link=self.link_task - if not re_vnum.match(self.vnum): - raise Errors.WafError('Invalid vnum %r for target %r'%(self.vnum,getattr(self,'name',self))) - nums=self.vnum.split('.') - node=link.outputs[0] - cnum=getattr(self,'cnum',str(nums[0])) - cnums=cnum.split('.') - if len(cnums)>len(nums)or nums[0:len(cnums)]!=cnums: - raise Errors.WafError('invalid compatibility version %s'%cnum) - libname=node.name - if libname.endswith('.dylib'): - name3=libname.replace('.dylib','.%s.dylib'%self.vnum) - name2=libname.replace('.dylib','.%s.dylib'%cnum) - else: - name3=libname+'.'+self.vnum - name2=libname+'.'+cnum - if self.env.SONAME_ST: - v=self.env.SONAME_ST%name2 - self.env.append_value('LINKFLAGS',v.split()) - if self.env.DEST_OS!='openbsd': - outs=[node.parent.make_node(name3)] - if name2!=name3: - outs.append(node.parent.make_node(name2)) - self.create_task('vnum',node,outs) - if getattr(self,'install_task',None): - self.install_task.hasrun=Task.SKIPPED - self.install_task.no_errcheck_out=True - path=self.install_task.install_to - if self.env.DEST_OS=='openbsd': - libname=self.link_task.outputs[0].name - t1=self.add_install_as(install_to='%s/%s'%(path,libname),install_from=node,chmod=self.link_task.chmod) - self.vnum_install_task=(t1,) - else: - t1=self.add_install_as(install_to=path+os.sep+name3,install_from=node,chmod=self.link_task.chmod) - t3=self.add_symlink_as(install_to=path+os.sep+libname,install_from=name3) - if name2!=name3: - t2=self.add_symlink_as(install_to=path+os.sep+name2,install_from=name3) - self.vnum_install_task=(t1,t2,t3) - else: - self.vnum_install_task=(t1,t3) - if'-dynamiclib'in self.env.LINKFLAGS: - try: - inst_to=self.install_path - except AttributeError: - inst_to=self.link_task.inst_to - if inst_to: - p=Utils.subst_vars(inst_to,self.env) - path=os.path.join(p,name2) - self.env.append_value('LINKFLAGS',['-install_name',path]) - self.env.append_value('LINKFLAGS','-Wl,-compatibility_version,%s'%cnum) - self.env.append_value('LINKFLAGS','-Wl,-current_version,%s'%self.vnum) -class vnum(Task.Task): - color='CYAN' - ext_in=['.bin'] - def keyword(self): - return'Symlinking' - def run(self): - for x in self.outputs: - path=x.abspath() - try: - os.remove(path) - except OSError: - pass - try: - os.symlink(self.inputs[0].name,path) - except OSError: - return 1 -class fake_shlib(link_task): - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - return Task.SKIP_ME -class fake_stlib(stlink_task): - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - return Task.SKIP_ME -@conf -def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]): - return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib',export_includes=export_includes,export_defines=export_defines) -@conf -def read_stlib(self,name,paths=[],export_includes=[],export_defines=[]): - return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib',export_includes=export_includes,export_defines=export_defines) -lib_patterns={'shlib':['lib%s.so','%s.so','lib%s.dylib','lib%s.dll','%s.dll'],'stlib':['lib%s.a','%s.a','lib%s.dll','%s.dll','lib%s.lib','%s.lib'],} -@feature('fake_lib') -def process_lib(self): - node=None - names=[x%self.name for x in lib_patterns[self.lib_type]] - for x in self.lib_paths+[self.path]+SYSTEM_LIB_PATHS: - if not isinstance(x,Node.Node): - x=self.bld.root.find_node(x)or self.path.find_node(x) - if not x: - continue - for y in names: - node=x.find_node(y) - if node: - try: - Utils.h_file(node.abspath()) - except EnvironmentError: - raise ValueError('Could not read %r'%y) - break - else: - continue - break - else: - raise Errors.WafError('could not find library %r'%self.name) - self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node]) - self.target=self.name -class fake_o(Task.Task): - def runnable_status(self): - return Task.SKIP_ME -@extension('.o','.obj') -def add_those_o_files(self,node): - tsk=self.create_task('fake_o',[],node) - try: - self.compiled_tasks.append(tsk) - except AttributeError: - self.compiled_tasks=[tsk] -@feature('fake_obj') -@before_method('process_source') -def process_objs(self): - for node in self.to_nodes(self.source): - self.add_those_o_files(node) - self.source=[] -@conf -def read_object(self,obj): - if not isinstance(obj,self.path.__class__): - obj=self.path.find_resource(obj) - return self(features='fake_obj',source=obj,name=obj.name) -@feature('cxxprogram','cprogram') -@after_method('apply_link','process_use') -def set_full_paths_hpux(self): - if self.env.DEST_OS!='hp-ux': - return - base=self.bld.bldnode.abspath() - for var in['LIBPATH','STLIBPATH']: - lst=[] - for x in self.env[var]: - if x.startswith('/'): - lst.append(x) - else: - lst.append(os.path.normpath(os.path.join(base,x))) - self.env[var]=lst diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py deleted file mode 100755 index 9379f5a..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py +++ /dev/null @@ -1,20 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.Tools import ccroot,ar,gcc -from waflib.Configure import conf -@conf -def find_clang(conf): - cc=conf.find_program('clang',var='CC') - conf.get_cc_version(cc,clang=True) - conf.env.CC_NAME='clang' -def configure(conf): - conf.find_clang() - conf.find_program(['llvm-ar','ar'],var='AR') - conf.find_ar() - conf.gcc_common_flags() - conf.gcc_modifier_platform() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py deleted file mode 100755 index fc97135..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py +++ /dev/null @@ -1,20 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.Tools import ccroot,ar,gxx -from waflib.Configure import conf -@conf -def find_clangxx(conf): - cxx=conf.find_program('clang++',var='CXX') - conf.get_cc_version(cxx,clang=True) - conf.env.CXX_NAME='clang' -def configure(conf): - conf.find_clangxx() - conf.find_program(['llvm-ar','ar'],var='AR') - conf.find_ar() - conf.gxx_common_flags() - conf.gxx_modifier_platform() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py deleted file mode 100755 index ee607be..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py +++ /dev/null @@ -1,44 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib.Tools import ccroot -from waflib import Utils -from waflib.Logs import debug -c_compiler={'win32':['msvc','gcc','clang'],'cygwin':['gcc'],'darwin':['clang','gcc'],'aix':['xlc','gcc','clang'],'linux':['gcc','clang','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'osf1V':['gcc'],'gnu':['gcc','clang'],'java':['gcc','msvc','clang','icc'],'default':['clang','gcc'],} -def default_compilers(): - build_platform=Utils.unversioned_sys_platform() - possible_compiler_list=c_compiler.get(build_platform,c_compiler['default']) - return' '.join(possible_compiler_list) -def configure(conf): - try: - test_for_compiler=conf.options.check_c_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_c')") - for compiler in re.split('[ ,]+',test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (C compiler)'%compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - debug('compiler_c: %r',e) - else: - if conf.env.CC: - conf.end_msg(conf.env.get_flat('CC')) - conf.env.COMPILER_CC=compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a C compiler!') -def options(opt): - test_for_compiler=default_compilers() - opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py']) - cc_compiler_opts=opt.add_option_group('Configuration options') - cc_compiler_opts.add_option('--check-c-compiler',default=None,help='list of C compilers to try [%s]'%test_for_compiler,dest="check_c_compiler") - for x in test_for_compiler.split(): - opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py deleted file mode 100755 index cbd267f..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py +++ /dev/null @@ -1,44 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib.Tools import ccroot -from waflib import Utils -from waflib.Logs import debug -cxx_compiler={'win32':['msvc','g++','clang++'],'cygwin':['g++'],'darwin':['clang++','g++'],'aix':['xlc++','g++','clang++'],'linux':['g++','clang++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'osf1V':['g++'],'gnu':['g++','clang++'],'java':['g++','msvc','clang++','icpc'],'default':['clang++','g++']} -def default_compilers(): - build_platform=Utils.unversioned_sys_platform() - possible_compiler_list=cxx_compiler.get(build_platform,cxx_compiler['default']) - return' '.join(possible_compiler_list) -def configure(conf): - try: - test_for_compiler=conf.options.check_cxx_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_cxx')") - for compiler in re.split('[ ,]+',test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (C++ compiler)'%compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - debug('compiler_cxx: %r',e) - else: - if conf.env.CXX: - conf.end_msg(conf.env.get_flat('CXX')) - conf.env.COMPILER_CXX=compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a C++ compiler!') -def options(opt): - test_for_compiler=default_compilers() - opt.load_special_tools('cxx_*.py') - cxx_compiler_opts=opt.add_option_group('Configuration options') - cxx_compiler_opts.add_option('--check-cxx-compiler',default=None,help='list of C++ compilers to try [%s]'%test_for_compiler,dest="check_cxx_compiler") - for x in test_for_compiler.split(): - opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py deleted file mode 100755 index 2ca7e26..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py +++ /dev/null @@ -1,41 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib import Utils,Logs -d_compiler={'default':['gdc','dmd','ldc2']} -def default_compilers(): - build_platform=Utils.unversioned_sys_platform() - possible_compiler_list=d_compiler.get(build_platform,d_compiler['default']) - return' '.join(possible_compiler_list) -def configure(conf): - try: - test_for_compiler=conf.options.check_d_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_d')") - for compiler in re.split('[ ,]+',test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (D compiler)'%compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - Logs.debug('compiler_d: %r',e) - else: - if conf.env.D: - conf.end_msg(conf.env.get_flat('D')) - conf.env.COMPILER_D=compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a D compiler!') -def options(opt): - test_for_compiler=default_compilers() - d_compiler_opts=opt.add_option_group('Configuration options') - d_compiler_opts.add_option('--check-d-compiler',default=None,help='list of D compilers to try [%s]'%test_for_compiler,dest='check_d_compiler') - for x in test_for_compiler.split(): - opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py deleted file mode 100755 index 8b23a2b..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py +++ /dev/null @@ -1,43 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib import Utils,Logs -from waflib.Tools import fc -fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']} -def default_compilers(): - build_platform=Utils.unversioned_sys_platform() - possible_compiler_list=fc_compiler.get(build_platform,fc_compiler['default']) - return' '.join(possible_compiler_list) -def configure(conf): - try: - test_for_compiler=conf.options.check_fortran_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_fc')") - for compiler in re.split('[ ,]+',test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (Fortran compiler)'%compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - Logs.debug('compiler_fortran: %r',e) - else: - if conf.env.FC: - conf.end_msg(conf.env.get_flat('FC')) - conf.env.COMPILER_FORTRAN=compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a Fortran compiler!') -def options(opt): - test_for_compiler=default_compilers() - opt.load_special_tools('fc_*.py') - fortran_compiler_opts=opt.add_option_group('Configuration options') - fortran_compiler_opts.add_option('--check-fortran-compiler',default=None,help='list of Fortran compiler to try [%s]'%test_for_compiler,dest="check_fortran_compiler") - for x in test_for_compiler.split(): - opt.load('%s'%x) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py deleted file mode 100755 index df73c94..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py +++ /dev/null @@ -1,113 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Utils,Task,Options,Errors -from waflib.TaskGen import before_method,after_method,feature -from waflib.Tools import ccroot -from waflib.Configure import conf -ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES']) -ccroot.lib_patterns['csshlib']=['%s'] -@feature('cs') -@before_method('process_source') -def apply_cs(self): - cs_nodes=[] - no_nodes=[] - for x in self.to_nodes(self.source): - if x.name.endswith('.cs'): - cs_nodes.append(x) - else: - no_nodes.append(x) - self.source=no_nodes - bintype=getattr(self,'bintype',self.gen.endswith('.dll')and'library'or'exe') - self.cs_task=tsk=self.create_task('mcs',cs_nodes,self.path.find_or_declare(self.gen)) - tsk.env.CSTYPE='/target:%s'%bintype - tsk.env.OUT='/out:%s'%tsk.outputs[0].abspath() - self.env.append_value('CSFLAGS','/platform:%s'%getattr(self,'platform','anycpu')) - inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}') - if inst_to: - mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644) - self.install_task=self.add_install_files(install_to=inst_to,install_from=self.cs_task.outputs[:],chmod=mod) -@feature('cs') -@after_method('apply_cs') -def use_cs(self): - names=self.to_list(getattr(self,'use',[])) - get=self.bld.get_tgen_by_name - for x in names: - try: - y=get(x) - except Errors.WafError: - self.env.append_value('CSFLAGS','/reference:%s'%x) - continue - y.post() - tsk=getattr(y,'cs_task',None)or getattr(y,'link_task',None) - if not tsk: - self.bld.fatal('cs task has no link task for use %r'%self) - self.cs_task.dep_nodes.extend(tsk.outputs) - self.cs_task.set_run_after(tsk) - self.env.append_value('CSFLAGS','/reference:%s'%tsk.outputs[0].abspath()) -@feature('cs') -@after_method('apply_cs','use_cs') -def debug_cs(self): - csdebug=getattr(self,'csdebug',self.env.CSDEBUG) - if not csdebug: - return - node=self.cs_task.outputs[0] - if self.env.CS_NAME=='mono': - out=node.parent.find_or_declare(node.name+'.mdb') - else: - out=node.change_ext('.pdb') - self.cs_task.outputs.append(out) - if getattr(self,'install_task',None): - self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out) - if csdebug=='pdbonly': - val=['/debug+','/debug:pdbonly'] - elif csdebug=='full': - val=['/debug+','/debug:full'] - else: - val=['/debug-'] - self.env.append_value('CSFLAGS',val) -@feature('cs') -@after_method('debug_cs') -def doc_cs(self): - csdoc=getattr(self,'csdoc',self.env.CSDOC) - if not csdoc: - return - node=self.cs_task.outputs[0] - out=node.change_ext('.xml') - self.cs_task.outputs.append(out) - if getattr(self,'install_task',None): - self.doc_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=out) - self.env.append_value('CSFLAGS','/doc:%s'%out.abspath()) -class mcs(Task.Task): - color='YELLOW' - run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' - def split_argfile(self,cmd): - inline=[cmd[0]] - infile=[] - for x in cmd[1:]: - if x.lower()=='/noconfig': - inline.append(x) - else: - infile.append(self.quote_flag(x)) - return(inline,infile) -def configure(conf): - csc=getattr(Options.options,'cscbinary',None) - if csc: - conf.env.MCS=csc - conf.find_program(['csc','mcs','gmcs'],var='MCS') - conf.env.ASS_ST='/r:%s' - conf.env.RES_ST='/resource:%s' - conf.env.CS_NAME='csc' - if str(conf.env.MCS).lower().find('mcs')>-1: - conf.env.CS_NAME='mono' -def options(opt): - opt.add_option('--with-csc-binary',type='string',dest='cscbinary') -class fake_csshlib(Task.Task): - color='YELLOW' - inst_to=None - def runnable_status(self): - return Task.SKIP_ME -@conf -def read_csshlib(self,name,paths=[]): - return self(name=name,features='fake_lib',lib_paths=paths,lib_type='csshlib') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py deleted file mode 100755 index e63ad8b..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import TaskGen,Task -from waflib.Tools import c_preproc -from waflib.Tools.ccroot import link_task,stlink_task -@TaskGen.extension('.cpp','.cc','.cxx','.C','.c++') -def cxx_hook(self,node): - return self.create_compiled_task('cxx',node) -if not'.c'in TaskGen.task_gen.mappings: - TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp'] -class cxx(Task.Task): - run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' - vars=['CXXDEPS'] - ext_in=['.h'] - scan=c_preproc.scan -class cxxprogram(link_task): - run_str='${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' - vars=['LINKDEPS'] - ext_out=['.bin'] - inst_to='${BINDIR}' -class cxxshlib(cxxprogram): - inst_to='${LIBDIR}' -class cxxstlib(stlink_task): - pass diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py deleted file mode 100755 index 6d1c3c6..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Utils,Task,Errors -from waflib.TaskGen import taskgen_method,feature,extension -from waflib.Tools import d_scan,d_config -from waflib.Tools.ccroot import link_task,stlink_task -class d(Task.Task): - color='GREEN' - run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}' - scan=d_scan.scan -class d_with_header(d): - run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}' -class d_header(Task.Task): - color='BLUE' - run_str='${D} ${D_HEADER} ${SRC}' -class dprogram(link_task): - run_str='${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}' - inst_to='${BINDIR}' -class dshlib(dprogram): - inst_to='${LIBDIR}' -class dstlib(stlink_task): - pass -@extension('.d','.di','.D') -def d_hook(self,node): - ext=Utils.destos_to_binfmt(self.env.DEST_OS)=='pe'and'obj'or'o' - out='%s.%d.%s'%(node.name,self.idx,ext) - def create_compiled_task(self,name,node): - task=self.create_task(name,node,node.parent.find_or_declare(out)) - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks=[task] - return task - if getattr(self,'generate_headers',None): - tsk=create_compiled_task(self,'d_with_header',node) - tsk.outputs.append(node.change_ext(self.env.DHEADER_ext)) - else: - tsk=create_compiled_task(self,'d',node) - return tsk -@taskgen_method -def generate_header(self,filename): - try: - self.header_lst.append([filename,self.install_path]) - except AttributeError: - self.header_lst=[[filename,self.install_path]] -@feature('d') -def process_header(self): - for i in getattr(self,'header_lst',[]): - node=self.path.find_resource(i[0]) - if not node: - raise Errors.WafError('file %r not found on d obj'%i[0]) - self.create_task('d_header',node,node.change_ext('.di')) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py deleted file mode 100755 index 3b4bdf0..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Utils -from waflib.Configure import conf -@conf -def d_platform_flags(self): - v=self.env - if not v.DEST_OS: - v.DEST_OS=Utils.unversioned_sys_platform() - binfmt=Utils.destos_to_binfmt(self.env.DEST_OS) - if binfmt=='pe': - v.dprogram_PATTERN='%s.exe' - v.dshlib_PATTERN='lib%s.dll' - v.dstlib_PATTERN='lib%s.a' - elif binfmt=='mac-o': - v.dprogram_PATTERN='%s' - v.dshlib_PATTERN='lib%s.dylib' - v.dstlib_PATTERN='lib%s.a' - else: - v.dprogram_PATTERN='%s' - v.dshlib_PATTERN='lib%s.so' - v.dstlib_PATTERN='lib%s.a' -DLIB=''' -version(D_Version2) { - import std.stdio; - int main() { - writefln("phobos2"); - return 0; - } -} else { - version(Tango) { - import tango.stdc.stdio; - int main() { - printf("tango"); - return 0; - } - } else { - import std.stdio; - int main() { - writefln("phobos1"); - return 0; - } - } -} -''' -@conf -def check_dlibrary(self,execute=True): - ret=self.check_cc(features='d dprogram',fragment=DLIB,compile_filename='test.d',execute=execute,define_ret=True) - if execute: - self.env.DLIBRARY=ret.strip() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py deleted file mode 100755 index 6926671..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py +++ /dev/null @@ -1,136 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib import Utils -def filter_comments(filename): - txt=Utils.readf(filename) - i=0 - buf=[] - max=len(txt) - begin=0 - while i-1: - conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead') - conf.load('ar') - conf.load('d') - conf.common_flags_dmd() - conf.d_platform_flags() - if str(conf.env.D).find('ldc')>-1: - conf.common_flags_ldc() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py deleted file mode 100755 index f993e58..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py +++ /dev/null @@ -1,175 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy','uses':'use',} -meths_typos=['__call__','program','shlib','stlib','objects'] -import sys -from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils -from waflib.Tools import ccroot -def check_same_targets(self): - mp=Utils.defaultdict(list) - uids={} - def check_task(tsk): - if not isinstance(tsk,Task.Task): - return - if hasattr(tsk,'no_errcheck_out'): - return - for node in tsk.outputs: - mp[node].append(tsk) - try: - uids[tsk.uid()].append(tsk) - except KeyError: - uids[tsk.uid()]=[tsk] - for g in self.groups: - for tg in g: - try: - for tsk in tg.tasks: - check_task(tsk) - except AttributeError: - check_task(tg) - dupe=False - for(k,v)in mp.items(): - if len(v)>1: - dupe=True - msg='* Node %r is created more than once%s. The task generators are:'%(k,Logs.verbose==1 and" (full message on 'waf -v -v')"or"") - Logs.error(msg) - for x in v: - if Logs.verbose>1: - Logs.error(' %d. %r',1+v.index(x),x.generator) - else: - Logs.error(' %d. %r in %r',1+v.index(x),x.generator.name,getattr(x.generator,'path',None)) - Logs.error('If you think that this is an error, set no_errcheck_out on the task instance') - if not dupe: - for(k,v)in uids.items(): - if len(v)>1: - Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid') - tg_details=tsk.generator.name - if Logs.verbose>2: - tg_details=tsk.generator - for tsk in v: - Logs.error(' - object %r (%r) defined in %r',tsk.__class__.__name__,tsk,tg_details) -def check_invalid_constraints(self): - feat=set() - for x in list(TaskGen.feats.values()): - feat.union(set(x)) - for(x,y)in TaskGen.task_gen.prec.items(): - feat.add(x) - feat.union(set(y)) - ext=set() - for x in TaskGen.task_gen.mappings.values(): - ext.add(x.__name__) - invalid=ext&feat - if invalid: - Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method',list(invalid)) - for cls in list(Task.classes.values()): - if sys.hexversion>0x3000000 and issubclass(cls,Task.Task)and isinstance(cls.hcode,str): - raise Errors.WafError('Class %r has hcode value %r of type , expecting (use Utils.h_cmd() ?)'%(cls,cls.hcode)) - for x in('before','after'): - for y in Utils.to_list(getattr(cls,x,[])): - if not Task.classes.get(y): - Logs.error('Erroneous order constraint %r=%r on task class %r',x,y,cls.__name__) - if getattr(cls,'rule',None): - Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")',cls.__name__) -def replace(m): - oldcall=getattr(Build.BuildContext,m) - def call(self,*k,**kw): - ret=oldcall(self,*k,**kw) - for x in typos: - if x in kw: - if x=='iscopy'and'subst'in getattr(self,'features',''): - continue - Logs.error('Fix the typo %r -> %r on %r',x,typos[x],ret) - return ret - setattr(Build.BuildContext,m,call) -def enhance_lib(): - for m in meths_typos: - replace(m) - def ant_glob(self,*k,**kw): - if k: - lst=Utils.to_list(k[0]) - for pat in lst: - sp=pat.split('/') - if'..'in sp: - Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'",k[0]) - if'.'in sp: - Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'",k[0]) - return self.old_ant_glob(*k,**kw) - Node.Node.old_ant_glob=Node.Node.ant_glob - Node.Node.ant_glob=ant_glob - def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True,quiet=False): - if remove: - try: - if self.is_child_of(self.ctx.bldnode)and not quiet: - quiet=True - Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False',self) - except AttributeError: - pass - return self.old_ant_iter(accept,maxdepth,pats,dir,src,remove,quiet) - Node.Node.old_ant_iter=Node.Node.ant_iter - Node.Node.ant_iter=ant_iter - old=Task.is_before - def is_before(t1,t2): - ret=old(t1,t2) - if ret and old(t2,t1): - Logs.error('Contradictory order constraints in classes %r %r',t1,t2) - return ret - Task.is_before=is_before - def check_err_features(self): - lst=self.to_list(self.features) - if'shlib'in lst: - Logs.error('feature shlib -> cshlib, dshlib or cxxshlib') - for x in('c','cxx','d','fc'): - if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]: - Logs.error('%r features is probably missing %r',self,x) - TaskGen.feature('*')(check_err_features) - def check_err_order(self): - if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features): - for x in('before','after','ext_in','ext_out'): - if hasattr(self,x): - Logs.warn('Erroneous order constraint %r on non-rule based task generator %r',x,self) - else: - for x in('before','after'): - for y in self.to_list(getattr(self,x,[])): - if not Task.classes.get(y): - Logs.error('Erroneous order constraint %s=%r on %r (no such class)',x,y,self) - TaskGen.feature('*')(check_err_order) - def check_compile(self): - check_invalid_constraints(self) - try: - ret=self.orig_compile() - finally: - check_same_targets(self) - return ret - Build.BuildContext.orig_compile=Build.BuildContext.compile - Build.BuildContext.compile=check_compile - def use_rec(self,name,**kw): - try: - y=self.bld.get_tgen_by_name(name) - except Errors.WafError: - pass - else: - idx=self.bld.get_group_idx(self) - odx=self.bld.get_group_idx(y) - if odx>idx: - msg="Invalid 'use' across build groups:" - if Logs.verbose>1: - msg+='\n target %r\n uses:\n %r'%(self,y) - else: - msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name) - raise Errors.WafError(msg) - self.orig_use_rec(name,**kw) - TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec - TaskGen.task_gen.use_rec=use_rec - def _getattr(self,name,default=None): - if name=='append'or name=='add': - raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique') - elif name=='prepend': - raise Errors.WafError('env.prepend does not exist: use env.prepend_value') - if name in self.__slots__: - return super(ConfigSet.ConfigSet,self).__getattr__(name,default) - else: - return self[name] - ConfigSet.ConfigSet.__getattr__=_getattr -def options(opt): - enhance_lib() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py deleted file mode 100755 index 64c479d..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py +++ /dev/null @@ -1,118 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Utils,Task,Errors -from waflib.Tools import ccroot,fc_config,fc_scan -from waflib.TaskGen import extension -from waflib.Configure import conf -ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES','FCPPFLAGS']) -ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) -ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS']) -ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS']) -@extension('.f','.F','.f90','.F90','.for','.FOR','.f95','.F95','.f03','.F03','.f08','.F08') -def fc_hook(self,node): - return self.create_compiled_task('fc',node) -@conf -def modfile(conf,name): - if name.find(':')>=0: - separator=conf.env.FC_SUBMOD_SEPARATOR or'@' - modpath=name.split(':') - modname=modpath[0]+separator+modpath[-1] - suffix=conf.env.FC_SUBMOD_SUFFIX or'.smod' - else: - modname=name - suffix='.mod' - return{'lower':modname.lower()+suffix.lower(),'lower.MOD':modname.lower()+suffix.upper(),'UPPER.mod':modname.upper()+suffix.lower(),'UPPER':modname.upper()+suffix.upper()}[conf.env.FC_MOD_CAPITALIZATION or'lower'] -def get_fortran_tasks(tsk): - bld=tsk.generator.bld - tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator)) - return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)] -class fc(Task.Task): - color='GREEN' - run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()} ${FCPPFLAGS}' - vars=["FORTRANMODPATHFLAG"] - def scan(self): - tmp=fc_scan.fortran_parser(self.generator.includes_nodes) - tmp.task=self - tmp.start(self.inputs[0]) - return(tmp.nodes,tmp.names) - def runnable_status(self): - if getattr(self,'mod_fortran_done',None): - return super(fc,self).runnable_status() - bld=self.generator.bld - lst=get_fortran_tasks(self) - for tsk in lst: - tsk.mod_fortran_done=True - for tsk in lst: - ret=tsk.runnable_status() - if ret==Task.ASK_LATER: - for x in lst: - x.mod_fortran_done=None - return Task.ASK_LATER - ins=Utils.defaultdict(set) - outs=Utils.defaultdict(set) - for tsk in lst: - key=tsk.uid() - for x in bld.raw_deps[key]: - if x.startswith('MOD@'): - name=bld.modfile(x.replace('MOD@','')) - node=bld.srcnode.find_or_declare(name) - tsk.set_outputs(node) - outs[node].add(tsk) - for tsk in lst: - key=tsk.uid() - for x in bld.raw_deps[key]: - if x.startswith('USE@'): - name=bld.modfile(x.replace('USE@','')) - node=bld.srcnode.find_resource(name) - if node and node not in tsk.outputs: - if not node in bld.node_deps[key]: - bld.node_deps[key].append(node) - ins[node].add(tsk) - for k in ins.keys(): - for a in ins[k]: - a.run_after.update(outs[k]) - for x in outs[k]: - self.generator.bld.producer.revdeps[x].add(a) - tmp=[] - for t in outs[k]: - tmp.extend(t.outputs) - a.dep_nodes.extend(tmp) - a.dep_nodes.sort(key=lambda x:x.abspath()) - for tsk in lst: - try: - delattr(tsk,'cache_sig') - except AttributeError: - pass - return super(fc,self).runnable_status() -class fcprogram(ccroot.link_task): - color='YELLOW' - run_str='${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB} ${LDFLAGS}' - inst_to='${BINDIR}' -class fcshlib(fcprogram): - inst_to='${LIBDIR}' -class fcstlib(ccroot.stlink_task): - pass -class fcprogram_test(fcprogram): - def runnable_status(self): - ret=super(fcprogram_test,self).runnable_status() - if ret==Task.SKIP_ME: - ret=Task.RUN_ME - return ret - def exec_command(self,cmd,**kw): - bld=self.generator.bld - kw['shell']=isinstance(cmd,str) - kw['stdout']=kw['stderr']=Utils.subprocess.PIPE - kw['cwd']=self.get_cwd() - bld.out=bld.err='' - bld.to_log('command: %s\n'%cmd) - kw['output']=0 - try: - (bld.out,bld.err)=bld.cmd_and_log(cmd,**kw) - except Errors.WafError: - return-1 - if bld.out: - bld.to_log('out: %s\n'%bld.out) - if bld.err: - bld.to_log('err: %s\n'%bld.err) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py deleted file mode 100755 index 8714276..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py +++ /dev/null @@ -1,299 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re,os,sys,shlex -from waflib.Configure import conf -from waflib.TaskGen import feature,before_method -FC_FRAGMENT=' program main\n end program main\n' -FC_FRAGMENT2=' PROGRAM MAIN\n END\n' -@conf -def fc_flags(conf): - v=conf.env - v.FC_SRC_F=[] - v.FC_TGT_F=['-c','-o'] - v.FCINCPATH_ST='-I%s' - v.FCDEFINES_ST='-D%s' - if not v.LINK_FC: - v.LINK_FC=v.FC - v.FCLNK_SRC_F=[] - v.FCLNK_TGT_F=['-o'] - v.FCFLAGS_fcshlib=['-fpic'] - v.LINKFLAGS_fcshlib=['-shared'] - v.fcshlib_PATTERN='lib%s.so' - v.fcstlib_PATTERN='lib%s.a' - v.FCLIB_ST='-l%s' - v.FCLIBPATH_ST='-L%s' - v.FCSTLIB_ST='-l%s' - v.FCSTLIBPATH_ST='-L%s' - v.FCSTLIB_MARKER='-Wl,-Bstatic' - v.FCSHLIB_MARKER='-Wl,-Bdynamic' - v.SONAME_ST='-Wl,-h,%s' -@conf -def fc_add_flags(conf): - conf.add_os_flags('FCPPFLAGS',dup=False) - conf.add_os_flags('FCFLAGS',dup=False) - conf.add_os_flags('LINKFLAGS',dup=False) - conf.add_os_flags('LDFLAGS',dup=False) -@conf -def check_fortran(self,*k,**kw): - self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app') -@conf -def check_fc(self,*k,**kw): - kw['compiler']='fc' - if not'compile_mode'in kw: - kw['compile_mode']='fc' - if not'type'in kw: - kw['type']='fcprogram' - if not'compile_filename'in kw: - kw['compile_filename']='test.f90' - if not'code'in kw: - kw['code']=FC_FRAGMENT - return self.check(*k,**kw) -@conf -def fortran_modifier_darwin(conf): - v=conf.env - v.FCFLAGS_fcshlib=['-fPIC'] - v.LINKFLAGS_fcshlib=['-dynamiclib'] - v.fcshlib_PATTERN='lib%s.dylib' - v.FRAMEWORKPATH_ST='-F%s' - v.FRAMEWORK_ST=['-framework'] - v.LINKFLAGS_fcstlib=[] - v.FCSHLIB_MARKER='' - v.FCSTLIB_MARKER='' - v.SONAME_ST='' -@conf -def fortran_modifier_win32(conf): - v=conf.env - v.fcprogram_PATTERN=v.fcprogram_test_PATTERN='%s.exe' - v.fcshlib_PATTERN='%s.dll' - v.implib_PATTERN='%s.dll.a' - v.IMPLIB_ST='-Wl,--out-implib,%s' - v.FCFLAGS_fcshlib=[] - v.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) -@conf -def fortran_modifier_cygwin(conf): - fortran_modifier_win32(conf) - v=conf.env - v.fcshlib_PATTERN='cyg%s.dll' - v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base']) - v.FCFLAGS_fcshlib=[] -@conf -def check_fortran_dummy_main(self,*k,**kw): - if not self.env.CC: - self.fatal('A c compiler is required for check_fortran_dummy_main') - lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN'] - lst.extend([m.lower()for m in lst]) - lst.append('') - self.start_msg('Detecting whether we need a dummy main') - for main in lst: - kw['fortran_main']=main - try: - self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True) - if not main: - self.env.FC_MAIN=-1 - self.end_msg('no') - else: - self.env.FC_MAIN=main - self.end_msg('yes %s'%main) - break - except self.errors.ConfigurationError: - pass - else: - self.end_msg('not found') - self.fatal('could not detect whether fortran requires a dummy main, see the config.log') -GCC_DRIVER_LINE=re.compile('^Driving:') -POSIX_STATIC_EXT=re.compile(r'\S+\.a') -POSIX_LIB_FLAGS=re.compile(r'-l\S+') -@conf -def is_link_verbose(self,txt): - assert isinstance(txt,str) - for line in txt.splitlines(): - if not GCC_DRIVER_LINE.search(line): - if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line): - return True - return False -@conf -def check_fortran_verbose_flag(self,*k,**kw): - self.start_msg('fortran link verbose flag') - for x in('-v','--verbose','-verbose','-V'): - try: - self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True) - except self.errors.ConfigurationError: - pass - else: - if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out): - self.end_msg(x) - break - else: - self.end_msg('failure') - self.fatal('Could not obtain the fortran link verbose flag (see config.log)') - self.env.FC_VERBOSE_FLAG=x - return x -LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*'] -if os.name=='nt': - LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname']) -else: - LINKFLAGS_IGNORED.append(r'-lgcc*') -RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED] -def _match_ignore(line): - for i in RLINKFLAGS_IGNORED: - if i.match(line): - return True - return False -def parse_fortran_link(lines): - final_flags=[] - for line in lines: - if not GCC_DRIVER_LINE.match(line): - _parse_flink_line(line,final_flags) - return final_flags -SPACE_OPTS=re.compile('^-[LRuYz]$') -NOSPACE_OPTS=re.compile('^-[RL]') -def _parse_flink_token(lexer,token,tmp_flags): - if _match_ignore(token): - pass - elif token.startswith('-lkernel32')and sys.platform=='cygwin': - tmp_flags.append(token) - elif SPACE_OPTS.match(token): - t=lexer.get_token() - if t.startswith('P,'): - t=t[2:] - for opt in t.split(os.pathsep): - tmp_flags.append('-L%s'%opt) - elif NOSPACE_OPTS.match(token): - tmp_flags.append(token) - elif POSIX_LIB_FLAGS.match(token): - tmp_flags.append(token) - else: - pass - t=lexer.get_token() - return t -def _parse_flink_line(line,final_flags): - lexer=shlex.shlex(line,posix=True) - lexer.whitespace_split=True - t=lexer.get_token() - tmp_flags=[] - while t: - t=_parse_flink_token(lexer,t,tmp_flags) - final_flags.extend(tmp_flags) - return final_flags -@conf -def check_fortran_clib(self,autoadd=True,*k,**kw): - if not self.env.FC_VERBOSE_FLAG: - self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?') - self.start_msg('Getting fortran runtime link flags') - try: - self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG]) - except Exception: - self.end_msg(False) - if kw.get('mandatory',True): - conf.fatal('Could not find the c library flags') - else: - out=self.test_bld.err - flags=parse_fortran_link(out.splitlines()) - self.end_msg('ok (%s)'%' '.join(flags)) - self.env.LINKFLAGS_CLIB=flags - return flags - return[] -def getoutput(conf,cmd,stdin=False): - from waflib import Errors - if conf.env.env: - env=conf.env.env - else: - env=dict(os.environ) - env['LANG']='C' - input=stdin and'\n'.encode()or None - try: - out,err=conf.cmd_and_log(cmd,env=env,output=0,input=input) - except Errors.WafError as e: - if not(hasattr(e,'stderr')and hasattr(e,'stdout')): - raise e - else: - out=e.stdout - err=e.stderr - except Exception: - conf.fatal('could not determine the compiler version %r'%cmd) - return(out,err) -ROUTINES_CODE="""\ - subroutine foobar() - return - end - subroutine foo_bar() - return - end -""" -MAIN_CODE=""" -void %(dummy_func_nounder)s(void); -void %(dummy_func_under)s(void); -int %(main_func_name)s() { - %(dummy_func_nounder)s(); - %(dummy_func_under)s(); - return 0; -} -""" -@feature('link_main_routines_func') -@before_method('process_source') -def link_main_routines_tg_method(self): - def write_test_file(task): - task.outputs[0].write(task.generator.code) - bld=self.bld - bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__) - bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE) - bld(features='fc fcstlib',source='test.f',target='test') - bld(features='c fcprogram',source='main.c',target='app',use='test') -def mangling_schemes(): - for u in('_',''): - for du in('','_'): - for c in("lower","upper"): - yield(u,du,c) -def mangle_name(u,du,c,name): - return getattr(name,c)()+u+(name.find('_')!=-1 and du or'') -@conf -def check_fortran_mangling(self,*k,**kw): - if not self.env.CC: - self.fatal('A c compiler is required for link_main_routines') - if not self.env.FC: - self.fatal('A fortran compiler is required for link_main_routines') - if not self.env.FC_MAIN: - self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)') - self.start_msg('Getting fortran mangling scheme') - for(u,du,c)in mangling_schemes(): - try: - self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',dummy_func_nounder=mangle_name(u,du,c,'foobar'),dummy_func_under=mangle_name(u,du,c,'foo_bar'),main_func_name=self.env.FC_MAIN) - except self.errors.ConfigurationError: - pass - else: - self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c)) - self.env.FORTRAN_MANGLING=(u,du,c) - break - else: - self.end_msg(False) - self.fatal('mangler not found') - return(u,du,c) -@feature('pyext') -@before_method('propagate_uselib_vars','apply_link') -def set_lib_pat(self): - self.env.fcshlib_PATTERN=self.env.pyext_PATTERN -@conf -def detect_openmp(self): - for x in('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'): - try: - self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP') - except self.errors.ConfigurationError: - pass - else: - break - else: - self.fatal('Could not find OpenMP') -@conf -def check_gfortran_o_space(self): - if self.env.FC_NAME!='GFORTRAN'or int(self.env.FC_VERSION[0])>4: - return - self.env.stash() - self.env.FCLNK_TGT_F=['-o',''] - try: - self.check_fc(msg='Checking if the -o link must be split from arguments',fragment=FC_FRAGMENT,features='fc fcshlib') - except self.errors.ConfigurationError: - self.env.revert() - else: - self.env.commit() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py deleted file mode 100755 index 76921fc..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py +++ /dev/null @@ -1,70 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -INC_REGEX=r"""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])""" -USE_REGEX=r"""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)""" -MOD_REGEX=r"""(?:^|;)\s*MODULE(?!\s+(?:PROCEDURE|SUBROUTINE|FUNCTION))\s+(\w+)""" -SMD_REGEX=r"""(?:^|;)\s*SUBMODULE\s*\(([\w:]+)\)\s*(\w+)""" -re_inc=re.compile(INC_REGEX,re.I) -re_use=re.compile(USE_REGEX,re.I) -re_mod=re.compile(MOD_REGEX,re.I) -re_smd=re.compile(SMD_REGEX,re.I) -class fortran_parser(object): - def __init__(self,incpaths): - self.seen=[] - self.nodes=[] - self.names=[] - self.incpaths=incpaths - def find_deps(self,node): - txt=node.read() - incs=[] - uses=[] - mods=[] - for line in txt.splitlines(): - m=re_inc.search(line) - if m: - incs.append(m.group(1)) - m=re_use.search(line) - if m: - uses.append(m.group(1)) - m=re_mod.search(line) - if m: - mods.append(m.group(1)) - m=re_smd.search(line) - if m: - uses.append(m.group(1)) - mods.append('{0}:{1}'.format(m.group(1),m.group(2))) - return(incs,uses,mods) - def start(self,node): - self.waiting=[node] - while self.waiting: - nd=self.waiting.pop(0) - self.iter(nd) - def iter(self,node): - incs,uses,mods=self.find_deps(node) - for x in incs: - if x in self.seen: - continue - self.seen.append(x) - self.tryfind_header(x) - for x in uses: - name="USE@%s"%x - if not name in self.names: - self.names.append(name) - for x in mods: - name="MOD@%s"%x - if not name in self.names: - self.names.append(name) - def tryfind_header(self,filename): - found=None - for n in self.incpaths: - found=n.find_resource(filename) - if found: - self.nodes.append(found) - self.waiting.append(found) - break - if not found: - if not filename in self.names: - self.names.append(filename) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py deleted file mode 100755 index 1f1620e..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py +++ /dev/null @@ -1,38 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re -from waflib import Task,TaskGen -from waflib.Tools import ccroot -def decide_ext(self,node): - if'cxx'in self.features: - return['.lex.cc'] - return['.lex.c'] -def flexfun(tsk): - env=tsk.env - bld=tsk.generator.bld - wd=bld.variant_dir - def to_list(xx): - if isinstance(xx,str): - return[xx] - return xx - tsk.last_cmd=lst=[] - lst.extend(to_list(env.FLEX)) - lst.extend(to_list(env.FLEXFLAGS)) - inputs=[a.path_from(tsk.get_cwd())for a in tsk.inputs] - if env.FLEX_MSYS: - inputs=[x.replace(os.sep,'/')for x in inputs] - lst.extend(inputs) - lst=[x for x in lst if x] - txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0) - tsk.outputs[0].write(txt.replace('\r\n','\n').replace('\r','\n')) -TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,) -Task.classes['flex'].vars=['FLEXFLAGS','FLEX'] -ccroot.USELIB_VARS['c'].add('FLEXFLAGS') -ccroot.USELIB_VARS['cxx'].add('FLEXFLAGS') -def configure(conf): - conf.find_program('flex',var='FLEX') - conf.env.FLEXFLAGS=['-t'] - if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX[0]): - conf.env.FLEX_MSYS=True diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py deleted file mode 100755 index b62adcd..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib import Utils -from waflib.Tools import fc,fc_config,fc_scan,ar -from waflib.Configure import conf -@conf -def find_g95(conf): - fc=conf.find_program('g95',var='FC') - conf.get_g95_version(fc) - conf.env.FC_NAME='G95' -@conf -def g95_flags(conf): - v=conf.env - v.FCFLAGS_fcshlib=['-fPIC'] - v.FORTRANMODFLAG=['-fmod=',''] - v.FCFLAGS_DEBUG=['-Werror'] -@conf -def g95_modifier_win32(conf): - fc_config.fortran_modifier_win32(conf) -@conf -def g95_modifier_cygwin(conf): - fc_config.fortran_modifier_cygwin(conf) -@conf -def g95_modifier_darwin(conf): - fc_config.fortran_modifier_darwin(conf) -@conf -def g95_modifier_platform(conf): - dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform() - g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None) - if g95_modifier_func: - g95_modifier_func() -@conf -def get_g95_version(conf,fc): - version_re=re.compile(r"g95\s*(?P\d*)\.(?P\d*)").search - cmd=fc+['--version'] - out,err=fc_config.getoutput(conf,cmd,stdin=False) - if out: - match=version_re(out) - else: - match=version_re(err) - if not match: - conf.fatal('cannot determine g95 version') - k=match.groupdict() - conf.env.FC_VERSION=(k['major'],k['minor']) -def configure(conf): - conf.find_g95() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.g95_flags() - conf.g95_modifier_platform() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py deleted file mode 100755 index 654d37f..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py +++ /dev/null @@ -1,13 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import waflib.Tools.asm -from waflib.Tools import ar -def configure(conf): - conf.find_program(['gas','gcc'],var='AS') - conf.env.AS_TGT_F=['-c','-o'] - conf.env.ASLNK_TGT_F=['-o'] - conf.find_ar() - conf.load('asm') - conf.env.ASM_NAME='gas' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py deleted file mode 100755 index 12afcc6..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py +++ /dev/null @@ -1,104 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.Tools import ccroot,ar -from waflib.Configure import conf -@conf -def find_gcc(conf): - cc=conf.find_program(['gcc','cc'],var='CC') - conf.get_cc_version(cc,gcc=True) - conf.env.CC_NAME='gcc' -@conf -def gcc_common_flags(conf): - v=conf.env - v.CC_SRC_F=[] - v.CC_TGT_F=['-c','-o'] - if not v.LINK_CC: - v.LINK_CC=v.CC - v.CCLNK_SRC_F=[] - v.CCLNK_TGT_F=['-o'] - v.CPPPATH_ST='-I%s' - v.DEFINES_ST='-D%s' - v.LIB_ST='-l%s' - v.LIBPATH_ST='-L%s' - v.STLIB_ST='-l%s' - v.STLIBPATH_ST='-L%s' - v.RPATH_ST='-Wl,-rpath,%s' - v.SONAME_ST='-Wl,-h,%s' - v.SHLIB_MARKER='-Wl,-Bdynamic' - v.STLIB_MARKER='-Wl,-Bstatic' - v.cprogram_PATTERN='%s' - v.CFLAGS_cshlib=['-fPIC'] - v.LINKFLAGS_cshlib=['-shared'] - v.cshlib_PATTERN='lib%s.so' - v.LINKFLAGS_cstlib=['-Wl,-Bstatic'] - v.cstlib_PATTERN='lib%s.a' - v.LINKFLAGS_MACBUNDLE=['-bundle','-undefined','dynamic_lookup'] - v.CFLAGS_MACBUNDLE=['-fPIC'] - v.macbundle_PATTERN='%s.bundle' -@conf -def gcc_modifier_win32(conf): - v=conf.env - v.cprogram_PATTERN='%s.exe' - v.cshlib_PATTERN='%s.dll' - v.implib_PATTERN='%s.dll.a' - v.IMPLIB_ST='-Wl,--out-implib,%s' - v.CFLAGS_cshlib=[] - v.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) -@conf -def gcc_modifier_cygwin(conf): - gcc_modifier_win32(conf) - v=conf.env - v.cshlib_PATTERN='cyg%s.dll' - v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base']) - v.CFLAGS_cshlib=[] -@conf -def gcc_modifier_darwin(conf): - v=conf.env - v.CFLAGS_cshlib=['-fPIC'] - v.LINKFLAGS_cshlib=['-dynamiclib'] - v.cshlib_PATTERN='lib%s.dylib' - v.FRAMEWORKPATH_ST='-F%s' - v.FRAMEWORK_ST=['-framework'] - v.ARCH_ST=['-arch'] - v.LINKFLAGS_cstlib=[] - v.SHLIB_MARKER=[] - v.STLIB_MARKER=[] - v.SONAME_ST=[] -@conf -def gcc_modifier_aix(conf): - v=conf.env - v.LINKFLAGS_cprogram=['-Wl,-brtl'] - v.LINKFLAGS_cshlib=['-shared','-Wl,-brtl,-bexpfull'] - v.SHLIB_MARKER=[] -@conf -def gcc_modifier_hpux(conf): - v=conf.env - v.SHLIB_MARKER=[] - v.STLIB_MARKER=[] - v.CFLAGS_cshlib=['-fPIC','-DPIC'] - v.cshlib_PATTERN='lib%s.sl' -@conf -def gcc_modifier_openbsd(conf): - conf.env.SONAME_ST=[] -@conf -def gcc_modifier_osf1V(conf): - v=conf.env - v.SHLIB_MARKER=[] - v.STLIB_MARKER=[] - v.SONAME_ST=[] -@conf -def gcc_modifier_platform(conf): - gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None) - if gcc_modifier_func: - gcc_modifier_func() -def configure(conf): - conf.find_gcc() - conf.find_ar() - conf.gcc_common_flags() - conf.gcc_modifier_platform() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - conf.check_gcc_o_space() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py deleted file mode 100755 index c809930..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.Tools import ar,d -from waflib.Configure import conf -@conf -def find_gdc(conf): - conf.find_program('gdc',var='D') - out=conf.cmd_and_log(conf.env.D+['--version']) - if out.find("gdc")==-1: - conf.fatal("detected compiler is not gdc") -@conf -def common_flags_gdc(conf): - v=conf.env - v.DFLAGS=[] - v.D_SRC_F=['-c'] - v.D_TGT_F='-o%s' - v.D_LINKER=v.D - v.DLNK_SRC_F='' - v.DLNK_TGT_F='-o%s' - v.DINC_ST='-I%s' - v.DSHLIB_MARKER=v.DSTLIB_MARKER='' - v.DSTLIB_ST=v.DSHLIB_ST='-l%s' - v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L%s' - v.LINKFLAGS_dshlib=['-shared'] - v.DHEADER_ext='.di' - v.DFLAGS_d_with_header='-fintfc' - v.D_HDR_F='-fintfc-file=%s' -def configure(conf): - conf.find_gdc() - conf.load('ar') - conf.load('d') - conf.common_flags_gdc() - conf.d_platform_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py deleted file mode 100755 index 47d005a..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py +++ /dev/null @@ -1,71 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib import Utils -from waflib.Tools import fc,fc_config,fc_scan,ar -from waflib.Configure import conf -@conf -def find_gfortran(conf): - fc=conf.find_program(['gfortran','g77'],var='FC') - conf.get_gfortran_version(fc) - conf.env.FC_NAME='GFORTRAN' -@conf -def gfortran_flags(conf): - v=conf.env - v.FCFLAGS_fcshlib=['-fPIC'] - v.FORTRANMODFLAG=['-J',''] - v.FCFLAGS_DEBUG=['-Werror'] -@conf -def gfortran_modifier_win32(conf): - fc_config.fortran_modifier_win32(conf) -@conf -def gfortran_modifier_cygwin(conf): - fc_config.fortran_modifier_cygwin(conf) -@conf -def gfortran_modifier_darwin(conf): - fc_config.fortran_modifier_darwin(conf) -@conf -def gfortran_modifier_platform(conf): - dest_os=conf.env.DEST_OS or Utils.unversioned_sys_platform() - gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None) - if gfortran_modifier_func: - gfortran_modifier_func() -@conf -def get_gfortran_version(conf,fc): - version_re=re.compile(r"GNU\s*Fortran",re.I).search - cmd=fc+['--version'] - out,err=fc_config.getoutput(conf,cmd,stdin=False) - if out: - match=version_re(out) - else: - match=version_re(err) - if not match: - conf.fatal('Could not determine the compiler type') - cmd=fc+['-dM','-E','-'] - out,err=fc_config.getoutput(conf,cmd,stdin=True) - if out.find('__GNUC__')<0: - conf.fatal('Could not determine the compiler type') - k={} - out=out.splitlines() - import shlex - for line in out: - lst=shlex.split(line) - if len(lst)>2: - key=lst[1] - val=lst[2] - k[key]=val - def isD(var): - return var in k - def isT(var): - return var in k and k[var]!='0' - conf.env.FC_VERSION=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__']) -def configure(conf): - conf.find_gfortran() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.gfortran_flags() - conf.gfortran_modifier_platform() - conf.check_gfortran_o_space() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py deleted file mode 100755 index ba5a71e..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py +++ /dev/null @@ -1,242 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os -import functools -from waflib import Context,Task,Utils,Options,Errors,Logs -from waflib.TaskGen import taskgen_method,before_method,feature,extension -from waflib.Configure import conf -@taskgen_method -def add_marshal_file(self,filename,prefix): - if not hasattr(self,'marshal_list'): - self.marshal_list=[] - self.meths.append('process_marshal') - self.marshal_list.append((filename,prefix)) -@before_method('process_source') -def process_marshal(self): - for f,prefix in getattr(self,'marshal_list',[]): - node=self.path.find_resource(f) - if not node: - raise Errors.WafError('file not found %r'%f) - h_node=node.change_ext('.h') - c_node=node.change_ext('.c') - task=self.create_task('glib_genmarshal',node,[h_node,c_node]) - task.env.GLIB_GENMARSHAL_PREFIX=prefix - self.source=self.to_nodes(getattr(self,'source',[])) - self.source.append(c_node) -class glib_genmarshal(Task.Task): - vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL'] - color='BLUE' - ext_out=['.h'] - def run(self): - bld=self.generator.bld - get=self.env.get_flat - cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath()) - ret=bld.exec_command(cmd1) - if ret: - return ret - c='''#include "%s"\n'''%self.outputs[0].name - self.outputs[1].write(c) - cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath()) - return bld.exec_command(cmd2) -@taskgen_method -def add_enums_from_template(self,source='',target='',template='',comments=''): - if not hasattr(self,'enums_list'): - self.enums_list=[] - self.meths.append('process_enums') - self.enums_list.append({'source':source,'target':target,'template':template,'file-head':'','file-prod':'','file-tail':'','enum-prod':'','value-head':'','value-prod':'','value-tail':'','comments':comments}) -@taskgen_method -def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''): - if not hasattr(self,'enums_list'): - self.enums_list=[] - self.meths.append('process_enums') - self.enums_list.append({'source':source,'template':'','target':target,'file-head':file_head,'file-prod':file_prod,'file-tail':file_tail,'enum-prod':enum_prod,'value-head':value_head,'value-prod':value_prod,'value-tail':value_tail,'comments':comments}) -@before_method('process_source') -def process_enums(self): - for enum in getattr(self,'enums_list',[]): - task=self.create_task('glib_mkenums') - env=task.env - inputs=[] - source_list=self.to_list(enum['source']) - if not source_list: - raise Errors.WafError('missing source '+str(enum)) - source_list=[self.path.find_resource(k)for k in source_list] - inputs+=source_list - env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list] - if not enum['target']: - raise Errors.WafError('missing target '+str(enum)) - tgt_node=self.path.find_or_declare(enum['target']) - if tgt_node.name.endswith('.c'): - self.source.append(tgt_node) - env.GLIB_MKENUMS_TARGET=tgt_node.abspath() - options=[] - if enum['template']: - template_node=self.path.find_resource(enum['template']) - options.append('--template %s'%(template_node.abspath())) - inputs.append(template_node) - params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'} - for param,option in params.items(): - if enum[param]: - options.append('%s %r'%(option,enum[param])) - env.GLIB_MKENUMS_OPTIONS=' '.join(options) - task.set_inputs(inputs) - task.set_outputs(tgt_node) -class glib_mkenums(Task.Task): - run_str='${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}' - color='PINK' - ext_out=['.h'] -@taskgen_method -def add_settings_schemas(self,filename_list): - if not hasattr(self,'settings_schema_files'): - self.settings_schema_files=[] - if not isinstance(filename_list,list): - filename_list=[filename_list] - self.settings_schema_files.extend(filename_list) -@taskgen_method -def add_settings_enums(self,namespace,filename_list): - if hasattr(self,'settings_enum_namespace'): - raise Errors.WafError("Tried to add gsettings enums to %r more than once"%self.name) - self.settings_enum_namespace=namespace - if not isinstance(filename_list,list): - filename_list=[filename_list] - self.settings_enum_files=filename_list -@feature('glib2') -def process_settings(self): - enums_tgt_node=[] - install_files=[] - settings_schema_files=getattr(self,'settings_schema_files',[]) - if settings_schema_files and not self.env.GLIB_COMPILE_SCHEMAS: - raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure") - if hasattr(self,'settings_enum_files'): - enums_task=self.create_task('glib_mkenums') - source_list=self.settings_enum_files - source_list=[self.path.find_resource(k)for k in source_list] - enums_task.set_inputs(source_list) - enums_task.env.GLIB_MKENUMS_SOURCE=[k.abspath()for k in source_list] - target=self.settings_enum_namespace+'.enums.xml' - tgt_node=self.path.find_or_declare(target) - enums_task.set_outputs(tgt_node) - enums_task.env.GLIB_MKENUMS_TARGET=tgt_node.abspath() - enums_tgt_node=[tgt_node] - install_files.append(tgt_node) - options='--comments "" --fhead "" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " " --vtail " " --ftail "" '%(self.settings_enum_namespace) - enums_task.env.GLIB_MKENUMS_OPTIONS=options - for schema in settings_schema_files: - schema_task=self.create_task('glib_validate_schema') - schema_node=self.path.find_resource(schema) - if not schema_node: - raise Errors.WafError("Cannot find the schema file %r"%schema) - install_files.append(schema_node) - source_list=enums_tgt_node+[schema_node] - schema_task.set_inputs(source_list) - schema_task.env.GLIB_COMPILE_SCHEMAS_OPTIONS=[("--schema-file="+k.abspath())for k in source_list] - target_node=schema_node.change_ext('.xml.valid') - schema_task.set_outputs(target_node) - schema_task.env.GLIB_VALIDATE_SCHEMA_OUTPUT=target_node.abspath() - def compile_schemas_callback(bld): - if not bld.is_install: - return - compile_schemas=Utils.to_list(bld.env.GLIB_COMPILE_SCHEMAS) - destdir=Options.options.destdir - paths=bld._compile_schemas_registered - if destdir: - paths=(os.path.join(destdir,path.lstrip(os.sep))for path in paths) - for path in paths: - Logs.pprint('YELLOW','Updating GSettings schema cache %r'%path) - if self.bld.exec_command(compile_schemas+[path]): - Logs.warn('Could not update GSettings schema cache %r'%path) - if self.bld.is_install: - schemadir=self.env.GSETTINGSSCHEMADIR - if not schemadir: - raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)') - if install_files: - self.add_install_files(install_to=schemadir,install_from=install_files) - registered_schemas=getattr(self.bld,'_compile_schemas_registered',None) - if not registered_schemas: - registered_schemas=self.bld._compile_schemas_registered=set() - self.bld.add_post_fun(compile_schemas_callback) - registered_schemas.add(schemadir) -class glib_validate_schema(Task.Task): - run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}' - color='PINK' -@extension('.gresource.xml') -def process_gresource_source(self,node): - if not self.env.GLIB_COMPILE_RESOURCES: - raise Errors.WafError("Unable to process GResource file - glib-compile-resources was not found during configure") - if'gresource'in self.features: - return - h_node=node.change_ext('_xml.h') - c_node=node.change_ext('_xml.c') - self.create_task('glib_gresource_source',node,[h_node,c_node]) - self.source.append(c_node) -@feature('gresource') -def process_gresource_bundle(self): - for i in self.to_list(self.source): - node=self.path.find_resource(i) - task=self.create_task('glib_gresource_bundle',node,node.change_ext('')) - inst_to=getattr(self,'install_path',None) - if inst_to: - self.add_install_files(install_to=inst_to,install_from=task.outputs) -class glib_gresource_base(Task.Task): - color='BLUE' - base_cmd='${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}' - def scan(self): - bld=self.generator.bld - kw={} - kw['cwd']=self.get_cwd() - kw['quiet']=Context.BOTH - cmd=Utils.subst_vars('${GLIB_COMPILE_RESOURCES} --sourcedir=%s --sourcedir=%s --generate-dependencies %s'%(self.inputs[0].parent.srcpath(),self.inputs[0].bld_dir(),self.inputs[0].bldpath()),self.env) - output=bld.cmd_and_log(cmd,**kw) - nodes=[] - names=[] - for dep in output.splitlines(): - if dep: - node=bld.bldnode.find_node(dep) - if node: - nodes.append(node) - else: - names.append(dep) - return(nodes,names) -class glib_gresource_source(glib_gresource_base): - vars=['GLIB_COMPILE_RESOURCES'] - fun_h=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[0].abspath()} --generate-header ${SRC}') - fun_c=Task.compile_fun_shell(glib_gresource_base.base_cmd+' --target=${TGT[1].abspath()} --generate-source ${SRC}') - ext_out=['.h'] - def run(self): - return self.fun_h[0](self)or self.fun_c[0](self) -class glib_gresource_bundle(glib_gresource_base): - run_str=glib_gresource_base.base_cmd+' --target=${TGT} ${SRC}' - shell=True -@conf -def find_glib_genmarshal(conf): - conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL') -@conf -def find_glib_mkenums(conf): - if not conf.env.PERL: - conf.find_program('perl',var='PERL') - conf.find_program('glib-mkenums',interpreter='PERL',var='GLIB_MKENUMS') -@conf -def find_glib_compile_schemas(conf): - conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS') - def getstr(varname): - return getattr(Options.options,varname,getattr(conf.env,varname,'')) - gsettingsschemadir=getstr('GSETTINGSSCHEMADIR') - if not gsettingsschemadir: - datadir=getstr('DATADIR') - if not datadir: - prefix=conf.env.PREFIX - datadir=os.path.join(prefix,'share') - gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas') - conf.env.GSETTINGSSCHEMADIR=gsettingsschemadir -@conf -def find_glib_compile_resources(conf): - conf.find_program('glib-compile-resources',var='GLIB_COMPILE_RESOURCES') -def configure(conf): - conf.find_glib_genmarshal() - conf.find_glib_mkenums() - conf.find_glib_compile_schemas(mandatory=False) - conf.find_glib_compile_resources(mandatory=False) -def options(opt): - gr=opt.add_option_group('Installation directories') - gr.add_option('--gsettingsschemadir',help='GSettings schema location [DATADIR/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py deleted file mode 100755 index 21a6288..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py +++ /dev/null @@ -1,66 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re -from waflib import Utils,Options,Context -gnuopts=''' -bindir, user commands, ${EXEC_PREFIX}/bin -sbindir, system binaries, ${EXEC_PREFIX}/sbin -libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec -sysconfdir, host-specific configuration, ${PREFIX}/etc -sharedstatedir, architecture-independent variable data, ${PREFIX}/com -localstatedir, variable data, ${PREFIX}/var -libdir, object code libraries, ${EXEC_PREFIX}/lib%s -includedir, header files, ${PREFIX}/include -oldincludedir, header files for non-GCC compilers, /usr/include -datarootdir, architecture-independent data root, ${PREFIX}/share -datadir, architecture-independent data, ${DATAROOTDIR} -infodir, GNU "info" documentation, ${DATAROOTDIR}/info -localedir, locale-dependent data, ${DATAROOTDIR}/locale -mandir, manual pages, ${DATAROOTDIR}/man -docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE} -htmldir, HTML documentation, ${DOCDIR} -dvidir, DVI documentation, ${DOCDIR} -pdfdir, PDF documentation, ${DOCDIR} -psdir, PostScript documentation, ${DOCDIR} -'''%Utils.lib64() -_options=[x.split(', ')for x in gnuopts.splitlines()if x] -def configure(conf): - def get_param(varname,default): - return getattr(Options.options,varname,'')or default - env=conf.env - env.LIBDIR=env.BINDIR=[] - env.EXEC_PREFIX=get_param('EXEC_PREFIX',env.PREFIX) - env.PACKAGE=getattr(Context.g_module,'APPNAME',None)or env.PACKAGE - complete=False - iter=0 - while not complete and iter\d*)\.(?P\d*)",re.I).search - if Utils.is_win32: - cmd=fc - else: - cmd=fc+['-logo'] - out,err=fc_config.getoutput(conf,cmd,stdin=False) - match=version_re(out)or version_re(err) - if not match: - conf.fatal('cannot determine ifort version.') - k=match.groupdict() - conf.env.FC_VERSION=(k['major'],k['minor']) -def configure(conf): - if Utils.is_win32: - compiler,version,path,includes,libdirs,arch=conf.detect_ifort() - v=conf.env - v.DEST_CPU=arch - v.PATH=path - v.INCLUDES=includes - v.LIBPATH=libdirs - v.MSVC_COMPILER=compiler - try: - v.MSVC_VERSION=float(version) - except ValueError: - v.MSVC_VERSION=float(version[:-3]) - conf.find_ifort_win32() - conf.ifort_modifier_win32() - else: - conf.find_ifort() - conf.find_program('xiar',var='AR') - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.ifort_modifier_platform() -all_ifort_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')] -@conf -def gather_ifort_versions(conf,versions): - version_pattern=re.compile(r'^...?.?\....?.?') - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran') - except OSError: - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\Fortran') - except OSError: - return - index=0 - while 1: - try: - version=Utils.winreg.EnumKey(all_versions,index) - except OSError: - break - index+=1 - if not version_pattern.match(version): - continue - targets={} - for target,arch in all_ifort_platforms: - if target=='intel64': - targetDir='EM64T_NATIVE' - else: - targetDir=target - try: - Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) - icl_version=Utils.winreg.OpenKey(all_versions,version) - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - pass - else: - batch_file=os.path.join(path,'bin','ifortvars.bat') - if os.path.isfile(batch_file): - targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) - for target,arch in all_ifort_platforms: - try: - icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target) - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - continue - else: - batch_file=os.path.join(path,'bin','ifortvars.bat') - if os.path.isfile(batch_file): - targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) - major=version[0:2] - versions['intel '+major]=targets -@conf -def setup_ifort(conf,versiondict): - platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_ifort_platforms] - desired_versions=conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys()))) - for version in desired_versions: - try: - targets=versiondict[version] - except KeyError: - continue - for arch in platforms: - try: - cfg=targets[arch] - except KeyError: - continue - cfg.evaluate() - if cfg.is_valid: - compiler,revision=version.rsplit(' ',1) - return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu - conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys()))) -@conf -def get_ifort_version_win32(conf,compiler,version,target,vcvars): - try: - conf.msvc_cnt+=1 - except AttributeError: - conf.msvc_cnt=1 - batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt) - batfile.write("""@echo off -set INCLUDE= -set LIB= -call "%s" %s -echo PATH=%%PATH%% -echo INCLUDE=%%INCLUDE%% -echo LIB=%%LIB%%;%%LIBPATH%% -"""%(vcvars,target)) - sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()]) - batfile.delete() - lines=sout.splitlines() - if not lines[0]: - lines.pop(0) - MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None - for line in lines: - if line.startswith('PATH='): - path=line[5:] - MSVC_PATH=path.split(';') - elif line.startswith('INCLUDE='): - MSVC_INCDIR=[i for i in line[8:].split(';')if i] - elif line.startswith('LIB='): - MSVC_LIBDIR=[i for i in line[4:].split(';')if i] - if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR): - conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)') - env=dict(os.environ) - env.update(PATH=path) - compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) - fc=conf.find_program(compiler_name,path_list=MSVC_PATH) - if'CL'in env: - del(env['CL']) - try: - conf.cmd_and_log(fc+['/help'],env=env) - except UnicodeError: - st=traceback.format_exc() - if conf.logger: - conf.logger.error(st) - conf.fatal('ifort: Unicode error - check the code page?') - except Exception as e: - Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s',compiler,version,target,str(e)) - conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)') - else: - Logs.debug('ifort: get_ifort_version: %r %r %r -> OK',compiler,version,target) - finally: - conf.env[compiler_name]='' - return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR) -class target_compiler(object): - def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None): - self.conf=ctx - self.name=None - self.is_valid=False - self.is_done=False - self.compiler=compiler - self.cpu=cpu - self.version=version - self.bat_target=bat_target - self.bat=bat - self.callback=callback - def evaluate(self): - if self.is_done: - return - self.is_done=True - try: - vs=self.conf.get_ifort_version_win32(self.compiler,self.version,self.bat_target,self.bat) - except Errors.ConfigurationError: - self.is_valid=False - return - if self.callback: - vs=self.callback(self,vs) - self.is_valid=True - (self.bindirs,self.incdirs,self.libdirs)=vs - def __str__(self): - return str((self.bindirs,self.incdirs,self.libdirs)) - def __repr__(self): - return repr((self.bindirs,self.incdirs,self.libdirs)) -@conf -def detect_ifort(self): - return self.setup_ifort(self.get_ifort_versions(False)) -@conf -def get_ifort_versions(self,eval_and_save=True): - dct={} - self.gather_ifort_versions(dct) - return dct -def _get_prog_names(self,compiler): - if compiler=='intel': - compiler_name='ifort' - linker_name='XILINK' - lib_name='XILIB' - else: - compiler_name='CL' - linker_name='LINK' - lib_name='LIB' - return compiler_name,linker_name,lib_name -@conf -def find_ifort_win32(conf): - v=conf.env - path=v.PATH - compiler=v.MSVC_COMPILER - version=v.MSVC_VERSION - compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) - v.IFORT_MANIFEST=(compiler=='intel'and version>=11) - fc=conf.find_program(compiler_name,var='FC',path_list=path) - env=dict(conf.environ) - if path: - env.update(PATH=';'.join(path)) - if not conf.cmd_and_log(fc+['/nologo','/help'],env=env): - conf.fatal('not intel fortran compiler could not be identified') - v.FC_NAME='IFORT' - if not v.LINK_FC: - conf.find_program(linker_name,var='LINK_FC',path_list=path,mandatory=True) - if not v.AR: - conf.find_program(lib_name,path_list=path,var='AR',mandatory=True) - v.ARFLAGS=['/nologo'] - if v.IFORT_MANIFEST: - conf.find_program('MT',path_list=path,var='MT') - v.MTFLAGS=['/nologo'] - try: - conf.load('winres') - except Errors.WafError: - Logs.warn('Resource compiler not found. Compiling resource file is disabled') -@after_method('apply_link') -@feature('fc') -def apply_flags_ifort(self): - if not self.env.IFORT_WIN32 or not getattr(self,'link_task',None): - return - is_static=isinstance(self.link_task,ccroot.stlink_task) - subsystem=getattr(self,'subsystem','') - if subsystem: - subsystem='/subsystem:%s'%subsystem - flags=is_static and'ARFLAGS'or'LINKFLAGS' - self.env.append_value(flags,subsystem) - if not is_static: - for f in self.env.LINKFLAGS: - d=f.lower() - if d[1:]=='debug': - pdbnode=self.link_task.outputs[0].change_ext('.pdb') - self.link_task.outputs.append(pdbnode) - if getattr(self,'install_task',None): - self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode) - break -@feature('fcprogram','fcshlib','fcprogram_test') -@after_method('apply_link') -def apply_manifest_ifort(self): - if self.env.IFORT_WIN32 and getattr(self,'link_task',None): - self.link_task.env.FC=self.env.LINK_FC - if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self,'link_task',None): - out_node=self.link_task.outputs[0] - man_node=out_node.parent.find_or_declare(out_node.name+'.manifest') - self.link_task.outputs.append(man_node) - self.env.DO_MANIFEST=True diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py deleted file mode 100755 index d799402..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py +++ /dev/null @@ -1,101 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from __future__ import with_statement -import os,re -from waflib import Context,Task,Utils,Logs -import waflib.Tools.ccroot -from waflib.TaskGen import feature,before_method,taskgen_method -from waflib.Logs import error -from waflib.Configure import conf -_style_flags={'ba':'-b','desktop':'-d','keys':'-k','quoted':'--quoted-style','quotedxml':'--quotedxml-style','rfc822deb':'-r','schemas':'-s','xml':'-x',} -@taskgen_method -def ensure_localedir(self): - if not self.env.LOCALEDIR: - if self.env.DATAROOTDIR: - self.env.LOCALEDIR=os.path.join(self.env.DATAROOTDIR,'locale') - else: - self.env.LOCALEDIR=os.path.join(self.env.PREFIX,'share','locale') -@before_method('process_source') -@feature('intltool_in') -def apply_intltool_in_f(self): - try: - self.meths.remove('process_source') - except ValueError: - pass - self.ensure_localedir() - podir=getattr(self,'podir','.') - podirnode=self.path.find_dir(podir) - if not podirnode: - error("could not find the podir %r"%podir) - return - cache=getattr(self,'intlcache','.intlcache') - self.env.INTLCACHE=[os.path.join(str(self.path.get_bld()),podir,cache)] - self.env.INTLPODIR=podirnode.bldpath() - self.env.append_value('INTLFLAGS',getattr(self,'flags',self.env.INTLFLAGS_DEFAULT)) - if'-c'in self.env.INTLFLAGS: - self.bld.fatal('Redundant -c flag in intltool task %r'%self) - style=getattr(self,'style',None) - if style: - try: - style_flag=_style_flags[style] - except KeyError: - self.bld.fatal('intltool_in style "%s" is not valid'%style) - self.env.append_unique('INTLFLAGS',[style_flag]) - for i in self.to_list(self.source): - node=self.path.find_resource(i) - task=self.create_task('intltool',node,node.change_ext('')) - inst=getattr(self,'install_path',None) - if inst: - self.add_install_files(install_to=inst,install_from=task.outputs) -@feature('intltool_po') -def apply_intltool_po(self): - try: - self.meths.remove('process_source') - except ValueError: - pass - self.ensure_localedir() - appname=getattr(self,'appname',getattr(Context.g_module,Context.APPNAME,'set_your_app_name')) - podir=getattr(self,'podir','.') - inst=getattr(self,'install_path','${LOCALEDIR}') - linguas=self.path.find_node(os.path.join(podir,'LINGUAS')) - if linguas: - with open(linguas.abspath())as f: - langs=[] - for line in f.readlines(): - if not line.startswith('#'): - langs+=line.split() - re_linguas=re.compile('[-a-zA-Z_@.]+') - for lang in langs: - if re_linguas.match(lang): - node=self.path.find_resource(os.path.join(podir,re_linguas.match(lang).group()+'.po')) - task=self.create_task('po',node,node.change_ext('.mo')) - if inst: - filename=task.outputs[0].name - (langname,ext)=os.path.splitext(filename) - inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo' - self.add_install_as(install_to=inst_file,install_from=task.outputs[0],chmod=getattr(self,'chmod',Utils.O644)) - else: - Logs.pprint('RED',"Error no LINGUAS file found in po directory") -class po(Task.Task): - run_str='${MSGFMT} -o ${TGT} ${SRC}' - color='BLUE' -class intltool(Task.Task): - run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}' - color='BLUE' -@conf -def find_msgfmt(conf): - conf.find_program('msgfmt',var='MSGFMT') -@conf -def find_intltool_merge(conf): - if not conf.env.PERL: - conf.find_program('perl',var='PERL') - conf.env.INTLCACHE_ST='--cache=%s' - conf.env.INTLFLAGS_DEFAULT=['-q','-u'] - conf.find_program('intltool-merge',interpreter='PERL',var='INTLTOOL') -def configure(conf): - conf.find_msgfmt() - conf.find_intltool_merge() - if conf.env.CC or conf.env.CXX: - conf.check(header_name='locale.h') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py deleted file mode 100755 index 06099ff..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py +++ /dev/null @@ -1,51 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Errors -from waflib.Tools import ccroot,ar -from waflib.Configure import conf -@conf -def find_irixcc(conf): - v=conf.env - cc=None - if v.CC: - cc=v.CC - elif'CC'in conf.environ: - cc=conf.environ['CC'] - if not cc: - cc=conf.find_program('cc',var='CC') - if not cc: - conf.fatal('irixcc was not found') - try: - conf.cmd_and_log(cc+['-version']) - except Errors.WafError: - conf.fatal('%r -version could not be executed'%cc) - v.CC=cc - v.CC_NAME='irix' -@conf -def irixcc_common_flags(conf): - v=conf.env - v.CC_SRC_F='' - v.CC_TGT_F=['-c','-o'] - v.CPPPATH_ST='-I%s' - v.DEFINES_ST='-D%s' - if not v.LINK_CC: - v.LINK_CC=v.CC - v.CCLNK_SRC_F='' - v.CCLNK_TGT_F=['-o'] - v.LIB_ST='-l%s' - v.LIBPATH_ST='-L%s' - v.STLIB_ST='-l%s' - v.STLIBPATH_ST='-L%s' - v.cprogram_PATTERN='%s' - v.cshlib_PATTERN='lib%s.so' - v.cstlib_PATTERN='lib%s.a' -def configure(conf): - conf.find_irixcc() - conf.find_cpp() - conf.find_ar() - conf.irixcc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py deleted file mode 100755 index 7f97c97..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py +++ /dev/null @@ -1,330 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,shutil -from waflib import Task,Utils,Errors,Node -from waflib.Configure import conf -from waflib.TaskGen import feature,before_method,after_method,taskgen_method -from waflib.Tools import ccroot -ccroot.USELIB_VARS['javac']=set(['CLASSPATH','JAVACFLAGS']) -SOURCE_RE='**/*.java' -JAR_RE='**/*' -class_check_source=''' -public class Test { - public static void main(String[] argv) { - Class lib; - if (argv.length < 1) { - System.err.println("Missing argument"); - System.exit(77); - } - try { - lib = Class.forName(argv[0]); - } catch (ClassNotFoundException e) { - System.err.println("ClassNotFoundException"); - System.exit(1); - } - lib = null; - System.exit(0); - } -} -''' -@feature('javac') -@before_method('process_source') -def apply_java(self): - Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[]) - outdir=getattr(self,'outdir',None) - if outdir: - if not isinstance(outdir,Node.Node): - outdir=self.path.get_bld().make_node(self.outdir) - else: - outdir=self.path.get_bld() - outdir.mkdir() - self.outdir=outdir - self.env.OUTDIR=outdir.abspath() - self.javac_task=tsk=self.create_task('javac') - tmp=[] - srcdir=getattr(self,'srcdir','') - if isinstance(srcdir,Node.Node): - srcdir=[srcdir] - for x in Utils.to_list(srcdir): - if isinstance(x,Node.Node): - y=x - else: - y=self.path.find_dir(x) - if not y: - self.bld.fatal('Could not find the folder %s from %s'%(x,self.path)) - tmp.append(y) - tsk.srcdir=tmp - if getattr(self,'compat',None): - tsk.env.append_value('JAVACFLAGS',['-source',str(self.compat)]) - if hasattr(self,'sourcepath'): - fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)] - names=os.pathsep.join([x.srcpath()for x in fold]) - else: - names=[x.srcpath()for x in tsk.srcdir] - if names: - tsk.env.append_value('JAVACFLAGS',['-sourcepath',names]) -@taskgen_method -def java_use_rec(self,name,**kw): - if name in self.tmp_use_seen: - return - self.tmp_use_seen.append(name) - try: - y=self.bld.get_tgen_by_name(name) - except Errors.WafError: - self.uselib.append(name) - return - else: - y.post() - if hasattr(y,'jar_task'): - self.use_lst.append(y.jar_task.outputs[0].abspath()) - else: - if hasattr(y,'outdir'): - self.use_lst.append(y.outdir.abspath()) - else: - self.use_lst.append(y.path.get_bld().abspath()) - for x in self.to_list(getattr(y,'use',[])): - self.java_use_rec(x) -@feature('javac') -@before_method('propagate_uselib_vars') -@after_method('apply_java') -def use_javac_files(self): - self.use_lst=[] - self.tmp_use_seen=[] - self.uselib=self.to_list(getattr(self,'uselib',[])) - names=self.to_list(getattr(self,'use',[])) - get=self.bld.get_tgen_by_name - for x in names: - try: - tg=get(x) - except Errors.WafError: - self.uselib.append(x) - else: - tg.post() - if hasattr(tg,'jar_task'): - self.use_lst.append(tg.jar_task.outputs[0].abspath()) - self.javac_task.set_run_after(tg.jar_task) - self.javac_task.dep_nodes.extend(tg.jar_task.outputs) - else: - if hasattr(tg,'outdir'): - base_node=tg.outdir - else: - base_node=tg.path.get_bld() - self.use_lst.append(base_node.abspath()) - self.javac_task.dep_nodes.extend([x for x in base_node.ant_glob(JAR_RE,remove=False,quiet=True)]) - for tsk in tg.tasks: - self.javac_task.set_run_after(tsk) - if getattr(self,'recurse_use',False)or self.bld.env.RECURSE_JAVA: - self.java_use_rec(x) - self.env.append_value('CLASSPATH',self.use_lst) -@feature('javac') -@after_method('apply_java','propagate_uselib_vars','use_javac_files') -def set_classpath(self): - if getattr(self,'classpath',None): - self.env.append_unique('CLASSPATH',getattr(self,'classpath',[])) - for x in self.tasks: - x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep -@feature('jar') -@after_method('apply_java','use_javac_files') -@before_method('process_source') -def jar_files(self): - destfile=getattr(self,'destfile','test.jar') - jaropts=getattr(self,'jaropts',[]) - manifest=getattr(self,'manifest',None) - basedir=getattr(self,'basedir',None) - if basedir: - if not isinstance(self.basedir,Node.Node): - basedir=self.path.get_bld().make_node(basedir) - else: - basedir=self.path.get_bld() - if not basedir: - self.bld.fatal('Could not find the basedir %r for %r'%(self.basedir,self)) - self.jar_task=tsk=self.create_task('jar_create') - if manifest: - jarcreate=getattr(self,'jarcreate','cfm') - if not isinstance(manifest,Node.Node): - node=self.path.find_resource(manifest) - else: - node=manifest - if not node: - self.bld.fatal('invalid manifest file %r for %r'%(manifest,self)) - tsk.dep_nodes.append(node) - jaropts.insert(0,node.abspath()) - else: - jarcreate=getattr(self,'jarcreate','cf') - if not isinstance(destfile,Node.Node): - destfile=self.path.find_or_declare(destfile) - if not destfile: - self.bld.fatal('invalid destfile %r for %r'%(destfile,self)) - tsk.set_outputs(destfile) - tsk.basedir=basedir - jaropts.append('-C') - jaropts.append(basedir.bldpath()) - jaropts.append('.') - tsk.env.JAROPTS=jaropts - tsk.env.JARCREATE=jarcreate - if getattr(self,'javac_task',None): - tsk.set_run_after(self.javac_task) -@feature('jar') -@after_method('jar_files') -def use_jar_files(self): - self.uselib=self.to_list(getattr(self,'uselib',[])) - names=self.to_list(getattr(self,'use',[])) - get=self.bld.get_tgen_by_name - for x in names: - try: - y=get(x) - except Errors.WafError: - self.uselib.append(x) - else: - y.post() - self.jar_task.run_after.update(y.tasks) -class JTask(Task.Task): - def split_argfile(self,cmd): - inline=[cmd[0]] - infile=[] - for x in cmd[1:]: - if x.startswith('-J'): - inline.append(x) - else: - infile.append(self.quote_flag(x)) - return(inline,infile) -class jar_create(JTask): - color='GREEN' - run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}' - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - if not self.inputs: - try: - self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False,quiet=True)if id(x)!=id(self.outputs[0])] - except Exception: - raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self)) - return super(jar_create,self).runnable_status() -class javac(JTask): - color='BLUE' - run_str='${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}' - vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR'] - def uid(self): - lst=[self.__class__.__name__,self.generator.outdir.abspath()] - for x in self.srcdir: - lst.append(x.abspath()) - return Utils.h_list(lst) - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - if not self.inputs: - self.inputs=[] - for x in self.srcdir: - if x.exists(): - self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False,quiet=True)) - return super(javac,self).runnable_status() - def post_run(self): - for node in self.generator.outdir.ant_glob('**/*.class',quiet=True): - self.generator.bld.node_sigs[node]=self.uid() - self.generator.bld.task_sigs[self.uid()]=self.cache_sig -@feature('javadoc') -@after_method('process_rule') -def create_javadoc(self): - tsk=self.create_task('javadoc') - tsk.classpath=getattr(self,'classpath',[]) - self.javadoc_package=Utils.to_list(self.javadoc_package) - if not isinstance(self.javadoc_output,Node.Node): - self.javadoc_output=self.bld.path.find_or_declare(self.javadoc_output) -class javadoc(Task.Task): - color='BLUE' - def __str__(self): - return'%s: %s -> %s\n'%(self.__class__.__name__,self.generator.srcdir,self.generator.javadoc_output) - def run(self): - env=self.env - bld=self.generator.bld - wd=bld.bldnode - srcpath=self.generator.path.abspath()+os.sep+self.generator.srcdir - srcpath+=os.pathsep - srcpath+=self.generator.path.get_bld().abspath()+os.sep+self.generator.srcdir - classpath=env.CLASSPATH - classpath+=os.pathsep - classpath+=os.pathsep.join(self.classpath) - classpath="".join(classpath) - self.last_cmd=lst=[] - lst.extend(Utils.to_list(env.JAVADOC)) - lst.extend(['-d',self.generator.javadoc_output.abspath()]) - lst.extend(['-sourcepath',srcpath]) - lst.extend(['-classpath',classpath]) - lst.extend(['-subpackages']) - lst.extend(self.generator.javadoc_package) - lst=[x for x in lst if x] - self.generator.bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0) - def post_run(self): - nodes=self.generator.javadoc_output.ant_glob('**',quiet=True) - for node in nodes: - self.generator.bld.node_sigs[node]=self.uid() - self.generator.bld.task_sigs[self.uid()]=self.cache_sig -def configure(self): - java_path=self.environ['PATH'].split(os.pathsep) - v=self.env - if'JAVA_HOME'in self.environ: - java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path - self.env.JAVA_HOME=[self.environ['JAVA_HOME']] - for x in'javac java jar javadoc'.split(): - self.find_program(x,var=x.upper(),path_list=java_path,mandatory=(x not in('javadoc'))) - if'CLASSPATH'in self.environ: - v.CLASSPATH=self.environ['CLASSPATH'] - if not v.JAR: - self.fatal('jar is required for making java packages') - if not v.JAVAC: - self.fatal('javac is required for compiling java classes') - v.JARCREATE='cf' - v.JAVACFLAGS=[] -@conf -def check_java_class(self,classname,with_classpath=None): - javatestdir='.waf-javatest' - classpath=javatestdir - if self.env.CLASSPATH: - classpath+=os.pathsep+self.env.CLASSPATH - if isinstance(with_classpath,str): - classpath+=os.pathsep+with_classpath - shutil.rmtree(javatestdir,True) - os.mkdir(javatestdir) - Utils.writef(os.path.join(javatestdir,'Test.java'),class_check_source) - self.exec_command(self.env.JAVAC+[os.path.join(javatestdir,'Test.java')],shell=False) - cmd=self.env.JAVA+['-cp',classpath,'Test',classname] - self.to_log("%s\n"%str(cmd)) - found=self.exec_command(cmd,shell=False) - self.msg('Checking for java class %s'%classname,not found) - shutil.rmtree(javatestdir,True) - return found -@conf -def check_jni_headers(conf): - if not conf.env.CC_NAME and not conf.env.CXX_NAME: - conf.fatal('load a compiler first (gcc, g++, ..)') - if not conf.env.JAVA_HOME: - conf.fatal('set JAVA_HOME in the system environment') - javaHome=conf.env.JAVA_HOME[0] - dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include') - if dir is None: - dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/../Headers') - if dir is None: - conf.fatal('JAVA_HOME does not seem to be set properly') - f=dir.ant_glob('**/(jni|jni_md).h') - incDirs=[x.parent.abspath()for x in f] - dir=conf.root.find_dir(conf.env.JAVA_HOME[0]) - f=dir.ant_glob('**/*jvm.(so|dll|dylib)') - libDirs=[x.parent.abspath()for x in f]or[javaHome] - f=dir.ant_glob('**/*jvm.(lib)') - if f: - libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f] - if conf.env.DEST_OS=='freebsd': - conf.env.append_unique('LINKFLAGS_JAVA','-pthread') - for d in libDirs: - try: - conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA') - except Exception: - pass - else: - break - else: - conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs) diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py deleted file mode 100755 index 40d435e..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py +++ /dev/null @@ -1,36 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.Tools import ar,d -from waflib.Configure import conf -@conf -def find_ldc2(conf): - conf.find_program(['ldc2'],var='D') - out=conf.cmd_and_log(conf.env.D+['-version']) - if out.find("based on DMD v2.")==-1: - conf.fatal("detected compiler is not ldc2") -@conf -def common_flags_ldc2(conf): - v=conf.env - v.D_SRC_F=['-c'] - v.D_TGT_F='-of%s' - v.D_LINKER=v.D - v.DLNK_SRC_F='' - v.DLNK_TGT_F='-of%s' - v.DINC_ST='-I%s' - v.DSHLIB_MARKER=v.DSTLIB_MARKER='' - v.DSTLIB_ST=v.DSHLIB_ST='-L-l%s' - v.DSTLIBPATH_ST=v.DLIBPATH_ST='-L-L%s' - v.LINKFLAGS_dshlib=['-L-shared'] - v.DHEADER_ext='.di' - v.DFLAGS_d_with_header=['-H','-Hf'] - v.D_HDR_F='%s' - v.LINKFLAGS=[] - v.DFLAGS_dshlib=['-relocation-model=pic'] -def configure(conf): - conf.find_ldc2() - conf.load('ar') - conf.load('d') - conf.common_flags_ldc2() - conf.d_platform_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py deleted file mode 100755 index 7c6a682..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py +++ /dev/null @@ -1,18 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.TaskGen import extension -from waflib import Task -@extension('.lua') -def add_lua(self,node): - tsk=self.create_task('luac',node,node.change_ext('.luac')) - inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None) - if inst_to: - self.add_install_files(install_to=inst_to,install_from=tsk.outputs) - return tsk -class luac(Task.Task): - run_str='${LUAC} -s -o ${TGT} ${SRC}' - color='PINK' -def configure(conf): - conf.find_program('luac',var='LUAC') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py deleted file mode 100755 index 0d0faa0..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,stat -from waflib import Utils,Build,Node -STRONGEST=True -Build.SAVED_ATTRS.append('hashes_md5_tstamp') -def h_file(self): - filename=self.abspath() - st=os.stat(filename) - cache=self.ctx.hashes_md5_tstamp - if filename in cache and cache[filename][0]==st.st_mtime: - return cache[filename][1] - if STRONGEST: - ret=Utils.h_file(filename) - else: - if stat.S_ISDIR(st[stat.ST_MODE]): - raise IOError('Not a file') - ret=Utils.md5(str((st.st_mtime,st.st_size)).encode()).digest() - cache[filename]=(st.st_mtime,ret) - return ret -h_file.__doc__=Node.Node.h_file.__doc__ -Node.Node.h_file=h_file diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py deleted file mode 100755 index 36839d2..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py +++ /dev/null @@ -1,704 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,sys,re,traceback -from waflib import Utils,Logs,Options,Errors -from waflib.TaskGen import after_method,feature -from waflib.Configure import conf -from waflib.Tools import ccroot,c,cxx,ar -g_msvc_systemlibs=''' -aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet -cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs -credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d -ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp -faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid -gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop -kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi -mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree -msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm -netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp -odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32 -osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu -ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm -rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32 -shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32 -traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg -version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm -wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp -'''.split() -all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm'),('x86_arm64','arm64'),('amd64_x86','x86'),('amd64_arm','arm'),('amd64_arm64','arm64')] -all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')] -all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')] -def options(opt): - opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='') - opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='') - opt.add_option('--no-msvc-lazy',action='store_false',help='lazily check msvc target environments',default=True,dest='msvc_lazy') -@conf -def setup_msvc(conf,versiondict): - platforms=getattr(Options.options,'msvc_targets','').split(',') - if platforms==['']: - platforms=Utils.to_list(conf.env.MSVC_TARGETS)or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms] - desired_versions=getattr(Options.options,'msvc_version','').split(',') - if desired_versions==['']: - desired_versions=conf.env.MSVC_VERSIONS or list(reversed(sorted(versiondict.keys()))) - lazy_detect=getattr(Options.options,'msvc_lazy',True) - if conf.env.MSVC_LAZY_AUTODETECT is False: - lazy_detect=False - if not lazy_detect: - for val in versiondict.values(): - for arch in list(val.keys()): - cfg=val[arch] - cfg.evaluate() - if not cfg.is_valid: - del val[arch] - conf.env.MSVC_INSTALLED_VERSIONS=versiondict - for version in desired_versions: - Logs.debug('msvc: detecting %r - %r',version,desired_versions) - try: - targets=versiondict[version] - except KeyError: - continue - seen=set() - for arch in platforms: - if arch in seen: - continue - else: - seen.add(arch) - try: - cfg=targets[arch] - except KeyError: - continue - cfg.evaluate() - if cfg.is_valid: - compiler,revision=version.rsplit(' ',1) - return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu - conf.fatal('msvc: Impossible to find a valid architecture for building %r - %r'%(desired_versions,list(versiondict.keys()))) -@conf -def get_msvc_version(conf,compiler,version,target,vcvars): - Logs.debug('msvc: get_msvc_version: %r %r %r',compiler,version,target) - try: - conf.msvc_cnt+=1 - except AttributeError: - conf.msvc_cnt=1 - batfile=conf.bldnode.make_node('waf-print-msvc-%d.bat'%conf.msvc_cnt) - batfile.write("""@echo off -set INCLUDE= -set LIB= -call "%s" %s -echo PATH=%%PATH%% -echo INCLUDE=%%INCLUDE%% -echo LIB=%%LIB%%;%%LIBPATH%% -"""%(vcvars,target)) - sout=conf.cmd_and_log(['cmd.exe','/E:on','/V:on','/C',batfile.abspath()]) - lines=sout.splitlines() - if not lines[0]: - lines.pop(0) - MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None - for line in lines: - if line.startswith('PATH='): - path=line[5:] - MSVC_PATH=path.split(';') - elif line.startswith('INCLUDE='): - MSVC_INCDIR=[i for i in line[8:].split(';')if i] - elif line.startswith('LIB='): - MSVC_LIBDIR=[i for i in line[4:].split(';')if i] - if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR): - conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)') - env=dict(os.environ) - env.update(PATH=path) - compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) - cxx=conf.find_program(compiler_name,path_list=MSVC_PATH) - if'CL'in env: - del(env['CL']) - try: - conf.cmd_and_log(cxx+['/help'],env=env) - except UnicodeError: - st=traceback.format_exc() - if conf.logger: - conf.logger.error(st) - conf.fatal('msvc: Unicode error - check the code page?') - except Exception as e: - Logs.debug('msvc: get_msvc_version: %r %r %r -> failure %s',compiler,version,target,str(e)) - conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)') - else: - Logs.debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target) - finally: - conf.env[compiler_name]='' - return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR) -def gather_wince_supported_platforms(): - supported_wince_platforms=[] - try: - ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs') - except OSError: - try: - ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs') - except OSError: - ce_sdk='' - if not ce_sdk: - return supported_wince_platforms - index=0 - while 1: - try: - sdk_device=Utils.winreg.EnumKey(ce_sdk,index) - sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device) - except OSError: - break - index+=1 - try: - path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir') - except OSError: - try: - path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation') - except OSError: - continue - path,xml=os.path.split(path) - path=str(path) - path,device=os.path.split(path) - if not device: - path,device=os.path.split(path) - platforms=[] - for arch,compiler in all_wince_platforms: - if os.path.isdir(os.path.join(path,device,'Lib',arch)): - platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch))) - if platforms: - supported_wince_platforms.append((device,platforms)) - return supported_wince_platforms -def gather_msvc_detected_versions(): - version_pattern=re.compile(r'^(\d\d?\.\d\d?)(Exp)?$') - detected_versions=[] - for vcver,vcvar in(('VCExpress','Exp'),('VisualStudio','')): - prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix) - except OSError: - prefix='SOFTWARE\\Microsoft\\'+vcver - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix) - except OSError: - continue - index=0 - while 1: - try: - version=Utils.winreg.EnumKey(all_versions,index) - except OSError: - break - index+=1 - match=version_pattern.match(version) - if match: - versionnumber=float(match.group(1)) - else: - continue - detected_versions.append((versionnumber,version+vcvar,prefix+'\\'+version)) - def fun(tup): - return tup[0] - detected_versions.sort(key=fun) - return detected_versions -class target_compiler(object): - def __init__(self,ctx,compiler,cpu,version,bat_target,bat,callback=None): - self.conf=ctx - self.name=None - self.is_valid=False - self.is_done=False - self.compiler=compiler - self.cpu=cpu - self.version=version - self.bat_target=bat_target - self.bat=bat - self.callback=callback - def evaluate(self): - if self.is_done: - return - self.is_done=True - try: - vs=self.conf.get_msvc_version(self.compiler,self.version,self.bat_target,self.bat) - except Errors.ConfigurationError: - self.is_valid=False - return - if self.callback: - vs=self.callback(self,vs) - self.is_valid=True - (self.bindirs,self.incdirs,self.libdirs)=vs - def __str__(self): - return str((self.compiler,self.cpu,self.version,self.bat_target,self.bat)) - def __repr__(self): - return repr((self.compiler,self.cpu,self.version,self.bat_target,self.bat)) -@conf -def gather_wsdk_versions(conf,versions): - version_pattern=re.compile(r'^v..?.?\...?.?') - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows') - except OSError: - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows') - except OSError: - return - index=0 - while 1: - try: - version=Utils.winreg.EnumKey(all_versions,index) - except OSError: - break - index+=1 - if not version_pattern.match(version): - continue - try: - msvc_version=Utils.winreg.OpenKey(all_versions,version) - path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder') - except OSError: - continue - if path and os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')): - targets={} - for target,arch in all_msvc_platforms: - targets[target]=target_compiler(conf,'wsdk',arch,version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')) - versions['wsdk '+version[1:]]=targets -@conf -def gather_msvc_targets(conf,versions,version,vc_path): - targets={} - if os.path.isfile(os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat')): - for target,realtarget in all_msvc_platforms[::-1]: - targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'VC','Auxiliary','Build','vcvarsall.bat')) - elif os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')): - for target,realtarget in all_msvc_platforms[::-1]: - targets[target]=target_compiler(conf,'msvc',realtarget,version,target,os.path.join(vc_path,'vcvarsall.bat')) - elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')): - targets['x86']=target_compiler(conf,'msvc','x86',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')) - elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')): - targets['x86']=target_compiler(conf,'msvc','x86',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')) - if targets: - versions['msvc %s'%version]=targets -@conf -def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms): - for device,platforms in supported_platforms: - targets={} - for platform,compiler,include,lib in platforms: - winCEpath=os.path.join(vc_path,'ce') - if not os.path.isdir(winCEpath): - continue - if os.path.isdir(os.path.join(winCEpath,'lib',platform)): - bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)] - incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include] - libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib] - def combine_common(obj,compiler_env): - (common_bindirs,_1,_2)=compiler_env - return(bindirs+common_bindirs,incdirs,libdirs) - targets[platform]=target_compiler(conf,'msvc',platform,version,'x86',vsvars,combine_common) - if targets: - versions[device+' '+version]=targets -@conf -def gather_winphone_targets(conf,versions,version,vc_path,vsvars): - targets={} - for target,realtarget in all_msvc_platforms[::-1]: - targets[target]=target_compiler(conf,'winphone',realtarget,version,target,vsvars) - if targets: - versions['winphone '+version]=targets -@conf -def gather_vswhere_versions(conf,versions): - try: - import json - except ImportError: - Logs.error('Visual Studio 2017 detection requires Python 2.6') - return - prg_path=os.environ.get('ProgramFiles(x86)',os.environ.get('ProgramFiles','C:\\Program Files (x86)')) - vswhere=os.path.join(prg_path,'Microsoft Visual Studio','Installer','vswhere.exe') - args=[vswhere,'-products','*','-legacy','-format','json'] - try: - txt=conf.cmd_and_log(args) - except Errors.WafError as e: - Logs.debug('msvc: vswhere.exe failed %s',e) - return - if sys.version_info[0]<3: - txt=txt.decode(Utils.console_encoding()) - arr=json.loads(txt) - arr.sort(key=lambda x:x['installationVersion']) - for entry in arr: - ver=entry['installationVersion'] - ver=str('.'.join(ver.split('.')[:2])) - path=str(os.path.abspath(entry['installationPath'])) - if os.path.exists(path)and('msvc %s'%ver)not in versions: - conf.gather_msvc_targets(versions,ver,path) -@conf -def gather_msvc_versions(conf,versions): - vc_paths=[] - for(v,version,reg)in gather_msvc_detected_versions(): - try: - try: - msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC") - except OSError: - msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++") - path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir') - except OSError: - try: - msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Wow6432node\\Microsoft\\VisualStudio\\SxS\\VS7") - path,type=Utils.winreg.QueryValueEx(msvc_version,version) - except OSError: - continue - else: - vc_paths.append((version,os.path.abspath(str(path)))) - continue - else: - vc_paths.append((version,os.path.abspath(str(path)))) - wince_supported_platforms=gather_wince_supported_platforms() - for version,vc_path in vc_paths: - vs_path=os.path.dirname(vc_path) - vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat') - if wince_supported_platforms and os.path.isfile(vsvars): - conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms) - for version,vc_path in vc_paths: - vs_path=os.path.dirname(vc_path) - vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat') - if os.path.isfile(vsvars): - conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars) - break - for version,vc_path in vc_paths: - vs_path=os.path.dirname(vc_path) - conf.gather_msvc_targets(versions,version,vc_path) -@conf -def gather_icl_versions(conf,versions): - version_pattern=re.compile(r'^...?.?\....?.?') - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++') - except OSError: - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++') - except OSError: - return - index=0 - while 1: - try: - version=Utils.winreg.EnumKey(all_versions,index) - except OSError: - break - index+=1 - if not version_pattern.match(version): - continue - targets={} - for target,arch in all_icl_platforms: - if target=='intel64': - targetDir='EM64T_NATIVE' - else: - targetDir=target - try: - Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) - icl_version=Utils.winreg.OpenKey(all_versions,version) - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - pass - else: - batch_file=os.path.join(path,'bin','iclvars.bat') - if os.path.isfile(batch_file): - targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) - for target,arch in all_icl_platforms: - try: - icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target) - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - continue - else: - batch_file=os.path.join(path,'bin','iclvars.bat') - if os.path.isfile(batch_file): - targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) - major=version[0:2] - versions['intel '+major]=targets -@conf -def gather_intel_composer_versions(conf,versions): - version_pattern=re.compile(r'^...?.?\...?.?.?') - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites') - except OSError: - try: - all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites') - except OSError: - return - index=0 - while 1: - try: - version=Utils.winreg.EnumKey(all_versions,index) - except OSError: - break - index+=1 - if not version_pattern.match(version): - continue - targets={} - for target,arch in all_icl_platforms: - if target=='intel64': - targetDir='EM64T_NATIVE' - else: - targetDir=target - try: - try: - defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir) - except OSError: - if targetDir=='EM64T_NATIVE': - defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T') - else: - raise - uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey') - Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir) - icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++') - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - pass - else: - batch_file=os.path.join(path,'bin','iclvars.bat') - if os.path.isfile(batch_file): - targets[target]=target_compiler(conf,'intel',arch,version,target,batch_file) - compilervars_warning_attr='_compilervars_warning_key' - if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True): - setattr(conf,compilervars_warning_attr,False) - patch_url='http://software.intel.com/en-us/forums/topic/328487' - compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat') - for vscomntool in('VS110COMNTOOLS','VS100COMNTOOLS'): - if vscomntool in os.environ: - vs_express_path=os.environ[vscomntool]+r'..\IDE\VSWinExpress.exe' - dev_env_path=os.environ[vscomntool]+r'..\IDE\devenv.exe' - if(r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"'in Utils.readf(compilervars_arch)and not os.path.exists(vs_express_path)and not os.path.exists(dev_env_path)): - Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ''(VSWinExpress.exe) but it does not seem to be installed at %r. ''The intel command line set up will fail to configure unless the file %r''is patched. See: %s')%(vs_express_path,compilervars_arch,patch_url)) - major=version[0:2] - versions['intel '+major]=targets -@conf -def detect_msvc(self): - return self.setup_msvc(self.get_msvc_versions()) -@conf -def get_msvc_versions(self): - dct=Utils.ordered_iter_dict() - self.gather_icl_versions(dct) - self.gather_intel_composer_versions(dct) - self.gather_wsdk_versions(dct) - self.gather_msvc_versions(dct) - self.gather_vswhere_versions(dct) - Logs.debug('msvc: detected versions %r',list(dct.keys())) - return dct -@conf -def find_lt_names_msvc(self,libname,is_static=False): - lt_names=['lib%s.la'%libname,'%s.la'%libname,] - for path in self.env.LIBPATH: - for la in lt_names: - laf=os.path.join(path,la) - dll=None - if os.path.exists(laf): - ltdict=Utils.read_la_file(laf) - lt_libdir=None - if ltdict.get('libdir',''): - lt_libdir=ltdict['libdir'] - if not is_static and ltdict.get('library_names',''): - dllnames=ltdict['library_names'].split() - dll=dllnames[0].lower() - dll=re.sub(r'\.dll$','',dll) - return(lt_libdir,dll,False) - elif ltdict.get('old_library',''): - olib=ltdict['old_library'] - if os.path.exists(os.path.join(path,olib)): - return(path,olib,True) - elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)): - return(lt_libdir,olib,True) - else: - return(None,olib,True) - else: - raise self.errors.WafError('invalid libtool object file: %s'%laf) - return(None,None,None) -@conf -def libname_msvc(self,libname,is_static=False): - lib=libname.lower() - lib=re.sub(r'\.lib$','',lib) - if lib in g_msvc_systemlibs: - return lib - lib=re.sub('^lib','',lib) - if lib=='m': - return None - (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static) - if lt_path!=None and lt_libname!=None: - if lt_static: - return os.path.join(lt_path,lt_libname) - if lt_path!=None: - _libpaths=[lt_path]+self.env.LIBPATH - else: - _libpaths=self.env.LIBPATH - static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,] - dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,] - libnames=static_libs - if not is_static: - libnames=dynamic_libs+static_libs - for path in _libpaths: - for libn in libnames: - if os.path.exists(os.path.join(path,libn)): - Logs.debug('msvc: lib found: %s',os.path.join(path,libn)) - return re.sub(r'\.lib$','',libn) - self.fatal('The library %r could not be found'%libname) - return re.sub(r'\.lib$','',libname) -@conf -def check_lib_msvc(self,libname,is_static=False,uselib_store=None): - libn=self.libname_msvc(libname,is_static) - if not uselib_store: - uselib_store=libname.upper() - if False and is_static: - self.env['STLIB_'+uselib_store]=[libn] - else: - self.env['LIB_'+uselib_store]=[libn] -@conf -def check_libs_msvc(self,libnames,is_static=False): - for libname in Utils.to_list(libnames): - self.check_lib_msvc(libname,is_static) -def configure(conf): - conf.autodetect(True) - conf.find_msvc() - conf.msvc_common_flags() - conf.cc_load_tools() - conf.cxx_load_tools() - conf.cc_add_flags() - conf.cxx_add_flags() - conf.link_add_flags() - conf.visual_studio_add_flags() -@conf -def no_autodetect(conf): - conf.env.NO_MSVC_DETECT=1 - configure(conf) -@conf -def autodetect(conf,arch=False): - v=conf.env - if v.NO_MSVC_DETECT: - return - compiler,version,path,includes,libdirs,cpu=conf.detect_msvc() - if arch: - v.DEST_CPU=cpu - v.PATH=path - v.INCLUDES=includes - v.LIBPATH=libdirs - v.MSVC_COMPILER=compiler - try: - v.MSVC_VERSION=float(version) - except ValueError: - v.MSVC_VERSION=float(version[:-3]) -def _get_prog_names(conf,compiler): - if compiler=='intel': - compiler_name='ICL' - linker_name='XILINK' - lib_name='XILIB' - else: - compiler_name='CL' - linker_name='LINK' - lib_name='LIB' - return compiler_name,linker_name,lib_name -@conf -def find_msvc(conf): - if sys.platform=='cygwin': - conf.fatal('MSVC module does not work under cygwin Python!') - v=conf.env - path=v.PATH - compiler=v.MSVC_COMPILER - version=v.MSVC_VERSION - compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler) - v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11) - cxx=conf.find_program(compiler_name,var='CXX',path_list=path) - env=dict(conf.environ) - if path: - env.update(PATH=';'.join(path)) - if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env): - conf.fatal('the msvc compiler could not be identified') - v.CC=v.CXX=cxx - v.CC_NAME=v.CXX_NAME='msvc' - if not v.LINK_CXX: - conf.find_program(linker_name,path_list=path,errmsg='%s was not found (linker)'%linker_name,var='LINK_CXX') - if not v.LINK_CC: - v.LINK_CC=v.LINK_CXX - if not v.AR: - stliblink=conf.find_program(lib_name,path_list=path,var='AR') - if not stliblink: - return - v.ARFLAGS=['/nologo'] - if v.MSVC_MANIFEST: - conf.find_program('MT',path_list=path,var='MT') - v.MTFLAGS=['/nologo'] - try: - conf.load('winres') - except Errors.ConfigurationError: - Logs.warn('Resource compiler not found. Compiling resource file is disabled') -@conf -def visual_studio_add_flags(self): - v=self.env - if self.environ.get('INCLUDE'): - v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x]) - if self.environ.get('LIB'): - v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x]) -@conf -def msvc_common_flags(conf): - v=conf.env - v.DEST_BINFMT='pe' - v.append_value('CFLAGS',['/nologo']) - v.append_value('CXXFLAGS',['/nologo']) - v.append_value('LINKFLAGS',['/nologo']) - v.DEFINES_ST='/D%s' - v.CC_SRC_F='' - v.CC_TGT_F=['/c','/Fo'] - v.CXX_SRC_F='' - v.CXX_TGT_F=['/c','/Fo'] - if(v.MSVC_COMPILER=='msvc'and v.MSVC_VERSION>=8)or(v.MSVC_COMPILER=='wsdk'and v.MSVC_VERSION>=6): - v.CC_TGT_F=['/FC']+v.CC_TGT_F - v.CXX_TGT_F=['/FC']+v.CXX_TGT_F - v.CPPPATH_ST='/I%s' - v.AR_TGT_F=v.CCLNK_TGT_F=v.CXXLNK_TGT_F='/OUT:' - v.CFLAGS_CRT_MULTITHREADED=v.CXXFLAGS_CRT_MULTITHREADED=['/MT'] - v.CFLAGS_CRT_MULTITHREADED_DLL=v.CXXFLAGS_CRT_MULTITHREADED_DLL=['/MD'] - v.CFLAGS_CRT_MULTITHREADED_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DBG=['/MTd'] - v.CFLAGS_CRT_MULTITHREADED_DLL_DBG=v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG=['/MDd'] - v.LIB_ST='%s.lib' - v.LIBPATH_ST='/LIBPATH:%s' - v.STLIB_ST='%s.lib' - v.STLIBPATH_ST='/LIBPATH:%s' - if v.MSVC_MANIFEST: - v.append_value('LINKFLAGS',['/MANIFEST']) - v.CFLAGS_cshlib=[] - v.CXXFLAGS_cxxshlib=[] - v.LINKFLAGS_cshlib=v.LINKFLAGS_cxxshlib=['/DLL'] - v.cshlib_PATTERN=v.cxxshlib_PATTERN='%s.dll' - v.implib_PATTERN='%s.lib' - v.IMPLIB_ST='/IMPLIB:%s' - v.LINKFLAGS_cstlib=[] - v.cstlib_PATTERN=v.cxxstlib_PATTERN='%s.lib' - v.cprogram_PATTERN=v.cxxprogram_PATTERN='%s.exe' - v.def_PATTERN='/def:%s' -@after_method('apply_link') -@feature('c','cxx') -def apply_flags_msvc(self): - if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None): - return - is_static=isinstance(self.link_task,ccroot.stlink_task) - subsystem=getattr(self,'subsystem','') - if subsystem: - subsystem='/subsystem:%s'%subsystem - flags=is_static and'ARFLAGS'or'LINKFLAGS' - self.env.append_value(flags,subsystem) - if not is_static: - for f in self.env.LINKFLAGS: - d=f.lower() - if d[1:]in('debug','debug:full','debug:fastlink'): - pdbnode=self.link_task.outputs[0].change_ext('.pdb') - self.link_task.outputs.append(pdbnode) - if getattr(self,'install_task',None): - self.pdb_install_task=self.add_install_files(install_to=self.install_task.install_to,install_from=pdbnode) - break -@feature('cprogram','cshlib','cxxprogram','cxxshlib') -@after_method('apply_link') -def apply_manifest(self): - if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None): - out_node=self.link_task.outputs[0] - man_node=out_node.parent.find_or_declare(out_node.name+'.manifest') - self.link_task.outputs.append(man_node) - self.env.DO_MANIFEST=True -def make_winapp(self,family): - append=self.env.append_unique - append('DEFINES','WINAPI_FAMILY=%s'%family) - append('CXXFLAGS',['/ZW','/TP']) - for lib_path in self.env.LIBPATH: - append('CXXFLAGS','/AI%s'%lib_path) -@feature('winphoneapp') -@after_method('process_use') -@after_method('propagate_uselib_vars') -def make_winphone_app(self): - make_winapp(self,'WINAPI_FAMILY_PHONE_APP') - self.env.append_unique('LINKFLAGS',['/NODEFAULTLIB:ole32.lib','PhoneAppModelHost.lib']) -@feature('winapp') -@after_method('process_use') -@after_method('propagate_uselib_vars') -def make_windows_app(self): - make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py deleted file mode 100755 index 59067ed..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os -import waflib.Tools.asm -from waflib.TaskGen import feature -@feature('asm') -def apply_nasm_vars(self): - self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[]))) -def configure(conf): - conf.find_program(['nasm','yasm'],var='AS') - conf.env.AS_TGT_F=['-o'] - conf.env.ASLNK_TGT_F=['-o'] - conf.load('asm') - conf.env.ASMPATH_ST='-I%s'+os.sep - txt=conf.cmd_and_log(conf.env.AS+['--version']) - if'yasm'in txt.lower(): - conf.env.ASM_NAME='yasm' - else: - conf.env.ASM_NAME='nasm' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py deleted file mode 100755 index beb2217..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Task -def build(bld): - def run(self): - for x in self.outputs: - x.write('') - for(name,cls)in Task.classes.items(): - cls.run=run diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py deleted file mode 100755 index ee86113..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py +++ /dev/null @@ -1,85 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os -from waflib import Task,Options,Utils,Errors -from waflib.Configure import conf -from waflib.TaskGen import extension,feature,before_method -@before_method('apply_incpaths','apply_link','propagate_uselib_vars') -@feature('perlext') -def init_perlext(self): - self.uselib=self.to_list(getattr(self,'uselib',[])) - if not'PERLEXT'in self.uselib: - self.uselib.append('PERLEXT') - self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.perlext_PATTERN -@extension('.xs') -def xsubpp_file(self,node): - outnode=node.change_ext('.c') - self.create_task('xsubpp',node,outnode) - self.source.append(outnode) -class xsubpp(Task.Task): - run_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}' - color='BLUE' - ext_out=['.h'] -@conf -def check_perl_version(self,minver=None): - res=True - if minver: - cver='.'.join(map(str,minver)) - else: - cver='' - self.start_msg('Checking for minimum perl version %s'%cver) - perl=self.find_program('perl',var='PERL',value=getattr(Options.options,'perlbinary',None)) - version=self.cmd_and_log(perl+["-e",'printf \"%vd\", $^V']) - if not version: - res=False - version="Unknown" - elif not minver is None: - ver=tuple(map(int,version.split("."))) - if ver -#ifdef __cplusplus -extern "C" { -#endif - void Py_Initialize(void); - void Py_Finalize(void); -#ifdef __cplusplus -} -#endif -int main(int argc, char **argv) -{ - (void)argc; (void)argv; - Py_Initialize(); - Py_Finalize(); - return 0; -} -''' -INST=''' -import sys, py_compile -py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True) -''' -DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib'] -@before_method('process_source') -@feature('py') -def feature_py(self): - self.install_path=getattr(self,'install_path','${PYTHONDIR}') - install_from=getattr(self,'install_from',None) - if install_from and not isinstance(install_from,Node.Node): - install_from=self.path.find_dir(install_from) - self.install_from=install_from - ver=self.env.PYTHON_VERSION - if not ver: - self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version') - if int(ver.replace('.',''))>31: - self.install_32=True -@extension('.py') -def process_py(self,node): - assert(hasattr(self,'install_path')),'add features="py" for target "%s" in "%s/wscript".'%(self.target,self.path.nice_path()) - self.install_from=getattr(self,'install_from',None) - relative_trick=getattr(self,'relative_trick',True) - if self.install_from: - assert isinstance(self.install_from,Node.Node),'add features="py" for target "%s" in "%s/wscript" (%s).'%(self.target,self.path.nice_path(),type(self.install_from)) - if self.install_path: - if self.install_from: - self.add_install_files(install_to=self.install_path,install_from=node,cwd=self.install_from,relative_trick=relative_trick) - else: - self.add_install_files(install_to=self.install_path,install_from=node,relative_trick=relative_trick) - lst=[] - if self.env.PYC: - lst.append('pyc') - if self.env.PYO: - lst.append('pyo') - if self.install_path: - if self.install_from: - target_dir=node.path_from(self.install_from)if relative_trick else node.name - pyd=Utils.subst_vars("%s/%s"%(self.install_path,target_dir),self.env) - else: - target_dir=node.path_from(self.path)if relative_trick else node.name - pyd=Utils.subst_vars("%s/%s"%(self.install_path,target_dir),self.env) - else: - pyd=node.abspath() - for ext in lst: - if self.env.PYTAG and not self.env.NOPYCACHE: - name=node.name[:-3] - pyobj=node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s"%(name,self.env.PYTAG,ext)) - pyobj.parent.mkdir() - else: - pyobj=node.change_ext(".%s"%ext) - tsk=self.create_task(ext,node,pyobj) - tsk.pyd=pyd - if self.install_path: - self.add_install_files(install_to=os.path.dirname(pyd),install_from=pyobj,cwd=node.parent.get_bld(),relative_trick=relative_trick) -class pyc(Task.Task): - color='PINK' - def __str__(self): - node=self.outputs[0] - return node.path_from(node.ctx.launch_node()) - def run(self): - cmd=[Utils.subst_vars('${PYTHON}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd] - ret=self.generator.bld.exec_command(cmd) - return ret -class pyo(Task.Task): - color='PINK' - def __str__(self): - node=self.outputs[0] - return node.path_from(node.ctx.launch_node()) - def run(self): - cmd=[Utils.subst_vars('${PYTHON}',self.env),Utils.subst_vars('${PYFLAGS_OPT}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd] - ret=self.generator.bld.exec_command(cmd) - return ret -@feature('pyext') -@before_method('propagate_uselib_vars','apply_link') -@after_method('apply_bundle') -def init_pyext(self): - self.uselib=self.to_list(getattr(self,'uselib',[])) - if not'PYEXT'in self.uselib: - self.uselib.append('PYEXT') - self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN - self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN - try: - if not self.install_path: - return - except AttributeError: - self.install_path='${PYTHONARCHDIR}' -@feature('pyext') -@before_method('apply_link','apply_bundle') -def set_bundle(self): - if Utils.unversioned_sys_platform()=='darwin': - self.mac_bundle=True -@before_method('propagate_uselib_vars') -@feature('pyembed') -def init_pyembed(self): - self.uselib=self.to_list(getattr(self,'uselib',[])) - if not'PYEMBED'in self.uselib: - self.uselib.append('PYEMBED') -@conf -def get_python_variables(self,variables,imports=None): - if not imports: - try: - imports=self.python_imports - except AttributeError: - imports=DISTUTILS_IMP - program=list(imports) - program.append('') - for v in variables: - program.append("print(repr(%s))"%v) - os_env=dict(os.environ) - try: - del os_env['MACOSX_DEPLOYMENT_TARGET'] - except KeyError: - pass - try: - out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env) - except Errors.WafError: - self.fatal('The distutils module is unusable: install "python-devel"?') - self.to_log(out) - return_values=[] - for s in out.splitlines(): - s=s.strip() - if not s: - continue - if s=='None': - return_values.append(None) - elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'): - return_values.append(eval(s)) - elif s[0].isdigit(): - return_values.append(int(s)) - else:break - return return_values -@conf -def test_pyembed(self,mode,msg='Testing pyembed configuration'): - self.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg=msg,fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(mode,mode)) -@conf -def test_pyext(self,mode,msg='Testing pyext configuration'): - self.check(header_name='Python.h',define_name='HAVE_PYEXT',msg=msg,fragment=FRAG,errmsg='Could not build python extensions',features='%s %sshlib pyext'%(mode,mode)) -@conf -def python_cross_compile(self,features='pyembed pyext'): - features=Utils.to_list(features) - if not('PYTHON_LDFLAGS'in self.environ or'PYTHON_PYEXT_LDFLAGS'in self.environ or'PYTHON_PYEMBED_LDFLAGS'in self.environ): - return False - for x in'PYTHON_VERSION PYTAG pyext_PATTERN'.split(): - if not x in self.environ: - self.fatal('Please set %s in the os environment'%x) - else: - self.env[x]=self.environ[x] - xx=self.env.CXX_NAME and'cxx'or'c' - if'pyext'in features: - flags=self.environ.get('PYTHON_PYEXT_LDFLAGS',self.environ.get('PYTHON_LDFLAGS')) - if flags is None: - self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required') - else: - self.parse_flags(flags,'PYEXT') - self.test_pyext(xx) - if'pyembed'in features: - flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS')) - if flags is None: - self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required') - else: - self.parse_flags(flags,'PYEMBED') - self.test_pyembed(xx) - return True -@conf -def check_python_headers(conf,features='pyembed pyext'): - features=Utils.to_list(features) - assert('pyembed'in features)or('pyext'in features),"check_python_headers features must include 'pyembed' and/or 'pyext'" - env=conf.env - if not env.CC_NAME and not env.CXX_NAME: - conf.fatal('load a compiler first (gcc, g++, ..)') - if conf.python_cross_compile(features): - return - if not env.PYTHON_VERSION: - conf.check_python_version() - pybin=env.PYTHON - if not pybin: - conf.fatal('Could not find the python executable') - v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split() - try: - lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v]) - except RuntimeError: - conf.fatal("Python development headers not found (-v for details).") - vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)] - conf.to_log("Configuration returned from %r:\n%s\n"%(pybin,'\n'.join(vals))) - dct=dict(zip(v,lst)) - x='MACOSX_DEPLOYMENT_TARGET' - if dct[x]: - env[x]=conf.environ[x]=dct[x] - env.pyext_PATTERN='%s'+dct['SO'] - num='.'.join(env.PYTHON_VERSION.split('.')[:2]) - conf.find_program([''.join(pybin)+'-config','python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',msg="python-config",mandatory=False) - if env.PYTHON_CONFIG: - if conf.env.HAVE_PYTHON_H: - return - all_flags=[['--cflags','--libs','--ldflags']] - if sys.hexversion<0x2070000: - all_flags=[[k]for k in all_flags[0]] - xx=env.CXX_NAME and'cxx'or'c' - if'pyembed'in features: - for flags in all_flags: - embedflags=flags+['--embed'] - try: - conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(embedflags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=embedflags) - except conf.errors.ConfigurationError: - conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=flags) - try: - conf.test_pyembed(xx) - except conf.errors.ConfigurationError: - if dct['Py_ENABLE_SHARED']and dct['LIBDIR']: - env.append_unique('LIBPATH_PYEMBED',[dct['LIBDIR']]) - conf.test_pyembed(xx) - else: - raise - if'pyext'in features: - for flags in all_flags: - conf.check_cfg(msg='Asking python-config for pyext %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=flags) - try: - conf.test_pyext(xx) - except conf.errors.ConfigurationError: - if dct['Py_ENABLE_SHARED']and dct['LIBDIR']: - env.append_unique('LIBPATH_PYEXT',[dct['LIBDIR']]) - conf.test_pyext(xx) - else: - raise - conf.define('HAVE_PYTHON_H',1) - return - all_flags=dct['LDFLAGS']+' '+dct['CFLAGS'] - conf.parse_flags(all_flags,'PYEMBED') - all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS'] - conf.parse_flags(all_flags,'PYEXT') - result=None - if not dct["LDVERSION"]: - dct["LDVERSION"]=env.PYTHON_VERSION - for name in('python'+dct['LDVERSION'],'python'+env.PYTHON_VERSION+'m','python'+env.PYTHON_VERSION.replace('.','')): - if not result and env.LIBPATH_PYEMBED: - path=env.LIBPATH_PYEMBED - conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path) - result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name) - if not result and dct['LIBDIR']: - path=[dct['LIBDIR']] - conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path) - result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name) - if not result and dct['LIBPL']: - path=[dct['LIBPL']] - conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n") - result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name) - if not result: - path=[os.path.join(dct['prefix'],"libs")] - conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n") - result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name) - if result: - break - if result: - env.LIBPATH_PYEMBED=path - env.append_value('LIB_PYEMBED',[name]) - else: - conf.to_log("\n\n### LIB NOT FOUND\n") - if Utils.is_win32 or dct['Py_ENABLE_SHARED']: - env.LIBPATH_PYEXT=env.LIBPATH_PYEMBED - env.LIB_PYEXT=env.LIB_PYEMBED - conf.to_log("Include path for Python extensions (found via distutils module): %r\n"%(dct['INCLUDEPY'],)) - env.INCLUDES_PYEXT=[dct['INCLUDEPY']] - env.INCLUDES_PYEMBED=[dct['INCLUDEPY']] - if env.CC_NAME=='gcc': - env.append_unique('CFLAGS_PYEMBED',['-fno-strict-aliasing']) - env.append_unique('CFLAGS_PYEXT',['-fno-strict-aliasing']) - if env.CXX_NAME=='gcc': - env.append_unique('CXXFLAGS_PYEMBED',['-fno-strict-aliasing']) - env.append_unique('CXXFLAGS_PYEXT',['-fno-strict-aliasing']) - if env.CC_NAME=="msvc": - from distutils.msvccompiler import MSVCCompiler - dist_compiler=MSVCCompiler() - dist_compiler.initialize() - env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options) - env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options) - env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared) - conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg='Distutils not installed? Broken python installation? Get python-config now!') -@conf -def check_python_version(conf,minver=None): - assert minver is None or isinstance(minver,tuple) - pybin=conf.env.PYTHON - if not pybin: - conf.fatal('could not find the python executable') - cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))'] - Logs.debug('python: Running python command %r',cmd) - lines=conf.cmd_and_log(cmd).split() - assert len(lines)==5,"found %r lines, expected 5: %r"%(len(lines),lines) - pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4])) - result=(minver is None)or(pyver_tuple>=minver) - if result: - pyver='.'.join([str(x)for x in pyver_tuple[:2]]) - conf.env.PYTHON_VERSION=pyver - if'PYTHONDIR'in conf.env: - pydir=conf.env.PYTHONDIR - elif'PYTHONDIR'in conf.environ: - pydir=conf.environ['PYTHONDIR'] - else: - if Utils.is_win32: - (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"]) - else: - python_LIBDEST=None - (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX]) - if python_LIBDEST is None: - if conf.env.LIBDIR: - python_LIBDEST=os.path.join(conf.env.LIBDIR,'python'+pyver) - else: - python_LIBDEST=os.path.join(conf.env.PREFIX,'lib','python'+pyver) - if'PYTHONARCHDIR'in conf.env: - pyarchdir=conf.env.PYTHONARCHDIR - elif'PYTHONARCHDIR'in conf.environ: - pyarchdir=conf.environ['PYTHONARCHDIR'] - else: - (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env.PREFIX]) - if not pyarchdir: - pyarchdir=pydir - if hasattr(conf,'define'): - conf.define('PYTHONDIR',pydir) - conf.define('PYTHONARCHDIR',pyarchdir) - conf.env.PYTHONDIR=pydir - conf.env.PYTHONARCHDIR=pyarchdir - pyver_full='.'.join(map(str,pyver_tuple[:3])) - if minver is None: - conf.msg('Checking for python version',pyver_full) - else: - minver_str='.'.join(map(str,minver)) - conf.msg('Checking for python version >= %s'%(minver_str,),pyver_full,color=result and'GREEN'or'YELLOW') - if not result: - conf.fatal('The python version is too old, expecting %r'%(minver,)) -PYTHON_MODULE_TEMPLATE=''' -import %s as current_module -version = getattr(current_module, '__version__', None) -if version is not None: - print(str(version)) -else: - print('unknown version') -''' -@conf -def check_python_module(conf,module_name,condition=''): - msg="Checking for python module %r"%module_name - if condition: - msg='%s (%s)'%(msg,condition) - conf.start_msg(msg) - try: - ret=conf.cmd_and_log(conf.env.PYTHON+['-c',PYTHON_MODULE_TEMPLATE%module_name]) - except Errors.WafError: - conf.end_msg(False) - conf.fatal('Could not find the python module %r'%module_name) - ret=ret.strip() - if condition: - conf.end_msg(ret) - if ret=='unknown version': - conf.fatal('Could not check the %s version'%module_name) - from distutils.version import LooseVersion - def num(*k): - if isinstance(k[0],int): - return LooseVersion('.'.join([str(x)for x in k])) - else: - return LooseVersion(k[0]) - d={'num':num,'ver':LooseVersion(ret)} - ev=eval(condition,{},d) - if not ev: - conf.fatal('The %s version does not satisfy the requirements'%module_name) - else: - if ret=='unknown version': - conf.end_msg(True) - else: - conf.end_msg(ret) -def configure(conf): - v=conf.env - if getattr(Options.options,'pythondir',None): - v.PYTHONDIR=Options.options.pythondir - if getattr(Options.options,'pythonarchdir',None): - v.PYTHONARCHDIR=Options.options.pythonarchdir - if getattr(Options.options,'nopycache',None): - v.NOPYCACHE=Options.options.nopycache - if not v.PYTHON: - v.PYTHON=[getattr(Options.options,'python',None)or sys.executable] - v.PYTHON=Utils.to_list(v.PYTHON) - conf.find_program('python',var='PYTHON') - v.PYFLAGS='' - v.PYFLAGS_OPT='-O' - v.PYC=getattr(Options.options,'pyc',1) - v.PYO=getattr(Options.options,'pyo',1) - try: - v.PYTAG=conf.cmd_and_log(conf.env.PYTHON+['-c',"import imp;print(imp.get_tag())"]).strip() - except Errors.WafError: - pass -def options(opt): - pyopt=opt.add_option_group("Python Options") - pyopt.add_option('--nopyc',dest='pyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]') - pyopt.add_option('--nopyo',dest='pyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]') - pyopt.add_option('--nopycache',dest='nopycache',action='store_true',help='Do not use __pycache__ directory to install objects [Default:auto]') - pyopt.add_option('--python',dest="python",help='python binary to be used [Default: %s]'%sys.executable) - pyopt.add_option('--pythondir',dest='pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)') - pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py deleted file mode 100755 index ea97019..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py +++ /dev/null @@ -1,499 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from __future__ import with_statement -try: - from xml.sax import make_parser - from xml.sax.handler import ContentHandler -except ImportError: - has_xml=False - ContentHandler=object -else: - has_xml=True -import os,sys,re -from waflib.Tools import cxx -from waflib import Build,Task,Utils,Options,Errors,Context -from waflib.TaskGen import feature,after_method,extension,before_method -from waflib.Configure import conf -from waflib import Logs -MOC_H=['.h','.hpp','.hxx','.hh'] -EXT_RCC=['.qrc'] -EXT_UI=['.ui'] -EXT_QT5=['.cpp','.cc','.cxx','.C'] -class qxx(Task.classes['cxx']): - def __init__(self,*k,**kw): - Task.Task.__init__(self,*k,**kw) - self.moc_done=0 - def runnable_status(self): - if self.moc_done: - return Task.Task.runnable_status(self) - else: - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - self.add_moc_tasks() - return Task.Task.runnable_status(self) - def create_moc_task(self,h_node,m_node): - try: - moc_cache=self.generator.bld.moc_cache - except AttributeError: - moc_cache=self.generator.bld.moc_cache={} - try: - return moc_cache[h_node] - except KeyError: - tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator) - tsk.set_inputs(h_node) - tsk.set_outputs(m_node) - tsk.env.append_unique('MOC_FLAGS','-i') - if self.generator: - self.generator.tasks.append(tsk) - gen=self.generator.bld.producer - gen.outstanding.append(tsk) - gen.total+=1 - return tsk - else: - delattr(self,'cache_sig') - def add_moc_tasks(self): - node=self.inputs[0] - bld=self.generator.bld - if bld.is_install==Build.UNINSTALL: - return - try: - self.signature() - except KeyError: - pass - else: - delattr(self,'cache_sig') - include_nodes=[node.parent]+self.generator.includes_nodes - moctasks=[] - mocfiles=set() - for d in bld.raw_deps.get(self.uid(),[]): - if not d.endswith('.moc'): - continue - if d in mocfiles: - continue - mocfiles.add(d) - h_node=None - base2=d[:-4] - prefix=node.name[:node.name.rfind('.')] - if base2==prefix: - h_node=node - else: - for x in include_nodes: - for e in MOC_H: - h_node=x.find_node(base2+e) - if h_node: - break - else: - continue - break - if h_node: - m_node=h_node.change_ext('.moc') - else: - raise Errors.WafError('No source found for %r which is a moc file'%d) - task=self.create_moc_task(h_node,m_node) - moctasks.append(task) - self.run_after.update(set(moctasks)) - self.moc_done=1 -class trans_update(Task.Task): - run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}' - color='BLUE' -class XMLHandler(ContentHandler): - def __init__(self): - ContentHandler.__init__(self) - self.buf=[] - self.files=[] - def startElement(self,name,attrs): - if name=='file': - self.buf=[] - def endElement(self,name): - if name=='file': - self.files.append(str(''.join(self.buf))) - def characters(self,cars): - self.buf.append(cars) -@extension(*EXT_RCC) -def create_rcc_task(self,node): - rcnode=node.change_ext('_rc.%d.cpp'%self.idx) - self.create_task('rcc',node,rcnode) - cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o')) - try: - self.compiled_tasks.append(cpptask) - except AttributeError: - self.compiled_tasks=[cpptask] - return cpptask -@extension(*EXT_UI) -def create_uic_task(self,node): - try: - uic_cache=self.bld.uic_cache - except AttributeError: - uic_cache=self.bld.uic_cache={} - if node not in uic_cache: - uictask=uic_cache[node]=self.create_task('ui5',node) - uictask.outputs=[node.parent.find_or_declare(self.env.ui_PATTERN%node.name[:-3])] -@extension('.ts') -def add_lang(self,node): - self.lang=self.to_list(getattr(self,'lang',[]))+[node] -@feature('qt5') -@before_method('process_source') -def process_mocs(self): - lst=self.to_nodes(getattr(self,'moc',[])) - self.source=self.to_list(getattr(self,'source',[])) - for x in lst: - prefix=x.name[:x.name.rfind('.')] - moc_target='moc_%s.%d.cpp'%(prefix,self.idx) - moc_node=x.parent.find_or_declare(moc_target) - self.source.append(moc_node) - self.create_task('moc',x,moc_node) -@feature('qt5') -@after_method('apply_link') -def apply_qt5(self): - if getattr(self,'lang',None): - qmtasks=[] - for x in self.to_list(self.lang): - if isinstance(x,str): - x=self.path.find_resource(x+'.ts') - qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.%d.qm'%self.idx))) - if getattr(self,'update',None)and Options.options.trans_qt5: - cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if a.inputs and a.inputs[0].name.endswith('.ui')] - for x in qmtasks: - self.create_task('trans_update',cxxnodes,x.inputs) - if getattr(self,'langname',None): - qmnodes=[x.outputs[0]for x in qmtasks] - rcnode=self.langname - if isinstance(rcnode,str): - rcnode=self.path.find_or_declare(rcnode+('.%d.qrc'%self.idx)) - t=self.create_task('qm2rcc',qmnodes,rcnode) - k=create_rcc_task(self,t.outputs[0]) - self.link_task.inputs.append(k.outputs[0]) - lst=[] - for flag in self.to_list(self.env.CXXFLAGS): - if len(flag)<2: - continue - f=flag[0:2] - if f in('-D','-I','/D','/I'): - if(f[0]=='/'): - lst.append('-'+flag[1:]) - else: - lst.append(flag) - self.env.append_value('MOC_FLAGS',lst) -@extension(*EXT_QT5) -def cxx_hook(self,node): - return self.create_compiled_task('qxx',node) -class rcc(Task.Task): - color='BLUE' - run_str='${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' - ext_out=['.h'] - def rcname(self): - return os.path.splitext(self.inputs[0].name)[0] - def scan(self): - if not has_xml: - Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') - return([],[]) - parser=make_parser() - curHandler=XMLHandler() - parser.setContentHandler(curHandler) - with open(self.inputs[0].abspath(),'r')as f: - parser.parse(f) - nodes=[] - names=[] - root=self.inputs[0].parent - for x in curHandler.files: - nd=root.find_resource(x) - if nd: - nodes.append(nd) - else: - names.append(x) - return(nodes,names) - def quote_flag(self,x): - return x -class moc(Task.Task): - color='BLUE' - run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' - def quote_flag(self,x): - return x -class ui5(Task.Task): - color='BLUE' - run_str='${QT_UIC} ${SRC} -o ${TGT}' - ext_out=['.h'] -class ts2qm(Task.Task): - color='BLUE' - run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' -class qm2rcc(Task.Task): - color='BLUE' - after='ts2qm' - def run(self): - txt='\n'.join(['%s'%k.path_from(self.outputs[0].parent)for k in self.inputs]) - code='\n\n%s\n\n'%txt - self.outputs[0].write(code) -def configure(self): - self.find_qt5_binaries() - self.set_qt5_libs_dir() - self.set_qt5_libs_to_check() - self.set_qt5_defines() - self.find_qt5_libraries() - self.add_qt5_rpath() - self.simplify_qt5_libs() - if not has_xml: - Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') - if'COMPILER_CXX'not in self.env: - self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?') - frag='#include \nint main(int argc, char **argv) {return 0;}\n' - uses='QT5CORE QT5WIDGETS QT5GUI' - for flag in[[],'-fPIE','-fPIC','-std=c++11',['-std=c++11','-fPIE'],['-std=c++11','-fPIC']]: - msg='See if Qt files compile ' - if flag: - msg+='with %s'%flag - try: - self.check(features='qt5 cxx',use=uses,uselib_store='qt5',cxxflags=flag,fragment=frag,msg=msg) - except self.errors.ConfigurationError: - pass - else: - break - else: - self.fatal('Could not build a simple Qt application') - if Utils.unversioned_sys_platform()=='freebsd': - frag='#include \nint main(int argc, char **argv) { QApplication app(argc, argv); return NULL != (void*) (&app);}\n' - try: - self.check(features='qt5 cxx cxxprogram',use=uses,fragment=frag,msg='Can we link Qt programs on FreeBSD directly?') - except self.errors.ConfigurationError: - self.check(features='qt5 cxx cxxprogram',use=uses,uselib_store='qt5',libpath='/usr/local/lib',fragment=frag,msg='Is /usr/local/lib required?') -@conf -def find_qt5_binaries(self): - env=self.env - opt=Options.options - qtdir=getattr(opt,'qtdir','') - qtbin=getattr(opt,'qtbin','') - paths=[] - if qtdir: - qtbin=os.path.join(qtdir,'bin') - if not qtdir: - qtdir=self.environ.get('QT5_ROOT','') - qtbin=self.environ.get('QT5_BIN')or os.path.join(qtdir,'bin') - if qtbin: - paths=[qtbin] - if not qtdir: - paths=self.environ.get('PATH','').split(os.pathsep) - paths.extend(['/usr/share/qt5/bin','/usr/local/lib/qt5/bin']) - try: - lst=Utils.listdir('/usr/local/Trolltech/') - except OSError: - pass - else: - if lst: - lst.sort() - lst.reverse() - qtdir='/usr/local/Trolltech/%s/'%lst[0] - qtbin=os.path.join(qtdir,'bin') - paths.append(qtbin) - cand=None - prev_ver=['5','0','0'] - for qmk in('qmake-qt5','qmake5','qmake'): - try: - qmake=self.find_program(qmk,path_list=paths) - except self.errors.ConfigurationError: - pass - else: - try: - version=self.cmd_and_log(qmake+['-query','QT_VERSION']).strip() - except self.errors.WafError: - pass - else: - if version: - new_ver=version.split('.') - if new_ver>prev_ver: - cand=qmake - prev_ver=new_ver - if not cand: - try: - self.find_program('qtchooser') - except self.errors.ConfigurationError: - pass - else: - cmd=self.env.QTCHOOSER+['-qt=5','-run-tool=qmake'] - try: - version=self.cmd_and_log(cmd+['-query','QT_VERSION']) - except self.errors.WafError: - pass - else: - cand=cmd - if cand: - self.env.QMAKE=cand - else: - self.fatal('Could not find qmake for qt5') - self.env.QT_HOST_BINS=qtbin=self.cmd_and_log(self.env.QMAKE+['-query','QT_HOST_BINS']).strip() - paths.insert(0,qtbin) - def find_bin(lst,var): - if var in env: - return - for f in lst: - try: - ret=self.find_program(f,path_list=paths) - except self.errors.ConfigurationError: - pass - else: - env[var]=ret - break - find_bin(['uic-qt5','uic'],'QT_UIC') - if not env.QT_UIC: - self.fatal('cannot find the uic compiler for qt5') - self.start_msg('Checking for uic version') - uicver=self.cmd_and_log(env.QT_UIC+['-version'],output=Context.BOTH) - uicver=''.join(uicver).strip() - uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','') - self.end_msg(uicver) - if uicver.find(' 3.')!=-1 or uicver.find(' 4.')!=-1: - self.fatal('this uic compiler is for qt3 or qt4, add uic for qt5 to your path') - find_bin(['moc-qt5','moc'],'QT_MOC') - find_bin(['rcc-qt5','rcc'],'QT_RCC') - find_bin(['lrelease-qt5','lrelease'],'QT_LRELEASE') - find_bin(['lupdate-qt5','lupdate'],'QT_LUPDATE') - env.UIC_ST='%s -o %s' - env.MOC_ST='-o' - env.ui_PATTERN='ui_%s.h' - env.QT_LRELEASE_FLAGS=['-silent'] - env.MOCCPPPATH_ST='-I%s' - env.MOCDEFINES_ST='-D%s' -@conf -def set_qt5_libs_dir(self): - env=self.env - qtlibs=getattr(Options.options,'qtlibs',None)or self.environ.get('QT5_LIBDIR') - if not qtlibs: - try: - qtlibs=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_LIBS']).strip() - except Errors.WafError: - qtdir=self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_PREFIX']).strip() - qtlibs=os.path.join(qtdir,'lib') - self.msg('Found the Qt5 libraries in',qtlibs) - env.QTLIBS=qtlibs -@conf -def find_single_qt5_lib(self,name,uselib,qtlibs,qtincludes,force_static): - env=self.env - if force_static: - exts=('.a','.lib') - prefix='STLIB' - else: - exts=('.so','.lib') - prefix='LIB' - def lib_names(): - for x in exts: - for k in('','5')if Utils.is_win32 else['']: - for p in('lib',''): - yield(p,name,k,x) - for tup in lib_names(): - k=''.join(tup) - path=os.path.join(qtlibs,k) - if os.path.exists(path): - if env.DEST_OS=='win32': - libval=''.join(tup[:-1]) - else: - libval=name - env.append_unique(prefix+'_'+uselib,libval) - env.append_unique('%sPATH_%s'%(prefix,uselib),qtlibs) - env.append_unique('INCLUDES_'+uselib,qtincludes) - env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,name.replace('Qt5','Qt'))) - return k - return False -@conf -def find_qt5_libraries(self): - env=self.env - qtincludes=self.environ.get('QT5_INCLUDES')or self.cmd_and_log(env.QMAKE+['-query','QT_INSTALL_HEADERS']).strip() - force_static=self.environ.get('QT5_FORCE_STATIC') - try: - if self.environ.get('QT5_XCOMPILE'): - self.fatal('QT5_XCOMPILE Disables pkg-config detection') - self.check_cfg(atleast_pkgconfig_version='0.1') - except self.errors.ConfigurationError: - for i in self.qt5_vars: - uselib=i.upper() - if Utils.unversioned_sys_platform()=='darwin': - fwk=i.replace('Qt5','Qt') - frameworkName=fwk+'.framework' - qtDynamicLib=os.path.join(env.QTLIBS,frameworkName,fwk) - if os.path.exists(qtDynamicLib): - env.append_unique('FRAMEWORK_'+uselib,fwk) - env.append_unique('FRAMEWORKPATH_'+uselib,env.QTLIBS) - self.msg('Checking for %s'%i,qtDynamicLib,'GREEN') - else: - self.msg('Checking for %s'%i,False,'YELLOW') - env.append_unique('INCLUDES_'+uselib,os.path.join(env.QTLIBS,frameworkName,'Headers')) - else: - ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,force_static) - if not force_static and not ret: - ret=self.find_single_qt5_lib(i,uselib,env.QTLIBS,qtincludes,True) - self.msg('Checking for %s'%i,ret,'GREEN'if ret else'YELLOW') - else: - path='%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib'%(self.environ.get('PKG_CONFIG_PATH',''),env.QTLIBS,env.QTLIBS) - for i in self.qt5_vars: - self.check_cfg(package=i,args='--cflags --libs',mandatory=False,force_static=force_static,pkg_config_path=path) -@conf -def simplify_qt5_libs(self): - env=self.env - def process_lib(vars_,coreval): - for d in vars_: - var=d.upper() - if var=='QTCORE': - continue - value=env['LIBPATH_'+var] - if value: - core=env[coreval] - accu=[] - for lib in value: - if lib in core: - continue - accu.append(lib) - env['LIBPATH_'+var]=accu - process_lib(self.qt5_vars,'LIBPATH_QTCORE') -@conf -def add_qt5_rpath(self): - env=self.env - if getattr(Options.options,'want_rpath',False): - def process_rpath(vars_,coreval): - for d in vars_: - var=d.upper() - value=env['LIBPATH_'+var] - if value: - core=env[coreval] - accu=[] - for lib in value: - if var!='QTCORE': - if lib in core: - continue - accu.append('-Wl,--rpath='+lib) - env['RPATH_'+var]=accu - process_rpath(self.qt5_vars,'LIBPATH_QTCORE') -@conf -def set_qt5_libs_to_check(self): - self.qt5_vars=Utils.to_list(getattr(self,'qt5_vars',[])) - if not self.qt5_vars: - dirlst=Utils.listdir(self.env.QTLIBS) - pat=self.env.cxxshlib_PATTERN - if Utils.is_win32: - pat=pat.replace('.dll','.lib') - if self.environ.get('QT5_FORCE_STATIC'): - pat=self.env.cxxstlib_PATTERN - if Utils.unversioned_sys_platform()=='darwin': - pat=r"%s\.framework" - re_qt=re.compile(pat%'Qt5?(?P.*)'+'$') - for x in dirlst: - m=re_qt.match(x) - if m: - self.qt5_vars.append("Qt5%s"%m.group('name')) - if not self.qt5_vars: - self.fatal('cannot find any Qt5 library (%r)'%self.env.QTLIBS) - qtextralibs=getattr(Options.options,'qtextralibs',None) - if qtextralibs: - self.qt5_vars.extend(qtextralibs.split(',')) -@conf -def set_qt5_defines(self): - if sys.platform!='win32': - return - for x in self.qt5_vars: - y=x.replace('Qt5','Qt')[2:].upper() - self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y) -def options(opt): - opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries') - for i in'qtdir qtbin qtlibs'.split(): - opt.add_option('--'+i,type='string',default='',dest=i) - opt.add_option('--translate',action='store_true',help='collect translation strings',dest='trans_qt5',default=False) - opt.add_option('--qtextralibs',type='string',default='',dest='qtextralibs',help='additional qt libraries on the system to add to default ones, comma separated') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py deleted file mode 100755 index 887234f..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py +++ /dev/null @@ -1,97 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os -from waflib import Errors,Options,Task,Utils -from waflib.TaskGen import before_method,feature,extension -from waflib.Configure import conf -@feature('rubyext') -@before_method('apply_incpaths','process_source','apply_bundle','apply_link') -def init_rubyext(self): - self.install_path='${ARCHDIR_RUBY}' - self.uselib=self.to_list(getattr(self,'uselib','')) - if not'RUBY'in self.uselib: - self.uselib.append('RUBY') - if not'RUBYEXT'in self.uselib: - self.uselib.append('RUBYEXT') -@feature('rubyext') -@before_method('apply_link','propagate_uselib_vars') -def apply_ruby_so_name(self): - self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.rubyext_PATTERN -@conf -def check_ruby_version(self,minver=()): - ruby=self.find_program('ruby',var='RUBY',value=Options.options.rubybinary) - try: - version=self.cmd_and_log(ruby+['-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip() - except Errors.WafError: - self.fatal('could not determine ruby version') - self.env.RUBY_VERSION=version - try: - ver=tuple(map(int,version.split('.'))) - except Errors.WafError: - self.fatal('unsupported ruby version %r'%version) - cver='' - if minver: - cver='> '+'.'.join(str(x)for x in minver) - if ver=(1,9,0): - ruby_hdrdir=read_config('rubyhdrdir') - cpppath+=ruby_hdrdir - if version>=(2,0,0): - cpppath+=read_config('rubyarchhdrdir') - cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])] - self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file',link_header_test=False) - self.env.LIBPATH_RUBYEXT=read_config('libdir') - self.env.LIBPATH_RUBYEXT+=archdir - self.env.INCLUDES_RUBYEXT=cpppath - self.env.CFLAGS_RUBYEXT=read_config('CCDLFLAGS') - self.env.rubyext_PATTERN='%s.'+read_config('DLEXT')[0] - flags=read_config('LDSHARED') - while flags and flags[0][0]!='-': - flags=flags[1:] - if len(flags)>1 and flags[1]=="ppc": - flags=flags[2:] - self.env.LINKFLAGS_RUBYEXT=flags - self.env.LINKFLAGS_RUBYEXT+=read_config('LIBS') - self.env.LINKFLAGS_RUBYEXT+=read_config('LIBRUBYARG_SHARED') - if Options.options.rubyarchdir: - self.env.ARCHDIR_RUBY=Options.options.rubyarchdir - else: - self.env.ARCHDIR_RUBY=read_config('sitearchdir')[0] - if Options.options.rubylibdir: - self.env.LIBDIR_RUBY=Options.options.rubylibdir - else: - self.env.LIBDIR_RUBY=read_config('sitelibdir')[0] -@conf -def check_ruby_module(self,module_name): - self.start_msg('Ruby module %s'%module_name) - try: - self.cmd_and_log(self.env.RUBY+['-e','require \'%s\';puts 1'%module_name]) - except Errors.WafError: - self.end_msg(False) - self.fatal('Could not find the ruby module %r'%module_name) - self.end_msg(True) -@extension('.rb') -def process(self,node): - return self.create_task('run_ruby',node) -class run_ruby(Task.Task): - run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}' -def options(opt): - opt.add_option('--with-ruby-archdir',type='string',dest='rubyarchdir',help='Specify directory where to install arch specific files') - opt.add_option('--with-ruby-libdir',type='string',dest='rubylibdir',help='Specify alternate ruby library path') - opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py deleted file mode 100755 index 676c884..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py +++ /dev/null @@ -1,48 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Errors -from waflib.Tools import ccroot,ar -from waflib.Configure import conf -@conf -def find_scc(conf): - v=conf.env - cc=conf.find_program('cc',var='CC') - try: - conf.cmd_and_log(cc+['-flags']) - except Errors.WafError: - conf.fatal('%r is not a Sun compiler'%cc) - v.CC_NAME='sun' - conf.get_suncc_version(cc) -@conf -def scc_common_flags(conf): - v=conf.env - v.CC_SRC_F=[] - v.CC_TGT_F=['-c','-o',''] - if not v.LINK_CC: - v.LINK_CC=v.CC - v.CCLNK_SRC_F='' - v.CCLNK_TGT_F=['-o',''] - v.CPPPATH_ST='-I%s' - v.DEFINES_ST='-D%s' - v.LIB_ST='-l%s' - v.LIBPATH_ST='-L%s' - v.STLIB_ST='-l%s' - v.STLIBPATH_ST='-L%s' - v.SONAME_ST='-Wl,-h,%s' - v.SHLIB_MARKER='-Bdynamic' - v.STLIB_MARKER='-Bstatic' - v.cprogram_PATTERN='%s' - v.CFLAGS_cshlib=['-xcode=pic32','-DPIC'] - v.LINKFLAGS_cshlib=['-G'] - v.cshlib_PATTERN='lib%s.so' - v.LINKFLAGS_cstlib=['-Bstatic'] - v.cstlib_PATTERN='lib%s.a' -def configure(conf): - conf.find_scc() - conf.find_ar() - conf.scc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py deleted file mode 100755 index 0047098..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py +++ /dev/null @@ -1,48 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib import Errors -from waflib.Tools import ccroot,ar -from waflib.Configure import conf -@conf -def find_sxx(conf): - v=conf.env - cc=conf.find_program(['CC','c++'],var='CXX') - try: - conf.cmd_and_log(cc+['-flags']) - except Errors.WafError: - conf.fatal('%r is not a Sun compiler'%cc) - v.CXX_NAME='sun' - conf.get_suncc_version(cc) -@conf -def sxx_common_flags(conf): - v=conf.env - v.CXX_SRC_F=[] - v.CXX_TGT_F=['-c','-o',''] - if not v.LINK_CXX: - v.LINK_CXX=v.CXX - v.CXXLNK_SRC_F=[] - v.CXXLNK_TGT_F=['-o',''] - v.CPPPATH_ST='-I%s' - v.DEFINES_ST='-D%s' - v.LIB_ST='-l%s' - v.LIBPATH_ST='-L%s' - v.STLIB_ST='-l%s' - v.STLIBPATH_ST='-L%s' - v.SONAME_ST='-Wl,-h,%s' - v.SHLIB_MARKER='-Bdynamic' - v.STLIB_MARKER='-Bstatic' - v.cxxprogram_PATTERN='%s' - v.CXXFLAGS_cxxshlib=['-xcode=pic32','-DPIC'] - v.LINKFLAGS_cxxshlib=['-G'] - v.cxxshlib_PATTERN='lib%s.so' - v.LINKFLAGS_cxxstlib=['-Bstatic'] - v.cxxstlib_PATTERN='lib%s.a' -def configure(conf): - conf.find_sxx() - conf.find_ar() - conf.sxx_common_flags() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py deleted file mode 100755 index 3a208d8..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py +++ /dev/null @@ -1,327 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re -from waflib import Utils,Task,Errors,Logs,Node -from waflib.TaskGen import feature,before_method -re_bibunit=re.compile(r'\\(?Pputbib)\[(?P[^\[\]]*)\]',re.M) -def bibunitscan(self): - node=self.inputs[0] - nodes=[] - if not node: - return nodes - code=node.read() - for match in re_bibunit.finditer(code): - path=match.group('file') - if path: - found=None - for k in('','.bib'): - Logs.debug('tex: trying %s%s',path,k) - fi=node.parent.find_resource(path+k) - if fi: - found=True - nodes.append(fi) - if not found: - Logs.debug('tex: could not find %s',path) - Logs.debug('tex: found the following bibunit files: %s',nodes) - return nodes -exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps','.sty'] -exts_tex=['.ltx','.tex'] -re_tex=re.compile(r'\\(?Pusepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P[^{}]*)}',re.M) -g_bibtex_re=re.compile('bibdata',re.M) -g_glossaries_re=re.compile('\\@newglossary',re.M) -class tex(Task.Task): - bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False) - bibtex_fun.__doc__=""" - Execute the program **bibtex** - """ - makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False) - makeindex_fun.__doc__=""" - Execute the program **makeindex** - """ - makeglossaries_fun,_=Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}',shell=False) - makeglossaries_fun.__doc__=""" - Execute the program **makeglossaries** - """ - def exec_command(self,cmd,**kw): - if self.env.PROMPT_LATEX: - kw['stdout']=kw['stderr']=None - return super(tex,self).exec_command(cmd,**kw) - def scan_aux(self,node): - nodes=[node] - re_aux=re.compile(r'\\@input{(?P[^{}]*)}',re.M) - def parse_node(node): - code=node.read() - for match in re_aux.finditer(code): - path=match.group('file') - found=node.parent.find_or_declare(path) - if found and found not in nodes: - Logs.debug('tex: found aux node %r',found) - nodes.append(found) - parse_node(found) - parse_node(node) - return nodes - def scan(self): - node=self.inputs[0] - nodes=[] - names=[] - seen=[] - if not node: - return(nodes,names) - def parse_node(node): - if node in seen: - return - seen.append(node) - code=node.read() - for match in re_tex.finditer(code): - multibib=match.group('type') - if multibib and multibib.startswith('bibliography'): - multibib=multibib[len('bibliography'):] - if multibib.startswith('style'): - continue - else: - multibib=None - for path in match.group('file').split(','): - if path: - add_name=True - found=None - for k in exts_deps_tex: - for up in self.texinputs_nodes: - Logs.debug('tex: trying %s%s',path,k) - found=up.find_resource(path+k) - if found: - break - for tsk in self.generator.tasks: - if not found or found in tsk.outputs: - break - else: - nodes.append(found) - add_name=False - for ext in exts_tex: - if found.name.endswith(ext): - parse_node(found) - break - if found and multibib and found.name.endswith('.bib'): - try: - self.multibibs.append(found) - except AttributeError: - self.multibibs=[found] - if add_name: - names.append(path) - parse_node(node) - for x in nodes: - x.parent.get_bld().mkdir() - Logs.debug("tex: found the following : %s and names %s",nodes,names) - return(nodes,names) - def check_status(self,msg,retcode): - if retcode!=0: - raise Errors.WafError('%r command exit status %r'%(msg,retcode)) - def info(self,*k,**kw): - try: - info=self.generator.bld.conf.logger.info - except AttributeError: - info=Logs.info - info(*k,**kw) - def bibfile(self): - for aux_node in self.aux_nodes: - try: - ct=aux_node.read() - except EnvironmentError: - Logs.error('Error reading %s: %r',aux_node.abspath()) - continue - if g_bibtex_re.findall(ct): - self.info('calling bibtex') - self.env.env={} - self.env.env.update(os.environ) - self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}) - self.env.SRCFILE=aux_node.name[:-4] - self.check_status('error when calling bibtex',self.bibtex_fun()) - for node in getattr(self,'multibibs',[]): - self.env.env={} - self.env.env.update(os.environ) - self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}) - self.env.SRCFILE=node.name[:-4] - self.check_status('error when calling bibtex',self.bibtex_fun()) - def bibunits(self): - try: - bibunits=bibunitscan(self) - except OSError: - Logs.error('error bibunitscan') - else: - if bibunits: - fn=['bu'+str(i)for i in range(1,len(bibunits)+1)] - if fn: - self.info('calling bibtex on bibunits') - for f in fn: - self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()} - self.env.SRCFILE=f - self.check_status('error when calling bibtex',self.bibtex_fun()) - def makeindex(self): - self.idx_node=self.inputs[0].change_ext('.idx') - try: - idx_path=self.idx_node.abspath() - os.stat(idx_path) - except OSError: - self.info('index file %s absent, not calling makeindex',idx_path) - else: - self.info('calling makeindex') - self.env.SRCFILE=self.idx_node.name - self.env.env={} - self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun()) - def bibtopic(self): - p=self.inputs[0].parent.get_bld() - if os.path.exists(os.path.join(p.abspath(),'btaux.aux')): - self.aux_nodes+=p.ant_glob('*[0-9].aux') - def makeglossaries(self): - src_file=self.inputs[0].abspath() - base_file=os.path.basename(src_file) - base,_=os.path.splitext(base_file) - for aux_node in self.aux_nodes: - try: - ct=aux_node.read() - except EnvironmentError: - Logs.error('Error reading %s: %r',aux_node.abspath()) - continue - if g_glossaries_re.findall(ct): - if not self.env.MAKEGLOSSARIES: - raise Errors.WafError("The program 'makeglossaries' is missing!") - Logs.warn('calling makeglossaries') - self.env.SRCFILE=base - self.check_status('error when calling makeglossaries %s'%base,self.makeglossaries_fun()) - return - def texinputs(self): - return os.pathsep.join([k.abspath()for k in self.texinputs_nodes])+os.pathsep - def run(self): - env=self.env - if not env.PROMPT_LATEX: - env.append_value('LATEXFLAGS','-interaction=batchmode') - env.append_value('PDFLATEXFLAGS','-interaction=batchmode') - env.append_value('XELATEXFLAGS','-interaction=batchmode') - self.cwd=self.inputs[0].parent.get_bld() - self.info('first pass on %s',self.__class__.__name__) - cur_hash=self.hash_aux_nodes() - self.call_latex() - self.hash_aux_nodes() - self.bibtopic() - self.bibfile() - self.bibunits() - self.makeindex() - self.makeglossaries() - for i in range(10): - prev_hash=cur_hash - cur_hash=self.hash_aux_nodes() - if not cur_hash: - Logs.error('No aux.h to process') - if cur_hash and cur_hash==prev_hash: - break - self.info('calling %s',self.__class__.__name__) - self.call_latex() - def hash_aux_nodes(self): - try: - self.aux_nodes - except AttributeError: - try: - self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux')) - except IOError: - return None - return Utils.h_list([Utils.h_file(x.abspath())for x in self.aux_nodes]) - def call_latex(self): - self.env.env={} - self.env.env.update(os.environ) - self.env.env.update({'TEXINPUTS':self.texinputs()}) - self.env.SRCFILE=self.inputs[0].abspath() - self.check_status('error when calling latex',self.texfun()) -class latex(tex): - texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False) -class pdflatex(tex): - texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False) -class xelatex(tex): - texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False) -class dvips(Task.Task): - run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}' - color='BLUE' - after=['latex','pdflatex','xelatex'] -class dvipdf(Task.Task): - run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}' - color='BLUE' - after=['latex','pdflatex','xelatex'] -class pdf2ps(Task.Task): - run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}' - color='BLUE' - after=['latex','pdflatex','xelatex'] -@feature('tex') -@before_method('process_source') -def apply_tex(self): - if not getattr(self,'type',None)in('latex','pdflatex','xelatex'): - self.type='pdflatex' - outs=Utils.to_list(getattr(self,'outs',[])) - try: - self.generator.bld.conf - except AttributeError: - default_prompt=False - else: - default_prompt=True - self.env.PROMPT_LATEX=getattr(self,'prompt',default_prompt) - deps_lst=[] - if getattr(self,'deps',None): - deps=self.to_list(self.deps) - for dep in deps: - if isinstance(dep,str): - n=self.path.find_resource(dep) - if not n: - self.bld.fatal('Could not find %r for %r'%(dep,self)) - if not n in deps_lst: - deps_lst.append(n) - elif isinstance(dep,Node.Node): - deps_lst.append(dep) - for node in self.to_nodes(self.source): - if self.type=='latex': - task=self.create_task('latex',node,node.change_ext('.dvi')) - elif self.type=='pdflatex': - task=self.create_task('pdflatex',node,node.change_ext('.pdf')) - elif self.type=='xelatex': - task=self.create_task('xelatex',node,node.change_ext('.pdf')) - task.env=self.env - if deps_lst: - for n in deps_lst: - if not n in task.dep_nodes: - task.dep_nodes.append(n) - if hasattr(self,'texinputs_nodes'): - task.texinputs_nodes=self.texinputs_nodes - else: - task.texinputs_nodes=[node.parent,node.parent.get_bld(),self.path,self.path.get_bld()] - lst=os.environ.get('TEXINPUTS','') - if self.env.TEXINPUTS: - lst+=os.pathsep+self.env.TEXINPUTS - if lst: - lst=lst.split(os.pathsep) - for x in lst: - if x: - if os.path.isabs(x): - p=self.bld.root.find_node(x) - if p: - task.texinputs_nodes.append(p) - else: - Logs.error('Invalid TEXINPUTS folder %s',x) - else: - Logs.error('Cannot resolve relative paths in TEXINPUTS %s',x) - if self.type=='latex': - if'ps'in outs: - tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps')) - tsk.env.env=dict(os.environ) - if'pdf'in outs: - tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf')) - tsk.env.env=dict(os.environ) - elif self.type=='pdflatex': - if'ps'in outs: - self.create_task('pdf2ps',task.outputs,node.change_ext('.ps')) - self.source=[] -def configure(self): - v=self.env - for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split(): - try: - self.find_program(p,var=p.upper()) - except self.errors.ConfigurationError: - pass - v.DVIPSFLAGS='-Ppdf' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py deleted file mode 100755 index 2f5a30d..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py +++ /dev/null @@ -1,218 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib import Build,Context,Errors,Logs,Node,Options,Task,Utils -from waflib.TaskGen import extension,taskgen_method -from waflib.Configure import conf -class valac(Task.Task): - vars=["VALAC","VALAC_VERSION","VALAFLAGS"] - ext_out=['.h'] - def run(self): - cmd=self.env.VALAC+self.env.VALAFLAGS - resources=getattr(self,'vala_exclude',[]) - cmd.extend([a.abspath()for a in self.inputs if a not in resources]) - ret=self.exec_command(cmd,cwd=self.vala_dir_node.abspath()) - if ret: - return ret - if self.generator.dump_deps_node: - self.generator.dump_deps_node.write('\n'.join(self.generator.packages)) - return ret -@taskgen_method -def init_vala_task(self): - self.profile=getattr(self,'profile','gobject') - self.packages=packages=Utils.to_list(getattr(self,'packages',[])) - self.use=Utils.to_list(getattr(self,'use',[])) - if packages and not self.use: - self.use=packages[:] - if self.profile=='gobject': - if not'GOBJECT'in self.use: - self.use.append('GOBJECT') - def addflags(flags): - self.env.append_value('VALAFLAGS',flags) - if self.profile: - addflags('--profile=%s'%self.profile) - valatask=self.valatask - if hasattr(self,'vala_dir'): - if isinstance(self.vala_dir,str): - valatask.vala_dir_node=self.path.get_bld().make_node(self.vala_dir) - try: - valatask.vala_dir_node.mkdir() - except OSError: - raise self.bld.fatal('Cannot create the vala dir %r'%valatask.vala_dir_node) - else: - valatask.vala_dir_node=self.vala_dir - else: - valatask.vala_dir_node=self.path.get_bld() - addflags('--directory=%s'%valatask.vala_dir_node.abspath()) - if hasattr(self,'thread'): - if self.profile=='gobject': - if not'GTHREAD'in self.use: - self.use.append('GTHREAD') - else: - Logs.warn('Profile %s means no threading support',self.profile) - self.thread=False - if self.thread: - addflags('--thread') - self.is_lib='cprogram'not in self.features - if self.is_lib: - addflags('--library=%s'%self.target) - h_node=valatask.vala_dir_node.find_or_declare('%s.h'%self.target) - valatask.outputs.append(h_node) - addflags('--header=%s'%h_node.name) - valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi'%self.target)) - if getattr(self,'gir',None): - gir_node=valatask.vala_dir_node.find_or_declare('%s.gir'%self.gir) - addflags('--gir=%s'%gir_node.name) - valatask.outputs.append(gir_node) - self.vala_target_glib=getattr(self,'vala_target_glib',getattr(Options.options,'vala_target_glib',None)) - if self.vala_target_glib: - addflags('--target-glib=%s'%self.vala_target_glib) - addflags(['--define=%s'%x for x in Utils.to_list(getattr(self,'vala_defines',[]))]) - packages_private=Utils.to_list(getattr(self,'packages_private',[])) - addflags(['--pkg=%s'%x for x in packages_private]) - def _get_api_version(): - api_version='1.0' - if hasattr(Context.g_module,'API_VERSION'): - version=Context.g_module.API_VERSION.split(".") - if version[0]=="0": - api_version="0."+version[1] - else: - api_version=version[0]+".0" - return api_version - self.includes=Utils.to_list(getattr(self,'includes',[])) - valatask.install_path=getattr(self,'install_path','') - valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi') - valatask.pkg_name=getattr(self,'pkg_name',self.env.PACKAGE) - valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version())) - valatask.install_binding=getattr(self,'install_binding',True) - self.vapi_dirs=vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[])) - if hasattr(self,'use'): - local_packages=Utils.to_list(self.use)[:] - seen=[] - while len(local_packages)>0: - package=local_packages.pop() - if package in seen: - continue - seen.append(package) - try: - package_obj=self.bld.get_tgen_by_name(package) - except Errors.WafError: - continue - package_obj.post() - package_name=package_obj.target - task=getattr(package_obj,'valatask',None) - if task: - for output in task.outputs: - if output.name==package_name+".vapi": - valatask.set_run_after(task) - if package_name not in packages: - packages.append(package_name) - if output.parent not in vapi_dirs: - vapi_dirs.append(output.parent) - if output.parent not in self.includes: - self.includes.append(output.parent) - if hasattr(package_obj,'use'): - lst=self.to_list(package_obj.use) - lst.reverse() - local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages - addflags(['--pkg=%s'%p for p in packages]) - for vapi_dir in vapi_dirs: - if isinstance(vapi_dir,Node.Node): - v_node=vapi_dir - else: - v_node=self.path.find_dir(vapi_dir) - if not v_node: - Logs.warn('Unable to locate Vala API directory: %r',vapi_dir) - else: - addflags('--vapidir=%s'%v_node.abspath()) - self.dump_deps_node=None - if self.is_lib and self.packages: - self.dump_deps_node=valatask.vala_dir_node.find_or_declare('%s.deps'%self.target) - valatask.outputs.append(self.dump_deps_node) - if self.is_lib and valatask.install_binding: - headers_list=[o for o in valatask.outputs if o.suffix()==".h"] - if headers_list: - self.install_vheader=self.add_install_files(install_to=valatask.header_path,install_from=headers_list) - vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))] - if vapi_list: - self.install_vapi=self.add_install_files(install_to=valatask.vapi_path,install_from=vapi_list) - gir_list=[o for o in valatask.outputs if o.suffix()=='.gir'] - if gir_list: - self.install_gir=self.add_install_files(install_to=getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),install_from=gir_list) - if hasattr(self,'vala_resources'): - nodes=self.to_nodes(self.vala_resources) - valatask.vala_exclude=getattr(valatask,'vala_exclude',[])+nodes - valatask.inputs.extend(nodes) - for x in nodes: - addflags(['--gresources',x.abspath()]) -@extension('.vala','.gs') -def vala_file(self,node): - try: - valatask=self.valatask - except AttributeError: - valatask=self.valatask=self.create_task('valac') - self.init_vala_task() - valatask.inputs.append(node) - name=node.name[:node.name.rfind('.')]+'.c' - c_node=valatask.vala_dir_node.find_or_declare(name) - valatask.outputs.append(c_node) - self.source.append(c_node) -@extension('.vapi') -def vapi_file(self,node): - try: - valatask=self.valatask - except AttributeError: - valatask=self.valatask=self.create_task('valac') - self.init_vala_task() - valatask.inputs.append(node) -@conf -def find_valac(self,valac_name,min_version): - valac=self.find_program(valac_name,var='VALAC') - try: - output=self.cmd_and_log(valac+['--version']) - except Errors.WafError: - valac_version=None - else: - ver=re.search(r'\d+.\d+.\d+',output).group().split('.') - valac_version=tuple([int(x)for x in ver]) - self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version) - if valac and valac_version= %r"%(valac_name,valac_version,min_version)) - self.env.VALAC_VERSION=valac_version - return valac -@conf -def check_vala(self,min_version=(0,8,0),branch=None): - if self.env.VALA_MINVER: - min_version=self.env.VALA_MINVER - if self.env.VALA_MINVER_BRANCH: - branch=self.env.VALA_MINVER_BRANCH - if not branch: - branch=min_version[:2] - try: - find_valac(self,'valac-%d.%d'%(branch[0],branch[1]),min_version) - except self.errors.ConfigurationError: - find_valac(self,'valac',min_version) -@conf -def check_vala_deps(self): - if not self.env.HAVE_GOBJECT: - pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'} - if getattr(Options.options,'vala_target_glib',None): - pkg_args['atleast_version']=Options.options.vala_target_glib - self.check_cfg(**pkg_args) - if not self.env.HAVE_GTHREAD: - pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'} - if getattr(Options.options,'vala_target_glib',None): - pkg_args['atleast_version']=Options.options.vala_target_glib - self.check_cfg(**pkg_args) -def configure(self): - self.load('gnu_dirs') - self.check_vala_deps() - self.check_vala() - self.add_os_flags('VALAFLAGS') - self.env.append_unique('VALAFLAGS',['-C']) -def options(opt): - opt.load('gnu_dirs') - valaopts=opt.add_option_group('Vala Compiler Options') - valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py deleted file mode 100755 index fa58d9d..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py +++ /dev/null @@ -1,172 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,shlex,sys -from waflib.TaskGen import feature,after_method,taskgen_method -from waflib import Utils,Task,Logs,Options -from waflib.Tools import ccroot -testlock=Utils.threading.Lock() -SCRIPT_TEMPLATE="""#! %(python)s -import subprocess, sys -cmd = %(cmd)r -# if you want to debug with gdb: -#cmd = ['gdb', '-args'] + cmd -env = %(env)r -status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str)) -sys.exit(status) -""" -@taskgen_method -def handle_ut_cwd(self,key): - cwd=getattr(self,key,None) - if cwd: - if isinstance(cwd,str): - if os.path.isabs(cwd): - self.ut_cwd=self.bld.root.make_node(cwd) - else: - self.ut_cwd=self.path.make_node(cwd) -@feature('test_scripts') -def make_interpreted_test(self): - for x in['test_scripts_source','test_scripts_template']: - if not hasattr(self,x): - Logs.warn('a test_scripts taskgen i missing %s'%x) - return - self.ut_run,lst=Task.compile_fun(self.test_scripts_template,shell=getattr(self,'test_scripts_shell',False)) - script_nodes=self.to_nodes(self.test_scripts_source) - for script_node in script_nodes: - tsk=self.create_task('utest',[script_node]) - tsk.vars=lst+tsk.vars - tsk.env['SCRIPT']=script_node.path_from(tsk.get_cwd()) - self.handle_ut_cwd('test_scripts_cwd') - env=getattr(self,'test_scripts_env',None) - if env: - self.ut_env=env - else: - self.ut_env=dict(os.environ) - paths=getattr(self,'test_scripts_paths',{}) - for(k,v)in paths.items(): - p=self.ut_env.get(k,'').split(os.pathsep) - if isinstance(v,str): - v=v.split(os.pathsep) - self.ut_env[k]=os.pathsep.join(p+v) -@feature('test') -@after_method('apply_link','process_use') -def make_test(self): - if not getattr(self,'link_task',None): - return - tsk=self.create_task('utest',self.link_task.outputs) - if getattr(self,'ut_str',None): - self.ut_run,lst=Task.compile_fun(self.ut_str,shell=getattr(self,'ut_shell',False)) - tsk.vars=lst+tsk.vars - self.handle_ut_cwd('ut_cwd') - if not hasattr(self,'ut_paths'): - paths=[] - for x in self.tmp_use_sorted: - try: - y=self.bld.get_tgen_by_name(x).link_task - except AttributeError: - pass - else: - if not isinstance(y,ccroot.stlink_task): - paths.append(y.outputs[0].parent.abspath()) - self.ut_paths=os.pathsep.join(paths)+os.pathsep - if not hasattr(self,'ut_env'): - self.ut_env=dct=dict(os.environ) - def add_path(var): - dct[var]=self.ut_paths+dct.get(var,'') - if Utils.is_win32: - add_path('PATH') - elif Utils.unversioned_sys_platform()=='darwin': - add_path('DYLD_LIBRARY_PATH') - add_path('LD_LIBRARY_PATH') - else: - add_path('LD_LIBRARY_PATH') - if not hasattr(self,'ut_cmd'): - self.ut_cmd=getattr(Options.options,'testcmd',False) -@taskgen_method -def add_test_results(self,tup): - Logs.debug("ut: %r",tup) - try: - self.utest_results.append(tup) - except AttributeError: - self.utest_results=[tup] - try: - self.bld.utest_results.append(tup) - except AttributeError: - self.bld.utest_results=[tup] -@Task.deep_inputs -class utest(Task.Task): - color='PINK' - after=['vnum','inst'] - vars=[] - def runnable_status(self): - if getattr(Options.options,'no_tests',False): - return Task.SKIP_ME - ret=super(utest,self).runnable_status() - if ret==Task.SKIP_ME: - if getattr(Options.options,'all_tests',False): - return Task.RUN_ME - return ret - def get_test_env(self): - return self.generator.ut_env - def post_run(self): - super(utest,self).post_run() - if getattr(Options.options,'clear_failed_tests',False)and self.waf_unit_test_results[1]: - self.generator.bld.task_sigs[self.uid()]=None - def run(self): - if hasattr(self.generator,'ut_run'): - return self.generator.ut_run(self) - self.ut_exec=getattr(self.generator,'ut_exec',[self.inputs[0].abspath()]) - ut_cmd=getattr(self.generator,'ut_cmd',False) - if ut_cmd: - self.ut_exec=shlex.split(ut_cmd%' '.join(self.ut_exec)) - return self.exec_command(self.ut_exec) - def exec_command(self,cmd,**kw): - self.generator.bld.log_command(cmd,kw) - if getattr(Options.options,'dump_test_scripts',False): - script_code=SCRIPT_TEMPLATE%{'python':sys.executable,'env':self.get_test_env(),'cwd':self.get_cwd().abspath(),'cmd':cmd} - script_file=self.inputs[0].abspath()+'_run.py' - Utils.writef(script_file,script_code,encoding='utf-8') - os.chmod(script_file,Utils.O755) - if Logs.verbose>1: - Logs.info('Test debug file written as %r'%script_file) - proc=Utils.subprocess.Popen(cmd,cwd=self.get_cwd().abspath(),env=self.get_test_env(),stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,shell=isinstance(cmd,str)) - (stdout,stderr)=proc.communicate() - self.waf_unit_test_results=tup=(self.inputs[0].abspath(),proc.returncode,stdout,stderr) - testlock.acquire() - try: - return self.generator.add_test_results(tup) - finally: - testlock.release() - def get_cwd(self): - return getattr(self.generator,'ut_cwd',self.inputs[0].parent) -def summary(bld): - lst=getattr(bld,'utest_results',[]) - if lst: - Logs.pprint('CYAN','execution summary') - total=len(lst) - tfail=len([x for x in lst if x[1]]) - Logs.pprint('GREEN',' tests that pass %d/%d'%(total-tfail,total)) - for(f,code,out,err)in lst: - if not code: - Logs.pprint('GREEN',' %s'%f) - Logs.pprint('GREEN'if tfail==0 else'RED',' tests that fail %d/%d'%(tfail,total)) - for(f,code,out,err)in lst: - if code: - Logs.pprint('RED',' %s'%f) -def set_exit_code(bld): - lst=getattr(bld,'utest_results',[]) - for(f,code,out,err)in lst: - if code: - msg=[] - if out: - msg.append('stdout:%s%s'%(os.linesep,out.decode('utf-8'))) - if err: - msg.append('stderr:%s%s'%(os.linesep,err.decode('utf-8'))) - bld.fatal(os.linesep.join(msg)) -def options(opt): - opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests') - opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests') - opt.add_option('--clear-failed',action='store_true',default=False,help='Force failed unit tests to run again next time',dest='clear_failed_tests') - opt.add_option('--testcmd',action='store',default=False,dest='testcmd',help='Run the unit tests using the test-cmd string example "--testcmd="valgrind --error-exitcode=1 %s" to run under valgrind') - opt.add_option('--dump-test-scripts',action='store_true',default=False,help='Create python scripts to help debug tests',dest='dump_test_scripts') diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py deleted file mode 100755 index 39d1f39..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import re -from waflib import Task -from waflib.TaskGen import extension -from waflib.Tools import c_preproc -@extension('.rc') -def rc_file(self,node): - obj_ext='.rc.o' - if self.env.WINRC_TGT_F=='/fo': - obj_ext='.res' - rctask=self.create_task('winrc',node,node.change_ext(obj_ext)) - try: - self.compiled_tasks.append(rctask) - except AttributeError: - self.compiled_tasks=[rctask] -re_lines=re.compile(r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',re.IGNORECASE|re.MULTILINE) -class rc_parser(c_preproc.c_parser): - def filter_comments(self,node): - code=node.read() - if c_preproc.use_trigraphs: - for(a,b)in c_preproc.trig_def: - code=code.split(a).join(b) - code=c_preproc.re_nl.sub('',code) - code=c_preproc.re_cpp.sub(c_preproc.repl,code) - ret=[] - for m in re.finditer(re_lines,code): - if m.group(2): - ret.append((m.group(2),m.group(3))) - else: - ret.append(('include',m.group(5))) - return ret -class winrc(Task.Task): - run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}' - color='BLUE' - def scan(self): - tmp=rc_parser(self.generator.includes_nodes) - tmp.start(self.inputs[0],self.env) - return(tmp.nodes,tmp.names) -def configure(conf): - v=conf.env - if not v.WINRC: - if v.CC_NAME=='msvc': - conf.find_program('RC',var='WINRC',path_list=v.PATH) - v.WINRC_TGT_F='/fo' - v.WINRC_SRC_F='' - else: - conf.find_program('windres',var='WINRC',path_list=v.PATH) - v.WINRC_TGT_F='-o' - v.WINRC_SRC_F='-i' diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py deleted file mode 100755 index a86010d..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py +++ /dev/null @@ -1,44 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.Tools import ccroot,ar -from waflib.Configure import conf -@conf -def find_xlc(conf): - cc=conf.find_program(['xlc_r','xlc'],var='CC') - conf.get_xlc_version(cc) - conf.env.CC_NAME='xlc' -@conf -def xlc_common_flags(conf): - v=conf.env - v.CC_SRC_F=[] - v.CC_TGT_F=['-c','-o'] - if not v.LINK_CC: - v.LINK_CC=v.CC - v.CCLNK_SRC_F=[] - v.CCLNK_TGT_F=['-o'] - v.CPPPATH_ST='-I%s' - v.DEFINES_ST='-D%s' - v.LIB_ST='-l%s' - v.LIBPATH_ST='-L%s' - v.STLIB_ST='-l%s' - v.STLIBPATH_ST='-L%s' - v.RPATH_ST='-Wl,-rpath,%s' - v.SONAME_ST=[] - v.SHLIB_MARKER=[] - v.STLIB_MARKER=[] - v.LINKFLAGS_cprogram=['-Wl,-brtl'] - v.cprogram_PATTERN='%s' - v.CFLAGS_cshlib=['-fPIC'] - v.LINKFLAGS_cshlib=['-G','-Wl,-brtl,-bexpfull'] - v.cshlib_PATTERN='lib%s.so' - v.LINKFLAGS_cstlib=[] - v.cstlib_PATTERN='lib%s.a' -def configure(conf): - conf.find_xlc() - conf.find_ar() - conf.xlc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py deleted file mode 100755 index 8a081b6..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py +++ /dev/null @@ -1,44 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from waflib.Tools import ccroot,ar -from waflib.Configure import conf -@conf -def find_xlcxx(conf): - cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX') - conf.get_xlc_version(cxx) - conf.env.CXX_NAME='xlc++' -@conf -def xlcxx_common_flags(conf): - v=conf.env - v.CXX_SRC_F=[] - v.CXX_TGT_F=['-c','-o'] - if not v.LINK_CXX: - v.LINK_CXX=v.CXX - v.CXXLNK_SRC_F=[] - v.CXXLNK_TGT_F=['-o'] - v.CPPPATH_ST='-I%s' - v.DEFINES_ST='-D%s' - v.LIB_ST='-l%s' - v.LIBPATH_ST='-L%s' - v.STLIB_ST='-l%s' - v.STLIBPATH_ST='-L%s' - v.RPATH_ST='-Wl,-rpath,%s' - v.SONAME_ST=[] - v.SHLIB_MARKER=[] - v.STLIB_MARKER=[] - v.LINKFLAGS_cxxprogram=['-Wl,-brtl'] - v.cxxprogram_PATTERN='%s' - v.CXXFLAGS_cxxshlib=['-fPIC'] - v.LINKFLAGS_cxxshlib=['-G','-Wl,-brtl,-bexpfull'] - v.cxxshlib_PATTERN='lib%s.so' - v.LINKFLAGS_cxxstlib=[] - v.cxxstlib_PATTERN='lib%s.a' -def configure(conf): - conf.find_xlcxx() - conf.find_ar() - conf.xlcxx_common_flags() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py deleted file mode 100755 index 79b38f3..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py +++ /dev/null @@ -1,625 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from __future__ import with_statement -import atexit,os,sys,errno,inspect,re,datetime,platform,base64,signal,functools,time -try: - import cPickle -except ImportError: - import pickle as cPickle -if os.name=='posix'and sys.version_info[0]<3: - try: - import subprocess32 as subprocess - except ImportError: - import subprocess -else: - import subprocess -try: - TimeoutExpired=subprocess.TimeoutExpired -except AttributeError: - class TimeoutExpired(Exception): - pass -from collections import deque,defaultdict -try: - import _winreg as winreg -except ImportError: - try: - import winreg - except ImportError: - winreg=None -from waflib import Errors -try: - from hashlib import md5 -except ImportError: - try: - from hashlib import sha1 as md5 - except ImportError: - pass -else: - try: - md5().digest() - except ValueError: - from hashlib import sha1 as md5 -try: - import threading -except ImportError: - if not'JOBS'in os.environ: - os.environ['JOBS']='1' - class threading(object): - pass - class Lock(object): - def acquire(self): - pass - def release(self): - pass - threading.Lock=threading.Thread=Lock -SIG_NIL='SIG_NIL_SIG_NIL_'.encode() -O644=420 -O755=493 -rot_chr=['\\','|','/','-'] -rot_idx=0 -class ordered_iter_dict(dict): - def __init__(self,*k,**kw): - self.lst=deque() - dict.__init__(self,*k,**kw) - def clear(self): - dict.clear(self) - self.lst=deque() - def __setitem__(self,key,value): - if key in dict.keys(self): - self.lst.remove(key) - dict.__setitem__(self,key,value) - self.lst.append(key) - def __delitem__(self,key): - dict.__delitem__(self,key) - try: - self.lst.remove(key) - except ValueError: - pass - def __iter__(self): - return reversed(self.lst) - def keys(self): - return reversed(self.lst) -class lru_node(object): - __slots__=('next','prev','key','val') - def __init__(self): - self.next=self - self.prev=self - self.key=None - self.val=None -class lru_cache(object): - __slots__=('maxlen','table','head') - def __init__(self,maxlen=100): - self.maxlen=maxlen - self.table={} - self.head=lru_node() - self.head.next=self.head - self.head.prev=self.head - def __getitem__(self,key): - node=self.table[key] - if node is self.head: - return node.val - node.prev.next=node.next - node.next.prev=node.prev - node.next=self.head.next - node.prev=self.head - self.head=node.next.prev=node.prev.next=node - return node.val - def __setitem__(self,key,val): - if key in self.table: - node=self.table[key] - node.val=val - self.__getitem__(key) - else: - if len(self.table)0x3000000 and not'b'in m: - m+='b' - with open(fname,m)as f: - txt=f.read() - if encoding: - txt=txt.decode(encoding) - else: - txt=txt.decode() - else: - with open(fname,m)as f: - txt=f.read() - return txt -def writef(fname,data,m='w',encoding='latin-1'): - if sys.hexversion>0x3000000 and not'b'in m: - data=data.encode(encoding) - m+='b' - with open(fname,m)as f: - f.write(data) -def h_file(fname): - m=md5() - with open(fname,'rb')as f: - while fname: - fname=f.read(200000) - m.update(fname) - return m.digest() -def readf_win32(f,m='r',encoding='latin-1'): - flags=os.O_NOINHERIT|os.O_RDONLY - if'b'in m: - flags|=os.O_BINARY - if'+'in m: - flags|=os.O_RDWR - try: - fd=os.open(f,flags) - except OSError: - raise IOError('Cannot read from %r'%f) - if sys.hexversion>0x3000000 and not'b'in m: - m+='b' - with os.fdopen(fd,m)as f: - txt=f.read() - if encoding: - txt=txt.decode(encoding) - else: - txt=txt.decode() - else: - with os.fdopen(fd,m)as f: - txt=f.read() - return txt -def writef_win32(f,data,m='w',encoding='latin-1'): - if sys.hexversion>0x3000000 and not'b'in m: - data=data.encode(encoding) - m+='b' - flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT - if'b'in m: - flags|=os.O_BINARY - if'+'in m: - flags|=os.O_RDWR - try: - fd=os.open(f,flags) - except OSError: - raise OSError('Cannot write to %r'%f) - with os.fdopen(fd,m)as f: - f.write(data) -def h_file_win32(fname): - try: - fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT) - except OSError: - raise OSError('Cannot read from %r'%fname) - m=md5() - with os.fdopen(fd,'rb')as f: - while fname: - fname=f.read(200000) - m.update(fname) - return m.digest() -readf_unix=readf -writef_unix=writef -h_file_unix=h_file -if hasattr(os,'O_NOINHERIT')and sys.hexversion<0x3040000: - readf=readf_win32 - writef=writef_win32 - h_file=h_file_win32 -try: - x=''.encode('hex') -except LookupError: - import binascii - def to_hex(s): - ret=binascii.hexlify(s) - if not isinstance(ret,str): - ret=ret.decode('utf-8') - return ret -else: - def to_hex(s): - return s.encode('hex') -to_hex.__doc__=""" -Return the hexadecimal representation of a string - -:param s: string to convert -:type s: string -""" -def listdir_win32(s): - if not s: - try: - import ctypes - except ImportError: - return[x+':\\'for x in'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] - else: - dlen=4 - maxdrives=26 - buf=ctypes.create_string_buffer(maxdrives*dlen) - ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf)) - return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))] - if len(s)==2 and s[1]==":": - s+=os.sep - if not os.path.isdir(s): - e=OSError('%s is not a directory'%s) - e.errno=errno.ENOENT - raise e - return os.listdir(s) -listdir=os.listdir -if is_win32: - listdir=listdir_win32 -def num2ver(ver): - if isinstance(ver,str): - ver=tuple(ver.split('.')) - if isinstance(ver,tuple): - ret=0 - for i in range(4): - if i0x3000000: - ret=ret.encode('latin-1','xmlcharrefreplace') - return ret -reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") -def subst_vars(expr,params): - def repl_var(m): - if m.group(1): - return'\\' - if m.group(2): - return'$' - try: - return params.get_flat(m.group(3)) - except AttributeError: - return params[m.group(3)] - return reg_subst.sub(repl_var,expr) -def destos_to_binfmt(key): - if key=='darwin': - return'mac-o' - elif key in('win32','cygwin','uwin','msys'): - return'pe' - return'elf' -def unversioned_sys_platform(): - s=sys.platform - if s.startswith('java'): - from java.lang import System - s=System.getProperty('os.name') - if s=='Mac OS X': - return'darwin' - elif s.startswith('Windows '): - return'win32' - elif s=='OS/2': - return'os2' - elif s=='HP-UX': - return'hp-ux' - elif s in('SunOS','Solaris'): - return'sunos' - else:s=s.lower() - if s=='powerpc': - return'darwin' - if s=='win32'or s=='os2': - return s - if s=='cli'and os.name=='nt': - return'win32' - return re.split(r'\d+$',s)[0] -def nada(*k,**kw): - pass -class Timer(object): - def __init__(self): - self.start_time=self.now() - def __str__(self): - delta=self.now()-self.start_time - if not isinstance(delta,datetime.timedelta): - delta=datetime.timedelta(seconds=delta) - days=delta.days - hours,rem=divmod(delta.seconds,3600) - minutes,seconds=divmod(rem,60) - seconds+=delta.microseconds*1e-6 - result='' - if days: - result+='%dd'%days - if days or hours: - result+='%dh'%hours - if days or hours or minutes: - result+='%dm'%minutes - return'%s%.3fs'%(result,seconds) - def now(self): - return datetime.datetime.utcnow() - if hasattr(time,'perf_counter'): - def now(self): - return time.perf_counter() -def read_la_file(path): - sp=re.compile(r'^([^=]+)=\'(.*)\'$') - dc={} - for line in readf(path).splitlines(): - try: - _,left,right,_=sp.split(line.strip()) - dc[left]=right - except ValueError: - pass - return dc -def run_once(fun): - cache={} - def wrap(*k): - try: - return cache[k] - except KeyError: - ret=fun(*k) - cache[k]=ret - return ret - wrap.__cache__=cache - wrap.__name__=fun.__name__ - return wrap -def get_registry_app_path(key,filename): - if not winreg: - return None - try: - result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0]) - except OSError: - pass - else: - if os.path.isfile(result): - return result -def lib64(): - if os.sep=='/': - if platform.architecture()[0]=='64bit': - if os.path.exists('/usr/lib64')and not os.path.exists('/usr/lib32'): - return'64' - return'' -def sane_path(p): - return os.path.abspath(os.path.expanduser(p)) -process_pool=[] -def get_process(): - try: - return process_pool.pop() - except IndexError: - filepath=os.path.dirname(os.path.abspath(__file__))+os.sep+'processor.py' - cmd=[sys.executable,'-c',readf(filepath)] - return subprocess.Popen(cmd,stdout=subprocess.PIPE,stdin=subprocess.PIPE,bufsize=0,close_fds=not is_win32) -def run_prefork_process(cmd,kwargs,cargs): - if not'env'in kwargs: - kwargs['env']=dict(os.environ) - try: - obj=base64.b64encode(cPickle.dumps([cmd,kwargs,cargs])) - except(TypeError,AttributeError): - return run_regular_process(cmd,kwargs,cargs) - proc=get_process() - if not proc: - return run_regular_process(cmd,kwargs,cargs) - proc.stdin.write(obj) - proc.stdin.write('\n'.encode()) - proc.stdin.flush() - obj=proc.stdout.readline() - if not obj: - raise OSError('Preforked sub-process %r died'%proc.pid) - process_pool.append(proc) - lst=cPickle.loads(base64.b64decode(obj)) - assert len(lst)==5 - ret,out,err,ex,trace=lst - if ex: - if ex=='OSError': - raise OSError(trace) - elif ex=='ValueError': - raise ValueError(trace) - elif ex=='TimeoutExpired': - exc=TimeoutExpired(cmd,timeout=cargs['timeout'],output=out) - exc.stderr=err - raise exc - else: - raise Exception(trace) - return ret,out,err -def lchown(path,user=-1,group=-1): - if isinstance(user,str): - import pwd - entry=pwd.getpwnam(user) - if not entry: - raise OSError('Unknown user %r'%user) - user=entry[2] - if isinstance(group,str): - import grp - entry=grp.getgrnam(group) - if not entry: - raise OSError('Unknown group %r'%group) - group=entry[2] - return os.lchown(path,user,group) -def run_regular_process(cmd,kwargs,cargs={}): - proc=subprocess.Popen(cmd,**kwargs) - if kwargs.get('stdout')or kwargs.get('stderr'): - try: - out,err=proc.communicate(**cargs) - except TimeoutExpired: - if kwargs.get('start_new_session')and hasattr(os,'killpg'): - os.killpg(proc.pid,signal.SIGKILL) - else: - proc.kill() - out,err=proc.communicate() - exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out) - exc.stderr=err - raise exc - status=proc.returncode - else: - out,err=(None,None) - try: - status=proc.wait(**cargs) - except TimeoutExpired as e: - if kwargs.get('start_new_session')and hasattr(os,'killpg'): - os.killpg(proc.pid,signal.SIGKILL) - else: - proc.kill() - proc.wait() - raise e - return status,out,err -def run_process(cmd,kwargs,cargs={}): - if kwargs.get('stdout')and kwargs.get('stderr'): - return run_prefork_process(cmd,kwargs,cargs) - else: - return run_regular_process(cmd,kwargs,cargs) -def alloc_process_pool(n,force=False): - global run_process,get_process,alloc_process_pool - if not force: - n=max(n-len(process_pool),0) - try: - lst=[get_process()for x in range(n)] - except OSError: - run_process=run_regular_process - get_process=alloc_process_pool=nada - else: - for x in lst: - process_pool.append(x) -def atexit_pool(): - for k in process_pool: - try: - os.kill(k.pid,9) - except OSError: - pass - else: - k.wait() -if(sys.hexversion<0x207000f and not is_win32)or sys.hexversion>=0x306000f: - atexit.register(atexit_pool) -if os.environ.get('WAF_NO_PREFORK')or sys.platform=='cli'or not sys.executable: - run_process=run_regular_process - get_process=alloc_process_pool=nada diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py deleted file mode 100755 index 55e850d..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py deleted file mode 100755 index 1ab9c5c..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py +++ /dev/null @@ -1,238 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,re,sys -from waflib import Utils -wlock=Utils.threading.Lock() -try: - from ctypes import Structure,windll,c_short,c_ushort,c_ulong,c_int,byref,c_wchar,POINTER,c_long -except ImportError: - class AnsiTerm(object): - def __init__(self,stream): - self.stream=stream - try: - self.errors=self.stream.errors - except AttributeError: - pass - self.encoding=self.stream.encoding - def write(self,txt): - try: - wlock.acquire() - self.stream.write(txt) - self.stream.flush() - finally: - wlock.release() - def fileno(self): - return self.stream.fileno() - def flush(self): - self.stream.flush() - def isatty(self): - return self.stream.isatty() -else: - class COORD(Structure): - _fields_=[("X",c_short),("Y",c_short)] - class SMALL_RECT(Structure): - _fields_=[("Left",c_short),("Top",c_short),("Right",c_short),("Bottom",c_short)] - class CONSOLE_SCREEN_BUFFER_INFO(Structure): - _fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_ushort),("Window",SMALL_RECT),("MaximumWindowSize",COORD)] - class CONSOLE_CURSOR_INFO(Structure): - _fields_=[('dwSize',c_ulong),('bVisible',c_int)] - try: - _type=unicode - except NameError: - _type=str - to_int=lambda number,default:number and int(number)or default - STD_OUTPUT_HANDLE=-11 - STD_ERROR_HANDLE=-12 - windll.kernel32.GetStdHandle.argtypes=[c_ulong] - windll.kernel32.GetStdHandle.restype=c_ulong - windll.kernel32.GetConsoleScreenBufferInfo.argtypes=[c_ulong,POINTER(CONSOLE_SCREEN_BUFFER_INFO)] - windll.kernel32.GetConsoleScreenBufferInfo.restype=c_long - windll.kernel32.SetConsoleTextAttribute.argtypes=[c_ulong,c_ushort] - windll.kernel32.SetConsoleTextAttribute.restype=c_long - windll.kernel32.FillConsoleOutputCharacterW.argtypes=[c_ulong,c_wchar,c_ulong,POINTER(COORD),POINTER(c_ulong)] - windll.kernel32.FillConsoleOutputCharacterW.restype=c_long - windll.kernel32.FillConsoleOutputAttribute.argtypes=[c_ulong,c_ushort,c_ulong,POINTER(COORD),POINTER(c_ulong)] - windll.kernel32.FillConsoleOutputAttribute.restype=c_long - windll.kernel32.SetConsoleCursorPosition.argtypes=[c_ulong,POINTER(COORD)] - windll.kernel32.SetConsoleCursorPosition.restype=c_long - windll.kernel32.SetConsoleCursorInfo.argtypes=[c_ulong,POINTER(CONSOLE_CURSOR_INFO)] - windll.kernel32.SetConsoleCursorInfo.restype=c_long - class AnsiTerm(object): - def __init__(self,s): - self.stream=s - try: - self.errors=s.errors - except AttributeError: - pass - self.encoding=s.encoding - self.cursor_history=[] - handle=(s.fileno()==2)and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE - self.hconsole=windll.kernel32.GetStdHandle(handle) - self._sbinfo=CONSOLE_SCREEN_BUFFER_INFO() - self._csinfo=CONSOLE_CURSOR_INFO() - windll.kernel32.GetConsoleCursorInfo(self.hconsole,byref(self._csinfo)) - self._orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO() - r=windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._orig_sbinfo)) - self._isatty=r==1 - def screen_buffer_info(self): - windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self._sbinfo)) - return self._sbinfo - def clear_line(self,param): - mode=param and int(param)or 0 - sbinfo=self.screen_buffer_info() - if mode==1: - line_start=COORD(0,sbinfo.CursorPosition.Y) - line_length=sbinfo.Size.X - elif mode==2: - line_start=COORD(sbinfo.CursorPosition.X,sbinfo.CursorPosition.Y) - line_length=sbinfo.Size.X-sbinfo.CursorPosition.X - else: - line_start=sbinfo.CursorPosition - line_length=sbinfo.Size.X-sbinfo.CursorPosition.X - chars_written=c_ulong() - windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),line_length,line_start,byref(chars_written)) - windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,line_length,line_start,byref(chars_written)) - def clear_screen(self,param): - mode=to_int(param,0) - sbinfo=self.screen_buffer_info() - if mode==1: - clear_start=COORD(0,0) - clear_length=sbinfo.CursorPosition.X*sbinfo.CursorPosition.Y - elif mode==2: - clear_start=COORD(0,0) - clear_length=sbinfo.Size.X*sbinfo.Size.Y - windll.kernel32.SetConsoleCursorPosition(self.hconsole,clear_start) - else: - clear_start=sbinfo.CursorPosition - clear_length=((sbinfo.Size.X-sbinfo.CursorPosition.X)+sbinfo.Size.X*(sbinfo.Size.Y-sbinfo.CursorPosition.Y)) - chars_written=c_ulong() - windll.kernel32.FillConsoleOutputCharacterW(self.hconsole,c_wchar(' '),clear_length,clear_start,byref(chars_written)) - windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,clear_length,clear_start,byref(chars_written)) - def push_cursor(self,param): - sbinfo=self.screen_buffer_info() - self.cursor_history.append(sbinfo.CursorPosition) - def pop_cursor(self,param): - if self.cursor_history: - old_pos=self.cursor_history.pop() - windll.kernel32.SetConsoleCursorPosition(self.hconsole,old_pos) - def set_cursor(self,param): - y,sep,x=param.partition(';') - x=to_int(x,1)-1 - y=to_int(y,1)-1 - sbinfo=self.screen_buffer_info() - new_pos=COORD(min(max(0,x),sbinfo.Size.X),min(max(0,y),sbinfo.Size.Y)) - windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos) - def set_column(self,param): - x=to_int(param,1)-1 - sbinfo=self.screen_buffer_info() - new_pos=COORD(min(max(0,x),sbinfo.Size.X),sbinfo.CursorPosition.Y) - windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos) - def move_cursor(self,x_offset=0,y_offset=0): - sbinfo=self.screen_buffer_info() - new_pos=COORD(min(max(0,sbinfo.CursorPosition.X+x_offset),sbinfo.Size.X),min(max(0,sbinfo.CursorPosition.Y+y_offset),sbinfo.Size.Y)) - windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos) - def move_up(self,param): - self.move_cursor(y_offset=-to_int(param,1)) - def move_down(self,param): - self.move_cursor(y_offset=to_int(param,1)) - def move_left(self,param): - self.move_cursor(x_offset=-to_int(param,1)) - def move_right(self,param): - self.move_cursor(x_offset=to_int(param,1)) - def next_line(self,param): - sbinfo=self.screen_buffer_info() - self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=to_int(param,1)) - def prev_line(self,param): - sbinfo=self.screen_buffer_info() - self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=-to_int(param,1)) - def rgb2bgr(self,c): - return((c&1)<<2)|(c&2)|((c&4)>>2) - def set_color(self,param): - cols=param.split(';') - sbinfo=self.screen_buffer_info() - attr=sbinfo.Attributes - for c in cols: - c=to_int(c,0) - if 29>4)|((attr&0x07)<<4) - windll.kernel32.SetConsoleTextAttribute(self.hconsole,attr) - def show_cursor(self,param): - self._csinfo.bVisible=1 - windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo)) - def hide_cursor(self,param): - self._csinfo.bVisible=0 - windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(self._csinfo)) - ansi_command_table={'A':move_up,'B':move_down,'C':move_right,'D':move_left,'E':next_line,'F':prev_line,'G':set_column,'H':set_cursor,'f':set_cursor,'J':clear_screen,'K':clear_line,'h':show_cursor,'l':hide_cursor,'m':set_color,'s':push_cursor,'u':pop_cursor,} - ansi_tokens=re.compile(r'(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))') - def write(self,text): - try: - wlock.acquire() - if self._isatty: - for param,cmd,txt in self.ansi_tokens.findall(text): - if cmd: - cmd_func=self.ansi_command_table.get(cmd) - if cmd_func: - cmd_func(self,param) - else: - self.writeconsole(txt) - else: - self.stream.write(text) - finally: - wlock.release() - def writeconsole(self,txt): - chars_written=c_ulong() - writeconsole=windll.kernel32.WriteConsoleA - if isinstance(txt,_type): - writeconsole=windll.kernel32.WriteConsoleW - done=0 - todo=len(txt) - chunk=32<<10 - while todo!=0: - doing=min(chunk,todo) - buf=txt[done:done+doing] - r=writeconsole(self.hconsole,buf,doing,byref(chars_written),None) - if r==0: - chunk>>=1 - continue - done+=doing - todo-=doing - def fileno(self): - return self.stream.fileno() - def flush(self): - pass - def isatty(self): - return self._isatty - if sys.stdout.isatty()or sys.stderr.isatty(): - handle=sys.stdout.isatty()and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE - console=windll.kernel32.GetStdHandle(handle) - sbinfo=CONSOLE_SCREEN_BUFFER_INFO() - def get_term_cols(): - windll.kernel32.GetConsoleScreenBufferInfo(console,byref(sbinfo)) - return sbinfo.Size.X-1 -try: - import struct,fcntl,termios -except ImportError: - pass -else: - if(sys.stdout.isatty()or sys.stderr.isatty())and os.environ.get('TERM','')not in('dumb','emacs'): - FD=sys.stdout.isatty()and sys.stdout.fileno()or sys.stderr.fileno() - def fun(): - return struct.unpack("HHHH",fcntl.ioctl(FD,termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[1] - try: - fun() - except Exception as e: - pass - else: - get_term_cols=fun diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py deleted file mode 100755 index 55e850d..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py deleted file mode 100755 index fb4e578..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py +++ /dev/null @@ -1,305 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import sys -from waflib import ConfigSet,Logs,Options,Scripting,Task,Build,Configure,Node,Runner,TaskGen,Utils,Errors,Context -sys.modules['Environment']=ConfigSet -ConfigSet.Environment=ConfigSet.ConfigSet -sys.modules['Logs']=Logs -sys.modules['Options']=Options -sys.modules['Scripting']=Scripting -sys.modules['Task']=Task -sys.modules['Build']=Build -sys.modules['Configure']=Configure -sys.modules['Node']=Node -sys.modules['Runner']=Runner -sys.modules['TaskGen']=TaskGen -sys.modules['Utils']=Utils -sys.modules['Constants']=Context -Context.SRCDIR='' -Context.BLDDIR='' -from waflib.Tools import c_preproc -sys.modules['preproc']=c_preproc -from waflib.Tools import c_config -sys.modules['config_c']=c_config -ConfigSet.ConfigSet.copy=ConfigSet.ConfigSet.derive -ConfigSet.ConfigSet.set_variant=Utils.nada -Utils.pproc=Utils.subprocess -Build.BuildContext.add_subdirs=Build.BuildContext.recurse -Build.BuildContext.new_task_gen=Build.BuildContext.__call__ -Build.BuildContext.is_install=0 -Node.Node.relpath_gen=Node.Node.path_from -Utils.pproc=Utils.subprocess -Utils.get_term_cols=Logs.get_term_cols -def cmd_output(cmd,**kw): - silent=False - if'silent'in kw: - silent=kw['silent'] - del(kw['silent']) - if'e'in kw: - tmp=kw['e'] - del(kw['e']) - kw['env']=tmp - kw['shell']=isinstance(cmd,str) - kw['stdout']=Utils.subprocess.PIPE - if silent: - kw['stderr']=Utils.subprocess.PIPE - try: - p=Utils.subprocess.Popen(cmd,**kw) - output=p.communicate()[0] - except OSError as e: - raise ValueError(str(e)) - if p.returncode: - if not silent: - msg="command execution failed: %s -> %r"%(cmd,str(output)) - raise ValueError(msg) - output='' - return output -Utils.cmd_output=cmd_output -def name_to_obj(self,s,env=None): - if Logs.verbose: - Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"') - return self.get_tgen_by_name(s) -Build.BuildContext.name_to_obj=name_to_obj -def env_of_name(self,name): - try: - return self.all_envs[name] - except KeyError: - Logs.error('no such environment: '+name) - return None -Build.BuildContext.env_of_name=env_of_name -def set_env_name(self,name,env): - self.all_envs[name]=env - return env -Configure.ConfigurationContext.set_env_name=set_env_name -def retrieve(self,name,fromenv=None): - try: - env=self.all_envs[name] - except KeyError: - env=ConfigSet.ConfigSet() - self.prepare_env(env) - self.all_envs[name]=env - else: - if fromenv: - Logs.warn('The environment %s may have been configured already',name) - return env -Configure.ConfigurationContext.retrieve=retrieve -Configure.ConfigurationContext.sub_config=Configure.ConfigurationContext.recurse -Configure.ConfigurationContext.check_tool=Configure.ConfigurationContext.load -Configure.conftest=Configure.conf -Configure.ConfigurationError=Errors.ConfigurationError -Utils.WafError=Errors.WafError -Options.OptionsContext.sub_options=Options.OptionsContext.recurse -Options.OptionsContext.tool_options=Context.Context.load -Options.Handler=Options.OptionsContext -Task.simple_task_type=Task.task_type_from_func=Task.task_factory -Task.Task.classes=Task.classes -def setitem(self,key,value): - if key.startswith('CCFLAGS'): - key=key[1:] - self.table[key]=value -ConfigSet.ConfigSet.__setitem__=setitem -@TaskGen.feature('d') -@TaskGen.before('apply_incpaths') -def old_importpaths(self): - if getattr(self,'importpaths',[]): - self.includes=self.importpaths -from waflib import Context -eld=Context.load_tool -def load_tool(*k,**kw): - ret=eld(*k,**kw) - if'set_options'in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "set_options" to options') - ret.options=ret.set_options - if'detect'in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "detect" to "configure"') - ret.configure=ret.detect - return ret -Context.load_tool=load_tool -def get_curdir(self): - return self.path.abspath() -Context.Context.curdir=property(get_curdir,Utils.nada) -def get_srcdir(self): - return self.srcnode.abspath() -Configure.ConfigurationContext.srcdir=property(get_srcdir,Utils.nada) -def get_blddir(self): - return self.bldnode.abspath() -Configure.ConfigurationContext.blddir=property(get_blddir,Utils.nada) -Configure.ConfigurationContext.check_message_1=Configure.ConfigurationContext.start_msg -Configure.ConfigurationContext.check_message_2=Configure.ConfigurationContext.end_msg -rev=Context.load_module -def load_module(path,encoding=None): - ret=rev(path,encoding) - if'set_options'in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "set_options" to "options" (%r)',path) - ret.options=ret.set_options - if'srcdir'in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "srcdir" to "top" (%r)',path) - ret.top=ret.srcdir - if'blddir'in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "blddir" to "out" (%r)',path) - ret.out=ret.blddir - Utils.g_module=Context.g_module - Options.launch_dir=Context.launch_dir - return ret -Context.load_module=load_module -old_post=TaskGen.task_gen.post -def post(self): - self.features=self.to_list(self.features) - if'cc'in self.features: - if Logs.verbose: - Logs.warn('compat: the feature cc does not exist anymore (use "c")') - self.features.remove('cc') - self.features.append('c') - if'cstaticlib'in self.features: - if Logs.verbose: - Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")') - self.features.remove('cstaticlib') - self.features.append(('cxx'in self.features)and'cxxstlib'or'cstlib') - if getattr(self,'ccflags',None): - if Logs.verbose: - Logs.warn('compat: "ccflags" was renamed to "cflags"') - self.cflags=self.ccflags - return old_post(self) -TaskGen.task_gen.post=post -def waf_version(*k,**kw): - Logs.warn('wrong version (waf_version was removed in waf 1.6)') -Utils.waf_version=waf_version -import os -@TaskGen.feature('c','cxx','d') -@TaskGen.before('apply_incpaths','propagate_uselib_vars') -@TaskGen.after('apply_link','process_source') -def apply_uselib_local(self): - env=self.env - from waflib.Tools.ccroot import stlink_task - self.uselib=self.to_list(getattr(self,'uselib',[])) - self.includes=self.to_list(getattr(self,'includes',[])) - names=self.to_list(getattr(self,'uselib_local',[])) - get=self.bld.get_tgen_by_name - seen=set() - seen_uselib=set() - tmp=Utils.deque(names) - if tmp: - if Logs.verbose: - Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') - while tmp: - lib_name=tmp.popleft() - if lib_name in seen: - continue - y=get(lib_name) - y.post() - seen.add(lib_name) - if getattr(y,'uselib_local',None): - for x in self.to_list(getattr(y,'uselib_local',[])): - obj=get(x) - obj.post() - if getattr(obj,'link_task',None): - if not isinstance(obj.link_task,stlink_task): - tmp.append(x) - if getattr(y,'link_task',None): - link_name=y.target[y.target.rfind(os.sep)+1:] - if isinstance(y.link_task,stlink_task): - env.append_value('STLIB',[link_name]) - else: - env.append_value('LIB',[link_name]) - self.link_task.set_run_after(y.link_task) - self.link_task.dep_nodes+=y.link_task.outputs - tmp_path=y.link_task.outputs[0].parent.bldpath() - if not tmp_path in env['LIBPATH']: - env.prepend_value('LIBPATH',[tmp_path]) - for v in self.to_list(getattr(y,'uselib',[])): - if v not in seen_uselib: - seen_uselib.add(v) - if not env['STLIB_'+v]: - if not v in self.uselib: - self.uselib.insert(0,v) - if getattr(y,'export_includes',None): - self.includes.extend(y.to_incnodes(y.export_includes)) -@TaskGen.feature('cprogram','cxxprogram','cstlib','cxxstlib','cshlib','cxxshlib','dprogram','dstlib','dshlib') -@TaskGen.after('apply_link') -def apply_objdeps(self): - names=getattr(self,'add_objects',[]) - if not names: - return - names=self.to_list(names) - get=self.bld.get_tgen_by_name - seen=[] - while names: - x=names[0] - if x in seen: - names=names[1:] - continue - y=get(x) - if getattr(y,'add_objects',None): - added=0 - lst=y.to_list(y.add_objects) - lst.reverse() - for u in lst: - if u in seen: - continue - added=1 - names=[u]+names - if added: - continue - y.post() - seen.append(x) - for t in getattr(y,'compiled_tasks',[]): - self.link_task.inputs.extend(t.outputs) -@TaskGen.after('apply_link') -def process_obj_files(self): - if not hasattr(self,'obj_files'): - return - for x in self.obj_files: - node=self.path.find_resource(x) - self.link_task.inputs.append(node) -@TaskGen.taskgen_method -def add_obj_file(self,file): - if not hasattr(self,'obj_files'): - self.obj_files=[] - if not'process_obj_files'in self.meths: - self.meths.append('process_obj_files') - self.obj_files.append(file) -old_define=Configure.ConfigurationContext.__dict__['define'] -@Configure.conf -def define(self,key,val,quote=True,comment=''): - old_define(self,key,val,quote,comment) - if key.startswith('HAVE_'): - self.env[key]=1 -old_undefine=Configure.ConfigurationContext.__dict__['undefine'] -@Configure.conf -def undefine(self,key,comment=''): - old_undefine(self,key,comment) - if key.startswith('HAVE_'): - self.env[key]=0 -def set_incdirs(self,val): - Logs.warn('compat: change "export_incdirs" by "export_includes"') - self.export_includes=val -TaskGen.task_gen.export_incdirs=property(None,set_incdirs) -def install_dir(self,path): - if not path: - return[] - destpath=Utils.subst_vars(path,self.env) - if self.is_install>0: - Logs.info('* creating %s',destpath) - Utils.check_dir(destpath) - elif self.is_install<0: - Logs.info('* removing %s',destpath) - try: - os.remove(destpath) - except OSError: - pass -Build.BuildContext.install_dir=install_dir -repl={'apply_core':'process_source','apply_lib_vars':'process_source','apply_obj_vars':'propagate_uselib_vars','exec_rule':'process_rule'} -def after(*k): - k=[repl.get(key,key)for key in k] - return TaskGen.after_method(*k) -def before(*k): - k=[repl.get(key,key)for key in k] - return TaskGen.before_method(*k) -TaskGen.before=before diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py deleted file mode 100755 index 9aa8418..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py +++ /dev/null @@ -1,47 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -from __future__ import with_statement -import os -all_modifs={} -def fixdir(dir): - for k in all_modifs: - for v in all_modifs[k]: - modif(os.path.join(dir,'waflib'),k,v) -def modif(dir,name,fun): - if name=='*': - lst=[] - for y in'. Tools extras'.split(): - for x in os.listdir(os.path.join(dir,y)): - if x.endswith('.py'): - lst.append(y+os.sep+x) - for x in lst: - modif(dir,x,fun) - return - filename=os.path.join(dir,name) - with open(filename,'r')as f: - txt=f.read() - txt=fun(txt) - with open(filename,'w')as f: - f.write(txt) -def subst(*k): - def do_subst(fun): - for x in k: - try: - all_modifs[x].append(fun) - except KeyError: - all_modifs[x]=[fun] - return fun - return do_subst -@subst('*') -def r1(code): - code=code.replace('as e:',',e:') - code=code.replace(".decode(sys.stdout.encoding or'latin-1',errors='replace')",'') - return code.replace('.encode()','') -@subst('Runner.py') -def r4(code): - return code.replace('next(self.biter)','self.biter.next()') -@subst('Context.py') -def r5(code): - return code.replace("('Execution failure: %s'%str(e),ex=e)","('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]") diff --git a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py b/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py deleted file mode 100755 index f7033d4..0000000 --- a/Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py +++ /dev/null @@ -1,57 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file - -import os,sys,traceback,base64,signal -try: - import cPickle -except ImportError: - import pickle as cPickle -try: - import subprocess32 as subprocess -except ImportError: - import subprocess -try: - TimeoutExpired=subprocess.TimeoutExpired -except AttributeError: - class TimeoutExpired(Exception): - pass -def run(): - txt=sys.stdin.readline().strip() - if not txt: - sys.exit(1) - [cmd,kwargs,cargs]=cPickle.loads(base64.b64decode(txt)) - cargs=cargs or{} - if not'close_fds'in kwargs: - kwargs['close_fds']=False - ret=1 - out,err,ex,trace=(None,None,None,None) - try: - proc=subprocess.Popen(cmd,**kwargs) - try: - out,err=proc.communicate(**cargs) - except TimeoutExpired: - if kwargs.get('start_new_session')and hasattr(os,'killpg'): - os.killpg(proc.pid,signal.SIGKILL) - else: - proc.kill() - out,err=proc.communicate() - exc=TimeoutExpired(proc.args,timeout=cargs['timeout'],output=out) - exc.stderr=err - raise exc - ret=proc.returncode - except Exception as e: - exc_type,exc_value,tb=sys.exc_info() - exc_lines=traceback.format_exception(exc_type,exc_value,tb) - trace=str(cmd)+'\n'+''.join(exc_lines) - ex=e.__class__.__name__ - tmp=[ret,out,err,ex,trace] - obj=base64.b64encode(cPickle.dumps(tmp)) - sys.stdout.write(obj.decode()) - sys.stdout.write('\n') - sys.stdout.flush() -while 1: - try: - run() - except KeyboardInterrupt: - break diff --git a/Program/libcsp/wscript b/Program/libcsp/wscript deleted file mode 100755 index 6421f08..0000000 --- a/Program/libcsp/wscript +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -# Cubesat Space Protocol - A small network-layer protocol designed for Cubesats -# Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com) -# Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk) -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library 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 -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -import os - -APPNAME = 'libcsp' -VERSION = '1.6' - -valid_os = ['posix', 'windows', 'freertos', 'macosx'] -valid_loglevel = ['error', 'warn', 'info', 'debug'] - - -def options(ctx): - # Load compiler - ctx.load('compiler_c') - - ctx.add_option('--toolchain', default=None, help='Set toolchain prefix') - - # Set libcsp options - gr = ctx.add_option_group('libcsp options') - gr.add_option('--includes', default='', help='Add additional include paths, separate with comma') - gr.add_option('--install-csp', action='store_true', help='Installs CSP headers and lib') - - gr.add_option('--disable-output', action='store_true', help='Disable CSP output') - gr.add_option('--disable-stlib', action='store_true', help='Build objects only') - gr.add_option('--enable-shlib', action='store_true', help='Build shared library') - gr.add_option('--enable-rdp', action='store_true', help='Enable RDP support') - gr.add_option('--enable-rdp-fast-close', action='store_true', help='Enable fast close of RDP connections') - gr.add_option('--enable-qos', action='store_true', help='Enable Quality of Service support') - gr.add_option('--enable-promisc', action='store_true', help='Enable promiscuous support') - gr.add_option('--enable-crc32', action='store_true', help='Enable CRC32 support') - gr.add_option('--enable-hmac', action='store_true', help='Enable HMAC-SHA1 support') - gr.add_option('--enable-xtea', action='store_true', help='Enable XTEA support') - gr.add_option('--enable-python3-bindings', action='store_true', help='Enable Python3 bindings') - gr.add_option('--enable-examples', action='store_true', help='Enable examples') - gr.add_option('--enable-dedup', action='store_true', help='Enable packet deduplicator') - gr.add_option('--enable-external-debug', action='store_true', help='Enable external debug API') - gr.add_option('--enable-debug-timestamp', action='store_true', help='Enable timestamps on debug/log') - - # Drivers and interfaces (requires external dependencies) - gr.add_option('--enable-if-zmqhub', action='store_true', help='Enable ZMQ interface') - gr.add_option('--enable-can-socketcan', action='store_true', help='Enable Linux socketcan driver') - gr.add_option('--with-driver-usart', default=None, metavar='DRIVER', - help='Build USART driver. [windows, linux, None]') - - # OS - gr.add_option('--with-os', metavar='OS', default='posix', - help='Set operating system. Must be one of: ' + str(valid_os)) - - # Options - gr.add_option('--with-loglevel', metavar='LEVEL', default='debug', - help='Set minimum compile time log level. Must be one of: ' + str(valid_loglevel)) - gr.add_option('--with-rtable', metavar='TABLE', default='static', - help='Set routing table type: \'static\' or \'cidr\'') - - -def configure(ctx): - # Validate options - if ctx.options.with_os not in valid_os: - ctx.fatal('--with-os must be either: ' + str(valid_os)) - - if ctx.options.with_loglevel not in valid_loglevel: - ctx.fatal('--with-loglevel must be either: ' + str(valid_loglevel)) - - # Setup and validate toolchain - if (len(ctx.stack_path) <= 1) and ctx.options.toolchain: - ctx.env.CC = ctx.options.toolchain + 'gcc' - ctx.env.AR = ctx.options.toolchain + 'ar' - - ctx.load('compiler_c') - - # Set git revision define - git_rev = os.popen('git describe --long --always 2> /dev/null || echo unknown').read().strip() - ctx.define('GIT_REV', git_rev) - - # Set build output format - ctx.env.FEATURES = ['c'] - if not ctx.options.disable_stlib: - ctx.env.FEATURES += ['cstlib'] - - ctx.env.LIBCSP_SHLIB = ctx.options.enable_shlib - - # Setup CFLAGS - if (len(ctx.stack_path) <= 1) and (len(ctx.env.CFLAGS) == 0): - ctx.env.prepend_value('CFLAGS', ["-std=gnu99", "-g", "-Os", "-Wall", "-Wextra", "-Wshadow", "-Wcast-align", - "-Wwrite-strings", "-Wno-unused-parameter"]) - - # Setup default include path and any extra defined - ctx.env.append_unique('INCLUDES_CSP', ['include'] + ctx.options.includes.split(',')) - - # Store OS as env variable - ctx.env.append_unique('OS', ctx.options.with_os) - - # Platform/OS specifics - if ctx.options.with_os == 'posix': - ctx.env.append_unique('LIBS', ['rt', 'pthread', 'util']) - elif ctx.options.with_os == 'macosx': - ctx.env.append_unique('LIBS', ['pthread']) - elif ctx.options.with_os == 'windows': - ctx.env.append_unique('CFLAGS', ['-D_WIN32_WINNT=0x0600']) - - ctx.define_cond('CSP_FREERTOS', ctx.options.with_os == 'freertos') - ctx.define_cond('CSP_POSIX', ctx.options.with_os == 'posix') - ctx.define_cond('CSP_WINDOWS', ctx.options.with_os == 'windows') - ctx.define_cond('CSP_MACOSX', ctx.options.with_os == 'macosx') - - # Add files - ctx.env.append_unique('FILES_CSP', ['src/*.c', - 'src/external/**/*.c', - 'src/transport/**/*.c', - 'src/crypto/**/*.c', - 'src/interfaces/**/*.c', - 'src/arch/*.c', - 'src/arch/{0}/**/*.c'.format(ctx.options.with_os), - 'src/rtable/csp_rtable.c', - 'src/rtable/csp_rtable_{0}.c'.format(ctx.options.with_rtable)]) - - # Add socketcan - if ctx.options.enable_can_socketcan: - ctx.env.append_unique('FILES_CSP', 'src/drivers/can/can_socketcan.c') - ctx.check_cfg(package='libsocketcan', args='--cflags --libs', define_name='CSP_HAVE_LIBSOCKETCAN') - ctx.env.append_unique('LIBS', ctx.env.LIB_LIBSOCKETCAN) - - # Add USART driver - if ctx.options.with_driver_usart: - ctx.env.append_unique('FILES_CSP', ['src/drivers/usart/usart_kiss.c', - 'src/drivers/usart/usart_{0}.c'.format(ctx.options.with_driver_usart)]) - - # Add ZMQ - if ctx.options.enable_if_zmqhub: - ctx.check_cfg(package='libzmq', args='--cflags --libs', define_name='CSP_HAVE_LIBZMQ') - ctx.env.append_unique('LIBS', ctx.env.LIB_LIBZMQ) - - # Store configuration options - ctx.env.ENABLE_EXAMPLES = ctx.options.enable_examples - - # Add Python bindings - if ctx.options.enable_python3_bindings: - ctx.env.LIBCSP_PYTHON3 = ctx.check_cfg(package='python3', args='--cflags --libs', atleast_version='3.5', - mandatory=True) - - # Set defines for enabling features - ctx.define('CSP_DEBUG', not ctx.options.disable_output) - ctx.define('CSP_DEBUG_TIMESTAMP', ctx.options.enable_debug_timestamp) - ctx.define('CSP_USE_RDP', ctx.options.enable_rdp) - ctx.define('CSP_USE_RDP_FAST_CLOSE', ctx.options.enable_rdp and ctx.options.enable_rdp_fast_close) - ctx.define('CSP_USE_CRC32', ctx.options.enable_crc32) - ctx.define('CSP_USE_HMAC', ctx.options.enable_hmac) - ctx.define('CSP_USE_XTEA', ctx.options.enable_xtea) - ctx.define('CSP_USE_PROMISC', ctx.options.enable_promisc) - ctx.define('CSP_USE_QOS', ctx.options.enable_qos) - ctx.define('CSP_USE_DEDUP', ctx.options.enable_dedup) - ctx.define('CSP_USE_EXTERNAL_DEBUG', ctx.options.enable_external_debug) - - # Set logging level - ctx.define('CSP_LOG_LEVEL_DEBUG', ctx.options.with_loglevel in ('debug')) - ctx.define('CSP_LOG_LEVEL_INFO', ctx.options.with_loglevel in ('debug', 'info')) - ctx.define('CSP_LOG_LEVEL_WARN', ctx.options.with_loglevel in ('debug', 'info', 'warn')) - ctx.define('CSP_LOG_LEVEL_ERROR', ctx.options.with_loglevel in ('debug', 'info', 'warn', 'error')) - - # Check compiler endianness - endianness = ctx.check_endianness() - ctx.define_cond('CSP_LITTLE_ENDIAN', endianness == 'little') - ctx.define_cond('CSP_BIG_ENDIAN', endianness == 'big') - - ctx.define('LIBCSP_VERSION', VERSION) - - ctx.write_config_header('include/csp/csp_autoconfig.h') - - -def build(ctx): - - # Set install path for header files - install_path = None - if ctx.options.install_csp: - install_path = '${PREFIX}/lib' - ctx.install_files('${PREFIX}/include/csp', - ctx.path.ant_glob('include/csp/**'), - cwd=ctx.path.find_dir('include/csp'), - relative_trick=True) - ctx.install_files('${PREFIX}/include/csp', 'include/csp/csp_autoconfig.h', cwd=ctx.bldnode) - - ctx(export_includes=ctx.env.INCLUDES_CSP, name='csp_h') - - ctx(features=ctx.env.FEATURES, - source=ctx.path.ant_glob(ctx.env.FILES_CSP), - target='csp', - use=['csp_h', 'freertos_h', 'util'], - install_path=install_path) - - # Build shared library - if ctx.env.LIBCSP_SHLIB or ctx.env.LIBCSP_PYTHON3: - ctx.shlib(source=ctx.path.ant_glob(ctx.env.FILES_CSP), - name='csp_shlib', - target='csp', - use=['csp_h', 'util_shlib'], - lib=ctx.env.LIBS) - - # Build Python bindings - if ctx.env.LIBCSP_PYTHON3: - ctx.shlib(source=ctx.path.ant_glob('src/bindings/python/**/*.c'), - target='csp_py3', - includes=ctx.env.INCLUDES_PYTHON3, - use=['csp_shlib'], - lib=ctx.env.LIBS, - pytest_path=[ctx.path.get_bld()]) - - if ctx.env.ENABLE_EXAMPLES: - ctx.program(source='examples/csp_server_client.c', - target='csp_server_client', - lib=ctx.env.LIBS, - use='csp') - - ctx.program(source='examples/csp_arch.c', - target='csp_arch', - lib=ctx.env.LIBS, - use='csp') - - if ctx.env.CSP_HAVE_LIBZMQ: - ctx.program(source='examples/zmqproxy.c', - target='zmqproxy', - lib=ctx.env.LIBS, - use='csp') - - -def dist(ctx): - ctx.excl = 'build/* **/.* **/*.pyc **/*.o **/*~ *.tar.gz' From 513f938ef531adfa37f66bbc21894466778851ee Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 7 Jul 2021 20:20:28 -0600 Subject: [PATCH 365/400] add safe_strncpy to utils --- Program/include/utils.h | 1 + Program/src/utils.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Program/include/utils.h b/Program/include/utils.h index 231b4e4..9105d95 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -11,5 +11,6 @@ Author: Evan Giese void ssp_print_hex(char *stuff, int size); void ssp_print_bits(char *stuff, int size); +char *safe_strncpy(char *to, char*from, int len); #endif //UTILS_H diff --git a/Program/src/utils.c b/Program/src/utils.c index 35de85c..e27f3d2 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -45,10 +45,9 @@ void ssp_print_bits(char *stuff, int size){ } //replace strings with this -/* -static char *safe_strncpy(char *to, char*from, int len){ + +char *safe_strncpy(char *to, char*from, int len){ void *ret = strncpy(to, from, len); to[len] = '\0'; return ret; } -*/ \ No newline at end of file From de8e03b0aabc103237fb1d1c3c3e577d82d8c15b Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 7 Jul 2021 20:21:15 -0600 Subject: [PATCH 366/400] add 'onExit' callback to clients --- Program/src/csp_server_provider.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index c290b06..125db44 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -88,6 +88,7 @@ void csp_connectionless_client(uint8_t dest_id, uint8_t dest_port, uint8_t src_p } csp_buffer_free(packet_sending); + onExit(params); } @@ -233,11 +234,11 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_o if (get_exit() || checkExit(other)) break; - - conn = csp_accept(sock, 10); + conn = csp_accept(sock, 1000); if (conn == NULL) { continue; } + ssp_printf("accepted\n"); while(1) { @@ -264,8 +265,8 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_o csp_close(conn); } - onExit(other); ssp_free(buff); + onExit(other); } @@ -320,8 +321,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, /* Close connection */ if (conn != NULL) csp_close(conn); - - onExit(params); ssp_free(buff); + onExit(params); } From 1ab730c2135f9937e0e7ef8b107c776e516398a5 Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 7 Jul 2021 20:22:10 -0600 Subject: [PATCH 367/400] reduce nak timer --- Program/src/file_delivery_app.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index ab21834..0ccca52 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -92,8 +92,8 @@ static void make_default_data(){ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ \"total_round_trip_allowance\" : 100000,\n\ - \"async_NAK_interval\" : 30000,\n\ - \"transaction_inactivity_limit\" : 15000,\n\ + \"async_NAK_interval\" : 1000,\n\ + \"transaction_inactivity_limit\" : 1500,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ \"prompt_transmission_interval\" : 123,\n\ @@ -114,8 +114,8 @@ static void make_default_data(){ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ \"total_round_trip_allowance\" : 100000,\n\ - \"async_NAK_interval\" : 30000,\n\ - \"transaction_inactivity_limit\" : 15000,\n\ + \"async_NAK_interval\" : 1000,\n\ + \"transaction_inactivity_limit\" : 1500,\n\ \"async_keep_alive_interval\" : 123,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ From d4eec237eaf2e43036f7f1c372eb8b76ce0a46b5 Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 7 Jul 2021 20:22:28 -0600 Subject: [PATCH 368/400] general 'main' client --- Program/src/main.c | 115 +++++++++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 40 deletions(-) diff --git a/Program/src/main.c b/Program/src/main.c index fb974a1..f434e20 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -27,7 +27,7 @@ Author: Evan Giese //for signal handler, because its nice #include "posix_server_provider.h" //for ssp_thread_join, can use p_thread join on linux - +#include "utils.h" #include "app_control.h" #include "mib.h" @@ -49,8 +49,24 @@ typedef struct config uint32_t baudrate; char *uart_device; bool unackowledged_mode; + uint8_t get_request; + char file_name[255]; + } Config; +//sets file_name and returns the length of the file_name +static int get_file_name(char *buff, int len, char *file_name) { + int i = 0; + for (i = 0; i < len; i++) { + if (buff[i] == ' ' || buff[i] == '\0') { + file_name[i] = '\0'; + break; + } + file_name[i] = buff[i]; + } + + return i; +} static Config *configuration(int argc, char **argv) { @@ -59,17 +75,20 @@ static Config *configuration(int argc, char **argv) if (conf == NULL) return NULL; - conf->timer = 15; conf->verbose_level = 0; conf->client_cfdp_id = -1; conf->my_cfdp_id = 0; conf->baudrate = 9600; conf->uart_device = NULL; - conf->unackowledged_mode = 0; + conf->unackowledged_mode = ACKNOWLEDGED_MODE; + conf->get_request = 0; + uint32_t tmp; - while ((ch = getopt(argc, argv, "t: i: c: v: k: hu ")) != -1) + char file_name[255]; + + while ((ch = getopt(argc, argv, "t: f: i: c: v: k: gphu")) != -1) { switch (ch) { @@ -82,14 +101,30 @@ static Config *configuration(int argc, char **argv) tmp = strtol(optarg, NULL, 10); conf->my_cfdp_id = tmp; break; - + + case 'f': + get_file_name(optarg, 254, conf->file_name); + break; + + case 'g': + conf->get_request = 1; + ssp_printf("get request\n"); + break; + + case 'p': + conf->get_request = 2; + ssp_printf("put request\n"); + break; + case 'v': tmp = strtol(optarg, NULL, 10); conf->verbose_level = (uint8_t) tmp; break; + case 'u': - conf->unackowledged_mode = true; + conf->unackowledged_mode = UN_ACKNOWLEDGED_MODE; break; + case 'c': tmp = strtol(optarg, NULL, 10); conf->client_cfdp_id = tmp; @@ -107,11 +142,14 @@ static Config *configuration(int argc, char **argv) case 'h': ssp_printf("\n-----------HELP MESSAGE------------\n"); ssp_printf("\nusage: %s [options] \n\n", basename(argv[0])); - ssp_printf("Options: %s%s%s%s\n", + ssp_printf("Options: %s%s%s%s%s%s%s\n", "-u un_ackowledged mode\n" "-t \n", "-i \n", "-c \n", + "-g get request\n", + "-p pot request\n", + "-f file name\n", "-v eg (1-3)" "-k eg /dev/ttyUSB0\n" "-b default is 9600" @@ -120,6 +158,11 @@ static Config *configuration(int argc, char **argv) ssp_printf("Default port number is 1111\n"); ssp_printf("\n---------------END----------------\n"); break; + + case ':': + ssp_printf("missing argument\n"); + break; + default: ssp_printf("\ngot something not found using default\n"); break; @@ -128,17 +171,19 @@ static Config *configuration(int argc, char **argv) return conf; } + static int init_csp_stuff(Config conf){ #ifdef CSP_NETWORK - /* - csp_debug_level_t debug_level = CSP_INFO; - // enable/disable debug levels + csp_debug_level_t debug_level = 0; + // enable/disable debug levels + /* for (csp_debug_level_t i = 0; i <= CSP_LOCK; ++i) { csp_debug_set_level(i, (i <= debug_level) ? true : false); } */ + Remote_entity remote_entity; int error = get_remote_entity_from_json(&remote_entity, conf.my_cfdp_id); @@ -158,11 +203,11 @@ static int init_csp_stuff(Config conf){ csp_log_error("csp_init() failed, error: %d", error); exit(1); } - + /* for (int i = 0; i <= CSP_LOCK; ++i) { csp_debug_set_level(i, true); } - + */ // Start router task with 10000 bytes of stack (priority is only supported on FreeRTOS) csp_route_start_task(500, 0); @@ -195,19 +240,6 @@ static int init_csp_stuff(Config conf){ #endif return 0; } -//sets file_name and returns the length of the file_name -static int get_file_name(char *buff, int len, char *file_name) { - int i = 0; - for (i = 0; i < len; i++) { - if (buff[i] == ' ' || buff[i] == '\0') { - file_name[i] = '\0'; - break; - } - file_name[i] = buff[i]; - } - - return i; -} static int confirm(){ @@ -225,7 +257,7 @@ static int confirm(){ } } -/* + static void input_daemon(uint32_t client_id, FTP *app){ int buff_len = 25000; @@ -260,10 +292,10 @@ static void input_daemon(uint32_t client_id, FTP *app){ len = get_file_name(&input[len + 5], buff_len, dest_file); while(1) { - printf("put source_file:%s destination_file:%s?(y/n)\n", src_file, dest_file); + printf("put source_file:%s destination_file:%s? (y/n): ", src_file, dest_file); int confirming = confirm(); if (confirming) { - put_request(client_id, src_file, dest_file, ACKNOWLEDGED_MODE, app); + start_request(put_request(client_id, src_file, dest_file, ACKNOWLEDGED_MODE, app)); break; } else if (confirming == 0) { break; @@ -282,7 +314,7 @@ static void input_daemon(uint32_t client_id, FTP *app){ printf("get destination_file:%s source_file:%s?(y/n)\n", src_file, dest_file); int confirming = confirm(); if (confirming) { - get_request(client_id, src_file, dest_file, ACKNOWLEDGED_MODE, app); + start_request(get_request(client_id, src_file, dest_file, ACKNOWLEDGED_MODE, app)); break; } else if (confirming == 0) { break; @@ -294,7 +326,7 @@ static void input_daemon(uint32_t client_id, FTP *app){ } } } -*/ + int main(int argc, char** argv) { @@ -303,10 +335,16 @@ int main(int argc, char** argv) { //get-opt configuration Config *conf = configuration(argc, argv); + if (conf->my_cfdp_id == 0){ printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } + + if (conf->get_request == false) { + ssp_printf("get request or put request not specified\n"); + return 1; + } init_csp_stuff(*conf); @@ -320,21 +358,18 @@ int main(int argc, char** argv) { uint32_t client_id = conf->client_cfdp_id; - //input_daemon(client_id, &app); - //csp_custom_ftp_ping(client_id, 1); - if (client_id != -1) { sleep(5); - start_request(put_request(client_id, "pictures/udp.jpg", "test-received.jpg", ACKNOWLEDGED_MODE, &app)); - - - //put_request(client_id, "udp.jpeg", "udp.jpeg", conf->unackowledged_mode, &app); - //put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); - //start_request(get_request(client_id, "mib/peer_1.json", "GET_REQUEST.json", ACKNOWLEDGED_MODE, &app)); + + if (conf->get_request == 1) { + start_request(get_request(client_id, conf->file_name, conf->file_name, conf->unackowledged_mode, &app)); + } + else if (conf->get_request == 2) { + start_request(put_request(client_id, conf->file_name, conf->file_name, conf->unackowledged_mode, &app)); + } } - free(conf); ssp_thread_join(handler); From d5e03565ca21187765c287a020bc43fface62801 Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 7 Jul 2021 20:22:50 -0600 Subject: [PATCH 369/400] add taskDelete to client thread cleanup --- Program/src/port.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Program/src/port.c b/Program/src/port.c index 5de22cb..6303759 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -201,7 +201,7 @@ void ssp_sendto(Response res) { ssp_printf("couldn't get packet, is NULL"); } - ssp_printf("sending packet to dest %d port %d srcaddr %d srcport %d \n", packet->id.dst, packet->id.dport, packet->id.src, packet->id.sport); + //ssp_printf("sending packet to dest %d port %d srcaddr %d srcport %d \n", packet->id.dst, packet->id.dport, packet->id.src, packet->id.sport); ssp_memcpy(packet_sending->data, res.msg, res.packet_len); packet_sending->length = res.packet_len; @@ -410,4 +410,7 @@ void ssp_thread_join(void *thread_handle) { pthread_join(*handle, NULL); ssp_free(thread_handle); #endif + #ifdef FREE_RTOS_PORT + vTaskDelete(thread_handle); + #endif } From f9d5ea3cb225f297565c52cef33feef694a873a7 Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 7 Jul 2021 20:46:37 -0600 Subject: [PATCH 370/400] change round trip allowance --- Program/src/file_delivery_app.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 0ccca52..f56b5b7 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -91,7 +91,7 @@ static void make_default_data(){ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ - \"total_round_trip_allowance\" : 100000,\n\ + \"total_round_trip_allowance\" : 2000,\n\ \"async_NAK_interval\" : 1000,\n\ \"transaction_inactivity_limit\" : 1500,\n\ \"async_report_interval\" : 123,\n\ @@ -113,7 +113,7 @@ static void make_default_data(){ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ - \"total_round_trip_allowance\" : 100000,\n\ + \"total_round_trip_allowance\" : 2000,\n\ \"async_NAK_interval\" : 1000,\n\ \"transaction_inactivity_limit\" : 1500,\n\ \"async_keep_alive_interval\" : 123,\n\ From 7fb261d6219aed7613587c855966ee8d67afdd43 Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 7 Jul 2021 20:47:41 -0600 Subject: [PATCH 371/400] reduce round trip allowance --- Program/src/file_delivery_app.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 0ccca52..05bc922 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -91,7 +91,7 @@ static void make_default_data(){ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ - \"total_round_trip_allowance\" : 100000,\n\ + \"total_round_trip_allowance\" : 3000,\n\ \"async_NAK_interval\" : 1000,\n\ \"transaction_inactivity_limit\" : 1500,\n\ \"async_report_interval\" : 123,\n\ @@ -113,7 +113,7 @@ static void make_default_data(){ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ - \"total_round_trip_allowance\" : 100000,\n\ + \"total_round_trip_allowance\" : 3000,\n\ \"async_NAK_interval\" : 1000,\n\ \"transaction_inactivity_limit\" : 1500,\n\ \"async_keep_alive_interval\" : 123,\n\ From 013c9d5b3700aa0c9385b3eb87d62588d5ddc0f6 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 8 Jul 2021 19:03:32 -0600 Subject: [PATCH 372/400] make client tasks spin in freeRTOS --- Program/src/app_control.c | 4 ++++ Program/src/filesystem_funcs.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index cc5782a..3612f12 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -303,6 +303,10 @@ static void on_exit_client_callback (void *params) { return; client->close = true; + #ifdef FREE_RTOS_PORT + //free rtos has to spin, unlike pthreads + for(;;); + #endif } static void on_exit_server_callback (void *params) { diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 02745ca..f32eb01 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -437,7 +437,7 @@ static int get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id if (error < 0) return -1; - ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%lu%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".json"); + ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%llu%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".json"); return 1; } From 3ad2f528bee3ce6f14432e85a645aa63eca12103 Mon Sep 17 00:00:00 2001 From: evangee Date: Mon, 19 Jul 2021 15:40:08 -0600 Subject: [PATCH 373/400] fix some timeout issues --- Program/src/file_delivery_app.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 05bc922..38ef2bc 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -91,7 +91,7 @@ static void make_default_data(){ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ - \"total_round_trip_allowance\" : 3000,\n\ + \"total_round_trip_allowance\" : 10000,\n\ \"async_NAK_interval\" : 1000,\n\ \"transaction_inactivity_limit\" : 1500,\n\ \"async_report_interval\" : 123,\n\ @@ -113,7 +113,7 @@ static void make_default_data(){ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ \"MTU\" : 200,\n\ - \"total_round_trip_allowance\" : 3000,\n\ + \"total_round_trip_allowance\" : 10000,\n\ \"async_NAK_interval\" : 1000,\n\ \"transaction_inactivity_limit\" : 1500,\n\ \"async_keep_alive_interval\" : 123,\n\ From bdb59568558ff51d9501b0af895970ddd29d9a94 Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 20 Jul 2021 13:13:52 -0600 Subject: [PATCH 374/400] add 'closing connection' message --- Program/src/csp_server_provider.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 125db44..dd6e585 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -314,6 +314,8 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_buffer_free(packet); } + + ssp_printf("closing connection\n"); csp_close(conn); break; From a4515dbbe2cbaf0f0cba227dd985097239d2200a Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 20 Jul 2021 18:44:15 -0600 Subject: [PATCH 375/400] fix client Delete crash --- Program/src/port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Program/src/port.c b/Program/src/port.c index 6303759..bbd7ed4 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -411,6 +411,7 @@ void ssp_thread_join(void *thread_handle) { ssp_free(thread_handle); #endif #ifdef FREE_RTOS_PORT - vTaskDelete(thread_handle); + ssp_printf("joining client thread %d\n", thread_handle); + vTaskDelete(NULL); #endif } From 5319961fa2a58afb59d1e9c28582358a3420cb76 Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 20 Jul 2021 18:48:03 -0600 Subject: [PATCH 376/400] fix task delete crash --- Program/src/port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Program/src/port.c b/Program/src/port.c index 6303759..66af5e5 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -411,6 +411,7 @@ void ssp_thread_join(void *thread_handle) { ssp_free(thread_handle); #endif #ifdef FREE_RTOS_PORT - vTaskDelete(thread_handle); + ssp_printf("deleting client task\n"); + vTaskDelete(NULL); #endif } From 39696cf69292b728e582f3dd90d4951f05d5c6b5 Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 24 Jul 2021 12:14:28 -0600 Subject: [PATCH 377/400] spin lock for clients to wait until app is ready --- Program/src/file_delivery_app.c | 2 ++ Program/src/requests.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 38ef2bc..cc192a4 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -208,6 +208,7 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { app->current_request = NULL; ssp_printf("initializing ftp server task: "); + app->initialized = true; return create_ssp_server_drivers(app); } @@ -268,6 +269,7 @@ Client *init_client(uint32_t dest_cfdp_id, uint32_t my_cfdp_id){ Client *ssp_client(uint32_t cfdp_id, FTP *app) { + Client *client = init_client(cfdp_id, app->my_cfdp_id); if (client == NULL) { return NULL; diff --git a/Program/src/requests.c b/Program/src/requests.c index 0cefd9e..79c9ec3 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -302,6 +302,9 @@ Request *init_request(char *buff, uint32_t buff_len) { Client *start_client(FTP *app, uint8_t dest_id) { + + + while (!app->initialized); //spin up a new client thread Client *client = (Client *) app->active_clients->find(app->active_clients, dest_id, NULL, NULL); From 3b466bdcc322c405fe6bb6948c0407adb4fa00ab Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 24 Jul 2021 15:29:19 -0600 Subject: [PATCH 378/400] quality of life, and add timeout to csp server --- Program/include/types.h | 3 + Program/src/csp_server_provider.c | 4 +- Program/src/main.c | 158 +++++++++++++++++++++--------- 3 files changed, 120 insertions(+), 45 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index 16639b0..6260e19 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -672,6 +672,9 @@ typedef struct ftp { uint32_t transaction_sequence_number; uint8_t verbose_level; + + //is ok now to start client threads... probably. There is a chance that the server will not be ready yet to receive 'get requests' but that is a rare timing/scheduling. + bool initialized; //bool for exiting the server thread uint8_t close; diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index dd6e585..d3f455b 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -234,10 +234,12 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_o if (get_exit() || checkExit(other)) break; - conn = csp_accept(sock, 1000); + conn = csp_accept(sock, time_out); if (conn == NULL) { + onTimeOut(other); continue; } + ssp_printf("accepted\n"); while(1) { diff --git a/Program/src/main.c b/Program/src/main.c index f434e20..d61616a 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -30,6 +30,7 @@ Author: Evan Giese #include "utils.h" #include "app_control.h" #include "mib.h" +#include "list.h" #ifdef CSP_NETWORK #include @@ -49,11 +50,26 @@ typedef struct config uint32_t baudrate; char *uart_device; bool unackowledged_mode; - uint8_t get_request; - char file_name[255]; + List *file_list; } Config; +typedef enum request_type { + REQUEST_GET, + REQUEST_PUT +} Request_type; + + +typedef struct file_path_pair +{ + char dest_name[255]; + char src_name[255]; + Request_type type; + +} File_path_pair; + + + //sets file_name and returns the length of the file_name static int get_file_name(char *buff, int len, char *file_name) { int i = 0; @@ -68,6 +84,73 @@ static int get_file_name(char *buff, int len, char *file_name) { return i; } +//parses the file name paths between source and destination filenames +int parse_file_path(char *buff, int len, char *file_name) { + int i = 0; + for (i = 0; i < len; i++) { + if (buff[i] == ':') { + file_name[i] = '\0'; + break; + } + file_name[i] = buff[i]; + } + return i; +} + + + +List *parse_file_list(char *target){ + + int buff_size = 5000; + int len = strnlen(target, buff_size); + char string_name[buff_size]; + char source_name[255]; + char dest_name[255]; + + List *list = linked_list(); + + int i = 0; + int j = 0; + int path_len = 0; + File_path_pair pair; + memset(&pair, 0, sizeof(File_path_pair)); + + while (i < len) { + i += get_file_name(&target[i], len, string_name) + 1; + if (strncmp(string_name, "PUT", 4) == 0) { + + pair.type = REQUEST_PUT; + //ssp_printf("PUT REQUEST!!!!\n"); + } else if (strncmp(string_name, "GET", 4) == 0) { + + pair.type = REQUEST_GET; + //ssp_printf("GET REQUEST!!!!\n"); + } else { + + //ssp_printf("file name: %s\n", string_name); + j = 0; + path_len = strnlen(string_name, 255); + + j += parse_file_path(&string_name[j], path_len, source_name) + 1; + //printf("source_name %s %d\n",source_name, j); + strncpy(pair.src_name, source_name, 255); + + j += parse_file_path(&string_name[j], path_len, dest_name); + //printf("dest_name %s %d\n",dest_name, j); + strncpy(pair.dest_name, dest_name, 255); + + File_path_pair *add = ssp_alloc(1, sizeof(File_path_pair)); + memcpy(add, &pair, sizeof(File_path_pair)); + + list->push(list, add, -1); + + } + } + + return list; +} + + static Config *configuration(int argc, char **argv) { int ch; @@ -82,49 +165,29 @@ static Config *configuration(int argc, char **argv) conf->baudrate = 9600; conf->uart_device = NULL; conf->unackowledged_mode = ACKNOWLEDGED_MODE; - conf->get_request = 0; uint32_t tmp; char file_name[255]; - while ((ch = getopt(argc, argv, "t: f: i: c: v: k: gphu")) != -1) + while ((ch = getopt(argc, argv, "f: i: c: v: k: hu")) != -1) { switch (ch) { - case 't': - tmp = strtol(optarg, NULL, 10); - conf->timer = tmp; - break; - case 'i': tmp = strtol(optarg, NULL, 10); conf->my_cfdp_id = tmp; break; case 'f': - get_file_name(optarg, 254, conf->file_name); - break; - - case 'g': - conf->get_request = 1; - ssp_printf("get request\n"); - break; - - case 'p': - conf->get_request = 2; - ssp_printf("put request\n"); + conf->file_list = parse_file_list(optarg); break; - + case 'v': tmp = strtol(optarg, NULL, 10); conf->verbose_level = (uint8_t) tmp; break; - case 'u': - conf->unackowledged_mode = UN_ACKNOWLEDGED_MODE; - break; - case 'c': tmp = strtol(optarg, NULL, 10); conf->client_cfdp_id = tmp; @@ -142,15 +205,11 @@ static Config *configuration(int argc, char **argv) case 'h': ssp_printf("\n-----------HELP MESSAGE------------\n"); ssp_printf("\nusage: %s [options] \n\n", basename(argv[0])); - ssp_printf("Options: %s%s%s%s%s%s%s\n", - "-u un_ackowledged mode\n" - "-t \n", + ssp_printf("Options: %s%s%s%s\n", "-i \n", "-c \n", - "-g get request\n", - "-p pot request\n", - "-f file name\n", - "-v eg (1-3)" + "-f list of file names eg, \"PUT local/path:/path/on/sat GET /path/on/sat:local/path ...\"\n", + "-v eg (1-3)\n" "-k eg /dev/ttyUSB0\n" "-b default is 9600" "-h HelpMessage"); @@ -336,19 +395,16 @@ int main(int argc, char** argv) { //get-opt configuration Config *conf = configuration(argc, argv); + if (conf->my_cfdp_id == 0){ printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; } - - if (conf->get_request == false) { - ssp_printf("get request or put request not specified\n"); - return 1; - } init_csp_stuff(*conf); FTP app; + memset(&app, 0, sizeof(FTP)); uint32_t id = conf->my_cfdp_id; void *handler = create_ftp_task(id, &app); @@ -360,18 +416,32 @@ int main(int argc, char** argv) { if (client_id != -1) { - sleep(5); + while(conf->file_list->count > 0) { + File_path_pair *file_names = conf->file_list->pop(conf->file_list); - if (conf->get_request == 1) { - start_request(get_request(client_id, conf->file_name, conf->file_name, conf->unackowledged_mode, &app)); + if (file_names->type == REQUEST_PUT) { + ssp_printf("putting file %s path %s\n", file_names->src_name, file_names->dest_name); + start_request(put_request(client_id, file_names->src_name, file_names->dest_name, conf->unackowledged_mode, &app)); + } + else if (file_names->type == REQUEST_GET) { + ssp_printf("getting file %s to path %s\n", file_names->src_name, file_names->dest_name); + start_request(get_request(client_id, file_names->src_name, file_names->dest_name, conf->unackowledged_mode, &app)); + } + free(file_names); } - else if (conf->get_request == 2) { - start_request(put_request(client_id, conf->file_name, conf->file_name, conf->unackowledged_mode, &app)); + + while (app.active_clients->count != 0) { + sleep(1); } + + ssp_printf("closing app\n"); + app.close = 1; } - + if (conf->file_list != NULL) + conf->file_list->freeOnlyList(conf->file_list); + free(conf); ssp_thread_join(handler); - + return 0; } From aac7e9a3a46a90ba44215aa64ddd2961b65ba654 Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 24 Jul 2021 15:52:38 -0600 Subject: [PATCH 379/400] change deliminator, add TODO --- Program/src/app_control.c | 7 +++++-- Program/src/main.c | 10 +++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 3612f12..290e329 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -96,8 +96,11 @@ void remove_request_check(Node *node, void *request, void *args) { if (req->local_entity.transaction_finished_indication || req->transmission_mode == UN_ACKNOWLEDGED_MODE) { int error = delete_saved_request(req); - if (error < 0) - ssp_error("couldn't delete finished request, the request may have finished before journaling it\n"); + if (error < 0) { + //TODO check if file exists, errno should be present + //ssp_error("couldn't delete finished request, the request may have finished before journaling it\n"); + } + } ssp_cleanup_req(remove_this); diff --git a/Program/src/main.c b/Program/src/main.c index d61616a..9d1d684 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -88,7 +88,7 @@ static int get_file_name(char *buff, int len, char *file_name) { int parse_file_path(char *buff, int len, char *file_name) { int i = 0; for (i = 0; i < len; i++) { - if (buff[i] == ':') { + if (buff[i] == '|') { file_name[i] = '\0'; break; } @@ -208,7 +208,7 @@ static Config *configuration(int argc, char **argv) ssp_printf("Options: %s%s%s%s\n", "-i \n", "-c \n", - "-f list of file names eg, \"PUT local/path:/path/on/sat GET /path/on/sat:local/path ...\"\n", + "-f list of file names eg, \"PUT local/path|/path/on/sat GET /path/on/sat|local/path ...\"\n", "-v eg (1-3)\n" "-k eg /dev/ttyUSB0\n" "-b default is 9600" @@ -395,7 +395,7 @@ int main(int argc, char** argv) { //get-opt configuration Config *conf = configuration(argc, argv); - + if (conf->my_cfdp_id == 0){ printf("can't start server, please select an ID (-i #) and client ID (-c #) \n"); return 1; @@ -439,9 +439,9 @@ int main(int argc, char** argv) { } if (conf->file_list != NULL) conf->file_list->freeOnlyList(conf->file_list); - + free(conf); ssp_thread_join(handler); - + return 0; } From 97f5c9b5c4bba804b179def9acd00427a2f3c5a5 Mon Sep 17 00:00:00 2001 From: evangee Date: Mon, 2 Aug 2021 13:31:23 -0600 Subject: [PATCH 380/400] Add locking functions --- Program/include/port.h | 4 ++ Program/src/csp_server_provider.c | 4 +- Program/src/port.c | 96 +++++++++++++++++++++++++++- Program/test/main.c | 16 +++-- Program/test/makefile | 2 +- Program/test/server_tests.c | 102 +++++++++++++++++++++++++----- Program/test/unit_tests.h | 4 +- 7 files changed, 199 insertions(+), 29 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 1950208..d830c59 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -149,6 +149,10 @@ void *ssp_opendir(char *dir_name); int ssp_readdir(void *dir, char *file); int get_exit(); void set_exit(); +int ssp_lock_give(void *lock); +int ssp_lock_take(void *lock); +void *ssp_lock_create(); +int ssp_lock_destory(void *lock); void reset_request(Request *req); diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index d3f455b..8eb9591 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -290,10 +290,10 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, return; } - //Client *client = (Client*) params; + Client *client = (Client*) params; while (1) { - + if (get_exit() || checkExit(params)){ ssp_printf("exiting client thread\n"); break; diff --git a/Program/src/port.c b/Program/src/port.c index 66af5e5..1d6170c 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -42,6 +42,7 @@ static int exit_now = 0; #include #include #include + #include #endif @@ -402,6 +403,99 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void } +void *ssp_lock_create() { + #ifdef FREE_RTOS_PORT + + /* Create a mutex type semaphore. */ + void *lock = xSemaphoreCreateMutex(); + if (lock == NULL) { + ssp_printf("mutex init failed\n"); + return NULL; + } + + #else + pthread_mutex_t *lock = ssp_alloc(1, sizeof(pthread_mutex_t)); + if (lock == NULL) { + return NULL; + } + + if (pthread_mutex_init(lock, NULL) != 0) { + ssp_printf("mutex init failed\n"); + ssp_free(lock); + return NULL; + } + + #endif + return lock; +} + +int ssp_lock_destory(void *lock) { + #ifdef FREE_RTOS_PORT + #else + int error = pthread_mutex_destroy(lock); + + if (!error) { + return 1; + + } else if (error == EBUSY){ + ssp_printf("mutex is currently locked\n"); + } + #endif + return 0; +} + +int ssp_lock_give(void *lock) { + #ifdef FREE_RTOS_PORT3 + if( lock != NULL ) { + SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; + return xSemaphoreGive( xSemaphore ); + } + #else + + pthread_mutex_t *mutex = (pthread_mutex_t *) lock; + if (pthread_mutex_trylock(mutex) != 0) { + //lock is currently not locked + return 1; + } + + int error = pthread_mutex_unlock(mutex); + if (!error) { + return 1; + + } else if (error == EBUSY){ + ssp_printf("mutex is currently locked\n"); + } + + #endif + return 0; +} + +int ssp_lock_take(void *lock) { + #ifdef FREE_RTOS_PORT + SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; + if( xSemaphore != NULL ) { + return xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ); + } + #else + + pthread_mutex_t *mutex = (pthread_mutex_t *) lock; + if (pthread_mutex_trylock(mutex) != 0) { + return 0; + } + + int error = pthread_mutex_lock(mutex); + if (!error) { + return 1; + + } else { + ssp_printf("mutex lock take error %d\n", error); + } + + return 0; + #endif +} + + //not required for Free_rtos void ssp_thread_join(void *thread_handle) { @@ -412,6 +506,6 @@ void ssp_thread_join(void *thread_handle) { #endif #ifdef FREE_RTOS_PORT ssp_printf("deleting client task\n"); - vTaskDelete(NULL); + // Doesn't work vTaskDelete(NULL); #endif } diff --git a/Program/test/main.c b/Program/test/main.c index 389b11e..68a3a84 100755 --- a/Program/test/main.c +++ b/Program/test/main.c @@ -1,15 +1,17 @@ + #include "unit_tests.h" int main () { int error = 0; - error = request_tests(); - error = packet_tests(); - error = protocol_handler_test(); - error = list_tests(); - error = tasks_tests(); - error = file_system_tests(); - + //error = file_system_tests(); + //error = request_tests(); + //error = packet_tests(); + //error = protocol_handler_test(); + //error = tasks_tests(); + error = server_tests(); + //error = list_tests(); + return error; } \ No newline at end of file diff --git a/Program/test/makefile b/Program/test/makefile index 3f3489f..0323780 100755 --- a/Program/test/makefile +++ b/Program/test/makefile @@ -38,7 +38,7 @@ CFILES += $(PROJDIR)/test/list_tests.c CFILES += $(PROJDIR)/test/filesystem_tests.c CFILES += $(PROJDIR)/test/protocol_handler_tests.c CFILES += $(PROJDIR)/test/list_tests.c -#CFILES += $(PROJDIR)/test/server_tests.c +CFILES += $(PROJDIR)/test/server_tests.c #entrypoint diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index 9e05a70..b500327 100755 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -5,6 +5,7 @@ #include "port.h" #include "app_control.h" +#include "csp_server_provider.h" //-------------------------------- #include @@ -268,7 +269,7 @@ static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *b res.packet_len = 10; res.size_of_addr = size_of_addr; res.sfd = sfd; - res.type_of_network = csp; + res.type_of_network = csp_connection; res.transmission_mode = ACKNOWLEDGED_MODE; ssp_sendto(res); @@ -297,7 +298,7 @@ static int onSend(int sfd, void *addr, size_t size_of_addr, void *onSendParams) res.msg = "hello server!!\n"; res.packet_len = 12; res.sfd = sfd; - res.type_of_network = csp; + res.type_of_network = csp_connection; res.transmission_mode = ACKNOWLEDGED_MODE; printf("sending!!!\n"); @@ -319,6 +320,7 @@ static void onExitClient(void *params) { } void *ssp_csp_connectionless_server_task_test(void *params) { + /* printf("starting csp connectionless server\n"); csp_connectionless_server( @@ -329,22 +331,26 @@ void *ssp_csp_connectionless_server_task_test(void *params) { checkExit, onExit, params); - + */ return NULL; } void *ssp_csp_connectionless_client_task_test(void *params) { + printf("starting csp connectionless client\n"); + /* csp_connectionless_client(1, 1, 2, onSend, onRecvClient, checkExitClient, onExitClient, params); return NULL; + */ } void *ssp_csp_connection_server_task_test(void *params) { + /* csp_connection_server(1, onRecvServer, onTimeOut, @@ -352,17 +358,20 @@ void *ssp_csp_connection_server_task_test(void *params) { checkExit, onExit, params); + */ } void *ssp_csp_connection_client_task_test(void *params) { + /* csp_connection_client(1, 1, onSend, onRecvClient, checkExitClient, onExitClient, params); + */ } /* void *ssp_csp_connectionless_client_task_test(void *params) { @@ -375,32 +384,93 @@ void *ssp_csp_connectionless_client_task_test(void *params) { } */ -int server_tests(int client){ + +int test_lock_create(){ + void *lock = ssp_lock_create(); + ASSERT_NOT_NULL("lock initialized", lock); + + if (lock == NULL) + return 1; + + int success = ssp_lock_destory(lock); + ASSERT_EQUALS_INT("lock destroy success", success, 1); + + ssp_free(lock); + return 0; + +} + +int test_lock_get(){ + + void *lock = ssp_lock_create(); + if (lock == NULL) + return 1; + + int success = ssp_lock_take(lock); + ASSERT_EQUALS_INT("successfully got lock", success, 1); + + success = ssp_lock_destory(lock); + ASSERT_EQUALS_INT("lock destroy success", success, 1); + + ssp_free(lock); + return success; +} + + +int test_lock_give(){ + void *lock = ssp_lock_create(); + if (lock == NULL) + return 1; + + int success = ssp_lock_give(lock); + ASSERT_EQUALS_INT("successfully gave lock", success, 1); + + success = ssp_lock_destory(lock); + ASSERT_EQUALS_INT("lock destroy success", success, 1); + + ssp_free(lock); + return success; + +} + + +int server_tests(int client) { int buffsize = 10000; char buff[buffsize]; /* Init buffer system with 10 packets of maximum 300 bytes each */ printf("Initialising CSP\r\n"); - csp_buffer_init(100, 300); - /* Init CSP with address MY_ADDRESS */ - csp_init(1); + csp_conf_t csp_conf; + csp_conf_get_defaults(&csp_conf); + csp_conf.buffers = 4096; + csp_conf.address = 1; + csp_conf.buffer_data_size = 250; - /* Start router task with 500 word stack, OS task priority 1 */ - csp_route_start_task(500, 1); + int error = csp_init(&csp_conf); + if (error != CSP_ERR_NONE) { + csp_log_error("csp_init() failed, error: %d", error); + exit(1); + } -// void *handle = ssp_thread_create(20000, ssp_csp_connectionless_server_task_test, NULL); -// void *handle2 = ssp_thread_create(20000, ssp_csp_connectionless_client_task_test, NULL); - void *handle = ssp_thread_create(20000, ssp_csp_connection_server_task_test, NULL); - void *handle2 = ssp_thread_create(20000, ssp_csp_connection_client_task_test, NULL); + error = test_lock_create(); + error = test_lock_give(); + error = test_lock_get(); + + + //void *handle = ssp_thread_create(20000, ssp_csp_connectionless_server_task_test, NULL); + //void *handle2 = ssp_thread_create(20000, ssp_csp_connectionless_client_task_test, NULL); + //void *handle = ssp_thread_create(20000, ssp_csp_connection_server_task_test, NULL); + //void *handle2 = ssp_thread_create(20000, ssp_csp_connection_client_task_test, NULL); //test_csp_connectionless_server(); - ssp_thread_join(handle); - ssp_thread_join(handle2); + //ssp_thread_join(handle); + //ssp_thread_join(handle2); + /* if (client) { printf("I'm a client!\n"); //connection_client("127.0.0.1", "1111", buffsize, NULL, NULL, NULL, NULL, onSend, onRecvClient, checkExitClient, onExitClient); @@ -417,6 +487,6 @@ int server_tests(int client){ //csp_connectionless_server(1, 1, onRecvServer, onTimeOut, onStdIn, checkExit, onExit, NULL); //csp_connection_server(); } - + */ return 0; } diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index 229a72d..ca910db 100755 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -12,6 +12,7 @@ int list_tests(); int file_system_tests(); int request_tests(); int protocol_handler_test(); +int server_tests(); int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); Response *mock_response(); @@ -21,8 +22,7 @@ Request *mock_empty_request(); List *populate_request_list(); Client *mock_client(); -#define TEMP_FILESIZE 1000 -//int server_tests(int client ); +#define TEMP_FILESIZE 1000 #endif \ No newline at end of file From ddc04c73539e94afd178d43ad05557ee64b39284 Mon Sep 17 00:00:00 2001 From: evangee Date: Mon, 2 Aug 2021 15:21:36 -0600 Subject: [PATCH 381/400] basic locking for continuous csp RTOS tasks --- Program/include/csp_server_provider.h | 2 +- Program/include/types.h | 3 ++ Program/src/app_control.c | 48 +++++++++++++++--------- Program/src/csp_server_provider.c | 15 +++++--- Program/src/file_delivery_app.c | 2 + Program/src/port.c | 30 ++++++++------- Program/src/requests.c | 3 ++ Program/test/server_tests.c | 53 ++++++++++++++++++--------- 8 files changed, 102 insertions(+), 54 deletions(-) diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index 4934539..d73b512 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -29,7 +29,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_o void (*onExit)(void *other), void *other); -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, uint32_t time_out, +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, uint32_t time_out, void*lock, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), diff --git a/Program/include/types.h b/Program/include/types.h index 6260e19..fdf20d1 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -707,6 +707,9 @@ typedef struct client { //bool for exiting the client thread bool close; + + //for contiuously running clients + void *lock; } Client; diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 290e329..cb7e1a5 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -175,7 +175,7 @@ static int on_send_client_callback(int sfd, void *addr, size_t size_of_addr, voi Response res; Client *client = (Client *) other; - if (client->request_list->count == 0){ + if (client->request_list->count == 0 && client->lock == NULL){ client->close = true; return 0; } @@ -289,7 +289,7 @@ static int check_exit_server_callback(void *params) { static int check_exit_client_callback(void *params) { Client *client = (Client*) params; - if (client->close) + if (client->close) return 1; return 0; } @@ -306,10 +306,6 @@ static void on_exit_client_callback (void *params) { return; client->close = true; - #ifdef FREE_RTOS_PORT - //free rtos has to spin, unlike pthreads - for(;;); - #endif } static void on_exit_server_callback (void *params) { @@ -532,17 +528,29 @@ void *ssp_csp_connection_server_task(void *params) { void *ssp_csp_connection_client_task(void *params) { #ifdef CSP_NETWORK ssp_printf("starting csp connection client\n"); + Client *client = (Client *) params; - csp_connection_client(client->remote_entity.UT_address, - client->remote_entity.UT_port, - CSP_ANY, - client->remote_entity.mtu, - client->remote_entity.total_round_trip_allowance, - on_send_client_callback, - on_recv_client_callback, - check_exit_client_callback, - on_exit_client_callback, - params); + + #ifdef FREE_RTOS_PORT + + void *lock = ssp_lock_create(); + if (lock == NULL) + return NULL; + + client->lock = lock; + #endif + + csp_connection_client(client->remote_entity.UT_address, + client->remote_entity.UT_port, + CSP_ANY, + client->remote_entity.mtu, + client->remote_entity.total_round_trip_allowance, + client->lock, + on_send_client_callback, + on_recv_client_callback, + check_exit_client_callback, + on_exit_client_callback, + params); #endif #ifndef CSP_NETWORK @@ -572,11 +580,14 @@ void ssp_cleanup_client(Client *client) { return; client->request_list->free(client->request_list, ssp_cleanup_req); + ssp_lock_give(client->lock); + ssp_lock_destory(client->lock); ssp_free(client->buff); ssp_free(client); } -void ssp_client_join(Client *client) { +void ssp_client_join(Client *client) { + ssp_thread_join(client->client_handle); ssp_cleanup_client(client); } @@ -587,6 +598,8 @@ static void exit_client(Node *node, void *element, void *args) { Client *client = (Client *) element; client->close = true; + //in case we are currently blocking in the client thread + ssp_lock_give(client->lock); } void ssp_cleanup_ftp(FTP *app) { @@ -595,5 +608,4 @@ void ssp_cleanup_ftp(FTP *app) { app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); app->active_clients->freeOnlyList(app->active_clients); ssp_free(app->buff); - } diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 8eb9591..52d0578 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -272,7 +272,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_o } -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, uint32_t time_out, +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, uint32_t time_out, void*lock, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), @@ -283,7 +283,6 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, csp_packet_t * packet = NULL; csp_conn_t * conn = NULL; - char *buff = ssp_alloc(packet_len, sizeof(char)); if (buff == NULL) { ssp_printf("exiting client thread\n"); @@ -294,10 +293,14 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, while (1) { + //lock will block, need to unlock when new request/s are started + ssp_lock_take(lock); + if (get_exit() || checkExit(params)){ ssp_printf("exiting client thread\n"); break; } + /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ conn = csp_connect(CSP_PRIO_NORM, dest_id, dest_port, 100, CSP_SO_NONE); if (conn == NULL) { @@ -319,9 +322,11 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, ssp_printf("closing connection\n"); csp_close(conn); - break; - - } + + if (lock == NULL) + break; + + } /* Close connection */ if (conn != NULL) csp_close(conn); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index cc192a4..1983fa5 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -261,6 +261,8 @@ Client *init_client(uint32_t dest_cfdp_id, uint32_t my_cfdp_id){ client->close = 0; client->remote_entity = remote_entity; + client->lock = NULL; + get_header_from_mib(&client->pdu_header, remote_entity, my_cfdp_id); client->current_request = NULL; diff --git a/Program/src/port.c b/Program/src/port.c index 1d6170c..38d9e4d 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -430,11 +430,16 @@ void *ssp_lock_create() { } int ssp_lock_destory(void *lock) { + if (lock == NULL) { + return 0; + } + #ifdef FREE_RTOS_PORT #else int error = pthread_mutex_destroy(lock); if (!error) { + ssp_free(lock); return 1; } else if (error == EBUSY){ @@ -445,19 +450,17 @@ int ssp_lock_destory(void *lock) { } int ssp_lock_give(void *lock) { - #ifdef FREE_RTOS_PORT3 - if( lock != NULL ) { - SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; - return xSemaphoreGive( xSemaphore ); + if (lock == NULL) { + return 0; } - #else + + #ifdef FREE_RTOS_PORT + SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; + return xSemaphoreGive( xSemaphore ); + #else pthread_mutex_t *mutex = (pthread_mutex_t *) lock; - if (pthread_mutex_trylock(mutex) != 0) { - //lock is currently not locked - return 1; - } - + int error = pthread_mutex_unlock(mutex); if (!error) { return 1; @@ -471,6 +474,10 @@ int ssp_lock_give(void *lock) { } int ssp_lock_take(void *lock) { + if (lock == NULL) { + return 0; + } + #ifdef FREE_RTOS_PORT SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; if( xSemaphore != NULL ) { @@ -479,9 +486,6 @@ int ssp_lock_take(void *lock) { #else pthread_mutex_t *mutex = (pthread_mutex_t *) lock; - if (pthread_mutex_trylock(mutex) != 0) { - return 0; - } int error = pthread_mutex_lock(mutex); if (!error) { diff --git a/Program/src/requests.c b/Program/src/requests.c index 79c9ec3..61b2a3e 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -331,6 +331,9 @@ void add_request_to_client(Request *req, Client *client) { req->buff_len = client->packet_len; client->request_list->insert(client->request_list, req, -1); + //unlock if lock is present + ssp_lock_give(client->lock); + } int put_request_no_client( diff --git a/Program/test/server_tests.c b/Program/test/server_tests.c index b500327..8955bad 100755 --- a/Program/test/server_tests.c +++ b/Program/test/server_tests.c @@ -269,7 +269,7 @@ static int onRecvServer(int sfd, char *packet, uint32_t packet_len, uint32_t *b res.packet_len = 10; res.size_of_addr = size_of_addr; res.sfd = sfd; - res.type_of_network = csp_connection; + res.type_of_network = test; res.transmission_mode = ACKNOWLEDGED_MODE; ssp_sendto(res); @@ -298,7 +298,7 @@ static int onSend(int sfd, void *addr, size_t size_of_addr, void *onSendParams) res.msg = "hello server!!\n"; res.packet_len = 12; res.sfd = sfd; - res.type_of_network = csp_connection; + res.type_of_network = test; res.transmission_mode = ACKNOWLEDGED_MODE; printf("sending!!!\n"); @@ -359,19 +359,26 @@ void *ssp_csp_connection_server_task_test(void *params) { onExit, params); */ + } void *ssp_csp_connection_client_task_test(void *params) { - /* - csp_connection_client(1, 1, - onSend, - onRecvClient, - checkExitClient, - onExitClient, - params); - */ + ssp_printf("starting csp connection client\n"); + Client *client = (Client *) params; + + csp_connection_client(1, + 1, + CSP_ANY, + 200, + 1000, + client->lock, + onSend, + onRecvClient, + checkExitClient, + onExitClient, + params); } /* void *ssp_csp_connectionless_client_task_test(void *params) { @@ -395,7 +402,6 @@ int test_lock_create(){ int success = ssp_lock_destory(lock); ASSERT_EQUALS_INT("lock destroy success", success, 1); - ssp_free(lock); return 0; } @@ -409,10 +415,12 @@ int test_lock_get(){ int success = ssp_lock_take(lock); ASSERT_EQUALS_INT("successfully got lock", success, 1); + success = ssp_lock_give(lock); + ASSERT_EQUALS_INT("successfully gave lock", success, 1); + success = ssp_lock_destory(lock); ASSERT_EQUALS_INT("lock destroy success", success, 1); - ssp_free(lock); return success; } @@ -428,13 +436,13 @@ int test_lock_give(){ success = ssp_lock_destory(lock); ASSERT_EQUALS_INT("lock destroy success", success, 1); - ssp_free(lock); return success; } -int server_tests(int client) { + +int server_tests() { int buffsize = 10000; char buff[buffsize]; @@ -460,14 +468,25 @@ int server_tests(int client) { error = test_lock_get(); + + Client client; + memset(&client, 0, sizeof(Client)); + + void *lock = ssp_lock_create(); + client.lock = lock; + + //void *handle = ssp_thread_create(20000, ssp_csp_connectionless_server_task_test, NULL); //void *handle2 = ssp_thread_create(20000, ssp_csp_connectionless_client_task_test, NULL); //void *handle = ssp_thread_create(20000, ssp_csp_connection_server_task_test, NULL); - //void *handle2 = ssp_thread_create(20000, ssp_csp_connection_client_task_test, NULL); + void *handle2 = ssp_thread_create(20000, ssp_csp_connection_client_task_test, &client); //test_csp_connectionless_server(); - + + sleep(5); + ssp_lock_give(client.lock); + //ssp_thread_join(handle); - //ssp_thread_join(handle2); + ssp_thread_join(handle2); /* From a72097247831f4aaf239134c9e3c695740ebac49 Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 8 Aug 2021 18:33:12 -0600 Subject: [PATCH 382/400] add binary semiphore --- Program/src/port.c | 27 ++++++++++++++++++++++----- Program/src/protocol_handler.c | 4 +++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 38d9e4d..40f30be 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -407,7 +407,7 @@ void *ssp_lock_create() { #ifdef FREE_RTOS_PORT /* Create a mutex type semaphore. */ - void *lock = xSemaphoreCreateMutex(); + void *lock = xSemaphoreCreateBinary(); if (lock == NULL) { ssp_printf("mutex init failed\n"); return NULL; @@ -456,8 +456,14 @@ int ssp_lock_give(void *lock) { #ifdef FREE_RTOS_PORT SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; - return xSemaphoreGive( xSemaphore ); - + ssp_printf("waiting to give client lock\n"); + if (xSemaphoreGive( xSemaphore ) == pdTRUE) { + ssp_printf("gave the lock\n"); + return 1; + } + ssp_printf("couldn't give the lock\n"); + return 0; + #else pthread_mutex_t *mutex = (pthread_mutex_t *) lock; @@ -469,6 +475,8 @@ int ssp_lock_give(void *lock) { ssp_printf("mutex is currently locked\n"); } + + #endif return 0; } @@ -480,8 +488,17 @@ int ssp_lock_take(void *lock) { #ifdef FREE_RTOS_PORT SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; - if( xSemaphore != NULL ) { - return xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ); + if( xSemaphore == NULL ) { + return 0; + } + + ssp_printf("waiting for client lock\n"); + if (xSemaphoreTake( xSemaphore, portMAX_DELAY) == pdTRUE) { + ssp_printf("took the lock\n"); + return 1; + } else { + ssp_printf("couldn't take the lock\n"); + return 0; } #else diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index f750cf2..7bc81ae 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -784,7 +784,9 @@ static void process_metadata(char *packet, uint32_t packet_index, Response res, else { ssp_printf("just receiving messages, closing request\n"); req->local_entity.EOF_recv_indication = true; - req->procedure = none; + //TODO this was set to clean_up on FreeRTOS because we didn't have a correct clock yet to, set to NONE when clock is right + //it kind of creates a weird timing issue when the request closes before the finacks are sent and received + req->procedure = clean_up; req->paused = true; } } From 2d9b59766647363c3bbcb24cd5480ce21b5cd287 Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 15 Aug 2021 15:15:00 -0600 Subject: [PATCH 383/400] add logging function --- Program/include/utils.h | 1 + Program/src/port.c | 17 ++++- Program/src/utils.c | 57 +++++++++++++++ Program/test/unit_tests.h | 1 + Program/test/utils.c | 143 ------------------------------------- Program/test/utils_tests.c | 9 +++ 6 files changed, 82 insertions(+), 146 deletions(-) delete mode 100755 Program/test/utils.c create mode 100755 Program/test/utils_tests.c diff --git a/Program/include/utils.h b/Program/include/utils.h index 9105d95..0be3ceb 100755 --- a/Program/include/utils.h +++ b/Program/include/utils.h @@ -12,5 +12,6 @@ Author: Evan Giese void ssp_print_hex(char *stuff, int size); void ssp_print_bits(char *stuff, int size); char *safe_strncpy(char *to, char*from, int len); +void log_ftp(char* info, char *stuff); #endif //UTILS_H diff --git a/Program/src/port.c b/Program/src/port.c index 40f30be..78eb0f1 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -23,6 +23,7 @@ static int exit_now = 0; #include #include #include + #include "utils.h" #endif #ifdef RED_FS @@ -315,9 +316,19 @@ void ssp_error(char *error){ void ssp_printf(char *stuff, ...) { va_list args; va_start(args, stuff); - vfprintf(stdout, stuff, args); - va_end (args); - fflush(stdout); + #ifdef FREE_RTOS_PORT + vfprintf(stdout, stuff, args); + va_end (args); + fflush(stdout); + #else + + char log_string[1000]; + int error = vsnprintf(log_string, sizeof(log_string), stuff, args); + log_ftp("INFO", log_string); + va_end (args); + + #endif + } #ifdef FREE_RTOS_PORT diff --git a/Program/src/utils.c b/Program/src/utils.c index e27f3d2..16a9fb7 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -6,6 +6,10 @@ Author: Evan Giese ------------------------------------------------------------------------------*/ #include "port.h" #include "utils.h" +#include +#include +#include + //size is the number of bytes we want to print void ssp_print_hex(char *stuff, int size){ @@ -20,6 +24,58 @@ void ssp_print_hex(char *stuff, int size){ ssp_printf("\n"); } + +static int log_fd = 0; +void log_ftp( char *info, char *stuff){ + + time_t current_time; + char c_time_string[1000]; + current_time = time(NULL); + + if (current_time == -1) { + ssp_printf("Failure to obtain the current time.\n"); + } + /* Convert to local time format. */ + struct tm *time = localtime(¤t_time); + + ssp_snprintf(c_time_string, sizeof(c_time_string), "%d-%d-%dT%d:%d:%dZ|%s|%s\n", + time->tm_year, + time->tm_mon, + time->tm_mday, + time->tm_hour, + time->tm_min, + time->tm_sec, + info, + stuff + ); + + if (c_time_string == NULL) { + printf("Failure to obtain the current time string.\n"); + return; + } + + if (log_fd == 0) { + if (does_file_exist("log.txt") == -1) { + ssp_printf("creating log\n"); + log_fd = ssp_open("log.txt", SSP_O_CREAT | SSP_O_RDWR | SSP_O_TRUNC, 0655); + } + else + log_fd = open("log.txt", SSP_O_RDWR | O_APPEND, 0655); + } + + int size = strnlen(c_time_string, sizeof(c_time_string)); + if (size < 0) { + printf("Failure to obtain the current time string.\n"); + return; + } + int bytes = write(log_fd, c_time_string, size); + if (bytes < 0) { + printf("Failure to write log string.\n"); + return; + } + +} + void ssp_print_bits(char *stuff, int size){ ssp_printf("printing number of bytes: %u\n", size); @@ -44,6 +100,7 @@ void ssp_print_bits(char *stuff, int size){ ssp_printf("\n"); } + //replace strings with this char *safe_strncpy(char *to, char*from, int len){ diff --git a/Program/test/unit_tests.h b/Program/test/unit_tests.h index ca910db..5ecbc0e 100755 --- a/Program/test/unit_tests.h +++ b/Program/test/unit_tests.h @@ -13,6 +13,7 @@ int file_system_tests(); int request_tests(); int protocol_handler_test(); int server_tests(); +int utils_tests(); int mock_packet(char *packet, uint32_t dest_id, uint32_t src_id); Response *mock_response(); diff --git a/Program/test/utils.c b/Program/test/utils.c deleted file mode 100755 index d9cc988..0000000 --- a/Program/test/utils.c +++ /dev/null @@ -1,143 +0,0 @@ - -/* -struct myStruct { - int id; - int b; -}; - - -static int list_remove(void *element, void *args) { - - int id = *(int *) args; - struct myStruct *st = (struct myStruct *)element; - - if (id == ((struct myStruct*) element)->id) { - free(st); - return 1; - - } - return 0; -} - -static void list_print(void *element, void *args) { - - Offset *offset = (Offset *) element; - printf("missing offsets:start:%u end:%u\n", offset->start, offset->end); - - -} -static int find(void *element, void *args) { - - int id = *(int *) args; - if (id == ((struct myStruct*) element)->id) - return 1; - return 0; -} - - -static void list_free(void *element) { - - free(element); -} -*/ - - - - - /*test sequence of files - File *file = create_file("test.txt"); - ssp_printf("file size: %u\n", file->total_size); - - uint32_t data_size = PACKET_LEN - 4; - uint32_t data_start = 0; - uint32_t data_end = data_size; - - for (int i=0; i < file->total_size; i+= data_size) { - data_start = i; - data_end = data_size + i; - //ssp_printf("i:%d\n", data_end); - receive_offset(file, 0, data_start, data_end); - } - - receive_offset(file, 0, 48516, 48833); - /* - - //doesnt do this edge case because, would never request it? - - file->missing_offsets->print(file->missing_offsets, list_print, NULL); - - free_file(file); - - char *packet = "hello world"; - uint32_t checksum = calc_check_sum(packet, 10); - printf("%d\n", checksum); - - File *file = create_file("test2.txt"); - - checksum = check_sum_file(file, file->total_size, 20000); - printf("%d\n", checksum); - /* - char **ptr,*ptr1,*ptr2,*ptr3; - - ptr = malloc(sizeof(char*) * 2); - ptr1 = malloc(1); - ptr2 = malloc(1); - - *ptr1 = 'h'; - *ptr2 = 'i'; - - ptr[0] = ptr1; - ptr[1] = ptr2; - - printf("%c%c\n", *ptr[0], *ptr[1]); - - - - List *list = linked_list(); - //static void *findElement(List *list, int (*f)(void *element, void *args), void *args) - - struct myStruct *st = malloc(sizeof(struct myStruct)); - struct myStruct *st2 = malloc(sizeof(struct myStruct)); - struct myStruct *st3 = malloc(sizeof(struct myStruct)); - - st->id = 1; - st->b = 2; - - st2->id = 2; - st2->b = 3; - - st3->id = 3; - st3->b = 4; - - list->insert(list, st, 1); - list->insert(list, st2, 2); - list->push(list, st3, 3); - - list->push(list, list->pop(list), list->count); - - /* - list->insert(list, st3, 3); - list->print(list, list_print, NULL); - - //list_free(list->pop(list)); - - int id = 1; - struct myStruct *found = list->find(list, 1, NULL, NULL); - printf("found %d\n", found->id); - - id = 2; - found = list->find(list, 2, find, &id); - printf("found %d\n", found->id); - - found = list->find(list, 3, NULL, NULL); - printf("found %d\n", found->id); - - void * element = list->pop(list); - //free(list->remove(list, "3", NULL, NULL)); - //free(list->remove(list, "2", NULL, NULL)); - - - list->print(list, list_print, NULL); - - list->free(list, list_free); - */ \ No newline at end of file diff --git a/Program/test/utils_tests.c b/Program/test/utils_tests.c new file mode 100755 index 0000000..f26f9bf --- /dev/null +++ b/Program/test/utils_tests.c @@ -0,0 +1,9 @@ + + +#include "utils.h" +#include "unit_tests.h" + +int utils_tests() { + log_ftp("WARN", "log this"); + return 0; +} \ No newline at end of file From 13c4c2c197d76a7dcf1d6394d2f111f1c928bf7e Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 15 Aug 2021 16:07:16 -0600 Subject: [PATCH 384/400] update logging --- Program/src/file_delivery_app.c | 2 +- Program/src/port.c | 4 ++-- Program/src/protocol_handler.c | 6 +++--- Program/src/utils.c | 19 +++++++++++-------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 1983fa5..521853e 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -207,7 +207,7 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { app->current_request = NULL; - ssp_printf("initializing ftp server task: "); + ssp_printf("initializing ftp server task \n"); app->initialized = true; return create_ssp_server_drivers(app); } diff --git a/Program/src/port.c b/Program/src/port.c index 78eb0f1..390216f 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -322,8 +322,8 @@ void ssp_printf(char *stuff, ...) { fflush(stdout); #else - char log_string[1000]; - int error = vsnprintf(log_string, sizeof(log_string), stuff, args); + char log_string[2000]; + vsnprintf(log_string, sizeof(log_string), stuff, args); log_ftp("INFO", log_string); va_end (args); diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 7bc81ae..327a14c 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -15,9 +15,9 @@ Author: Evan Giese #include "app_control.h" static void transasction_log(char *msg, uint64_t transaction_sequence_number){ - ssp_printf("transaction: %llu ", transaction_sequence_number); - ssp_printf(msg); - ssp_printf("\n"); + char log_message[2000]; + ssp_snprintf(log_message, sizeof(log_message), "%s%llu|%s\n", "transaction:", transaction_sequence_number, msg); + ssp_printf(log_message); } static void build_temperary_file(Request *req, uint32_t size) { diff --git a/Program/src/utils.c b/Program/src/utils.c index 16a9fb7..37b81ad 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -26,7 +26,7 @@ void ssp_print_hex(char *stuff, int size){ static int log_fd = 0; -void log_ftp( char *info, char *stuff){ +void log_ftp(char *info, char *stuff){ time_t current_time; char c_time_string[1000]; @@ -35,10 +35,10 @@ void log_ftp( char *info, char *stuff){ if (current_time == -1) { ssp_printf("Failure to obtain the current time.\n"); } - /* Convert to local time format. */ + struct tm *time = localtime(¤t_time); - ssp_snprintf(c_time_string, sizeof(c_time_string), "%d-%d-%dT%d:%d:%dZ|%s|%s\n", + ssp_snprintf(c_time_string, sizeof(c_time_string), "%d-%d-%dT%d:%d:%dZ|%s|%s", time->tm_year, time->tm_mon, time->tm_mday, @@ -53,14 +53,16 @@ void log_ftp( char *info, char *stuff){ printf("Failure to obtain the current time string.\n"); return; } - + if (log_fd == 0) { - if (does_file_exist("log.txt") == -1) { - ssp_printf("creating log\n"); - log_fd = ssp_open("log.txt", SSP_O_CREAT | SSP_O_RDWR | SSP_O_TRUNC, 0655); + + int log_fd = ssp_open("log.txt", SSP_O_RDWR); + if (log_fd == -1){ + log_fd = ssp_open("log.txt", SSP_O_CREAT | SSP_O_RDWR, 0655); + return -1; } else - log_fd = open("log.txt", SSP_O_RDWR | O_APPEND, 0655); + log_fd = open("log.txt", SSP_O_RDWR | O_APPEND); } int size = strnlen(c_time_string, sizeof(c_time_string)); @@ -68,6 +70,7 @@ void log_ftp( char *info, char *stuff){ printf("Failure to obtain the current time string.\n"); return; } + int bytes = write(log_fd, c_time_string, size); if (bytes < 0) { printf("Failure to write log string.\n"); From 3346d37f1b5d6f0782c4daec35c6f76c8d909da3 Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 15 Aug 2021 16:24:11 -0600 Subject: [PATCH 385/400] improve posix logging --- Program/src/utils.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/Program/src/utils.c b/Program/src/utils.c index 37b81ad..b7c3057 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -25,7 +25,7 @@ void ssp_print_hex(char *stuff, int size){ } -static int log_fd = 0; +static int log_fd = -1; void log_ftp(char *info, char *stuff){ time_t current_time; @@ -54,29 +54,31 @@ void log_ftp(char *info, char *stuff){ return; } - if (log_fd == 0) { + if (log_fd < 0) { - int log_fd = ssp_open("log.txt", SSP_O_RDWR); + int log_fd = ssp_open("log.txt", SSP_O_RDWR, 0655); if (log_fd == -1){ log_fd = ssp_open("log.txt", SSP_O_CREAT | SSP_O_RDWR, 0655); - return -1; } - else - log_fd = open("log.txt", SSP_O_RDWR | O_APPEND); - } + else { + log_fd = ssp_open("log.txt", SSP_O_RDWR | O_APPEND); + + } - int size = strnlen(c_time_string, sizeof(c_time_string)); - if (size < 0) { - printf("Failure to obtain the current time string.\n"); - return; - } + int size = strnlen(c_time_string, sizeof(c_time_string)); + if (size < 0) { + printf("Failure to obtain the current time string.\n"); + return; + } - int bytes = write(log_fd, c_time_string, size); - if (bytes < 0) { - printf("Failure to write log string.\n"); - return; + int bytes = write(log_fd, c_time_string, size); + if (bytes < 0) { + printf("Failure to write log string.\n"); + return; + } + + close(log_fd); } - } void ssp_print_bits(char *stuff, int size){ From 023d32c8dc8ad96896dd78fde852411b974c22ff Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 19 Aug 2021 20:18:43 -0600 Subject: [PATCH 386/400] add python bindings plus debug statement --- Program/__init__.py | 0 Program/ftp_python.py | 57 +++++++++++++++++++++++++++++++++++++++++++ Program/src/packet.c | 6 ++--- Program/src/utils.c | 3 +++ 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 Program/__init__.py create mode 100644 Program/ftp_python.py diff --git a/Program/__init__.py b/Program/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Program/ftp_python.py b/Program/ftp_python.py new file mode 100644 index 0000000..ff1b7ed --- /dev/null +++ b/Program/ftp_python.py @@ -0,0 +1,57 @@ +import subprocess +from pprint import pprint +import os +import datetime + +def change_working_dir(): + path = os.path.abspath(__file__) + split = path.split("/")[0:-1] + split.append("src") + new_path = "/".join(split) + os.chdir(new_path) + + +class logger(): + def __init__(self, path="ftp_log/log.txt"): + self.log_file = self.create_ftp_log(path) + + def create_ftp_log(self, path): + if not os.path.exists("ftp_log"): + os.makedirs("ftp_log") + + file = open(path, "a") + return file + + def close(self): + self.log_file.close() + + def log(self, stuff): + self.log_file.writelines(str(datetime.datetime.today()) + ":" + stuff) + +def get_request(sat_path, file_path, block=True): + change_working_dir() + + print("need sudo password for opening /dev/ttyUSB0") + cmd = ["sudo", "./main", "-i", "10", "-c", "1", "-k", "/dev/ttyUSB0", "-f", 'GET {0}|{1}'.format(sat_path, file_path)] + + if block: + output = subprocess.run(cmd) + return + + #subprocess.Popen(cmd) + +def put_request(file_path, sat_path, block=True): + change_working_dir() + + print("need sudo password for opening /dev/ttyUSB0") + cmd = ["sudo", "./main", "-i", "10", "-c", "1", "-k", "/dev/ttyUSB0", "-f", 'PUT {0}|{1}'.format(file_path, sat_path)] + + if block: + output = subprocess.run(cmd) + return + + #subprocess.Popen(cmd) + + +if __name__ == "__main__": + print("thats not how you use this, please import either 'get_request' or 'put_request' into your program") diff --git a/Program/src/packet.c b/Program/src/packet.c index 8bf5969..2715427 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -49,6 +49,7 @@ int copy_id_to_packet(char *bytes, uint64_t id) { uint32_t length = 0; if (id < 0xFF){ + bytes[0] = (uint8_t) id; length = 1; } else if (id < 0xFFFF) { @@ -95,8 +96,6 @@ uint64_t copy_id_from_packet(char *bytes, uint32_t length_of_ids) { //returns amount of bytes written or -1 on error int copy_id_lv_to_packet(char *bytes, uint64_t id) { - - int len = copy_id_to_packet(&bytes[1], id); if (len < 0) { return -1; @@ -759,7 +758,8 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { ssp_free(m->value); return -1; } - //ssp_printf("idlen %d %d\n", id_len, proxy_put->destination_id); + + ssp_printf("idlen %d id %d\n", id_len, proxy_put->destination_id); message_start += id_len + 1; copy_lv_from_buffer(&proxy_put->source_file_name, packet, message_start); diff --git a/Program/src/utils.c b/Program/src/utils.c index b7c3057..f20598d 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -28,6 +28,7 @@ void ssp_print_hex(char *stuff, int size){ static int log_fd = -1; void log_ftp(char *info, char *stuff){ + #ifdef POSIX_PORT time_t current_time; char c_time_string[1000]; current_time = time(NULL); @@ -79,6 +80,8 @@ void log_ftp(char *info, char *stuff){ close(log_fd); } + #endif + return; } void ssp_print_bits(char *stuff, int size){ From ae88c773acdedb4a0a9d1994cdae4a6bfad0fc23 Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 19 Sep 2021 18:47:59 -0600 Subject: [PATCH 387/400] add sleep --- Program/src/main.c | 21 ++++++++++++--------- test.py | 10 ++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 test.py diff --git a/Program/src/main.c b/Program/src/main.c index 9d1d684..fd202fc 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -403,44 +403,47 @@ int main(int argc, char** argv) { init_csp_stuff(*conf); - FTP app; - memset(&app, 0, sizeof(FTP)); + FTP *app = ssp_alloc(1, sizeof(FTP)); uint32_t id = conf->my_cfdp_id; - void *handler = create_ftp_task(id, &app); + void *handler = create_ftp_task(id, app); if (handler == NULL) { return 1; } - uint32_t client_id = conf->client_cfdp_id; + while(app->my_cfdp_id != id); + sleep(1); + uint32_t client_id = conf->client_cfdp_id; if (client_id != -1) { - while(conf->file_list->count > 0) { File_path_pair *file_names = conf->file_list->pop(conf->file_list); if (file_names->type == REQUEST_PUT) { ssp_printf("putting file %s path %s\n", file_names->src_name, file_names->dest_name); - start_request(put_request(client_id, file_names->src_name, file_names->dest_name, conf->unackowledged_mode, &app)); + start_request(put_request(client_id, file_names->src_name, file_names->dest_name, conf->unackowledged_mode, app)); } else if (file_names->type == REQUEST_GET) { ssp_printf("getting file %s to path %s\n", file_names->src_name, file_names->dest_name); - start_request(get_request(client_id, file_names->src_name, file_names->dest_name, conf->unackowledged_mode, &app)); + + start_request(get_request(client_id, file_names->src_name, file_names->dest_name, conf->unackowledged_mode, app)); } free(file_names); } - while (app.active_clients->count != 0) { + while (app->active_clients->count != 0) { sleep(1); } ssp_printf("closing app\n"); - app.close = 1; + app->close = 1; } if (conf->file_list != NULL) conf->file_list->freeOnlyList(conf->file_list); free(conf); + ssp_cleanup_ftp(app); + ssp_thread_join(handler); return 0; diff --git a/test.py b/test.py new file mode 100644 index 0000000..d32fe92 --- /dev/null +++ b/test.py @@ -0,0 +1,10 @@ + +from Program import ftp_python +import os + +#ftp_python.put_request("pictures/log.txt", "log.c", block=True) + +print("RUNNING") +ftp_python.get_request("log.txt", "/home/evan/SAT/CCSDS_FileDeliveryProtocol/logreceived.txt", block=True) +#ftp_python.put_request("pictures/pic.jpeg", "sat_path.c", block=True) + From f36dac17703e758d93e0b9c4eeec96aa0c482358 Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 19 Sep 2021 19:08:31 -0600 Subject: [PATCH 388/400] Update ReadMe --- README.md | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9191f41..bf7db71 100755 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Supported network stacks: If you are compiling on Linux, it should compile posix compliant by default. ### Compiling CSP: + first, one needs to build the .a file for your specific cpu architecture. instructions can be found here: https://github.com/libcsp/libcsp @@ -72,10 +73,14 @@ if you want to join this thread, and it is a posix thread, you can run: ssp_thread_join(app->server_handle); if you want to exit this task for any reason set app->close = 1; -this will run the exiting subroutines and close the task. +this will run the exiting subroutines and close the thread. Free RTOS has +issues exiting tasks. FreeRTOS will spin up a task for every new +peer one wishes to commucate with, and block/deschedule if there is no activity. if you wish to send a file to a peer: +### Running in C + params: id of destination, source file name, @@ -121,6 +126,23 @@ example: start_request(req); +### Running in Python + +One can look at the 'test.y' file to get an idea of how it works. + + from Program import ftp_python + + #params: + #Source Path: The source path on the local computer. If this is not an absolute path, it will start its path from the 'src' directory + #Destination Path: The destination path on the satellite + #block: to block the python program or not. + ftp_python.put_request("pictures/log.txt", "log.c", block=True) + + #params: + #Source Path: The source path on the satellite. + #Destination Path: The destination path on the local computer, If this is not an absolute path, it will start its path from the 'src' directory. + #block: to block the python program or not. + ftp_python.get_request("log.txt", "/home/evan/SAT/CCSDS_FileDeliveryProtocol/logreceived.txt", block=True) # MIB (management information base) @@ -187,9 +209,16 @@ Below are the meanings of the fields for the MIB - async_NAK_interval This number represents the time in miliseconds we wait to recv a packet. If it expires, we send NAKs +- total_round_trip_allowance + This is the maximum time that a program will accept packets for (CSP stack only). This gets reset if the program receives a packet. In miliseconds. + +- transaction_inactivity_limit + This is the maximum time in miliseconds, that a program will keep a transaction 'open' to receive packets. If connection is lost, it + can be regained and continue the transaction while within this timeframe. The request will also be 'saved' in which we create + a metadata file with the current state of the transaction. This happens every transaction_inactivity_limit / 2. + - default_transmission_mode: not implemented - one_way_light_time : not implemented -- total_round_trip_allowance : not implemented - async_keep_alive_interval : not implemented - async_report_interval : not implemented - immediate_nak_mode_enabled : not implemented @@ -199,7 +228,6 @@ Below are the meanings of the fields for the MIB - keep_alive_discrepancy_limit : not implemented - positive_ack_timer_expiration_limit : not implemented - nak_timer_expiration_limit : not implemented -- transaction_inactivity_limit : not implemented if you want to get in contact with me email me at evangiese77@gmail.com From 1faccf815d179664fc6d40df68a0e1af371232c4 Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 19 Sep 2021 19:17:20 -0600 Subject: [PATCH 389/400] update README --- README.md | 73 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index bf7db71..bddee71 100755 --- a/README.md +++ b/README.md @@ -82,28 +82,30 @@ if you wish to send a file to a peer: ### Running in C params: -id of destination, -source file name, -name of the file as it will arrive at destination, -ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), -app + + : id of destination, + : source file path, If this is not an absolute path, it will start its path from the 'src' directory. + : destination file path, + : ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + : The FTP app struct pointer. example: - Request *req = put_request(, , , , &app); + Request *req = put_request(, , , , <&app>); start_request(req); if you wish to get a file from a peer, you can call get_request: params: -id of destination, -source file name, -name of the file as it will arrive at destination, -ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), -app -example: + : id of destination, + : source file path, + : destination file path, If this is not an absolute path, it will start its path from the 'src' directory. + : ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + : The FTP app struct pointer. + +example: Request *req = get_request(, , , , &app); start_request(req); @@ -112,17 +114,19 @@ if you wish to send a file from a peer via a proxy node, we need to add a 'messa if we jsut want to send messages, we can set the filenames to NULL: params: -id of destination, -source file name, -name of the file as it will arrive at destination, -ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), -app + + : id of destination, + : source file path, + : destination file path, If this is not an absolute path, it will start its path from the 'src' directory. + : ACKNOWLEDGED_MODE/UN_ACKNOWLEDGED_MODE (ACKNOWLEDGED_MODE will allow for acks/naks to be sent.), + : The FTP app struct pointer. + : The constructed Request struct from the 'request' example: - Request *req = put_request(, NULL, NULL, , &app); + Request *req = put_request(, NULL, NULL, , <&app>); - add_proxy_message_to_request(, , , req); + add_proxy_message_to_request(, , , ); start_request(req); @@ -132,16 +136,27 @@ One can look at the 'test.y' file to get an idea of how it works. from Program import ftp_python - #params: - #Source Path: The source path on the local computer. If this is not an absolute path, it will start its path from the 'src' directory - #Destination Path: The destination path on the satellite - #block: to block the python program or not. - ftp_python.put_request("pictures/log.txt", "log.c", block=True) - - #params: - #Source Path: The source path on the satellite. - #Destination Path: The destination path on the local computer, If this is not an absolute path, it will start its path from the 'src' directory. - #block: to block the python program or not. +params: + + + #: source file path, If this is not an absolute path, it will start its path from the 'src' directory. + #: destination file path, + #: to block the python program or not. + + #ftp_python.put_request(, , ) + + example + ftp_python.put_request("pictures/log.txt", "log.txt", block=True) + +params: + + #: source file path, + #: destination file path, If this is not an absolute path, it will start its path from the 'src' directory. + #: to block the python program or not. + + #ftp_python.get_request(, , ) + + example: ftp_python.get_request("log.txt", "/home/evan/SAT/CCSDS_FileDeliveryProtocol/logreceived.txt", block=True) # MIB (management information base) From cec6729b2814ee891f2c7dbfd268eb575e7d5996 Mon Sep 17 00:00:00 2001 From: evangee Date: Sun, 19 Sep 2021 19:18:38 -0600 Subject: [PATCH 390/400] another one --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bddee71..d7b210b 100755 --- a/README.md +++ b/README.md @@ -133,19 +133,18 @@ example: ### Running in Python One can look at the 'test.y' file to get an idea of how it works. - - from Program import ftp_python params: - #: source file path, If this is not an absolute path, it will start its path from the 'src' directory. #: destination file path, #: to block the python program or not. #ftp_python.put_request(, , ) - example +example: + + from Program import ftp_python ftp_python.put_request("pictures/log.txt", "log.txt", block=True) params: @@ -156,7 +155,9 @@ params: #ftp_python.get_request(, , ) - example: +example: + + from Program import ftp_python ftp_python.get_request("log.txt", "/home/evan/SAT/CCSDS_FileDeliveryProtocol/logreceived.txt", block=True) # MIB (management information base) From 56351c5a06433bf9068c91658c0b50350c7c45c2 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 08:49:05 -0600 Subject: [PATCH 391/400] update readme --- Program/ftp_python.py | 2 ++ Program/src/file_delivery_app.c | 5 ++- Program/src/main.c | 16 ++++----- Program/src/packet.c | 1 - README.md | 63 +++++++++++++++++++++++---------- test.py | 3 +- 6 files changed, 57 insertions(+), 33 deletions(-) diff --git a/Program/ftp_python.py b/Program/ftp_python.py index ff1b7ed..646384d 100644 --- a/Program/ftp_python.py +++ b/Program/ftp_python.py @@ -36,6 +36,7 @@ def get_request(sat_path, file_path, block=True): if block: output = subprocess.run(cmd) + print(output) return #subprocess.Popen(cmd) @@ -48,6 +49,7 @@ def put_request(file_path, sat_path, block=True): if block: output = subprocess.run(cmd) + print(output) return #subprocess.Popen(cmd) diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 521853e..c60f2e7 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -159,6 +159,7 @@ static void make_default_data(){ int init_ftp(uint32_t my_cfdp_address, FTP *app) { int error = 0; + //sanitize everything but the server_handle in case of race condition which sets the handler first. void *handler = app->server_handle; @@ -206,7 +207,6 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { } app->current_request = NULL; - ssp_printf("initializing ftp server task \n"); app->initialized = true; return create_ssp_server_drivers(app); @@ -215,8 +215,7 @@ int init_ftp(uint32_t my_cfdp_address, FTP *app) { static void init_ftp_task(void *app){ FTP *ap = (FTP *) app; - - int error = init_ftp(ap->my_cfdp_id, app); + int error = init_ftp(ap->my_cfdp_id, ap); if (error < 0) { //task failed to start destroy task/thread } diff --git a/Program/src/main.c b/Program/src/main.c index fd202fc..219a4c3 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -203,9 +203,9 @@ static Config *configuration(int argc, char **argv) break; case 'h': - ssp_printf("\n-----------HELP MESSAGE------------\n"); - ssp_printf("\nusage: %s [options] \n\n", basename(argv[0])); - ssp_printf("Options: %s%s%s%s\n", + printf("\n-----------HELP MESSAGE------------\n"); + printf("\nusage: %s [options] \n\n", basename(argv[0])); + printf("Options: %s%s%s%s\n", "-i \n", "-c \n", "-f list of file names eg, \"PUT local/path|/path/on/sat GET /path/on/sat|local/path ...\"\n", @@ -214,16 +214,16 @@ static Config *configuration(int argc, char **argv) "-b default is 9600" "-h HelpMessage"); - ssp_printf("Default port number is 1111\n"); - ssp_printf("\n---------------END----------------\n"); + printf("Default port number is 1111\n"); + printf("\n---------------END----------------\n"); break; case ':': - ssp_printf("missing argument\n"); + printf("missing argument\n"); break; default: - ssp_printf("\ngot something not found using default\n"); + printf("\ngot something not found using default\n"); break; } } @@ -442,8 +442,6 @@ int main(int argc, char** argv) { conf->file_list->freeOnlyList(conf->file_list); free(conf); - ssp_cleanup_ftp(app); - ssp_thread_join(handler); return 0; diff --git a/Program/src/packet.c b/Program/src/packet.c index 2715427..c0f85b4 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -759,7 +759,6 @@ uint32_t get_message_from_packet(char *packet, uint32_t start, Request *req) { return -1; } - ssp_printf("idlen %d id %d\n", id_len, proxy_put->destination_id); message_start += id_len + 1; copy_lv_from_buffer(&proxy_put->source_file_name, packet, message_start); diff --git a/README.md b/README.md index d7b210b..0801860 100755 --- a/README.md +++ b/README.md @@ -26,9 +26,38 @@ Supported network stacks: # Compilation Notes: -If you are compiling on Linux, it should compile posix compliant by default. +master branch is currently configured to be compiled on the Satellite Exalta-2. To +compile if for linux, change the files in /Program/include/port.h to include +POSIX_FILESYSTEM and POSIX_PORT, and comment out FREE_RTOS_PORT and RED_FS +what it should look like: -### Compiling CSP: + /*------------------------------------------------------------------------------ + This file is protected under copyright. If you want to use it, + please include this text, that is my only stipulation. + Author: Evan Giese + ------------------------------------------------------------------------------*/ + #ifndef PORT_H + #define PORT_H + + //#define FREE_RTOS_PORT + //#define RED_FS + #define CSP_NETWORK + + #define POSIX_FILESYSTEM + #define POSIX_PORT + +### Building + +To build for linux, we need to first install the CSP dependecy. We can +do this automatically by running: + + git submodule init + +followed by: + + git submodule update + +### Updating CSP: first, one needs to build the .a file for your specific cpu architecture. instructions can be found here: https://github.com/libcsp/libcsp @@ -37,18 +66,7 @@ archive file: Once one has the .a file by following the above instructions. simply link to it my adding the path to STATIC_FILES in our makefile: STATIC_FILES += /path/to/libcsp.a -.h files: -We need to include the .h files to our include path. We can do this -by linking the .h files to our INCLUDES in our makefile. -INCLUDES += /path/to/libcsp/include - -The last thing you need to do to let this app integrate seamlessly with csp, -is to make sure that CSP_NETWORK is defined in port.h and csp_server_provider.c -is uncommented in the makefile. - -run make to compile! - -### Compiling with FreeRTOS: +### Compiling with FreeRTOS (using make -- not for you Exalta-2): The best way to compile with FreeRTOS is to do the same thing as we did with libscp -- create an .a file, and link to the .h files. @@ -57,10 +75,19 @@ There are examples to help you with linking in the makefile. Once again, make sure that FREE_RTOS_PORT is defined in port.h and that POSIX_PORT is not defined. -run make to compile! - # Getting started: + +### Running using the linux build premade (basic) client + +To get a file: + sudo ./main -i 10 -c 1 -k "/dev/ttyUSB0 -f "GET |" + +To push a file: + sudo ./main -i 10 -c 1 -k "/dev/ttyUSB0 -f "PUT |" + +### Running in C + init the app or task with: void *handler = create_ftp_task(id, &app); @@ -79,8 +106,6 @@ peer one wishes to commucate with, and block/deschedule if there is no activity. if you wish to send a file to a peer: -### Running in C - params: : id of destination, @@ -132,7 +157,7 @@ example: ### Running in Python -One can look at the 'test.y' file to get an idea of how it works. +One can look at the 'test.py' file to get an idea of how it works. params: diff --git a/test.py b/test.py index d32fe92..7ba84e6 100644 --- a/test.py +++ b/test.py @@ -2,9 +2,10 @@ from Program import ftp_python import os -#ftp_python.put_request("pictures/log.txt", "log.c", block=True) +#ftp_python.put_request("pictures/log.txt", "log.txt", block=True) print("RUNNING") ftp_python.get_request("log.txt", "/home/evan/SAT/CCSDS_FileDeliveryProtocol/logreceived.txt", block=True) + #ftp_python.put_request("pictures/pic.jpeg", "sat_path.c", block=True) From 78e588465ead12806c5f72d66c414798d4895087 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 09:22:43 -0600 Subject: [PATCH 392/400] Add submodules, plz don't break exalta --- .gitignore | 7 +++++++ .gitmodules | 3 +++ 2 files changed, 10 insertions(+) create mode 100644 .gitmodules diff --git a/.gitignore b/.gitignore index 9a5167d..da3008f 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,10 @@ Program/libcsp *.jpg *.jpeg .gitignore + +Program/jsmn +SAT_BUILD +give_packet_loss.sh +packetStates +README.md +Program/libcsp \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e507c8e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Program/libcsp"] + path = Program/libcsp + url = git@github.com:EvanGee/libcsp.git From 9b8193ce4f86142c3d83ca5561b025d86c968609 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 09:27:49 -0600 Subject: [PATCH 393/400] add diff? --- Program/libcsp | 1 + 1 file changed, 1 insertion(+) create mode 160000 Program/libcsp diff --git a/Program/libcsp b/Program/libcsp new file mode 160000 index 0000000..35952db --- /dev/null +++ b/Program/libcsp @@ -0,0 +1 @@ +Subproject commit 35952dbdf086a94055d0adf996e36c7241750f60 From 9bd7bf20ef42fe6f799122c7f83c4cc00926b601 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 09:33:52 -0600 Subject: [PATCH 394/400] update readme --- .gitignore | 7 ++----- README.md | 30 +++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index da3008f..980989d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,9 +17,6 @@ Program/libcsp *.jpeg .gitignore -Program/jsmn -SAT_BUILD give_packet_loss.sh -packetStates -README.md -Program/libcsp \ No newline at end of file +Program/libcsp +Program/__pycache__ \ No newline at end of file diff --git a/README.md b/README.md index 0801860..5c5e419 100755 --- a/README.md +++ b/README.md @@ -55,7 +55,11 @@ do this automatically by running: followed by: - git submodule update + git submodule update + +Make sure you followed the comment steps in 'Compilation Notes' above, then change to the Program/src directory and run: + + make ### Updating CSP: @@ -81,10 +85,30 @@ and that POSIX_PORT is not defined. ### Running using the linux build premade (basic) client To get a file: - sudo ./main -i 10 -c 1 -k "/dev/ttyUSB0 -f "GET |" + + sudo ./main -i 10 -c 1 -k "/dev/ttyUSB0" -f "GET |" To push a file: - sudo ./main -i 10 -c 1 -k "/dev/ttyUSB0 -f "PUT |" + + sudo ./main -i 10 -c 1 -k "/dev/ttyUSB0" -f "PUT |" + +To get the help menu: + ./main -h + + -----------HELP MESSAGE------------ + + usage: main [options] + + Options: -i + -c + -f list of file names eg, "PUT local/path|/path/on/sat GET /path/on/sat|local/path ..." + -v eg (1-3) + -k eg /dev/ttyUSB0 + -b default is 9600 + -h HelpMessage + + ---------------END---------------- + ### Running in C From 68e3f05fa4bd6b8e223d5c172bb1da01419195fb Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 09:34:57 -0600 Subject: [PATCH 395/400] rename build instructions --- build_instructions => build_instructions_code_composer_studio.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename build_instructions => build_instructions_code_composer_studio.txt (100%) diff --git a/build_instructions b/build_instructions_code_composer_studio.txt similarity index 100% rename from build_instructions rename to build_instructions_code_composer_studio.txt From 8d859b6ecd7824c1de8bc94887977ea671bee1f5 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 10:53:09 -0600 Subject: [PATCH 396/400] update readme with log instructions --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 5c5e419..2bd0a44 100755 --- a/README.md +++ b/README.md @@ -109,6 +109,9 @@ To get the help menu: ---------------END---------------- +To track the file progress, one can tail the log file: + + tail -F Program/src/log.txt ### Running in C From 314cc41a42f40e157255c1ece30ac7fb90473e6b Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 12:11:04 -0600 Subject: [PATCH 397/400] set lock to open on init --- Program/include/port.h | 5 +++-- Program/src/app_control.c | 3 +++ Program/src/port.c | 8 ++++---- Program/src/requests.c | 4 +++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index d830c59..c5a39bb 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -7,15 +7,16 @@ Author: Evan Giese #ifndef PORT_H #define PORT_H + #define FREE_RTOS_PORT #define RED_FS -#define CSP_NETWORK +#define CSP_NETWORK //#define POSIX_FILESYSTEM //#define POSIX_PORT #include "types.h" -#define STACK_ALLOCATION 20000 +#define STACK_ALLOCATION 2000 #ifdef CSP_NETWORK #include "csp/csp.h" diff --git a/Program/src/app_control.c b/Program/src/app_control.c index cb7e1a5..5d63fd6 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -537,6 +537,9 @@ void *ssp_csp_connection_client_task(void *params) { if (lock == NULL) return NULL; + //start out with open lock + ssp_lock_give(lock); + client->lock = lock; #endif diff --git a/Program/src/port.c b/Program/src/port.c index 390216f..8af3e68 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -467,9 +467,9 @@ int ssp_lock_give(void *lock) { #ifdef FREE_RTOS_PORT SemaphoreHandle_t xSemaphore = (SemaphoreHandle_t) lock; - ssp_printf("waiting to give client lock\n"); + if (xSemaphoreGive( xSemaphore ) == pdTRUE) { - ssp_printf("gave the lock\n"); + //ssp_printf("gave the lock\n"); return 1; } ssp_printf("couldn't give the lock\n"); @@ -503,9 +503,9 @@ int ssp_lock_take(void *lock) { return 0; } - ssp_printf("waiting for client lock\n"); + //ssp_printf("waiting for client lock\n"); if (xSemaphoreTake( xSemaphore, portMAX_DELAY) == pdTRUE) { - ssp_printf("took the lock\n"); + //ssp_printf("took the lock\n"); return 1; } else { ssp_printf("couldn't take the lock\n"); diff --git a/Program/src/requests.c b/Program/src/requests.c index 61b2a3e..31f565f 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -311,8 +311,10 @@ Client *start_client(FTP *app, uint8_t dest_id) { if (client == NULL) { ssp_printf("Spinning up a new client thread\n"); client = ssp_client(dest_id, app); - if (client == NULL) + if (client == NULL) { + ssp_printf("client is null, couln't spin up client thread"); return NULL; + } } else { ssp_printf("adding request to existing client thread\n"); From 0e88357d88de0eb77af8ce2577e8ea4bf459fe77 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 13:06:17 -0600 Subject: [PATCH 398/400] delete weird old file --- .../pending_req_id:1:num:1.binary | Bin 745 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 Program/test/incomplete_requests/pending_req_id:1:num:1.binary diff --git a/Program/test/incomplete_requests/pending_req_id:1:num:1.binary b/Program/test/incomplete_requests/pending_req_id:1:num:1.binary deleted file mode 100755 index fc8dcb0a72820c67deb154dff52562871bd35133..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 745 zcmZQzU|?VbVi17Q5Z)*`8UoY{0b!_74llNaftk(QAvCd8Ff*_fmz1WZF>vMP7o|d& JjEuw!0ss}2790Qo From 451baf7fa58d02b6a1d6fd849c6869b291c5f144 Mon Sep 17 00:00:00 2001 From: evangee Date: Thu, 30 Sep 2021 13:09:05 -0600 Subject: [PATCH 399/400] delete other file --- Program/test/temp/pending_req_id:1:num:1.binary | Bin 749 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 Program/test/temp/pending_req_id:1:num:1.binary diff --git a/Program/test/temp/pending_req_id:1:num:1.binary b/Program/test/temp/pending_req_id:1:num:1.binary deleted file mode 100755 index 5ddffaa391597e2087fd6bbb0192e378203af0cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 749 zcmZQzU|?VbVi17Q5Z)*`(nH{<%A`0@7*H!+2txx@V2yM53uXoeg%!@>*uof>I0G{S WTX9KgS{egaZhlcJgvrQAydVH6sTpek From 0041546d2b176c3e85e5ff969e643101c0fba78f Mon Sep 17 00:00:00 2001 From: Evan G Date: Tue, 30 May 2023 19:52:57 -0600 Subject: [PATCH 400/400] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2bd0a44..de34525 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -This is not finished! - currently working on it! +This is not a complete version of the protocol, Just put images, and proxy put (get). This is a FTP protocol that is partially (mostly) adheres to the CCSDS (Consultative Committee for Space Data Systems) spec for sending files into space CCSDS 727.0-B-4 (https://public.ccsds.org/pubs/727x0b4.pdf). This project is being built for a student lead space initiative at the Univerity of Alberta called ABsat.

    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 X7-rg!ud({7{{`v)x)Nhw&HDcjbL@iw diff --git a/Program/libcsp/build/src/drivers/usart/usart_kiss.c.2.o b/Program/libcsp/build/src/drivers/usart/usart_kiss.c.2.o deleted file mode 100755 index 375b6df1414ec0e660a9458a8c14a4ddfddbd154..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16160 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 JrXo!JzXH53vl{>a diff --git a/Program/libcsp/build/src/drivers/usart/usart_kiss.c.3.o b/Program/libcsp/build/src/drivers/usart/usart_kiss.c.3.o deleted file mode 100755 index 16224a9eb4b2cbdb3ca171845f9f6b10c0a2e6c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16168 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 GssBI8RJ3&f diff --git a/Program/libcsp/build/src/drivers/usart/usart_linux.c.2.o b/Program/libcsp/build/src/drivers/usart/usart_linux.c.2.o deleted file mode 100755 index 3356081b82eeb436431ffc9341030d888bc2ae1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20896 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 diff --git a/Program/libcsp/build/src/drivers/usart/usart_linux.c.3.o b/Program/libcsp/build/src/drivers/usart/usart_linux.c.3.o deleted file mode 100755 index 88c3a47058fa1f24df379a228bb7a208c1bdf591..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20936 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 Vkbqg8;c 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 P|9$fR6=B9X>h=Ez@n5!p diff --git a/Program/libcsp/build/src/interfaces/csp_if_can.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_can.c.2.o deleted file mode 100755 index 7d157060e4578793fe647d5066bf97ce86dae0cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19856 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 diff --git a/Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.3.o b/Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.3.o deleted file mode 100755 index 5e74a03b2f82865cb4722f282707527a0a5f0be1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8808 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 diff --git a/Program/libcsp/build/src/interfaces/csp_if_i2c.c.3.o b/Program/libcsp/build/src/interfaces/csp_if_i2c.c.3.o deleted file mode 100755 index 2d659301aa962fc06645f2b34b1167053f3dd286..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13008 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 E4>TbWcmMzZ diff --git a/Program/libcsp/build/src/interfaces/csp_if_kiss.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_kiss.c.2.o deleted file mode 100755 index 416d8b7f4ab04add4190a90a83e3ee11e1071c41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17240 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 N{QtgCV_wzv{|jDr_o)B? diff --git a/Program/libcsp/build/src/interfaces/csp_if_lo.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_lo.c.2.o deleted file mode 100755 index 9f44b99d898b5e159f5c17d06e51719fa81119b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10560 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 diff --git a/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.2.o b/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.2.o deleted file mode 100755 index b7c8b66b60a7fa0c0df5230bfc1bc7355aeb3c78..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29712 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 SFb*aEDcS#~Qe$6D`Tqs2cPAhK diff --git a/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.3.o b/Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.3.o deleted file mode 100755 index fccc13b31c8648d70b51be46da7eed3d99b41aae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29744 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 diff --git a/Program/libcsp/build/src/rtable/csp_rtable.c.2.o b/Program/libcsp/build/src/rtable/csp_rtable.c.2.o deleted file mode 100755 index df517306993c9281af206aab75dc41266751ec50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26704 zcmbt+34GMmwg3IiWElud0&xk7G6=z-WP?D$o)sq=mV`tBmvNGrgn1-0=_~=ZEL;B zFNrhxJFrm|@D64a7J&wDvVLY!`93h`9juZ%ckH{*%DwnaY#TV=C7Ol`(UNy46Hg7f zd*5#wx?tuJO}P!PRd4$$Gd`pJTx9yeun-%f>cv-nElK=P(SkslwRfX4t38w z9(xo&fkX{4Z}M-t*zv+Ucs|6VE|1u~15XaGOujDdcxQj+buPwExEcqu+J?(&&M4nk z)8-wF&n%L?@eVxZ*|Bd+)?(neAm?CR!7!BaC*O5>cYCcm*L~3K)|o{C@4O>qICee} z&t$o(GtaI$tLE&Qb83A1LFvvfs<#b$>T~O#%dP*gW~lbHC9m}5cz3)I&#K<`b!K17 zwx!TzAs+l148&V;AfYjL@1x!!*${Vn2N$hrOg?`GMCyQd=tyLyF#+u`*yY30vQz+W z7wpg7`y?d5C(!oAA>`iQ=1sndBa6e@m^{3;q5OTYvo4vq`jG&%YlGVG1clI>-0vOO zm)Deh%RBJehu-8Lyt5zkCf`L`T5G^YfZ`L zo01=aa8t5vr&K-gSw{T)ropzI8Yi$Rp67|h89z;H{;Vnay5ivG#JGbEw_{SiTW0f_ zOpZhzF&%8UYZ!Sm4m3OjiTU<{hJ!+C8ocn9f#GSJ3kDOn4}6`uInTRe-{8u-;;!$0 zj{JQm)3Db3T#jpB`oMXUFPGanzG2|Pt3{#`Vki~w*jJN$EM7$N@g?b!HOYNx!pC_B z+jet5hHHi&mpWkd4s8a*4aqm5{Rulw>yz(ro(=_HI+N4%?EU4R9D4Dq;o(Pc4jy_2 zD4gsEvSDB^nCbE+<1-5&9bf$t@S!*W2kU3%0jGeo2hUmt$z?$~kv2mHft76!JXQtS z^`1+zycCGmw@ESELg+rnN#p`rqE-cmx|1KsTN4r@8K{mBfGy5`iEBq zk-ZZwXSfQenv~V7$yB{eRVRp?KrAk@2W2%gTja!|9U}X3RdtA*-e^c<56P+n^i9af zKEEAIObl)TsSBS1$o&=^lrPy=qWK9T`|WGtoQrt&p%nSqN|Y3Q}n_j;3>%Oi6?|>(LTUE z3SW#}Iw3#4MYxur|1}qUbuLs})_3 zbbWp(`W@kFK-#PD6(R6!4fXJ_6Dlt3n(SuYxJvX}GLBmq0aE0{lojKo+b$*KDxC)n zS+0d}Jh}&1RsvBV4{K2(%k?$r%W`34vt0KA;=+Js;~~q1Ae}YPh{t~lZ#drK+q*Z*!e}!~`;{O_HkD`Z>E}8-dNMs8uWvXJyN|mZOWTjeF zGGxW8Dw(pfMpd$8Wu2whYY|j7s>%cl9qv_?JXwjW%4F*jXxXAFM_D-g zx2ej}RwGolt4e`Y4cZ1&WvaCXDmzuB(AouTSE@>}g$cG>RZ3*#MpY@5mD^RNOjhny zmAMwq{0CKKp7d>>s?4`e2Ro06W1wA(|93h51>E5~4Vo676I(UmOceVk#cSFSig^bhSp;NcuSB$+;A5DspFvOxomx zW27TKuzvtJj~A|oSzyAkh)m1Qz=dgIxf>Q`59(A$%Y&pt9-Z=-A&;5zm?iQOpmGYx z9IwnzT!so{fXdt@j{+?N8Dq3A_O&s6l{eL&Ar^b(|t6fIYdIcj3Mm(2vR9B;^07O#(&`Auy9BDj`Vsm1_USXY& zc~y)~SQq{kP(==;$Rzqb2ky&+b(!pPmJ3~%a}q;C*SsRBV!a-eOAvx$?Rj_{M`1m> zhD8O%u9k#4JA}1fUMZlp1TPkr-CBwgPl1wDGT3pmAQNwfCP)>l48|$NGQ(=tE9;#f zTg|Cqod9w$qFEnXEv{i$yYlb?gEnM`+^`4$t$Nj__e$RM0IRj@e8s;mo-TOdw+Mo#Xw|fL&$o-E?3@VwJ3s=^aocf>*jEbw=DCGYO9guFSb@&y z+ufff#Dej>ss%GY#n~@c3QT&rQsfC2HcLM27cCzP zv1`sQId7H#EEj2K*DZh&8Gto|NO@_H5{}Lulv~ddj!tA-Bvj*4*?2iL7W#ZK;aH05 zfD8kPI;1+sQYEq&uclnQL|A)ngvX`II5k!FGjSOc*ATHp7eA83&q)(z)=FEL)h)#? zb75iY_R1!L?eSbssZwsP+^{aU!n&+h=w`V>i!`nIq~5yoU)2f%i}CWzWeqJ*)*igo zs7z2(!`G~+IHA-HG9T_ z%U^|fFM9_LSZdw}!nx~~{+f>@aZmrUPpN77VIXQTYq-c%fQr@sejZrwr>4p{6Crab z0yMSyan@LiU_MwdDlJH@)2GS$%swHuHh zw2+^Y$LbNN0f{4#yA+6{@-3%3<>t{xS|?6X3JWr&!YQOMQwbi!p%CKOeCW~=c$A%5 zq51|a%cmf4903p%1sp#eLO(6TT9$)>;+S}fKyE5HF}=iEK1D_N#3>m6>Vj))r(my6 zNN%@aY_6%DQVz8lmuJz~afumvR~IIjJ_d^-uK|?!Z%CppsH-Ys{~hf-1^%r_)TA zr&OTST&)Un^PtL}Kx;(~#AI?d253Gz1vdxBK?hr`wxieOte5eq%oOGMsI5wlHgGRY z@4P3cLPmKJm=KFgKs?Q-B{_tkp{1xDn^8NgtretuITG;7OSuGVt!w~=wYmUmsMGy} z7h~uhd`T-2m?L4g8Z9AKqyQmKNmXF1Gs7?$z3Gq;jcGs*@`&aPHP=IQwnQ6~VS*fD zmzU|QY%DIA{x8BZ1U!n|pwy*~Y=AXbqLoQj00!1Ett)FCp=>u@PjBbzs%T@BuN1AI*8B!FR`c^GLcEnq0uv}ngmv)1es)=qYH9W*4RnW#^eu^Tw!favFl=Zuu3mYq=Zd7MA;2YA7l6O>~tX^T1jl3?ZX--S=th7O{pMp&nLwW zvDsu1EdIlkW+rd8p|z7q!_l^jYfMd1dW*4_&X!p73nG7=f=sFBsOjSr3zMJP&^ji+ zu%WX|Mcmh(l+)kN@-JvP!_>m{A|fD}nJgzrbjaoEbpv~9yws)Zedav zY#AXql_ZPkJZ8Ar0-srsBZBc6TRrze>yR!uvO}z%M+Po_Or~^=F-YtppIH}M9IxJY zWAli3Fi$-Re-kf9_9Ehi*fDv9eN9-)Bww~hPfFI+ZtH4gQWqSVMJ%}87Hnox7aSSk zk%BEOc#ZA-IZW!hMh^29GS1!qzeM5|(iKfPL5O`~mUjrT#OZb$5zLa(GGfsm$ueSv zzniqBw47xcT1;*(v)x_8Bul}SYWIjM)lW##%XI#xL^F9EV$q1iHF+%IGhO|FfIM>b zn@pO#qnR{$Mi~ZKDl6g6NaD`)%#Yc_g9O#xqcFmR6V|_b^-f$fGQbuRfh|Y^N z-wB+lj0hi{+v#jx8cq2%PW10Rux43b!UMJi1$eMtQc?gX8BQpwT+6tg1O2a~4RXahdlz!Srk zlsly*u+XM9(Uia^AR%J$KqxY|WFrO~zBYuyUB1ppG#=^<1p^9=Z|x1nm>~elixY4N z+ejeT2{eQRRWoyjs@kpq2SF+{st)}QMQlZq%mg>K#(c0Js5=ykt2R^|2(~A>Y%Mn7 z3w8RsQAHLT451LbRZVr&C%p*!yP*Mkj18eq(hg3kUPBw0UecZjb;pZC;bl1Hss;NF zP4Lx)(gWV@+-g~;WjLHQu6Ty!d|Wt+Ea!?-U2}UoKY6nF-&}7)Q*9@-JSrTstTUnZ z^Zt*ZdQdn{ur@&Tf&T4KeNwnemM&fo^}YQ|p#C(}UraQ0l{!xWv7=6^zE3zZtgP+w zcsCyV@NhaD9L~NHc^ZEzoSa#2z%gqH9blwf#Rizlu88D{PCcyI}=YhbC)<~9g)8|-?{wyro}ftIQ-8Iu3w*armJ+CGw=F* zhZ|;)He4MWgB_cM&llX=~xPRVU5ys6_ zfnM+ryzUAI1D=kJ{-{*Ere$^O>bliU0yo`({ix`P1cKed*9kl0!V#%gx+{%9?!#uT zjgeS9j3MZbgu7rbAM|buPLoI!#Jc@mG3a+F7U@{H&=-q!_`@nB4J|FJTcj%+BfY}c zk%;;_BHf7|2nqB8ay=AA`!XKd5OhcU0Rg@23`Tv}9UsP>)j$w1z~u`t8r=~bt4MbM zhYPpq@tK?mM0}`MPG3+Uw;Ael6GZI!3BwxdBa1YO^X7sPjFRXKbw+#;ov!#sUB06` z$U&{CJFTG=Mi6Crk^KGpBBZKzc1*6Eda6$TX5UPDXZE%bqg1IDof^{qyh3iD|f(lP@m#27j%u@{gSqfJR5GwAB#Ua^>d!vzfup=IcLR%D) z0YbH+ZB<=sIaB6luBXQbvcnR9wFRL3ZKwYbX>sbgni#h1QS6X z)##S?t#R1-ptvBjq$W%-u*$3jj1Z-0f2BbF<6KX1G*A9U`;Cv^x7{&r^LAUj; z)U#P`HN^uLRN1K>{}$>4USxb-5ViKLKAA(fsx+=zv6>P` z&f;K?A7YG4ikxH+f2iy6mCpK`sG3U{e4$NOIT>MWaS4QR=zul0qbIEsa`BK$w_I63r`m=r7a-YNxrjgj z`hwkH8#e~?A|>dC3nnNmy7JPopaQZ+b4W%}rjcA(Wo||Ty^tJRe49hzKxA_&an-Wh z*@LR!`ctk>FnO>xPn{~%X};izBgNI)A>|X{L@XGXi*pU1B)L7GN5p=fr< zQ3l5$MDfTbUlh`v7J0s=$+;xdiZ9bG(An*aMMNL&HNyOAT3vS<_{MJ8^I5s3`mGYB zBLY{!SZ{YI?t{x{=)6c67jJ=%%CNLUSm1SfUELy2QCoW=98ai)t9V{Q*2*s`uPQ04 zn5|HuzL3F9@Odr5+LC7-J0aVJU*HhuCwBRaTJO$t)VW>j0I$FsD=2G#Pt>~ezUQcQ z7hK_NaC?R_YTZSbXV$yRF3GBKR}EyZarZi2bZ@D3Z?kIMJFR;6mDVbE?-qAejk~PI zT~zD#fGDV_b;DBw+Pe}JL%9SG33uLFcR{_|vk{x+R-=0nhjIem*VVZ5E^*XN%<_KE zc}2!h=H*$Z4P-mVJD>}&X;O$kAtMy}TraT?6{NOa1C9O6zAl!}kw-jW}5Pu&Yjm?R7wxbkh>di=6s}pa>M=4HqtDDw>zBx4gatr}0 zB%JGV3<1M^M;6|YQ{nekE1`~h_+7J%J7DL)AM#_Iu}o4Yd30)eG#GltBcY>kXAT>} zM=MTyl+s(BBY!j?8JzY$Nt2&@W8%8ksWzwmGBAZ9<+Nu@3h$MqeAGyRKqUx=FKB7y zJi>Wyaie-OktyJ#YFfEi)-u)BVXY-e_;d|J@(RLnob_^*tYoS!bXvo1!tIR#)OH== z%HNd0&4lkvL6W+iaAhaecn{&%ryxoFlp6b-N`Tm_>G)guYea{Ym8=h{up@e82E-UaQsolX!`$c3_Laljz4l6 zP0zmrj{V~AJ3M3WB%HrU;Vv&M4-?LxxcmwhPXRuf{#S^fzmv+f6=d++;b{EBW8f}W z|3~AW3^@A#GA)(34$6|ch~q6E+~3l#l=K@l4VL%9eEXKVQ!klUUQv}ME`QXd-^>Hc zymC>}R9A)vNmU><7Z3CBFdq*K@KA||Dm*O2L%9->GUbxLTnfOR0pBT2t7~hTe5+Ti zSliI*Yptn;rysnVkx#nvenGoKGw&qKTS2{}@c4(-(eBgIo&(cmQqO;2HjFpuc*ZAm z`!2|Qv_%E#9ZuTqwWe1-!D@B&Qb7ac4XRe>rx*=V&z2fs-?GX3Xl#(LpV9^qgQ(JE z8l?-~UK|O3@Jl{fP9_}FYLNe*s%4h^&jsQ)FykjdkxgF zAb$b;F}?>uD2U@VgYmrxLO~q1Y}@#65rl&Ji{Ov>|BfIOt{Yg;e|$B~{43FM zD2SK9ALAhnFV*lk;ds*He5uA?rtv?a@gJ|@f7bZ%>lWMnNaM%cV>}by&0;}6b^b|& zqnHQ&n1ALN{0lYy=^B6I82n)kpR4g-t?ALn>lO{iae=MSviwNHPXL7dd_dE$kIO-g z|0Iq7zcpO9`-+C^cHh+S8JeDd5N_s!g#Z+cr#`+pgyTsc-(n5d^Z7~*UjQ=P-#av1 z=YK%Mt2F*c2uFVwYWU+CzDUETAR`oPE`~q0`xi~W?hoJL5DQK}QX%WucPz-yIz6 z_}dg`Ugz1*>2#y^sKI{^*?ro;e@=Q{G;sTV%)m=Y|JMfoI{7(~?65zqx5L11B>6rA zzmMYfT?22Xd3(8mKSg?;F>ubmmks=P)Zc8f!+u^z`tiOI3*)?w@WwC3Unc(92LE+b zpKsukC_Xg?o=J7S9r;wbo`KIM{@Dh83-x!4fo~;$E;Mit z;YkBuLVB(-a9$T~GH}lOyA8aH{C~*6&msRGH*g-;=M8*6>EY`g$7g`z`L4l#2jQO? z_)}ERq<*uW`-z|TzA=6=*_~$apGoyO20o7RYN3H=QapJ_BkMnx{8?-8^L^pD2F^c~ z>oM>;vU{F^<24VvfK2EKyyOf_&`7m5sg3F+xF@U1kTyAAvb@_&ng zw^03J1COcU5?2~{BkBJS1LynH+YI~<)UW#t{ASYgw1M;cj5iE?E#<>s4g5;-^FsrF zi{kT%fmaj%VFO=A{y4~A9bo#L>=zz3z)J?+PH}$Mz^kav*Eb&DS4n>^*=M|l;x^U5pCtYh4g7S{Urac56IuDa zSG|GrHmo)Sr(qO9LqD$<+YFrZhsTHg=WX*pF!=AJalhHXi>Y6?6VCqgd%<5CIIpu$ z8#wp(Ekpm~G%g<+{QRC0J`u^n{_}WE(s29TA#fh0;rM*Si2kH5(h9f`UPrs+($Ulqt|E}T4 z&-wf%;hfKT(1s<0l9Kb`eu~=^!ch$M@H{OtaGsAV44j{reHxB_M##?q;cS=n4;cKn z68}zvpPzTGF>rn^`jLj?5c2oN2Q?f?j>B&>97DkG$Ns9}sE5Coy6J@)`#+AxceaKj z|4#VBa*Bqde*C||u(WG9^7HrAi!>bhR}%jZH5~b`hd(So)^OzKA2J;@@P|py>l%)F zZbKzdKG1MIK3{7%>d&Qdfgd8vf^k4S_)P-K$r_IQyuEuK;h0w#`!e{$Qmf&ZCm)dh z(+qqP8iCSk;POA%0(?E;JTCl8s`CuI8J&W%+rS42|A~g{{d!!(k(Hmna?oigJYP1c zsyNobk3q+v%rfxD6)egP{6y;SQUm`X@vk&+zMtM;;6J15!ZrhE{#}G~+(^B+OXElK z4D#oG1AmC{M-04%>>f1mA;O;{obB?yi9-he0pkD2z=sL{(!dL8UCp4aAvi9`!tZA$ z5^ma^Y4G1kdS)B^r4*p$8crdQEgc#z^Mv@%Bb@#DJ?ZZ^`0I)P8VyJNv>b_BH5~PO ziGQD=-$D0hPa60t!e21(O9}s@f$t;y4FjJ*_ZeBVka9eS$e(G1bAS1MtH{95Cq3l` zem&uf4E#~TmlJN-Exe~<8=8v6PD z`5!bK$9Fo}{Yb-cd_N$3B7IOmwV2QUMf#62@K*?*X5bD=pqYeo+;G1OmQytx{V9|v ztg9N1{@^|sEPhQtxh(N+4M#r<$!@~Hn+fkX^z(0#{!_!zpV?Bo5PLNo{TU$qDGf({ zUQd3f;mDsP|NlZbh70d=?xpMF+hgD#82H<~E{%bIZs6CUQ&7Gd19zYkP}rZB$WQp+ zWJkp(8uxGw|<_pN$62{HqLn9gT0x82APQ@1}m8GX@?s@YS@QhYUPHb|VJP{BZ++ zkMd;882B&94tAedWrPkHI886nLhAwZPp5c3Zs3K4Dtc5NNi~=W4<*AN7()0iCXcK=Zt0cqI_5i!nU&cZ7agZ@A6m#rZf| z{O_$%67S$9Ehrd&T#C&2uLsQ336QuKH-kap|4KvEM)Gz;!)Wr`=t7_51&@lnC_|4zVAC-)ObS-v`1 zoqtHzFM@4f*$@1lJ(~Ov<|&DjSdh*v$LB{#-e42^NZ!O*j`81;ygC0^-fIYO|5^T7 zAV!Pdx^orBOT>urI|BY#o~DQFyJ;ImT=c^EM!Fd|8Zf+;oAUS=WDGGNLfnp<&Y;XN YlpEcVd%H%HFY_yT-hZWPBXjM40bWP~c>n+a diff --git a/Program/libcsp/build/src/rtable/csp_rtable.c.3.o b/Program/libcsp/build/src/rtable/csp_rtable.c.3.o deleted file mode 100755 index 3f84441633da04320e984cedf4296109deb282be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26736 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 diff --git a/Program/libcsp/build/src/rtable/csp_rtable_static.c.2.o b/Program/libcsp/build/src/rtable/csp_rtable_static.c.2.o deleted file mode 100755 index 8dafae52df3bbdad6861206b70e5208835db5379..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13192 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 diff --git a/Program/libcsp/build/src/rtable/csp_rtable_static.c.3.o b/Program/libcsp/build/src/rtable/csp_rtable_static.c.3.o deleted file mode 100755 index b331b10f991fb422a6042850cc2235532afe7384..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13200 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 HShwGQdekFY diff --git a/Program/libcsp/build/src/transport/csp_udp.c.2.o b/Program/libcsp/build/src/transport/csp_udp.c.2.o deleted file mode 100755 index 0fdff41c8321c8a3623246fe36cf68ce8e68eb34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11968 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 BrTqW^ diff --git a/Program/libcsp/build/src/transport/csp_udp.c.3.o b/Program/libcsp/build/src/transport/csp_udp.c.3.o deleted file mode 100755 index 11591156184a1ab078dacf1dd1b6c77b44a1215b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11984 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 af4+!JRpI`l&V~A)Ap5^n)fY+L|9=5K*{-nw diff --git a/Program/libcsp/build/zmqproxy b/Program/libcsp/build/zmqproxy deleted file mode 100755 index c06b40dcf643963ed1d79dae959c935fa31a4feb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38720 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 J2_&K7{{tHUg-ZYc diff --git a/Program/libcsp/doc/basic.rst b/Program/libcsp/doc/basic.rst deleted file mode 100755 index 70ad741..0000000 --- a/Program/libcsp/doc/basic.rst +++ /dev/null @@ -1,153 +0,0 @@ -The basics of CSP -================= - -The following diagram shows a conceptual overview of the different blocks in CSP. The shown inferface is CAN (src/interfaces/csp_if_can.c, driver: src/drivers/can/can_socketcan.c). - -.. code-block:: none - - buffer connection send read/accept - ^ | | ^ - | | v | - | +-----------------+ | +----------------+ +-------------------+ - | | connection pool | | | CSP Core | | csp_task_router() | - | | csp_conn.c |<--+---->| * routing |<---| csp_route.c | - | +-----------------+ | * crypt | +-------------------+ - | | * UDP/RDP | ^ - | csp_route_t | * CRC32 | | - v +------------>| | +----------------+ - +--------------+ | | | | incoming queue | - | buffer pool | | | | | qfifo.c | - | csp_buffer.c | +-------------+ +----------------+ +----------------+ - +--------------+ |routing table| | ^ - ^ | rtable.c | v | - | +-------------+ +------------------------------------+ - | | (next_hop) | - | | CAN interface (csp_if_can.c) | - +------------------------------>| csp_can_rx() | - +------------------------------------+ - | CAN frame (8 bytes) ^ - v | - csp_can_tx_frame() socketcan_rx_thread() - (drivers/can/can_socketcan.c) - - -Buffer ------- - -All buffers are allocated once during initialization of CSP, after this the buffer system is entirely self-contained. All allocated elements are of the same size, so the buffer size must be chosen to be able to handle the maximum possible packet length. The buffer pool uses a queue to store pointers to free buffer elements. First of all, this gives a very quick method to get the next free element since the dequeue is an O(1) operation. Furthermore, since the queue is a protected operating system primitive, it can be accessed from both task-context and interrupt-context. The `csp_buffer_get()` version is for task-context and `csp_buffer_get_isr()` is for interrupt-context. Using fixed size buffer elements that are preallocated is again a question of speed and safety. - -Definition of a buffer element `csp_packet_t`: - -.. literalinclude:: ../include/csp/csp_types.h - :language: c - :start-after: //doc-begin:csp_packet_t - :end-before: //doc-end:csp_packet_t - -A basic concept in the buffer system is called Zero-Copy. This means that from userspace to the kernel-driver, the buffer is never copied from one buffer to another. This is a big deal for a small microprocessor, where a call to `memcpy()` can be very expensive. -This is achieved by a number of `padding` bytes in the buffer, allowing for a header to be prepended at the lower layers without copying the actual payload. This also means that there is a strict contract between the layers, which data can be modified and where. - -The padding bytes are used by the I2C interface, where the `csp_packet_t` will be casted to a `csp_i2c_frame_t`, when the interface calls the driver Tx function `csp_i2c_driver_tx_t`: - -.. literalinclude:: ../include/csp/interfaces/csp_if_i2c.h - :language: c - :start-after: //doc-begin:csp_i2c_frame_t - :end-before: //doc-end:csp_i2c_frame_t - - -Connection ----------- - -CSP supports both connection-less and connection-oriented connections. See more about protocols in :ref:`layer4`. - -During initialization libcsp allocates the configured number of connections. The required number of connections depends on the application. Here is a list functions, that will allocate a connection from the connection pool: - - - client connection, call to `csp_connect()` - - server socket for listening `csp_socket()` - - server accepting an incmoing connection `csp_accept()` - -An applications receive queue is located on the connection and is also allocated once during initialization. The length of the queue is the same for all queues, and specified in the configuration. - - -Send ----- - -The data flow from the application to the driver, can basically be broken down into following steps: - - 1. if using connection-oriented communication, establish a connection> `csp_connect()`, `csp_accept()` - 2. get packet from the buffer pool: `csp_buffer_get()` - 3. add payload data to the packet - 4. send packet, e.g. `csp_send()`, `csp_sendto()` - 5. CSP looks up the destination route, using the routing table, and calls `nexthop()` on the resolved interface. - 6. The interface (in this case the CAN interface), splits the packet into a number of CAN frames (8 bytes) and forwards them to the driver. - - -Receive -------- - -The data flow from the driver to the application, can basically be broken down into following steps: - - 1. the driver layer forwards the raw data frames to the interface, in this case CAN frames - 2. the interface will aquire a free buffer (e.g. `csp_buffer_get_isr()`) for assembling the CAN frames into a complete packet - 3. once the interface has successfully assembled a packet, the packet is queued for routing - primarily to decouple the interface, e.g. if the interfacec/drivers uses interrupt (ISR). - 4. the router picks up the packet from the incoming queue and routes it on - this can either to a local destination, or another interface. - 5. the application waits for new packets at its Rx queue, by calling `csp_read()` or `csp_accept` in case it is a server socket. - 6. the application can now process the packet, and either send it using e.g. `csp_send()`, or free the packet using `csp_buffer_free()`. - - -Routing table -------------- - -When a packet is routed, the destination address is looked up in the routing table, which results in a `csp_route_t` record. The record contains the inteface (`csp_iface_t`) the packet is to be send on, and an optional `via` address. The `via` address is used, when the sender cannot direcly reach the receiver on one of its connected networks, e.g. sending a packet from the satellite to the ground - the radio will be the `via` address. - -CSP comes with 2 routing table implementations (selected at compile time). - - - static: supports a one-to-one mapping, meaning routes must be configured per destination address or a single `default` address. The `default` address is used, in case there are no routes set for the specific destination address. - The `static` routing table has the fastest lookup, but requires more setup. - - - cidr (Classless Inter-Domain Routing): supports a one-to-many mapping, meaning routes can be configued for a range of destianation addresses. - The `cidr` is a bit slower for lookup, but simple to setup. - -Routes can be configured using text strings in the format: - -

  5. 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

    H+! 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

    }q$O~n& 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 Date: Sat, 10 Apr 2021 12:18:55 -0600 Subject: [PATCH 346/400] change port for ex2 build --- Program/include/port.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 5a67250..5371059 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -8,12 +8,13 @@ Author: Evan Giese #define PORT_H -//#define FREE_RTOS_PORT -//#define RED_FS +//#define TEST 1 +#define FREE_RTOS_PORT +#define RED_FS #define CSP_NETWORK -#define POSIX_FILESYSTEM -#define POSIX_PORT +//#define POSIX_FILESYSTEM +//#define POSIX_PORT From e8f31b5868f835c0c7a075daa9ed080cbd7a5203 Mon Sep 17 00:00:00 2001 From: evanGee Date: Sat, 10 Apr 2021 18:00:08 -0600 Subject: [PATCH 347/400] update to working version --- Program/src/file_delivery_app.c | 4 ++-- Program/src/filesystem_funcs.c | 7 +++---- Program/src/port.c | 8 ++++---- build_instructions | 12 ++++++++++++ 4 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 build_instructions diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 15a00d8..82bdb0f 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -85,7 +85,7 @@ static void make_default_data(){ } const char *peer_file_sat = "{\n\ \"cfdp_id\": 0,\n\ - \"UT_address\" : 0,\n\ + \"UT_address\" : 1,\n\ \"UT_port\" : 20,\n\ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ @@ -127,7 +127,7 @@ static void make_default_data(){ \"transaction_inactivity_limit\" : 123\n\ }"; - int fd = ssp_open("mib/peer_0.json", SSP_O_CREAT | SSP_O_RDWR); + int fd = ssp_open("mib/peer_1.json", SSP_O_CREAT | SSP_O_RDWR); if (fd < 0) { if (fd == SSP_EEXIST) { ssp_error("file exists\n"); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index f3c8668..539bd96 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -53,7 +53,7 @@ File *create_file(char *source_file_name, int clear_file_contents) { } - uint32_t total_size = get_file_size(source_file_name); + int total_size = get_file_size(source_file_name); if (total_size == -1){ ssp_error("couldn't get file size\n"); return NULL; @@ -330,13 +330,12 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa jsmntok_t tok[255]; - uint32_t total_size = get_file_size(file_name); + int total_size = get_file_size(file_name); - if (total_size == 0){ + if (total_size < 0){ ssp_error("couldn't get file size\n"); return -1; } - char *buff = ssp_alloc(total_size, sizeof(char)); if (buff == NULL) return -1; diff --git a/Program/src/port.c b/Program/src/port.c index 9786dac..ecb284e 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -31,7 +31,8 @@ static int exit_now = 0; #ifdef FREE_RTOS_PORT #include "FreeRTOS.h" - #include "task.h" + #include + #include //#include "portable.h" //not sure what i need here for sat build //make sure these are available in FREERTOS @@ -161,8 +162,7 @@ int ssp_readdir(void *dir, char *file){ Network port functions, these are used to interchange different network stacks ------------------------------------------------------------------------------*/ -#ifdef FREE_RTOS_PORT -#include "queue.h" +#ifdef FREE_RTOS_PORT extern QueueHandle_t sendQueue; #endif @@ -174,7 +174,7 @@ void ssp_sendto(Response res) { if (res.type_of_network == generic) { - #ifdef FREE_RTOS_PORT + #ifdef FREE_RTOS_PORT while (true) { if (xQueueSendToBack(sendQueue, res.msg, 100) != pdPASS) ssp_printf("queue full, failed to post packet, blocking task untill sent\n"); diff --git a/build_instructions b/build_instructions new file mode 100644 index 0000000..b143a3e --- /dev/null +++ b/build_instructions @@ -0,0 +1,12 @@ +right click /Program/src/main.c and 'exclude from build' +right click /Program/test directory and 'exclude from build' +right click /Program/src/posix_server_provider.c directory and 'exclude from build' + +project -> properties -> include Options -> add ${workspace_loc:/${ProjName}/libcsp/src} +project -> properties -> include Options -> add ${workspace_loc:/${ProjName}/ex2_ftp/Program/include} +project -> properties -> include Options -> add ${workspace_loc:/${ProjName}/libcsp/include} +project -> properties -> include Options -> add${workspace_loc:/${ProjName}/include/ex2_os} + +then right click the ext_ftp folder and go to the 'includes' and select restore defaults + +make sure the connection in Project -> properties -> general -> connection isset to XDS110 USB \ No newline at end of file From 44372dff23cd21296a7897772f6a45b42a5e7bb8 Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 15 May 2021 17:29:49 -0600 Subject: [PATCH 348/400] add new json parsing for saved meta data --- Program/include/filesystem_funcs.h | 8 +- Program/src/filesystem_funcs.c | 492 ++++++++++++++++++++++++++++- Program/test/filesystem_tests.c | 90 ++++++ 3 files changed, 585 insertions(+), 5 deletions(-) diff --git a/Program/include/filesystem_funcs.h b/Program/include/filesystem_funcs.h index dcc0b80..c432e73 100755 --- a/Program/include/filesystem_funcs.h +++ b/Program/include/filesystem_funcs.h @@ -31,7 +31,7 @@ uint32_t check_sum_file(File *file, uint16_t stack_buffer); int receive_offset(File *file, uint32_t offset_start, uint32_t offset_end); File *create_temp_file(char *file_name, uint32_t size); int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file); -int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params); +int read_json(char *file_name, int (*callback)(char *key, char *value, void *params), void *params); int write_lv(int fd, LV lv); int read_lv(int fd, LV *lv); @@ -45,4 +45,10 @@ int get_file_from_file(int fd, File *file); int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint32_t my_cfdp_id, Request *req); int delete_saved_request(Request *req); int read_request_from_file(int fd, Request *req); + + +//new json stuff: +int write_request_json (Request *req, char *file_name); +int get_request_from_json (Request *req, char *file_name); + #endif diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index f3c8668..12b0baf 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -9,7 +9,7 @@ Author: Evan Giese #include "filesystem_funcs.h" #include "jsmn.h" #include "requests.h" - +#include "utils.h" int get_file_size(char *source_file_name) { @@ -322,11 +322,12 @@ int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t return 0; } -int read_json(char *file_name, void (*callback)(char *key, char *value, void *params), void *params) { +int read_json(char *file_name, int (*callback)(char *key, char *value, void *params), void *params) { int number_of_tokens = 255; jsmn_parser p; jsmn_init(&p); + int error = 0; jsmntok_t tok[255]; @@ -367,7 +368,6 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa int key_size = tok[i].end - tok[i].start; int value_size = tok[i+1].end - tok[i+1].start; - //char key[key_size + 1]; char *key = ssp_alloc(key_size + 1, sizeof(char)); if (key == NULL) { ssp_free(buff); @@ -387,10 +387,16 @@ int read_json(char *file_name, void (*callback)(char *key, char *value, void *pa value[value_size] = '\0'; strncpy(value, &buff[tok[i+1].start], value_size); - callback(key, value, params); + error = callback(key, value, params); + ssp_free(key); ssp_free(value); i++; + + if (error < 0) { + return error; + } + } ssp_free(buff); @@ -877,3 +883,481 @@ int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint3 return 0; } + + +//NEEEEEEEEEEEEW stuff + +/* +//incoming requests spin up requests +typedef struct request { + Request_procedure procedure; + + uint64_t transaction_sequence_number; + uint32_t dest_cfdp_id; + uint32_t my_cfdp_id; + + File *file; + uint32_t file_size; + + char source_file_name[MAX_PATH]; + char destination_file_name[MAX_PATH]; + + //previous timeout time in seconds + int timeout_before_cancel; + int timeout_before_journal; + + uint8_t segmentation_control; + uint8_t fault_handler_overides; + uint8_t flow_lable; + uint8_t transmission_mode; + bool paused; + + //counter for resending eof packets == 3 + uint8_t resent_eof; + //counter for resending finished packets == 3 + uint8_t resent_finished; + + //bool for sending first blast of data packets + // uint8_t sent_first_data_round; + + Remote_entity remote_entity; + Local_entity local_entity; + + List *messages_to_user; + + //sets the buffer length, for making packets + uint32_t buff_len; + + //buffer for making packets + char* buff; + + //header for building response packets + Pdu_header pdu_header; + + //handler for sending responses back + Response res; +} Request; + +typedef struct file { + int fd; + uint8_t is_temp; + uint32_t next_offset_to_send; + uint32_t total_size; + uint32_t partial_checksum; + uint32_t eof_checksum; + List *missing_offsets; + +} File; +*/ + + +static int parse_json_missing_offset_list(List *list, char *value) { + + int i = 0; + char *parse_string = (char *) value; + int len = strnlen(parse_string, 10000); + + int value_length = 15; + char tmp_offset[value_length]; + char start[value_length]; + int value_index = 0; + + Offset *offset; + int comma_number = 0; + + //add comma at end for algorithm + parse_string[len-1] = ','; + + for (i = 1; i < len; i++) { + + if (parse_string[i] == ',') { + tmp_offset[value_index] = '\0'; + value_index = 0; + comma_number++; + + if (comma_number % 2 == 0) { + offset = ssp_alloc(1, sizeof(Offset)); + if (offset == NULL) { + ssp_printf("memory allocation failed\n"); + return -1; + } + offset->start = ssp_atol(start); + offset->end = ssp_atol(tmp_offset); + + list->push(list, offset, -1); + continue; + } + + memcpy(start, tmp_offset, value_length); + continue; + } + + tmp_offset[value_index] = parse_string[i]; + value_index++; + + } + return 0; +} + + + +enum { + REQ_my_cfdp_id, + REQ_dest_cfdp_id, + REQ_transaction_sequence_number, + REQ_file_size, + REQ_source_file_name, + REQ_destination_file_name, + REQ_transmission_mode, + REQ_paused, + REQ_resent_eof, + REQ_resent_finished, + REQ_sent_first_data_round, + REQ_local_entity_EOF_sent_indication, + REQ_local_entity_EOF_recv_indication, + REQ_local_entity_file_segment_recv_indication, + REQ_local_entity_transaction_finished_indication, + REQ_local_entity_suspended_indication, + REQ_local_entity_resumed_indication, + REQ_local_entity_Metadata_recv_indication, + REQ_local_entity_Metadata_sent_indication, + REQ_messages_to_user, + REQ_file_is_temp, + REQ_file_next_offset_to_send, + REQ_file_total_size, + REQ_file_partial_checksum, + REQ_file_eof_checksum, + REQ_file_missing_offsets, + REQ_TOTAL +}; + +static char *parse_list[REQ_TOTAL] = { + "my_cfdp_id", + "dest_cfdp_id", + "transaction_sequence_number", + "file_size", + "source_file_name", + "destination_file_name", + "transmission_mode", + "paused", + "resent_eof", + "resent_finished", + "sent_first_data_round", + "local_entity.EOF_sent_indication", + "local_entity.EOF_recv_indication", + "local_entity.file_segment_recv_indication", + "local_entity.transaction_finished_indication", + "local_entity.suspended_indication", + "local_entity.resumed_indication", + "local_entity.Metadata_recv_indication", + "local_entity.Metadata_sent_indication", + "messages_to_user", + "file.is_temp", + "file.next_offset_to_send", + "file.total_size", + "file.partial_checksum", + "file.eof_checksum", + "file.missing_offsets" +}; + + +static int parse_json_request(char *key, char *value, void *params) { + + int len = 0; + int i = 0; + int error = 0; + + Request *req = (Request *) params; + + for (i = 0; i < REQ_TOTAL; i++) { + len = strnlen(parse_list[i], 50); + + //ssp_printf("parsing %s\n", parse_list[i]); + if (strncmp(key, parse_list[i], len) != 0) + continue; + + switch (i) + { + case REQ_my_cfdp_id: + req->my_cfdp_id = ssp_atol(value); + break; + case REQ_dest_cfdp_id: + req->dest_cfdp_id = ssp_atol(value); + break; + case REQ_transaction_sequence_number: + req->transaction_sequence_number = ssp_atoll(value); + break; + case REQ_file_size: + req->file_size = ssp_atol(value); + break; + case REQ_source_file_name: + //req->my_cfdp_id = ssp_atol(value); + break; + case REQ_destination_file_name: + //req->my_cfdp_id = ssp_atol(value); + break; + case REQ_transmission_mode: + req->transmission_mode = ssp_atol(value); + break; + case REQ_paused: + req->paused = ssp_atol(value); + break; + case REQ_resent_eof: + req->resent_eof = ssp_atol(value); + break; + case REQ_resent_finished: + req->resent_finished = ssp_atol(value); + break; + case REQ_sent_first_data_round: + req->sent_first_data_round = ssp_atol(value); + break; + case REQ_local_entity_EOF_sent_indication: + req->local_entity.EOF_sent_indication = ssp_atol(value); + break; + case REQ_local_entity_EOF_recv_indication: + req->local_entity.EOF_recv_indication = ssp_atol(value); + break; + case REQ_local_entity_file_segment_recv_indication: + req->local_entity.file_segment_recv_indication = ssp_atol(value); + break; + case REQ_local_entity_transaction_finished_indication: + req->local_entity.transaction_finished_indication = ssp_atol(value); + break; + case REQ_local_entity_suspended_indication: + req->local_entity.suspended_indication = ssp_atol(value); + break; + case REQ_local_entity_resumed_indication: + req->local_entity.resumed_indication = ssp_atol(value); + break; + case REQ_local_entity_Metadata_recv_indication: + req->local_entity.Metadata_recv_indication = ssp_atol(value); + break; + case REQ_local_entity_Metadata_sent_indication: + req->local_entity.Metadata_sent_indication = ssp_atol(value); + break; + case REQ_messages_to_user: + //req->messages_to_user = ssp_atol(value); + break; + case REQ_file_is_temp: + req->file->is_temp = ssp_atol(value); + break; + case REQ_file_next_offset_to_send: + req->file->next_offset_to_send = ssp_atol(value); + break; + case REQ_file_total_size: + req->file->total_size = ssp_atol(value); + break; + case REQ_file_partial_checksum: + req->file->partial_checksum = ssp_atol(value); + break; + case REQ_file_eof_checksum: + req->file->eof_checksum = ssp_atol(value); + break; + case REQ_file_missing_offsets: + error = parse_json_missing_offset_list(req->file->missing_offsets, value); + if (error < 0) { + ssp_printf("ERROR %d\n", error); + return error; + } + break; + case REQ_TOTAL: + break; + default: + break; + } + } + + return 0; +} + +int get_request_from_json (Request *req, char *file_name) { + + int error = read_json(file_name, parse_json_request, req); + + if (error < 0) { + ssp_error("json parsing failed\n"); + return -1; + } + + return 0; +} + + + +static struct json_write_callback { + int error; + int fd; + int bytes_written; +}; + +static void save_file_callback_json(Node *node, void *element, void *param) { + + char *error_message = "failed to write offset\n"; + + struct json_write_callback *p = (struct json_write_callback *) param; + if (p->error < 0){ + return; + } + + Offset *offset = (Offset *)element; + char buff[100]; + + int bytes_added = ssp_snprintf(buff, sizeof(buff), "%d,%d,", offset->start, offset->end); + + int err = ssp_write(p->fd, buff, bytes_added); + + if (err < 0) { + ssp_error(error_message); + p->error = err; + return; + } + p->bytes_written += err; + +} + +static int add_file_json(int fd, File *file) { + + + char buff[500]; + int size = sizeof(buff); + + int bytes_added = ssp_snprintf(buff, size, "\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":[", + parse_list[REQ_file_is_temp], file->is_temp, + parse_list[REQ_file_next_offset_to_send], file->next_offset_to_send, + parse_list[REQ_file_total_size], file->total_size, + parse_list[REQ_file_partial_checksum], file->partial_checksum, + parse_list[REQ_file_eof_checksum], file->eof_checksum, + parse_list[REQ_file_missing_offsets]); + + int bytes = ssp_write(fd, buff, strnlen(buff, sizeof(buff))); + if (bytes < 0) { + ssp_printf("couldn't write file\n"); + return bytes; + } + + struct json_write_callback p = { + 0, + fd, + bytes, + }; + + file->missing_offsets->iterate(file->missing_offsets, save_file_callback_json, &p); + if (p.error < 0) { + ssp_printf("couldn't write file offsets\n"); + return -1; + } + + if (ssp_lseek(fd, -1, SSP_SEEK_END) == -1){ + ssp_error("could'nt set offset\n"); + } + + p.bytes_written += ssp_write(fd, "],\n", 3); + if (bytes < 0) { + ssp_printf("couldn't write file\n"); + return bytes; + } + + return p.bytes_written; + +} + +static int add_end_of_json(int fd) { + + if (ssp_lseek(fd, -2, SSP_SEEK_END) == -1){ + ssp_error("could'nt set offset\n"); + } + + int err = ssp_write(fd, "\n\ +}", 2); + if (err < 0) { + return -1; + } + return 1; +} + +static int add_base_req_json(int fd, Request *req){ + + char buff[1000]; + int size = sizeof(buff); + + int bytes_added = ssp_snprintf(buff, size, "{\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%llu,\n\ + \"%s\":%d,\n\ + \"%s\":\"%s\",\n\ + \"%s\":\"%s\",\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":%d,\n\ + \"%s\":[],\n", + parse_list[REQ_my_cfdp_id], req->my_cfdp_id, + parse_list[REQ_dest_cfdp_id], req->dest_cfdp_id, + parse_list[REQ_transaction_sequence_number], req->transaction_sequence_number, + parse_list[REQ_file_size], req->file_size, + + parse_list[REQ_source_file_name], req->source_file_name, + parse_list[REQ_destination_file_name], req->destination_file_name, + parse_list[REQ_transmission_mode], req->transmission_mode, + parse_list[REQ_paused], req->paused, + parse_list[REQ_resent_eof], req->resent_eof, + parse_list[REQ_resent_finished], req->resent_finished, + parse_list[REQ_sent_first_data_round], req->sent_first_data_round, + parse_list[REQ_local_entity_EOF_sent_indication], req->local_entity.EOF_sent_indication, + parse_list[REQ_local_entity_EOF_recv_indication], req->local_entity.EOF_recv_indication, + parse_list[REQ_local_entity_file_segment_recv_indication], req->local_entity.file_segment_recv_indication, + parse_list[REQ_local_entity_transaction_finished_indication], req->local_entity.transaction_finished_indication, + parse_list[REQ_local_entity_suspended_indication], req->local_entity.suspended_indication, + parse_list[REQ_local_entity_resumed_indication], req->local_entity.resumed_indication, + parse_list[REQ_local_entity_Metadata_recv_indication], req->local_entity.Metadata_recv_indication, + parse_list[REQ_local_entity_Metadata_sent_indication], req->local_entity.Metadata_sent_indication, + parse_list[REQ_messages_to_user] + ); + + + int bytes = ssp_write(fd, buff, strnlen(buff, sizeof(buff))); + if (bytes < 0) { + ssp_printf("couldn't write file\n"); + return bytes; + } + + return bytes; +} + +int write_request_json (Request *req, char *file_name) { + + if (req == NULL) { + return -1; + } + + int fd = ssp_open(file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC); + if (fd == -1) { + ssp_error("count not open file\n"); + return fd; + } + + int bytes_added = add_base_req_json(fd, req); + + if (req->file != NULL) + bytes_added += add_file_json(fd, req->file); + + + add_end_of_json(fd); + +} \ No newline at end of file diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index 9ab8458..f0176a0 100755 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -292,17 +292,107 @@ int test_save_file_and_messages() { return 1; } +int test_write_request_json() { + + char *json_file = "test_incomeplete_file.json"; + Request req; + + req.file = NULL; + req.file = create_file("test_files/dest.jpg", 0); + + add_first_offset(req.file, 3000); + receive_offset(req.file, 1000, 2000); + + req.my_cfdp_id = 5; + req.dest_cfdp_id = 10; + req.transaction_sequence_number = 56423487523; + req.paused = 0; + req.resent_eof = 2; + req.resent_finished = 2; + req.sent_first_data_round = 1; + req.timeout_before_cancel = 50; + req.timeout_before_journal = 40; + req.transmission_mode = 1; + req.file_size = 150; + + req.local_entity.EOF_recv_indication = 1; + req.local_entity.EOF_sent_indication = 1; + req.local_entity.file_segment_recv_indication = 1; + req.local_entity.Metadata_recv_indication = 1; + req.local_entity.Metadata_sent_indication = 1; + req.local_entity.resumed_indication = 1; + req.local_entity.suspended_indication = 2; + req.local_entity.transaction_finished_indication = 1; + + int error = write_request_json(&req, json_file); + if (error < 0) { + ssp_printf("failed to write json test file\n"); + } + + Request req2; + + req2.file = create_file("test_files/dest.jpg", 0); + + error = get_request_from_json(&req2, "test_incomeplete_file.json"); + if (error < 0) { + ssp_printf("failed to read json test file\n"); + return -1; + } + + ASSERT_EQUALS_INT("my_cfdp_id", req.my_cfdp_id, req2.my_cfdp_id); + ASSERT_EQUALS_INT("dest_cfdp_id", req.dest_cfdp_id, req2.dest_cfdp_id); + ASSERT_EQUALS_INT("transaction_sequence_number", req.transaction_sequence_number, req2.transaction_sequence_number); + ASSERT_EQUALS_INT("paused", req.paused, req2.paused); + + ASSERT_EQUALS_INT("resent_eof", req.resent_eof, req2.resent_eof); + ASSERT_EQUALS_INT("resent_finished", req.resent_finished, req2.resent_finished); + ASSERT_EQUALS_INT("sent_first_data_round", req.sent_first_data_round, req2.sent_first_data_round); + ASSERT_EQUALS_INT("transmission_mode", req.transmission_mode, req2.transmission_mode); + ASSERT_EQUALS_INT("file_size", req.file_size, req2.file_size); + + ASSERT_EQUALS_INT("local_entity.EOF_recv_indication", req.local_entity.EOF_recv_indication, req2.local_entity.EOF_recv_indication); + ASSERT_EQUALS_INT("local_entity.EOF_sent_indication", req.local_entity.EOF_sent_indication, req2.local_entity.EOF_sent_indication); + ASSERT_EQUALS_INT("local_entity.file_segment_recv_indication", req.local_entity.file_segment_recv_indication, req2.local_entity.file_segment_recv_indication); + ASSERT_EQUALS_INT("local_entity.Metadata_recv_indication", req.local_entity.Metadata_recv_indication, req2.local_entity.Metadata_recv_indication); + ASSERT_EQUALS_INT("local_entity.Metadata_sent_indication", req.local_entity.Metadata_sent_indication, req2.local_entity.Metadata_sent_indication); + ASSERT_EQUALS_INT("local_entity.resumed_indication", req.local_entity.resumed_indication, req2.local_entity.resumed_indication); + ASSERT_EQUALS_INT("local_entity.suspended_indication", req.local_entity.suspended_indication, req2.local_entity.suspended_indication); + ASSERT_EQUALS_INT("local_entity.transaction_finished_indication", req.local_entity.transaction_finished_indication, req2.local_entity.transaction_finished_indication); + + + Offset *o1 = req2.file->missing_offsets->pop(req2.file->missing_offsets); + ASSERT_EQUALS_INT("offset start", 2000, o1->start); + ASSERT_EQUALS_INT("offset end", 3000, o1->end); + ssp_free(o1); + + Offset *o2 = req2.file->missing_offsets->pop(req2.file->missing_offsets); + ASSERT_EQUALS_INT("offset start", 0, o2->start); + ASSERT_EQUALS_INT("offset end", 1000, o2->end); + ssp_free(o2); + + + ssp_free_file(req2.file); + ssp_free_file(req.file); + + return error; + +} int file_system_tests() { int error = 0; + /* error = test_write_lv(); error = test_saving_request(); error = test_save_file(); error = test_get_file(); error = test_save_file_and_messages(); + */ + + error = test_write_request_json(); + return error; } From ae4912ef621b401d95ff4f5041e4894ee29fd6c2 Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 22 May 2021 18:30:21 -0600 Subject: [PATCH 349/400] update way files are saved --- Program/include/protocol_handler.h | 4 +- Program/include/requests.h | 2 +- Program/include/types.h | 2 +- Program/src/app_control.c | 20 +- Program/src/csp_server_provider.c | 20 +- Program/src/file_delivery_app.c | 28 +- Program/src/filesystem_funcs.c | 599 ++++------------------------- Program/src/mib.c | 5 +- Program/src/packet.c | 2 +- Program/src/port.c | 10 +- 10 files changed, 132 insertions(+), 560 deletions(-) diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 7f2dcc8..e011191 100755 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -12,8 +12,8 @@ Author: Evan Giese #define RESEND_FINISHED_TIMES 1 #define RESEND_META_TIMES 1 -#define TIMEOUT_BEFORE_CANCEL_REQUEST 10 -#define TIMEOUT_BEFORE_SAVE_REQUEST 30 +//#define TIMEOUT_BEFORE_CANCEL_REQUEST 600 +//#define TIMEOUT_BEFORE_SAVE_REQUEST 30 int parse_packet_server(char *packet, uint32_t packet_index, Response res, Request *req, Pdu_header incoming_header, FTP *app); void user_request_handler(Response res, Request *req, Client *client); diff --git a/Program/include/requests.h b/Program/include/requests.h index a959253..f041e75 100755 --- a/Program/include/requests.h +++ b/Program/include/requests.h @@ -82,7 +82,7 @@ void free_lv(LV lv); void print_request_procedure(Request *req); int start_scheduled_requests(uint32_t dest_id, FTP *app); int schedule_put_request(uint32_t dest_id,char *source_file_name,char *destination_file_name,uint8_t transmission_mode, FTP *app); -int schedule_request(Request *req, uint32_t dest_id, uint8_t transmission_mode, FTP *app); +int schedule_request(Request *req, uint32_t dest_id, FTP *app); Request *init_request_no_client(); diff --git a/Program/include/types.h b/Program/include/types.h index 6feec9f..b49e834 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -614,7 +614,7 @@ typedef struct request { uint8_t resent_finished; //bool for sending first blast of data packets - // uint8_t sent_first_data_round; + uint8_t sent_first_data_round; Remote_entity remote_entity; Local_entity local_entity; diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 3e3be46..4c1ea13 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -60,9 +60,9 @@ static int check_timeout(int *prevtime, uint32_t timeout) { } //sets request procedure as clean_up if ttl has passed -static void timeout(Request *req) { +static void timeout(Request *req, uint32_t time_out_before_cancel) { - bool is_timeout = check_timeout(&req->timeout_before_cancel, TIMEOUT_BEFORE_CANCEL_REQUEST); + bool is_timeout = check_timeout(&req->timeout_before_cancel, time_out_before_cancel); if (is_timeout) { if (req->local_entity.transaction_finished_indication){ ssp_printf("ACKNOWLEDGED request successfully sent without issue transaction: %llu\n", req->transaction_sequence_number); @@ -77,7 +77,7 @@ static void timeout(Request *req) { req->procedure = clean_up; } - is_timeout = check_timeout(&req->timeout_before_journal, TIMEOUT_BEFORE_SAVE_REQUEST); + is_timeout = check_timeout(&req->timeout_before_journal, time_out_before_cancel/2); if (is_timeout) { int error = save_req_to_file(req); if (error < 0) { @@ -131,14 +131,13 @@ static int on_recv_client_callback(int sfd, char *packet, uint32_t packet_len, u Request **request_container = &client->current_request; Pdu_header incoming_pdu_header; - - int packet_index = process_pdu_header(packet, false, &incoming_pdu_header, res, request_container, client->request_list, client->app); if (packet_index < 0) { ssp_printf("error parsing header\n"); return -1; } + Request *current_request = (*request_container); parse_packet_client(packet, packet_index, res, current_request, client); @@ -163,7 +162,7 @@ static void user_request_check(Node *node, void *request, void *args) { memset(params->res.msg, 0, params->client->packet_len); user_request_handler(params->res, req, params->client); - timeout(req); + timeout(req, params->client->remote_entity.transaction_inactivity_limit); remove_request_check(node, request, params->client->request_list); } @@ -213,9 +212,11 @@ static void client_check_callback(Node *node, void *client, void *args) { static void timeout_check_callback_server(Node *node, void *request, void *args) { Request *req = (Request *) request; + FTP *app = (FTP *) args; + on_server_time_out(req->res, req); - timeout(req); - remove_request_check(node, request, args); + timeout(req, app->remote_entity.transaction_inactivity_limit); + remove_request_check(node, request, app->request_list); } //return 1 if there are active requests, 0 if not @@ -227,7 +228,7 @@ static int on_time_out_callback_server(void *other) { app->active_clients->iterate(app->active_clients, client_check_callback, app->active_clients); } if (app->request_list->count) { - app->request_list->iterate(app->request_list, timeout_check_callback_server, app->request_list); + app->request_list->iterate(app->request_list, timeout_check_callback_server, app); } else { return 0; @@ -538,6 +539,7 @@ void *ssp_csp_connection_client_task(void *params) { client->remote_entity.UT_port, CSP_ANY, client->remote_entity.mtu, + client->remote_entity.total_round_trip_allowance, on_send_client_callback, on_recv_client_callback, check_exit_client_callback, diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 116fc01..7a87c4f 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -144,7 +144,7 @@ void csp_connectionless_server(uint8_t my_port, uint32_t packet_len, uint32_t ti } } -int csp_custom_ftp_ping(uint32_t dest_id){ +int csp_custom_ftp_ping(uint32_t dest_id, uint32_t port){ char buff[255]; memset(buff, 0, 255); @@ -152,7 +152,7 @@ int csp_custom_ftp_ping(uint32_t dest_id){ csp_packet_t * packet; csp_conn_t * conn; /* Connect to host HOST, port PORT with regular UDP-like protocol and 1000 ms timeout */ - conn = csp_connect(CSP_PRIO_NORM, dest_id, 1, 1000, CSP_SO_NONE); + conn = csp_connect(CSP_PRIO_NORM, dest_id, port, 1000, CSP_SO_NONE); if (conn == NULL) { /* Connect failed */ ssp_printf("Connection failed\n"); @@ -178,7 +178,7 @@ int csp_custom_ftp_ping(uint32_t dest_id){ } else { memcpy(buff, (char *)p->data, p->length); - ssp_printf("%s\n", buff); + ssp_printf("received: %s\n", buff); csp_close(conn); return 1; @@ -269,7 +269,7 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_o } -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, uint32_t time_out, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), @@ -287,7 +287,8 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, return; } - + Client *client = (Client*) params; + while (1) { if (get_exit() || checkExit(params)){ @@ -301,8 +302,8 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, } onSend(-1, conn, sizeof(conn), params); - - while ((packet = csp_read(conn, 10000)) != NULL) { + + while ((packet = csp_read(conn, time_out)) != NULL) { memcpy(buff, (char *)packet->data, packet_len); @@ -313,8 +314,9 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, } csp_close(conn); - } - + break; + + } /* Close connection */ if (conn != NULL) csp_close(conn); diff --git a/Program/src/file_delivery_app.c b/Program/src/file_delivery_app.c index 82bdb0f..6f3d7b8 100755 --- a/Program/src/file_delivery_app.c +++ b/Program/src/file_delivery_app.c @@ -84,25 +84,25 @@ static void make_default_data(){ ssp_error("couldn't make directory mib it either already exists or there is an issue\n"); } const char *peer_file_sat = "{\n\ - \"cfdp_id\": 0,\n\ + \"cfdp_id\": 1,\n\ \"UT_address\" : 1,\n\ \"UT_port\" : 20,\n\ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ - \"MTU\" : 1450,\n\ - \"one_way_light_time\" : 123,\n\ - \"total_round_trip_allowance\" : 123,\n\ + \"MTU\" : 200,\n\ + \"total_round_trip_allowance\" : 100000,\n\ \"async_NAK_interval\" : 30000,\n\ - \"async_keep_alive_interval\" : 123,\n\ + \"transaction_inactivity_limit\" : 15000,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ \"prompt_transmission_interval\" : 123,\n\ \"disposition_of_incomplete\" : 123,\n\ - \"CRC_required\" : 0,\n\ - \"keep_alive_discrepancy_limit\" : 8,\n\ + \"CRC_required\" : 123,\n\ + \"keep_alive_discrepancy_limit\" : 123,\n\ \"positive_ack_timer_expiration_limit\" : 123,\n\ \"nak_timer_expiration_limit\" : 123,\n\ - \"transaction_inactivity_limit\" : 123\n\ + \"async_keep_alive_interval\" : 123,\n\ + \"one_way_light_time\" : 123\n\ }"; const char *peer_file_ground_station = "{\n\ @@ -111,10 +111,10 @@ static void make_default_data(){ \"UT_port\" : 1,\n\ \"type_of_network\" : 3,\n\ \"default_transmission_mode\" : 1,\n\ - \"MTU\" : 1450,\n\ - \"one_way_light_time\" : 123,\n\ - \"total_round_trip_allowance\" : 123,\n\ + \"MTU\" : 200,\n\ + \"total_round_trip_allowance\" : 100000,\n\ \"async_NAK_interval\" : 30000,\n\ + \"transaction_inactivity_limit\" : 15000,\n\ \"async_keep_alive_interval\" : 123,\n\ \"async_report_interval\" : 123,\n\ \"immediate_nak_mode_enabled\" : 123,\n\ @@ -124,7 +124,7 @@ static void make_default_data(){ \"keep_alive_discrepancy_limit\" : 8,\n\ \"positive_ack_timer_expiration_limit\" : 123,\n\ \"nak_timer_expiration_limit\" : 123,\n\ - \"transaction_inactivity_limit\" : 123\n\ + \"one_way_light_time\" : 123\n\ }"; int fd = ssp_open("mib/peer_1.json", SSP_O_CREAT | SSP_O_RDWR); @@ -159,7 +159,11 @@ static void make_default_data(){ int init_ftp(uint32_t my_cfdp_address, FTP *app) { int error = 0; + //sanitize everything but the server_handle in case of race condition which sets the handler first. + void *handler = app->server_handle; memset(app, 0, sizeof(FTP)); + app->server_handle = handler; + make_default_data(); diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 8a2223d..6ac8396 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -39,9 +39,9 @@ File *create_file(char *source_file_name, int clear_file_contents) { int fd = 0; if (clear_file_contents){ - fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC); + fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC, 0777); }else { - fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT); + fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT, 0777); } if (fd == -1){ ssp_error("couldn't create file\n"); @@ -60,6 +60,9 @@ File *create_file(char *source_file_name, int clear_file_contents) { } File *file = ssp_alloc(1, sizeof(File)); + if (file == NULL) { + return NULL; + } file->fd = fd; file->eof_checksum = 0; @@ -67,6 +70,10 @@ File *create_file(char *source_file_name, int clear_file_contents) { file->total_size = total_size; file->partial_checksum = 0; file->missing_offsets = linked_list(); + if (file->missing_offsets == NULL) { + ssp_free(file); + return NULL; + } return file; @@ -304,7 +311,7 @@ static int print_nak(void *element, void* args) { int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file) { - ssp_printf("renaming %s to: %s", temp, destination_file_name); + ssp_printf("renaming %s to: %s\n", temp, destination_file_name); ssp_rename(temp, destination_file_name); //file->missing_offsets->print(file->missing_offsets, print_nak, NULL); @@ -328,6 +335,7 @@ int read_json(char *file_name, int (*callback)(char *key, char *value, void *par jsmn_parser p; jsmn_init(&p); int error = 0; + char *close_file_error = "couldn't close file\n"; jsmntok_t tok[255]; @@ -352,6 +360,10 @@ int read_json(char *file_name, int (*callback)(char *key, char *value, void *par if (r < 0) { ssp_free(buff); ssp_error("read failed\n"); + error = ssp_close(fd); + if (error) { + ssp_printf(close_file_error); + } return -1; } @@ -359,6 +371,10 @@ int read_json(char *file_name, int (*callback)(char *key, char *value, void *par if (r < 0) { ssp_free(buff); ssp_error("Failed to parse JSON\n"); + error = ssp_close(fd); + if (error) { + ssp_printf(close_file_error); + } return -1; } int i = 1; @@ -369,6 +385,10 @@ int read_json(char *file_name, int (*callback)(char *key, char *value, void *par char *key = ssp_alloc(key_size + 1, sizeof(char)); if (key == NULL) { + error = ssp_close(fd); + if (error) { + ssp_printf(close_file_error); + } ssp_free(buff); return -1; } @@ -380,6 +400,10 @@ int read_json(char *file_name, int (*callback)(char *key, char *value, void *par if (value == NULL) { ssp_free(buff); ssp_free(value); + error = ssp_close(fd); + if (error) { + ssp_printf(close_file_error); + } return -1; } @@ -393,256 +417,25 @@ int read_json(char *file_name, int (*callback)(char *key, char *value, void *par i++; if (error < 0) { + error = ssp_close(fd); + if (error) { + ssp_printf(close_file_error); + } return error; } } - ssp_free(buff); - - return 0; -} - - - -static void save_file_callback(Node *node, void *element, void *param) { - - char *error_message = "failed to write offset\n"; - - struct params *p = (struct params *) param; - if (p->error < 0){ - return; - } - - Offset *offset = (Offset *)element; - int err = ssp_write(p->fd, offset, sizeof(Offset)); - if (err < 0) { - ssp_error(error_message); - p->error = err; - return; - } -} - -/* - first write file, - then length of offsets, - then offsets -*/ -int save_file_to_file(int fd, File *file) { - - char *error_message = "failed to write file\n"; - - int err = ssp_write(fd, file, sizeof(File)); - if (err < 0) { - ssp_error(error_message); - return -1; - } - - err = ssp_write(fd, &file->missing_offsets->count, sizeof(uint32_t)); - if (err < 0) { - ssp_error(error_message); - return -1; - } - - struct params param = { - 0, - fd - }; - - file->missing_offsets->iterate(file->missing_offsets, save_file_callback, ¶m); - return param.error; -} -//[file][length][offsets] -int get_file_from_file(int fd, File *file) { - - uint32_t length = 0; - char *error_msg = "read failed meta data\n"; - int r = ssp_read(fd, (char *)file, sizeof(File)); - if (r < 0) { - ssp_error(error_msg); - return -1; - } - - r = ssp_read(fd, (char *)&length, sizeof(uint32_t)); - if (r < 0) { - ssp_error(error_msg); - return -1; - } - Offset offset; - memset(&offset, 0, sizeof(Offset)); - - List *missing_offsets = linked_list(); - if (missing_offsets == NULL) { - return -1; - } - int i = 0; - for (i = 0; i < length; i++) { - - r = ssp_read(fd, (char*)&offset, sizeof(Offset)); - - if (r < 0) { - ssp_error(error_msg); - return -1; - } - - Offset *new_offset = ssp_alloc(1, sizeof(Offset)); - if (new_offset == NULL) { - missing_offsets->free(missing_offsets, ssp_free); - return -1; - } - - ssp_memcpy(new_offset, &offset, sizeof(Offset)); - missing_offsets->push(missing_offsets, new_offset, -1); + error = ssp_close(fd); + if (error) { + ssp_printf(close_file_error); } + ssp_free(buff); - file->missing_offsets = missing_offsets; return 0; } -int write_id(int fd, uint64_t id){ - - char *error_message = "failed to write id\n"; - uint64_t network_byte_order = 0; - network_byte_order = ssp_htonll(id); - - int err = ssp_write(fd, &network_byte_order, sizeof(uint64_t)); - if (err < 0) { - ssp_error(error_message); - return -1; - } - return 1; -} - -int read_id(int fd, uint64_t *id){ - - char *error_message = "failed to write id\n"; - uint64_t host_byte_order = 0; - - int err = ssp_read(fd, &host_byte_order, sizeof(uint64_t)); - if (err < 0) { - ssp_error(error_message); - return -1; - } - - *id = ssp_ntohll(host_byte_order); - return 1; -} - -int write_lv(int fd, LV lv){ - - char *error_message = "failed to write lv\n"; - int err = ssp_write(fd, (char*)&lv.length, sizeof(uint8_t)); - if (err < 0) { - ssp_error(error_message); - return -1; - } - err = ssp_write(fd, (char*)lv.value, lv.length); - if (err < 0) { - ssp_error(error_message); - return -1; - } - return 1; -} -int read_lv(int fd, LV *lv){ - - char *error_message = "failed to read lv\n"; - int err = ssp_read(fd, (char*)&lv->length, sizeof(uint8_t)); - if (err < 0) { - ssp_error(error_message); - return -1; - } - lv->value = ssp_alloc(lv->length, sizeof(uint8_t)); - if(lv->value == NULL) { - return -1; - } - err = ssp_read(fd, (char*)lv->value, lv->length); - if (err < 0) { - ssp_error(error_message); - return -1; - } - return 1; -} - -//length -//dest_file -//length -//src_file - -static void write_put_proxy_message(int fd, int *error, Message_put_proxy *proxy_message) { - - char *error_message = "failed to write put proxy message\n"; - - int err = write_lv(fd, proxy_message->destination_file_name); - if (err < 0) { - *error = err; - ssp_error(error_message); - return; - } - - err = write_lv(fd, proxy_message->source_file_name); - if (err < 0) { - *error = err; - ssp_error(error_message); - return; - } - - err = write_id(fd, proxy_message->destination_id); - if (err < 0) { - *error = err; - ssp_error(error_message); - return; - } -} -static void write_message_callback(Node *node, void *element, void *param) { - - struct params *p = (struct params *) param; - int fd = p->fd; - if (p->error < 0){ - return; - } - - Message *message = (Message *)element; - - //write type - int error = ssp_write(fd, &message->header.message_type, sizeof(uint8_t)); - if (error < 0) { - p->error = error; - ssp_error("failed to append to end of file\n"); - return; - } - Message_put_proxy *proxy_message; - - switch (message->header.message_type) - { - case PROXY_PUT_REQUEST: - proxy_message = (Message_put_proxy *)message->value; - //ssp_printf("writing put proxy message\n"); - write_put_proxy_message(fd, &p->error, proxy_message); - break; - - default: - break; - } -} - - -static int write_file_present_bool(int fd, File *file) { - int error = 0; - bool file_is_present = true; - bool file_is_not_present = false; - - if (file != NULL) { - error = ssp_write(fd, &file_is_present, sizeof(bool)); - if (error == -1) - return -1; - } else { - error = ssp_write(fd, &file_is_not_present, sizeof(bool)); - if (error == -1) - return -1; - } - return error; -} static int get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id, uint64_t trans) { @@ -653,7 +446,7 @@ static int get_file_name(char *filename, uint32_t dest_cfdp_id, uint32_t cfdp_id if (error < 0) return -1; - ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%lu%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".request"); + ssp_snprintf(filename, MAX_PATH, "%s%u%s%u%s%u%s%lu%s", "incomplete_requests/CFID:", dest_cfdp_id, "_requests/dest_id:", dest_cfdp_id,":cfdp_id:", cfdp_id, ":trans:", trans, ".json"); return 1; } @@ -666,290 +459,44 @@ int delete_saved_request(Request *req) { return error; } -//work in progress -//[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] + int save_req_to_file(Request *req) { char file_name[255]; - get_file_name(file_name, req->dest_cfdp_id, req->my_cfdp_id, req->transaction_sequence_number); - - int fd = ssp_open(file_name, SSP_O_RDWR | SSP_O_CREAT); - if (fd < 0) { - ssp_error("couldn't open file\n"); - return -1; - } - - //writing request struct - int error = ssp_write(fd, req, sizeof(Request)); - if (error == -1) { - ssp_printf("couldnt write request struct\n"); - return -1; - } - - struct params param = { - 0, - fd - }; + memset(file_name, 0, sizeof(file_name)); - //writing is file present - error = write_file_present_bool(fd, req->file); - if (error < 0){ - ssp_printf("couldnt write bool\n"); - return -1; - } - - //writing file - if (req->file != NULL) { - error = save_file_to_file(fd, req->file); - if (error < 0) { - ssp_printf("couldnt write file\n"); - return -1; - } - } + get_file_name(file_name, req->dest_cfdp_id, req->my_cfdp_id, req->transaction_sequence_number); - //writing message count - error = ssp_write(fd, &req->messages_to_user->count, sizeof(uint8_t)); + int error = write_request_json(req, file_name); if (error == -1) { - ssp_printf("couldnt write message count\n"); - return -1; - } - - if (!req->messages_to_user->count) - return 0; - - //writing messages - req->messages_to_user->iterate(req->messages_to_user, write_message_callback, ¶m); - if (param.error < 0) { - ssp_printf("couldnt write messsages\n"); - return -1; - } - - error = ssp_close(fd); - if (error < 0) { - ssp_error("couldn't close file descriptor\n"); - return -1; - } - return 0; -} - -static Message *read_in_proxy_message(int fd) { - - - char *error_message = "failed to read put proxy message\n"; - - LV destination_file; - LV src_file_name; - uint64_t dest_id; - - int err = read_lv(fd, &destination_file); - if (err < 0) { - ssp_error(error_message); - return NULL; - } - err = read_lv(fd, &src_file_name); - if (err < 0) { - ssp_error(error_message); - return NULL; - } - err = read_id(fd, &dest_id); - if (err < 0) { - ssp_error(error_message); - return NULL; - } - - Message *message = create_message(PROXY_PUT_REQUEST); - if (message == NULL) - return NULL; - - Message_put_proxy *proxy_message = ssp_alloc(1, sizeof(Message_put_proxy)); - if (proxy_message == NULL) { - ssp_free(message); - return NULL; - } - proxy_message->destination_file_name = destination_file; - proxy_message->source_file_name = src_file_name; - proxy_message->destination_id = dest_id; - - message->value = proxy_message; - return message; -} - -static int get_messages_from_file(int fd, List *messages){ - - uint8_t number_of_messages; - int error = ssp_read(fd, (char *) &number_of_messages, sizeof(uint8_t)); - if (error == -1){ + ssp_printf("couldnt write request struct\n"); return -1; } - if (number_of_messages > 0) { - int i = 0; - for (i = 0; i < number_of_messages; i++) { - - uint8_t message_type = 0; - error = ssp_read(fd, (char *) &message_type, sizeof(uint8_t)); - if (error == -1) - return -1; - - Message *message; - switch (message_type) - { - case PROXY_PUT_REQUEST: - message = read_in_proxy_message(fd); - break; - case CONTINUE_PARTIAL: - ssp_printf("this type of message is not implmeneted yet\n"); - continue; - default: - ssp_printf("failed to read in message, no known message type\n"); - continue; - } - message->header.message_type = message_type; - messages->push(messages, message, -1); - } - } return 0; } -int read_request_from_file(int fd, Request *req){ - - //will overwrite messages pointer, so we need to save it - List *messages = req->messages_to_user; - int timeout_before_cancel = req->timeout_before_cancel; - int timeout_before_journal = req->timeout_before_journal; - void *addr = req->res.addr; - - //read in request struct - int error = ssp_read(fd, (char *)req, sizeof(Request)); - if (error == -1) - return -1; - - //check to see if file is present - bool is_file_present = false; - error = ssp_read(fd, (char *)&is_file_present, sizeof(bool)); - if (error == -1) - return -1; - - File *file = NULL; - if (is_file_present) { - file = ssp_alloc(1, sizeof(File)); - if (file == NULL) { - return -1; - } - error = get_file_from_file(fd, file); - if (error < 0) { - ssp_free(file); - return -1; - } - req->file = file; - } - - req->messages_to_user = messages; - req->timeout_before_cancel = timeout_before_cancel; - req->timeout_before_journal = timeout_before_journal; - req->res.addr = addr; - - error = get_messages_from_file(fd, req->messages_to_user); - if (error == -1) { - ssp_free(file); - return -1; - } - - return error; -} - -//[REQ][IS_FILE_PRESENT][FILE][MESSAGE_LENGTH][MESSAGES] int get_req_from_file(uint32_t dest_cfdp_id, uint64_t transaction_seq_num, uint32_t my_cfdp_id, Request *req) { char file_name[255]; get_file_name(file_name, dest_cfdp_id, my_cfdp_id, transaction_seq_num); - ssp_printf("opening %s\n", file_name); - int fd = ssp_open(file_name, SSP_O_RDWR); - if (fd < 0) { - ssp_error("couldn't open file\n"); - return -1; - } - int error = read_request_from_file(fd, req); + int error = does_file_exist(file_name); if (error < 0) { return -1; } - error = ssp_close(fd); + + error = get_request_from_json (req, file_name); if (error < 0) { - ssp_error("couldn't close file descriptor \n"); + ssp_error("couldn't get json file\n"); + return -1; } return 0; } -//NEEEEEEEEEEEEW stuff - -/* -//incoming requests spin up requests -typedef struct request { - Request_procedure procedure; - - uint64_t transaction_sequence_number; - uint32_t dest_cfdp_id; - uint32_t my_cfdp_id; - - File *file; - uint32_t file_size; - - char source_file_name[MAX_PATH]; - char destination_file_name[MAX_PATH]; - - //previous timeout time in seconds - int timeout_before_cancel; - int timeout_before_journal; - - uint8_t segmentation_control; - uint8_t fault_handler_overides; - uint8_t flow_lable; - uint8_t transmission_mode; - bool paused; - - //counter for resending eof packets == 3 - uint8_t resent_eof; - //counter for resending finished packets == 3 - uint8_t resent_finished; - - //bool for sending first blast of data packets - // uint8_t sent_first_data_round; - - Remote_entity remote_entity; - Local_entity local_entity; - - List *messages_to_user; - - //sets the buffer length, for making packets - uint32_t buff_len; - - //buffer for making packets - char* buff; - - //header for building response packets - Pdu_header pdu_header; - - //handler for sending responses back - Response res; -} Request; - -typedef struct file { - int fd; - uint8_t is_temp; - uint32_t next_offset_to_send; - uint32_t total_size; - uint32_t partial_checksum; - uint32_t eof_checksum; - List *missing_offsets; - -} File; -*/ - - static int parse_json_missing_offset_list(List *list, char *value) { int i = 0; @@ -1059,6 +606,13 @@ static char *parse_list[REQ_TOTAL] = { "file.missing_offsets" }; +static int check_null_file(File *file){ + if (file == NULL) { + ssp_printf("the json has file data, but the request struct has no file initialized\n"); + return 1; + } + return 0; +} static int parse_json_request(char *key, char *value, void *params) { @@ -1067,7 +621,7 @@ static int parse_json_request(char *key, char *value, void *params) { int error = 0; Request *req = (Request *) params; - + for (i = 0; i < REQ_TOTAL; i++) { len = strnlen(parse_list[i], 50); @@ -1090,10 +644,10 @@ static int parse_json_request(char *key, char *value, void *params) { req->file_size = ssp_atol(value); break; case REQ_source_file_name: - //req->my_cfdp_id = ssp_atol(value); + strncpy(req->source_file_name, (char *) value, MAX_PATH); break; case REQ_destination_file_name: - //req->my_cfdp_id = ssp_atol(value); + strncpy(req->destination_file_name, (char *) value, MAX_PATH); break; case REQ_transmission_mode: req->transmission_mode = ssp_atol(value); @@ -1138,6 +692,11 @@ static int parse_json_request(char *key, char *value, void *params) { //req->messages_to_user = ssp_atol(value); break; case REQ_file_is_temp: + if (check_null_file(req->file)) + req->file = create_file(req->destination_file_name, false); + if (req->file == NULL) + return -1; + req->file->is_temp = ssp_atol(value); break; case REQ_file_next_offset_to_send: @@ -1169,19 +728,6 @@ static int parse_json_request(char *key, char *value, void *params) { return 0; } -int get_request_from_json (Request *req, char *file_name) { - - int error = read_json(file_name, parse_json_request, req); - - if (error < 0) { - ssp_error("json parsing failed\n"); - return -1; - } - - return 0; -} - - static struct json_write_callback { int error; @@ -1345,7 +891,7 @@ int write_request_json (Request *req, char *file_name) { return -1; } - int fd = ssp_open(file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC); + int fd = ssp_open(file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC, 0777); if (fd == -1) { ssp_error("count not open file\n"); return fd; @@ -1359,4 +905,23 @@ int write_request_json (Request *req, char *file_name) { add_end_of_json(fd); -} \ No newline at end of file + if (ssp_close(fd) == -1){ + ssp_error("could not close file\n"); + return -1; + } + +} + + +int get_request_from_json (Request *req, char *file_name) { + + int error = read_json(file_name, parse_json_request, req); + + if (error < 0) { + ssp_error("json parsing failed\n"); + return -1; + } + + return 0; +} + diff --git a/Program/src/mib.c b/Program/src/mib.c index 7a846e3..0949df9 100755 --- a/Program/src/mib.c +++ b/Program/src/mib.c @@ -59,7 +59,6 @@ static char *parse_list[PARSE_TOTAL] = { "UT_port" , "type_of_network", "default_transmission_mode" , - "one_way_light_time" , "total_round_trip_allowance" , "async_NAK_interval", @@ -68,7 +67,6 @@ static char *parse_list[PARSE_TOTAL] = { "immediate_nak_mode_enabled" , "prompt_transmission_interval" , "disposition_of_incomplete" , - "CRC_required" , "MTU" , "keep_alive_discrepancy_limit" , @@ -78,7 +76,7 @@ static char *parse_list[PARSE_TOTAL] = { }; -static void parse_mib(char *key, char *value, void *params) { +static int parse_mib(char *key, char *value, void *params) { int len = 0; int i = 0; @@ -153,6 +151,7 @@ static void parse_mib(char *key, char *value, void *params) { break; } } + return 0; } int get_remote_entity_from_json (Remote_entity *remote, uint32_t cfdp_id) { diff --git a/Program/src/packet.c b/Program/src/packet.c index 3e86f0a..e667ae7 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -137,7 +137,7 @@ void ssp_print_header(Pdu_header *pdu_header){ ssp_printf("pdu_header->reserved_bit_2 %d\n",pdu_header->reserved_bit_2); ssp_printf("pdu_header->transaction_seq_num_len %d\n",pdu_header->transaction_seq_num_len); ssp_printf("pdu_header->source_id %d\n",pdu_header->source_id); - ssp_printf("pdu_header->transaction_sequence_number %d\n",pdu_header->transaction_sequence_number); + ssp_printf("pdu_header->transaction_sequence_number %llu\n",pdu_header->transaction_sequence_number); ssp_printf("pdu_header->destination_id %d\n",pdu_header->destination_id); ssp_printf("---------------------------------------------\n"); diff --git a/Program/src/port.c b/Program/src/port.c index ecb284e..e0f44db 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -170,8 +170,7 @@ void ssp_sendto(Response res) { #ifdef TEST return; #endif - //sleep(1); - + if (res.type_of_network == generic) { #ifdef FREE_RTOS_PORT @@ -289,6 +288,7 @@ void ssp_free(void *pointer) { //what kind of errorno functions do we have in RED_FS? void ssp_error(char *error){ + ssp_printf("ERROR: "); perror(error); } @@ -355,13 +355,13 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void int err = pthread_attr_init(attr); if (0 != err) { - perror("pthread_init failed"); + ssp_error("pthread_init failed"); ssp_free(attr); ssp_free(handler); } err = pthread_attr_setstacksize(attr, stack_size); if (0 != err) - ssp_error("ERROR pthread_attr_setstacksize %d"); + ssp_error("pthread_attr_setstacksize %d"); if (EINVAL == err) { ssp_printf("the stack size is less that PTHREAD_STACK_MIN %d\n", PTHREAD_STACK_MIN); @@ -372,7 +372,7 @@ void *ssp_thread_create(int stack_size, void * (thread_func)(void *params), void err = pthread_create(handler, attr, thread_func, params); if (0 != err) { - perror("ERROR pthread_create"); + ssp_error("pthread_create"); ssp_free(handler); } ssp_free(attr); From c2a7875eb54f01cdccff95db20da844248a19597 Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 22 May 2021 18:31:19 -0600 Subject: [PATCH 350/400] change filesystem and request tests --- Program/include/csp_server_provider.h | 4 +- Program/src/requests.c | 53 +++-- Program/test/filesystem_tests.c | 268 +------------------------- Program/test/request_tests.c | 98 +++++++--- 4 files changed, 98 insertions(+), 325 deletions(-) diff --git a/Program/include/csp_server_provider.h b/Program/include/csp_server_provider.h index 126b98d..4934539 100755 --- a/Program/include/csp_server_provider.h +++ b/Program/include/csp_server_provider.h @@ -29,11 +29,11 @@ void csp_connection_server(uint8_t my_port, uint32_t packet_len, uint32_t time_o void (*onExit)(void *other), void *other); -void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, +void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, uint32_t packet_len, uint32_t time_out, int (*onSend)(int sfd, void *addr, uint32_t size_of_addr, void *onSendParams), int (*onRecv)(int sfd, char *packet, uint32_t packet_len, uint32_t *buff_size, void *addr, size_t size_of_addr, void *onRecvParams) , int (*checkExit)(void *checkExitParams), void (*onExit)(void *params), void *params); -int csp_custom_ftp_ping(uint32_t dest_id); +int csp_custom_ftp_ping(uint32_t dest_id, uint32_t port); #endif diff --git a/Program/src/requests.c b/Program/src/requests.c index 0bd7dd1..d4124b5 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -441,10 +441,9 @@ Request *get_request( data will be delivered. Side effect: add request to client request list returns the request*/ -int schedule_request(Request *req, uint32_t dest_id, uint8_t transmission_mode, FTP *app) { +int schedule_request(Request *req, uint32_t dest_id, FTP *app) { req->dest_cfdp_id = dest_id; req->my_cfdp_id = app->my_cfdp_id; - req->transmission_mode = transmission_mode; req->procedure = sending_start; int error = save_req_to_file(req); return error; @@ -458,19 +457,26 @@ int schedule_put_request( FTP *app ) { int error = 0; + Request *req = init_request_no_client(); if (req == NULL) { ssp_error("couldn't init request"); - return error; + return -1; } - if (put_request_no_client(req, source_file_name, destination_file_name, transmission_mode, app) < 0){ + + error = put_request_no_client(req, source_file_name, destination_file_name, transmission_mode, app); + if (error < 0){ ssp_error("couldn't configure request"); - return error; + return -1; } - error = schedule_request(req, dest_id, transmission_mode, app); - return error; + error = schedule_request(req, dest_id, app); + if (error < 0) { + ssp_error("failed to schedule request"); + return -1; + } + return 0; } static void clean_up_start_scheduled_requests(int fd, Request *req){ @@ -506,6 +512,12 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ //adding +2 here because file->name is of max 256 size, and then we add a /. char file_path[MAX_PATH + 2]; + client = start_client(app, dest_id); + if (client == NULL) { + ssp_error("couldn't start new request"); + return -1; + } + while( (ssp_readdir(dir, file)) ) { if (strncmp(file, ".", 1) == 0 || strncmp(file, "..", 2) == 0) @@ -513,40 +525,21 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ ssp_snprintf(file_path, sizeof(file_path), "%s/%s", dir_name, file); - fd = ssp_open(file_path, SSP_O_RDWR); - if (fd < 0) { - clean_up_start_scheduled_requests(fd, req); - ssp_error("couldn't open request data file"); - continue; - } - - client = start_client(app, dest_id); - if (client == NULL) { - clean_up_start_scheduled_requests(fd, req); - ssp_error("couldn't start new request"); - continue; - } - req = init_request_no_client(); if (req == NULL) { - clean_up_start_scheduled_requests(fd, req); + ssp_cleanup_req(req); ssp_error("couldn't init request"); continue; } - error = read_request_from_file(fd, req); + error = get_request_from_json(req, file_path); if (error < 0) { - clean_up_start_scheduled_requests(fd, req); - ssp_error("couldn't read in request"); + ssp_cleanup_req(req); + ssp_error("couldn't read in json request"); continue; } add_request_to_client(req, client); - - error = ssp_close(fd); - if (error < 0) { - ssp_error("there was an error closing the file descriptor"); - } } ssp_closedir(dir); diff --git a/Program/test/filesystem_tests.c b/Program/test/filesystem_tests.c index f0176a0..5d1cbdd 100755 --- a/Program/test/filesystem_tests.c +++ b/Program/test/filesystem_tests.c @@ -43,262 +43,18 @@ int read_json_file_test() { return 1; } - -int test_write_lv() { - - DECLARE_NEW_TEST("test write lv"); - char *my_file_name = "temp/test_lv_write"; - int fd = ssp_open(my_file_name, O_RDWR | O_CREAT); - if (fd < 0) { - ssp_error("couldn't open file\n"); - return -1; - } - - LV lv; - lv.value = my_file_name; - lv.length = strnlen(my_file_name, 255); - - int error = write_lv(fd, lv); - if (error < 0) { - return -1; - } - //seek back to start of file - ssp_lseek(fd, 0, 0); - - LV new_lv; - error = read_lv(fd, &new_lv); - if (error < 0) { - return -1; - } - - ASSERT_EQUALS_STR("write&read lv value to file", lv.value, my_file_name, lv.length); - ASSERT_EQUALS_INT("write&read lv length", new_lv.length, lv.length); - free_lv(new_lv); - - return 1; -} - -int test_save_file() { - - - DECLARE_NEW_TEST("test saving file"); - - char *file_name = "temp/test_file_save"; - int fd = ssp_open(file_name, O_RDWR | O_CREAT); - if (fd < 0) { - ssp_error("couldn't open file\n"); - return -1; - } - int *error = 0; - File file; - memset(&file, 0, sizeof(File)); - - file.missing_offsets = linked_list(); - - Offset one = { - 0, 250 - }; - Offset two = { - 100, 250 - }; - Offset three = { - 250, 250 - }; - - file.missing_offsets->push(file.missing_offsets, &one, -1); - file.missing_offsets->push(file.missing_offsets, &two, -1); - file.missing_offsets->push(file.missing_offsets, &three, -1); - - - save_file_to_file(fd, &file); - - File read; - memset(&read, 0, sizeof(File)); - - file.missing_offsets->freeOnlyList(file.missing_offsets); - - ssp_lseek(fd, 0, 0); - - get_file_from_file(fd, &read); - - Offset *offset = read.missing_offsets->pop(read.missing_offsets); - ASSERT_EQUALS_INT("offset start should equal", three.start, offset->start); - ASSERT_EQUALS_INT("offset end should equal", three.end, offset->end); - ssp_free(offset); - - offset = read.missing_offsets->pop(read.missing_offsets); - ASSERT_EQUALS_INT("offset start should equal", two.start, offset->start); - ASSERT_EQUALS_INT("offset end should equal", two.end, offset->end); - ssp_free(offset); - - offset = read.missing_offsets->pop(read.missing_offsets); - ASSERT_EQUALS_INT("offset start should equal", one.start, offset->start); - ASSERT_EQUALS_INT("offset end should equal", one.end, offset->end); - ssp_free(offset); - - ASSERT_EQUALS_INT("File eof_checksum", file.eof_checksum, read.eof_checksum); - ASSERT_EQUALS_INT("File fd --should be ignored", file.fd, read.fd); - - ASSERT_EQUALS_INT("File is_temp", file.is_temp, read.is_temp); - ASSERT_EQUALS_INT("File next_offset_to_send", file.next_offset_to_send, read.next_offset_to_send); - - ASSERT_EQUALS_INT("File partial_checksum", file.partial_checksum, read.partial_checksum); - ASSERT_EQUALS_INT("File total_size", file.total_size, read.total_size); - - read.missing_offsets->free(read.missing_offsets, ssp_free); -} - -static int test_saving_request(){ - - int error = 0; - - DECLARE_NEW_TEST("test saving requests"); - - Request *req = mock_empty_request(); - - req->dest_cfdp_id = 1; - req->transaction_sequence_number = 1; - req->my_cfdp_id = 1; - - req->local_entity.EOF_recv_indication = 1; - req->local_entity.EOF_sent_indication = 1; - req->local_entity.suspended_indication = 1; - char *dest_file = "stuff"; - char *src_file = "morestuff"; - - Message *m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m, 0); - - Message *m2 = create_message(PROXY_PUT_REQUEST); - m2->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m2, 0); - - Message *m3 = create_message(PROXY_PUT_REQUEST); - m3->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m3, 0); - - error = save_req_to_file(req); - if (error == -1) - printf("failed to write\n"); - - ssp_cleanup_req(req); -} - -int test_get_file(){ - DECLARE_NEW_TEST("test getting requests"); - Request *req = mock_empty_request(); - char *dest_file = "stuff"; - char *src_file = "morestuff"; - - int error = get_req_from_file(1, 1, 1, req); - if (error < 0) - printf("failed to read\n"); - - Message *message = req->messages_to_user->pop(req->messages_to_user); - Message_put_proxy *proxy_message = (Message_put_proxy *) message->value; - - ASSERT_EQUALS_STR("third message src file name", proxy_message->destination_file_name.value, dest_file, proxy_message->destination_file_name.length); - ASSERT_EQUALS_STR("third message src file name", proxy_message->source_file_name.value, src_file, proxy_message->source_file_name.length); - ASSERT_EQUALS_INT("third message id", proxy_message->destination_id, req->dest_cfdp_id); - ssp_free_message(message); - - message = req->messages_to_user->pop(req->messages_to_user); - proxy_message = (Message_put_proxy *) message->value; - ASSERT_EQUALS_STR("second message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); - ASSERT_EQUALS_STR("second message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); - ASSERT_EQUALS_INT("second message id", proxy_message->destination_id, req->dest_cfdp_id); - ssp_free_message(message); - - message = req->messages_to_user->pop(req->messages_to_user); - proxy_message = (Message_put_proxy *) message->value; - ASSERT_EQUALS_STR("first message src file name", proxy_message->destination_file_name.value, dest_file, sizeof(dest_file)); - ASSERT_EQUALS_STR("first message src file name", proxy_message->source_file_name.value, src_file, sizeof(src_file)); - ASSERT_EQUALS_INT("first message id", proxy_message->destination_id, req->dest_cfdp_id); - ssp_free_message(message); - - ssp_cleanup_req(req); - //need to free list - return error; -} - -int test_save_file_and_messages() { - - DECLARE_NEW_TEST("test saving file and messages"); - int error = 0; - Request *req = mock_empty_request(); - - req->dest_cfdp_id = 2; - req->transaction_sequence_number = 2; - req->my_cfdp_id = 2; - req->local_entity.EOF_recv_indication = 1; - req->local_entity.EOF_sent_indication = 1; - req->local_entity.suspended_indication = 1; - req->file = NULL; - char *dest_file = "stuff"; - char *src_file = "morestuff"; - - Message *m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m, 0); - - m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m, 0); - - m = create_message(PROXY_PUT_REQUEST); - m->value = create_message_put_proxy(1, 1, src_file, dest_file); - req->messages_to_user->push(req->messages_to_user, m, 0); - - error = save_req_to_file(req); - if (error == -1) - printf("failed to write\n"); - - - File *file = ssp_alloc(1, sizeof(File)); - file->missing_offsets = linked_list(); - - - - Offset *one = ssp_alloc(1, sizeof(Offset)); - Offset *two = ssp_alloc(1, sizeof(Offset)); - Offset *three = ssp_alloc(1, sizeof(Offset)); - - one->start = 0; - one->end = 250; - two->start = 100; - two->end = 250; - three->start = 250; - three->end = 250; - - file->missing_offsets->push(file->missing_offsets, one, -1); - file->missing_offsets->push(file->missing_offsets, two, -1); - file->missing_offsets->push(file->missing_offsets, three, -1); - req->file = file; - error = save_req_to_file(req); - if (error < 0) - printf("failed to write\n"); - - Request *got_req = mock_empty_request(); - - error = get_req_from_file(2, 2, 2, got_req); - if (error < 0) - printf("failed to write\n"); - - print_request_state(got_req); - ssp_cleanup_req(req); - ssp_cleanup_req(got_req); - - return 1; -} - int test_write_request_json() { + DECLARE_NEW_TEST("test writing and getting json data"); char *json_file = "test_incomeplete_file.json"; Request req; req.file = NULL; req.file = create_file("test_files/dest.jpg", 0); + + strncpy(req.source_file_name, "FileName", 20); + strncpy(req.destination_file_name, "DestinationFileName", 100); + add_first_offset(req.file, 3000); receive_offset(req.file, 1000, 2000); @@ -314,7 +70,6 @@ int test_write_request_json() { req.timeout_before_journal = 40; req.transmission_mode = 1; req.file_size = 150; - req.local_entity.EOF_recv_indication = 1; req.local_entity.EOF_sent_indication = 1; req.local_entity.file_segment_recv_indication = 1; @@ -331,8 +86,6 @@ int test_write_request_json() { Request req2; - req2.file = create_file("test_files/dest.jpg", 0); - error = get_request_from_json(&req2, "test_incomeplete_file.json"); if (error < 0) { ssp_printf("failed to read json test file\n"); @@ -343,13 +96,13 @@ int test_write_request_json() { ASSERT_EQUALS_INT("dest_cfdp_id", req.dest_cfdp_id, req2.dest_cfdp_id); ASSERT_EQUALS_INT("transaction_sequence_number", req.transaction_sequence_number, req2.transaction_sequence_number); ASSERT_EQUALS_INT("paused", req.paused, req2.paused); - + ASSERT_EQUALS_STR("FileName", req.source_file_name, req2.source_file_name, strnlen(req.source_file_name, 100)); + ASSERT_EQUALS_STR("DestinationFileName", req.destination_file_name, req2.destination_file_name, strnlen(req.destination_file_name, 100)); ASSERT_EQUALS_INT("resent_eof", req.resent_eof, req2.resent_eof); ASSERT_EQUALS_INT("resent_finished", req.resent_finished, req2.resent_finished); ASSERT_EQUALS_INT("sent_first_data_round", req.sent_first_data_round, req2.sent_first_data_round); ASSERT_EQUALS_INT("transmission_mode", req.transmission_mode, req2.transmission_mode); ASSERT_EQUALS_INT("file_size", req.file_size, req2.file_size); - ASSERT_EQUALS_INT("local_entity.EOF_recv_indication", req.local_entity.EOF_recv_indication, req2.local_entity.EOF_recv_indication); ASSERT_EQUALS_INT("local_entity.EOF_sent_indication", req.local_entity.EOF_sent_indication, req2.local_entity.EOF_sent_indication); ASSERT_EQUALS_INT("local_entity.file_segment_recv_indication", req.local_entity.file_segment_recv_indication, req2.local_entity.file_segment_recv_indication); @@ -383,13 +136,6 @@ int test_write_request_json() { int file_system_tests() { int error = 0; - /* - error = test_write_lv(); - error = test_saving_request(); - error = test_save_file(); - error = test_get_file(); - error = test_save_file_and_messages(); - */ error = test_write_request_json(); diff --git a/Program/test/request_tests.c b/Program/test/request_tests.c index fca1181..0e37f4c 100755 --- a/Program/test/request_tests.c +++ b/Program/test/request_tests.c @@ -120,7 +120,7 @@ static int add_proxy_message() { ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); Message_put_proxy *proxy = (Message_put_proxy *) message->value; - ASSERT_EQUALS_STR("proxy dest_id should equal 2", proxy->destination_id, &id, len); + ASSERT_EQUALS_INT("proxy dest_id should equal 2", proxy->destination_id, id); ASSERT_EQUALS_STR("proxy src file", proxy->source_file_name.value, src, proxy->source_file_name.length); ASSERT_EQUALS_STR("proxy dest file", proxy->destination_file_name.value, dest, proxy->destination_file_name.length); @@ -131,15 +131,19 @@ static int add_proxy_message() { int init_cont_partial_request_test_fail() { + + + DECLARE_NEW_TEST("Test fail to create init partial"); + Message_cont_part_request p_cont; uint32_t dest_id = 0; uint32_t org_id = 1; uint64_t tran_id = 0; Request *req = mock_request(); - p_cont.destination_id = &dest_id; - p_cont.originator_id = &org_id; - p_cont.transaction_id = &tran_id; + p_cont.destination_id = dest_id; + p_cont.originator_id = org_id; + p_cont.transaction_id = tran_id; uint32_t buff_len = 1500; char buff[buff_len]; @@ -149,6 +153,10 @@ int init_cont_partial_request_test_fail() { } int init_cont_partial_request_test() { + + + DECLARE_NEW_TEST("Test create cont partial"); + Message_cont_part_request p_cont; uint32_t dest_id = 3; uint32_t org_id = 2; @@ -163,9 +171,9 @@ int init_cont_partial_request_test() { save_req_to_file(req); - p_cont.destination_id = &dest_id; - p_cont.originator_id = &org_id; - p_cont.transaction_id = &tran_id; + p_cont.destination_id = dest_id; + p_cont.originator_id = org_id; + p_cont.transaction_id = tran_id; uint32_t buff_len = 1500; char buff[buff_len]; @@ -173,6 +181,7 @@ int init_cont_partial_request_test() { Request *req2 = mock_empty_request(); get_req_from_file(dest_id, tran_id, org_id, req2); + ASSERT_EQUALS_INT("eof received, don't resend. local_entity.eof_recv = 1", req->local_entity.EOF_recv_indication, req2->local_entity.EOF_sent_indication); @@ -186,6 +195,9 @@ int init_cont_partial_request_test() { } static int add_continue_partial_message_test() { + + + DECLARE_NEW_TEST("Test add cont partial to request"); int error = 0; Request *req = mock_empty_request(); @@ -205,9 +217,9 @@ static int add_continue_partial_message_test() { ASSERT_EQUALS_STR("message header should have asci: cfdp", message->header.message_id_cfdp, "cfdp", 5); Message_cont_part_request *proxy = (Message_cont_part_request *) message->value; - ASSERT_EQUALS_STR("proxy dest_id should equal 1", proxy->destination_id, &dest_id, proxy->destination_id); - ASSERT_EQUALS_STR("proxy originator id should equal 1", proxy->originator_id, &src_id, proxy->originator_id); - ASSERT_EQUALS_STR("proxy transaction id should equal 4444", proxy->transaction_id, &transaction_id, proxy->transaction_id); + ASSERT_EQUALS_INT("proxy dest_id should equal 1", proxy->destination_id, dest_id); + ASSERT_EQUALS_INT("proxy originator id should equal 1", proxy->originator_id, src_id); + ASSERT_EQUALS_INT("proxy transaction id should equal 4444", proxy->transaction_id, transaction_id); ssp_free_message(message); ssp_cleanup_req(req); @@ -218,6 +230,9 @@ static int add_continue_partial_message_test() { int test_lv_functions() { + + DECLARE_NEW_TEST("Testing LV functions"); + char packet[100]; char *str = "suphomie"; @@ -245,45 +260,68 @@ int test_lv_functions() { int request_user_input_tests() { + + DECLARE_NEW_TEST("Add requests to app"); + FTP app; void *handler = create_ftp_task(1, &app); + if (handler == NULL) { + ssp_printf("couldn't create thread\n"); + return -1; + } //need to let task initialize first. sleep(1); - put_request(2, "", "", 0, &app); - put_request(2, NULL, NULL, 0, &app); - (&app)->close = true; - ssp_thread_join(handler); + ASSERT_NOT_NULL("app handler should be not null\n", app.server_handle); + + Request *req = put_request(2, "", "", 0, &app); + ASSERT_NULL("request should be null\n", req); + + req = put_request(2, NULL, NULL, 0, &app); + ASSERT_NOT_NULL("request should not be null\n", req); + } int scheduled_requests_test() { + DECLARE_NEW_TEST("Save scheduled requests"); FTP app; void *handler = create_ftp_task(1, &app); + int error = schedule_put_request(1, "test_files/dest.jpg", "test_files/scheduled_file_sent", ACKNOWLEDGED_MODE, &app); ASSERT_EQUALS_INT("couldn't schedule request when should have been able to ", error, 0); - //error = schedule_put_request(1, "test_files/dest.jp", "test_files/scheduled_file_fail", ACKNOWLEDGED_MODE, app); - //ASSERT_EQUALS_INT("couldn't schedule request, file not found", error, -1); + error = schedule_put_request(1, "test_files/dest.jp", "test_files/scheduled_file_fail", ACKNOWLEDGED_MODE, &app); + ASSERT_EQUALS_INT("scheduled request failed", error, -1); - //error = schedule_put_request(1, NULL, NULL, ACKNOWLEDGED_MODE, app); + //error = schedule_put_request(1, NULL, NULL, ACKNOWLEDGED_MODE, &app); //ASSERT_EQUALS_INT("scheduling just messages", error, 0); - sleep(1); - app.close = true; - ssp_thread_join(handler); - return 0; + return error; } int schedule_requests_start_test(){ - sleep(1); + + DECLARE_NEW_TEST("Start scheduled requests"); FTP app; void *handler = create_ftp_task(1, &app); - int error = start_scheduled_requests(1, &app); + int error = 0; + sleep(1); + + error = schedule_put_request(5, "test_files/dest.jpg", "test_files/success_sent_scheduled", ACKNOWLEDGED_MODE, &app); + ASSERT_EQUALS_INT("scheduling requests", error, 0); + + error = schedule_put_request(5, "test_files/nak_test.jpg", "test_files/success_sent_scheduled", ACKNOWLEDGED_MODE, &app); + ASSERT_EQUALS_INT("scheduling requests", error, 0); + + error = start_scheduled_requests(4, &app); ASSERT_EQUALS_INT("start request batch successfully", error, 0); - //app->close = true; - ssp_thread_join(handler); + ssp_printf("count %d\n", app.active_clients->count); + ASSERT_EQUALS_INT("app has filled request list", app.active_clients->count, 3); + + + return error; } int test_process_messages() { @@ -296,19 +334,15 @@ int request_tests() { int error = 0; - error = request_finding_test(); - error = request_user_input_tests(); - /* error = add_proxy_message(); error = test_lv_functions(); error = add_continue_partial_message_test(); error = init_cont_partial_request_test_fail(); error = init_cont_partial_request_test(); - - scheduled_requests_test(); - schedule_requests_start_test(); - */ + error = scheduled_requests_test(); + error = schedule_requests_start_test(); + return error; } \ No newline at end of file From 8f9cc2964e156de110a7060ef2abc4a1b8c61051 Mon Sep 17 00:00:00 2001 From: evangee Date: Wed, 26 May 2021 21:00:15 -0600 Subject: [PATCH 351/400] add close function to exit out of current request --- Program/src/protocol_handler.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 2911153..0cf9023 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -430,7 +430,7 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t } -static void acknowledged_start(Request *req, Response res) { +static void acknowledged_start(Request *req, Response res, bool *close) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); send_put_metadata(req, res); @@ -442,6 +442,9 @@ static void acknowledged_start(Request *req, Response res) { while (!create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { ssp_sendto(res); + if (*close) { + return; + } } ssp_sendto(res); @@ -449,7 +452,7 @@ static void acknowledged_start(Request *req, Response res) { req->procedure = none; } -static void unacknowledged_start(Request *req, Response res){ +static void unacknowledged_start(Request *req, Response res, bool *close){ uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); int i = 0; @@ -465,6 +468,9 @@ static void unacknowledged_start(Request *req, Response res){ while (!create_data_burst_packets(req->buff, start, req->file, res.packet_len)) { ssp_sendto(res); + if (*close) { + return; + } } ssp_sendto(res); @@ -477,15 +483,16 @@ static void unacknowledged_start(Request *req, Response res){ } //if no file attached to request, set procedure to none -static void start_sequence(Request *req, Response res) { +static void start_sequence(Request *req, Response res, bool *close) { if (req->transmission_mode == UN_ACKNOWLEDGED_MODE) { - unacknowledged_start(req, res); + unacknowledged_start(req, res, close); return; } - acknowledged_start(req, res); + acknowledged_start(req, res, close); //set timeout to 0, databurst can take a while, timeout should start after data burst reset_timeout(&req->timeout_before_cancel); + } @@ -557,12 +564,6 @@ int process_nak_pdu(char *packet, Request *req, Response res, Client *client){ //fills the current request with packet data, responses from servers void parse_packet_client(char *packet, uint32_t packet_index, Response res, Request *req, Client* client) { - //if client is still sending the first data_burst, don't accepts packets - if (req->procedure == sending_start) - return; - - //ssp_printf("NO %d\n", req->procedure); - uint8_t directive = packet[packet_index]; packet_index += 1; @@ -629,7 +630,7 @@ void user_request_handler(Response res, Request *req, Client* client) { break; case sending_start: - start_sequence(req, res); + start_sequence(req, res, &client->close); break; case clean_up: // will close the request happens in the previous functions @@ -812,14 +813,17 @@ int parse_packet_server(char *packet, uint32_t packet_index, Response res, Reque uint16_t data_len = get_data_length(packet); uint32_t packet_len = packet_index + data_len; + int error = 0; //process file data if (incoming_header.PDU_type == DATA) { if (!req->local_entity.Metadata_recv_indication) { if (req->file == NULL) { - transasction_log("file is null", incoming_header.transaction_sequence_number); - build_temperary_file(req, TEMP_FILESIZE); + error = get_req_from_file(incoming_header.source_id, incoming_header.transaction_sequence_number, incoming_header.destination_id, req); + if (error < 0) + build_temperary_file(req, TEMP_FILESIZE); + } } process_data_packet(&packet[packet_index], data_len, req->file); From 0125f8016b9219a3efb57e4986e61c3363490f88 Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 29 May 2021 12:56:01 -0600 Subject: [PATCH 352/400] moved if to switch --- Program/include/types.h | 3 +- Program/src/port.c | 110 +++++++++++++++++++++++----------------- 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/Program/include/types.h b/Program/include/types.h index b49e834..16639b0 100755 --- a/Program/include/types.h +++ b/Program/include/types.h @@ -499,7 +499,8 @@ typedef enum Network_type { posix_connection, csp_connectionless, csp_connection, - generic + generic, + test } Network_type; diff --git a/Program/src/port.c b/Program/src/port.c index e0f44db..8ad511e 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -167,12 +167,18 @@ extern QueueHandle_t sendQueue; #endif void ssp_sendto(Response res) { - #ifdef TEST - return; - #endif - - if (res.type_of_network == generic) { + #ifdef CSP_NETWORK + csp_packet_t *packet_sending; + csp_packet_t *packet; + csp_conn_t *conn; + #endif + int err = 0; + + switch (res.type_of_network) + { + case generic: + /* code */ #ifdef FREE_RTOS_PORT while (true) { if (xQueueSendToBack(sendQueue, res.msg, 100) != pdPASS) @@ -184,37 +190,39 @@ void ssp_sendto(Response res) { #else ssp_printf("FreeRtos not defined, can't use generic queues"); #endif - } - else if (res.type_of_network == csp_connectionless) { + break; + case csp_connectionless: #ifdef CSP_NETWORK - csp_packet_t *packet = (csp_packet_t *) res.addr; - csp_packet_t *packet_sending; + packet = (csp_packet_t *) res.addr; + + if (csp_buffer_remaining() != 0) { + packet_sending = csp_buffer_get(1); + if (packet_sending == NULL) { + ssp_printf("couldn't get packet, is NULL"); + } + + ssp_printf("sending packet to dest %d port %d srcaddr %d srcport %d \n", packet->id.dst, packet->id.dport, packet->id.src, packet->id.sport); + + ssp_memcpy(packet_sending->data, res.msg, res.packet_len); + packet_sending->length = res.packet_len; - if (csp_buffer_remaining() != 0) { - packet_sending = csp_buffer_get(1); - if (packet_sending == NULL) { - ssp_printf("couldn't get packet, is NULL"); - } - - ssp_printf("sending packet to dest %d port %d srcaddr %d srcport %d \n", packet->id.dst, packet->id.dport, packet->id.src, packet->id.sport); + int err = csp_sendto(packet->id.pri, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 100); - ssp_memcpy(packet_sending->data, res.msg, res.packet_len); - packet_sending->length = res.packet_len; - - int err = csp_sendto(packet->id.pri, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 100); - - if (err < 0) { - ssp_error("ERROR in ssp_sento"); - csp_buffer_free(packet_sending); - } + if (err < 0) { + ssp_error("ERROR in ssp_sento"); + csp_buffer_free(packet_sending); } - else - ssp_error("couldn't get new packet for sending!\n"); + } + else + ssp_error("couldn't get new packet for sending!\n"); + #else + ssp_printf("CSP network not defined, but network is trying to use it\n"); #endif - } else if (res.type_of_network == csp_connection) { + break; + + case csp_connection: #ifdef CSP_NETWORK - csp_conn_t *conn = (csp_conn_t*) res.addr; - csp_packet_t *packet_sending; + conn = (csp_conn_t*) res.addr; if (csp_buffer_remaining() != 0) { packet_sending = csp_buffer_get(1); @@ -230,24 +238,34 @@ void ssp_sendto(Response res) { csp_buffer_free(packet_sending); } } - #endif - } - else { - #ifdef POSIX_PORT - struct sockaddr* addr = (struct sockaddr*) res.addr; - - //ssp_print_bits(res.msg, 10); - //Pdu_header header; - //memset(&header, 0, sizeof(Pdu_header)); - //get_pdu_header_from_packet(res.msg, &header); - //ssp_print_header(&header); + #else + ssp_printf("CSP network not defined, but network is trying to use it\n"); + #endif + break; - int err = sendto(res.sfd, res.msg, res.packet_len, 0, addr, sizeof(struct sockaddr)); - if (err < 0) { - ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, addr, sizeof(struct sockaddr)); - ssp_error("ERROR in sendto"); - } + case test: + ssp_printf("test\n"); + break; + + default: + #ifdef POSIX_PORT + + //ssp_print_bits(res.msg, 10); + //Pdu_header header; + //memset(&header, 0, sizeof(Pdu_header)); + //get_pdu_header_from_packet(res.msg, &header); + //ssp_print_header(&header); + + err = sendto(res.sfd, res.msg, res.packet_len, 0, (struct sockaddr*)res.addr, sizeof(struct sockaddr)); + if (err < 0) { + ssp_printf("res.sfd %d, res.packet_len %d, addr %d, addr size %d\n", res.sfd, res.packet_len, (struct sockaddr*)res.addr, sizeof(struct sockaddr)); + ssp_error("ERROR in sendto"); + } + break; + #else + ssp_printf("Posix network not defined, but network is trying to use it\n"); #endif + break; } } From c9fa4c3787e944a259378793b6e4f45cd8505acd Mon Sep 17 00:00:00 2001 From: evangee Date: Sat, 29 May 2021 16:14:26 -0600 Subject: [PATCH 353/400] Add continue partial file function --- Program/src/port.c | 1 - Program/src/protocol_handler.c | 52 +++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/Program/src/port.c b/Program/src/port.c index 8ad511e..ebe47da 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -244,7 +244,6 @@ void ssp_sendto(Response res) { break; case test: - ssp_printf("test\n"); break; default: diff --git a/Program/src/protocol_handler.c b/Program/src/protocol_handler.c index 0cf9023..b5a0f4e 100755 --- a/Program/src/protocol_handler.c +++ b/Program/src/protocol_handler.c @@ -396,7 +396,6 @@ static void send_eof_pdu(Request *req, Response res) { return; } - int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t length) { if (file->next_offset_to_send >= file->total_size){ @@ -429,6 +428,56 @@ int create_data_burst_packets(char *packet, uint32_t start, File *file, uint32_t return 0; } +static struct cont_partial_params { + uint32_t start; + Response *res; + Request *req; +}; + +static void continue_partials_send_partials(Node *node, void *element, void *args) { + + struct cont_partial_params *params = (struct cont_partial_params *) args; + + + Request *req = params->req; + Response *res = params->res; + uint32_t start = params->start; + Offset *o = (Offset *) element; + + int i = 0; + for (i = o->start; i < o->end; i += res->packet_len) { + req->file->next_offset_to_send = i; + create_data_burst_packets(req->buff, start, req->file, res->packet_len); + ssp_sendto(*res); + } + +} + +static void continue_partials_start(Request *req, Response res, bool *close) { + uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); + int i = 0; + + for (i = 0; i < RESEND_META_TIMES; i++) { + send_put_metadata(req, res); + } + + + struct cont_partial_params params = { + start, + &res, + req, + }; + + //send all missing offsets + req->file->missing_offsets->iterate(req->file->missing_offsets, continue_partials_send_partials, ¶ms); + + for (i = 0; i < RESEND_EOF_TIMES; i++) { + send_eof_pdu(req, res); + } + + req->procedure = none; +} + static void acknowledged_start(Request *req, Response res, bool *close) { uint32_t start = build_pdu_header(req->buff, req->transaction_sequence_number, req->transmission_mode, 0, &req->pdu_header); @@ -627,6 +676,7 @@ void user_request_handler(Response res, Request *req, Client* client) { switch (req->procedure) { case sending_nak_data: + continue_partials_start(req, res, &client->close); break; case sending_start: From dc17b0b3e20c8bd9068638542cb791281db4901c Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 8 Jun 2021 12:59:56 -0600 Subject: [PATCH 354/400] update port.h --- Program/include/port.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 5371059..1021096 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -9,12 +9,12 @@ Author: Evan Giese //#define TEST 1 -#define FREE_RTOS_PORT -#define RED_FS +//#define FREE_RTOS_PORT +//#define RED_FS #define CSP_NETWORK -//#define POSIX_FILESYSTEM -//#define POSIX_PORT +#define POSIX_FILESYSTEM +#define POSIX_PORT @@ -56,6 +56,7 @@ Author: Evan Giese #define SSP_O_CREAT O_CREAT #define SSP_O_TRUNC O_TRUNC #define SSP_SEEK_SET SEEK_SET + #define SSP_SEEK_END SEEK_END #define SSP_EEXIST EEXIST #define ssp_open open #define ssp_rename rename @@ -82,6 +83,7 @@ Author: Evan Giese #define SSP_O_TRUNC RED_O_TRUNC #define SSP_EEXIST RED_EEXIST #define SSP_SEEK_SET RED_SEEK_SET + #define SSP_SEEK_END SEEK_END #define ssp_open red_open #define ssp_rename red_rename #define ssp_close red_close @@ -116,6 +118,7 @@ Author: Evan Giese #include "stdlib.h" #define ssp_atol atol + #define ssp_atoll atoll #endif #ifdef FREE_RTOS_PORT @@ -128,6 +131,7 @@ Author: Evan Giese #include "stdlib.h" #define ssp_atol atol + #define ssp_atoll atoll #endif From 8c7c7036685953d878644734a4c3fd4ce80906d9 Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 8 Jun 2021 13:01:21 -0600 Subject: [PATCH 355/400] remove test comments --- Program/include/port.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 1021096..2f294b2 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -7,8 +7,6 @@ Author: Evan Giese #ifndef PORT_H #define PORT_H - -//#define TEST 1 //#define FREE_RTOS_PORT //#define RED_FS #define CSP_NETWORK @@ -16,11 +14,6 @@ Author: Evan Giese #define POSIX_FILESYSTEM #define POSIX_PORT - - -//comment this out if you want to sendto function to actually work -//#define TEST - #include "types.h" #define STACK_ALLOCATION 20000 From 64917dfdfa16a6c352eba06ede1d8c1cb7394c46 Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 8 Jun 2021 13:13:35 -0600 Subject: [PATCH 356/400] remove permissions for red_open --- Program/include/port.h | 8 ++++---- Program/src/filesystem_funcs.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 2f294b2..cdb28c6 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -7,12 +7,12 @@ Author: Evan Giese #ifndef PORT_H #define PORT_H -//#define FREE_RTOS_PORT -//#define RED_FS +#define FREE_RTOS_PORT +#define RED_FS #define CSP_NETWORK -#define POSIX_FILESYSTEM -#define POSIX_PORT +//#define POSIX_FILESYSTEM +//#define POSIX_PORT #include "types.h" #define STACK_ALLOCATION 20000 diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 6ac8396..cf05dd9 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -39,9 +39,9 @@ File *create_file(char *source_file_name, int clear_file_contents) { int fd = 0; if (clear_file_contents){ - fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC, 0777); + fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC); }else { - fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT, 0777); + fd = ssp_open(source_file_name, SSP_O_RDWR | SSP_O_CREAT); } if (fd == -1){ ssp_error("couldn't create file\n"); @@ -891,7 +891,7 @@ int write_request_json (Request *req, char *file_name) { return -1; } - int fd = ssp_open(file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC, 0777); + int fd = ssp_open(file_name, SSP_O_RDWR | SSP_O_CREAT | SSP_O_TRUNC); if (fd == -1) { ssp_error("count not open file\n"); return fd; From 213a7c81f0124c5dd3c0e26ab55b3a18e423cfa3 Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 8 Jun 2021 18:12:17 -0600 Subject: [PATCH 357/400] fix some compiler warnings --- Program/include/port.h | 19 ++++++++++--------- Program/src/app_control.c | 9 --------- Program/src/csp_server_provider.c | 2 +- Program/src/filesystem_funcs.c | 19 +++++-------------- Program/src/main.c | 26 ++++++++++++++++++-------- Program/src/makefile | 6 +++--- Program/src/packet.c | 7 ------- Program/src/port.c | 7 +++++-- Program/src/requests.c | 6 +++--- Program/src/utils.c | 8 +++++--- 10 files changed, 50 insertions(+), 59 deletions(-) diff --git a/Program/include/port.h b/Program/include/port.h index 2f294b2..4604a9b 100755 --- a/Program/include/port.h +++ b/Program/include/port.h @@ -27,15 +27,16 @@ Author: Evan Giese csp_packet_t *packet; } csp_packet_wrapper; - #include - #define SSP_INET_ADDRSTRLEN 16 - #define SSP_AF_INET 2 - #define ssp_htonl csp_hton32 - #define ssp_ntohl csp_ntoh32 - #define ssp_ntohs csp_ntoh16 - #define ssp_htons csp_hton16 - #define ssp_inet_ntop inet_ntop - + #ifndef POSIX_PORT + #include + #define SSP_INET_ADDRSTRLEN 16 + #define SSP_AF_INET 2 + #define ssp_htonl csp_hton32 + #define ssp_ntohl csp_ntoh32 + #define ssp_ntohs csp_ntoh16 + #define ssp_htons csp_hton16 + #define ssp_inet_ntop inet_ntop + #endif #endif #ifdef POSIX_FILESYSTEM diff --git a/Program/src/app_control.c b/Program/src/app_control.c index 4c1ea13..cc5782a 100755 --- a/Program/src/app_control.c +++ b/Program/src/app_control.c @@ -310,15 +310,6 @@ static void on_exit_server_callback (void *params) { ssp_cleanup_ftp(app); } -/*------------------------------------------------------------------------------ - - on std in - -------------------------------------------------------------------------------*/ -static int on_stdin_callback(void *other) { - return 0; -} - /*------------------------------------------------------------------------------ diff --git a/Program/src/csp_server_provider.c b/Program/src/csp_server_provider.c index 7a87c4f..c290b06 100755 --- a/Program/src/csp_server_provider.c +++ b/Program/src/csp_server_provider.c @@ -287,7 +287,7 @@ void csp_connection_client(uint8_t dest_id, uint8_t dest_port, uint8_t my_port, return; } - Client *client = (Client*) params; + //Client *client = (Client*) params; while (1) { diff --git a/Program/src/filesystem_funcs.c b/Program/src/filesystem_funcs.c index 6ac8396..26cd317 100755 --- a/Program/src/filesystem_funcs.c +++ b/Program/src/filesystem_funcs.c @@ -301,20 +301,11 @@ File *create_temp_file(char *file_name, uint32_t size) { return file; } - -static int print_nak(void *element, void* args) { - - Offset *offset_in_list = (Offset *) element; - ssp_printf("start: %u, end: %u\n", offset_in_list->start, offset_in_list->end); - return 0; -} - int change_tempfile_to_actual(char *temp, char *destination_file_name, uint32_t file_size, File *file) { ssp_printf("renaming %s to: %s\n", temp, destination_file_name); ssp_rename(temp, destination_file_name); - //file->missing_offsets->print(file->missing_offsets, print_nak, NULL); Offset* offset = (Offset*)file->missing_offsets->pop(file->missing_offsets); if (offset == NULL) { ssp_printf("no last node to pop\n"); @@ -692,11 +683,11 @@ static int parse_json_request(char *key, char *value, void *params) { //req->messages_to_user = ssp_atol(value); break; case REQ_file_is_temp: - if (check_null_file(req->file)) + if (check_null_file(req->file)) { req->file = create_file(req->destination_file_name, false); if (req->file == NULL) return -1; - + } req->file->is_temp = ssp_atol(value); break; case REQ_file_next_offset_to_send: @@ -766,7 +757,7 @@ static int add_file_json(int fd, File *file) { char buff[500]; int size = sizeof(buff); - int bytes_added = ssp_snprintf(buff, size, "\ + ssp_snprintf(buff, size, "\ \"%s\":%d,\n\ \"%s\":%d,\n\ \"%s\":%d,\n\ @@ -831,7 +822,7 @@ static int add_base_req_json(int fd, Request *req){ char buff[1000]; int size = sizeof(buff); - int bytes_added = ssp_snprintf(buff, size, "{\n\ + ssp_snprintf(buff, size, "{\n\ \"%s\":%d,\n\ \"%s\":%d,\n\ \"%s\":%llu,\n\ @@ -909,7 +900,7 @@ int write_request_json (Request *req, char *file_name) { ssp_error("could not close file\n"); return -1; } - + return 0; } diff --git a/Program/src/main.c b/Program/src/main.c index c0e5726..fb974a1 100755 --- a/Program/src/main.c +++ b/Program/src/main.c @@ -131,13 +131,15 @@ static Config *configuration(int argc, char **argv) static int init_csp_stuff(Config conf){ #ifdef CSP_NETWORK - + /* csp_debug_level_t debug_level = CSP_INFO; // enable/disable debug levels + for (csp_debug_level_t i = 0; i <= CSP_LOCK; ++i) { csp_debug_set_level(i, (i <= debug_level) ? true : false); } - + */ + Remote_entity remote_entity; int error = get_remote_entity_from_json(&remote_entity, conf.my_cfdp_id); if (error < 0) { @@ -149,7 +151,7 @@ static int init_csp_stuff(Config conf){ csp_conf_get_defaults(&csp_conf); csp_conf.buffers = 4096; csp_conf.address = remote_entity.UT_address; - csp_conf.buffer_data_size = 1500; + csp_conf.buffer_data_size = 250; error = csp_init(&csp_conf); if (error != CSP_ERR_NONE) { @@ -157,6 +159,11 @@ static int init_csp_stuff(Config conf){ exit(1); } + for (int i = 0; i <= CSP_LOCK; ++i) { + csp_debug_set_level(i, true); + } + + // Start router task with 10000 bytes of stack (priority is only supported on FreeRTOS) csp_route_start_task(500, 0); @@ -218,7 +225,8 @@ static int confirm(){ } } -void input_daemon(uint32_t client_id, FTP *app){ +/* +static void input_daemon(uint32_t client_id, FTP *app){ int buff_len = 25000; char input[buff_len]; @@ -286,6 +294,7 @@ void input_daemon(uint32_t client_id, FTP *app){ } } } +*/ int main(int argc, char** argv) { @@ -312,16 +321,17 @@ int main(int argc, char** argv) { uint32_t client_id = conf->client_cfdp_id; //input_daemon(client_id, &app); - + //csp_custom_ftp_ping(client_id, 1); + if (client_id != -1) { sleep(5); - Request *req = put_request(client_id, "pictures/udp.jpg", "test-received.jpg", conf->unackowledged_mode, &app); - start_request(req); + start_request(put_request(client_id, "pictures/udp.jpg", "test-received.jpg", ACKNOWLEDGED_MODE, &app)); + //put_request(client_id, "udp.jpeg", "udp.jpeg", conf->unackowledged_mode, &app); //put_request(client_id, "mib/peer_1.json", "mib/peer_test.json", ACKNOWLEDGED_MODE, &app); - //get_request(client_id, "mib/peer_0.json", "GET_REQUEST.json", ACKNOWLEDGED_MODE, &app); + //start_request(get_request(client_id, "mib/peer_1.json", "GET_REQUEST.json", ACKNOWLEDGED_MODE, &app)); } diff --git a/Program/src/makefile b/Program/src/makefile index a0980f1..e66f503 100755 --- a/Program/src/makefile +++ b/Program/src/makefile @@ -5,13 +5,13 @@ INCLUDE += -I$(PROJDIR)/include #---------------------------FOR FREE RTOS INTEGRATION--------------------------- #path to source includes -INCLUDE += -I$(PROJDIR)/Source/include +#INCLUDE += -I$(PROJDIR)/Source/include #path to compiler includes (portmacro.h) -INCLUDE += -I$(PROJDIR)/Source/portable/GCC/POSIX/ +#INCLUDE += -I$(PROJDIR)/Source/portable/GCC/POSIX/ #path to FreeRTOSconfig -INCLUDE += -I$(PROJDIR)/Project/ +#INCLUDE += -I$(PROJDIR)/Project/ #------------------------------------------------------------------------------- #---------------------------FOR CSP INTEGRATION--------------------------------- diff --git a/Program/src/packet.c b/Program/src/packet.c index e667ae7..8bf5969 100755 --- a/Program/src/packet.c +++ b/Program/src/packet.c @@ -529,13 +529,6 @@ int get_nak_packet(char *packet, Pdu_nak *nak) { return packet_index; } -static int print_nak(void *element, void* args) { - - Offset *offset_in_list = (Offset *) element; - ssp_printf("start: %d, end: %d\n", offset_in_list->start, offset_in_list->end); - return 0; -} - //this function is weird because it uses a callback into an iterator. We fill the array //with as many 'offsets' as we can. uint32_t build_nak_packet(char *packet, uint32_t start, Request *req) { diff --git a/Program/src/port.c b/Program/src/port.c index ebe47da..5de22cb 100755 --- a/Program/src/port.c +++ b/Program/src/port.c @@ -206,7 +206,7 @@ void ssp_sendto(Response res) { ssp_memcpy(packet_sending->data, res.msg, res.packet_len); packet_sending->length = res.packet_len; - int err = csp_sendto(packet->id.pri, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 100); + err = csp_sendto(packet->id.pri, packet->id.dst, packet->id.dport, packet->id.sport, 0, packet_sending, 100); if (err < 0) { ssp_error("ERROR in ssp_sento"); @@ -319,7 +319,10 @@ void ssp_printf(char *stuff, ...) { fflush(stdout); } -static int shit_time = 1; +#ifdef FREE_RTOS_PORT + //replace with real time clock + static int shit_time = 1; +#endif //returns seconds elapsed, need FREE RTOS realtime clock lib to properly port int ssp_time_count() { diff --git a/Program/src/requests.c b/Program/src/requests.c index d4124b5..0cefd9e 100755 --- a/Program/src/requests.c +++ b/Program/src/requests.c @@ -478,7 +478,7 @@ int schedule_put_request( } return 0; } - +/* static void clean_up_start_scheduled_requests(int fd, Request *req){ if (req != NULL) @@ -488,8 +488,8 @@ static void clean_up_start_scheduled_requests(int fd, Request *req){ if (error < 0) { ssp_error("there was an error closing the file descriptor"); } - } +*/ int start_scheduled_requests(uint32_t dest_id, FTP *app){ @@ -505,7 +505,7 @@ int start_scheduled_requests(uint32_t dest_id, FTP *app){ ssp_error("Unable to open directory"); return -1; } - int error, fd = 0; + int error = 0; Request *req = NULL; Client *client = NULL; diff --git a/Program/src/utils.c b/Program/src/utils.c index 6506a00..35de85c 100755 --- a/Program/src/utils.c +++ b/Program/src/utils.c @@ -44,9 +44,11 @@ void ssp_print_bits(char *stuff, int size){ ssp_printf("\n"); } - -char *safe_strncpy(char *to, char*from, int len){ +//replace strings with this +/* +static char *safe_strncpy(char *to, char*from, int len){ void *ret = strncpy(to, from, len); to[len] = '\0'; return ret; -} \ No newline at end of file +} +*/ \ No newline at end of file From df338f419e8dca3681a3b07089170fd28c5414bc Mon Sep 17 00:00:00 2001 From: evangee Date: Tue, 8 Jun 2021 18:27:11 -0600 Subject: [PATCH 358/400] add configured libcsp lib --- Program/libcsp/CHANGELOG | 163 +++ Program/libcsp/CI.rst | 6 + Program/libcsp/COPYING | 503 +++++++ Program/libcsp/INSTALL.rst | 29 + Program/libcsp/README.rst | 41 + Program/libcsp/build/.lock-waf_linux_build | 10 + .../libcsp/build/.wafpickle-linux-50727408-20 | Bin 0 -> 30138 bytes Program/libcsp/build/c4che/_cache.py | 59 + Program/libcsp/build/c4che/build.config.py | 2 + Program/libcsp/build/config.log | 409 ++++++ Program/libcsp/build/csp_arch | Bin 0 -> 93424 bytes Program/libcsp/build/csp_server_client | Bin 0 -> 339352 bytes Program/libcsp/build/examples/csp_arch.c.6.o | Bin 0 -> 99912 bytes .../build/examples/csp_server_client.c.5.o | Bin 0 -> 35520 bytes Program/libcsp/build/examples/zmqproxy.c.7.o | Bin 0 -> 24472 bytes .../libcsp/build/include/csp/csp_autoconfig.h | 33 + Program/libcsp/build/libcsp.a | Bin 0 -> 782614 bytes Program/libcsp/build/libcsp.so | Bin 0 -> 370272 bytes Program/libcsp/build/libcsp_py3.so | Bin 0 -> 103352 bytes .../libcsp/build/src/arch/csp_system.c.2.o | Bin 0 -> 8832 bytes .../libcsp/build/src/arch/csp_system.c.3.o | Bin 0 -> 8856 bytes Program/libcsp/build/src/arch/csp_time.c.2.o | Bin 0 -> 3976 bytes Program/libcsp/build/src/arch/csp_time.c.3.o | Bin 0 -> 3984 bytes .../build/src/arch/posix/csp_clock.c.2.o | Bin 0 -> 5696 bytes .../build/src/arch/posix/csp_clock.c.3.o | Bin 0 -> 5704 bytes .../build/src/arch/posix/csp_malloc.c.2.o | Bin 0 -> 4872 bytes .../build/src/arch/posix/csp_malloc.c.3.o | Bin 0 -> 4872 bytes .../build/src/arch/posix/csp_queue.c.2.o | Bin 0 -> 9368 bytes .../build/src/arch/posix/csp_queue.c.3.o | Bin 0 -> 8784 bytes .../build/src/arch/posix/csp_semaphore.c.2.o | Bin 0 -> 17592 bytes .../build/src/arch/posix/csp_semaphore.c.3.o | Bin 0 -> 17648 bytes .../build/src/arch/posix/csp_system.c.2.o | Bin 0 -> 16888 bytes .../build/src/arch/posix/csp_system.c.3.o | Bin 0 -> 16864 bytes .../build/src/arch/posix/csp_thread.c.2.o | Bin 0 -> 9248 bytes .../build/src/arch/posix/csp_thread.c.3.o | Bin 0 -> 9256 bytes .../build/src/arch/posix/csp_time.c.2.o | Bin 0 -> 5568 bytes .../build/src/arch/posix/csp_time.c.3.o | Bin 0 -> 5632 bytes .../build/src/arch/posix/pthread_queue.c.2.o | Bin 0 -> 19096 bytes .../build/src/arch/posix/pthread_queue.c.3.o | Bin 0 -> 19104 bytes .../build/src/bindings/python/pycsp.c.4.o | Bin 0 -> 157552 bytes .../libcsp/build/src/crypto/csp_hmac.c.2.o | Bin 0 -> 15840 bytes .../libcsp/build/src/crypto/csp_hmac.c.3.o | Bin 0 -> 15848 bytes .../libcsp/build/src/crypto/csp_sha1.c.2.o | Bin 0 -> 11832 bytes .../libcsp/build/src/crypto/csp_sha1.c.3.o | Bin 0 -> 11872 bytes .../libcsp/build/src/crypto/csp_xtea.c.2.o | Bin 0 -> 13304 bytes .../libcsp/build/src/crypto/csp_xtea.c.3.o | Bin 0 -> 12968 bytes Program/libcsp/build/src/csp_bridge.c.2.o | Bin 0 -> 13336 bytes Program/libcsp/build/src/csp_bridge.c.3.o | Bin 0 -> 13352 bytes Program/libcsp/build/src/csp_buffer.c.2.o | Bin 0 -> 19776 bytes Program/libcsp/build/src/csp_buffer.c.3.o | Bin 0 -> 19608 bytes Program/libcsp/build/src/csp_conn.c.2.o | Bin 0 -> 37800 bytes Program/libcsp/build/src/csp_conn.c.3.o | Bin 0 -> 37872 bytes Program/libcsp/build/src/csp_crc32.c.2.o | Bin 0 -> 11960 bytes Program/libcsp/build/src/csp_crc32.c.3.o | Bin 0 -> 11968 bytes Program/libcsp/build/src/csp_debug.c.2.o | Bin 0 -> 13752 bytes Program/libcsp/build/src/csp_debug.c.3.o | Bin 0 -> 13768 bytes Program/libcsp/build/src/csp_dedup.c.2.o | Bin 0 -> 8848 bytes Program/libcsp/build/src/csp_dedup.c.3.o | Bin 0 -> 8856 bytes Program/libcsp/build/src/csp_endian.c.2.o | Bin 0 -> 9144 bytes Program/libcsp/build/src/csp_endian.c.3.o | Bin 0 -> 9064 bytes Program/libcsp/build/src/csp_hex_dump.c.2.o | Bin 0 -> 10880 bytes Program/libcsp/build/src/csp_hex_dump.c.3.o | Bin 0 -> 10880 bytes Program/libcsp/build/src/csp_iflist.c.2.o | Bin 0 -> 14224 bytes Program/libcsp/build/src/csp_iflist.c.3.o | Bin 0 -> 14232 bytes Program/libcsp/build/src/csp_init.c.2.o | Bin 0 -> 14856 bytes Program/libcsp/build/src/csp_init.c.3.o | Bin 0 -> 15048 bytes Program/libcsp/build/src/csp_io.c.2.o | Bin 0 -> 33800 bytes Program/libcsp/build/src/csp_io.c.3.o | Bin 0 -> 33752 bytes Program/libcsp/build/src/csp_port.c.2.o | Bin 0 -> 14704 bytes Program/libcsp/build/src/csp_port.c.3.o | Bin 0 -> 14664 bytes Program/libcsp/build/src/csp_promisc.c.2.o | Bin 0 -> 5080 bytes Program/libcsp/build/src/csp_promisc.c.3.o | Bin 0 -> 5080 bytes Program/libcsp/build/src/csp_qfifo.c.2.o | Bin 0 -> 15288 bytes Program/libcsp/build/src/csp_qfifo.c.3.o | Bin 0 -> 15320 bytes Program/libcsp/build/src/csp_route.c.2.o | Bin 0 -> 22768 bytes Program/libcsp/build/src/csp_route.c.3.o | Bin 0 -> 22712 bytes .../build/src/csp_service_handler.c.2.o | Bin 0 -> 27968 bytes .../build/src/csp_service_handler.c.3.o | Bin 0 -> 27808 bytes Program/libcsp/build/src/csp_services.c.2.o | Bin 0 -> 33304 bytes Program/libcsp/build/src/csp_services.c.3.o | Bin 0 -> 33312 bytes Program/libcsp/build/src/csp_sfp.c.2.o | Bin 0 -> 21392 bytes Program/libcsp/build/src/csp_sfp.c.3.o | Bin 0 -> 21440 bytes .../build/src/drivers/can/can_socketcan.c.2.o | Bin 0 -> 33072 bytes .../build/src/drivers/can/can_socketcan.c.3.o | Bin 0 -> 32976 bytes .../build/src/drivers/usart/usart_kiss.c.2.o | Bin 0 -> 16160 bytes .../build/src/drivers/usart/usart_kiss.c.3.o | Bin 0 -> 16168 bytes .../build/src/drivers/usart/usart_linux.c.2.o | Bin 0 -> 20896 bytes .../build/src/drivers/usart/usart_linux.c.3.o | Bin 0 -> 20936 bytes .../build/src/interfaces/csp_if_can.c.2.o | Bin 0 -> 19856 bytes .../build/src/interfaces/csp_if_can.c.3.o | Bin 0 -> 19856 bytes .../src/interfaces/csp_if_can_pbuf.c.2.o | Bin 0 -> 8808 bytes .../src/interfaces/csp_if_can_pbuf.c.3.o | Bin 0 -> 8808 bytes .../build/src/interfaces/csp_if_i2c.c.2.o | Bin 0 -> 13000 bytes .../build/src/interfaces/csp_if_i2c.c.3.o | Bin 0 -> 13008 bytes .../build/src/interfaces/csp_if_kiss.c.2.o | Bin 0 -> 17240 bytes .../build/src/interfaces/csp_if_kiss.c.3.o | Bin 0 -> 17248 bytes .../build/src/interfaces/csp_if_lo.c.2.o | Bin 0 -> 10560 bytes .../build/src/interfaces/csp_if_lo.c.3.o | Bin 0 -> 10568 bytes .../build/src/interfaces/csp_if_zmqhub.c.2.o | Bin 0 -> 29712 bytes .../build/src/interfaces/csp_if_zmqhub.c.3.o | Bin 0 -> 29744 bytes .../libcsp/build/src/rtable/csp_rtable.c.2.o | Bin 0 -> 26704 bytes .../libcsp/build/src/rtable/csp_rtable.c.3.o | Bin 0 -> 26736 bytes .../build/src/rtable/csp_rtable_static.c.2.o | Bin 0 -> 13192 bytes .../build/src/rtable/csp_rtable_static.c.3.o | Bin 0 -> 13200 bytes .../libcsp/build/src/transport/csp_rdp.c.2.o | Bin 0 -> 82592 bytes .../libcsp/build/src/transport/csp_rdp.c.3.o | Bin 0 -> 81376 bytes .../libcsp/build/src/transport/csp_udp.c.2.o | Bin 0 -> 11968 bytes .../libcsp/build/src/transport/csp_udp.c.3.o | Bin 0 -> 11984 bytes Program/libcsp/build/zmqproxy | Bin 0 -> 38720 bytes Program/libcsp/doc/basic.rst | 153 +++ Program/libcsp/doc/example.rst | 61 + Program/libcsp/doc/history.rst | 21 + Program/libcsp/doc/libcsp.rst | 21 + Program/libcsp/doc/memory.rst | 16 + Program/libcsp/doc/mtu.rst | 19 + Program/libcsp/doc/protocolstack.rst | 61 + Program/libcsp/doc/structure.rst | 29 + Program/libcsp/doc/topology.rst | 27 + Program/libcsp/examples/buildall.py | 52 + Program/libcsp/examples/csp_arch.c | 159 +++ Program/libcsp/examples/csp_server_client.c | 316 +++++ .../python_bindings_example_client.py | 63 + .../python_bindings_example_server.py | 74 ++ Program/libcsp/examples/zmqproxy.c | 115 ++ Program/libcsp/include/csp/arch/csp_clock.h | 70 + Program/libcsp/include/csp/arch/csp_malloc.h | 60 + Program/libcsp/include/csp/arch/csp_queue.h | 126 ++ .../libcsp/include/csp/arch/csp_semaphore.h | 206 +++ Program/libcsp/include/csp/arch/csp_system.h | 135 ++ Program/libcsp/include/csp/arch/csp_thread.h | 133 ++ Program/libcsp/include/csp/arch/csp_time.h | 73 ++ .../include/csp/arch/posix/csp_system.h | 59 + .../include/csp/arch/posix/pthread_queue.h | 114 ++ Program/libcsp/include/csp/crypto/csp_hmac.h | 82 ++ Program/libcsp/include/csp/crypto/csp_sha1.h | 89 ++ Program/libcsp/include/csp/crypto/csp_xtea.h | 78 ++ Program/libcsp/include/csp/csp.h | 491 +++++++ Program/libcsp/include/csp/csp_buffer.h | 94 ++ Program/libcsp/include/csp/csp_cmp.h | 214 +++ Program/libcsp/include/csp/csp_crc32.h | 62 + Program/libcsp/include/csp/csp_debug.h | 226 ++++ Program/libcsp/include/csp/csp_endian.h | 148 +++ Program/libcsp/include/csp/csp_error.h | 60 + Program/libcsp/include/csp/csp_iflist.h | 76 ++ Program/libcsp/include/csp/csp_interface.h | 95 ++ Program/libcsp/include/csp/csp_platform.h | 70 + Program/libcsp/include/csp/csp_promisc.h | 64 + Program/libcsp/include/csp/csp_rtable.h | 172 +++ Program/libcsp/include/csp/csp_sfp.h | 111 ++ Program/libcsp/include/csp/csp_types.h | 292 +++++ .../include/csp/drivers/can_socketcan.h | 73 ++ Program/libcsp/include/csp/drivers/usart.h | 121 ++ .../include/csp/interfaces/csp_if_can.h | 178 +++ .../include/csp/interfaces/csp_if_i2c.h | 118 ++ .../include/csp/interfaces/csp_if_kiss.h | 116 ++ .../libcsp/include/csp/interfaces/csp_if_lo.h | 49 + .../include/csp/interfaces/csp_if_zmqhub.h | 118 ++ Program/libcsp/src/arch/csp_system.c | 58 + Program/libcsp/src/arch/csp_time.c | 32 + Program/libcsp/src/arch/freertos/csp_clock.c | 32 + Program/libcsp/src/arch/freertos/csp_malloc.c | 42 + Program/libcsp/src/arch/freertos/csp_queue.c | 60 + .../libcsp/src/arch/freertos/csp_semaphore.c | 84 ++ Program/libcsp/src/arch/freertos/csp_system.c | 88 ++ Program/libcsp/src/arch/freertos/csp_thread.c | 48 + Program/libcsp/src/arch/freertos/csp_time.c | 40 + Program/libcsp/src/arch/macosx/csp_clock.c | 22 + Program/libcsp/src/arch/macosx/csp_malloc.c | 22 + Program/libcsp/src/arch/macosx/csp_queue.c | 22 + .../libcsp/src/arch/macosx/csp_semaphore.c | 85 ++ Program/libcsp/src/arch/macosx/csp_system.c | 87 ++ Program/libcsp/src/arch/macosx/csp_thread.c | 55 + Program/libcsp/src/arch/macosx/csp_time.c | 22 + .../libcsp/src/arch/macosx/pthread_queue.c | 178 +++ Program/libcsp/src/arch/posix/csp_clock.c | 45 + Program/libcsp/src/arch/posix/csp_malloc.c | 36 + Program/libcsp/src/arch/posix/csp_queue.c | 60 + Program/libcsp/src/arch/posix/csp_semaphore.c | 155 +++ Program/libcsp/src/arch/posix/csp_system.c | 135 ++ Program/libcsp/src/arch/posix/csp_thread.c | 72 + Program/libcsp/src/arch/posix/csp_time.c | 57 + Program/libcsp/src/arch/posix/pthread_queue.c | 239 ++++ Program/libcsp/src/arch/windows/README | 18 + Program/libcsp/src/arch/windows/csp_clock.c | 42 + Program/libcsp/src/arch/windows/csp_malloc.c | 35 + Program/libcsp/src/arch/windows/csp_queue.c | 59 + .../libcsp/src/arch/windows/csp_semaphore.c | 100 ++ Program/libcsp/src/arch/windows/csp_system.c | 54 + Program/libcsp/src/arch/windows/csp_thread.c | 46 + Program/libcsp/src/arch/windows/csp_time.c | 44 + .../libcsp/src/arch/windows/windows_queue.c | 127 ++ .../libcsp/src/arch/windows/windows_queue.h | 46 + Program/libcsp/src/bindings/python/pycsp.c | 1121 ++++++++++++++++ Program/libcsp/src/crypto/csp_hmac.c | 194 +++ Program/libcsp/src/crypto/csp_sha1.c | 211 +++ Program/libcsp/src/crypto/csp_xtea.c | 181 +++ Program/libcsp/src/csp_bridge.c | 96 ++ Program/libcsp/src/csp_buffer.c | 224 ++++ Program/libcsp/src/csp_conn.c | 527 ++++++++ Program/libcsp/src/csp_conn.h | 119 ++ Program/libcsp/src/csp_crc32.c | 130 ++ Program/libcsp/src/csp_debug.c | 138 ++ Program/libcsp/src/csp_dedup.c | 62 + Program/libcsp/src/csp_dedup.h | 33 + Program/libcsp/src/csp_endian.c | 200 +++ Program/libcsp/src/csp_hex_dump.c | 76 ++ Program/libcsp/src/csp_iflist.c | 106 ++ Program/libcsp/src/csp_init.c | 95 ++ Program/libcsp/src/csp_init.h | 38 + Program/libcsp/src/csp_io.c | 408 ++++++ Program/libcsp/src/csp_io.h | 44 + Program/libcsp/src/csp_port.c | 115 ++ Program/libcsp/src/csp_port.h | 57 + Program/libcsp/src/csp_promisc.c | 84 ++ Program/libcsp/src/csp_promisc.h | 39 + Program/libcsp/src/csp_qfifo.c | 168 +++ Program/libcsp/src/csp_qfifo.h | 58 + Program/libcsp/src/csp_route.c | 337 +++++ Program/libcsp/src/csp_service_handler.c | 338 +++++ Program/libcsp/src/csp_services.c | 254 ++++ Program/libcsp/src/csp_sfp.c | 229 ++++ .../libcsp/src/drivers/can/can_socketcan.c | 237 ++++ Program/libcsp/src/drivers/usart/usart_kiss.c | 86 ++ .../libcsp/src/drivers/usart/usart_linux.c | 271 ++++ .../libcsp/src/drivers/usart/usart_windows.c | 173 +++ Program/libcsp/src/interfaces/csp_if_can.c | 275 ++++ .../libcsp/src/interfaces/csp_if_can_pbuf.c | 93 ++ .../libcsp/src/interfaces/csp_if_can_pbuf.h | 46 + Program/libcsp/src/interfaces/csp_if_i2c.c | 112 ++ Program/libcsp/src/interfaces/csp_if_kiss.c | 245 ++++ Program/libcsp/src/interfaces/csp_if_lo.c | 53 + Program/libcsp/src/interfaces/csp_if_zmqhub.c | 238 ++++ Program/libcsp/src/rtable/csp_rtable.c | 180 +++ Program/libcsp/src/rtable/csp_rtable_cidr.c | 147 +++ .../libcsp/src/rtable/csp_rtable_internal.h | 24 + Program/libcsp/src/rtable/csp_rtable_static.c | 73 ++ Program/libcsp/src/transport/csp_rdp.c | 1157 +++++++++++++++++ Program/libcsp/src/transport/csp_transport.h | 48 + Program/libcsp/src/transport/csp_udp.c | 50 + Program/libcsp/utils/cfpsplit.py | 53 + Program/libcsp/utils/cspsplit.py | 53 + Program/libcsp/waf | 173 +++ .../waflib/Build.py | 804 ++++++++++++ .../waflib/ConfigSet.py | 165 +++ .../waflib/Configure.py | 377 ++++++ .../waflib/Context.py | 406 ++++++ .../waflib/Errors.py | 39 + .../waflib/Logs.py | 206 +++ .../waflib/Node.py | 477 +++++++ .../waflib/Options.py | 200 +++ .../waflib/Runner.py | 375 ++++++ .../waflib/Scripting.py | 415 ++++++ .../waflib/Task.py | 792 +++++++++++ .../waflib/TaskGen.py | 471 +++++++ .../waflib/Tools/__init__.py | 4 + .../waflib/Tools/ar.py | 13 + .../waflib/Tools/asm.py | 50 + .../waflib/Tools/bison.py | 28 + .../waflib/Tools/c.py | 26 + .../waflib/Tools/c_aliases.py | 62 + .../waflib/Tools/c_config.py | 805 ++++++++++++ .../waflib/Tools/c_osx.py | 121 ++ .../waflib/Tools/c_preproc.py | 672 ++++++++++ .../waflib/Tools/c_tests.py | 152 +++ .../waflib/Tools/ccroot.py | 486 +++++++ .../waflib/Tools/clang.py | 20 + .../waflib/Tools/clangxx.py | 20 + .../waflib/Tools/compiler_c.py | 44 + .../waflib/Tools/compiler_cxx.py | 44 + .../waflib/Tools/compiler_d.py | 41 + .../waflib/Tools/compiler_fc.py | 43 + .../waflib/Tools/cs.py | 113 ++ .../waflib/Tools/cxx.py | 26 + .../waflib/Tools/d.py | 54 + .../waflib/Tools/d_config.py | 52 + .../waflib/Tools/d_scan.py | 136 ++ .../waflib/Tools/dbus.py | 29 + .../waflib/Tools/dmd.py | 51 + .../waflib/Tools/errcheck.py | 175 +++ .../waflib/Tools/fc.py | 118 ++ .../waflib/Tools/fc_config.py | 299 +++++ .../waflib/Tools/fc_scan.py | 70 + .../waflib/Tools/flex.py | 38 + .../waflib/Tools/g95.py | 54 + .../waflib/Tools/gas.py | 13 + .../waflib/Tools/gcc.py | 104 ++ .../waflib/Tools/gdc.py | 35 + .../waflib/Tools/gfortran.py | 71 + .../waflib/Tools/glib2.py | 242 ++++ .../waflib/Tools/gnu_dirs.py | 66 + .../waflib/Tools/gxx.py | 104 ++ .../waflib/Tools/icc.py | 20 + .../waflib/Tools/icpc.py | 20 + .../waflib/Tools/ifort.py | 303 +++++ .../waflib/Tools/intltool.py | 101 ++ .../waflib/Tools/irixcc.py | 51 + .../waflib/Tools/javaw.py | 330 +++++ .../waflib/Tools/ldc2.py | 36 + .../waflib/Tools/lua.py | 18 + .../waflib/Tools/md5_tstamp.py | 24 + .../waflib/Tools/msvc.py | 704 ++++++++++ .../waflib/Tools/nasm.py | 21 + .../waflib/Tools/nobuild.py | 11 + .../waflib/Tools/perl.py | 85 ++ .../waflib/Tools/python.py | 422 ++++++ .../waflib/Tools/qt5.py | 499 +++++++ .../waflib/Tools/ruby.py | 97 ++ .../waflib/Tools/suncc.py | 48 + .../waflib/Tools/suncxx.py | 48 + .../waflib/Tools/tex.py | 327 +++++ .../waflib/Tools/vala.py | 218 ++++ .../waflib/Tools/waf_unit_test.py | 172 +++ .../waflib/Tools/winres.py | 52 + .../waflib/Tools/xlc.py | 44 + .../waflib/Tools/xlcxx.py | 44 + .../waflib/Utils.py | 625 +++++++++ .../waflib/__init__.py | 4 + .../waflib/ansiterm.py | 238 ++++ .../waflib/extras/__init__.py | 4 + .../waflib/extras/compat15.py | 305 +++++ .../waflib/fixpy2.py | 47 + .../waflib/processor.py | 57 + Program/libcsp/wscript | 245 ++++ 323 files changed, 32859 insertions(+) create mode 100755 Program/libcsp/CHANGELOG create mode 100755 Program/libcsp/CI.rst create mode 100755 Program/libcsp/COPYING create mode 100755 Program/libcsp/INSTALL.rst create mode 100755 Program/libcsp/README.rst create mode 100755 Program/libcsp/build/.lock-waf_linux_build create mode 100755 Program/libcsp/build/.wafpickle-linux-50727408-20 create mode 100755 Program/libcsp/build/c4che/_cache.py create mode 100755 Program/libcsp/build/c4che/build.config.py create mode 100755 Program/libcsp/build/config.log create mode 100755 Program/libcsp/build/csp_arch create mode 100755 Program/libcsp/build/csp_server_client create mode 100755 Program/libcsp/build/examples/csp_arch.c.6.o create mode 100755 Program/libcsp/build/examples/csp_server_client.c.5.o create mode 100755 Program/libcsp/build/examples/zmqproxy.c.7.o create mode 100755 Program/libcsp/build/include/csp/csp_autoconfig.h create mode 100755 Program/libcsp/build/libcsp.a create mode 100755 Program/libcsp/build/libcsp.so create mode 100755 Program/libcsp/build/libcsp_py3.so create mode 100755 Program/libcsp/build/src/arch/csp_system.c.2.o create mode 100755 Program/libcsp/build/src/arch/csp_system.c.3.o create mode 100755 Program/libcsp/build/src/arch/csp_time.c.2.o create mode 100755 Program/libcsp/build/src/arch/csp_time.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_clock.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_clock.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_malloc.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_malloc.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_queue.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_queue.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_semaphore.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_semaphore.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_system.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_system.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_thread.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_thread.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_time.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/csp_time.c.3.o create mode 100755 Program/libcsp/build/src/arch/posix/pthread_queue.c.2.o create mode 100755 Program/libcsp/build/src/arch/posix/pthread_queue.c.3.o create mode 100755 Program/libcsp/build/src/bindings/python/pycsp.c.4.o create mode 100755 Program/libcsp/build/src/crypto/csp_hmac.c.2.o create mode 100755 Program/libcsp/build/src/crypto/csp_hmac.c.3.o create mode 100755 Program/libcsp/build/src/crypto/csp_sha1.c.2.o create mode 100755 Program/libcsp/build/src/crypto/csp_sha1.c.3.o create mode 100755 Program/libcsp/build/src/crypto/csp_xtea.c.2.o create mode 100755 Program/libcsp/build/src/crypto/csp_xtea.c.3.o create mode 100755 Program/libcsp/build/src/csp_bridge.c.2.o create mode 100755 Program/libcsp/build/src/csp_bridge.c.3.o create mode 100755 Program/libcsp/build/src/csp_buffer.c.2.o create mode 100755 Program/libcsp/build/src/csp_buffer.c.3.o create mode 100755 Program/libcsp/build/src/csp_conn.c.2.o create mode 100755 Program/libcsp/build/src/csp_conn.c.3.o create mode 100755 Program/libcsp/build/src/csp_crc32.c.2.o create mode 100755 Program/libcsp/build/src/csp_crc32.c.3.o create mode 100755 Program/libcsp/build/src/csp_debug.c.2.o create mode 100755 Program/libcsp/build/src/csp_debug.c.3.o create mode 100755 Program/libcsp/build/src/csp_dedup.c.2.o create mode 100755 Program/libcsp/build/src/csp_dedup.c.3.o create mode 100755 Program/libcsp/build/src/csp_endian.c.2.o create mode 100755 Program/libcsp/build/src/csp_endian.c.3.o create mode 100755 Program/libcsp/build/src/csp_hex_dump.c.2.o create mode 100755 Program/libcsp/build/src/csp_hex_dump.c.3.o create mode 100755 Program/libcsp/build/src/csp_iflist.c.2.o create mode 100755 Program/libcsp/build/src/csp_iflist.c.3.o create mode 100755 Program/libcsp/build/src/csp_init.c.2.o create mode 100755 Program/libcsp/build/src/csp_init.c.3.o create mode 100755 Program/libcsp/build/src/csp_io.c.2.o create mode 100755 Program/libcsp/build/src/csp_io.c.3.o create mode 100755 Program/libcsp/build/src/csp_port.c.2.o create mode 100755 Program/libcsp/build/src/csp_port.c.3.o create mode 100755 Program/libcsp/build/src/csp_promisc.c.2.o create mode 100755 Program/libcsp/build/src/csp_promisc.c.3.o create mode 100755 Program/libcsp/build/src/csp_qfifo.c.2.o create mode 100755 Program/libcsp/build/src/csp_qfifo.c.3.o create mode 100755 Program/libcsp/build/src/csp_route.c.2.o create mode 100755 Program/libcsp/build/src/csp_route.c.3.o create mode 100755 Program/libcsp/build/src/csp_service_handler.c.2.o create mode 100755 Program/libcsp/build/src/csp_service_handler.c.3.o create mode 100755 Program/libcsp/build/src/csp_services.c.2.o create mode 100755 Program/libcsp/build/src/csp_services.c.3.o create mode 100755 Program/libcsp/build/src/csp_sfp.c.2.o create mode 100755 Program/libcsp/build/src/csp_sfp.c.3.o create mode 100755 Program/libcsp/build/src/drivers/can/can_socketcan.c.2.o create mode 100755 Program/libcsp/build/src/drivers/can/can_socketcan.c.3.o create mode 100755 Program/libcsp/build/src/drivers/usart/usart_kiss.c.2.o create mode 100755 Program/libcsp/build/src/drivers/usart/usart_kiss.c.3.o create mode 100755 Program/libcsp/build/src/drivers/usart/usart_linux.c.2.o create mode 100755 Program/libcsp/build/src/drivers/usart/usart_linux.c.3.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_can.c.2.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_can.c.3.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.2.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_can_pbuf.c.3.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_i2c.c.2.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_i2c.c.3.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_kiss.c.2.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_kiss.c.3.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_lo.c.2.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_lo.c.3.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.2.o create mode 100755 Program/libcsp/build/src/interfaces/csp_if_zmqhub.c.3.o create mode 100755 Program/libcsp/build/src/rtable/csp_rtable.c.2.o create mode 100755 Program/libcsp/build/src/rtable/csp_rtable.c.3.o create mode 100755 Program/libcsp/build/src/rtable/csp_rtable_static.c.2.o create mode 100755 Program/libcsp/build/src/rtable/csp_rtable_static.c.3.o create mode 100755 Program/libcsp/build/src/transport/csp_rdp.c.2.o create mode 100755 Program/libcsp/build/src/transport/csp_rdp.c.3.o create mode 100755 Program/libcsp/build/src/transport/csp_udp.c.2.o create mode 100755 Program/libcsp/build/src/transport/csp_udp.c.3.o create mode 100755 Program/libcsp/build/zmqproxy create mode 100755 Program/libcsp/doc/basic.rst create mode 100755 Program/libcsp/doc/example.rst create mode 100755 Program/libcsp/doc/history.rst create mode 100755 Program/libcsp/doc/libcsp.rst create mode 100755 Program/libcsp/doc/memory.rst create mode 100755 Program/libcsp/doc/mtu.rst create mode 100755 Program/libcsp/doc/protocolstack.rst create mode 100755 Program/libcsp/doc/structure.rst create mode 100755 Program/libcsp/doc/topology.rst create mode 100755 Program/libcsp/examples/buildall.py create mode 100755 Program/libcsp/examples/csp_arch.c create mode 100755 Program/libcsp/examples/csp_server_client.c create mode 100755 Program/libcsp/examples/python_bindings_example_client.py create mode 100755 Program/libcsp/examples/python_bindings_example_server.py create mode 100755 Program/libcsp/examples/zmqproxy.c create mode 100755 Program/libcsp/include/csp/arch/csp_clock.h create mode 100755 Program/libcsp/include/csp/arch/csp_malloc.h create mode 100755 Program/libcsp/include/csp/arch/csp_queue.h create mode 100755 Program/libcsp/include/csp/arch/csp_semaphore.h create mode 100755 Program/libcsp/include/csp/arch/csp_system.h create mode 100755 Program/libcsp/include/csp/arch/csp_thread.h create mode 100755 Program/libcsp/include/csp/arch/csp_time.h create mode 100755 Program/libcsp/include/csp/arch/posix/csp_system.h create mode 100755 Program/libcsp/include/csp/arch/posix/pthread_queue.h create mode 100755 Program/libcsp/include/csp/crypto/csp_hmac.h create mode 100755 Program/libcsp/include/csp/crypto/csp_sha1.h create mode 100755 Program/libcsp/include/csp/crypto/csp_xtea.h create mode 100755 Program/libcsp/include/csp/csp.h create mode 100755 Program/libcsp/include/csp/csp_buffer.h create mode 100755 Program/libcsp/include/csp/csp_cmp.h create mode 100755 Program/libcsp/include/csp/csp_crc32.h create mode 100755 Program/libcsp/include/csp/csp_debug.h create mode 100755 Program/libcsp/include/csp/csp_endian.h create mode 100755 Program/libcsp/include/csp/csp_error.h create mode 100755 Program/libcsp/include/csp/csp_iflist.h create mode 100755 Program/libcsp/include/csp/csp_interface.h create mode 100755 Program/libcsp/include/csp/csp_platform.h create mode 100755 Program/libcsp/include/csp/csp_promisc.h create mode 100755 Program/libcsp/include/csp/csp_rtable.h create mode 100755 Program/libcsp/include/csp/csp_sfp.h create mode 100755 Program/libcsp/include/csp/csp_types.h create mode 100755 Program/libcsp/include/csp/drivers/can_socketcan.h create mode 100755 Program/libcsp/include/csp/drivers/usart.h create mode 100755 Program/libcsp/include/csp/interfaces/csp_if_can.h create mode 100755 Program/libcsp/include/csp/interfaces/csp_if_i2c.h create mode 100755 Program/libcsp/include/csp/interfaces/csp_if_kiss.h create mode 100755 Program/libcsp/include/csp/interfaces/csp_if_lo.h create mode 100755 Program/libcsp/include/csp/interfaces/csp_if_zmqhub.h create mode 100755 Program/libcsp/src/arch/csp_system.c create mode 100755 Program/libcsp/src/arch/csp_time.c create mode 100755 Program/libcsp/src/arch/freertos/csp_clock.c create mode 100755 Program/libcsp/src/arch/freertos/csp_malloc.c create mode 100755 Program/libcsp/src/arch/freertos/csp_queue.c create mode 100755 Program/libcsp/src/arch/freertos/csp_semaphore.c create mode 100755 Program/libcsp/src/arch/freertos/csp_system.c create mode 100755 Program/libcsp/src/arch/freertos/csp_thread.c create mode 100755 Program/libcsp/src/arch/freertos/csp_time.c create mode 100755 Program/libcsp/src/arch/macosx/csp_clock.c create mode 100755 Program/libcsp/src/arch/macosx/csp_malloc.c create mode 100755 Program/libcsp/src/arch/macosx/csp_queue.c create mode 100755 Program/libcsp/src/arch/macosx/csp_semaphore.c create mode 100755 Program/libcsp/src/arch/macosx/csp_system.c create mode 100755 Program/libcsp/src/arch/macosx/csp_thread.c create mode 100755 Program/libcsp/src/arch/macosx/csp_time.c create mode 100755 Program/libcsp/src/arch/macosx/pthread_queue.c create mode 100755 Program/libcsp/src/arch/posix/csp_clock.c create mode 100755 Program/libcsp/src/arch/posix/csp_malloc.c create mode 100755 Program/libcsp/src/arch/posix/csp_queue.c create mode 100755 Program/libcsp/src/arch/posix/csp_semaphore.c create mode 100755 Program/libcsp/src/arch/posix/csp_system.c create mode 100755 Program/libcsp/src/arch/posix/csp_thread.c create mode 100755 Program/libcsp/src/arch/posix/csp_time.c create mode 100755 Program/libcsp/src/arch/posix/pthread_queue.c create mode 100755 Program/libcsp/src/arch/windows/README create mode 100755 Program/libcsp/src/arch/windows/csp_clock.c create mode 100755 Program/libcsp/src/arch/windows/csp_malloc.c create mode 100755 Program/libcsp/src/arch/windows/csp_queue.c create mode 100755 Program/libcsp/src/arch/windows/csp_semaphore.c create mode 100755 Program/libcsp/src/arch/windows/csp_system.c create mode 100755 Program/libcsp/src/arch/windows/csp_thread.c create mode 100755 Program/libcsp/src/arch/windows/csp_time.c create mode 100755 Program/libcsp/src/arch/windows/windows_queue.c create mode 100755 Program/libcsp/src/arch/windows/windows_queue.h create mode 100755 Program/libcsp/src/bindings/python/pycsp.c create mode 100755 Program/libcsp/src/crypto/csp_hmac.c create mode 100755 Program/libcsp/src/crypto/csp_sha1.c create mode 100755 Program/libcsp/src/crypto/csp_xtea.c create mode 100755 Program/libcsp/src/csp_bridge.c create mode 100755 Program/libcsp/src/csp_buffer.c create mode 100755 Program/libcsp/src/csp_conn.c create mode 100755 Program/libcsp/src/csp_conn.h create mode 100755 Program/libcsp/src/csp_crc32.c create mode 100755 Program/libcsp/src/csp_debug.c create mode 100755 Program/libcsp/src/csp_dedup.c create mode 100755 Program/libcsp/src/csp_dedup.h create mode 100755 Program/libcsp/src/csp_endian.c create mode 100755 Program/libcsp/src/csp_hex_dump.c create mode 100755 Program/libcsp/src/csp_iflist.c create mode 100755 Program/libcsp/src/csp_init.c create mode 100755 Program/libcsp/src/csp_init.h create mode 100755 Program/libcsp/src/csp_io.c create mode 100755 Program/libcsp/src/csp_io.h create mode 100755 Program/libcsp/src/csp_port.c create mode 100755 Program/libcsp/src/csp_port.h create mode 100755 Program/libcsp/src/csp_promisc.c create mode 100755 Program/libcsp/src/csp_promisc.h create mode 100755 Program/libcsp/src/csp_qfifo.c create mode 100755 Program/libcsp/src/csp_qfifo.h create mode 100755 Program/libcsp/src/csp_route.c create mode 100755 Program/libcsp/src/csp_service_handler.c create mode 100755 Program/libcsp/src/csp_services.c create mode 100755 Program/libcsp/src/csp_sfp.c create mode 100755 Program/libcsp/src/drivers/can/can_socketcan.c create mode 100755 Program/libcsp/src/drivers/usart/usart_kiss.c create mode 100755 Program/libcsp/src/drivers/usart/usart_linux.c create mode 100755 Program/libcsp/src/drivers/usart/usart_windows.c create mode 100755 Program/libcsp/src/interfaces/csp_if_can.c create mode 100755 Program/libcsp/src/interfaces/csp_if_can_pbuf.c create mode 100755 Program/libcsp/src/interfaces/csp_if_can_pbuf.h create mode 100755 Program/libcsp/src/interfaces/csp_if_i2c.c create mode 100755 Program/libcsp/src/interfaces/csp_if_kiss.c create mode 100755 Program/libcsp/src/interfaces/csp_if_lo.c create mode 100755 Program/libcsp/src/interfaces/csp_if_zmqhub.c create mode 100755 Program/libcsp/src/rtable/csp_rtable.c create mode 100755 Program/libcsp/src/rtable/csp_rtable_cidr.c create mode 100755 Program/libcsp/src/rtable/csp_rtable_internal.h create mode 100755 Program/libcsp/src/rtable/csp_rtable_static.c create mode 100755 Program/libcsp/src/transport/csp_rdp.c create mode 100755 Program/libcsp/src/transport/csp_transport.h create mode 100755 Program/libcsp/src/transport/csp_udp.c create mode 100755 Program/libcsp/utils/cfpsplit.py create mode 100755 Program/libcsp/utils/cspsplit.py create mode 100755 Program/libcsp/waf create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Build.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ConfigSet.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Configure.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Context.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Errors.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Logs.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Node.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Options.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Runner.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Scripting.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Task.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/TaskGen.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/__init__.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ar.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/asm.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/bison.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_aliases.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_config.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_osx.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_preproc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/c_tests.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ccroot.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clang.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/clangxx.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_c.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_cxx.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_d.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/compiler_fc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cs.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/cxx.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_config.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/d_scan.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/dbus.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/dmd.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/errcheck.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_config.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/fc_scan.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/flex.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/g95.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gas.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gcc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gdc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gfortran.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/glib2.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gnu_dirs.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/gxx.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/icc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/icpc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ifort.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/intltool.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/irixcc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/javaw.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ldc2.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/lua.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/md5_tstamp.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/msvc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nasm.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/nobuild.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/perl.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/python.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/qt5.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/ruby.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/suncxx.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/tex.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/vala.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/waf_unit_test.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/winres.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlc.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Tools/xlcxx.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/Utils.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/__init__.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/ansiterm.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/__init__.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/extras/compat15.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/fixpy2.py create mode 100755 Program/libcsp/waf3-2.0.18-96675f149f50dab16c9e2e6aaf5e787b/waflib/processor.py create mode 100755 Program/libcsp/wscript diff --git a/Program/libcsp/CHANGELOG b/Program/libcsp/CHANGELOG new file mode 100755 index 0000000..bde5e6e --- /dev/null +++ b/Program/libcsp/CHANGELOG @@ -0,0 +1,163 @@ +libcsp 1.6, 16-04-2020 +---------------------- +- Updated documentation. +- Updated Python bindings, removed Python2 support. +- Removed timeout for send (internally only) and interface tx functions - the timeout was only used on I2C interface. +- Updated example code to a single csp_server_client.c implementation. +- Renamed (scoped) clock_set_time()/clock_get_time() to csp_clock_set_time()/csp_clock_get_time() +- Changed csp_sys_reboot()/csp_sys_shutdown() to use callbacks, default POSIX impl. in csp/arch/posix/csp_system.h. +- Added support for timestamps in logs by setting CSP_DEBUG_TIMESTAMP (uses csp_clock_get_time()). +- Renamed mac to via (structs, functions, examples and documentation) +- RDP: Ensure connection is kept in CLOSE_WAIT for period of time. In some cases, the connection would switch to CLOSED immediately. +- RDP: Fixed connection leak, if a RST segment was received on a closed connecton. +- RDP: Ensure connection is closed from both userspace and protocol, before closing completely (preventing undetermined behaviour). +- RDP: Added support for fast close of a connection (skipping the CLOSE_WAIT period), but only if both ends agree on close. +- RDP: Fixed issue "Possible bug in RDP TX timeout" (#109), see issue on github for further details. +- Added Travis-CI support on Github, build: Linux, Mac and Windows. +- Changed #ifdef/ifndef to single #if in order to support forced disabling and alignment with log macro's. +- Updated thread API, documentation, aligned implementation +- Refactored all CSP interfaces. + - Accept csp_route_t, instead of csp_iface_t. + - No static members -> multiple interfaces of all types. + - Added csp_iface_t.interface_data for interface data. + - Added csp_iface_t.driver_data for driver data (unknown to interface level). + - Check for buffer overrun + - Set MTU if not already set, and it make sense on the respective interface. + - Driver Tx function is now a callback, must be set by the application (in the interface data). +- csp_packet_t (and other structs) are no longer packed (increases performance), padding is increased from 8->10 bytes for alignment. +- Refactored rtable CIDR/static implementation: + - Use same format for storing table (text). + - Added csp_route_t to hold route entry, e.g. interface and via. + - Replaced csp_rtable_find_iface()/csp_rtable_find_mac() with csp_rtable_find_route() +- Added csp_get_memfree()/csp_get_buf_free()/csp_get_uptime(), which returns an error code. +- Improved logging, check level before doing the actual call. Added support for external log macros. +- Removed unused defines/functions: csp_conn_lock, csp_conn_unlock, CSP_PROMISC +- Replaced CSP_MAX_DELAY and CSP_INFINITY with CSP_MAX_TIMEOUT (same value). +- Added csp_calloc(), csp/arch/csp_malloc.h +- Added csp_buffer_data_size(), csp/csp_buffer.h +- Updated header documentation (doxygen). +- Restructured header includes. +- api: Added const for read-only pointers. +- api: Changed a number of uint8_t pointers to void to avoid cast. + +libcsp 1.5-internal, 21-08-2018 +------------------------------- +- Internal release. +- New python bindings with examples and python3 support. +- Introduced csp_conf_t, which replaces a number of compile options. This has broken csp_init(). +- Refactored CAN interface. +- Bug fixes. + +libcsp 1.4, 07-05-2015 +---------------------- +- new: General rtable interface with support for STATIC or CIDR format +- new: CIDR (classless interdomain routing) route table format with netmasks +- new: Bridge capability +- new: Added routing table (de)serialization functions for load/save +- new: Automatic packet deduplication using CRC32 (compile time option) +- new: Autogenerated python bindings using ctypesgen +- new: Task-less operation with router invocation from external scheduler function +- api: Refactor route_if_add to csp_iflist_add +- api: Refactor route_set and friends to rtable_set +- api: Refactor csp_fifo_qos to csp_qfifo +- api: Added defined to be backwards compatible with 1.x +- interfaces: Drop packets on LOOP interface not for own address (blackhole) +- interfaces: New ZMQHUB interface (using zeroMQ over TCP) +- other: Increase stack size from 250 to 1100 for csp_can_rx_task +- other: Cleanup in csp_route.c +- other: Show incoming interface name in debug message +- other: Remove newlines from debug calls +- improvement: Reduce debug hook function complexity with valist passing +- fix: csp_sleep_ms did not work + +libcsp 1.3, 07-05-2015 +---------------------- +- new: Split long process lists into multiple packets +- new: Added posix csp_clock.h +- new: cmp clock functions (requires that you provide csp_clock.h implementation) +- new: Added SFP (Small fragmentation protocol) for larger data chunks +- fix: csp_if_fifo example +- fix: NULL char at the end of rps +- doc: Updated mtu documentation +- other: Tested with FreeRTOS 8.0 +- other: Added disable-stlib option to build only object files + +libcsp 1.2, 25-10-2013 +---------------------- +- Feature release +- New: CMP service for peek and poke of memory +- New: CMP interface statistics struct is now packed +- New: Faster O(1) buffer system with reference counting and automatic alignment +- New: Thread safe KISS driver with support for multiple interfaces +- New: CSP interface struct now holds an opaque pointer to driver handle +- New: removed TXBUF from KISS driver entirely to minimize stack usage, added TX lock instead +- New: Pre-calculated CRC table .romem or PROGMEM on __avr__ +- New: Added buffer overflow protection to KISS interface +- New: Allow posting null pointers on conn RX queues +- New: Lower memory usage on AVR8 +- New: csp_route_save and csp_route_load functions +- New: option --disable-verbose to disable filenames and linenumber on debug +- Protocol: KISS uses csp_crc32 instead of it own embedded crc32 +- Improvement: Use buffer clone function to copy promisc packets +- Bugfix: Fix pointer size (32/16bit) in cmp_peek/poke +- Bugfix: Issue with double free in KISS fixed +- Bugfix: Change rdp_send timeout from packet to connection timeout to make sending task block longer +- Bugfix: Fix conn pool leak when using security check and discarding new packets +- Bugfix: Add packet too short check for CRC32 +- Bugfix: Accept CRC32 responses from nodes without CRC support +- Bugfix: Ensure csp_ping works for packets > 256 bytes +- Bugfix: Cleanup printf inside ISR functions +- Bugfix: Do not add forwarded packets to promisc queue twice +- Bugfix: Fix return value bug of csp_buffer_get when out of buffers +- Bugfix: Always post null pointer with lowest priority, not highest +- Bugfix: Add check on debug level before calling do_csp_debug, fixes #35 +- Other: Export csp/arch include files +- Other: Remove the use of bool type from csp_debug +- Other: Moved csp debug functions to csp_debug.h instead of csp.h +- Other: Ensure assignment of id happens using the uint32_t .ext value of the union, quenches warning + +libcsp 1.1, 24-08-2012 +---------------------- +- Feature release +- Defacto stable since Feb 2012 +- New: I2C interface +- New: KISS interface +- New: USART drivers for Linux, Mac and Windows +- New: Windows/MinGW support +- New: MacOSX support +- New: Interface register function +- New: Interface search function +- New: CMP service for remote route updating +- New: CMP service for interface statistics +- Improvement: Better QoS support +- Improvement: Send RDP control messages with high priority +- Improvement: WAF distcheck now works +- Improvement: Automatic endian discovery +- Improvement: Accept packets with CRC32 checksum if compiled without CRC32 support +- Improvement: Do not wake the router task if RDP is not enabled +- Improvement: Save 102 bytes of RAM by packing route entries +- Cleanup: Simplify CAN configuration +- Cleanup: Move architecture specific code to src/arch +- Bugfix: CSP_MEMFREE gives wrong answer on freertos AVR due to truncation +- Bugfix: Fixed wrong 64-bit size_t in csp_service_handler +- Bugfix: Fixed problem in csp_if_kiss when out of buffers +- Bigfix: Handle bus-off CAN IRQ for AT90CAN128 + +libcsp 1.0.1, 30-10-2011 +------------------------ +- Hotfix release +- Bugfix: missing extern in csp_if_lo.h + +libcsp 1.0, 24-10-2011 +---------------------- +- First official release +- New: CSP 32-bit header 1.0 +- Features: Network Router with promiscous mode, broadcast and QoS +- Features: Connection-oriented transport protocol w. flow-control +- Features: Connection-less "UDP" like transport +- Features: Encryption, Authentication and message check +- Features: Loopback interface +- Features: Python Bindings +- Features: CAN interface w. drivers for several chips +- Features: CSP-services (ping, reboot, uptime, memfree, buffree, ident) + diff --git a/Program/libcsp/CI.rst b/Program/libcsp/CI.rst new file mode 100755 index 0000000..ce27736 --- /dev/null +++ b/Program/libcsp/CI.rst @@ -0,0 +1,6 @@ +Continous Integration +===================== + +libcsp uses Travis-CI App for continous integration: https://github.com/marketplace/travis-ci. + +libcsp on Travis: https://travis-ci.com/libcsp/libcsp/branches diff --git a/Program/libcsp/COPYING b/Program/libcsp/COPYING new file mode 100755 index 0000000..54c619a --- /dev/null +++ b/Program/libcsp/COPYING @@ -0,0 +1,503 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/Program/libcsp/INSTALL.rst b/Program/libcsp/INSTALL.rst new file mode 100755 index 0000000..35ed8ab --- /dev/null +++ b/Program/libcsp/INSTALL.rst @@ -0,0 +1,29 @@ +How to install LibCSP +===================== + +CSP uses the `waf` build system (http://code.google.com/p/waf/). In order to +compile CSP, you first need to configure the toolchain, what operating system +to compile for, the location of required libraries and whether to enable +certain optional features. + +To configure CSP to build with the AVR32 toolchain for FreeRTOS and output +the compiled libcsp.a and header files to the install directory, issue: + +.. code-block:: bash + + ./waf configure --toolchain=avr32- --with-os=freertos --prefix=install + +When compiling for FreeRTOS, the path to the FreeRTOS header files must be +specified with `--includes=PATH`. + +A number of optional features can be enabled by from the configure script. +Support for XTEA encryption can e.g. be enabled with `--enable-xtea`. Run +`./waf configure --help` to list the available configure options. + +The CAN driver (based on socketcan) can be enabled by appending the configure option `--enable-can-socketcan`. + +To build and copy the library to the location specified with --prefix, use: + +.. code-block:: bash + + ./waf build install diff --git a/Program/libcsp/README.rst b/Program/libcsp/README.rst new file mode 100755 index 0000000..76a27bf --- /dev/null +++ b/Program/libcsp/README.rst @@ -0,0 +1,41 @@ +The Cubesat Space Protocol +========================== + +Cubesat Space Protocol (CSP) is a small protocol stack written in C. CSP is designed to ease communication between distributed embedded systems in smaller networks, such as Cubesats. The design follows the TCP/IP model and includes a transport protocol, a routing protocol and several MAC-layer interfaces. The core of `libcsp` includes a router, a connection oriented socket API and message/connection pools. + +The protocol is based on a 32-bit header containing both transport and network-layer information. Its implementation is designed for, but not limited to, embedded systems such as the 8-bit AVR microprocessor and the 32-bit ARM and AVR from Atmel. The implementation is written in GNU C and is currently ported to run on FreeRTOS, Linux (POSIX), MacOS and Windows. The primiary platforms being used are FreeRTOS and Linux. + +The idea is to give sub-system developers of cubesats the same features of a TCP/IP stack, but without adding the huge overhead of the IP header. The small footprint and simple implementation allows a small 8-bit system to be fully connected on the network. This allows all subsystems to provide their services on the same network level, without any master node required. Using a service oriented architecture has several advantages compared to the traditional mater/slave topology used on many cubesats. + + * Standardised network protocol: All subsystems can communicate with eachother + * Service loose coupling: Services maintain a relationship that minimizes dependencies between subsystems + * Service abstraction: Beyond descriptions in the service contract, services hide logic from the outside world + * Service reusability: Logic is divided into services with the intention of promoting reuse. + * Service autonomy: Services have control over the logic they encapsulate. + * Service Redundancy: Easily add redundant services to the bus + * Reduces single point of failure: The complexity is moved from a single master node to several well defined services on the network + +The implementation of `libcsp` is written with simplicity in mind, but it's compile time configuration allows it to have some rather advanced features as well: + +Features +-------- + + * Thread safe Socket API + * Router task with Quality of Services + * Connection-oriented operation (RFC 908 and 1151). + * Connection-less operation (similar to UDP) + * ICMP-like requests such as ping and buffer status. + * Loopback interface + * Very Small Footprint in regards to code and memory required + * Zero-copy buffer and queue system + * Modular network interface system + * OS abstraction, currently ported to: FreeRTOS, Linux (POSIX), MacOS and Windows + * Broadcast traffic + * Promiscuous mode + * Encrypted packets with XTEA in CTR mode + * Truncated HMAC-SHA1 Authentication (RFC 2104) + +LGPL Software license +--------------------- +The source code is available under an LGPL 2.1 license. See COPYING for the license text. + diff --git a/Program/libcsp/build/.lock-waf_linux_build b/Program/libcsp/build/.lock-waf_linux_build new file mode 100755 index 0000000..b06201e --- /dev/null +++ b/Program/libcsp/build/.lock-waf_linux_build @@ -0,0 +1,10 @@ +argv = ['waf', 'configure', '--with-os=posix', '--enable-can-socketcan', '--enable-rdp', '--enable-hmac', '--enable-xtea', '--with-loglevel=debug', '--enable-debug-timestamp', '--enable-python3-bindings', '--with-driver-usart=linux', '--enable-if-zmqhub', '--enable-examples'] +config_cmd = 'configure' +environ = {'CLUTTER_IM_MODULE': 'xim', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'ANDROID_HOME': '/media/evan/NewVolume/Android/Sdk', 'XDG_MENU_PREFIX': 'gnome-', 'LANG': 'en_CA.UTF-8', 'MANAGERPID': '2687', 'DISPLAY': ':0', 'INVOCATION_ID': '40736d50dbe74043b723449b3313ccde', 'GNOME_SHELL_SESSION_MODE': 'ubuntu', 'GTK2_MODULES': 'overlay-scrollbar', 'COLORTERM': 'truecolor', 'GEM_HOME': '/home/evan/.gem', 'ZEITGEIST_DATA_PATH': '/home/evan/.local/share/zeitgeist', 'USERNAME': 'evan', 'JAVA_HOME': '/home/evan/jdk1.8.0_181', 'XDG_VTNR': '2', 'SSH_AUTH_SOCK': '/run/user/1000/keyring/ssh', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path', 'S_COLORS': 'auto', 'XDG_SESSION_ID': '2', 'USER': 'evan', 'DESKTOP_SESSION': 'ubuntu', 'RBENV_SHELL': 'bash', 'QT4_IM_MODULE': 'xim', 'GOPATH': '/home/evan/Desktop/GO', 'TEXTDOMAINDIR': '/usr/share/locale/', 'GNOME_TERMINAL_SCREEN': '/org/gnome/Terminal/screen/00188ceb_b3cc_4ac6_9aa1_7e7bd14bf55b', 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu.default.path', 'PWD': '/media/evan/NewVolume/ground_station/libcsp', 'HOME': '/home/evan', 'JOURNAL_STREAM': '9:39688', 'ANDROID_NDK_HOME': '/home/evan/ndk-web3/android-ndk-r17b', 'TEXTDOMAIN': 'im-config', 'SSH_AGENT_PID': '3322', 'QT_ACCESSIBILITY': '1', 'DPDK_BUILD': '/usr/src/dpdk-stable-17.05.2/x86_64-native-linuxapp-gcc', 'LIBVIRT_DEFAULT_URI': 'qemu:///system', 'XDG_SESSION_TYPE': 'x11', 'XDG_DATA_DIRS': '/home/evan/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share/:/usr/share/ubuntu:/home/evan/.local/share/flatpak/exports/share/:/var/lib/flatpak/exports/share/:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop:/var/lib/snapd/desktop', 'XDG_SESSION_DESKTOP': 'ubuntu', 'GEM_PATH': '/home/evan/.gem', 'DBUS_STARTER_ADDRESS': 'unix:path=/run/user/1000/bus,guid=5366896dc62962572a54bde85fe78121', 'DPDK_DIR': '/usr/src/dpdk-stable-17.05.2', 'GTK_MODULES': 'gail:atk-bridge', 'WINDOWPATH': '2', 'TERM': 'vt100', 'VTE_VERSION': '5202', 'SHELL': '/bin/bash', 'QT_IM_MODULE': 'ibus', 'XMODIFIERS': '@im=ibus', 'IM_CONFIG_PHASE': '2', 'DBUS_STARTER_BUS_TYPE': 'session', 'XDG_CURRENT_DESKTOP': 'ubuntu:GNOME', 'GPG_AGENT_INFO': '/run/user/1000/gnupg/S.gpg-agent:0:1', 'GNOME_TERMINAL_SERVICE': ':1.87', 'SHLVL': '1', 'XDG_SEAT': 'seat0', 'LANGUAGE': 'en_CA:en', 'DPDK_TARGET': 'x86_64-native-linuxapp-gcc', 'GDMSESSION': 'ubuntu', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'LOGNAME': 'evan', 'DBUS_SESSION_BUS_ADDRESS': 'unix:path=/run/user/1000/bus,guid=5366896dc62962572a54bde85fe78121', 'XDG_RUNTIME_DIR': '/run/user/1000', 'XAUTHORITY': '/run/user/1000/gdm/Xauthority', 'GOBIN': '/home/evan/Desktop/GO/bin', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/etc/xdg', 'PATH': '/home/evan/.rbenv/shims:/home/evan/.rbenv/shims:/home/evan/.rbenv/bin:/home/evan/.rbenv/shims:/home/evan/.rbenv/shims:/home/evan/.rbenv/bin:/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin:/home/evan/.npm-global/bin:/home/evan/.cargo/bin:/home/evan/bin:/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/evan/VSCode-linux-x64/bin:/home/evan/node-v8.7.0-linux-x64/bin:/home/evan/Python-3.6.4/python:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/tools/bin:/media/evan/NewVolume/Android/Sdk/platform-tools:/media/evan/NewVolume/Android/Sdk/emulator:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/platform-tools:/home/evan/BlockChain/go-ethereum/build/bin:/home/evan/Desktop/GO/bin:/home/evan/AllGethTools:/home/evan/.gem/gems/ceedling-0.28.3/bin:/home/evan/VSCode-linux-x64/bin:/home/evan/node-v8.7.0-linux-x64/bin:/home/evan/Python-3.6.4/python:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/tools/bin:/media/evan/NewVolume/Android/Sdk/platform-tools:/media/evan/NewVolume/Android/Sdk/emulator:/media/evan/NewVolume/Android/Sdk/tools:/media/evan/NewVolume/Android/Sdk/platform-tools:/home/evan/BlockChain/go-ethereum/build/bin:/home/evan/Desktop/GO/bin:/home/evan/AllGethTools:/home/evan/.gem/gems/ceedling-0.28.3/bin', 'SESSION_MANAGER': 'local/evan-Aspire-E5-575G:@/tmp/.ICE-unix/3192,unix/evan-Aspire-E5-575G:/tmp/.ICE-unix/3192', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'GTK_IM_MODULE': 'ibus', '_': '/usr/bin/python3', 'OLDPWD': '/media/evan/NewVolume/ground_station'} +files = ['/media/evan/NewVolume/ground_station/libcsp/wscript'] +hash = b'\xbb\xfe\xcd\xa3\x17\xbd(\x1e\xcaR\xa8\x08z\x8c\x90\xc0' +launch_dir = '/media/evan/NewVolume/ground_station/libcsp' +options = {'colors': 'auto', 'jobs': 4, 'keep': 0, 'verbose': 0, 'zones': '', 'profile': 0, 'pdb': 0, 'whelp': 0, 'out': '', 'top': '', 'no_lock_in_run': '', 'no_lock_in_out': '', 'no_lock_in_top': '', 'prefix': '/usr/local', 'bindir': None, 'libdir': None, 'progress_bar': 0, 'targets': '', 'files': '', 'destdir': '', 'force': False, 'distcheck_args': None, 'check_c_compiler': None, 'toolchain': None, 'includes': '', 'install_csp': None, 'disable_output': None, 'disable_stlib': None, 'enable_shlib': None, 'enable_rdp': True, 'enable_rdp_fast_close': None, 'enable_qos': None, 'enable_promisc': None, 'enable_crc32': None, 'enable_hmac': True, 'enable_xtea': True, 'enable_python3_bindings': True, 'enable_examples': True, 'enable_dedup': None, 'enable_external_debug': None, 'enable_debug_timestamp': True, 'enable_if_zmqhub': True, 'enable_can_socketcan': True, 'with_driver_usart': 'linux', 'with_os': 'posix', 'with_loglevel': 'debug', 'with_rtable': 'static'} +out_dir = '/media/evan/NewVolume/ground_station/libcsp/build' +run_dir = '/media/evan/NewVolume/ground_station/libcsp' +top_dir = '/media/evan/NewVolume/ground_station/libcsp' diff --git a/Program/libcsp/build/.wafpickle-linux-50727408-20 b/Program/libcsp/build/.wafpickle-linux-50727408-20 new file mode 100755 index 0000000000000000000000000000000000000000..b9aef2db67751cec86c6033e0f3796cda02e9d2b GIT binary patch literal 30138 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 ['/usr/bin/gcc'] +['/usr/bin/gcc', '-dM', '-E', '-'] +out: #define __SSP_STRONG__ 3 +#define __DBL_MIN_EXP__ (-1021) +#define __FLT32X_MAX_EXP__ 1024 +#define __UINT_LEAST16_MAX__ 0xffff +#define __ATOMIC_ACQUIRE 2 +#define __FLT128_MAX_10_EXP__ 4932 +#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F +#define __GCC_IEC_559_COMPLEX 2 +#define __UINT_LEAST8_TYPE__ unsigned char +#define __SIZEOF_FLOAT80__ 16 +#define __INTMAX_C(c) c ## L +#define __CHAR_BIT__ 8 +#define __UINT8_MAX__ 0xff +#define __WINT_MAX__ 0xffffffffU +#define __FLT32_MIN_EXP__ (-125) +#define __ORDER_LITTLE_ENDIAN__ 1234 +#define __SIZE_MAX__ 0xffffffffffffffffUL +#define __WCHAR_MAX__ 0x7fffffff +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 +#define __DBL_DENORM_MIN__ ((double)4.94065645841246544176568792868221372e-324L) +#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 +#define __GCC_ATOMIC_CHAR_LOCK_FREE 2 +#define __GCC_IEC_559 2 +#define __FLT32X_DECIMAL_DIG__ 17 +#define __FLT_EVAL_METHOD__ 0 +#define __unix__ 1 +#define __FLT64_DECIMAL_DIG__ 17 +#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 +#define __x86_64 1 +#define __UINT_FAST64_MAX__ 0xffffffffffffffffUL +#define __SIG_ATOMIC_TYPE__ int +#define __DBL_MIN_10_EXP__ (-307) +#define __FINITE_MATH_ONLY__ 0 +#define __GNUC_PATCHLEVEL__ 0 +#define __FLT32_HAS_DENORM__ 1 +#define __UINT_FAST8_MAX__ 0xff +#define __has_include(STR) __has_include__(STR) +#define __DEC64_MAX_EXP__ 385 +#define __INT8_C(c) c +#define __INT_LEAST8_WIDTH__ 8 +#define __UINT_LEAST64_MAX__ 0xffffffffffffffffUL +#define __SHRT_MAX__ 0x7fff +#define __LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L +#define __FLT64X_MAX_10_EXP__ 4932 +#define __UINT_LEAST8_MAX__ 0xff +#define __GCC_ATOMIC_BOOL_LOCK_FREE 2 +#define __FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128 +#define __UINTMAX_TYPE__ long unsigned int +#define __linux 1 +#define __DEC32_EPSILON__ 1E-6DF +#define __FLT_EVAL_METHOD_TS_18661_3__ 0 +#define __unix 1 +#define __UINT32_MAX__ 0xffffffffU +#define __LDBL_MAX_EXP__ 16384 +#define __FLT128_MIN_EXP__ (-16381) +#define __WINT_MIN__ 0U +#define __linux__ 1 +#define __FLT128_MIN_10_EXP__ (-4931) +#define __INT_LEAST16_WIDTH__ 16 +#define __SCHAR_MAX__ 0x7f +#define __FLT128_MANT_DIG__ 113 +#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1) +#define __INT64_C(c) c ## L +#define __DBL_DIG__ 15 +#define __GCC_ATOMIC_POINTER_LOCK_FREE 2 +#define __FLT64X_MANT_DIG__ 64 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_POINTER__ 8 +#define __USER_LABEL_PREFIX__ +#define __FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x +#define __STDC_HOSTED__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __FLT32_DIG__ 6 +#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F +#define __SHRT_WIDTH__ 16 +#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L +#define __STDC_UTF_16__ 1 +#define __DEC32_MAX__ 9.999999E96DF +#define __FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x +#define __FLT32X_HAS_INFINITY__ 1 +#define __INT32_MAX__ 0x7fffffff +#define __INT_WIDTH__ 32 +#define __SIZEOF_LONG__ 8 +#define __STDC_IEC_559__ 1 +#define __STDC_ISO_10646__ 201706L +#define __UINT16_C(c) c +#define __PTRDIFF_WIDTH__ 64 +#define __DECIMAL_DIG__ 21 +#define __FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64 +#define __gnu_linux__ 1 +#define __INTMAX_WIDTH__ 64 +#define __has_include_next(STR) __has_include_next__(STR) +#define __FLT64X_MIN_10_EXP__ (-4931) +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __FLT64_MANT_DIG__ 53 +#define __GNUC__ 7 +#define __pie__ 2 +#define __MMX__ 1 +#define __FLT_HAS_DENORM__ 1 +#define __SIZEOF_LONG_DOUBLE__ 16 +#define __BIGGEST_ALIGNMENT__ 16 +#define __FLT64_MAX_10_EXP__ 308 +#define __DBL_MAX__ ((double)1.79769313486231570814527423731704357e+308L) +#define __INT_FAST32_MAX__ 0x7fffffffffffffffL +#define __DBL_HAS_INFINITY__ 1 +#define __DEC32_MIN_EXP__ (-94) +#define __INTPTR_WIDTH__ 64 +#define __FLT32X_HAS_DENORM__ 1 +#define __INT_FAST16_TYPE__ long int +#define __LDBL_HAS_DENORM__ 1 +#define __FLT128_HAS_INFINITY__ 1 +#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL +#define __INT_LEAST32_MAX__ 0x7fffffff +#define __DEC32_MIN__ 1E-95DF +#define __DBL_MAX_EXP__ 1024 +#define __WCHAR_WIDTH__ 32 +#define __FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32 +#define __DEC128_EPSILON__ 1E-33DL +#define __SSE2_MATH__ 1 +#define __ATOMIC_HLE_RELEASE 131072 +#define __PTRDIFF_MAX__ 0x7fffffffffffffffL +#define __amd64 1 +#define __STDC_NO_THREADS__ 1 +#define __ATOMIC_HLE_ACQUIRE 65536 +#define __FLT32_HAS_QUIET_NAN__ 1 +#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL +#define __SIZEOF_SIZE_T__ 8 +#define __FLT64X_MIN_EXP__ (-16381) +#define __SIZEOF_WINT_T__ 4 +#define __LONG_LONG_WIDTH__ 64 +#define __FLT32_MAX_EXP__ 128 +#define __GCC_HAVE_DWARF2_CFI_ASM 1 +#define __GXX_ABI_VERSION 1011 +#define __FLT_MIN_EXP__ (-125) +#define __FLT64X_HAS_QUIET_NAN__ 1 +#define __INT_FAST64_TYPE__ long int +#define __FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64 +#define __DBL_MIN__ ((double)2.22507385850720138309023271733240406e-308L) +#define __PIE__ 2 +#define __LP64__ 1 +#define __FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x +#define __DECIMAL_BID_FORMAT__ 1 +#define __FLT64_MIN_EXP__ (-1021) +#define __FLT64_MIN_10_EXP__ (-307) +#define __FLT64X_DECIMAL_DIG__ 21 +#define __DEC128_MIN__ 1E-6143DL +#define __REGISTER_PREFIX__ +#define __UINT16_MAX__ 0xffff +#define __DBL_HAS_DENORM__ 1 +#define __FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32 +#define __UINT8_TYPE__ unsigned char +#define __NO_INLINE__ 1 +#define __FLT_MANT_DIG__ 24 +#define __LDBL_DECIMAL_DIG__ 21 +#define __VERSION__ "7.5.0" +#define __UINT64_C(c) c ## UL +#define _STDC_PREDEF_H 1 +#define __GCC_ATOMIC_INT_LOCK_FREE 2 +#define __FLT128_MAX_EXP__ 16384 +#define __FLT32_MANT_DIG__ 24 +#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __STDC_IEC_559_COMPLEX__ 1 +#define __FLT128_HAS_DENORM__ 1 +#define __FLT128_DIG__ 33 +#define __SCHAR_WIDTH__ 8 +#define __INT32_C(c) c +#define __DEC64_EPSILON__ 1E-15DD +#define __ORDER_PDP_ENDIAN__ 3412 +#define __DEC128_MIN_EXP__ (-6142) +#define __FLT32_MAX_10_EXP__ 38 +#define __INT_FAST32_TYPE__ long int +#define __UINT_LEAST16_TYPE__ short unsigned int +#define __FLT64X_HAS_INFINITY__ 1 +#define unix 1 +#define __INT16_MAX__ 0x7fff +#define __SIZE_TYPE__ long unsigned int +#define __UINT64_MAX__ 0xffffffffffffffffUL +#define __FLT64X_DIG__ 18 +#define __INT8_TYPE__ signed char +#define __ELF__ 1 +#define __GCC_ASM_FLAG_OUTPUTS__ 1 +#define __FLT_RADIX__ 2 +#define __INT_LEAST16_TYPE__ short int +#define __LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L +#define __UINTMAX_C(c) c ## UL +#define __SSE_MATH__ 1 +#define __k8 1 +#define __SIG_ATOMIC_MAX__ 0x7fffffff +#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +#define __SIZEOF_PTRDIFF_T__ 8 +#define __FLT32X_MANT_DIG__ 53 +#define __x86_64__ 1 +#define __FLT32X_MIN_EXP__ (-1021) +#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF +#define __INT_FAST16_MAX__ 0x7fffffffffffffffL +#define __FLT64_DIG__ 15 +#define __UINT_FAST32_MAX__ 0xffffffffffffffffUL +#define __UINT_LEAST64_TYPE__ long unsigned int +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MAX_10_EXP__ 38 +#define __LONG_MAX__ 0x7fffffffffffffffL +#define __FLT64X_HAS_DENORM__ 1 +#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL +#define __FLT_HAS_INFINITY__ 1 +#define __UINT_FAST16_TYPE__ long unsigned int +#define __DEC64_MAX__ 9.999999999999999E384DD +#define __INT_FAST32_WIDTH__ 64 +#define __CHAR16_TYPE__ short unsigned int +#define __PRAGMA_REDEFINE_EXTNAME 1 +#define __SIZE_WIDTH__ 64 +#define __SEG_FS 1 +#define __INT_LEAST16_MAX__ 0x7fff +#define __DEC64_MANT_DIG__ 16 +#define __INT64_MAX__ 0x7fffffffffffffffL +#define __UINT_LEAST32_MAX__ 0xffffffffU +#define __SEG_GS 1 +#define __FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32 +#define __GCC_ATOMIC_LONG_LOCK_FREE 2 +#define __SIG_ATOMIC_WIDTH__ 32 +#define __INT_LEAST64_TYPE__ long int +#define __INT16_TYPE__ short int +#define __INT_LEAST8_TYPE__ signed char +#define __STDC_VERSION__ 201112L +#define __DEC32_MAX_EXP__ 97 +#define __INT_FAST8_MAX__ 0x7f +#define __FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128 +#define __INTPTR_MAX__ 0x7fffffffffffffffL +#define linux 1 +#define __FLT64_HAS_QUIET_NAN__ 1 +#define __FLT32_MIN_10_EXP__ (-37) +#define __SSE2__ 1 +#define __FLT32X_DIG__ 15 +#define __LDBL_MANT_DIG__ 64 +#define __DBL_HAS_QUIET_NAN__ 1 +#define __FLT64_HAS_INFINITY__ 1 +#define __FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x +#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) +#define __code_model_small__ 1 +#define __k8__ 1 +#define __INTPTR_TYPE__ long int +#define __UINT16_TYPE__ short unsigned int +#define __WCHAR_TYPE__ int +#define __SIZEOF_FLOAT__ 4 +#define __pic__ 2 +#define __UINTPTR_MAX__ 0xffffffffffffffffUL +#define __INT_FAST64_WIDTH__ 64 +#define __DEC64_MIN_EXP__ (-382) +#define __FLT32_DECIMAL_DIG__ 9 +#define __INT_FAST64_MAX__ 0x7fffffffffffffffL +#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 +#define __FLT_DIG__ 6 +#define __FLT32_HAS_INFINITY__ 1 +#define __FLT64X_MAX_EXP__ 16384 +#define __UINT_FAST64_TYPE__ long unsigned int +#define __INT_MAX__ 0x7fffffff +#define __amd64__ 1 +#define __INT64_TYPE__ long int +#define __FLT_MAX_EXP__ 128 +#define __ORDER_BIG_ENDIAN__ 4321 +#define __DBL_MANT_DIG__ 53 +#define __SIZEOF_FLOAT128__ 16 +#define __INT_LEAST64_MAX__ 0x7fffffffffffffffL +#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 +#define __DEC64_MIN__ 1E-383DD +#define __WINT_TYPE__ unsigned int +#define __UINT_LEAST32_TYPE__ unsigned int +#define __SIZEOF_SHORT__ 2 +#define __SSE__ 1 +#define __LDBL_MIN_EXP__ (-16381) +#define __FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64 +#define __WINT_WIDTH__ 32 +#define __INT_LEAST8_MAX__ 0x7f +#define __FLT32X_MAX_10_EXP__ 308 +#define __SIZEOF_INT128__ 16 +#define __LDBL_MAX_10_EXP__ 4932 +#define __ATOMIC_RELAXED 0 +#define __DBL_EPSILON__ ((double)2.22044604925031308084726333618164062e-16L) +#define __FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128 +#define _LP64 1 +#define __UINT8_C(c) c +#define __FLT64_MAX_EXP__ 1024 +#define __INT_LEAST32_TYPE__ int +#define __SIZEOF_WCHAR_T__ 4 +#define __UINT64_TYPE__ long unsigned int +#define __FLT128_HAS_QUIET_NAN__ 1 +#define __INT_FAST8_TYPE__ signed char +#define __FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x +#define __GNUC_STDC_INLINE__ 1 +#define __FLT64_HAS_DENORM__ 1 +#define __FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32 +#define __DBL_DECIMAL_DIG__ 17 +#define __STDC_UTF_32__ 1 +#define __INT_FAST8_WIDTH__ 8 +#define __FXSR__ 1 +#define __DEC_EVAL_METHOD__ 2 +#define __FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x +#define __UINT32_C(c) c ## U +#define __INTMAX_MAX__ 0x7fffffffffffffffL +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#define __FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F +#define __INT8_MAX__ 0x7f +#define __LONG_WIDTH__ 64 +#define __PIC__ 2 +#define __UINT_FAST32_TYPE__ long unsigned int +#define __CHAR32_TYPE__ unsigned int +#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F +#define __INT32_TYPE__ int +#define __SIZEOF_DOUBLE__ 8 +#define __FLT_MIN_10_EXP__ (-37) +#define __FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64 +#define __INT_LEAST32_WIDTH__ 32 +#define __INTMAX_TYPE__ long int +#define __DEC128_MAX_EXP__ 6145 +#define __FLT32X_HAS_QUIET_NAN__ 1 +#define __ATOMIC_CONSUME 1 +#define __GNUC_MINOR__ 5 +#define __INT_FAST16_WIDTH__ 64 +#define __UINTMAX_MAX__ 0xffffffffffffffffUL +#define __DEC32_MANT_DIG__ 7 +#define __FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x +#define __DBL_MAX_10_EXP__ 308 +#define __LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L +#define __INT16_C(c) c +#define __STDC__ 1 +#define __PTRDIFF_TYPE__ long int +#define __ATOMIC_SEQ_CST 5 +#define __UINT32_TYPE__ unsigned int +#define __FLT32X_MIN_10_EXP__ (-307) +#define __UINTPTR_TYPE__ long unsigned int +#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD +#define __DEC128_MANT_DIG__ 34 +#define __LDBL_MIN_10_EXP__ (-4931) +#define __FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128 +#define __SIZEOF_LONG_LONG__ 8 +#define __FLT128_DECIMAL_DIG__ 36 +#define __GCC_ATOMIC_LLONG_LOCK_FREE 2 +#define __FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x +#define __LDBL_DIG__ 18 +#define __FLT_DECIMAL_DIG__ 9 +#define __UINT_FAST16_MAX__ 0xffffffffffffffffUL +#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 +#define __INT_LEAST64_WIDTH__ 64 +#define __UINT_FAST8_TYPE__ unsigned char +#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_RELEASE 3 + +find program=['ar'] paths=['/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/home/evan/.npm-global/bin', '/home/evan/.cargo/bin', '/home/evan/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games', '/snap/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin'] var='AR' -> ['/usr/bin/ar'] +/usr/bin/gcc +---------------------------------------- +Checking for program 'pkg-config' +/usr/bin/pkg-config +find program=['pkg-config'] paths=['/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/shims', '/home/evan/.rbenv/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/home/evan/.npm-global/bin', '/home/evan/.cargo/bin', '/home/evan/bin', '/media/evan/NewVolume/Firmware/esp-open-sdk/xtensa-lx106-elf/bin', '/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/games', '/usr/local/games', '/snap/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin', '/home/evan/VSCode-linux-x64/bin', '/home/evan/node-v8.7.0-linux-x64/bin', '/home/evan/Python-3.6.4/python', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/tools/bin', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/media/evan/NewVolume/Android/Sdk/emulator', '/media/evan/NewVolume/Android/Sdk/tools', '/media/evan/NewVolume/Android/Sdk/platform-tools', '/home/evan/BlockChain/go-ethereum/build/bin', '/home/evan/Desktop/GO/bin', '/home/evan/AllGethTools', '/home/evan/.gem/gems/ceedling-0.28.3/bin'] var='PKGCONFIG' -> ['/usr/bin/pkg-config'] +---------------------------------------- +Checking for 'libsocketcan' +['/usr/bin/pkg-config', '--cflags', '--libs', 'libsocketcan'] +out: -lsocketcan + +yes +---------------------------------------- +Checking for 'libzmq' +['/usr/bin/pkg-config', '--cflags', '--libs', 'libzmq'] +out: -I/usr/local/include -L/usr/local/lib -lzmq + +yes +---------------------------------------- +Checking for 'python3' +['/usr/bin/pkg-config', '--cflags', '--libs', 'python3'] +out: -I/usr/include/python3.6m -I/usr/include/x86_64-linux-gnu/python3.6m -lpython3.6m + +yes +---------------------------------------- +Checking for endianness +==> + +short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; +} +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; +} +extern int foo; + +<== +[1/2] Compiling build/.conf_check_7497c5620f03feadb3d79f4705d343d2/test.c + +['/usr/bin/gcc', '-std=gnu99', '-g', '-Os', '-Wall', '-Wextra', '-Wshadow', '-Wcast-align', '-Wwrite-strings', '-Wno-unused-parameter', '-DGIT_REV="v1.6-9-gbf96d6f"', '-DCSP_POSIX=1', '-DCSP_HAVE_LIBSOCKETCAN=1', '-DCSP_HAVE_LIBZMQ=1', '-DHAVE_PYTHON3=1', '-DCSP_DEBUG=1', '-DCSP_DEBUG_TIMESTAMP=1', '-DCSP_USE_RDP=1', '-DCSP_USE_RDP_FAST_CLOSE=0', '-DCSP_USE_CRC32=0', '-DCSP_USE_HMAC=1', '-DCSP_USE_XTEA=1', '-DCSP_USE_PROMISC=0', '-DCSP_USE_QOS=0', '-DCSP_USE_DEDUP=0', '-DCSP_USE_EXTERNAL_DEBUG=0', '-DCSP_LOG_LEVEL_DEBUG=1', '-DCSP_LOG_LEVEL_INFO=1', '-DCSP_LOG_LEVEL_WARN=1', '-DCSP_LOG_LEVEL_ERROR=1', '../test.c', '-c', '-o/media/evan/NewVolume/ground_station/libcsp/build/.conf_check_7497c5620f03feadb3d79f4705d343d2/testbuild/test.c.1.o'] +[2/2] Processing build/.conf_check_7497c5620f03feadb3d79f4705d343d2/testbuild/test.c.1.o + +little diff --git a/Program/libcsp/build/csp_arch b/Program/libcsp/build/csp_arch new file mode 100755 index 0000000000000000000000000000000000000000..481f40a02897e518549d2ca8dea4e8abe1c903e8 GIT binary patch literal 93424 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≪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 F{|V)%Kvn<% literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/csp_server_client b/Program/libcsp/build/csp_server_client new file mode 100755 index 0000000000000000000000000000000000000000..45f96799621a694293e9ac4deec4bb086fb9da3b GIT binary patch literal 339352 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 Tc5>3Ef6y4Ke?mebaTxr6827!V literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/examples/csp_arch.c.6.o b/Program/libcsp/build/examples/csp_arch.c.6.o new file mode 100755 index 0000000000000000000000000000000000000000..cbf77017dbe9257791506ada0a3b05fc87696f75 GIT binary patch literal 99912 zcmeIb2bdI97XIBmLm0_PL{S-(FeqtYP!LgqBt10xe~0t|?NA}R_h22{-M zu4_)~s;jHAX4f27UDvd$uCBV~to+ZZI&aV0r>6#I|MPs$_k17qKzH3=z4hL6PE}Wj z>ArXM*h%9u;_(=kcPj9>|cJ z+^zo(*4y=t#U5>{tML%1Pp~#&{pYsBsP)gO&xG|qF%47OwFDNca9FX0!@_?R2ty{zjE0^S#lrPLrR8*8#|A0hILFtl`MCAa@v!J4IQUAhNMWQl$#E9%MGp6Q`ojyH(@|4MA zV_oOu4j-IbItsIrA zfdl){*8Jki3Q`R63hZus=hp69NxRBc-BY$MsjAReC(oKRDYlO`q#^??wfsa)qOe*{ z9#t$TD5*>YfgE3*s7~Zp7OzO;9N#C@YgKD;&{6uPqC_CcIlgapucZYg)rr2@1B3nb z2uzzbcGg%u4pXL6Cw1&HNa}&ZR_{(>6t#V6ird*UQMTO(ryNG%)uB%hudY3QMQka% zQLzV8|B9*Dys3`RwpX`0c1h31A0gZ6S0v>3tmD}F2&D$WiK53lm-4P-*Yrqv=RxT^ z|B8s&A*^kwJQ`~93+2LEmB{H;nmnBjpEYyrk@Q&0;czr64Kh)LMD>SSw zGs|DqYr0=bbQOux@}I@GsYf1YU+e3)5juPNS759SLO7o`ZJgAjonxjk^ZN4JEpjMlCc!|Hl%Mn~G{ zme6M7${t-bxGq9MB*tB~V>~|6ShobmI2>KioYZ6YGiORC=`Z{O;i&bGj5_I&ujF`J z^Worr{UgEM1J5;&#ny-CPyh}Y_V3Dilb#wGn{EmFIO*YJe}@cvyMDiEk$$=*@Y@!~ zy1mGzM>^@2&?(Gx*sJx&G$YbUw**eXi5;v>Shsb;`iJU2Q)WjR>Xy)E{acS^wm|Ft z;K8F0(qG-joX9?OOJK8hc&z>h#@t8`-4b{_mf1;GC#-)fXxV94fA$5DuDT`g3G>yf zNzk0I{xPX(u)4j+@`6Zn-C}NGu-mg*7-^+jLaU7>JzB}-X8l_e)_?k|;#(AHs#^k! zdmfiH@k3F!7iV##rEUo44NMGIJQ&($!(h2zX ztji*;bxT^v$rEdPzDpu~bxYujqqO$B%=*(mKGI9KG|a0a(o46b<(s^YZ0}U6iuBbj zfiIn%dWiJVAMov2FO9U;EomX|3AjDqnn+*WlIB|kxV=NaBGOm41itdr-6~%HK|dkV zMYjYlRM4Qky}(vRTI!Z$U>WrXc4DN9ZV6mcE*jg5YE`74Zb?S9oyW-PNEh7_xahTZ z|a~8b0ht9OW^nGPml8=&2&qH z@;pD%O1CsHuFa8Vx+O46Ic>LhYHW%0(=F+K+kF^Z5^1Pg8dSJTBdv5xSh%edft@Ng@B_p1tI3q*eJjq>? z@GdL7i|ZR!*`{x7W0_5w7ME3pu9PB5{n$;}p3>AeY&2>H4 z++??-Wwp5;xS-wi)q`ZUS=J_{x5-VG-s~j*W3M**dX&75(w6|SX5Z)=7F+-E6j{v* z`A@puE?oav*Sm!4zvy~)xV}x-b6UzxtXV9sje%h!9yErAjf|i%GHf&n8WX}s)1Wam zY%~iRM~028_;QJGUf5_6UoDMAVWU-C16~p~+69fOu+br|FB)sYM(6lIX{-qwyTr#z zCB9DF)`pGU;}=Nd^sv!0zD#82gpGdjlcjM{*ytZLt_&Lkg2uIBV_?v@HEaxu zUnBe69X19Bv26_-L*kc6KM#i|OtUS)Vd&EAN=-5>sM>Kb{MYFY}?6koFJ@O z)?cL6`V6_zu-oVnR;oucpf`YajJ4HG?SkzG$CZccBWZn9u-;xZ%}>)l!`0JkSJx+3 zvv$)!THhr%E#rI2( zX0g`CieCSBkaJpMFw>n5QlHj(POXuZAk}!-UyCc22no7waivBTu3n`Nk8t&xTEWe= zf?HG&RK8uy=^uziQ2CZKb=B5q>3Wt_^g+3AA~@Fa2we^K%4xYYAuQahMtyC4xhCEu ztS-3i`mX6o#!n5Eukp>0p9p=z#!ZIOtSqaXQ7oq4DDq8n15hDM@VerXv zyGvG^-YuG1f^GWfRV7Te&A#CkCeXI&`yqB~J4|=mIlEntgJriMx^}%DlC9xt?;yHh zr*=8nq6k*oAE@GRb+kqudpx}negR@)crRV0x9OCZ$O@{`JHLLg3&F9J!MAzb2 zd@!Qyrc{^D2Fb-YJ}aYgb#{DaTzcvr@>uL(TUjJ0PZ;*7+YHs+g!f)AiYJ!dwh|vT zOnmnKr)^61|6|yHJXgA}Jwn;>Y2293jUzL%M#W-DgKnV#D^iUDd0JKn$0 z<(u_qHTMDWX{2K{w_#a{JT0q-fra(@4ikzR=Q;S4<*L%j!A#q+ZG_e=S&*nw4+XpVg|X#HW$6TGgN)tRYT`DXoDo%yWzG}5s;vte0@JT0r2_QtW=keZcm)}Pge--%BnWwoJUS&2L? ztLu9ptBt8y`DXoDZ9GAI8YwIJI-Fck!{t}}1y$r}S*_`btja1zv(@0sJ z)v&BYo|e@Sy^z(psag4E{aKycTYMTRt8*KcmB`bw>f0MxotK)GZ`PmHc|SK^R_8S= zE0L#Vm63z2&QHzCH|x*p{1>Ghn;Vvu z$kVdAxet!jmej0#v;M5MtQMa}%4$o)vJ!b(R;TQPtS(8-$~WuJ>XKRF(@0re(y**V zo|e_o`y#7LQ?v5T`m?%pU-4Rw9?@%5Z5mSiYPok;u24;sgD+jN$`Rg*Tco z?dwSL)uCCfu)9 z*j~zWZzzoZ4wV*ey51bAH%IB$-fA6o7l)TZ2mQud?FOyg7V>M-5`1B$7@S? zgJ{l8*Rai0_^z_CV=k&w+er`M z1C!kCq>ht$V@lk*wIp)u0NHv@k{k9wqfUc-)6Ax<_z1~o4=H+EZ*Y*@o2!)bLN-vS@J9(cQfUAK<=i|b27y& zFFWPC;S03mO#ODTykOJzpXGL+m^>MV%T7-uS2JcOS9khzanYFCHW zt{zmodPs7$^_t{r$3C^I``51KCRf{zs$H$9U0q(gI=^;xaqa5V+SQ|KSH~w;+n-#! zdS317CAF(()UN)%cJ=Ps)vdLwwKZ#hi#)G}i#)M}OQ!`Hv3UD<&o&)fX13|tX4Wq4 zI7lymQ4<+;-;=QiOKch3Qv7I9-HZr?l|*T>^Rl$=-csFnxskW#0@L|7w>p% zuD5RzTlv3w9pSw)V@p^6Z(+?yx2kL`t2zo8kEM0!1Ne1&)p5q88>RJC$6lGSI`aJ$ zVYY}RfB&=H%Galj$EN$h>zAjU@b$^Pb!IGU)c;ku-moE^*Qfn|ybPmvltIqmtnoX_ zpk-+1{|7ZScb>fb*LC=O&JIbJC*!~~t z|9|nIIAzD#pl8Fn9c9omtlv=vEyI~R%AjS~u%irGhK)PQpk+8~M;WvX=k6$jmf^e| zWzaI5zoQIVhRr+5pk>&yqYPSxOLmk&%W!F&uXa(t%0&egiK2eg?UHZ{5%mb6>?+08cA-v>UE2(1au1s_lXbz8 zMdcORk0hjGMz+5NVy)7G67jSBtBNEyS(hMXB9!pVl(o#>@xx>;sf=dlG|L(|yZWfi zWtTU}$b2MrV3T;}y{oH&^(tAvZ}q=2TF61?T?fRA_dQg0&iqDiD)nZ7-prPp_#C+r zS6ywE)twvF|9hiZR!!E~n~rLdp|+X54{aj9uacFcGJ40es*UzK+33+qYi1|q-6fAe zo-Z48CCegdmUY!>OV(B&HG2S@yIgM4MeMvwRtLkyj62_G^f;zFgDzIO?26$dEWY;r zOAb|}fcAnif2%rT>P zha?&fRY#y-KsseDJ!x&&=?1XQSxav)mbu~_&@Q#g%$g+K4UU=19uJk7J8^4w9 ziy_`6pd)9_wPRm&k9qIT^1@e)?xD2CwE0=thPx|XYWNsf?9CQ)lY#VLJO|>QOpgZb zr4;=gk+j%{#j_CHzD#GrqOVfKHXYjjY&Jcun0Pv$q6@gz9sDP5Mamt1s$OJi^` zi`jKFzbckrDVM{l`PB=8iy`K=Us7Hvn9}D{CR#9A) z2zIM3t1MnvmMF^B+4)o*UZG?83rY$WRt8;7oIGwyOnAlOL`7w+pt3SiQB_=Cmfj-~ zi#j0TGfI9%qN=*0O!C+8N6#8JZtV0}eh|`%^0F}F((0;2O@4Km1}xi9SP3mrQC3ir zug`WdeVQCRNPMIk<<()(!4qG8Nn&ZDM6xQFUy>*a@~kXa8m5__Uszr(8J3inEzAyX zQW9TKT#|?tmFH^#0uLQ25$s+py>bg^R0~pcqvv$_nf}3Qvl_VnIbBJhy^~bdIn@ zO|hL)!C|G7-OdOj`T3Pgipw;}B^8OKbbf~Al_Uq{=jI1F<S3 zK~ZjaHz>Rt9Ny)HcS8cp;FVJ>e`%GTk2p*80FRwMeaiGe5-@@#EQ!2Cj z$uSxsuc>9HehVtAqJCEd!w*o8W;EM5EU! z!KHE>f@3*u;-sKs94RWODv-OfYPk%B4Pey7Bs>=#v$*W87V9U=>UbN(j zXAhrBeV&l_A>pGYydvwvW_J=Fje*!vn?MZxm(3*^EfmmcX!uRy_*h(1JuQ#`-0x3(^7z^nDx7Rg>B(PuY2i0v^M_Ei~+jUO}Sfb5)E^X0l;9iFBA23H5I+*P?l`wz_P z6Vg~GeSaZKe8u!wyrx~eYpdp2=g8Z!cEWZKw!~t=2r7rPX{T(Uv0z}6X>Ho+`{qN8 z1@DbVw`sRAV|1G?8!|_=$v(Bos5Uukn~rO9Wju3k+cr6ZMz!f8lF@Ba-)5Ub?VY|^ zZ4&!@TP>+w%hdOabu5|smavW`Gkh17wk1>F47#P2wBw}bo-*})Umc5lic<%bH*4X1 znQ7ZHV=^8_9ZP1cbsbcF+D7p95xiprm#I1GSTe&II#afU$3DG2-2+wAw1|2cmvN&~ zmVJ#+N})K9n#PJ9A7c8`96!MLHI5%_{1L~)bFyjdea9!7K9diuu*t@|J05lDAdykPt_$6q!6mE&(3?;U(#Q|t6E<8vMV$oOW*KQsQQvLOh47}PR6Sp-_7_Xj%OQx)bU=%|KoUH;~kp?i6n0Z86WESP~(M; zA7uP&#}6@nx8sKz|BvHSjqln#8A`Bngz-Zi*NvIUXVKby=8C=pJx^g2vPHu6dDJg! zBKYPA{+kGXYXtwJaCvVYK9@`97?@12BXz~|n(z+ve234y-;B_I5y9nSkUIT$iQs!h z@Z1PKJc3V*;4>rmF%f)G1lPIR>#E!75nShfuS&;NT8KyV6fjT#k=Z3ond*ueZ^mecW3y8Tkrux z@YX%}U{6u_KHk5j$CmK@a_z@j%I)($T@60M(UrpRgH2rx-|W(7H?^NK1ijQYgAW~Q zci~R}LlJ+HS*x>8E6L1%ei`mfAB=|Y04b&rB;TNiP5T&8dkO(L;Jqz*03|T>eA9zpU$`TwnWxk5VX$`gD;0;IkFVqWY=wAG|=JEZ(PAhy$*}k3pYn z9Qh(nygpE_@7|yvXL|MLe05zH_&|?=>y+zzd+>!Smc{#&hB)bi`Y$7{?;7EAx^eGw z7U}gk{$lmNhAMlv_ond4BOe`P5By-#cO^cKxIRXp zKb*Kso|XKhBA@*Ed|nWt$NN@|pZi@#`YF`!sl@jrzL7Y`c|LKD^BUt?Pmc4Z2>l(z zx!?PVbDYnUzrNQ;-QFU7H{$OT=lDM%&hc*}e~!PI7E%_yV|{Dl+^@b~)bfc%O`yg@>xKf<1Z!7@vkO-e*B&qq2EZH`@N7j$A1<1A4PHA zO8TC}?;_6e-%p(5e~$b){=Y@&-z3ic{+l?*{|));XQDV>P4$4tqIYxTKX@nOdj7C~ zSK^%4Uc@=CJmY%Dc@2-yk0#FjP9n~E9Z6hY%OU=J;vDA!;v8pS4ZeiCC>ex zL!9Hh+_>Ix{eMe(UB&Cnn~CddX5{rp;+)r?iF01h7}q<_>*Waj8^pQa_la{}UmMrE zxfCbLl!-+a^yeq>Oh?H+LbuxwXbpY=e!0*=!X&Ke#a2!ybdG(V=2xf zNZ*I}F~m9kBH|qXQu62cPmIu?LY(_Oi#W%BCHd!5oHvkuAL6$Y=lK6boa29z{5k#? zBJ{5j=YIc5oa6tJ{5k$#NUwjh!uiv*nKWea&v&hebNqW6_vcT~2z_7T-0yzGIsP%^ zKTqO9oRdl4m-sB=T>rVmIsP*8=lWMi=vNZweorON@n1sz1r+Bsq}TWC$m=HJ9RD4} zIsQk_&<`Na z{SG6}@lPiI`4s0-q#rIr($_*F@+~BhLM9BF^z&O#a7EoWCReK;kzN z=lK6Xoa29l{5k%oBJ?j3=YIb|oa29w{Q3I-IqCH?BAh?p5$E`~5$E{ZXUWd8`17ZW zaXmj--;Fr;+lM&Ee-Qce`9G2LgQO3{Kb1JgKbttmQ%wF`|0NOnWyHDPlZbQt7n487 z|69@zruc6l&hg()oa29({5k$7BlIs2=YHQH&hdXv{`~m;iS&6Cf96iokVTI>$KQfD z$G^LAfBx(pq2Gr%_nSwYh;y9R66ZMYG4AX9mk9mi#JS%Wh;y9pl0Vn^6VmTb@qa~}@16qzmsu)o#{%P`|U}b;~z|XsPu#L;Q-pvkvKZQ8= zdlYfbtC0K?(m(PlBmIHItBG^`D~a=QIg9)`{tF`XmlEfGuOZIy|AG8D{s%}ug5rOa zILH4qagP5j^5^*9kI;WYocsNjILE(@{1;H1Em}!K7Cj#hlK(g^?TK^zU5Io1`xy6+ zi`)qPP~zP0XyP3I6!Pc#A5Hp$DgFZD9RDKX9RCXP=lY)%p+B8C_j@jJj(-dJbNzou zdalEb#5w*y5a;+GA%BklsR;dx#JS&p5a;;cBmad|=g&w#lK8j8IsRXWbNuaE%g(a+ z^Jf?1{(7}1@sYA0&f6T~9RCpVUqt$mq#s3mJaLYHGI5T79{F?q7e?sIh;zR+#5w+x z$-kK5+(`P-#Lp+r@n1rm2=CeHDXC4Y{8QiOg6 zaqjmR;vD~RN!vT>(Vp43%EVR1Jakc_S?;T^fL!t)JHi!Kh@Xdx`00(He-5C)&>0cO~dwt z@Gi-3Hh-;^F3{g?`Rd;Ubph{ZdVLPk1^hwNYi)G_$LGa0Ax`qC_PN+b$M4k>NtO%4 zyQF?aJOsaY9KTz5(D6qs-)9_u+uE-?-Z?V_?>l~j<@JT*r&yf7IDWMG;P)n|!z8O) zXUhZp9@~F!#|y1K107#y`Vo#_X8nfWm#?k=52l;#^jBNE$nnq2|9Hpuw0KrIzOU8c zOvihg{vyZm_oUxBo@e^o9q(iHf534(-thYx)N_j+cl}|-3?|A9|?YiLz<*=9 z0;eBk=V7Vi_&&{zju%@!Z}Z&xz0Yxcui^>EM_OLU8*yG{y0@Jkzq7*kYM`$U(~o`Q z^t)TTy~PDRerJW>AAt|G<1)bMTUdSYeHiFJuzrU-{ct;PMmheT)or}v_&yfCCj>;H z{GWAvhPD6h_#M{or;e{O|L+}NV&@gU$AY{*v-;z434V*kvxoVCziw?@Z@^cX&k(2o z+Ts}H_+iEmcf5n;b(G^*SUndxewW2r>bQLj5?kZ=GK=#}$NO1*@cT97)!F#%PXDs` zJm7eZ<@J)|IDT(AE<*tY%NLI0dkMcdUS#!YY5gP4qpaQ8@o%jyGq48>^vE~QapXJF z@k)yW-}itI{;rJgdw{pFx)nH|q1G<7drjZ0gZS`$5BR)h$9)ay%{tIu==?9T`dmd^ zy|7$ETwfn9x6W@Ru6q5fS(iT&SN${A#=UCwe}(+l&>|AaIGr zJ}0jIZZ-Xn#8r>iZTR7VvOsTjz;#-={ttiW7>l(vKj!kLT+ur^oa3a^u>a9`}9Zzb@xFexSv3E%|62z7N!~*zLr% zZ+!ptF5;?x#(e%lT=j2R{CGd1O!ebU_ngxg+jRivFXBg>Upf6*rvKhJ^o14=zF(nD zJq7Ul?cMFc0FK{#_aUzDAMrlz0OGoOg83gtT>as5BysjBCa$Y^9kR+e>Vx{9PF%O$ zWBG0*&h@{Lxa!|G{iVdY{?`y!{StfJ-C|tR)K$d!SEs+g^v^o|^;REz&jEEt{l6f+ z)(yXt$M+dj&vk2;B|sL$^Pu^6C(b_oiL=ka#5IIB%x9)?U;kr?>$bmGzJFu0A#9gYOUc`s4cp%Ju)_mhUk0fgabNF~oJ-SEippoa;ZG zxawEgbp+oxK>ZQtQm6lo>G8b+=&!K6Hkn>I*Z*?IZ&raUHxTE#{h7Gd?Jo0wnz;JI z=XK)j^B>~s^SJp0#g#VdiR(`b1;%ytST>l*6y1Gt-k|ozT z>WMffIsNsfpXT%!Ct@LSu78!|c%Od~ajx6B#I?)jc3s8a<#BxBb1UiD=P$(7r-S*t zVqEXEKB)iO#C7!*%lAFvT>t+P*VPPre11io>;DUJUEN^%=JrMa^+%k08CR|Tzs>Z$ zoqm|*HG(+T|4_$2wex>Aajx4U;#vazUAZpHiK{<+P9@Gh7ZO*Wx#n}Dam|VAe z_7BVVUgBK;M~JI_Cwsj8l{nY`CE}_-&-DK=j`}0c@0|W_)Bo)BYb~#i_5udyC$9h5 zj%V3*pdWFr+d;&&Zu+}>UGR5j_`_!|>Di~0xccDz|H;OE{WlQTZU3@-HxcLhUqW2< z?es>LD~WUcuP3h3EvCockx_rd`Ha&)V0!$$82Xp2J|CJM^+El=aUA3CWZH-Is^_|O zBCd7&*!+7E*Yh7fgNU=w7~<-K&o7QNuIXrfaQ&H2T(|wl^2Oh6p?^jLmgRV--^I?$ zrNp`ZYly4YRiniF$p1A7wwDSyqCxt)We;wiU*P1@x zIO>l$S2+FCreE#!D=jbl-BW$I{#TP;`5?Rg+(Mk|zm>Sw?R@ipo;drwNt}KDOI&^M z_m?L2_dC=F^>0I5w|#HbKN!**SdXV{=X-#{_wejIQu+8Tz#^1Cs|%M?(6?A;<_!k zILY0I#JT=o5?4LGXYd_yu75^5H4R_OsQymfC`(J@s6XQD<@A3y{k~2=!15YJoa;Z? zaeQtwhd9@*gt*piy!oF$c`r#|MaW{huJN`oX4u zhB(*%RpP3@&-CvYNBt4!Pfq`?>Erf?bLdxCUb_%igy-KLj^ppVxx~3{qls(X&NcrT z#1+A39&z?Lp1As4Yd)tM_w_%Ac(Bd#zkoQ`{|e%&Kfv_ACC>G~nYij7HvL`3QBTDA zg42I!`oB5-vzFH<#1*0bKRAwY0GoFZku2IT*R2b2t=k9Y--oy&`0PiVeZ~`4AABx6 z*SN3$0^+)DXN!9=ajt(gan+A9{R-k-|5J#o{z=nsG>-Zs&TF0iGt=MX^n2O+?uUqT z{hxCj<1PM!IM?k{;##)@%zqnk^@mTZj?$3DAICk2tIuKPGsw8F|AEAH+wRuiDB@iI z!-%VXg6XFc=lUN_T=g%QzR)=8k2qI3{kNuH>+}_t*TuxS{?|B;&nx~woa_HEajn}K z=KnHr^@q>9#M$Rd;_8FXud;NIAX$9pzgV>R&Vc zFyp8{;+*O9znK0gr~j+fr<^#~f2HI2`~7<2T(>R6wQld4{|&^|A3k>zXP+mCtIsdy z^QLiM|9=zLZTndJ6XIO|Z;7k^2y6dDoa^7rzUZP_{r|S<+8Rgw5$8Tm-_+UzoF3oL z8B3h&KizSR)0$75>$Zfr)@_8|$Z`^K^@q<{#M$Qx;%ae(`P^Y#YoPVP>;L$Y5L zKSZ4C|1@#cA7kwoh;#klAg=lkto@$dqyC5!Lo};a|F`NaH?lOfd+1NJyt)$S`sX-~ z@o{Cr#Ev`17GmL9aT>tZl>$aiRzL+@I|2M={k2tO+ z&h@{YxavQ(_PutGdLqtOoWA2OvXd--clswRug{5d{eN-%LHj(XrTJ;UT({kctMxnP z-;cQZ!{-3v>~k1#wfNM0<{9_(KaRL=JJ{Og#JT>r-6B+G41zq5T#`xtSq|4WX)X7zuEIM?k9;##tP=AUW(YnmM=RbOH4nZ&vN#}ZflPu5;&_ozSOJlW~H?4?W1Jp;->oFh^WsuG?l>zMm84`u|8=^=nKY47Mn3_~Y}p z7Peh^@V~39$kNd`>W?`4JN*FD4|e)&`#Z%%;#~hD9LKoug~YjTRm8P!L(P93arKAK zxy0G$H^kLvn)%#q9QFBLw(0U9aosk@@_mdr*Z+Cqsz1&2uMp?+|83%`Z?8Y*kmW<; zs6XOtVt%UC|NEJKC*#o9SYF+TbN%}|j_)rHBhGa@l(^RI9P>v#v|sgy&mz*Z&vN4G zbD{a1Wn6R8`k?+75!Y?=E#J$CbNzo$T=i#}{zl?l|2v7RzKaGc%LB$yPsI7U(~mIy zTTXw!<@Ggju78Hbg}Py$gSN!EZrQ}OZm*bsE^+mT&q2i5X9{uk`N({VjQjeR5!Y?S zmTx6-uK$U|Reyo$PbSXw-#}dT-S(6lSuQY+`XkO;o&FHh|Iz8&tC=iM66gBA>iF~a zdH#FExo+PO*ShsF|K^q-jw5_J5oe#C#MNh@`5a(en_3^7|A!FQZA&cQiNv}7Gl;AH zQqvzvoa;ZIxaxa#lN(tU8%O;S=c!JAnCZ`S`q^qG%T>g={x>_0c{}bUuB-Ovrr1-& zwQl9+{}1Bo51)^Sv(Jyj)n|?Qw6i*Clk2}5aox7e^2K=yJ^udH$LW7#`u@bZ{zHkY zSHEnzk!6%|)E{xqb^7Vqfjm~=^uJd#S(Xv!`k&%B=118?oa=TqajhHv?*9kk>JOi- z#M$S0;_CCL#reK*)D!3bXT){es%*KDsrHKAVZN&+mz= z&z|Pi;Nl-L}s1eUdoW|7GH;zs>Zo6X)~)U&K{Ed@s3?029zeyruSH*v22K*urP&j{jNx5>n{ZpWB^K5_MjPYH4MIgz;fEH%s zEwAs1bN!pyd7*mcm{+MIajshr;##-s&3_1S_8Co_eP$3>pFf+=BIBBq)(7W*1##VW zp5?oYIM@Fq;;MhZ^rsT%`kzBw^%Hx@jVu=%kIOp8d56=Nnf^~s|4+;7S>jy(Hyp?O zRUZ=Py8S?0*7pDI3=|Y@+`Vd#2=Jo`Cka1uC3B+~V7R&c=;#~jP#8v;O z>E{yX`Y#}^`l&tTMwW8pnit1;hSOJ@{%oi3Z+ZQWIM@Gn$1zXX1H`#*&k@&n#+m;+ z#MK`@pAu)EZN$}Qw)u3j^VHXWPvW}mD$93o;#~iJ#8v;a=?4+#`X5MK^|O1)jVxo0 zqyC61eZuKiSzad)=lY-S_xx?MwD>$cha?;@@i@OhXx`@BqCeXcg2 zkBs~Je??rkU2FM%Pn_$YY3I9Y_5Vwz&mzwC??7Dj$M%*RS-KiW{SoJWPQTXl!=3&K z%WE2OuK%%)JvF~Bg^N;QGdkQs%N-ewfg@I)3-McJ-#p7o4D2o z-#^K79PdGNW7_V_$(pLJ|_`ZpAqJ>*|_G!^}mw1ZoAX+{T*?x z|1HE-|E}rpAkOu_pSbEv`pAtej~Pcj5$C&3zsd9;IDL`j^)vCN;*0vXu*aqPE64B3 zcOlMo%OS3HTWS8oh_lZ);_QR#EAl$Sd`e93>%Ww^ZoAL&J%Kpae;skve`xwMh;#kV zC$9R+edI=#%Z&Rt?{@l&On;x#-)4EeNSy2cw&VDH=_kawZod%M`afa*ZF>jd2CtLV zA3nPiXP~?F#UN>|C8l)9dWMzosMI^(uat1-CiQzT;l7bNyzdZarKAK7sS~o)2;`| zYcKQZVq9yW2=(8KxNdvW^6gDr_4xcJm$>S`HT{0XRgcdfMiN*3Nqyx;mWjrFoJCH5 zjp>V>exl{InmE^ggX5SN_G02(x9f>({R_cNBuu0uKKf0|Fv<{A91$ZN8Q3>tNJ@kzq4`ZKhjQQ*_Sxi zf2iZTYB6LPOPuR=1aXyS*!Qj%5?6otR1s&Nb;Q*NzpvP0yoECPkNW?XxNdvf^1Y6@ z>QVnc5LbPx0dgbD-NaRo`aeiq^_xxqq;b>}alY^L_nQ7cPM`e!hF$+~e&Y2{8^@$bB`W!0%b*UzqjPGjKIn?Js0mf9+xVZ5W`bBt#@KHqph$IFb5bG*{{499goYhC6!-X=5TrH&tIe1+q` zGrr03AB)B>MxTt|9)NC!q+o&LY}c>F7I_4>e$_p{C?J8+Tr&BW~?6m0pDxb|z! zSgS$dj#>xh!^37Q+c@GMX~Fi2(2sC>ybc*pT)ndGI87q1^}*|qBZ#ZM#PoBBs~(T{ z1aZ~hZTd3f$m<~4rpr>&+bJ0Eb;Q-Di52J!=QAfz$6{9!*E-u_k8LHcB}{JG;8*YE2H{*&W3*!dG190s5{X}{pj9e+^^B}>Z)-of!<=HEGj@8S6G zL;G0w2%h8kU#$*(Bluv)pS0(l{Ui86j&HE*|L6!l(ebyfK8Hu}nT`*(_>YX>`HsJA z^(lR%SYs~tD{*zyRz#&KK+PKn@WIzHO!e|7}l?D*NH-x9&Ea(rj2|L-FB zjgIGA!na27yBx>s$$KOCgN|=9|3@SE(~i%#e4mftuR5M%$M=m0{!hoBGW`b;{8PuL zSv|jq;NLrr*QGy4@Fsa-L2#Wp&7OR+B6wTJr&)bEM)2Jnx377`_Ke^?9e>{*k9{Ke zK*uN9@y(0i!yTVs`5qj>4{>~NJ6;naxOE?VK5Q>B17t4~lia>u80%;|=wVeocvr{E z?TKobhANW@|j`w#f96#31!wVcAZ^!F0$EO>=HiF;kc$wwNcrY#0aX#Q{9LIRV7>67_;O99#UY}sRPw2t#c6y9o{7?jc(($%- zop~jKzv=j3(|;JjKX-ha=`sGOZq~;mcqgkXIKFq;u4@>#6+Za94!_p~ z$GE0XJ0FaXit${bhtH>^*Ss#Wc)lmjb;z*CH+-OP;rMmtvvUN;IOp)W&Gb2>=YDgE zYn;#zbNnynb4UcAhE2acvPN>Q+N~jR!s$*VgMVb9#((do6K3?ieo?J{ZUK z3DRr7UF~s*@y}JSK6u{3II`a7Yv=R13Utw(WzigazK&mG`u&J=zXuc7exb+bUdZcC^O^4S;72=-x+REnzZl0C{;1ojq}O=hgYiYY z{syPN!s5J>xE=}|cZ`n4%Ni_lMYyqP^e9TmX~97o+sh;zRfKN$5v{V`rT zID9aEFgWzLlfSNFT%G%f^Kr+xyzs$zxo?tQS21oa{@$W`_4!m+WWjj7-lv7VVFvGQ zb;CFZ%DE1EM(BGvKGb}2Bls}KN1FZ+;@t1y#5G^&XE~17XY(TXBF9m;O5)rv#w|vD zQ2+Bu&-KT+#a{m>r^n~Rn9p7HeB3b}Fnlmh?|aS%nNjR!s$FWKw2Iz7fuev&vJcZ@>}AB+$DG3m8mjMMuqarNnC#~tGnd!H`) z0i-P8c%QI0ajrvO;@U6td5*tm^*=a*k9Yj7Hy{{E8mS_g~|jPcb~&&M6(B72{1 z_BjW5FZ17rIM;tLaqSoS;g0WbKI0u^AXezfB!n9t!6e3s*DO+Sw~_ghR{6*F)p>&zwGoFr}}N;eB3eKGkh=(bKJg{0sfKY+lsjQU_4}u z0}VZV`jKAa-)cTXiE|xB5oi5G$DcQ!nGt-hoU#f*MZZ{C;elhO2uiI0k*LdKAamT&>bEkjS;>5V|s#k>Lj`6(V zgK@U^XfGmJz%kx+4srFl$BsM3`Gy`o6G^Y}<8#=V#JLW~5NCbD@$U9{;*tnn<9Hv_ zuO-g?ZXmAxLVv#F!^{Wc%p+g$-#b0(b~|zI7vr772X%Xq^coL*Fy6V>f9LcV|2(sU z>@17w`M6^oarhi&dG#Q@_KR`02M|{ud>)AL#l6o|(yPxr^PfYU>rh0T^(BrUZ$8T+ z_-eb{uv46LIbr0_S{U|e(WGn@44gWm(rC(drg?Q z^(!3jVLt03_(sS3n*Ji<-0xMyRSNxejvr_~cSP_%JC3?NMx6V_xbnVk7~dWoJ{VUX z9LKA*8y6kp%y%Kq#~tIf!w2K24s2sxem)C z^gNEeTC6mm4Neb!zT>Bup2xT6ey@$t-|G1J=5ucZ$GG>X1M2n+>A7EwXAeE<|6kH; zm+--O_FmtK#!FZIi56!!;(XjOPCR@te)~w$s|ChUKa9Bg;PZ2gAMbriNUuJ3Sv<># za~;+YXZ`7pKW;wfMes`;f6nyR5a)hxA+A#B?{fTY^La3W|J8BS?PcQJFUHaLb^C_& z+9iB2j=tA-b>psMT>W0e`M6_zdiZ>5d5tH%B8=ZYow)kEW{-D_Tkm};Nv}Sc_V+xD zZ?Af;!)X!vvmNhbK3gLA)sF9O`kRPzzjqSXIHAAa@xJEsL{87Z!2jj+LynOGog7oS$$Lh9@ zIM?AU;;i57c!~L36~V7_yvp=<5a)jHBd+~I|A^zKn9p+&{8h(Mw|^4nelc%=uUnH{ zB?wu-;e&Ytz;V3#IDM(biE;8(&&M6(@xuq>>K< z&j#XLhYN_a{xZiOGoNcC_^pmVYx;YMbH5K0*M6aY%JH|%=Wh}GEyq!}kBD=>n6JRs zt)&~k9X^<^!0QJ(J?1YMPMnWB<^h1u_m?{f33a)d%C`V}1bdb2{nOr;Yvn z{ygGbhf9gG{(;?>_+Xv{uixM4F>k_X;(XkBynU@R<^?Duy>g7tUq)PgFg`!#B|tpzIh*wAv%u=M zg*eyYH^f=F|7`Pl&*{NGaU6B~jyU&= z`5EAky6tK|!~lm6=4Swhp2z3c_-icAiR8n_9rGT*=R(sTM|$=0yNw0Old;}|rs}KGTj(Hfo z&t;@npKVsRYl-WseLWy{8*$eE$#HzI>){CQ$MeVcz5YgeT}8id6W4yB|F`2g_C2I8 zBe);`A9ZVHYuK4YzJw-Dz#+)bSIJkG!JBh2SXrw4!0@ncQ@CUNff1LEor{eK1L@W00`tFG3D$8o$09LGE$CB*r-V?K?zdx zo{Np7SC086E+Vczm~R5}Ybd=SC^>-fc{ z|A9F7o4L0HCkx_-zNO>%eskvtj(G~;gSz!0J@<=wPM}Bq4<$X1eeYw+P-jfx? z`M6{L5cpvJkxNLg{bGKNYly4QC3+(Z<`wZikC9$|p11nHK%DFFcjB!7r{nLM&!-Xm z8^=E~eY{5yZg70L-xkERU+6I(0rJB4%lB}4@ScvNZUc#PznEVI{;2;n(sTXG9EX0X zm>Vx@2Fpmo2fzQj%r^M>^HgT@Q zhr~4==s$P-MDzJ6f;Z_UJIjK2)|tL7aqhPZaqSoSY{xG!pM4|vV8>CngNSp#e!c_L zEuZun4}3764Dy2h6sO1hGG`NSDn2;w*AiEM%%5_rG*S|?@XNg?MA%0_(9*>as2*dPy|1~anx-r zaqbuM*dTt?Z2{?D52Od_E=4b@-Mz>$f@H(R^Cuh^Z{-7rcYxT}{6SaqhPlaqSoS{*Lc!KEopT zD92H^NyNEd%%6k!QMXdkYdrA5{5f8KuG3>aoy&;xamTzg@WFgB_mf`xU1|9~L0o-? zHj^7!Fkg-L`H1xDGu?c?CeC&Eg*fY*^$EI39^XRqX&=FNb$qeudl2V-`w`cEp&#P- z3Fb30f=_T9b(=w)`z;}^{i6O=j>Bh@Wi+O7P zMqGU`PYveh@jl;?UVT2Yx@GPw4Ovvrb!bJL^_?95(R{i^@ZOGR+V8{$5$Aq~6W4yB zALBTFA2>OJAK^IaRzRHl#XLp6ZYPtT>wksgI9|VZ{3ol=?Zo-GKS^BuF@MmDj$?kD zH;Jncz7LOife=4@wvk@__qY1D=qn9b{BiF{ob_ED$L}Y5MezQP<9C(Ah;#jU{s`?C z`a?;te4fQWD}o>6IO?{DIQM%JarH;t);kU#%#Y;je6!PIzN9}9=i`ofhv0+xfLUt~W0BKQ!;uQdHg;#~iU z#I;}Or#XJB`OJ;rMUJCx<;1yP%**8Kb`I&e{x>;}^rw2dK@y|^^o;deA zmALi`{gIBx?f0dH5qz=ZsM}KF+%M*XLVZxT3rVl>zz6d|dHtWA9`i#zMx2lP+r-r$ z^B?`&am+*XC2{pRRCkgE^DiMD_;eZ&ZU^7n>eh`o*CB_vT0=k3@jUYx9>K>rexT_m z6X$+s6W4yB&v$&1`5YI)D;!7NP9)C#Vje2g2X(ug^coL*Fb|d2Kjid7+J<$1hBzO0 z%*&xZ8KE?|{V(a2+t)#3KSc11f#J^Z8E#&fH^cKBr$55lug_&CD;_)Lw}G_c!J}2dH+eKx394W z&pUcPBYrDG^7#mH54HW&U*kc4BOSM|&&4JgcMX%RWC7Al$c+=Fu%BLLAmT5tQX9mUy)dv zvbm(ZFr{5kQBbxpp`EB}xLX~lq_`{rSBWFmzp%WtG*KpTmX%i}`j4MHtDgi@xY&FW zi}Dv#6qMr7ScU$#yKLD_j|I*zxQw(F--#Vo$YNb(t%>{}nIz%LtC!lnaXrsKV1a*Za0!CX@}5|Gc38>Xef!)T$0XV{P5nZ#PR6j|X^T zKeR{6N?rB4^)ge~-}SU!+J~>-k;1&E?z!H6=QI@$AceAc?F?ac_WzeaE?;;F@3nvJ z+xK52%zNq{uN|hh@^?0VFiYEOm({^^zk!qWR_^UO9=6i=uaFIO#=mFSQ`WKJo*I8k z`S0UDO_+~K_n5a@Z`03fuRU2bb@hMu%1}8WaFOrH%6)73@B6<*nD^9OuC)Ho(FQGE zyIHo?)qm{7P?>EzX#aX?_Wj>1%zFxo4P2wQ@;SLXvAy;>(bUy{_Nq{c=P~WSz5Mt6 z-y=+w(8+4B+<0nufAV%7e~*Z)uKoL;74B~z--Qj+Y6E#ZL+i@19BKQbjeG2e_CIAs znLEv6*nbU#c8~ml-;|ZQ>NnNuH^GEjKmExn_Sd#9b@i?MRf~UW3vGq3lPAi(-+w1z j{@SVfoQw5Vet+OL`uz2nI!UnKMHc@jL96!0@Be=Qtj^?d literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/examples/csp_server_client.c.5.o b/Program/libcsp/build/examples/csp_server_client.c.5.o new file mode 100755 index 0000000000000000000000000000000000000000..86acc85168711f49d8f6906eeb6bb085b3daeb50 GIT binary patch literal 35520 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 Cx~8H4 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/examples/zmqproxy.c.7.o b/Program/libcsp/build/examples/zmqproxy.c.7.o new file mode 100755 index 0000000000000000000000000000000000000000..69fe3211ab7a9fd90aa71976c76064da16a92749 GIT binary patch literal 24472 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 literal 0 HcmV?d00001 diff --git a/Program/libcsp/build/include/csp/csp_autoconfig.h b/Program/libcsp/build/include/csp/csp_autoconfig.h new file mode 100755 index 0000000..538232e --- /dev/null +++ b/Program/libcsp/build/include/csp/csp_autoconfig.h @@ -0,0 +1,33 @@ +/* WARNING! All changes made to this file will be lost! */ + +#ifndef W_INCLUDE_CSP_CSP_AUTOCONFIG_H_WAF +#define W_INCLUDE_CSP_CSP_AUTOCONFIG_H_WAF + +#define GIT_REV "v1.6-9-gbf96d6f" +/* #undef CSP_FREERTOS */ +#define CSP_POSIX 1 +/* #undef CSP_WINDOWS */ +/* #undef CSP_MACOSX */ +#define CSP_HAVE_LIBSOCKETCAN 1 +#define CSP_HAVE_LIBZMQ 1 +#define HAVE_PYTHON3 1 +#define CSP_DEBUG 1 +#define CSP_DEBUG_TIMESTAMP 1 +#define CSP_USE_RDP 1 +#define CSP_USE_RDP_FAST_CLOSE 0 +#define CSP_USE_CRC32 0 +#define CSP_USE_HMAC 1 +#define CSP_USE_XTEA 1 +#define CSP_USE_PROMISC 0 +#define CSP_USE_QOS 0 +#define CSP_USE_DEDUP 0 +#define CSP_USE_EXTERNAL_DEBUG 0 +#define CSP_LOG_LEVEL_DEBUG 1 +#define CSP_LOG_LEVEL_INFO 1 +#define CSP_LOG_LEVEL_WARN 1 +#define CSP_LOG_LEVEL_ERROR 1 +#define CSP_LITTLE_ENDIAN 1 +/* #undef CSP_BIG_ENDIAN */ +#define LIBCSP_VERSION "1.6" + +#endif /* W_INCLUDE_CSP_CSP_AUTOCONFIG_H_WAF */ diff --git a/Program/libcsp/build/libcsp.a b/Program/libcsp/build/libcsp.a new file mode 100755 index 0000000000000000000000000000000000000000..09dc115fc4dbe6cdb57405ac8d549618ebf4a867 GIT binary patch literal 782614 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

    8WiVlHEzQj>Vor0SFl1zS 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

    dnMIB+EiaNqR6?KGtD(XnKTTIg0b>uj=f+9P0 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

    ow3z!1h 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

4eR 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 aadz==23ovDWoPGki~8Y%l(O_&)c*kTh-ygy literal 0 HcmV?d00001 diff --git a/Documents/ImplementorsGuide.pdf b/Documents/ImplementorsGuide.pdf new file mode 100755 index 0000000000000000000000000000000000000000..212c5a6325624d64456169440e6c99b720f45e25 GIT binary patch literal 1893185 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‰Z*4^bTqVsQtFCiz!WO4Qj739z{`P%DSx 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 pYibNqWAE;aMyK=xuw3Qd(7VgxFesY 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

u;b_%m1w>npTOZ22dacFAZgy8!w)SVc47OD( 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 z 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 = PACKET_LEN; @@ -150,11 +150,9 @@ Protocol_state* ssp_connectionless_server(char *port) { strncpy ((char*)state->server_port, port, 10); state->request_list = linked_list(); - state->current_server_request = init_request(state->packet_size); - state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, state); - return state; - + */ + p_state->server_handle = ssp_thread_create(STACK_ALLOCATION, ssp_connectionless_server_task, p_state); } @@ -215,7 +213,8 @@ Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state) { -void ssp_cleanup(Protocol_state *p_state) { + +void ssp_cleanup_p_state(Protocol_state *p_state) { ssp_thread_join(p_state->server_handle); p_state->request_list->free(p_state->request_list, ssp_cleanup_req); From e2c2d7ed7807290c1100bb4bd52c5db27c99fbff Mon Sep 17 00:00:00 2001 From: EvanGee Date: Fri, 31 May 2019 12:27:00 -0600 Subject: [PATCH 057/400] give server and client unique exit functions/callbacks --- Program/include/file_delivery_app.h | 3 +- Program/include/protocol_handler.h | 12 +++- Program/include/server.h | 13 +++-- Program/include/tasks.h | 8 +-- Program/src/file_delivery_app.a | Bin 0 -> 151170 bytes Program/src/file_delivery_app.c | 52 +++++++++++++++-- Program/src/main.c | 6 +- Program/src/makefile | 6 +- Program/src/port.c | 1 + Program/src/protocol_handler.c | 1 + Program/src/requests.c | 3 - Program/src/server.c | 20 +++++-- Program/src/tasks.c | 86 ++++++++++------------------ 13 files changed, 121 insertions(+), 90 deletions(-) create mode 100644 Program/src/file_delivery_app.a diff --git a/Program/include/file_delivery_app.h b/Program/include/file_delivery_app.h index 911e79b..54f75e3 100644 --- a/Program/include/file_delivery_app.h +++ b/Program/include/file_delivery_app.h @@ -7,6 +7,7 @@ Protocol_state *init_ftp(uint32_t my_cfdp_address); - +void ssp_connectionless_server(Protocol_state *p_state); +Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); #endif \ No newline at end of file diff --git a/Program/include/protocol_handler.h b/Program/include/protocol_handler.h index 0a397d0..a153f6c 100644 --- a/Program/include/protocol_handler.h +++ b/Program/include/protocol_handler.h @@ -25,6 +25,9 @@ typedef struct protocol_state { uint8_t verbose_level; uint32_t timeout; + //bool for exiting the server thread + uint8_t close; + } Protocol_state; @@ -45,9 +48,12 @@ typedef struct client { Remote_entity *mib_info; Pdu_header *pdu_header; - uint8_t is_active; - Protocol_state *p_state; - + Protocol_state *p_state; + + //bool for exiting the client thread + uint8_t close; + + } Client; diff --git a/Program/include/server.h b/Program/include/server.h index 53239f1..ba198f2 100755 --- a/Program/include/server.h +++ b/Program/include/server.h @@ -42,10 +42,12 @@ int prepareUdpHost(char *port); Return: None ------------------------------------------------------------------------------*/ -void udpSelectServer(char *port, int packet_len, - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, void *addr, void *other), +void udpSelectServer(char* port, int packet_len, + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *other), int (*onTimeOut)(void *other), int (*onStdIn)(void *other), + int (*checkExit)(void *other), + void (*onExit)(void *other), void *other); /*-----------------------------CALLBACK onTimeOut------------------------------- @@ -59,9 +61,10 @@ void udpSelectServer(char *port, int packet_len, int *prepareSignalHandler(void); -void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, +void udpClient(char *hostname, char*port, int packet_len, void *onSendParams, void *onRecvParams, void *checkExitParams, void *onExitParams, int (*onSend)(int sfd, struct sockaddr_in client, void *onSendParams), - int (*onRecv)(int sfd, char *msg, uint32_t *buff_size, void* addr, void *onRecvParams)); + int (*onRecv)(int sfd, char *packet, uint32_t *buff_size, void *addr, void *onRecvParams) , + int (*checkExit)(void *checkExitParams), + void (*onExit)(void *params)); - #endif //SERVER_H diff --git a/Program/include/tasks.h b/Program/include/tasks.h index 340f0a3..2f8bf81 100644 --- a/Program/include/tasks.h +++ b/Program/include/tasks.h @@ -9,11 +9,7 @@ void ssp_cleanup_client(Client *client); void ssp_cleanup_req(void *request); -void ssp_connectionless_server(Protocol_state *p_state); - void ssp_cleanup_p_state(Protocol_state *p_state); -Client *ssp_connectionless_client(uint32_t cfdp_id, Protocol_state *p_state); -void *ssp_connectionless_client_task(void *params); - - +void *ssp_connectionless_server_task(void *params); +void *ssp_connectionless_client_task(void* params); #endif \ No newline at end of file diff --git a/Program/src/file_delivery_app.a b/Program/src/file_delivery_app.a new file mode 100644 index 0000000000000000000000000000000000000000..4283d633a53ef5066ca68a1c066d28817a0ff4f3 GIT binary patch literal 151170 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