From 77595182401f825524173bae74c800f9852beba0 Mon Sep 17 00:00:00 2001 From: Xael South Date: Thu, 6 May 2021 11:56:09 +0000 Subject: [PATCH] split signal processing chains --- Makefile | 4 +- build/rtl_wmbus_x64.exe | Bin 405319 -> 406391 bytes build/rtl_wmbus_x86.exe | Bin 368525 -> 368584 bytes rtl_wmbus.c | 366 +++++++++++++++++++++++++--------------- rtl_wmbus.py | 73 ++++++++ 5 files changed, 307 insertions(+), 136 deletions(-) create mode 100755 rtl_wmbus.py diff --git a/Makefile b/Makefile index 59ff524..159b197 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ $(shell $(MKDIR) -p $(OUTDIR)) # Create a version number based on the latest git tag. COMMIT_HASH?=$(shell git log --pretty=format:'%H' -n 1) -TAG?=$(shell git describe --tags) +TAG?=$(shell git describe --tags --always) BRANCH?=$(shell git rev-parse --abbrev-ref HEAD) CHANGES?=$(shell git status -s | grep -v '?? ') @@ -62,7 +62,7 @@ pi1: rebuild: clean all install: release - cp $(OUTFILE) /usr/bin + cp -f $(OUTFILE) /usr/bin clean: $(RM) -rf "$(OUTDIR)" diff --git a/build/rtl_wmbus_x64.exe b/build/rtl_wmbus_x64.exe index 53985f7429831cb69ed85308dc6d59a7444bf719..6f232e8e3308763297acb511d56321827682645d 100755 GIT binary patch delta 39229 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 j(t8cm? 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ÐlxO=ReM6zLl#nRpRPuH?NL-^d$JinP}{$y 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 K-K|ObHT(-LM>?he delta 38461 zcmce<3tUvy`aZt*p4kW@&ZwYxK?WEU6md{Q@H*(AgMyNxqLN@Lsga_hS($@^=7bo! z&1GeZWt~npNlnz_DZF2@LMyX0Ln|A!3u&2YI{)Y0dk-@seb1NQ`TT#s`Ly@D*0bLA ztarWZve#OBOMhGmK6Wv9- zwKDl3uID+27P1mSwzXIclJxm)#oQM;E^2L98=thxz=gG89hhmK=qoIqA+6)P@I}&I zKFY5>vX$fNAYJ7FU5oXT+)Dy6J@^gbqG2EfB0( z8`ic%5tmyXJ4;cN&8tO9b6gvwH9}XuLfS2KmEIEqrC)_Wew*Z@>B_$$#p1q08jt%% zX({d}rPpu|ls?AYDBZ+8R_d(n$}ieEOnZj!yO!hPP8{QSuv$yS4Tv^Gp7)Godq#Se zOQU@{^#)`Q*!Tg*m2xYp7bff_5=Yud+>YU9Ee)!MLrPoQ^^QNnWcu=FrOiIULfetj z9-scrCK{n>>@MB*8N`=MNzHotJqw4F`Z^vRA9 z8PW-9*3tssxS!HWBQ?^;&0_d9(w%1gCaocyv#zKvY>^UIy${(?J!g&M*)B*Z3)mRL zan7JQHKY~v2r1hIM{##KZS`HJ)A5f~*mNd>(#1PvlrAng0cd-w^sMiLyk7drH$nJy zxD@FZ7QT5n_o{lcTpbe7rt!IoAkF4+&4 z1gyjzcBa|Mj(LbUmZVBM{Kh1$=D2^88%uqPZ}GYnH(=A=P;%=Q6rh540V3Pi(6yEZ z9EEU994-xP9@VnV#~fET49R)rj-kV)1tM~NS`$~wvYkRaJ&#AY5l{5hlfdB{TJ~oq|N?=`4Z`(|9F16 z)ThPZ>;b6D4V^y3B+H4XZ|GWyQA+q6!U4f@IQvsw)WJj03+klm>pk>+J@jw=i})0M z$=os|^g{r;2?35`h^Vu=s4F*gR7%z@u!(Q{OIp%$XnaU-$}~}Y4oWC=;5f?z%7*)R0kKAAlDZ^=*YBXV1MFNOTba)o>$<#Cbc z%aQxYKa9mVIcPoLFy!gx)Z)5&ZDXF>>*L2Neh-mmqY3OE%fra|DfOnZpt+9`cEGWH z2*=3@Hs`0wduSBwqt-;1o&t?jXv}eGkOF#pgTg{pA>C5}aiPpLbU%yAy|9jn{TTXef0Xr6rFvTv&WG-~MrCQ$}2B=NdJemOnh&#G^D9kiDCpr6&F0=@?b7^JMjZta#OU|GxM-ZdHzY(yOm5zbu_L*fB zas2|tdu<0w*1&$k8w;h9!14ST>3m?6aNQ=l4TT+Yf`sX=MYiAt<*@T4|5@(>QL$ z8H+vBn3Yzxn`&#-S+uuwyN5|nw(XLWZ8W1tm7=ILd!f;kZvWF_w-^)A468wsYQIG} zt@eCl6kvm6K!1+AIZW?cIwe@Q;unw=Ej4k4e#LiSbA|w0opQPMrNMFM)5;=etZNr& zOP7fbIBL*~N{0nwHjXOS?OxK^B&%AB5An&)&(rLeVMnt4mg9t?W=%RY|4T)~{s$EH z(xc95Kj_$sbQuRogMs34)qCTSe8c)Cd}1ghMIUs5nUkmFJUBKvJNd!nDakqL3ubEi zH2YOY*)6A2xBIv~&6r&`_ny;Po)ULc_Wa6g;6ccyTX_oAODlWf9RQT8Otdb<;Ff1c z>0-N#A%%-estXHKi?0=>7T>llYMyTY{Mt*pPz%SU+pndTt$51mbfzx5wjB9&C8K1r ze4bCWpNKo7_DZQJxSws9erQ=>LUFCqvdOyLN8#!0y4jeNb)n>6UbnI>Oe7z#3_!sC zb-MjZoU{0QThiBsJ<{ygVO{c`rLx_JmpV=+a$NDTrA2d0LTd5PMa74TbS39Nmh|<) zPc3CB_mH7%Nl%DNjxA8_ONw=SppYlqUVN>EwQN*BYuWe#ACSv+C7Y18hk|lE`grl3 zR*S;RrQG&`Bd@jAmCQjhpvS(klnuRCwj}hPqaSGNCIC(^d+=UrS<2mX`&Gq*i!s3J zcAyUX;2US%S%grk{JfEVY5yWWL@Mntmp>!j=@5+tOJv9Nmi^{ZV`A9L#!32)fqazo zT*of_T4{gBVOZg4It?DSuYiu)%nn5k;j!DuO66fbu}zS>ecr-ik&N1F%X zcp9LkL5Xj09EK@6<808cID;W~&iT0oBg~4CY6FG=HlBq2fPD#uVA)CyZptqOAAA5;t)gDxlA-&V5qcC)i^kJVt!ncap$m1#RAe9c00tCg z#SH8WI*kbl)w+kIxD!@;$Wx?a7q7emvByu#Rg>WWju22P4jN6dlzIe*D#2UMpy!CA zEZ}k;neaLy&Y;$~@1yMKlFpzK#2g*lbtQ_FV6c@_DP<|}pcuJDN=~#2(;ksZ6Qled z#|p|?)@S~|r2UDj+NV8?*fi~OD_`TRRcASCS;!B0(t}BzY(udUxo*+5vKURN_H!5l zU%`Oux>ie!Q7ARl{wu<8r(;1RR-(G7LZg}1QW+-uvIGTza?s31tpBeI_OWUeS+Q@v{2*Kd@4fMYWE}FeZx~Q#(6LvfokK?Tyf)=;?Anbkq1aXBZP!bZX=s14 zVrZ<;`gv*7&_2SQ4$`MXd+?_u-qMZVD#chr`DId?CAitV4oXfySQ(vU-lSXZ1c>}4$-*zsk8`fS@OZMH-kU!@dz0gXj1=A*U9AWv}$lc7|6 zMlEqN;wTP|K@DxM$ zpPt7|_92|8!&Fp!*f80(ghrk^q&b6_%oDKxd1+lrk1hjo)Pbbe3rJ|syh>liJDHU&QMCM!k!gt`sZ#GJEhqaF`3KnRlwX#y= z)N#^BY2$_HaZ+UZV?ueRv^l-KurO2Fn?5N#IupZ|*2pxK>M{e`Q+#|wT=dJ7`i#mG zE{&C58WqFulunKc6XuPTei{|pGixjw{QTn<%ITPw{Bq_P7lx{#Lk@u! z#$&`-ssHHqtph1meAql08$H^^`;Oh2H(JM!d0L0jOVcks;Y&@9zKA0iH-@HY9JL&9 zJk?UwaCAf(rem5QfJ~bH^mdw7{|leb-3>nb-iZvw4xYATG_IEFxxxqS;`2bUWlOY+QZK1%W~5LtN*a~fLCEMO z&CVRsxdoExpsb`T{8c=#HVz|4R}zazsTfl#oy_bgRK-a@WEwhLdInX&4>b!sCO%Dy z_#G3M#Yth~f>UOuBmWOVa`AUOH0E2Ug**zCW8xMyTha|(*%r`RryWW!?Q|@;s6VzN zAp@bKEBOEez-sSdij$U(YujB9EV=j|%%Fi$8uSu=cDyBZ80D$v?czWLlInG~=ps@b&;Lnv`=h7yukl?ITH2K<=$LrCrxJqN3nQUc-wd|u zc8`-=<~eM>tL@@y=#+{VS4qJW223n~LK>C>iPUr@ZD;}-H~ z_T!f5>%|B7=o)*#$H463F47V2Jq?x=biDG?KAVBS3mZouVc>HVv5OlZ;PZtO$uJ-L zz;%cp6AN%xT6wk_O5RU#i@g@(&MJ+}>NsE}n3MOzRL&kU3|iMt;b0)ye$IZ~{%7<( zN3%bi&gecpDB=0I>g1w({R)GUb?=`|v)4Hyq?fb$g&x7lDJ(dFiq>U;d>_>q$!T`D z&2dt?lNH~66)?WeAE~7SXCbV*Zz6(l-#KJRFB{3H*#k0rNRuWe+1ewat~Jz?iyr5> zh0Th^*2GX6pods-qOh6V<_p6u_Q;ztWdC6D@?&To^s5U%QgplH>cTLtEb_Rmv!b!5 z-^3HWvpIk)Q1AJjTny(h1wXCDK1{v%@TSyZ<0-~-X$n7BuW27FF zg1amLl5}?INb9sSsioR4${rA)whno(Ra!R!Ifm%a80nEoCX)}C5NnPcrD7oN7+!6a zE~`_F`-F^p=6A9+@>+N4!%5w`RCPy*r8F({sX!3hZ5}PYVK{-2s87=|zyNpHc z@NkLVZ!Cwj=%P!E6-r>Wu~G@FH&!cwO~x7}u+3Pj1l}^%Q@}<%97;g`{YE_kX=Od4 z@O-!0Ked1Cc;_>DOEn=<*WDwsL3lrIEm`;ivQ;Tl}JrQBkiY3H1U}2b~-*6Jz$! z1~lmR-4HsLw+|BEa&};9ejC(+=6c!kf7d(c0Eo)uAh{*&aA>JJfpMRz!4-b)(ge z$AZO};b?IOxwzloC0X1}8?v|W6Tve}Qybl(zPX}}YJ9A6`u)c&og<;iMCWVQXI zR*Z8KEH`MOMw^cl)=~gCd(n%J*!t1CD*eEbkU+Y97aQp3Cem#R z4r38n=1gG77%x-RSHwO5k&a79j=GkGtB6WeecZRJyiA!m}zv%nXVa8EO4VJ2K{ECT50 zh&s|Dd2(wSs+a?sVRn$Wj{7)0AXP67qpk*{PT8x+LfKk|#=wxr_}*ebrK$RhlF|O|PQ& z`jApgb!sV=i=_cWKw~Kl7zu&B`v4MUE!J9#58~K=9GA==uypsc+jxsTAez#WuFv5f)+)J;SSX4UJWYIH|y#_6KIqEHYb)fkUicvXEJ;s&W$ zla4>O8{I=T%X*+zn~Ilf=SPdq(i8!PLGj0QAjNtLLRG6PddFI?1oLJPp0|~ zQR~3{E?*Yxa1|&rn`+JHm>Ml}ZfIZ;UJslE& zK7dST(1ikeV)cg^MIUknPcuTlquZB&CjN;~)@8bVV*|}^p!pH82Yy0gtB@+_>z>}< zLdhPqjj|(CU1?AyFTiZh9w;=gjZ4lA`rjogQmF04eQd0CD9tg5PZF^+CNLbWsj@$$)AFE(g{Y z7{bQo@aUwKhtwb#3*?4OFS@Yd4~)Ulhx>Q_%Qd^OaoQD5Z=U~ew3bI!RkoGJcR&OlEA ztKT`V4Du7fejByNjNr=fU2;PXTer(;_hpfv5%xMcOHFd|Wm>&d!=N<3ng;5+Pm!#+ zvQ*sKmfSJ%ro7-<1uv$RwJ>AeARN!(br4ufmj*qLKSroOLmS$NE9tuh6=rwLj#UJLm44z62iNyis%g37>7V56R{TYeS2DzAUG zF-x~*G?u`5%a#}?Ic>TX>+lGsWg7YzojvB$i<*^p0b-?@FW7V?%BsvsPj?*hWT8(g ztGT**Y(yGfAL00vR@PXMAM6UE)y5Wx@zwqqYgjo`QgQ8I-EOU5KZa3ef;w#sl0MOu zEQevmx3s!7j{~qEK?`}H*4JV`df;bUsD(dz`W{XN*GvYCr+myc`k=*%&rtA&b}_z1 zS%AeoHffgVY7|7Ipa_KEtNo4xpKj+>e%WlnvxL?@ zVFwrf1|JkYOeewy8*la`SuQ>yTwAZ~G6N!IYMi#^?7;EW2f9$3g{+kK zV`=t3l<#1)Q798NBSWrja@W9qK(kuj`jBU6CqvGlW-WU_XID~msizNoD;~J5#a}o>jV%&rt?)eTEcG ziM)ZMmJ6kJD;s~K_;y>}(<88tTv1&%Q=?0DK$W&w2kr{!2-!(TbY(F}h4Y@Oq>)`{ z%q9B^Fmlp$F;Vz>2%q$+Z$6^yVF6_Z$0-Q4i76;;jS95AEw?Fk2Jgnyl}JdT_M&a1 z#lFqxfOIt|VGRvR5qcBRA08=e4XggSOKH;S$;E$Z7cEk)SKUHQdPKLH_T6xyEt@RQ zRriqOc{tf#vYPg^NTxO;U)H@OPdG(Lr^c_FA$NoliekDE?}p3fSg;Aah;8n*HPlJ& z?*pG1VJ7&<+`3sZL6N)xR)_csl>Py2#$038HN^Aa&PjDWV1Y7OqsxPadP?0NbmCmB zIGC^dQ+~k6o6MWEsI8lfL(4qurK0ZDnQ5~aT0{otExUtRq+}t=%d@F-O36Fe^Ztuw zjQ7a|6rE4bpqT?R$fP{9aaP@%GQSz$RN=8wBhzljnQgheqHX|h*1hqYGEA&{TxSOK z{3=k6C_J|4@PR%c)t^)!DUFQf2 zVX^9S8h0K8#wzbv>Ffg^8L6(^?m0E8E;<4uXq)WBL6f{m&O`r)Gw=alT?HK4FqQt> zbFOtc&)t6cXukqaeb_Sdead5#=k8}w4(9Heg0AEmf_X`W#!0%e_Yh3pt1tslW^wGs zUHo;O-EE5Z24F+akUI}%`{{B9n44es2iiz3kSc-l9$ODRupx1#ZI8llF=ojXl`B|x z6gh}X=^Uh|D_M*Fm%NX(ljVNmvO+N{Q$8xdv!?DD}IL#JxV1_fPJrH=%Gq@m^P%VO} zS{lw?(`UmXwEwc(By=Tfkdf+T!QAgzv%~G}iQ7yF%x{`E$^c6mb7m0X5K@jb0>Wf#!O9T`Wtj*O$!BV*!GPK-fBC&t!ghv|&k{lObPFLikX zbMrjxlkLBvGdf10GswfEp{mC$Hd;~DUBLH*u5N)WgDK0Oj%VLMKYa|-g4)uqd6_x@ zx!Qwi9w|I7=`$mssL za4BPU`MP|ARFU7R^*XbhUZl$08neXbhe)-LHY9P9qEg{X%0J$wqDaByytvgOt>c{Z z=%Qubc*SY&c&!@OuMKPGXE>uIQp6`$jxPi^QZ6fBhb z&F(B!&q?;(tmGUFyq#p2s~=K7*}EWpwh}j}(xggG{h9BJXJkwB=dO{8o-s&K1x{)3 zyoaUp^M?3Lo!)PLzeUpK`E94q&!5_#E9`|E$L%`hbWT*SjUHha))e^|@;!npL(Ol2 z#J^?QIb^|7-e&5on4i&Bkp`n8&Hr!WHm+PPF!%pWft+^*yK|g5M5!?sp-3msIXRDC zu8J2)mlk!E^ovZ*3py#9`Uq*nqFBKYAzfYArB{*a$=o0%)uiStP~$FHsp94c>8nMt z>lXPo=hUiaxDde*xpTy0Z)h>^;H5|pOXi)h_8@f*Nql(Qpy{W23|<=+=wJJVQV#d2 zd2LvbrZS$!Q>ZSP@?hWN@Q&-HUzd%xRV?>L zYwpWcKgc^hqmOsI=sx|5`{MQLEX1k5jo#_u+xl64{#iZv2`0$CxS|j?Lk`CkgK!4q1Y9PB zb0J^B6_0QwWE&&L4M5lcS&GYoa5-ehNUXXDhkONBCh0>;IA6#`xB~Kcv<<5UL~5cr zZWO+^C_*>`QtSZ|gy|EKmvC*O43N!Ckc30F!LO2)lBraPCA~gtnorppau7x~;he-wD zkgW!wPatf7jKNinunF>qfv7RU^^jKwp_UYetT3a0AWYIf8T|ucJ>)7}zad->*?tK6 z!y#}Ep*`nNOhAZ`?2Jo~umQ3+u0Vv%kgIS7BU}#I(}GTfunF>ATu}&DLtevWLbx6> zJB8yC5zd8Nh0Ba^Ib_f8z8&mG9he& z?2juRVKd}NT!{#0Ku*Rr0O7W#2RW|KLRfPEN{}hI%!j3U&s<-(&eY3+Vt810I1qKg zMJ-IyPs?*!w4y8hH()J-C|!DJ-Ee8|I)k5&hVvOBnD|`j?7C^vK*=n9E@k(e*O{Al zYZ*V&QN-t*v+?7PFXhwsJjGjHU&8m__$1$J)f0U5;>Y>0nTz@Myr|h}S-)R{<&S0E z#ugn492n7;;iFnur2dR`DEM3aJ7`<>cM4Rf%GIi@P~~n_o>JunRsO6>-|vV`puS&HhoJEait1?fOi&VK>mF23e zP~{F;q9Y$wff`j_RHZ|e*H!tKDt&%Xif*mS&Z>-3WxOf}sdAVqGgO(S%7;jH!Zlk3 z3RSsOl`EyMUuAomRXS98U6p^S(g)qa^Y_1W02}vzxd;3& z9RLmVf42wxFC75obN^R+0QmpM4uB?;YF`X|;Q#kNu=Bx9&uXNbTlz{pD<(?j3azxN zVwYszdK{BRC&~9^gQln#t$6*h;*~o~QM|dTl~MeKuQC|L&-k4!U+d-LR~e@yeu6EZ zl>1hOh)f*EY@dih*!4*@Z|TKy8Tr*IBkSJQ`&AHt-#K>aMX{Y^dfVg&ZW%g6G(`Yh z3%gqc)V!@1GZLV|TrBUHd~*rFk5v?lZKYA~wDzm%uOQhn$vdXzrU432pv5#N)x4u` zUSU>{T>O=Zw(GWM_;EuO;0*iq9sD_pIon(N6^u}zRzy>=UGG<}0^JpRYqsl~SC3S5 z^eu>|(&Se&K>@l`ri@CxAD5*7ZDnHs7(9W>N_{i40)+KkD^dUt{!O`_cHv?Y3U5=aYPxP#?#}JjoBt9H^?*ATfd;$(U0Fm?@@f8?!`Vh!~ZCh_o{mPQ~rz52(XnAfd6e@6`n6*p<{&0LQ#B`W~|W6z;9yy3xt($#<~T2+uMB< zhg?EyZp0P9kKuc9Ezhd(Pcrm?pJwBxs+cE*7-URfla`>&jD)Humk7Q*`c27GXz<*G zsyR!A9TWIHEbOch;kWCYLL9|%x`-Wo_)|Pzo5&tLD@377ZGeU_BZ>X%tT0PR>Cd`+ zA@nzlP^Yq|r@(dm1HwYwv-o(dP`}6W^ZO*W3|c~c5_|s(p_4GaAG<*Dsr^{{bBMR; z&-$JNOYq;aBw~lK6D%41*}8K=g0QYXJ9$p%JB9tNHp;}BdXJh`i8b%*SlRZX-ni!_ zrCMCv5szd!smPUtU1?Y3S=5i^d@1y3SJ_X=@_i0*Ohmn~uY2#{c<^OkOKQ@YBwp2@Dd+KP8!K2?Doh%&Yk~o0=srz=+xn) znj8lnu9>e9-DxPfwI+duT@cK|cL{9T1tFzt&%O%v5a`9o29FVzz}{>X9|b(Y)|Y*9 zK?o7D64}oegih1*5|vDOlvt=n$Zanx41SudmlO>y;ebc-F;_CDCR4Mcw79Q5lw{u; zUaFe&wNStdHT|nc^=T&xulpJXu-9sZu0qTJ_DQYK1FGy^t*~5Z zF`#PsB|+r*8n)`P@Pl9)P&Mycp?ost4`Hwdb32P2tm!7yo@0{+Ya)gEL2TJz&4S@0 z1}g<@n2J3#>Jo>Mkr)S$n>f=nkF@okX>nYynQGeW$Yd0CSg$I_bEY-}*)vG8^&Y5{6Pnvloir69Tl=eUf5pAMr>JSv*~lbRaf^rgY!!}I zs%HAYBWN*H|_*Em4jSI!% z$+%eoIn#S;@+lx&vX^i|TwjfWl z0uO>e^E45HVF>H|uqIb{VF)XFSkuq8e~41h3tg~a_*RYl6A=TMQE^^1g9{Uk9QUA_ z&btC_IOWGb-|VFboU<9B)Hz?(x)O;*IbV^A@UDPP$;R<4X{M${&u2YzL_DR&-h&mt zfz{iR&c6>~g)=n^gz{uoH&Zid(7%(-GTTQ`{|@Efr+!0CmMh4q)L%AKkS&{~i52w8 z?A=+K@zVyY%HJdXRhSPhKF)w{Y~>;*d6aWlN%L?}=;La#o4Ubw&3x~M;p~t+SYc+f zXKT9HYSi%(Dx1!6IVdoy7Zg@>#la4)&Y!6ow~*5LOEscJO1Eoj1jbQM;39Ub0C`|3 zE^iNX_it=jmF^MEES|5fdOTkf!V8zqvyG2x5`^0GtmaY8R{}S*>a97NqH%&@7>hlu zStl5Wv4e*-F+%b%R)1I%>_2{(SvH&>Ka90GqQO78O<}8#XdV&Pr?5YdXkt25rYH*Y zFvWC%o%2b(+um$^Dv`pHk7^zka#PqFM=|M5PhqEzVq$nAh2W0o;IH!=~3;2mV9i}nOag46R7M5@vN?%%tAxSV<*o((CBZYVi za~y{)4_N*uTXHPSbV8Faln-T_PoNgB4Q1_4YGO?LhyG2D?iDJUH3c8Mpe9tW1^DQy zxrHq_DSM5L{!n8U3`5!44>i3zM*j_qiCkbFTJ_C`nsi<$7{Ovc(l|->#9y=%mW`;& z`dFjkh4K+q4}PLCQ2=XW&1m7d5v;aGV-og{V69JUVsv-aP10K$j%(d*BuhW7X+LPQ zVs#sSdW+wF;FYZn+|IR1SNBh(9ayAB-bbVj_3t)3R$1kntG1oi6!Sv$$g1d1H6M;L z)Gt@)I(KbG3&0;;(F8f_Sk3~&wPDdw7gViG88)a~?Jn%iWLvsw+X|m&vZ}7yaN%wyJKt5? zEhToG+oDezh}AupXBkJfe)?xeFT(b{lZvr!8Dr!f5#&U?unHZW>OyNmr*!O@~>ja}XG|{D7{K;|dQYxn71Xth$>vl6vkB z-Lw{7I6IQ{h|w+&~|G7lSguPL$dKsTGfsoTKow#j!8YW zKL|Aws+O3vJXVzxs%&xE4!po+u@`%3og_E))?&)bV!!m!c3`!=wU-4$7CRh|L`Wot z`d=G@7aO>Id&pXMSjT~g+6la1&SH-a&~|3C65*2(S*$!!J51P=#cmJKc8Wfb zrMTjA8vH+~kslB-(bPb*K_JZrTm>6EP#Ya7PIRlc?X5;g{eD#=dp1e?Omo*kO3_3X z(N9|^6iuvZ*5;PwI{_xz3l=Ib+dm4%Tks!}Y~V;mvb$rcRq*m@{kcLpga1=S<^- zjCPp9bczCDDWm$`kb}{;_M&KX|D?AY$k2cKF*t2 z0MmA)Xg3D$Wn{CUjoR#p4AoApZ(AN)sGOXFoSeKz=T67`+M=Z&pp5LQ^&7R-1L%-w z{O8&gTAZa+ef_0&l|aWM4`0x(z_PGc)z4pRPY84ru(wwGwY(AEcv*Xa_S1{L)n;mF zBYoehnAKGSO3uZi}cL;<1g)(^r$*>SNnj5 zhF>HvPWD5WX3Lw4A5l+!z+e2BI&D}B@d9;BXAAL5A!8!@DnPtQeFE{)@f_Z3 z!7KG~ivMS`2il8)?BDIgjzVrP_EkGEmd=`*2Seh}s2@ojyUY$2=g@i3SHa>iI_C&) zFLt4GjS=m|QFPAnLVM`p@Zw~9alD^=K8kWQ>{2^1l<6Zxt&a&$I_#;(bU;3AZlCA? zJ{&w;?I13Sb{&=`BM<#7EpwNUt$_%eMJ(9{mbY{j*e&hoD8~BL4>VIM zcbm-%7Q>l;CsE!l_Ua^#N7JxpI>BVDVb64esaO|>hlmNZ(w`I}j(Wg#=Gs|iP>NiI zhqYm-Sw>uIcrt}>vx-|){WKLXSMe<@%peA{R-MJ3Hj}!vTBhov2?VNFCpAyCnvO#- z`G@p8snKZ!bM-|$dkgwDb#`Yk;FXFAwnD!<~sL zVFjuL)Nm-QK(&Cpj)i~W*P48HcM*soB* zabLgyv12n;lTCd{Z1ayH1H}Hm_3G|~pdh@1*t&bMIL(L6vx%YNe(+Q)!OIBNC_!Hy z+ZQ?L6OCYzp4BWBJBz~+E|+1JU=!OZ3M&Dc6a`jJ=#8afM|RLAKA>p!DiYiAO1e*P znrT(t)gJgWz-v^U9SB#*;SS7a8K}rkW?m+Wa!9xf_5QSBhDIyHKVN zst-#1Xf##|tkctCxb3i4%1NYDdm(3m)F3O*8PwcA0inNh=;r$qNCiflTc-^YU-!}p z1yX>{&P|d__D!Y)ZDg zS@ZL#F7!bXAp%E8PX40{YTA1u1<=XBgs14tQgi7;Tu4EIOv6=pB6*ZcZ*b{6I(5;* zvw#@FfLP?h5aVu;)dV#le&{Y04T$`H2zsV;Pn}Tc)XGD{)(63JUVUy1kbEHcPi}Y| zIsuvPh1h}QdLf&D(0A7ET=bXk3|`0)Aho=w&S@K6j0ZC>GbM@ z;=MdH6FL<@+_j%ixxA32Kn$RD>pTObO|BQT0Zl51vYA} z_=T%3Q7mNDJow(MeJdBk|sCY*h3wpg%45wnwO0cPtttB3? z%O*y#=gmYQIMyw#R5G;^`qn;#l zBRsvm1_%uWcVFBBq!x3T8`%NGfIg%QJ6DUKq$f6d+KTP;fsJAW_EX=Jc#HWx58M1% z?DOIsm$_*#0NTXny+DpO%FW`gEE;#-TVlk97vbhM%3|OQd+$Zm>=@Z?BsX_hYtjav zMYIyjPWM#%J((zXsv*IDA#9FxrMk>T_Su`f%q?f{Zi1Z|N*6jTccBg}@Fnp9-oGmE zCGk^Uu{wf1xCMGYvSkoLM&x}~vkNbX&8u#15&QFO?Tb)s!NzS>6n{R2Xe8Ub)w5h# zpKUmS#;x#Y&0j|2&Xi5y9c{ zkjvyOoz+*5ghm*+;lgeAR>>T_(% zJ8){z>*8Id`W62~^-I{1f1+B|D50jiJa+n?MY!6_mhXTVVqEsRx>QYfLTL8Prn@{t zH}qyB8+JwPfY;zJy@5iPZleMHhIm6Mx%N$zyn%`6?Sd)he#h7U1IkalCBDhx(2@9m zvDCL=;T_ljT^ilFL8xPW50^dUzwSUBUN-jwLjOw__c*o?g4x%Nj3S;`7mur6DCNhu zJ)PU4*2T)_E^()vqsxef90eHr(+cnNAlDw72NbG~Nn3A34ZU48r9y@QF?%87fRuY7vw@i6 zJ##$`q}mJF0;Jvx*#RUMs~~q<9E=83?gf1V#E{@pa=9KBUwjYUMy+wZzw)Hhv((+_ z_2pHM?iLL^p5gM-va(7v`q#=F)L6ZkZY`R@owf5GJU$J5WygEKaD8W1y+YIqW|^o1 zju#(Yn7?3JZ|KU8T*#Zq>ybx(-e$3>dtrqy3;Pbexni&A$G2o}0Aio)0-ncyMOY~4 zr;tGQ+t-LhDABMf8vq9qO9cCIpZK1uK8OE>{<4bI{R=GR3X871AGwIC*Bt@}6ji0!oThRce z70{vZYl&q2Ko_FCB~lh&=qXd73rEN5ZW@OKPLsfK%7R?V&! zLwU9p&Bxw40OS-qeE{k;!{r_*QpE)pw!UGhiOzix!x4A`=@K*rur}#^uSgm%Gqb`ct zqo6P_@fau!Dh1@B8a27CyP@oegc=&Em_H8N7!#cMcAdi6tbu9%UE_G4iOaA0Lv zEBbm+PdO#d<`=UQSX~K4sY?AJhhcnpXvxDxuUZf+TflxiBpR9HBb5K^LDxgd_Y)ZL zEbH+JjMz`TWQ1bGyidfr{`Ai|lp#4tnQ`1r1S`T>T8(J!QsYwMVwHcp#_6f~(d#r^ z>_ZC{Q2#@l#(ahh=T3{QSw3!wK6s`!Q*_il&bg-Xyg@wU&w%GD@%#l6Z=Tww@kD(N zp3jJ9CT@w>8}T@r#`7BSjQJEiSBS^ah^M}3JjS!&sUe=}xFud_#B-}@JTDW^sL#N2 znRw1L;^9WBjryP4%kTwwP7zNoZi&Ym@%T24XEX7P_#8YJiRb-BJo={bbUFu~YZ@1HVGnYRZ~Pw};LlYhu%~uA{7jkb#{+);>=~B%VQyc#4|Fvz+XCi+IeqCB`@6S=A(-4c~yK+t;9ZpJ<{Q(UdodhAkzY*NJBU zZi$^6@oa1w&tJsT+0!(hj9p6aIY{6_Zt_A_`) zAWNh-UEcN_ZyL|XWKV}n;CY95b~NItX&O)cW$*E#Ck`YI!4bYX2+F)vWk3IHNAZv^}`>{qJa2v2Vz<*T9gN*T^(SlT2ere-*?1 zT413lw->YhEOuaJzltq<^Jd}A9>=}SQoqHL^c0q)^&{m)u7ACYnGa>(NZ9}C*#lRx z2zG54jI>lA&Me>I0MWg`HGeM}yL^J<3-_VJL)a~O|1O{yeVV*e95Zw39K2kdk2R~S zO=Ml<(WiOtsX~DmRD?Eq__qWeh|usP1@F!8asFQF{AcAySryb4~kTE@EwSGvpa z6_7xM;PW7Iy+;YvhfvHL4wP#64*a!Oz4+H(1AheDi|vii$KcFR`M*TC+LIp%awW1H zAi2-}0kZx4EoC2d?njic><1XJ`X`VNWAFYX_6cn0Q4Q|TO;e7eGOofI&m8h{i{UPg z>8AfICiMNgeD^Pta~o}II5v+4)Fzt9e15@5J=$nEQz15VQE$*L_qgWsE$yZ=VJ=Mq>F1-m;Oe0Ps+ew^Rx52r) z5vT8e#c5!1k1VK5Qmh30?G z*^D{wijkt0R=yq&(!TU@T{D*aoY;<;_KCic4d15x$4A!Vwea9J+GifcCb7+5?njnt zR1bFT9@bpH)0%Dut#8BsgMn>*=&Km$RXFht1%3TurX?4>ne?HLU$i1C+9r1P^V8#R z@614dXJIeF-hw(TF3q$S>-gLVpD0^fB-5Y3qD8Ut`k@byC901VWF(Mn7})OkiJGXaQe>Qj(W zK*~{Nw3?cG1`xOFa;D8#JPYq~lub2Rfwwy|<}AX#!^^J6k*gY)+lq}gMCs?mt7oOK zNmnSQM(5G?4tgs&-9>m;L`3eX=>hiGQ zMydVXc998y*g1x|dE*AQfIj!`rY*jZdIW@6{}0p!b(o&Kw||`VdeI ze;h~wJPI|nD$fAP^uezIAwl`^=XkkFFXnB;tj9Nu?k-6G z=cYn07kvW6+)#TWqW=lhj|~lkn$4I$ALALhl)946&(PW5z>}Akzi`1!%oJWe^G9!A z41@4BuB#P00IKjB+R;F=kPc9-Ykwe{8mIwtJ%y z7$hr7+W@WhqOJl`)6lJ^J~S8q@DNse)#Ds=G8%NKFoC_|;}ch9F1}F>t7f4^g65 zvGahqb}0(MQXuk|uMN320KtDAb$kucYA?_115)eNoabzSGQsI?s~bS*YjbrzoAvOV zsrlgbYN~tC(YJ8vAe9Tk%7}h$7k33Ry@46?;+$!Z7I4aIY=c_W=zz#6lq!d!fEW;R`=bw#+=hnEn?Gafbfnu7y&RiKL|||m^e_+_ z@9x?^4dk3xJ=OzJ4!vEDeVKH;+I~NfU0$9(1|*ICwXhE&p@0HnOZ zTZGI3vf7Jt2@vmf^D{tRPh;o6X?qdjO0O>QE|4W&3)lvT?Dp%7m zD2X8#I@MmLKLVt{%dAy4K;L=UPJgxCwOJ{vd*QAg(Vm73yRl!CrIy z1R%a%2>zBUSMSw`%Ybm{C|_AT=HOqb(WbAw!5>uEdMLS<1%A{nC? z^dS%mxhwVqkW*gO_zehto=fKzp>TDBQVtfySY2?HUWJ80XJbRV=1iM8b^fDM7gwS* zckxNk$#3AHQs{qw`JERs76^wXvjIg`bTq7G(DUVQoeXL{9)gm|t6k?2($LY6YuZe# z+?6k+T)8$t$90ON_~R`gyAX7bm%~70zuM&DapSH4%Jx#a2So2xe1O4oB3h&_)07Y4 zsCYcH(5GRdm(N0wD;M=tJk%4h*y%GKTKI6z)cI4ZmbCUcF0xs{KB@llqAzFRf~gPB zVDAR|oM{$YfIkxwYhp**`%J*U{r2g}LOb|8)BwNL(PswR-N7fE#dPwCZi&&;D`#r{ z!*emRW;EpjP^XWd)Y*Je0<_!5cDe=XLxdl0?KyeF0;FdwC z8bcEV+sJVGdnqJg6$iV6q{2yzfmQc_AXOcYQ+EmTx|OY&d`%;OP5 zx4EoQgUK;((=;|ZVsD0KV&)i{6_goutAR43nQobt=l6Z~KChzpbMO78AxY-=X?cVXn@tPyky>@&O z<-?(o<9M!9lw;?|Nzqo03*9lKuatR_u!CgH~#y!ecfvjldEksN1E{c(j{FNO-@bom7_$-6t*$aMydmA?^l`1A4v zX|S+nnw&2g`7QF((sCivD*Jd1o$&ogj%yJOfkq=|3$D3n#G8nl)igJ=;A zo$pPR)4ao@_+cE^7}RWp*@vLWB3LpF+Qv`-sECc>Q~~wYY`Mm}PEG@*Kn{Gm^YDdwb+YkQ|%il+0sSG(HJwGSk$eIOxk*==h_hfuWblF?3|;zmzc z`#?e*^p3Ngy?(ak%q;V@AnU*zE0mGo(O=v9Et!Ty?FdxiFF#y}1fv5*=s@TF8A@HH zB<~Z!7POE%9>|ar{Uf}05usm(T#Wizs{iL?c`NGORDX4{d<6BNO{njfOf)gMR9`&V zO)!LNd-t?pEfJn(B{us<(t04gn47+A%5vvgTfT4GM$KZ zFe$LY6zR^iZ#0<3%Eo{oQ}t#er#p7_9WaoI@eY`D z2h8gZm^U!f?TWQ`AcXBbjPbbx=6eUs&-_-OJHWr%v9a!*{_PHgzk6cxy1<8o>do@y zz}Z6eRyn$NG|l#hdPnz(L=em^e5-B^SG~aR=N2Jyv%IJGD51GlejBGlwer7uM+zmi za(JHsBaD|Y*WwMf;2^4m8|;%*JK}LnVa!D%W>eyUFjo!;*=f^`1Y zCqnqKR@V0&Z2BL`=}x9;W5Bd2tAF4@N*9)Q&DRR7yyZU8l4nS)%M~rXmHZ2f0<9V= zmzq1w$W``9?Fhyx++1Zy6m^^bgmhs(T`+fk;XKFuGnLiXW$3Ms1i}6sl$4(`{It5- z!$kSJuWs`M0r}^f&itD;o9@^ROO+v8cWjoQxr67M&0qZ9t946;-|}W!}&o`VmH74SLSHDyXuT`IfIP_=%qZ#a^<^3bI=g`;+Yhd3#X5^7-KId_D=i z$_T>h5$DL(x?@%2^mbzN8Q%5*4RTDqL zasYBgpP{DaTBB=tDu;9Rv6qxF_zJA%-%YyB*wJv70`#+`?#O=B9Tr(`#x~c1L3a#O z>WcXkPcyO|sh}67f~0?~{#th|O8PJXWKb*}E->awI(-L7WKsZGCE zLz+ofW58(FH0x@@aW-GCHva;p9q^CkAK&gJ1?XuuD7o0?uCuf>XWg=Vk4_ouvVO-H zrPP%RJSy#-NNK&!l_i}r>2{r>kf`(P zWA6C9*I9&??${}a&+b}E%E%)aJKj1yXiYEkFTT1b4w5N0%Z8w?KG+Blf%&>$-G-5M z)1zM{f9q;~2BY~_Z{6m(=*9648@3AthLor_%e#=9X!jos1}e%&L;9GOO~81giN9gK z-bYt61Z?16d&$yn1*7Fu-IQC1FcI8ZOA1ADV&_C+p-Gq*cdKhXS$d3oWI1aoH)LAN z4LPwtnLDasCmdxV%_r+JQ@Ogl1d4|gOIuVo*)p-xV62>Iq9#Zc$@?uE;cx9mk|i3T zHL>&Jc&I|9dWl|0`uFPNke+FIx9d83Usi891H)4wAMABAZc$rZ)dVtEiOQ$ITm6V$ z=xVn6s;>4i_+!&|kCTEbaK2|Ppx`RU*whXM(Q!1}x+W93(j$1l*fo#QaQAUPX84;oKot*{*x#%&g&mTS5NjI8c@B(h+Sn6 zC1MDnnLz|!^-mJ=H~-I5X8kyfoHJ!wK5`_@93^SqAz{W0My3o*?Ka>PVzwb&-a~_b zI!8^HFs0r)E69A)*Q9%*1TC@O#Wve>p>?{!KBM_&YXapw1ksc{DZvp{c%4j{6}3=|Odu#C{mLGPhcK+T5HqQc zEFz%4N@m+YnazgT(I$@_FtWFj#Tu}EQnT2odbwgiaGH{?%I)b2jT1Mxr7Ox?u5^V~ zN4olu6qN%|(v@CGS8ndXLehEo2U;jPyXswGQg8m=ukI1INg0B$Qs$x(K$wgOTeGeA znlyW$plhNf+F*X0daDgo{gK#NhwU6iI8A`MJjukFPxdi?k4f4BUEp7Pwr;9xaz?9@ za}F^nlQa2N*M2ez1BoRR`^_9|C`&L)%G)vdQ7>u_H`wwF6^%v=pfw?re*IJMTbIw* zrPRU<&N7hNFj7J7;ik>CpXh4-r2+b0`*man2yXXo^V@CyhBvo}S5KO6+E!o35*1XJ zlO$SG6G>9uiQnqh+LC_NnV*KZs57z6mVYDtn7Bn+;;Zr$@b>9mMpEgL#HzxtFEbmGZ2tTZMvFIuw+=Xf;3ryb*uH3QzyR}%%8e=6Je`2f8%ey z8KQe42^6)>b-5bry|j>ol5}16DU5dX$s2;D1(FPwvq|si>U5xNuQE*1HRTy5RbTKc zgP0U_y4;ZRSrzUL$_L5o4nt<(A|q6lX3)+{awrd0g}!4_@3mqH^3 zCGqK>t1t&M>jHsCwq#AhqXr1h5*<#hc@^OWhaOduV}1KO)`3M87?rcNpHwciCX}OI z7e2SK0%zRG%cdFko7((KaP=BjZL`sUfA+(tZMw$~l3$tzW@7-#HvMWd>1rt_H0GZ| zTDigNHc!Eo`G%mYrH~{yVMPr>oGosVhz0=x_DneLJRC>!CDX9j?z&LLbu?yrxTxD? z@%D7ll`sqCvIjang97)OO_wiqHeTg1=8@F>bBIQGqKGrSwVE&vUwZ%6vxRf;opC5 z$ZEB~9?KPW;s_N{?-hi;>~m!=I@A$(~C7;Y=l2T$>-GT=KR(mwbmo2(QcOEm}u!BT;#O z{jKgXTheu%c@KIY)q-4dtE~RERC4A{sU+NYHgWguNqi3aEQTZ@wYwwoj+jGE2m!7HLCI zk}Mj_#gkow`HL5SLHdYHI;-10+?g|S5c>Z>=wn^=%o&)Glsz0t!@tg?PF2W;MNzF5 z4c17S7ubDZUZimesd>Rl>NwZWl{&gyvw~7bx23!D&)+Ml16xxKGDl?9OO}(G=~^r; z`W6jEX5D={M-s72*Xr)Mc=9XhwuOpGPzvG!oa^OTq zD#@qeM=B}6*&3X;Lav^1A96`9F7KR6_M*i-mz+O!*IZI%2uD6aE+Lx#E|=(?xg-)k zyJ50;dHO6TMDdwDkKAzP5xs6^3*{K3lg`NN|7|WIvt7AlgTc~;RFNUlgH_5V8A@J> z`lTfUdj!n=O(!Xvv}DkuSgxhkGnZuO>Gnz;54*p+esG)4Ymmg$PP^w4vcQ>3nt6++ z>kZ;jw!_FJ(Jld#9l3=3=E^0J_KbpD@>qX+F3}?xBJYq(jx>aSE)H&nN-Gx1%3kZlHhg&*jgPaGJPm$Dt8=(Z%P*f9f z4($9&)(?xp^WXc1h4opt4KAx3jK~q`Hkj+w%a08U<)4*z50m-5^2p&2gzQnw3#@Hk zeZm%8K*nQRu}ywz_^^d>V>gtvx_8q1f<_l*kWXUPwb8XlGnXITeUz%0ZTf;Qedx}Koa0{Mke z@%%dZvr!3rs2m(UcrcMR5~amKZ^_U?*E&G9;C1q>=qY@*{7iIQfF64Ww}y|SO?;*N z(C9Sid}g$P&ph(x=r_fX3iz`9+$Z1YHpgRFKmC|?%N2FgbV&y5(;pK$5~@wzY=VhfFWv?h;4vCL~7@7V2<{` z$=^;G+lehEIkioGbz&6WkbOCEq~8^^K|5^kSRsd{ z7>LK161;$Xp{w~1(6>lb|2sNbYtz-f2`|$os}bkM4m6l=*i^aJV3LKKHC?TMM)O;| zWuVeoe?``b-ZhshH=|2Nq~yWm;wEVOa)tb9ih(~O3#qBom991O=!B7*h&-y>b`lGx z)t?;WX2mDz|b=IWctm7x@8*gq>T9Vg0KT{7am`>ly=hC7_kp#YL zFty*&Pv<~gH-ooe^yMMOI1`ENiUN7{dY)VDZI%=P)>I|xZI!)93x;&{P|HAyW*Gij z8Yxt*x2i#Otan#DCV_ojXr)2rf5z75U2B5s2AWZHkdnG7eC23MDnTvM7)O_s=<1qC zDS9BewgxLhB+Tk6fw!w46_P982g%O#0Ti19)1$`S7JZj0``b;e47A&!L|)oYs;9_& zd42j&z0%<~VXZoZb<=s*_|Z@wc|ARf4_Sn8YL~u5?7A{s$9DPG$q@zu&8Ji7H3}Bl z$j-qa#fls0L71MgD`YLAu3ft3A)|A<{B1^rfk1Z|V?pXE1B9`eb9!f9GII6xwqYsu zbE0g`oXQ8v?`IbFzH(7*yKFz7mou``LJufcW%cU+;1k?fNE)e4ekLo@#P!3_eMOIl zzU=P&%eOXL)M@K#Jo@nKjJbj&MvwN8J!zzn$n>^W#FZ_$6%uJebJa?q*@8O&&^iE6 z`}yNW<>|5o@5}enBL>Pl4d{-!bGG@0UiZW%)NO`Z&I}W<3JX9$KJ5o-f)I?B6w=lOt{qG5H}d&3y_ZYayiAqPbl zr6YQ-slMc~eMBA^4k_@S`z!4#DC(?%6c56bo`eU8aIQ*-R<83&)J@eUat@i(A{}t( zUPh*%cWc2yy}OQ(rq0o%v1&S>e8s7)b2@}9k*EWDB;1I)f zSU#%TWeCItum-w2BFvO&$c=3_rz)!d{b$QZ3O5LwLE(N~A-P?@nmfjb*5md4jHIc8 zZclVsr(SK2Lg=R|PKFZFr91?wF&rR$*m1#kiN`w(Ds^C(ku#Z76_11bkliL!Uv!v< z758`yl#uY;{!mt9IP4-j>LQCiUZj$Nf=pL#m}(5Uu$m5_d9G@{t7;va~+hAVj0h^Ga)*vIA4!=Q>AxGfJq;<(&ImmTflO(whrOsX_Q zu08@$xg-kK8p!g0Vp*q&(}htatnPIKeH{ccEoP=N`RFqwsP&@|-2-xZ#8)#0^j$~s zQ&!*pE*|mCxB6$|LE#BS_P`ue=?UL_`x8D>L8B26?#By0L6>lz-~LXW-zGfS!a|+R zzdx$KrMJ~T8#KuLMo+q=v-F_E>YqnKGtO8P>DGY-xFqK1NOEH?e)#uQk*ctKAP|;m z0VN(|;R#H}ndgYiU3#M)fOVjOej&@65RF=0xEY4=AC4Ml>1!Pr2?YDze2dbibP!LI zGtO8O;?d$R>^TzF7=s^@RTsaxF$HzLb(ELM67ni}25y9oM4-=6lR^tsN!_}PQ+TqQ z%Ri@Zqn4yhcHI+A;6f~9Vr-(}hFlDc5(*Rp*jJ@Et|2+FPMz^r>4{S=jTml$i*VLj zG5-@0Cn6*niSz0&^d_Mdm)Q^;gYJ0aKHJ4G|%PvH5q zy-|M>J`KJM0`xhuU3}acOtS`+_H*WDf6J+;b4e%h71TSrDW{$z;)r z_U5+#Y&V^5dkYt*+s|M90v|}d+eLS-9@9K26F2dGaE3A~KEu|>Il2Ex7mk_x6fW=r zx%5Y6>t|mKI-7u^j_F{}8gPO8XGs~3+tKTfV|ADY>f2uL~_K+9EgoP$nZ0~#u)jB?t%*x(}j^3`xkrK67U@*DF82!SQ? z7xN+_>4t_jm`VfAWPHb5BiD_>6&Sf0UmIV0x&ND)=+KY+&Z43bD=W(j*DhVKdR4N% zIA%gZd~BJ1?UKsH`ts!qi_7&37Z)#ERJzK?M=mVt?%QkhZ2hXm%h&4Hl&)O0Wcf1O zXv#B+7mwq(UZX4YbMvBS&C^#d*Ox3=RlK0QR9~@j`NGmwtClQVq|b{Tn-QyDzEVFc zR=;$4N$D8*XmO@#WqI*Lt}>2(xLMpPn9Kdo%;7k@tw}NQF>wiH@e5-n#Eg$CON=co zn~)eE7n87XTq)4v#5;9{D=tZ{NM4yNteGv}Dh@HNooD2H=Ks&iVmI1!xBCBt|KIRG z(VfS+8D+0}Epqh*Mwu@deB|*38+jAGXy&lcb`L{{g#7Q%MZ>XA`M>k~b47!o)PTD! zp0n*35+vjflmA#UW?I8Q$c0Va!Jef8HpbiuM?X41YjkU?N1YocPb%%#3oQ-c3{RXVRe8lJB@q9=%a@eyd zuhVjj5`@QWiQA6Meq?K}zpbefreX2q{4f>#R@=}U^@zktj|(lZMgr3Vw3~&D06()P zBS5cVe1Kp2TLIeiGXWx}M{^Enwylw0SQjQYtP{N|a2dIlE_u3y@U#=SGwGK$fHu;;XkzR*T)z`^kk0pC`qS{&~KZI(eH^&{`E^I~AFzC(00{d)=$K{LLDBB-B4CzhIgobv|il@S#Z^j&lAT*g7zsn;_)#;{!{Y(k0%Q+J|%B|e8$L>-8S1$l7xe# z#GvE@>q`I*JxV4@$!^)p93fQimPeZJ7tZgNH<}}+L^7L=45x!`ihe}N1U8R=i~y}! z5azrEzmecT%;ha;Gf*22Qe*&jfXQE*;{wG-p?Bd`M(cMJ(J zCC~Hu*T*gbpy{No^aunqR%2|}lC|6LvM)?=YO%(A1EIKG5D1%TU zQQ}aNQ6{5IL&-y#kFpqLB}x^_W|VrAXHX8H97cH+8VoiUl{9PvrCluQI}Sbv_w8i1o7?O2JNhuVI6 ziKD$CQ9iYIywIH_-`qPsg8tfOgOk=F?cLWM)D;uu`}d6(swc`@_YD#n(&QKRjgO$e zy7?m}oa0bce7r%ho6wvt3;So7^qEHPc{fv3vTcIKPNvT>a={K6IIHakMMt|4?f>r4 zK11tlzZYM*Vf>05-s|)Sz@_YOH3k~`5H~R+(hx28hX9o$b`SM7dy7T2}I31oN zKa5ky9C<5F4G+mL(A8Y|+_Qrux(gYAKf3x`!#Ato`KD`qd9N8UMer?I$?xr+!Epnt za7h(zP+?)o^1?;s%NG=v7cQ(^zH$}EPvE&k7O{X&$ch2kwwW9^M5yE>4ZYF6jiW^6 z2<54b)**iHX3!6);P|j0s)4I%?*e}DEZx}^MozDvg?#PTPtu%j>U#`-L&l$HgPZtI zgz7~0TN8hQZ)NWu=M#E6B8A_39fPIaoXC2=!hh-G2#_v+*61UIHT8d$ZBb5pc`ZvGD})I}No@95VSMi2ldz8+j)xAzIBqEV z#m8_FZvzV(fhU7@Ow!P6a?Wr8`2D~mK0~Dnm0&P}N%ZP%*-~9y#TovY#IB4LCO|n0 zjuEB_UnR2Q7@_aLpWwM~!C<(BN`I_C1}})nLS;m7QqztYVW-9i^F)b~s%1>stJRx4_NM;ES2n~WUnSJztFwT1&<^i`Z znf0D6kcQC{(4gM~@3jgpX3$SI32k z-XEnJIT05lUJ>F#ui_$cK9W42E386Da8bvx+E!0uD_#L<^(2tu;s}vGfs3A`A!+P) zA`M9cDK64p728T2LZ(oV#$I_3u#ob|(l4SFu3CIBxvSd02ucv1P9bhM+ER>WUN!KVc186KAG29ehoAgcmv{ zvc7K!vnEEQ7&#+IUZYMzIQ24dD!?3o2}@DQN98lMRTOsQfk?~ea0zdvu*NrpFjFf? z))Q?9Dr8Q$)1=OAM&RD5Djx5|>Ei}&Y(G1$n!gJeYNF!h$%Tb0ODmSItSl^DxpMhR zj-SO>V|eFqG$(sOS;o>;i+~R7Rm74{2;qBMv{q1n#&g&W^xV9nsOshFtQ!FdtA;+gh|O(#zXFZ0O3O_j~UabDnzY|JT4$p9mp zb_zk-kjB=W63T?n(weTG60Y(>pt0%1X<_XHsIUoPn)Ts%$lLEf$Z?;~#$=@EO~kK= zsXOEkMs_|-6B>ThP7w?$H;Pzp$S20#12mzg{{lgpqj4fPWN^AFa*hLww~HK_fR-gr zlp9iFr!+e-Re3CDSb~^q}oARNK`(luDz(phx6CN%lybR%~dlEQDHasidd07xKCWkL?Q z446!7yiH!j6(|cK(MGpx2sVwminw@k${|8NE*rcgOZaY$g zLCF`xKAg*O4+7#JoXP_B!U^?Lm}#$OKAk_?tBDN$k16i-QAGdl6c)ZuGgl~@!q)GD zGMxA9(-?%cQ`m`pnn;10!aDb9O6fdvKk)D=Z1sN4XrVQW9oVmlqVs!%|1*pI*M3c$ zkekJ#p4CjE^O9$wa!FPXm0Ppe!Dlr^!r@G&ZO|<6K9`9UcrKHzXwXCq`wSP(E{%E{ zSBsF1Gj7>`{!er4b4`$z(P&@*^ZX(fp+U%qTn;qqnW>p8EPih_!K7I9Nk zF8m>%)!&5gjrpvVt{+jZ2e3K6YWfI)`E2R0nj9f1pS||0W}MJ^AM5^A(_w0Z(IZz? z7O#Yp7V-S3tXW3xhle=sr96Z%Jg3=F;DxiY5R5v5#t-Lk+&}D%l7>DqP@1(5a-#zC zu*t^oe&uYY4_vrW6~IZR@W5>{wWCFD)Hiu-*6*4TA^RV|CN7`j(ufM{JHl$z8xOGh z-!(zPXAiK0za#SfXS3GdH3NoxKU+2AHM>MfL(X&B`PhTZ@0Mmv;L8uHWYiI|l})>) z87@@JXj*wo!}Eg<&rt0$B9jscmK3!wsobdKnQVtmGt@L?Cj5gwJ?fxY4YSSyBtQJY z4ypr0yyA}6Oo?_(!lq{Dw}NVV2ZH~T)7?$-xto2M90pIf;U zL?5zKsEyqArydfAAzuH!Nu0n7CHJydd9hOHzL&)aV!UwcUREZEgG@K?HF7EF%cuZ! zJR6n!F(@Pf>+`4xV0pk+s2C;-eW-?3EoH`0W9%%oZY-05Edk3P?JP9I6^2z{m|Z?o{u;{cr%}UrWOCIS1Y&%fUAwQdW-+bnteon+{LIgpD8r`n8sK9)TbMSe+OY> zDl2T~2e9=zv4x%Y6Mb>F!|n|fqk<-f<8c8>uWqD@pFxfv7UC~P2|;sMy1y7UG-{5K z8;e}xHy4$3RGtN;KY1+{zwlGXcDB)9j2*nfPN>^wC%ld5g1`8z*I~4MIESqY5I^_n zK%J~BN^@Fw2{&G3*m&=MqLKUO9JUo!3gSbmE&U&|+cF)MJK54{x24!lsH?LRy4wOG z*iy=#?=2>KHGtsEL+qcu#ZKJjHC^l@?&pOYE7*!4F$@5!3leV$-E*7jg2hQQc#fT4 zD5eU(tzf<-h^+3pES=6=0b5%lj`pTkRJdsRbBTC1k?s&z?-Pqf+=4Z=HHszy_ft)C z4u~e~*AkmP{*x%<9wMn}`5`e}xtXYYLEK4q21EWV&d|`E!HSo}U@Q`;O1V+>BwJiE|KiZB^HS{^}5iU&eZ^Xst!@thvcri1=W ztig_;isM$tJ^|7Zq#^=Ga!QsjEA6%;WE39$5mzvt61v!YpgJ(vT@V?g_dq5CiSa-d z0x^0Z>w)BYAhkg1J&34F<5rW1xe893>j~-%d0E&|wd@2Z#-Ba*g5=AVuJCiCzOF+k?vjBp(E@ z!Y+9qklaD;CcX@W{-i^oKlM;;JOQZ2gY7*a4Ib*h210N6TifFfhlREgwW}&VG=fH9#6X`nnUyiyp`!Acs7V z*MS`HKt2I-*&&(69}d;3?>AjzHUfx|T2RyhiU*>1B8AJwj8BLkue_XfaixQ%2sAEa z29O31WG;{nC!*+I3<&ek&Q`c!%=mG!Nn8W;l4=cCSPUdChU;)5fVtJA%#&+e99NAN zm(kUv-jgOaj?+7%s&EpCjvdDpIUy2lCD9HSaf(54;}vBt(Yr}B`#wM#Ahi#{%?IvX zq+nmYLp{HTjnzp*g}nlcPL)DgxlZzldL3DEB`NSY8X-v?d~}wlmv)QTkdaa_pUwDC zX{fFe9e{agqv0LPHjPHxCHA{c8tnB~@HUTNt&vg~O9_;;)0#o-GV&CfxkyJ`6&9+o zR^&v;jt@Z7;q2^~%F=a}Kp}K{pcKJ3H@zGv4d(eu#TMUiEHkPti`kAysXzZU>)!|6 ztd3;HSdgD)#eJk-`37}0yumj0b!$A&VuPj8Y1S6X)h8Q5DcNMP2htKHxwI$nqKUJ0q{unbO_jf09$>e>H>ug7cUJ(`(<`>m~0djb0kU!$ifb7Ix1Nn01lN8c8EHXxJyH7x~@poo>ZA3iS|$V5o;*g)eW}Fmd>d`|}FRDq>^CETnOA9A80O#V934!qL34 zbX93(#i-jI0SZ^(e8fkqI*Ac0t}nu80{5q{ssq4MacMVJC5A1Ic&NIED~f+J?J^ zaL@?J;JeP@UH+#XLxNfEAW39pBc$K>8ns`QzHCb*ct*27N5a^A2yPgw49>{qsFygE zklKwv=sh-VR|L+X7WAP}F17QcFw+jJ(xd%Y!ALZvG1EwREilH-YeU&LBN4M#oDLg4 z2l+=GzlC`4jPKa6?_23Mgu9_0B9t_z%yC@!MY}ZLAB}!#*`^87P~QslTaD6eW(q-y zTF=;Mbnq}_G{-8VVY-MqeR<*XeFu;V59E6wF>#JAlN0AEL^CMceoJQa44G` z0~Zz%n-X(@`in6o=GcX39W-+atB$;h<3R9PK5He(_z#beot zaM2p-YAQuc7&|;s(we$c)d5m-TMe2kCOMG8it^%xr5yJqe1RxcRz!SX2b$x!kt7b< z<1JmVWDz~0cOZbdgP@_?Mmx>2<;5#OL$4)NglLX}rqz`0P)5+(fZ9BiT>)~%1L*|P z;eq@Fq`^b90P|X1CaTY5xxj2y7j*@;pxu~laEAr}s&EoH0v7K2I7JDf-&3TizH|?* zbb^ndf6&yPpckhi88oXd*9Wq#lfW>a{bdq{uOV9rSk^jJ@?puraJ(|$DQQ@Ht`Ud2 z_N-w)q^Z=d_yudSQHo&YLY`o+(Cq1UchUAF7*j&yDRCJ z?4weU=H^I!hQHcFMaNzFI@stO@LeFj!#(&q@5*(*<6|$O8!Q=I z>>RPuGZs&8+_)?2hvbIi#F{+=tn?A5Co4DIK8m*w6^lmq*m!WUGsL>N2dnn3tS=Dj zQDV)U3D&9}tbuoBjU-#+z{O4x>&hOip?76HNUVp6)tC#`#XVT{cVUfZWo6(xL0t6b zW1b$0ybD(Z)03_j!NpSU1M9RNtTA_G-A}9|!Np#spBeZGO1vv|IO#Y^O8pGUK0t)=v(Smi9-YX&D{ClO6ag;wH)0*sgEjxIth*Pc6Z70m`$Js6liA6zf=;A*%Nm*UC*vM>N# zY(KH??ZJBJZmhdW-!|e5p94<%rrvW94&RNF+)-^p?kKdJbBWc}2tf3Eq zb#V{Y=DV`~Myy`oV!Mg;p&qPf@5=fpb+d+8gXV%Yrw426U0K(VtsT_iox~dRzhM25 zSgXOs0t*nPdKYWilJZil%>EJ^Ux4Q;GqLD*On2Kh;bLQfx^41duLe5yX`Kbw3jJu` zI9%?dY`cb!!VFdKdm)kg2BJKVA|Tz zN%jo1z#R29N@Q;?kfyTwB56Fi%{R=x0dYRqbgr8s8}cw#cP-7)U6cpnFb(=%?&07W zq#I8ToC=;TmZl0uo^>pQh1mj~hX@mXWMdcL$yb5X(y*Y+|K7^S`nnO=NAux3DPva` z;vTI*(Ky6wf)PFUVzD7oKjk6MWH!A-8XW3{I|gH4`+b`-0Kq`IXQ}r_>ca~6E~Kds zA&q@$3$5HY>gWM*_bmJVf|uCKk`&x)B&3LW0NHyIhTyPH5`~;#)-Vbe^AaR))_^UG zVBatHy+*b{yKBE_WGAt|6D~-sdI|hxCu9cNZH%F{Y#maoF#on@KT5hGG%7z)^Vgy$ zw@590Xf9V`RtYC=Yra8KRiH`pFKSLvoALduGUC_J!0%;+i)mCnn)pO^FHm-UF(_^^ zehCItWx|7zcd4a(30l7JXo+F>fR24bEtfr7qFD>IEPfa*&F(EM2MXA1;OuMqdGul2 z^xLgFM@^RrEqMfd&v@`cx%5}xmd4`ruF z(|KwvSc=9Jk47U2n+BYHOpVbVjVGw_EH&mYLt`J0#uSn`1vvYV8aa=~SE=zdHRdfx z<8}6Vh11b2kt9wA&Mr~o#~zKxsIi$Eb1Tqz&e7O=nUugL0b&;jKkC4h@%|fWdYu|` zR-kdeM`H{LO9sx)QR7yR#+Rt^I5lRkL}QglV>C$|51gH$#uAUl7pUot$Z?a0`dB~(9z;`t(Bbl38IZjm zG>_S7kk;(VwgEW+O<3;i$a6sGb+b$T-+|Qgcp>P5&H|uOX&TCptz7n6dJu7 zQVRsjm>bdv1m7ERcyDL#_YojQXmxqw4Ip^(!}&L_a;o_Y=DYm&3XU@sRTq5YG|s-v>1CnQORWO@MMe z`jZ2M`s3>1LqNdgHWrJ4lz7lo1EIqudS?&h1dwRZxW>J;&j|c+oQLzS_aM3j#K0D< zlLnjou%)0w)lyitcIA@FQZCZNHA6gTh&on5jBd6Wfn4*jKZj^MT(h8uoRuOVJ?phz z8XUC=)f}gU!lk847gnt20zE9*4VuO5K9HOKO5`4+^BRyBodU?r_kg&@i}DlxkAFwY zJ+!_9&2bMd#~*6C(u!{oa-lPRNb=AqKz>k<|0@OWaDcRWSepipw8u~ zdoSX_-w^^i?4&O&q&JH9=3RCgS6Eh7zIxSSF4svzTn~e*)k#B0C6GNH#ytt-s0Z=~ z6CkaJxvv0mr2~3dxnx;oS+<9=cR)j5DC7V3PJRs}*F*HbfK+(+Pm2YP4p&fy1tZiG4)D~v~6zu^Sfv68Q_4bjOMuI@&GI1V|bxzlipbbDmJ>*z` zU;y35Y7Y?C;!=or5v9w5*Km3d*Zc)UnQY)=_)mtt7Q!YyhOGNGAo?W8J`l8DSiF)` zpM*MW{17zCy`X9;et!c}LE9B4?r%d?Y#(BX30Y!8G|#u9vWPnivVv%7j3Xu3V*RP{rE)6{i| zuJaH?N}f}YKsRNt1My7X7Ze(!8_g#`XuIe#u?q;kj&;-Zb3c6GMv>-HFNJbkIWAqx z*M zg8pKsaVcv7a@MK75Py(Rx^78jwTI*m&`@S}W#{im4(-ld7HRvlZ%k4|P$<4wq{G!R zx4EeEvdcqWQV*I8ATb_R%(BzC>{@2(!L}ZV@|GG3)!lsM^3~<)TN{THHiO2s zT9RpdfY5ljL?7%S`BV?&<1kEyEgo!LAacA|Qq?0%bLtx%hx%VY^STF@4v&!bLbn=3 zv?Ex$d`+p=BOFG8Cfi9vMo%7q$&l|9R7fENc(DiDe0n;C!xb1yfn++lsBIe%O4hDH ze6|Ny6Obwou73a-e%3=-J0MTT{t6`0m$g1F4H_AQjr*6-;hHKVfHZpuO#>3`%R%*~?p{zO2b2MVcy?EG>;IEG}QP92?Zd zOYyf*^v_9^aD^qMi^`W&E?jKq!&lgDBI4q>!sX>9g;)(1K7yt(-1V R(uzX+t$WjrJ2oqJ&fWKcm70Y@Aa6cG>v6?9ZIQ$#W{Q;Z=6u}~4mAC)%7=j+}XW+wFW-tYIH&wX_6 zJ@{ zbXeN;Swc{I0055X+C{lfVX73eo#P^R4e2KtKjJu%P3a>I*p)1@urx^*N4oYN%pI zGj6pg+vWMf2>E3pT;3&w^Lyl93nTcw@&`EYldt1kE5~X^@TKw$ocG8pasE`^i}M%q z+nNyqC&~ZN{3`0Ik>lFG!^sg*cG}3c3RAtYhwfTrTI4;V^@1*JR7HwPOY}W^r7{O5l#^H615!xm+Z~nI-Si z#t3f=lZX5jOYb(j{8sN_!sTJ|Uwco{9#mu;YLp-DofbW*n@NEcrbE6=F~l?` ze!l%QtO<9-L{=(6z;hhu`k03E3_4|kugJfrGvx1r;{wZZ+x|p`92F85SWESS40#&r zO;jJ1A(x~6E!72;CVn&Ot>ff>gv3SWQ@w5+0{2w-q6a;maITX-42`gus*RlP=#`US zXj8t|9jy>b$L<;Q3ruqxOuP*y-3AM|4HoEwWq1^8eLw~C-Y@8-J9^zi7o_6yv$`p6 z+s~bB)25s)9b45`wfkN{ceDqlxeX@X29s`s1>6P;1ZMfAV(o1RVS5i_f^LHa-v$e@ zz1#OT@Xu~+jBlrJ-iGi${+O)ovrsTq%S-#r7fg2fM4v>OYhU+C?5jl(EGl}}xsJ0w z6!PO4L0c`y_Z=nFR>}9_vaL$q(l=hnsghssJ7`4ac?4#f!4(lkm1qM}N(cg0dlXSd zfont|nQHrrw_WECiN~6W=X+gFm+t8I>Rfhx>;R=B7o288xP7A`#9=nf1h>Jl z5%%U9qS1a&76^S4KV&*@e%yHMJQ>U&$q4fzp=U5wV?q$1$-U$MF zb>4noxZ9eP>#mRG;)ns3e}cI^6`YRg;mEtAF{HYq8`Je3t55T;k7<-TNeL8^qM;z4 zxHi1wsyO!h*Un7mYO9PGrNTuI7Fia1 z(+g+6(cbGPmrHlF3z}wjEXRuBG!N%$QqI!|ZS5d0x-7b_E72Kyxxwgs^Lapyazm!` zC@P%&>y!p!&>h8uxnyhPX}+~$qW7YSKK|cpztSD;|6{Z5pH?IX`$rgKm!;QP=Ui*) z_-5Un27BXXmla}kRph^_23^&+xZ18-Z9iGoiS`e_sdYa2gv;gH{I4yf3~Hg;h>^&F zxkg>pH=xEqWjf6Q|GydXV>5;}(@|&vZcigckTayO zt?fU(nh=1xqm6Lx%#Kp;I$K(ULFOHE!q@e({e(d#Z=|^FPlR^_x?N|x8sdCnq;pQ< zTQoT65SVSZ`slU}g{{Zh;A@u>uwOL^t=Apga z{%8A1r#R6WJ{I?x_V$EM(mv5_$TDX;Max8p6v^*rHX-!1o5nl3rPE|p<+J`!!sct5}bLrsM)zOgUnSTHwNt16?&ng$<06`*kPj^b?ZWY z%HlerG0e`pZed(=V42Z**MB-9Ky(bSt0NsX)e#*#Z+3IK1<0L|yC@IZ2Ab&d_kqJH z9rlizL`iK0 zw|_YQUi-(kZ*v{MROrW#*SFX~#hBM{BfGrWA-;BnBxQRmy~6sE7Ojakz?} z#MFijj`eXp=Xjjb5hdHVDN@hd?+s6JL8bgqbj$!H5p4pcV;Uu*6pue^q9ZIy@+nt` z@DY$qeB3AbeD0z=)SY~$q1}^wE>iND3c#CuG@O!qa*=zGde)JhX)p#UzvDL;*BaZu zLY$9`bk6q7m}HE&g=UINnL-IIHdmi@cO$CP?C&EPXWDPs&nQU>kcj2io@lWBiM*f< zgVgp-@fd-eY-EwX=4_foE%sLXkBFW$qr!PY_O*4KN~kE6XC-Fxhh$sgFy0{lCNU;Az7qVW z5>?kJHaT;!9En)l%ha7aYz!M)Xb5*jkbr9Qp$04cFgzt;W81GBj8^cYa1s&GZ*qC(--OXM09VcV1zZM$9ma`ckW zYpac%;K(r;%t2?QYw~?b&qo;`!1iqcK$Ao3yvJp`A*~N|L_cM8$i2tJrR>*p+-2le zjAsajQCU>ez;e0Jpa*V*5>z8m&BQgV{jzKtlg#5eW=vGy1rE5Ze6SL8SeCfmRM0j764WXD(wzgrGYo6aAU?@5~x zwHS|TRE+R6L}gg`3i;WL$wQg$~hV}BN zms?t;{2lUztRw*!F*}zo^Rg4^V$FVoF3FRuLcxy1zn}CjFPL`7>x~)xFNWfIP+AIE zXSgBMc{pLg4*8TZE`dNyChSwqUEe%U?!4U6ZYO#?W%^NXo)amLnDSxz>E6gCh1e8w zj%4&qiMB>y2wNp&t&oUNZI1=!X@5~3HFa>GEh^HTBR`cFP1OgBG}Evi9|)57i)<^+!py<3OT>DKWq7FXB? zH?{Lnn&v3drZgZ57Qdubg{Hj(%hyjg2yHv${nKLv+?|*{x(~6~KdJsqSM?JD&X(OJ z-myRv61U2EXc2_rWViBz}aqy`hTH#x?~iuaUZh*pMy;^%&K5?SG<_K`Q-!*KSl z)L|sYJ;SPDe!Dgh(l#2RF{Piv1I+;4(T1107h40+l4}Upy^Yly%~i29m$|nsTk({x%8tG{H}Upt>Xmg94=>GzlH;RcMaOrjx!0i@dyL{9)eZ8WXAZU~ z-oV!2jO6h;mbJ))MthU(B%jc1?@a_R5!Zn_L`Fv*GM6KrXjN0ZKEMWT?Y(4IfIXX- zyb@^~)e${T!-@%IZ&BB$Bl076htcppare+DV)~{wrNMe*f;p1njP{3i%$2e7TX(0% zdPcmX6f%@BgrBL0MDjN|XjbAVlE8NiruN(V=`5(7dAuE?FBi{BwUEe;1dv-F<+-(i zHc1iS$X24>W$r~b=6g5zx;>UL-k6J-+{U67&>S3-T|bsK74a_0^h#~ z@zg4vLhyQXT!T}dI490PpzTx^?aHvs#=+ z`^F|uxo4o|D}=*Kr+{@7B0A1U4esWSITXXhV?QG`dB9A7%OxV$BV{SOYv&0=4a7NO zi1SR9!HOF?-bx;z-0Lx#bif}Kl*Ye*&BK685ud7Z%Bc@4( z{g!*-LAJmmSD`x^NTSO=M`@KhVXp4zUAzJvplNWagIccqwY8zOk(4ZeoYwbSHySoM zdLKl@IqP6Tvehf3%X2>h&^brtL-t{Q1=xvz6F923uP~ntOGST zIkUDnBKDzz?(t_w4X|5uO5Ys4p9W}Gn#MPQ&32l9i5SMGQzFnkS%ztfp(sE|Ex_oO zlS44lh45q$s4cegqA zY-)os8!WH}d(o=DA+Nd3z?xBWTSGRehD4GmuOY?%iy>EA&!seccCGb2o!kJ8h04wQ zElsUw39!J1mZmF>ttVS=w4VF?Yu%F?JWpJ1ZI!NJnzi(9YJfxEZ|U8IyDRVFXSV`4 zFh)V)dq}}Zfd3?>-i_9)#J@Mhm;V&;zo+sapk)c91sKs7YQS8zRND|)2Wat0xlVJJ zo+B@}TyC);5z&)=1=b!~kjJ0FV=oc~Aie!ZJJR2F?3Tb$^&(Jr#ziC6Sz9-JEKK?{PB(H;>?DZpk(Gu5vhqO6&V)BnlNel)aTZ7oCx4%oOxBEWkCF zTMyJWVrU~MJ7a2OwThTqBpa31v$lrb_Qr%8BR$d0pRDl5(_NnEEPP(<&ZqKRJ#rozboFM#EJfCLms@mO_F@!D z$D0jhx}EQ16)WA0m-KiYUwtb8iyX2!Mup~kG9LGJTbJYE!?qDix320tT91)Z%Z|G+ zl~b;lA}!4%i)MAm*mY0>SJq(8aY9+4`G#QVFSM(mt!=XIsMTu2c$@~03AD8AkH4j> z>JKYyU7~L1-%)YwFwo+USN`_1C%+!dpZ(|tmaj6r+245@&6Md8hy^L1>FNs%o2(xo zvlkdPQZD=)Z|^CmX*g$!_AGmUMyIL_yRhuG2vn;Vqxy&NEf~x_3ZK2ReO4oO`O|?b9q??n zNJUBmeueSwYi`#!3p)2Hji)*!|8?hv<4vj4ZL_EsQOZ+_;-pLrT(iZcYd302xr!hf^_gsW&zNYQK9 zfF{ChZ8`++QVL$^8sDX>x*wAW474NER2gWGXm6x&ZB)b6_H}RDjsChPEp?!)ZgA#n z97mL0r*38=-t%Oh?4oZoOyfIs&YhreNA&`VYV29m{fc2DjLURKc05IP>wAdpc*Hdo z1BLd8jvuJ2s`FqEZEW2gP=ecHFzK9Y;f_&=b96>&uQJf~)*aYXMPO^V^u6oQ2}+z- zF!p;4w8Mq(_Rt0KjajCQy(h-0S&eaoINc~?PZh*JnahIbktNXQ$?;Xm zc+qr>(l=&RG8v-Is+rxhYF5X`5J&r?_fi^shXuxao{zqNjf@8Hzdt2e&@CE8cMp9$ z(D4B2F%S1sL|F|qG%@MvPf=t7;PdQUqXPl^E&S4ti)R15wiedfJhQXC_kQ zc8RX)eF*S*rcv?=7P0~?WG!AF)_Agy+fSZ6q-G)Vp_+wWCKiaVfm70yrBPWp_d&qS<>7iyU{R9HMi>r&^7Sxh=AZUyf#FHDLg$w16u>7za1yR z_BQGGgW7X^*g!_-LhR`CG3>xhIQ+Dnd`x*4zMANm(um=Q47DPu=7zqqDi#mZ(qv4~_>0WhL zVrQqWx>Xv?1Y}d)lM8`$2R(>Axd>H?u8s+4_vC87PC+rf81e0!vVd4<1)&yiibV=H z*^y??w_t~xizVg=Vnpd%lY4EQd(wUq0_k;$J;b1PhHj9Q6%3hJ=@#9%ldU;K$+PBo zbYtB-B~+Awvd}!IZmWak9?UNMj{Jv#Ta4WjJKKL~!28H1@}{SO+}D2P4;a-MNH-p@ zkWRN(s7iDDn_YMSr$@Kl)XBtAP)}&RB!(fXpR5T@!T7J z7!tP2RB8k@Qag^reG0Ao?uGghGVrCHhqrB`ftMm6fY1lY+R)^5Th{ITa_4J2KD6&2ty0Pu+w4H`mqR zD?yp*=FggEJj{yiyoELg9A4US!;D;8|NrmT3h?Rw|MU0enq#2UVB}mp=h`(STre5r z#wAI!!T^T>?!->qw^YDJ{cZ3z^n-To$v$nhs2dIPq^14k{H0nU-%}NZ&S8hwE!`;& z=Ws-h&MEkL$Us=(nwq)n;H0JJM$?dTZGQsvE=uy@k;}*N{Y~4AoCRec$_bQfD3OlC z>mJ_T>#)91&;Q=MQ3%q5F$B>NvR3|jU6kCmP7I(G>yUDr9*@=n+~%xvxrXD)O$pU* z6{dxT*fi5Z^_pltG-S%Vq1q{@Lq&WrgD3;dOu6^^i2)6$wLB{4t)D7s5s3NnQ|s>y zFrn7;n0$48Y(N#NUp^-H-Hv5NB3qqBYRFje?HB&;vwu)0i!)?;E&3lE)u&Q5RnZT^Sz;c0Y`~_wLw!sI}L#|l@ zXtu~nkH(IC8r2%KKS26m^pnEFL1#k6>A__<1Ja|M0L?jzyzbFhsSVXg`I$#Y1%#os z%qpLKRPFps+}2@n#0TWQouAg-`RSo1%_8c&E+@DEG~2*XyT#=?DD#`5Tb~(@5Us}4|ap;fM6rtH6kKCLj=y%8q zH%}1EJLJ8a^G1qJmuo0E=pY{^qv(P4BLIgUg^W&g%As50q?u^iqYUSqEg8Zdr@VDb zT>nmhG%4wzpB1j5gzS{x-V)V6f2Yf3ARGsYre&>sr+jrws?fAkj66I_Z)sn=D%C;0vm+N5pJH4Z)=x9?w+)3nm0IM@ZrkmrKH;^#Z?pTS!#m zMGWIdh}veAht8LP)qb>VNPkPtdHmG~iWy}K%3hS$Q5sRsqkM(Zg%b2JoQRT!l8;h` zvH@i`N*&5ElyfMbqFhJOUQo3~;u?>VhLVFa55Vhf_1c<`fT1*qVt3*k^PxrjC|wSadGrFLXUUTdZfL7!b6>$BF}qn zoM23mw?7vvn9}7}pBooPe=GDNCZ6X|Rebum;5NaUAq)HREN$bB+$%n&sAM|?jhn1( zijj-($iP)?|F!68=ceMf*dFb9+V1vg`0D^=hN?v2xCq>pCGK|l!+iq8?=f4c{ z1V~43c0emc)ek(z*UlC4li2Y<;gVoVs((f++=tJ;wzJMeA(l5V-DqJXAI~O?7NP|G z7&d>jFfM=X82r{boZ~(l#&JW@FFu)zs|FS|0Df zOkzME`!=g}BWHMJ47)U1$bfPdktEC#UQS}gNkYGvqj2yyU@*Lm%0MhjhSR7_M`gq( zN%gyugx#7T%o8O_CiJ83#MRGD6&4Q`LbkIv?hziuAGxv6dBS0YJ9~GYFhOV^!(8(O z{7qLfOTSmB6}V*fmwSb=fti>GTxK%sQy}CEJCf^{6bM^2LS1tGH}?x81ytC8g+jXF zdyqL1($i4FsN1PrpP?y6?iux7lr(AE>nj!tiM)`U!k%9w48XO%evxpQ#~iBPyI81Q zAhe~j%%g%)$QsKYJ1Q&}*jV=Wqr${MHr9y0OB~Ba)C;MR&*LWZL1Y3xUs!{X;1Z54 z#+sAHR@Z~nmT@IrIm#Ebm6SA%+Z9xy^&A%2PN)0$TnKbm(|g_H{RNLkiq1 zM?KiYAVqo#H*7^l{egj+Uc6wi#_@rl;QgHa~gw?k;UGAP7^OQOl0lPX-eoicOURe6WQ8* zn$bedM0RkWCV{RW68_3W_QO6+st`7jCG6KsqU-YgP?<2%*F;6-tcmQ``!yz^Vgl1X zuX!kN`vj!G?GxDQ=QVM|UcgOvmqu0NZW*##JuFQm$E`<@el>v|dtTEDw=nqyQZ<2n z{DLMWGRDoC$mi3<#cN3FVDg0e=vvKGUTB-bOb0YS()EECHG_p8rm)9e)chRe+2l-1 zVjoH3X*T_!W~9JPWvdTrW(8`dBB(S|S>r*?=)h>YiJr=?AJilat;CI8!*RV2qVgOn zAL7wIl;(5_&RB;Q>|j%0)}#%7$4#jF#!cu?RR7e=8app=)9UrFXx7h-q^~lgufcjr zL!W*|YXYgNtz^HwuF1luo9v(0H3OsQW7yc0t5&Y6K%!i^l;a-`xeHqiNpq9wf5h-u zoow!pnt_7R$sYa@f3~i5GMTPzJJ^XIHHj1G6Vuq`<>laCW3F7j5-GK^pYpXRXRKWWAaHFvSjpEPZjuGL0vwH1vQk@o-WZp6OLX(TdH(B99DYDTjL!~6H{X8IJG8&*oqw0E+aB2kzh$t`;yI# zx{aa>x3nM8&y6-<@&vwzzx3&nD{>J z=F@uow~kb6-E{r$Qt5uapSF35@kTeHN|9LRrcfIZK?`qbhEc$7zNN|F1;aGZU!FET#!>PkX9VjJ3Qq&B$e;FQYy{WhN@~Fwi6c>+`5DfE55+tzwug^d}8u6lKOy zSKTbtJ}d(Kw;U`lx>;z3D-3JE5Q;|9akQI3H~SPl^4P**%yL%CCHR#c>$EY$!jS%!%q!PwkcRl8JvQ4 zBGfH*6aIqegJAK6fC{wjoy*pQh<^>LMV+iOP42etJRZEruyKK}ppkoJF53<(g;R4? zTUr4swgl(j-j*h}Ekn?**fPgW=xYmzU`q*mMJG-OFo9reKKqAGY{z3>{YPQq^SlsQ z$yWCjqW~~xU-6budr!TypExOx*RylQVzv-n$$}q3VAbBkrqH$S9=84=adaU4mVul4 z*B%m^GU*9%?Q>$Wh)1ycmKQ{efaj_D2VN8{*smqkfBKRr;~8R1{i>rAsPaUp^MA1ai;fi=s10XztA# zhDdSsp^{X_3pabS&SWW$f0aEKAUz?}_F_?i(hR{A$Q}xm7KGO!jwB2}LIy_?F0Tvh zgFq?H(%{$f2wLbxy_a?akQ%H(Jg0Ya*8n-EVL6Dbb9FSTRFOrM9Wxa+}0rXzSE1AB-sPIE%Ae}%gUZO)p)ZfEaRJy#f6mn`K zRRn{HqY*Uu13idBQvp|dk>x5^O;k5cMFok$%M@Rv6kMHzSP)hMSG1yd-LmCyT8xK? zIL<+t$q)G(nb?hhYxzphHB9m4x&fMVexVl`0EFkDM;&bZT``bT3gRArj=Kj?gC9`| zkS0IGMu?y2S4of`@*$8~KdwtatbRxbka88VC=rRb%YY*Nh-l;21dGufH%&N@Q{70> z%A|4WW5;u~e(HyTCJi*+zNP}v`yrEoSTPZ3E?DS<$0I;X-H?VWdMIh!*p%^{6;h}j zNHLJqWUiqbA+CqPWx`c8QRPZiSbVrr#&X7P$;7o5T(ur9i>hpFsv^j1wG~8d9wL<{ zbsT5(^N@oC0r7fhFLC)HF9Fd*te2(^h^ZS%fDZ1DfT*u3QIff2gBfTWZXt`)@Xrju zH+pzFkRo(?0E(4-9ojB-9A3ZK4#(^r5)f*Nf$cO5y#^Lb4j3B!_-B zdyW+cND)GOsFJ3A&X+zPDzSlouQKUe(IH?7y9wH zJS5gT4~o>8ppW&P2e&}e)}vEag^P?i0XacRrzAx3zK%!nZs#X{0zJ zJR-dArqQxT`=PJFSUDiMApm`)e+w+wsPuzu3}7FQlLiW%UhW`vC_(DWDx#$THZolL zRA_OVx>3uT3t_6B&53}}CbfVZ{m3K>iwA9V-oGmm;JVUSxgxN`qK! z7=Fn<n=bR78^Kk z56*%bRr6W(K#WG+U}gL~5<3Sy{5G#qLRl{s5DUUumH?j%b$YiQ^%w#?2_8{x z_#^wzVAybjY|zut#YT!)=#AL4`+Ekh3-lhnM)t2^QlMZ6VyE=d4Zh8*HuxsERbS+= zlthgA1r`_w4WYo3hbX}@tf;i2vSdw(IeEx0d#57gN#BT>yf;SDvU71#4Ije(8bdK2 zq(*4%0YVtNz3XNgW%aINB7CdaYYMbrjE~Knjr* zydjbc#N>y}2htYjF`BsO&sP?7(|866T6PTcIBO_7KTI+R3xeyrhDotJzf|o)c@WDQ z0h*z#XatPgOv;8SBQWx5)R%S(B{i=AX&B~F>`?>yb0oqYt$pJ$t!h;1hF}(!fTnad zHUSQ59_Hhqq3rntMBxdqgXXgJBVofk&;m*&1L~(rz4&3QVWd}nz$ob^->%9p3uf_& zXj;W)CxWvToYoPFYb`fW-{5C`FU+$FKO_=J=Lk=KsE6Z#(5DVw_s=4(cwd@FfN%*O z#N!34B8Osz{{D3s>pdDd-R+VYqhWG5duIsEfM8aJOv-O&jwIZ+B`7Xohq94JCnQTj zd&fwx3dTN4E)A0*>XwV+mLct;Ye9SOf>1X{*kqOCh)}Ll52u{3Qdc0Zmza~55SRDZ z1H++@rnu#|sE3X8bb@H!1(NKCd<>+*59t6BHp-VP5L2|q577f@@I%so=o5XprY8W( z_k)%IY3oKjUWK{0Qm}fUvol#)D%|+A>c$fxZ2MR#PN*5p-oTXzjLI4!oEWWo6i5!U zhG9`VMJ$5@wn77b7gXYk76t(~AEc?gZpuzocy1`o>nPUHM-l^`0vng)!-kt*r+ZX( zPQ-tvnU!g{P*mgX;QJYfRwWrh9Jv~mo5orRYq_No?X-oXjC)cR5ok^ zyzl~bXDkIll%;5WaplSl$hl+H!BJDt|9~PHJ4yBVps1p}cu5IlA-M3Ll8^B>IG}mj z(`)PzS3IeQ?a#e99Xxh5Dl)uQm45FG0k23IbSAle)hhAk8 zSZ?|ueSi>wmu4^!Yqv6zGYUu@ifT}i`d*W3&Q^61XClXCfPkCih44`akmPQ}6Nm8F z&WY++1+lj#N|OX@Nd1k8NTfood(a|vY*IERb^$BS#-N!dDPbstE1QHkRxuURwKE%w z$2s<|WURa8?Bz)+oi`%EbafJBM6!=e*r6yq3nn8ny4*^d!qmvv!tOJIxnhzxGU(=c z<1d)CQ=rhmHc#^Gaju22x2J&UY4+DC5K!YQ05`u7aD>nI@#Wb+i`LG7p zDISBf`8Sy*6YH(J2c|SBn$aBL8(5!l(qLxH!LDVaS7>lSA5WZSsd3uGN~R-D=VKfy zCR6vYLF_Au?Dgr`V*rVo;q9YohE&df$^JY8_S7oG?u}&aWE#`|n>|gcJ+*hioyXGyCsZI3$~+ zFUoLw%J*lgy&aQcU2`5(eN85ABG%`7upYW2Yu;RNm65$SiFJ1m*19{gZY58AMXZnE zG<;hR)?;^MJx5xXlGR?<%8=BVqJ&RaQbr_e>XMVk+q3fO{Dr7u|C{` zwfT;$GwuP`)70Tg@DDfjU~Rb_t9~9vw2-uR5?5{yuD088DMQ*Y4_u!T>qtVc*uE*aWJ z{1vE$>+eWyG=b(UQ9p>&@SDgs{?QkIJJzuIh=ZA==n}D(qZXcgJ3><_2>VlK7J_Ct zy^Zu2pLshjC18^72iH6@uZ37I^k6mKk#*z(aP1+j^XG%Lp$F^CJF*Uc09-~=eSuhC z@4=dXN7jSH`nF;ZFaBC0F zvO96I+J)fCBy-OZ>&hOi6?bHfT?DS9#5xP7;iev}8}7u)=dz&-v8!kzzIi?Ptas#_ z$@pd9n*pPT=k(y)c1J!V8@vd7r-(29zvp9{;8?scNC9(rq?fN0f0x2xCn&PAMR-ZE z0gG_W6rcSMZt50EaZ)7qc7pOwi{YJ?R^3HK6=EZF!Mo057nXt@)bJ=wZ0{3RKkOj= z4?DEfPEoeYEOoKe|L!*wz<0;^0gyVy33~U=_j?~i=w700J&xk(S4Ba20VhNY^@kSI zHj)ch9~rv(ux}s44rdJ8{19#0iqV7AB24dE{+Cm?0Uf4CNdx{ArR@rmq#B~X;Yo>(FcjvRxb%IxdjJ1S!~ z35aRFI#lZOUAKQ=_+<4RUnVld6!)W@j^5Fl@Ie;L#m-ey{+z1Uy%1w2kV0sX@&qX) zhO@e*Qkvk|yv?UQN(F7lM4a#rV{!=`b*V*sN;74~9bW&r`a-5#0#!vkkS3UxK8#PAbggN8O`7JdD5c{)4G4f%_;1T+8 zIe;o^io}Vp^W$r$MuC|3QsZvF#?lqQt<)Hf6TiXJcya}Lc#H7egqL}6C6XUn349}o z4Z{h~EWT#8QR5A2+)0gTevJ>V0=|KChTsJAeK{{t<8^A>PK`l+jSDM)n@P47C%%jA zs_;6sg&O}&ja#YlE5FA1tASULY!N5^yr=PZtI@@)gl{3d(Ss{poL33F9AfvP@UQ!} z;l*bwbhAy=ve&QW61#sjT5eLy7QdDj_6fB-23vTuZ;Nn2Vh>X0Syd?ovMy>b^lk6g z?A;12r)L@i5wV%H<`$v~`m~3j4j>!nv-~yq1zg?!df24c(%^(wQJvW>p=d?PiX|0~a_Vaaj4r9=-T}>0_7uo1EvV)I z^*Z%SAcwjI5P266?|4yS!han7buNihMfUH9&v*Q|;(^fN%_nI<4t2*5wdE!NqW>$C zSI`4M)NQ}V+A<&;rm(_CrDV%m)GOS(Dpj!!i25)@^hHI}<`oppDYynxRGCGkrR8ha zlyTZAzGESStFxPiOxX|QX+PtR0XgD_oU#Cl_cQkkAl}?SKl?3TX)fjbl>Hkt^tlH9 zb9+mNH7egv^dKPRFvv@j0)!54P)-Y9OurQS65Ru$L_g6hfcSf8Bar-V(M6?|CB;k8 zd!w&Eo&ilK`^RI_;E6AzTHt5fn?Q`+Jt|sKj4ynbaPi#;S=j)ZZEVWp2&qp|rNcYp z{@DZJ@R3lRpOU^nl&33jsw0~KgsNVbj3WexSMnS;mzQRd1<)a*Z|6$fg1l@SfS9{o zLL&D9q519=bdV6Vc>RAEhl@!x?a8itWis2~yHYpTL-E<#d(oa;u4)+}GPvbdZ( zX7o4#A95%|*4&K{m(c>Yjop)}sB}sBsx>8?`tr%spFGgeFD72UECxb{*PE;T5XukB z@$oqAy1Yi)K|?E(R}SlM!EdpC&>=rTq~vV{3G-3*7a;y=xI>}w&7#+V&=$~ZqKI#8 zD9?D+_Z@)Wh$u~XA^JxE%W>;nyCwjk&r(#HqT+|}Cq!60r+6GoCeC!zc>7umq^z5Z zXtn^M!)s6t5R3ZG$m8mLZX&Px!$4~N1U0#7yvn`+LMw)f6ydx2k`2qvnSLhz3>r$q z-c+o`_jerjFg_Lyjbug(f^sZ1`L)ahlGE*%B82J6B`YePHu`$O)Pw5@AT)ox{(S}r z{nY10UIt?I>)_cCw;(L7c#knZA#*5f3J=pdDsTob(C!@$A=2dIUYmB}QIRF~(qDiJ5211_)dPSe?A^CC- zuQgXWkY*GM4ypj!;Z1sfe+=WhdI^i%%|5L&zNpHlEoJNMu^4`hQMS38j5 zRzGFe0Qoz%Ki+w1gV^vbQtZevsDB9^-bpkS$O%883xR|Lv6Y~=l%P(B*YsZj@lP-> z0NG~r?eK4aKdjAT9_DHJZ{)M}wk}|Bm#VbnigI&o(YnK%jSJnsHq=z&t zc`LsCdUdOm5v=SViq@_vURJ_B-zxnpFsTB6*^-pZ+N$toDQ}w;#4@%?8SEcVN-1ph zHfdQmLBH+NVis!0gZGZ@(kPZ{$5(^R+ojTAyamIPBz-H`4~YBwALLFD+VA zyrQDK1TC4Vcr1biy9MbOI_36(@a=`xqa~m3% diff --git a/rtl_wmbus.c b/rtl_wmbus.c index d4fed4f..beb4bdc 100644 --- a/rtl_wmbus.c +++ b/rtl_wmbus.c @@ -55,6 +55,14 @@ #include "net_support.h" #endif +#ifndef TIME2_ALGORITHM_ENABLED +#define TIME2_ALGORITHM_ENABLED 1 +#endif + +#ifndef RUN_LENGTH_ALGORITHM_ENABLED +#define RUN_LENGTH_ALGORITHM_ENABLED 1 +#endif + static const uint32_t ACCESS_CODE_T1_C1 = 0b0101010101010000111101u; static const uint32_t ACCESS_CODE_T1_C1_BITMASK = 0x3FFFFFu; static const unsigned ACCESS_CODE_T1_C1_ERRORS = 1u; // 0 if no errors allowed @@ -786,11 +794,13 @@ static void time2_algorithm_s1(unsigned bit, unsigned rssi, struct time2_algorit static int opts_run_length_algorithm_enabled = 1; -static int opts_time2_algorithm_enabled = 1; +static int opts_time2_algorithm_enabled = TIME2_ALGORITHM_ENABLED; static unsigned opts_decimation_rate = 2u; static int opts_s1_t1_c1_simultaneously = 0; static int opts_accurate_atan = 1; int opts_show_used_algorithm = 0; +static int opts_t1_c1_processing_enabled = 1; +static int opts_s1_processing_enabled = 1; static const unsigned opts_CLOCK_LOCK_THRESHOLD_T1_C1 = 2; // Is not implemented as option yet. static const unsigned opts_CLOCK_LOCK_THRESHOLD_S1 = 2; // Is not implemented as option yet. @@ -806,6 +816,7 @@ static void print_usage(const char *program_name) fprintf(stdout, "\t-v show used algorithm in the output\n"); fprintf(stdout, "\t-V show version\n"); fprintf(stdout, "\t-s receive S1 and T1/C1 datagrams simultaneously. rtl_sdr _MUST_ be set to 868.625MHz (-f 868.625M)\n"); + fprintf(stdout, "\t-p [T,S] to disable processing T1/C1 or S1 mode.\n"); } static void print_version(void) @@ -818,13 +829,28 @@ static void process_options(int argc, char *argv[]) { int option; - while ((option = getopt(argc, argv, "ad:r:vVst:")) != -1) + while ((option = getopt(argc, argv, "ad:p:r:vVst:")) != -1) { switch (option) { case 'a': opts_accurate_atan = 0; break; + case 'p': + if (strcmp(optarg, "T") == 0 || strcmp(optarg, "t") == 0) + { + opts_t1_c1_processing_enabled = 0; + } + else if (strcmp(optarg, "S") == 0 || strcmp(optarg, "s") == 0) + { + opts_s1_processing_enabled = 0; + } + else + { + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + break; case 'r': if (strcmp(optarg, "0") == 0) { @@ -931,6 +957,190 @@ static void shift_freq_plus_minus325(float *iplus, float *qplus, float *iminus, *qminus = qx - iz; } +typedef void (*t1_c1_signal_chain_prototype)(float i_t1_c1, float q_t1_c1, + struct time2_algorithm_t1_c1 *t2_algo_t1_c1, + struct runlength_algorithm_t1_c1 *rl_algo_t1_c1, + float (*polar_discriminator_t1_c1_function)(float i, float q)); + +void t1_c1_signal_chain(float i_t1_c1, float q_t1_c1, + struct time2_algorithm_t1_c1 *t2_algo_t1_c1, + struct runlength_algorithm_t1_c1 *rl_algo_t1_c1, + float (*polar_discriminator_t1_c1_function)(float i, float q)) +{ + static int16_t old_clock_t1_c1 = INT16_MIN; + static unsigned clock_lock_t1_c1 = 0; + + // Demodulate. + const float _delta_phi_t1_c1 = polar_discriminator_t1_c1_function(i_t1_c1, q_t1_c1); + //int16_t demodulated_signal = (INT16_MAX-1)*delta_phi; + //fwrite(&demodulated_signal, sizeof(demodulated_signal), 1, demod_out); + + // Post-filtering to prevent bit errors because of signal jitter. + const float delta_phi_t1_c1 = lp_fir_butter_800kHz_100kHz_160kHz(_delta_phi_t1_c1); + //const float delta_phi_t1_c1 = equalizer_t1_c1(_delta_phi_t1_c1, _delta_phi_t1_c1 >= 0.f ? 1.f : -1.f); + //const float delta_phi_s1 = equalizer_s1(_delta_phi_s1, _delta_phi_s1 >= 0.f ? 1.f : -1.f); + //int16_t demodulated_signal = (INT16_MAX-1)*delta_phi; + //fwrite(&demodulated_signal, sizeof(demodulated_signal), 1, demod_out2); + + // Get the bit! + unsigned bit_t1_c1 = (delta_phi_t1_c1 >= 0) ? (1u<= 0) ? INT16_MAX : INT16_MIN; + //fwrite(&clock, sizeof(clock), 1, clock_out); + + if (clock_t1_c1 > old_clock_t1_c1) + { // Clock signal rising edge detected. + clock_lock_t1_c1 = 1; + } + else if (clock_t1_c1 == INT16_MAX) + { // Clock signal is still high. + if (clock_lock_t1_c1 < opts_CLOCK_LOCK_THRESHOLD_T1_C1) + { // Skip up to (opts_CLOCK_LOCK_THRESHOLD_T1_C1 - 1) clock bits + // to get closer to the middle of the data bit. + clock_lock_t1_c1++; + } + else if (clock_lock_t1_c1 == opts_CLOCK_LOCK_THRESHOLD_T1_C1) + { // Sample data bit at CLOCK_LOCK_THRESHOLD_T1_C1 clock bit position. + clock_lock_t1_c1++; + time2_algorithm_t1_c1(bit_t1_c1, rssi_t1_c1, t2_algo_t1_c1); + //int16_t u = bit ? (INT16_MAX-1) : 0; + //fwrite(&u, sizeof(u), 1, bits_out); + } + } + old_clock_t1_c1 = clock_t1_c1; + // --- clock recovery section end --- + } + #endif + // --- time2 algorithm section end --- +} + +void t1_c1_signal_chain_empty(float i_t1_c1, float q_t1_c1, + struct time2_algorithm_t1_c1 *t2_algo_t1_c1, + struct runlength_algorithm_t1_c1 *rl_algo_t1_c1, + float (*polar_discriminator_t1_c1_function)(float i, float q)) +{ +} + +typedef void (*s1_signal_chain_prototype)(float i_s1, float q_s1, + struct time2_algorithm_s1 *t2_algo_s1, + struct runlength_algorithm_s1 *rl_algo_s1, + float (*polar_discriminator_s1_function)(float i, float q)); + +void s1_signal_chain(float i_s1, float q_s1, + struct time2_algorithm_s1 *t2_algo_s1, + struct runlength_algorithm_s1 *rl_algo_s1, + float (*polar_discriminator_s1_function)(float i, float q)) +{ + static int16_t old_clock_s1 = INT16_MIN; + static unsigned clock_lock_s1 = 0; + + // Demodulate. + const float _delta_phi_s1 = polar_discriminator_s1_function(i_s1, q_s1); + //int16_t demodulated_signal = (INT16_MAX-1)*delta_phi; + //fwrite(&demodulated_signal, sizeof(demodulated_signal), 1, demod_out); + + // Post-filtering to prevent bit errors because of signal jitter. + const float delta_phi_s1 = lp_fir_butter_800kHz_32kHz_36kHz(_delta_phi_s1); + //const float delta_phi_t1_c1 = equalizer_t1_c1(_delta_phi_t1_c1, _delta_phi_t1_c1 >= 0.f ? 1.f : -1.f); + //const float delta_phi_s1 = equalizer_s1(_delta_phi_s1, _delta_phi_s1 >= 0.f ? 1.f : -1.f); + //int16_t demodulated_signal = (INT16_MAX-1)*delta_phi; + //fwrite(&demodulated_signal, sizeof(demodulated_signal), 1, demod_out2); + + // Get the bit! + unsigned bit_s1 = (delta_phi_s1 >= 0) ? (1u<= 0) ? INT16_MAX : INT16_MIN; + //fwrite(&clock, sizeof(clock), 1, clock_out); + + if (clock_s1 > old_clock_s1) + { // Clock signal rising edge detected. + clock_lock_s1 = 1; + } + else if (clock_s1 == INT16_MAX) + { // Clock signal is still high. + if (clock_lock_s1 < opts_CLOCK_LOCK_THRESHOLD_S1) + { // Skip up to (opts_CLOCK_LOCK_THRESHOLD_S1 - 1) clock bits + // to get closer to the middle of the data bit. + clock_lock_s1++; + } + else if (clock_lock_s1 == opts_CLOCK_LOCK_THRESHOLD_S1) + { // Sample data bit at CLOCK_LOCK_THRESHOLD_S1 clock bit position. + clock_lock_s1++; + time2_algorithm_s1(bit_s1, rssi_s1, t2_algo_s1); + //int16_t u = bit ? (INT16_MAX-1) : 0; + //fwrite(&u, sizeof(u), 1, bits_out); + } + } + old_clock_s1 = clock_s1; + // --- clock recovery section end --- + } + #endif + // --- time2 algorithm section end --- +} + +void s1_signal_chain_empty(float i_s1, float q_s1, + struct time2_algorithm_s1 *t2_algo_s1, + struct runlength_algorithm_s1 *rl_algo_s1, + float (*polar_discriminator_s1_function)(float i, float q)) +{ +} + int main(int argc, char *argv[]) { #if WINDOWS_BUILD == 1 @@ -943,9 +1153,9 @@ int main(int argc, char *argv[]) const int fs_kHz = opts_decimation_rate*800; // Sample rate [kHz] as a multiple of 800 kHz. float i_t1_c1, q_t1_c1; float i_s1, q_s1; + + unsigned decimation_rate_index = 0; - int16_t old_clock_t1_c1 = INT16_MIN, old_clock_s1 = INT16_MIN; - unsigned clock_lock_t1_c1 = 0, clock_lock_s1 = 0; struct time2_algorithm_t1_c1 t2_algo_t1_c1; time2_algorithm_t1_c1_reset(&t2_algo_t1_c1); @@ -959,6 +1169,9 @@ int main(int argc, char *argv[]) struct runlength_algorithm_s1 rl_algo_s1; runlength_algorithm_reset_s1(&rl_algo_s1); + t1_c1_signal_chain_prototype process_t1_c1_chain = opts_t1_c1_processing_enabled ? t1_c1_signal_chain: t1_c1_signal_chain_empty; + s1_signal_chain_prototype process_s1_chain = opts_s1_processing_enabled ? s1_signal_chain : s1_signal_chain_empty; + float (*polar_discriminator_t1_c1_function)(float i, float q) = opts_accurate_atan ? polar_discriminator_t1_c1 : polar_discriminator_t1_c1_inaccurate; float (*polar_discriminator_s1_function)(float i, float q) = opts_accurate_atan ? polar_discriminator_s1 : polar_discriminator_s1_inaccurate; @@ -995,8 +1208,8 @@ int main(int argc, char *argv[]) for (size_t k = 0; k < sizeof(samples)/sizeof(samples[0]); k += 2) // +2 : i and q interleaved { - const float i_unfilt = ((float)samples[k] - 127.5f); - const float q_unfilt = ((float)samples[k + 1] - 127.5f); + const float i_unfilt = ((float)(samples[k]) - 127.5f); + const float q_unfilt = ((float)(samples[k + 1]) - 127.5f); // rtl_sdr -f 868.35M -s 2400000 - 2>/dev/null | build/rtl_wmbus -d 3 //shift_freq(&i_unfilt, &q_unfilt, 600, 2400); @@ -1015,145 +1228,30 @@ int main(int argc, char *argv[]) // Low-Pass-Filtering before decimation is necessary, to ensure // that i and q signals don't contain frequencies above new sample - // rate. - // The sample rate decimation is realised as sum over i and q, - // which must not be divided by decimation factor before - // demodulating (atan2(q,i)). -#if 0 - i_t1_c1 = lp_fir_butter_1600kHz_160kHz_200kHz_t1_c1(i_t1_c1_unfilt, 0); - q_t1_c1 = lp_fir_butter_1600kHz_160kHz_200kHz_t1_c1(q_t1_c1_unfilt, 1); - - i_s1 = lp_fir_butter_1600kHz_160kHz_200kHz_s1(i_s1_unfilt, 0); - q_s1 = lp_fir_butter_1600kHz_160kHz_200kHz_s1(q_s1_unfilt, 1); -#elif 0 - i = lp_ppf_butter_1600kHz_160kHz_200kHz(i_unfilt, 0); - q = lp_ppf_butter_1600kHz_160kHz_200kHz(q_unfilt, 1); -#elif 0 - i = lp_firfp_butter_1600kHz_160kHz_200kHz(i_unfilt, 0); - q = lp_firfp_butter_1600kHz_160kHz_200kHz(q_unfilt, 1); -#elif 0 - i = lp_ppffp_butter_1600kHz_160kHz_200kHz(i_unfilt, 0); - q = lp_ppffp_butter_1600kHz_160kHz_200kHz(q_unfilt, 1); -#else - // Moving average can be viewed as a low pass filter. - + // rate. Moving average can be viewed as a low pass filter. i_t1_c1 = moving_average_t1_c1(i_t1_c1_unfilt, 0); q_t1_c1 = moving_average_t1_c1(q_t1_c1_unfilt, 1); - i_s1 = moving_average_s1(i_s1_unfilt, 0); - q_s1 = moving_average_s1(q_s1_unfilt, 1); -#endif - #if 0 equalizer_complex_t1_c1(&i_t1_c1, &q_t1_c1); #endif + // Low-Pass-Filtering before decimation is necessary, to ensure + // that i and q signals don't contain frequencies above new sample + // rate. Moving average can be viewed as a low pass filter. + i_s1 = moving_average_s1(i_s1_unfilt, 0); + q_s1 = moving_average_s1(q_s1_unfilt, 1); + + #if 0 + equalizer_complex_s1(&i_s1, &q_s1); // FIXME: Function does not exist. + #endif + ++decimation_rate_index; if (decimation_rate_index < opts_decimation_rate) continue; decimation_rate_index = 0; - // Demodulate. - const float _delta_phi_t1_c1 = polar_discriminator_t1_c1_function(i_t1_c1, q_t1_c1); - const float _delta_phi_s1 = polar_discriminator_s1_function(i_s1, q_s1); - //int16_t demodulated_signal = (INT16_MAX-1)*delta_phi; - //fwrite(&demodulated_signal, sizeof(demodulated_signal), 1, demod_out); - - // Post-filtering to prevent bit errors because of signal jitter. - const float delta_phi_t1_c1 = lp_fir_butter_800kHz_100kHz_160kHz(_delta_phi_t1_c1); - const float delta_phi_s1 = lp_fir_butter_800kHz_32kHz_36kHz(_delta_phi_s1); - //const float delta_phi_t1_c1 = equalizer_t1_c1(_delta_phi_t1_c1, _delta_phi_t1_c1 >= 0.f ? 1.f : -1.f); - //const float delta_phi_s1 = equalizer_s1(_delta_phi_s1, _delta_phi_s1 >= 0.f ? 1.f : -1.f); - //int16_t demodulated_signal = (INT16_MAX-1)*delta_phi; - //fwrite(&demodulated_signal, sizeof(demodulated_signal), 1, demod_out2); - - // Get the bit! - unsigned bit_t1_c1 = (delta_phi_t1_c1 >= 0) ? (1u<= 0) ? (1u<= 0) ? INT16_MAX : INT16_MIN; - const int16_t clock_s1 = (bp_iir_cheb1_800kHz_22kHz_30kHz_34kHz_42kHz(delta_phi_s1 * delta_phi_s1) >= 0) ? INT16_MAX : INT16_MIN; - //fwrite(&clock, sizeof(clock), 1, clock_out); - - if (clock_t1_c1 > old_clock_t1_c1) - { // Clock signal rising edge detected. - clock_lock_t1_c1 = 1; - } - else if (clock_t1_c1 == INT16_MAX) - { // Clock signal is still high. - if (clock_lock_t1_c1 < opts_CLOCK_LOCK_THRESHOLD_T1_C1) - { // Skip up to (opts_CLOCK_LOCK_THRESHOLD_T1_C1 - 1) clock bits - // to get closer to the middle of the data bit. - clock_lock_t1_c1++; - } - else if (clock_lock_t1_c1 == opts_CLOCK_LOCK_THRESHOLD_T1_C1) - { // Sample data bit at CLOCK_LOCK_THRESHOLD_T1_C1 clock bit position. - clock_lock_t1_c1++; - time2_algorithm_t1_c1(bit_t1_c1, rssi_t1_c1, &t2_algo_t1_c1); - //int16_t u = bit ? (INT16_MAX-1) : 0; - //fwrite(&u, sizeof(u), 1, bits_out); - } - } - old_clock_t1_c1 = clock_t1_c1; - - if (clock_s1 > old_clock_s1) - { // Clock signal rising edge detected. - clock_lock_s1 = 1; - } - else if (clock_s1 == INT16_MAX) - { // Clock signal is still high. - if (clock_lock_s1 < opts_CLOCK_LOCK_THRESHOLD_S1) - { // Skip up to (opts_CLOCK_LOCK_THRESHOLD_S1 - 1) clock bits - // to get closer to the middle of the data bit. - clock_lock_s1++; - } - else if (clock_lock_s1 == opts_CLOCK_LOCK_THRESHOLD_S1) - { // Sample data bit at CLOCK_LOCK_THRESHOLD_S1 clock bit position. - clock_lock_s1++; - time2_algorithm_s1(bit_s1, rssi_s1, &t2_algo_s1); - //int16_t u = bit ? (INT16_MAX-1) : 0; - //fwrite(&u, sizeof(u), 1, bits_out); - } - } - old_clock_s1 = clock_s1; - // --- clock recovery section end --- - } - #endif - // --- time2 algorithm section end --- + process_t1_c1_chain(i_t1_c1, q_t1_c1, &t2_algo_t1_c1, &rl_algo_t1_c1, polar_discriminator_t1_c1_function); + process_s1_chain(i_s1, q_s1, &t2_algo_s1, &rl_algo_s1, polar_discriminator_s1_function); } } diff --git a/rtl_wmbus.py b/rtl_wmbus.py new file mode 100755 index 0000000..a5ea4ce --- /dev/null +++ b/rtl_wmbus.py @@ -0,0 +1,73 @@ +import sys +import os +import traceback +import subprocess +import psutil +import signal +from time import time + + +__rtl_sdr = None +__rtl_wmbus = None + + +def __signal_handler(signal, frame): + global __rtl_sdr, __rtl_wmbus + + if __rtl_wmbus: + #print("Terminating rtl_wmbus") + __rtl_wmbus.kill() + __rtl_wmbus.wait() + + if __rtl_sdr: + #print("Terminating rtl_sdr") + __rtl_sdr.kill() + __rtl_sdr.wait() + + +def _main(args): + global __rtl_sdr, __rtl_wmbus + + #"/C/Program Files/PothosSDR/bin/rtl_sdr" -f 868.95M -s 1600000 - 2>/dev/null | build/rtl_wmbus_x64.exe -v + #"C:\Program Files\PothosSDR\bin\rtl_sdr" -f 868.95M -s 1600000 - 2>NUL | build\rtl_wmbus_x64.exe -v + + try: + signal.signal(signal.SIGINT, __signal_handler) + + __rtl_sdr = subprocess.Popen([r"c:\Program Files\PothosSDR\bin\rtl_sdr", "-f", "868.95M", "-s", "1600000", "-"], stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + psutil.Process(__rtl_sdr.pid).nice(psutil.REALTIME_PRIORITY_CLASS) + + __rtl_wmbus = subprocess.Popen([r"d:\rtl-wmbus\build\rtl_wmbus_x64.exe", "-v"], stdin=__rtl_sdr.stdout, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) + psutil.Process(__rtl_wmbus.pid).nice(psutil.REALTIME_PRIORITY_CLASS) + + psutil.Process(os.getpid()).nice(psutil.REALTIME_PRIORITY_CLASS) + + #__rtl_sdr.stdout.close() # Allow rtl_sdr to receive a SIGPIPE if rtl_wmbus exits. + + t1 = time() + rate = 0 + while __rtl_sdr.poll() is None and __rtl_wmbus.poll() is None: + s = __rtl_wmbus.stdout.readline().decode('utf-8').rstrip('\n').rstrip('\r') + t2 = time() + + if s.find("T1;1") >= 0 or s.find("C1;1") >= 0 or s.find("S1;1") >= 0: + rate += 1 + print(s) + else: + pass + + dt = t2 - t1 + if dt >= 10: + #print(rate/dt, file=sys.stderr) + t1 = t2 + rate = 0 + + return 0 + + except Exception as e: + print(traceback.print_exc()) + return 1 + + +if __name__ == '__main__': + sys.exit(_main(sys.argv))