From bedf682ef267c519c3aaa69051a2f9884598254f Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 4 Mar 2020 07:51:27 +0100 Subject: [PATCH] LoRaMod refoctoring to ChirpChat --- ...d_payload.png => ChirpChatMod_payload.png} | Bin ...d_payload.xcf => ChirpChatMod_payload.xcf} | Bin doc/img/ChirpChatMod_plugin.png | Bin 0 -> 45998 bytes ...Mod_plugin.xcf => ChirpChatMod_plugin.xcf} | Bin 153474 -> 154747 bytes doc/img/LoRaMod_plugin.png | Bin 45855 -> 0 bytes plugins/channeltx/CMakeLists.txt | 2 +- plugins/channeltx/modchirpchat/CMakeLists.txt | 67 +++ .../chirpchatmod.cpp} | 431 +++++++++--------- .../loramod.h => modchirpchat/chirpchatmod.h} | 44 +- .../chirpchatmodbaseband.cpp} | 50 +- .../chirpchatmodbaseband.h} | 46 +- .../chirpchatmodencoder.cpp} | 38 +- .../chirpchatmodencoder.h} | 18 +- .../chirpchatmodencoderascii.cpp} | 4 +- .../chirpchatmodencoderascii.h} | 8 +- .../chirpchatmodencoderlora.cpp} | 8 +- .../chirpchatmodencoderlora.h} | 8 +- .../chirpchatmodencodertty.cpp} | 8 +- .../chirpchatmodencodertty.h} | 8 +- .../chirpchatmodgui.cpp} | 212 ++++----- .../chirpchatmodgui.h} | 20 +- .../chirpchatmodgui.ui} | 6 +- .../chirpchatmodplugin.cpp} | 42 +- .../chirpchatmodplugin.h} | 12 +- .../chirpchatmodsettings.cpp} | 25 +- .../chirpchatmodsettings.h} | 10 +- .../chirpchatmodsource.cpp} | 124 ++--- .../chirpchatmodsource.h} | 39 +- .../chirpchatmodwebapiadapter.cpp} | 22 +- .../chirpchatmodwebapiadapter.h} | 14 +- .../{modlora => modchirpchat}/readme.md | 28 +- plugins/channeltx/modlora/CMakeLists.txt | 67 --- sdrbase/resources/webapi.qrc | 2 +- sdrbase/resources/webapi/doc/html2/index.html | 360 +++++++-------- .../doc/swagger/include/ChannelSettings.yaml | 4 +- .../doc/swagger/include/ChirpChatDemod.yaml | 2 +- .../doc/swagger/include/ChirpChatMod.yaml | 12 +- .../webapi/doc/swagger/include/LoRaDemod.yaml | 173 ------- .../resources/webapi/doc/swagger/swagger.yaml | 4 +- sdrbase/webapi/webapirequestmapper.cpp | 12 +- .../api/swagger/include/ChannelSettings.yaml | 4 +- .../api/swagger/include/ChirpChatDemod.yaml | 2 +- .../api/swagger/include/ChirpChatMod.yaml | 12 +- swagger/sdrangel/api/swagger/swagger.yaml | 4 +- swagger/sdrangel/code/html2/index.html | 360 +++++++-------- .../code/qt5/client/SWGChannelReport.cpp | 50 +- .../code/qt5/client/SWGChannelReport.h | 14 +- .../code/qt5/client/SWGChannelSettings.cpp | 50 +- .../code/qt5/client/SWGChannelSettings.h | 14 +- ...odReport.cpp => SWGChirpChatModReport.cpp} | 44 +- ...oRaModReport.h => SWGChirpChatModReport.h} | 20 +- ...ttings.cpp => SWGChirpChatModSettings.cpp} | 168 +++---- ...odSettings.h => SWGChirpChatModSettings.h} | 20 +- .../code/qt5/client/SWGModelFactory.h | 16 +- 54 files changed, 1265 insertions(+), 1443 deletions(-) rename doc/img/{LoRaMod_payload.png => ChirpChatMod_payload.png} (100%) rename doc/img/{LoRaMod_payload.xcf => ChirpChatMod_payload.xcf} (100%) create mode 100644 doc/img/ChirpChatMod_plugin.png rename doc/img/{LoRaMod_plugin.xcf => ChirpChatMod_plugin.xcf} (92%) delete mode 100644 doc/img/LoRaMod_plugin.png create mode 100644 plugins/channeltx/modchirpchat/CMakeLists.txt rename plugins/channeltx/{modlora/loramod.cpp => modchirpchat/chirpchatmod.cpp} (54%) rename plugins/channeltx/{modlora/loramod.h => modchirpchat/chirpchatmod.h} (79%) rename plugins/channeltx/{modlora/loramodbaseband.cpp => modchirpchat/chirpchatmodbaseband.cpp} (74%) rename plugins/channeltx/{modlora/loramodbaseband.h => modchirpchat/chirpchatmodbaseband.h} (69%) rename plugins/channeltx/{modlora/loramodencoder.cpp => modchirpchat/chirpchatmodencoder.cpp} (65%) rename plugins/channeltx/{modlora/loramodencoder.h => modchirpchat/chirpchatmodencoder.h} (82%) rename plugins/channeltx/{modlora/loramodencoderascii.cpp => modchirpchat/chirpchatmodencoderascii.cpp} (91%) rename plugins/channeltx/{modlora/loramodencoderascii.h => modchirpchat/chirpchatmodencoderascii.h} (86%) rename plugins/channeltx/{modlora/loramodencoderlora.cpp => modchirpchat/chirpchatmodencoderlora.cpp} (97%) rename plugins/channeltx/{modlora/loramodencoderlora.h => modchirpchat/chirpchatmodencoderlora.h} (97%) rename plugins/channeltx/{modlora/loramodencodertty.cpp => modchirpchat/chirpchatmodencodertty.cpp} (96%) rename plugins/channeltx/{modlora/loramodencodertty.h => modchirpchat/chirpchatmodencodertty.h} (88%) rename plugins/channeltx/{modlora/loramodgui.cpp => modchirpchat/chirpchatmodgui.cpp} (66%) rename plugins/channeltx/{modlora/loramodgui.h => modchirpchat/chirpchatmodgui.h} (88%) rename plugins/channeltx/{modlora/loramodgui.ui => modchirpchat/chirpchatmodgui.ui} (99%) rename plugins/channeltx/{modlora/loramodplugin.cpp => modchirpchat/chirpchatmodplugin.cpp} (61%) rename plugins/channeltx/{modlora/loramodplugin.h => modchirpchat/chirpchatmodplugin.h} (87%) rename plugins/channeltx/{modlora/loramodsettings.cpp => modchirpchat/chirpchatmodsettings.cpp} (94%) rename plugins/channeltx/{modlora/loramodsettings.h => modchirpchat/chirpchatmodsettings.h} (93%) rename plugins/channeltx/{modlora/loramodsource.cpp => modchirpchat/chirpchatmodsource.cpp} (69%) rename plugins/channeltx/{modlora/loramodsource.h => modchirpchat/chirpchatmodsource.h} (84%) rename plugins/channeltx/{modlora/loramodwebapiadapter.cpp => modchirpchat/chirpchatmodwebapiadapter.cpp} (72%) rename plugins/channeltx/{modlora/loramodwebapiadapter.h => modchirpchat/chirpchatmodwebapiadapter.h} (87%) rename plugins/channeltx/{modlora => modchirpchat}/readme.md (77%) delete mode 100644 plugins/channeltx/modlora/CMakeLists.txt rename swagger/sdrangel/api/swagger/include/LoRaMod.yaml => sdrbase/resources/webapi/doc/swagger/include/ChirpChatMod.yaml (95%) delete mode 100644 sdrbase/resources/webapi/doc/swagger/include/LoRaDemod.yaml rename sdrbase/resources/webapi/doc/swagger/include/LoRaMod.yaml => swagger/sdrangel/api/swagger/include/ChirpChatMod.yaml (95%) rename swagger/sdrangel/code/qt5/client/{SWGLoRaModReport.cpp => SWGChirpChatModReport.cpp} (82%) rename swagger/sdrangel/code/qt5/client/{SWGLoRaModReport.h => SWGChirpChatModReport.h} (87%) rename swagger/sdrangel/code/qt5/client/{SWGLoRaModSettings.cpp => SWGChirpChatModSettings.cpp} (84%) rename swagger/sdrangel/code/qt5/client/{SWGLoRaModSettings.h => SWGChirpChatModSettings.h} (94%) diff --git a/doc/img/LoRaMod_payload.png b/doc/img/ChirpChatMod_payload.png similarity index 100% rename from doc/img/LoRaMod_payload.png rename to doc/img/ChirpChatMod_payload.png diff --git a/doc/img/LoRaMod_payload.xcf b/doc/img/ChirpChatMod_payload.xcf similarity index 100% rename from doc/img/LoRaMod_payload.xcf rename to doc/img/ChirpChatMod_payload.xcf diff --git a/doc/img/ChirpChatMod_plugin.png b/doc/img/ChirpChatMod_plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..6479324ab39e3cac499f5eb6043269b608c7794b GIT binary patch literal 45998 zcmeFZWmJ`I*DeeSNGTmk8gzH3L5F~}gdp7@-KBtlfOLrnh)B0|OPA8!NK5yg>%O1o z8{gjJ{k4DZ;Xrh;;=0b5^Qe;$WkspmnD;P|kdSW6NIy|QLPFk#uWNKPcqA%S)C|6% zy^@o9f^?1e^QkT;1|Gq%lh$%XLc$_Id?6zxrI5mdx13}Yp59uziGs#?FIBf6-jW(g z=81%w>%?ZNo2J_D>kj=MZ0xX`4{Ut1tC#BypH%B?*HnLut6qwGZO)pQWY*BdGF(>1 zEO%~^t!1&4Rz1gBu*4b~`f2n1Cj0)mQSfs@Ttfr2liD;>%BthEj7bY`>pCx>-6-?v}|g0{|_t~ z85s|z)EVZoh7t#aL+;s_*UqI;)4ae%$v|=7{uRX(#aMq(xoT6Z!faznyhT*EUAo~c zz-r|l;283v)X6j;T&piLN4%v{t+tKlCC#>g?A>TrIlJ1Nlt{c$i#uXR5e6sODpPg( zp6Q*vlzTyIQ*r(d(>Y3heEpHa@`&{9O6~$%@}7fa0!Nm{NK9LJi#}fd z?r+O^4iq~dDuV~+Hqffx6YRmdp{K{cQlu{STp-wRdaHbk+=GAU+Qw&v9P_jKtWwwu zQ9`D9? z`y$^oo2?Vs(^;_pGasn)E!nxAnMUIRn>?DG_7TbIK5~-(CYGI$? zIEFN)r5t?@Q+Qt@;)pKEAv_StGPzM@4D5T8$WN|l=H*!>lJ@6Ky-4)4ozKneuWO{hcK;hgZ=6g zw>bg>tvfcq#F-3cAFsOK9N}(kNZm{Gj_*>&4OK}^Gc>QXou#bP>pwf(C?(vwO~yO0 z_cj79Nw(((vu(pAFQ3hn!NtiQvtDh&sJ>5XS1gm*pnjHYEWgJQb7yBKQfqtr->u5o z68pvW?;`v+uzW+FMb(;?xsTq>pOV9=&c8#BwteFklG5U7P@~i0wT54$uTG=ovu?-2 z=kKnO`)*|Rl2(co;a8zep;g=9Da4$SKiN~_U^VH$MUBqQ)=5^OchDVQt z$FYUIFZdq^V;govQ0P|K`At^ZI$mF0Zi=|xZL_u}9z7Cun4(y-A{3-R}R*DcTH-3di@J05<< zYYoU=V`@ar9B50tzs(l@IsTRK462iRXivQ*;m^_VIJ@An9O0#GoT5Sc38b2EVr#O@ z7vxri)<|NDqBIUL5>9#1ubyxcVS` zb=vo@Zc(*iard*h>t7kTPDJjr2pBm@hKi`7o+ z_!NRp;u*?_>k>U(B7gym&lH0aQCnBXm5POdVYt82>+0(INj;D1n9zW*4NnVY>~2EJ zTa>j@+~l_mmV`o%t(RDK1iNUSKYv`G$Xwi3Lz_W~X6F_Wlcx{%v%yjAa}^Z~!-;$w zpP}UQ<(Hu8@77nfZ?nX?j07WII~EE|%Q>I2q5HQz70OgPzrNbJrrg*ko@b@K*loe7 zs;Mb88+<^knDTR{;abtoZkOQlHl=WaVya-`6Yb2wfqE~G0{sS?dqr^}j|}j48G@sx zW07vNqd&g3ExL=Ziq|s7_`X@~=HvY`frX>S0lt(wYEA6n-#_kYV+JGJ{h(qh-RSnaJ-;K}tumjc=$s+aJ*^lPt zovQ9#&sttIB=1#m2Is!=kzJ-oA7P!i+q<|iTF4jT(%^j=>P1O7DZ2fWASy8;Gc)t_ zPhO#e)6TOM2E*dw;+}M|bV?ETfnp;mSgEO2Df&klVSA^pr=Nf}w7~h*cxc;n#G^wfb zu9$J0A*nz;1*vV>w>;7oZG(#e>08;z*RrS#=p*VmtK9CMmuH7-hwg&Tn+evbdb;%L zma(&^>>r7+8cbVL@mg6!mvx67FKYj+(w$KV8q*&t{pxsKixt)JFtNn5OSMDHcv1ifE8Kwj-3tMP>^1#o(Q#FIHSr+y#o8jZh!bzHeQWbJ5D1 zny^1@3_{cAV@LlJGs1YRG0!PWC^~iBePh#?UFrVvziU7Fn8p<*MeYWXTpx$A1hthmVyU%pNO9;eGQ* z4K|x2}I{=<{6aSK7S%^DFnJICPBCS+bY^-d)r0JPizV^iQw5 zclUWY`3gM$}`qxu48 zE^po}LvQ8X3Yf{1!eP~~?+L;pIay8j;dkBrRNL!M{mzc$jp+4-BQLz^p$YXf6&00} zi~W8_Y&sE-cor>L*ZW=FQtoTefim>H%aZAS_ll>(6<*% zX>Kcbr>3S7c&(Gx7c-R7MWH4l1xZT0di7w|bN{wfB<0f#Wpem%EkqE|*n3J>BW zsvVZ?;0pgPcOxC_%%;Pb8k(ARobIol!Zn1vfB!`?2va^yIFa$iw@<_C{BQmchLNz* z-oK9wMby*FD_5^hFe)l)bGG4H!ti-6DVGVh^+cIOmWuu9-`6JnY2oU5SumDP>q9{& zC$7T6!jz?7M1+MA!?rV1x8@{>#Hv^Ob0FifLQUms5^oh1{5*}q_TRr_0mSS=Q5-6_ z)R-tUZz=5;?S_k5A1$P63BH}FnxlBIHW;wK+OL|Y&LS)#GG1l>&~o%1FT>7I7FNq! z94VOCxkhA*UtgR0QiV=83LDmD>V$0TPibYd@Bt}Jlv|!IMv8rj!$oQOMn97L{>js) z^Q)^;78Vw9qpGT^d;9wj85tQ@3&~qbv<{K58DG*k|GQ z;8h)C#YW@xUP5rAuX~etYWMqu$OWC=0o0;k$Nokpdu`zD}R3Hd7f`o!o;-ws-+?(HkqIkso6!``QafAEp4#( z<=GxA+rP6u*L#=8v-`{O`l3hj$=v46em8HC^4XB9X3Njl9nZ8hHTjji?&kD5b28~m zk(sUc!nkuMTPB7Uis|O&=E=!oWFo))gTneVMx*xk8L;sLybmz`S@lRTUTq^Iyxo=+ z6%~nRU#M1KmW}$;L^j7uZ~6H6py5#Ve36Oarna7urg= zG1`WvrlzS{w-}vD8)Q4!CtdM;n=IoM);cg(M%t>!Ffmg#E;wv#Y|!upoYrumHz8eI zo$o|yo!qsrupEuJJU=ENCJxpsT+J)2e+4fyOQ>4Yx^1XaJ<@)4ocqZ=^t;b z#!G^pXFh{H6`!~3*gak2BH*}!jU*ulWip+*=o%@6p+jYlxpPzdRdj*hY&Wn^S74u+M+&k|wF%LJPA zB>2U|sM6j?gUeT_@S0-LE}H|?%tb**OPh2xx^YO$L?E6soS{rwp8+WOv9z>wcG0U> zujo~?u~}JJr>Y%0oJ0i$1y%EW;kwej&lr%PY4^i#ClKTaig?u6>s;Q~z zN`LxwD-1QxLkw1s-+cR~R4t%iSXIvL=Lw5*O%rW}??ZuE9E4n{= zCC$ltPCBJ!y@HZb|MM!Um1Nuc`AD&=#*U7+52Yf62kYwUL=OM_UTh5^Q1U9o!^5M+ z>urQO^6nk_!omXmi*Fy-J;zI4D_rxL4+UC|7G(UkKz_{UmzS5f{v#mZ=5lvDov`o} z;YyvyF=r4CE(yuoXPF$Q9-7=xrn+IXjMts-T}o{H$_>yY($>)-Ho})g@cjAn3)n95N!*>kz9$p(i(Ly}UmjDzBrAEPUtgWGSx;7E zy=n{f%{Z-r&qhH(vHSCjA&Jjc5y}cI>>L2O-Evq<06awSI#UMf)W3k0PnC56JkGh9R6uy=O${#Gjjj1n+- z7BnVbLu2>$x60)fzfZPncI@mqtcV@ACd!3H!~kj(SM>&_r&9qbZtUy~sj8}y_o}Qm zgbj1>=XY3Bz^(lj9I>Ufqvv>D_Y~7bd!b-zm6_pT2Kk>K@9fXNrNSp6>DZpGF`ug9 z*ci!Q1f=mDdicSC6Wp-tdRBabsMimM6hJE_R^yy;Z2A!@xl0ReVV+0hroM)D6L8lG z9ut%T4uJp&Ztg;XTin>_hA|6y_s#&`u=Z%e(l^6WJaaJNti$NlE6pl9!-ApZot=JY z+=G?uqLDOKDqC4v}p*W`&XVuB#g?^ zA4*9{NzF2|sP%_7P~&ueIAPT3DJd)CLR)?f>pYv-FWu)#>$|lC?)N)n;`-$H3)|a$ zsW^`vb@MKQNc0Sv{83>-q5v&*4YP$P$YTcO&XO5GR{^vXc=OgB=@oQIj^#1mMOV*t zn|lX3OB=<}2fGoJBC_3aEKkei=$)ONt!C>}iCMIfg6)xsnADe=gRr6n{HY1=szswp z%G{@+2~rZf{0MuM!|kszJ^{h$QjC)P&HaDi9%@q;zulZKcNhT7W^09ahmX+zsp9vc zmC`AJj3wdvj_PSue&SRC4eVIzkGOvb3zz7ZLNEat!Ul%FsL>xxA^xLW!Z0%2lr-|b zB`;1rt%N$k&$s)YqMm)+d(a)X{o&C#yy@+qs>CRcbF258S9R~I37wl4gmcMb%mJR!hWrdO{YDb4-&YL}F%Zte=# ze{NjFK*qDVze6tOt;;DvkL!N;=c%;xyQe$%jc(OLIqtgIN$1?3o#D-!Kb9qzJJi`i zG|%c@W^sUBS+0~`7t3v~8z!COu9el<5SGc(KWdki5=Oy0hMS?VVyujfXV0K?V43U6 zvRqk}GpcPiT99hBW`y>uKYRYd!C{YJn=3I$h=+#=7R#$wpT`&M?Ccub+tGA%bnt8( zGsT|U8BTJSF1&w{`&aFg8l&%l{1t(U;cU=a$CT(jZ*^}LqQa~T;_CxU$-xIN<0GKd zLC@j|v95p9c7kVjb>RlnoW6Z|t)*`lLh(wK-c6hSMN>V}m}Pr0hIQ?y^7uC-BehtS zl+t~fq#?5lI~w$6!eU`8MMaOZtBpNaPJcu%efoUSo#!6>ebht~B1cd8N25#RjV!boq3xLvS^Gi@0-!4`FW=hNx6Kgb z!DjWBXSVm?FN=5cOZ?}Iv2OS_S)3yMS8cYPyG(@scF8ZF#H7(rwNcbvNrXk!)CfV_ zHw6|kRb{^z;?1N{&;#ASEBH1Uvnc;CBlcstS@ErJ134@QHdwuXnzw3{t1b6%ZL(An z>3rM{*}Ua~^(E*-Kd0WG0uk-AMxoxXf|tqgmX3?<;qsr;h(LnMP|w#!)G{cB&}yj8 zN!f9D2R;#$-9zi=y{X{#?v7vBwf`*nyDHY^e6_})*)UUy7xaYmgrUNx-FYww7nia| z)vt@6Z`fHSgg$OjQ(JZ#8(Wu-RQX`n7jg2~;vkndT1M#;08nn5sf5LjNXMg1Ex^~x zxoQB2xMFZ8$HtVQ0XPX#`1$$4(oKoia}Rm^_Ky8uV`LUn?R}aPJIfVEBFlT;Y_(|V z_2@2rI(qud=R|0$0du8P8RN-zhw2>eP1aU_FS;ZDxggBAmMkOAEDxHDg188kOsR~D zrjeJCa&L{hB1Zi4v8j7H7e+P?e--LeWvPTfaqsKv!=@5V0VtEHp2tM&!>!Tr)Fel>yikt^n$88zs7NG^~Z>*??{=K@~T?x;Pc^v8t+K z_qpCT+W;2gU7+Kk{#{d|(q?{>vRCrF)`@39rPEMYT^ELyY zkV)9|9tjF2L5+A`Zt()>p1gwtCy(XGQu(OfV)bg;Lk5PB?szstZ~ik{s3b3sz1p9i z1CSk+Zc0LGeiGSk#r9qGP4iA%cVzGDF}vv|LFa^zP3EL$cWPXA`qD%^)`oMGve!`o z>^#m=83gK=Q&F`)q;_T3mNq}zsn?dk%47CChrBPMBJdgA-_`la3-8?#f=g{iJ-JgB zjCCUBx6bh`Myt_mlX#^>Q+i5IUS!(|a{a?a0C4B3<_wrQ5XXcN&_#dz_yq14uoEGI zJ_6}Q43Xy_SD(v64PrJuY*Ms@UJ!bKv6LEjM(e(vpPz36WC8RAA*l_opTN)+m6jU8 zE>rue><3~Xr~SecK;L4pDk&)`k*4as$ZTzQB)P3$C|58Zq!{vxR%-=LYMV{};0Xx{ zLFm;mF>`*?tMG{OMhiJIjx!RZ;m!^i#=Dy7E9Py ze<(ane&XH1BbgavrujR_rDmjcMzJ%gu4(+NH}AtTA7UgJ)_ZY4Xq}(5ZQ!ApoS0C7 zMLAJnE$8W3tA^%gjj6~XocwFI`L4L@V*Bl29IC!Xzni)G4c-;oKxSl}Px;@Sr@r5u?Z!So>)^-TEoB5!44!F$NQz54sriqrIF zEkF9R%bljZI?LS_cK&(^xM`SIoMb**S}+N?O#23aWO$!0liav*1Hi|9AiYKdpCpu6 zu(gQJCSp?)#lGNeiH*lINtkO-$3E+iGx^(Z%I_?I>B}{0M89R+@oD76nClvEXRcr= zmX`NI`N!Gl=$Q*#a&r06f?#tpKvEz>;FFUxe@+z}&sNKOr1FsHQ5r+aGG8G8DJGY+ zv@~Gn+f&ssx!7uX>RTL@Ha0f$$-LpfX7ET!r2);Z!2l%lT6ghoLai%ySnkTf-yRrH z1~!gd<+yr>mzVcfzE1qyoI!={EMoK!v;a@$tR@PpYpaN8%KD zHDO3hUFbw?3f7k$9`E?XIyotOk3OJdOc`w#MzGn$RIp;88E=dXYgK)lua)+~NI z-q-pm#dAvv>fRqexX8)Lr4{>XiQPegI68{#e{MVU1;fzL5CskG#vH&t_;{{rg!+I$ zbwCL&PFK@)8@v(vjOcHXR1uFj!8d;pbq&;pj(nZUuR4{i(5ql^#H6Jus;LnI_(F`v zhYz@bXTyOqA;=1-U#RK!Z%0Yv*eK?ahVM0ogb!SaxLW%G&Jl-C0Xd3}vCCi!?miwU z_274{QqQfwvC~de$#1i7zFyriyxuN2YVW1BN|;&|5cGIqJn~~-_co8FH05h@jN07Z zp`GEG!s`FbK3%av(~SrUp}6%aSdW|(mFC02AT{re=-5W3>78H&kTW$>9Mq=!)PJy0 z5_yf*YNSDv`jbj7iddb!cL@mXasZAf5;Z&fhrPv))d^ck$r~2sg2Mt*QXR~E=XUn? z_j!5u9SR2r6GsPTiwpyDBPRz3qmXZ+?e6!BaoNp@Q!{7~A188|BDOcEcE*5u!TrL| zQjziW^vtH+Yi)hPYs-7UAoc9o-*z%vfHMl0i$SmKb7&=`slU5oS@7OUA2sad$Fq@p zWoan~wQ2Y8kSA46M#gZm!unu+m`=a>vM8wRWb4^4k9L9KLmyG=*Jsx`KK@#zJ0@`o zxkt{jDnm}e`@A^KiZWc>=@XL-T&Elw!}kB(Aasact)utX(B2!ELZaXsMkryT92^|P z9@mN%+$d%}e6pi*d0Dykh7mVxzc~%e^YSA2aYvqi$AKT zy=D&z)pGHH;G<#he=W7J7_}&myzSI&zA+LQh%)kBt7UC46Ct5h3LLhsIQYuNv)Y3k zsamd+!APOde4Q~4;h%%!4^5s5xg<{U*94@tbM_#?wroP=*Vyn6Hm)ksU zrl$d@C=bdRXe)89f3G_|qRlbNQ-S)eS+hm^Sd*_=9k$2Lob z1{#{W(+u#Z5K=#MTl>9*r(yLz$oFnDz4uBrx&P>ka-hz7lHzy<#;0Ed#gdQR)tZj@ zY3b<1My65;h#1uxySu|+qeMqXHv^Ho3&J6k(a)eqVUzQJ0O?_!!^gBQB?I(jKoseX zjpB$71-e5_=KOG_tvh}RRcU^)vapGR!HV7 z$4q$Hcrbem!IQ=-RRaKyI zf#ylX@3f{2O9uK6cbMHQrVsmW$Mbw~kQD_Uv1<4`&@uWEzv+Gzkhb)Zn^R9elJh9L z2ut$kUjl&JaUTy>-onm$4kZjUxn7uLg;lZ3gW=k(615@ib>U(9ef1lU#&NIe2!3dG zV-skX7-J|TaZBWKm;F3BKPSM)Zw7z)t5zv30iB}phI$L8fxh=C4VBLY2lQSN1_p+c z)6>KPksc^ZiF~${`ks5Jf~gS*u^2ROc@~kvhATl}hFn_L@of4lKyT@IdE;`-g{tir z(V%j3ZVg{PlDh;q3|j0-uBgG^K)I)DM|cP455j1JHBa6EU(14xdIxyF+vggetJBro zmOdMM-}kEHL?co;V&paCZOPVo3orAq-?BbQm@5CK5s`4B#v0W6TIkJ#fY5>?ry~bC zQHIpRD?TjY|FqkXqpe9(w|dk5wCro2>pHXVT)K=b;rBB#%0eQtJ!LUnwl>FJWMf}D zy3jRAZdAlu!~}N9;3&FJ(TRy>am{}ZU7Jn8ybzu7U^^$O1uwxIWQc6qUDyOGj8nkC zxh7Aisk{!Jr|t0Nov}0Fc{_!UwLGGsSzeoAzTm}>WRolvRo)XQdhz%P`$Z*LMep06 z26#5UakeD=k^YHs;ON1&Fp5uvmui|+qy(k*w<8rqP;>dEjYfZzR@M$ zs-nQ_Pq}?P?;^Yu;*Ff7?nuM)vg3yrUrGK&F9l+u1s=qqnA}30PmFGMlaeA9-Nz1Rukf*0{zZr^+uS1-<__1Q^A#2Ey|x7w!q4NRCdP}qst&T0g;}<1wbvd@p^B5S z?NXS}?8-*lt#;Vvcd_zM0_Cw4Brskj5shCqH|som<9|+Aho;+A9&ui@F0gt& zH`A`ezD~nfY=3DTg{LoLd*mHUGdJzl&X3L@o@w}NYw`dSr-MNxmHO7L5sj~nBjhW@ z$yjg7xgE5XAKA{w%7Z3^j*0mhD&|KfjXtY++DDJ<5K5Hw%9E{;;B?KYap5u(ni{vC zDpy<=SAY9ogtaoQvz+{Wu4~W9N<4f#BO-WLgB#^*@(16Y!wuI*bo&7Ut3IYQW&PQi z-W7HlAGwY@Bn@MxJ3>@)AAu`?MZ%i!MlfDG|5=8zfvM@S6XjdNOJ^qYw~W+7!^8V! zAB}_4YfnfT+GY#OHK$-d0G*BrC;o+HZ||v@iH6+QM}O$9EhWW8!=C`#<3c^-#>5Sa zXE=!~ukOy5Ho|8`-7nC}k79jir-O=+3FjFMlHZ2=H>+Ch?b>z4{KMAp@n7xzeOcj~ z{B7qh)9DK$CWpC<-&nBcGZiIoTy9TiI(rItywv?tg7;6xi@CR2CCimZSXheBJ$Zpc zp6&EUXq8XsESJ0nL*rO#{^7xAc2U0aG#XRtScE*H-c~=9HONSajd6Q9u1q#7xwR=BOmyHH!3`Uyhk!NlGPf6YJlC&}C{N!iJ+-Vqysm2Q7J_Z2M7%`KW_r4jm1=m)!!wX_jF`T|-gN_F$Z#?V$h1}W_V>D8h8L<3`hSUHb zyvwI1w4e8OWcZS^G=8o($r~svrkwVTT2mmcKk|b-E+)2uw0JQkxv5C=^cOnr%^PBO z0$li(w5oPo<$@3rS@a(NvtnYKpchj?M&_=TcP|8y9~8*t62R4=o->#tnolq@9MMw7IDX8MI*85fg+e#>_fZ$l_}$HMjNypJ4(L z9NcCDNFE*@RwZNE%7vpbA3wGN{{$BS7ZLu#Wu~8ECCccPZn>V(`ffV2ceBN|_g0am zeQ}pls-l#;yWru*s8p^R{@uHY`8r?)00Hg?^7tH~dtfq@gTO~a+MVkw`;vZebD}&9 z#EN-<-rzTlm6;Pjk_Q=~_IsTl8CqH<%g{%X3rI#%if{()kDI1*yzU|_#c%=iZc(0; zkU;7r__Cq_zW=h|0sS193`4O$bplbAO6U1bLqC{Wz0fdPKvvGxtu9%22PCRh{0i0M zczYR4g}GP_J&u=o;N*fbWDH#f)cq*1tBvn=)Vl41L@(y>Jx8a^Y;WuoJe%Q+$G6<1 z)s5_>&`j%UG+waniWtVl4s#|5yK!D!U4hT6+~DmM$E?*H%cKD~jvpzUjF0znXKPEr z%8D6ecJPSWcHd+w&uwjm7Zw(3l>*9Gm3@EcF5+I7R#nCSQ8w$NwnWh@D{JfG%1SoQ zd?VYsLt>!AwR`PkQw=`p4650?dmU6n0}R`P{F4CYB6tEM^Q?Wai0<)NJVE5z z;DV8E;ZT0DovjCTyj4wk*6aACp7-f%P$%UK45-=aPaeP>Q40u+e?N{HBu^uAxqHm! zHRW$``6WA>IMGAIc~dic5fqE0_a9f&JR*RYb2_fbC-GX#0+|B=XB9x5TE2EH8J~^u zUoxQ8;9V$mAP^b=Jpy2kr}eOMshCYgjDO-HuzJ)(DFEk~HYmo^foV9R=bK#63yRCj zpJu7-f!TrkYASXOMgokTAfVD2gJuI8haj8;0E`Da=`mb1V&rG*r#EGY=7|FrWS(2! zg)j~k;#M9$BaMp~G2?di@ZbWX0KU5d5c32;hOk@OnwsW0jA$7cFkqUHe!STT&d+Co zAAbgmSLwY6u#iZv-H)s<&p2G*6Am^;Bkw;B{tz9l@}OHIq^K%KAvw6Ap&{388LrZ} z{r%mZB%Uykq8zp+c=TN7QBzV=1>6tlkq|b<+Cav|(WEWH@_-pjxU5gB$h}zUO&;n1 z4L>3^mBOO@hxBx*WQIX=AO_-Dpq1bf5urAMc8Yj$=LN=sTNc!;MgKu4( zSGFBQ%4DRaKY5=1eNQeB4I{a7MhOAW-Gsvii{IbmJ3y>BIXmNo8UTi=oYh?>dxC(L zmX=fCod|dg#DY_68l3r-wzi;#>nk!ujOA||iT>`89GgAZ#vpST*@sPzk87mGQl;`!>yXFs+!H|byg z;D(iAGFD`$rRet?$X+T49DJ8Mb90Rsr~9WMeS!TeAL4BilzF3kQk+eHKR8~B``&F4 z_k%ew8M7T>(Hg^y@bmMt!xNE!&Bnrlzj_{A zs2o={HM&U-2+<$e^wWxsI!y4pu(3Q~kjrdm(}1}Tmb{h&T}A-n8xTzSl9k0_(1-*w znmB||%^=nS+k*n=bQkw!9;}LUc3aN7Dv)drr zm%J2U5fx2?3iVkf7Xdxkg%IHYsK7>GJSO%XL$2fNSNiq{im<{$HVAsqfFRZxLzm3F z2olKNpcEB{!;$hfiVk?+q)7#a5Y`+$0R^ ze6zj1{XT^wR4W24YH74qxo#)p2lBO$g{Id*vJl8C3UEzNRYlZHuB z(P6(TXT8cu8vWt6v>OXv|5cxi&CFiUph8E%eHEWXriOA#0ZfsR4`v1nRu}< z<4+06&LdCmJVl?^~KrmLf}F3GgGxM1+9Z{Oo?ghcmb>@dg& z{4U$%7#J8Oif&Ofk2GRse4n*oD)r;XFwrbfpks8F+UYo6#u9-)ZdN`a8LpZ+XgrZA zRJo(A*rRE3BGOfJY1nCeVi<$&67nQxI11D{AkJVRX|YzN`yq6?jnUQJ`IeIW9O@n4 z+ME7Cq=$^Um}u9-52la~EN&LMpscFkI+1x#qVB6pl-xb~%%)Sp3_egxcQ+QSndq1p zMD7Gg_k;WQ5xHe9`-RpH=k+0ra@d>ojg0wUzC8M6@g{jx>4%Pt_b#LwgbHSpcql1PH(QSxqyak+8Z1I~BA0Pi8a{^KVy$*R} zphW5Xc8F|Sr&yaPXM*QsL2C&N3Mz)ae}{@S;pi9LZ_|+{dFuHI97bpWO=ux@0w#)Z zMS&}%`o>C4acyHID_M@LC~Av4D5x;rPSRH;|k|GOgX?zwYETU+efWtH_m zpr$f3^c<8~ggVPhp;4fl2uZE>vUCp#b}*uW>I3e{ao(DE58@@l#sbioT=7b`#yMY$ zudVnYMl5TTa=zO>R5*$(6?38;aqq4dFa?S1hBqKKvBe$eY!r!lB<(e0DDFu?%QI72R z+m5uXcYmq~7*Q~s;omh!+PUp}+OWhH0pOzuoPc3DLOi^tj|{5cC6TxoGpE2r-rc3& zOAd!5Qa|IU^ECiSt$I(l?CE99P?&r~zTp;?XCriGM68dD*NQ#?Q!>7FW^jE@8SOx@ zG>9xiA@lSzN}k)TzuE35Hmm|IRWl!=f{CxSqw=J;n^I? zj5*MI*~>*C(+~mWS_SHNj2%KW26JlI!tFXxo>b(*0R zk0rr2Brq}u&A`sn$!I5|qUwj~a+?n#!IZChT+TbEa=XlA<{JkOg|c?9(1%e6B7mpL z${*INpe4b|wuj-k;YKO&+Z2*C5I-7#WR~;J%x&?vcPLH(RmjN6J%#DlmBLQHjqyiG0$whb45fy3+0fk5W=qaVP|!m25|5@eMiT5@gG4`O`IYPosLi3dAQq~Cu~2d|17`UryB7`#o~v^7wlT2-MOZ* ziHQ=xwg4=jL8cE0Mq&lb%)|>+G&D}DF?Ku~riVr_60aZ+>j@WAT|(Xq5z4ml)20Um z{}J`Nmsa5VJ$IXKxna&uKSj>PnA0AvHfl>9Ne= zIKXNJph{yPP9v;ouyEwlMW@wxxtQmE{Zg};{_(Uel*sauzd;!{UxgVGzIFMyw9hzoEJ8+i{$i}eDES;5&1ecbU_AFO$A~?tq zj788G4SlcQ-_o|$G$e8YVw3apW{S;fEK&Jd z{yLa?2c6%d_T;+|#YsC1%=9Z-s=VmnfQrdmmQY@u`CCGr8B_$5H4b6CEv`<3?eShqEn%nYUc4VU^{-{PM0{puWpo5^=TsYqhd#?u&Zm}3z zg%Y!@EHy?TpqLN^gvcYyBx4N6 zgdiUG<7e&ULw7$}^Opfb-zBRa8X5NWLy!fWn>KQ~qeA_LG{8C}?i0|GK{J^LXz_@S z&U8aDUp-SLSN4LN-7*V~R|VlK*%046Tg!|LRhuDt>tZn99K@_!RWz{Rq2h)1AtePN zw`Q;Ff@ucD)zpCxHvaH6L<4G%XFN>mMiEI1iwcDFl3(K4r)_wm^>E10LV^=bTWhh_ zSmJ}rCo@j)3Y(jo`F*Zxjh}I3X<}7su(04hP|_;$cSyi;(Pjw*^s3%pkIOd=!3$&P z^sqfRAY&=1WU2m=qK%^u|KXH%ZKKNIze034vtPeVGi} zO6zj?b2SIX6(@2OCd7Gy7uX+KbPvML=N9z#pK8|J{$=x0nAyhn9ao6%MVqH3#b`T= z94HB&-;E513C%ow^bloRnmFM$&LyU>BjI*kQRk>9-qBwcy=H5S=t3r$JJIHU1Tu!# zi^|KhJcIti=?tr%ua+4PfKA%(Y>TLwJiUF?xpOv>129RohvTF#D$&ZI8Qa9r>R9 z|IxbKM>{au(!erP$x)<$svp0u4ZHF#oLDi}$fA*pvpdhaD%x(w>lcI zglV;KAyg*Vo|)hRIBicQ0{bR9(feBs(ZZsYR6&vA_kM=Qd0W>u9i5#r&P_~D{!dPj zeOW`5jSxWq2ZDl!PejxPiSKR@-tr%?-2dP+&$@-o6&bMcxKyM|-LH>IvUg?oDU-BP zxtSo#nX_vdeUR!?q0g+e4kmjq7yMO=Sh7CJ(vkeR%_McGA-Aeig-olIW;H>R1D2@g z*?NwA0z0z4zJ7N(_lH2)cxg|bsJ62eI@EW8dIkgaUAw&N(FC+pI?yE`-_K&Rk6I4j#MhIfv6?V1TbEhv)dhC9W*@q%}@%CynYg5UnffhEmPo6QB%UH4N zP_&cUhE`J5MyHu=w!y}ixkN?Qv6^pHwOl3Q3y?^J-F;V-P({UTvVsM~q6Z+xKui*m z39Y)SF?_Z>gng=6H^OvNwj0{6r zD66nAIlI;LDLov5KtV-KL};sukOqR31nchkJ&tDf8+D*$(PGgv0U-;7g9re(X<=$` zL{EG{Rzy(3(plBGy4gMv0sWPHxnO9?7bmoKI{I^&8dWGeNCN}U->?hZ`J2n2&R)Kw+H>k)72(>eZ=1# z%hUm949q8(5Jy>8dhSX-evG^Zhl@bcr_D15S`J&m4_Hl7x!sQ%dTJhIT}$n+)elk8 zSsh|6+HF)up1^P+)M?n=-DP~v67ySIy zi|zrA>wve!G!|KB?smjuF`}s!2Ad-q5ki?H#t(lM0M!Dro~Ce41(ruJ@SZ^++{15e zqUhF0g@@6fUE%P0qRfxp_L{n^N77mJT^*vtwXZYABa^`>0GsSGO@kLyPLfE0$1n8$PpN{_Tfczu>OI=+~9wSj*Z>sk3@kEyy zx3>uT-beH3(cH>PJCIAvT49nlPW9++$2#{zdQc7!&}gLhf7XPHz?N9pGq_5-*?-J) zVCr$`Zl_0v>{s*2+e2B$nF22i((QI@gcd&c(Ua*?CD zgPH6V$#^;(m@&80RwP0rJxf7^I05Zoac?oW6MbrKYvXiF=U6y4&%X~Q)!jYIFaI8; z^9A7tpwtG@Z5cg z`A90q@$i^*n|wf}K7`=tHP&(WIh+v406Eu{l+WAF#Rc*)0{j93M0xRQ8Om^kIV3Vt z3QjCAj(+#P7mk*%9tM0~VCosvmcDm*4_)C1CFYAVWW_XL87Rie^n_r|48eI9=IJds zFjDVz{>s+YY-WFN&v2nNM5R5D85pr*T!0PZn8=Jx*l=>#NpIKlQBO2U&TPY}O;LC<5Wykja~s}wE# zSqpSXq{lI5aPA@NJ%*M_@vEl~9z38F67xK<1H$kOPGf+k1}YOVl;mv1R9Q1KdT0iH zzlAR!D6NJBi*9rI=or%~(|QH^PxF@psMEcm;p{H&+K6P33ZE%>lAG*%`y&E>Z}8(xtc1I~{plDhM4|J16NS0C9mPM|ZLG$rXTvsSMX)R2!>N{k zuWDF&o^D3qpw9gzovI@oQXTQUjDgnd72#CdXOh zr_@a%yr_2~bnfwUoPYfwgw1QsWcwux9f{ca&h`6m7Ht;t{u&Vnq2bl{DFein{~WI- z;u5GA#XfK4Be@}w$mlxb#+yfmf#N?JH!54TVQO5wP!{v^g+wClamiOUEEIoE)~V%L z-X@|+(|h{G&8dkj&!VyP1bS?r%sa^o-}0N&YS4&mEq~D@y=xj|nKvq5MV6pa@0VNj z$nO&=Gydmd>3769lGLtIRo==)A;d1vx35REsd3R^6#B4EM$X(GWYgoLqulTlN3Rq| zJbvT;6#NJNHBbD{!_;fp%DkXH(-gvml=R|GiGK3iW?{-GATizpryu zC#|*NL(Fef-oNj2`EBm#yyk%h;`O@|yldEcqwn3JUYJc)?HQ$05fMFgaw;pb`}d-} z??OfmPAA58h|adO1OS4<3PW6nMB++0Mas&~j*^MVicxBERFoeWhZjQ3%|6S_T)YKGyk#q&;D`z0dZR(y5(gyh8Pc=*axo_|CYS+C7Amd3#AN<^ZB=Z0w z^`IgD**f0e&jj7B%xusff~Cq3u&clLD`&{@pWCQSfOA=HZf=pnbZl&q0LMlDra<{B zc0aU$P$jZ&M#g;vfrgfhI0*&LmJwjp#KgPMaXtZWcF=@^57tsx*$4$WIpVig_+0GW z0++P|(*AJ94T(|x`%gGqFa`$;;P@$o@G{hhjbpR2Xb|2y)EvZVOz<_8G>iYe4UsC3 zV^(;k8F$jFNK5W}a0Cn+1doC_6NWs{5 zZ-^u42d@<=jB9f!Vp`FUH(KEMA#mO{N;rxEaJHtEAENAt6gPyLkqtnhd{4@813-p) z-ZHq`{6a!Ei>xPkL1SU(=0?FptFxZ1f5|55=;(-m@j!Bx)vp1qAVkyG^Lh|rM1nYc zYildw*vY3)N*-_pAbdDDI)Xccr_KyZ#1s+@5Hj+N$sA-=SVn5%A3DE$2UyEr*Hq5naskr>WF!Gs+y zRFs#aQq#~por#AtiO?jF5Wn{Z;eHPdMPFQaGHMja17TC1V{B+R^!6eD&wA0`1)FdX zemg^*mv;V9RI`X-GYWKsP!Ys0F}S)s)(7_UUNI*Va{quP3F%2UiSh9zK~T%pE@y;n ze@R%~2UyWa2G-WSz~`2)W1^$kd3auf=Hq$zTZ3HK71tLPi}EGaF0$jW*rRq-u2Tp(sNK^$5Xy0SBvrfa`)351+C z>G4ImxMBbR{x8nnJD|t^fBTL;8IeRKD~Mpl_=ehm(TZi{eIVV-StI*y+ zE2|9+FOmMeyrfFr*%ha~e7Qn7TCs26g#znS^9wk0<{6eTCTZeBANc)apsMPe-J`Dt z2Txm3Y_)!Uf3yVyCrt{Vx*449CI1{dUVa* z=zjYr4y!}jsODYh8W`8o@K)6Nl%ahNfpE;wZ>>*yr16KZK zbC2~IrtJ3bpR`5*bp0FkxG^h&kjDM{C#!zy?tCw$(y*<|#ZPR#e9Xeyf9p;*K)}VtLl@tC8NU3%3N?kng9l%Gxf#y{jG7SW z@{&vF27gxQ&ePCpd;Xsvn*FMbawn|c*rB`s!-I*^4Qn5?G5%w#8m4;;GCJ?i3n(Tnk_tm{}aVbrLHSy@MD5>W^p;iW;4D~Ks&Sqe}SgzH6P<+~Hw zYk7X9u4+Z0YpU%&7`L?8Jzu|P+)j%&yI)zA2WH%w*O9=#3rO5_*PW}W$;obTqu`{h z`1E|Ur6sSF3{yZQC8f`=_n$b?o%!e$$nL-qCnF+8Z7+=8ryJ~87T1w#d zE;BbbzwXX_-vg?Gti~H}wR`s`u!zCa6H2t5dcHsJ=jX1fqc1NQrJFbZ(tY#n?CwOj ziSwfudJWK*Y4OJXQY^LO<$tayZ6~uzg(P8RIaLiZ(q^Z*kJPdYwaXg)Le2++)EYY z_Uayl3>phRUF}7Sy5OVXr|Z7x>htd3lZy=u44|7yLdt@n($v&6a?p3MIiEGO4Iiz0 zg{Q3cn)uySYR7!f-;ch#C5}H=TBy*nVZ3^e=6KiG`WgY9F_U`A1g5i$Oy=XqWhktL zuHe?KLwh!vo0+9iV>Dryq@zFb_w&yRiZ2?YY|3;QC)K95+!caAqMqM8Rmm$?u5|6$ zGm}UXcE5FDoe{9G$#&zNU786E*3Cby-S+Q)TCr36*r5Xlsvl1*{u{RWRSsmZ+xPCB zy6~N(6JuBP)MXY&>3)%;p5hk<<2Fb#fCH7rZ zTl4PV!Gj`y;x+NB;k(|}t>0{&D)})4G6@p3r^_)}1l^117q73lsR&!239THwF^~@l zp?qNQ>Zss{%K{@yffEdU8>t(7iL5RLa&&n<=g&W;ArnEBHcGvFV{b*pN6c+etmnN= zWVqW_Qu1}Y)BU2B&36p}7198J4DN1L$PZuF{vs3Gf7-V{;qN~r-N)Zw*t`6PZZ)f? zyOq|N#M~L)_o{Wa1l;~I-QP#bxw?zdLgxp6zGGHr&D$i-D2H~~x&%!)h7WUd^<6EE zd)ywj$V&NM;+1G2@50GI<$ffmSN`UKcO+cWkU&xadjB+69juJ&Jzt0AmVad;(!sLkXYn&TDGoor?KRXek%6c_$ZwJl!5$Zq7@J6G!t{nK za<0uBa%=VNwv;Y-*8F@{)o48|ZXNFcBoPV?Gx%Uax_G;*8a6|-i!HDr`F$QlRjCS$ zXAaXX5;uh_1s`FuGb8Jsqt;8jdiAOgvO>p#N3URm6N4?_4#OO z8H%slckWz4L<3y!`m?k>)+UThRMpizNwvOyem^qo1Fu@;Ute|zh;zf{&BAnpu`gI! zXn~cls$9Q*`baM!XPs!Y!zMyjR+bmMqM`!e&Kj-k7_$;|oc!jS1;U!|1M@6L(^A)7 z6tttqjCl{Pbuz7*>8~&@pzISiYr_hu38WR&ND<(H1SiNYWtx;Jk>3kPz9GC&0KuH+ z>x+jff1M7-kx3n|1oL?89>vD1{DY@h-9$!477#8Dn|OJ738x~1i1qu1=SdLAh_y{Y zRo<#PMhVWRdHPEL=Jm!vJO$SV3(E zfpOgC7aoMU>{703A&;N}zaqGWj230~Lhyxnyr5%(+ zwwLtyu~*clTos*eVw8z23%1>d43U9gw!d9re|in4%C53-SZy3s$=T>`XQxaX ziSvl@)=m?&v@SqsK2@LrANXU{omdE_Fg;J7K8;(*uf{6JGPyZ7p)=AF9dbmQ+kTZ`gOL*=5FP^=+LFh zh`TqNaS9t6Sp^lSoS$QJvuY-8U6UPZRTUK#^?!uAxVlcKHlQ3h4vC-Xe;O72H7Gzd zWHwvY`l?cs{AhPw;fSlVbF*IGs~4YISQJDI2n!4AGs$W%QDn$=7ehls-_xg?GOX3y z1^UnXouPb>kS-Ec%url2EJg5FPW{HmVpZEFs z`5Ajn9C-O+$l{@ejraFbQtAdTRX!)Lr1Uefz2*A;hotI5lwGXUmg@K_PYoOrpP!Co zR8LQ|(G6FxUR?(6=THn$<0mTKeQs@L;Loy=mn*W<($JM3D39QB`>1xjYuHjyneRUn zRFE35wpBlcfZUWZz4G_(F8z3g8Lq3H{Pm`1&z?4k_GA`v5=v<=9@ex*D{JEev+RC( z{^@*ck{n|3bxPBnCqda)9XvS8CEok(uLU|fNjW*4ZEfqi#mf_8j{lCH3gJD%Bn7d< ziLE!$_>HrCc4a|vRf~)dB({q0YvLVu9WKR)ER}3fzx5+ypTX+tog^hCDQhOXHb)!x zi!PDb>E|zn2*8p6UX;K*j$}J{&p}~1d-q4{sR2>|$EQZ|-mP|>m1Z!76GIJp zwAAeEuZN#C-g@t_lrVHCI5@ayI?wOWF^eLUTHKwK=g*ggD=gzG-~b8p9zFk4Ee@9c zka~Ov=^1bCML%}r(4l!gIuj`N8I#~lSK(87*HD8DP6rS(XzipSP5VdGwx8I&dv{LD zl_5Jve(ipRQosg@Jr6bs)Zs$(4+nS~yb~253_cqeK3s(-nRf6k>T$X?N0$a(Cq^s1 zz*)jGnjmXlrn(#1;#w8H9$MtrZQdXLf+;Ymov-!SM3U;{XYbxUfeutZ|;Y@A>myK0b1Q z1pYnBhi+*p41OKh1Hz=LhK5&~XOCq_L;ysX6PhsFp{$!1mgBd))br@k)U2!KP((_15O70(0`So#j_6971P*&u{+U+39jvhZg7+?sd z*LmXV^!jN{umA;#3Mjf|g810ZxSPLDcLZsInU(j~ry z;QEOQLTCK>s!7hEXu!$3x9Ib!}Y!=#p2nez8tAup| zqK5E#y_!48@f6c4zoE$r)P#0G)0Okw@-cyxKBO z7E?rS6cUkK&bRNGGrFXf>YADXWJ_3dP+C2sPgIptZwQx2D%8w(LquZc5>Ya||M+o^ zx%uF9?|z%$Iq6TE^xfcH)rX~%0#;sM?i(2RL}X^FKp6Xu8wL4MMBIB@U)Sa(xwu8{ zYddtsut9xC4xCusx^@}Wwd!!)18%zG)MuSreLMbrZ=b`!ba(jfm@W|xC-CPOsG@Rd zzTGT?Age3(pt?UXeG-{~2=tMhE$I(~f9~A5yd9TbZl-NerI}UMqH0_B)94#%e$b*( zb^R$wiR1CUyX!;VRb`ull5}pG6jV^#`roL{)J8}fK@YU%9+g@SZ?DMSH(jPK>)w%~2sFTL zlQo7;RqELj#PqPcyA&Vm{XR`8_X|Yio_-ZO6~ik10s`h!QFD?`{nm$Q7|m~^Cj&WC zxg56cReZeVP2(ytnRK`(Wo`s1%s>4N=ZmcHGZT+sLR;uW$4Z)%T%joh-)H zUYvk)1t9M2fnMtlIvELMK~a7`s4|%IIkL#JeynFcKPK}e<>H7NkBVUlV;tLa?9^sI<@=% z#P(slpE1^E9tA2{ifdh)8%HMy4LaN} zSvcY|9baZvRyWxX3Ky+hECv)MpK{meRH_&kM6GONW0Pv*6W)Pp!F1YolkDVE>m(2O zN$Yx94LhRQJy*Mb?Sc-Cwn^{aod+=y^0O|=ni&k=c=OH{O@`922^zA1;6YKioj-ql z4L9@eEPu-ZcHJJzX*)pJ4zjXC@R}gmXj-3v4kqe-pFv78GBOb6WQkgix9lmWGex{+ zsOW)n8x0#RSXV#Y6{ZDLJ=ys&t*y@p@+rW^3`g_df)!n{D_XN7J`LurIOw{aouENV zO#kz917P3b^XK2S9$j^PBi*a;n%T?McZG%w2!QXx7!mzIc9X{&>5>Xk`3=KXg`F$< zLt!lhYmgx?G&%K>mroUvMUp1hc!^5TTcN@A_jxc?NQCy=?_nF_LJ*3!DLWFUJ#SvN z38RM9arUEy9u4D7%3Y%JK&^SO0Qt5fseS3eC`hbrZ3j-Do-qH+@ZrNzTngu>(n%aV~-=kdcv5LVyb9Vz7kWOAS#{UOwbP z9o9+DuxS4D}KYpYY z6a*MVnP>jSR%st*`1C8mG;6}@0h<1-xQgKQpzN6B>FEE%6K~>x7({N=x$UspQ0M{$ z+qYxKAR1la24C#@TLv$t2iQ%9Y<&&jk3J8YsLBp(DUbEp{`8VIEEfLTiB5DLZQwN= zHvls7Jd0nxygR>{7E|uvkfA>L54_*Lcp=Z|mz40BV!Nz`$^boJB$A0&;p;}`n=;bS zqhOFASzu;vyggY? zF#9!z2j=GHf*MW!L2l4#FBn2%OG9tL2?PHY4Tu;Ul(sgN_v0p~z_$0A6@<=A$oq;M z%KL(o#aNZL6{IEl-QbUz7@2t-J&O0D3DY$pW?(#KRsVU3p!{=K56rzhtf84e+g(|C zgyB&AB&=r)?r-nQ@Zuxva5KDxAbSdQA19n@hHO~N0z?Xl7X)_kv3OxAVM$-KJ z>S`-kUBeFnY{`(JH*VZ0I4Ha|M^euoKmPFF2J8PE%3bpK`b+yMq$xl=vx6qPEU840;1Bj>kO#T!dunl zSG}+|p|H#Q#rQq3j?~V@&3etY!b>s+ijP4RpO(%}H{f*^z z;7Ps4S%@VW9XfT|z^SphaO2-PNY?9WwYzIKevBSsS3Z-(&Tj=igz9+3kI*ELvmBqd z*wNlTg5lJHg$o%e$}U_sfVS2Q>Nes;`Z4O}wAZhjVy4x>=st1$_{IA%v9TLAZcIf$ z4g2rbx0m+ELHy!fQ_$bYSKQRZHGkWF0^MxPq9&v2f}bw}5)E&JU6pZ7h?bNX z$CBoS7J-=DtzSRyn3&0+59SP^B9(T$xpTOY(|r4VPDVz56_r`8JD9HNHOt?;RbYc# zk*M?O#o{m#1`Um3C`@46>o&cCGMBb{7FZzHU_yw;u59MWKm20(!^O;BmCjw9W4xtU zoW+RSw}GG()Qd=B<-GYbk~*YuR&_ujod5$19#dGBg#YsKsnYq&iY&6wq^hdwIE zluR;d?qWD1woab_IED-#ekh@9vl*a*tBl7by3yk zMgP^b+R~q8$7x6c2F&==Di(8~ZHdF9R(LD(lQ@zEk!GD1=lOrfRNKlbqG)vh=^wbj zK$Yg`5V7p~@~n6N>@{-OvwHTN{)UC&QatUAW@b;hODgF&19$@>;lC`)g=jxH?CB|Z zX|&fe^p3|+{v(M!vg;6>L1SfwUsvGzl$4YRp$|xnx=J$d*}rpI`e3nmhv_li?7~Fp zwxk_H?|^ZZ!YBaz)aL6e4I1Hx!k>&7s+Z{rE>Me_UaYU+|2~4AkWQ(>gu)U1 z0kX%wCGHuXLHz8ZP1xx-j0&hpDOmP^Aj}8#*!irJK#& zKr@ADQd3$a+$pHWSn&F_98SuMuBH%~Cv1DO-qf@< zxh@&Jk*bc!dypT6qrN$|PTF(dOz+Haz_qz%o&c(!T+jkJ>_UfSO87&fa<^dA=DWQB z-+86cU7xXkdtm_Ghj6x}lW)6z<3?dtNYUsYzt%nZ@^ZB%BnryCRuNbM_=R%>jIj+n zc6b8~azi(ur;J>6i@?B;e099zcp4=_C&-p~@cX zHfk-lZ@j;woEo;$VFDKl15So5QKo6qqhrsO{J1cA8>j>?&nSz${tyT{%hzj!8pSMC zzH{>2xf~E4r7;^jaBPzD@{Si48g=P2=^-cYV>CB$K9NE+#mp~=qe2-d(kX!FvM=L^ z?S7;t`L~-oN$r2k(9#`ld{MayLbdgzZyNsyhGMif9^T%YxB#0is+7+t?1d&%>>Z#` z7L*n&rBv0_ZY(H!36*5|w`eFqg#+B?c@;arQniTQZD2^rtr+U_LPhTAmmPW@efQbZ+hR zF2d6cYV_8Eh?$k$06NWKBqmq?Gjwmh>93yi=0VRKl-%m%zw*GO+on$1@wUSMpSUAT zb&ZP)Z!Vn=bF+qK;neAI09+6d2NzvhMf&SRQJuQK>%HbTuWOGVo2XQ4J?nN^>*(-A z>oZ?}E+|*FKOMJZS)ef&h&jbrl&q`N-U)&U1+|9lh4I&ytBsa!P@r!4eB1nmQ+GMK zsHPR~z0S(5=V%KAhUA$*+UYiLbmCT#A;A6FLt+2%itNb!$K^cXB0$5l&|Vx66CgYVBukv+|(#J56$k$Eswe~aHQ4wv2wASTiQ5asuYlM-J=_L zdLoMd zQunLDycr{%{q7S6Y)X@*U_V{D-@2sXXa7&1KH=YJLlhO7C_wHNALDyKJ4jSf>ecHR z1zo%g&HxNg;vyUGQ2IiB@w~MYo$+{988qdY$*`#chru*PB9zcV+w11$Hfqe6q2;^gvGthPvGwwCd-;*whaoNxmeTH)fJ@0m*6aBzi@33G>#|dx&&2x zE{v(`q)-W=9VKT!D=sp=#e0Ld?8*pYE|tR-&ek|qf-t)6n9>afgM!eJ!wP%#wo#-f zRI3-)=cVy()=R7ZOIy=38k$T@8NK0AHR&kAwZ&0!gwcE;osS9BOi-MhbqF&uT}2c*QLZ|WMxU=Q&EVh#x?TUKGI&m9D(L{E6I&-9@~ z=Z{d*JKJt%CRhOUE8&B|XkbQCq#wPQhKK`n(86rpMyrNi?I#*!;hQUbQ^3$msquY3 z@EyIGy-WrCF5!zo)Z`KcZ{K$B*;9uUM6-x5{vk532)&fpb;)W$Tp>!vwTXGoot=iK z(&&l5-u7l3*#;PFFrV%dbx(2tFU30T|MUQ8yw4e}W`gMnlT1?TvJu80KT_klyL0Bw zJr(V{1g^G_z5-g>J30!@;NKbvnjo8I1pU2B-zip1f|#JS8dbe~_;9Zn<*~|z8fD!_ zdtxHBu9Wm#&tJcO+5D=v#2(}cbt3I)8)?P;M4rBY2&!YoEbVgP?AdI_$}Jg+yL2qO zY8p=`&mF=+(Oq;f@6Y{j13m^SYZVMhzTG#z5!4p5EIMv7Z|RC(GNkoqVL zApZklQa5mR!n5OPtr(sQssJyR%YepT5y6iA(v>?=?{r~|7eocXhqqxt3dWlU2GAxX z-YATB@&|j+)YO#tTyT3J4mM<=P7JBnRkG`W9Ck&X~|4js(OJt`f zxx|?kgCPnU#)#AtC$w7}7~n?l`l<+F#{>$QY~PrvaQqmZ&*#VV9Bul~l=F+Gzk-;? z_MI%aaO~FjzydqRnnUjHHH_llmzOs#=e>V?f}|5k0{|xU8N(Y2n-35#{xfqE`z8L@ z%q??*j8%2XOox5v7|09vMPP7ic=BY`+NGWpEFWmeN!P2DcgpwbWoX{M|FkUSsvXu- z8H17E#BiNnlwr@EZEsg9oq{uYGmCnZ35n@D zSXC8GYqB#*vfQv?Kf|fO-y6bA(hM9N6SHe$*Z58g2@b~5w4=22EMHYJ?`tq}&ZgqQ zL0ywuZXmJVhabFX-KE%>ty@koznjTG5pHw^Qtv?os%6%}JU<6tFN7i;cqg$BD% zlp5sYX9+G&7a#uUg;A`;aUFD7g>sx3Zl(i|aGS*cHKWoC?`Gh^ zJsxf$`^F;Z{NO=@{3d`iN6Eii z;do^@74R|A!C09?N(d+bnTf}dBWew>C_++ao*wDu`|UQLUG!xVU^k!>Pe_990Mm?s z#7ZU*>kb>bo$NK**085odm(lzF)~tc(&Sk&j=*Rwn~z+73~q}j>GjL^-xSq?lnJY3 zBX!|)O?qi$sQVS zm>2^G?k8Vj*gg1uPL&80LXgO4vC4gUG#_p0;`zOl@;JtW7X&;c-aX<5{+RFd4bBE3 z!0-DWwE4qVN9+ZNJ3-A$hR2}Qf0XLX>q{iU(_W1Icl`2?zgzKt#xGk=Ea6p8{hwv1 z-=qg?7vGDBh_DX|eMR{#EO7~N+09XM4b7Y1*8QIa=}_4N&M)P{YFF*0@jgqoVodUC zjNb?(G_mic%=%GG;%H>wRTO!N?>nq==(!2-Q@{t{91a`p8T3447U>gE9&>cysUPwU z!@mj0UkYEPj8&H+x_3Bo`HH0l1>!&Y$E^JRl^XmX3WOr7IsF>-W?g>TU#A;S^}UJa zZ0OZUituFUai(8zeC6F6`59xfRi=%MU!FgH;<)tTDV@vJpQzMH?O5Qj;!Wd1e&KcF zwzQm3bJTlZEU6ead^K5uacske#25N!#m^Y;zr|wn7W-MB&y^a4R zc$&Eye_AC&v5yBqU7qFGenYf)BmhFsNT^zGq>f*jOD_5=*?uelF%mJ3Lg@JrZ z4R7^6wIdSI62||g{Ltj;5#dV`kIcWfhHYERjU2W}8fILv2*_WR}8pDrB8j4&pLj%fTlIaWz+tm*|E2JlE z@EhH4ifhI^1+7cl((WA?axm&sa$fsIvrL(i=|f6UMvSul!Q zw{Cr$#4H-4?*X8UMVmHn)+Lq;auu0T>;gf^8MUYN&(co!XD#K?j9T2Q#OTRs*YUrf zK8+b@lAluG;xciG-6iD_B`mW_Nlu0jb0XjSRmD!>DbFBWv!Pp5?tV~mswv?QyJE}R z{Ct1Ff}K;&LwS1pxJ6^TjxVtMB_WuLjur)~U_bV#q& zZZI*KDFAymCUI0@BH7^BE!LPpvp>*Y$V1c%7e~C<2p~z?BS{O5FA;DS${%}+k@KVV z&rRA#rsS@mETnE=xCwOFhTbw0%=IyvI&lL+LPA8x19W=w*8?V>23K=m6`ZPk8C$pS zdHVy84n#?!BRXhYqCeC=Xd%E&wJ z$E!79GmsfQ6~4bWeCPiDJDVoxMq+TBgKeCzoY?K)l zXl!Wd=J=`#`W(yneepR8WeKA2$^8qB&*P$ZwOOk1pmDnR?UFgca=a(o-+w zV9iK+Q{qjW?F^rWd)y5pR#@J8@7}wvzG)D=xYXjy{9;3w3Zvk$Q^UTme;&LrH6-kjG6Sm%vw{p?*v9__fnFo zgs>50pv0?~nUS%cQ4m;-++I@87`*s$9zP~NHN(ObWhtI6Pnjt~)YGQv0(`FAaJ9Ig zK#9N@->C07LPb@ghcR z*f^K>H6b%u!+eobW^!o$d&h_U+2l4G0vGiXr7_+892yx>eTgQRx0jIl|G|fxg$BECEuiFb5bMx-P-_uw`~mj_QaJ$Kv8N`M}qx zzAL`XSe0~iNz{LF0U~NVHr|w1+j?|c^^H>PP5w`m)H;`0jf|8SJ8G10al67qk8Z!) z|4kTJLzI1rD;a@Bk~WDJFWdhzgJ|}8uHZQsH20#(mSYk^j^|H^26R2Mf95}#Bs}bWTY>^2v zP&J7vK})Yk+`H#$lB}WAjb)X@-7g)@t*olYx&#f<5%jTuvuB^fY#=GuthUU~%JTia zNAGUr$(_Xw*G`39Dck;Jt*dv-`N!60Gau)=e2dV}rmQZAwHpc2G)P6ojawx?Hf^;B z_n(q{1K_rh-Pza(*JL7;%}+j1mfo|giA zPpz$|Ul<9qgG^s@y)xKpa>j3|HxD05K+@uNeVlpNJ)PzS#!GGM-${j2lT&5+AY~BT zkDtEmQ4Bb7VxW_Imai4%&oQntGZEs=>KL2gxTc>!sTYCr-}ClB4U^RIoy3A)B972Z zx*h{{KdG+EikLwwFS_3}s$Ob*uss1J?3=VOKm_APUm@1kEDbZ7OdT-jzPa=|b9Hrf z!B>RVscA7UbY*sETLg;e1M7|ULkXe)VqREFyE4u}OWrxf!2VXAOheq7-f8p;2XI?% zZmqi*VZ*8sv+!9uD3>xW995VeJ0!Br`TC4gQ7fO>O#M0`Hmve}uIC<`VRr+jZ+}zX#S}$4ixxd1PEjEN7>KL^W06Xw8eJ?~T(un?9~gIvjL;5SdYy#6 zr?Mr-y?Bw9#g>t_Sx*ne%ktqOA1XSgB>a5eDMmdtGqa z^`!jDK;yXv0}rgJUM>dx9DP9vCu#HhKhb-EP(^0MfV6~gXW_ma=1`Cxgqchy`TB_p z($)i*xB}?zb+q6vA7eXAP53CvqDZC-XE!10h9aaUEpFMqg34Bqa zMK7nu4?xvHQc-3$ALmWiM#M0BFbZ z0{g{xhY4pR_3=;bH-?0c$t~++2HI;LxY<1Dm9eMo@50u%IXOpVwVFl#A!qPzUE)e? zwlL^9*jZUqa6@n39snKS+qbPeVvFL0c+HNjAfKMht~nmFeO0lQ&H}h3i;A!Z;zT4O ze9%PGAkB7kbi8fp*eBn>pg{LTKVFa8tLil5jO;>F6XG${Xg?$DpJ`3*ohIn`=II*N z?rJj9OMLVt;HCZcx{Z&X_UxlGX=z?^Z1MO%B@J$3E-frCdHn#vQGle;3NXF$9zKez z4yGKk3E&YBB}U$VD3CdBx!_v?8$IH5NibyLuiep16Xb`m>;TB`62$+Xoz|uSJ1lpP zUwL!TlqrVy8j}~&lhHB^m3M3@ZrniuBj`N2`>W$VeeVJlNUOC;R?JX%azG2vM^nU{ zOT_b>Fh?vyxy!2~MqYliSH3{vmggU8ur^%7|8F)PxC- z-oEX9eo;ENw@h(P(Ah=-dTU8#qa@JOJV&y4_IlqUm8m1oCWbYq{kZeBdDoATroN`S zf%av?DjO}uT03FfN?9^+=ui)kTT!q%BE!Ea08`myBFKc}EkKr7$Ihq4N+PF@+DQ`(tF#t&^)3 z=dCS=bqyl|R#D2MM+cczQ>6(~0)#gS>4dhT2}E&x>0Gg(L&Hf7J235*+%m;)3B!Zz zZ~ypFF7(hHJ-a0Zmoy&fI%MV6@YRE#p8;$kta|p<(6ASKrb%Z*pG~Wt)MR2|;o+UT z_|2V~VO2V7!JqK>sopm)88>VFc^@II{7_29 zI&JyV*fVEhT)L|*wB7e2b+~QCjk58!`KdN~8VZk{zB`^!w9P#m8SU2`W_hNQhk?%a znEq#n4fVX}@vutvy}a9zwvq7{ywe>tCmotR)^_@Z(+;_tK8+pgr}i#?=j`5x-WR2u zFWB;0R>|SGlb__IRlCg_@4eGxBgN8HJp`4D=!&_4-x&v8J-rV;^OQ}X9iPXne+>nowIep9+8&*#~L_y;c2`V|d4Q#x%!?YlpR z><=x?&OZ%EZL?&^W^4aQ#rr3XJg1f$zT;u8H#eV~e(XHuWH$uoV#9BUlVAC{50G>Q z!;J0qZWZ5H!j~p=t=n&i2z%2x|8pwUVo?Z&`BVoS_ zMoUK~jLY+$SZ>?mwBp_?TdDie-5$Te}2^bMaI)J@8)dz_x2R5jk>&j`PvnK zBoEjv8d-ZT`we9a2E3V#Q@;NWUAHYxHd(xz)YD_7jHkzP ziPvwPrR+|>x?w#gRBf^L5s&$47uN(H@$k5owsuyx$f^M7<_fC{hFx}xT_9yQEdKFz z-d(rf6Jj;q9d@<3xOv5#D{f=w9x~}?J11$aqTAGv?^YVO`6ou9U9+}X-LyU9;W6Lc z!a98TAbsHbFlSE{jhmRc3RJUq?H)Gjk8 z=IqqyT?ro&y`GvxANVD{ouMTnXv4R2=16D$We!GNIMzc(y3(nAkhQrR-!9^GmfiX_cH?1uK> z8bWxY=jP$Dyrg78KuYrmZLM#TRM77a4+$*E@X;D616!vA2+puA{H3IYD;4LoN}K$# zO6^xvC~<0nd%uP@-ywoRTPc^W6vJ&sTQK${HriQ1*g?r_ zu5hqsN=`dv27k!VZO)vJL27}vg$Acfo_C(0f2htxd*V0AUx4S>jznEAHz8wT^)i~V z`Y4$X_>>XPMT;sJ!R*LpXeK!d-&sHk2hefMt0(g}Ff+FBxGbU?OzPBpIoT zOhbj#I52Q~uTMbxf}zPPCMF5AcY+iKAuyfA?DSl1s^PUV_YYFJkWMZg3n#|8^*%yg zI37vR1W>Bx)V1>YZ5f6Xx&Gev+_`8w&3hH>`R3C}yhC0A2Z%dHjy)v!|G1~Pws2L^p1xnwH(yeD>!eC80q3#gSU z`I>D7od!`gypY=FFci5_Ow%#=-kI+x0vhN!6skO|&Ym~ZRQm##ed@IvMxQey-H=8m z&1l;WzzPsD^N(i|sVdKul&lwYS|l*oLRy3sJB8QC_MLK)@ll{tWsFgZU@}vGZ`K=p zsbs_+283?(G{d6rgQk6LMNajXx>%c~E+$%(D76^_z1NR3*D@PCdi2wA-$27Wo&T_i zQ=54CJzqb*c+ zRd@EVEl|+!Zr)UfG(eqFje6}F<-Ab}jT&m&^G4z9e=M$2#9Nl4ac`D9G*`gEHSRD=+o`LTo)@0RX`Eq zw@iam9S9a<1t-Yp!n$}zKf&faR{WJZ2xKq$?c1~I%1%c~T-6lyrrWl8QOeVkPZk6( zNM*vo#O2pcG@ENnY9x)Kt@bgF!`= z4-hFd=up3r#b#3=>w_09A~+h?twW}UCZ+?}0{FUP*s-K0S)o)P{)Uhj5@JEF9 zvqJ|KBLs3BO-CsSmrWptkiJL2YP_%nzVq-ydqKj7Q)Z4};Em1Uq0!liM~`+E3VuRL z?VWpVgzMRb=`IrUX$vVP5%o}U&s(tI=&;2QH8PgzPh0V^&JNO~@G5+`Z_o61w~+3z z={ozxQltjmcYS#gwBn{#Rp)x9b*PG!IR+A|qs(Ol;qA?vDXTo4>3JG=8N2d7%Td4T ze~rJ!SX0oE35Ax>q`qzt-N!qShFIvLe5>~%c?}_p4!mEpE zs(X&#EYFP}$N~e-%XwOrw(GZVUj$->x|!SUI<)#{8{TB}S0?n7uxgCfjFgkIYw7_8 z070DX#tQ>mw-rR}qd*Wo`7GUK6X0mkY z(rTD=K%KZ#Y2{AhmOY|von-y~AB1C9S(fs%XOydo7sEThC1Q`iX-mK?_%5aj2S*A$dwjvFpOD)Wg!*gf@1|Yl^+ou>6A+mmc zeZQNMrhP<3b@lgM!n7UQqK1-5-q-<6K+-?d`ayr*?v=P=Dq!nTQAs9-8$^gSJ+M=B& zjxc8LjOE6;9rk#UpP{iVVTdC>e{(CrRH&Co`Mw}t>|Yv6$F?gy`?>TM zxCxpysoi1boB|*b>JeJ_+V7+H3=u;LK5ED^iK>L(Bd9CNSnZT!XHTz>A^&{L-X^lu~9leG17Yzv9p( zFnxQz?Tvj@cH|70qFyS%$)LhG+szB}5g)U9H1{dXRa2NpeC7sW~S zr?WeXYM$PltWgA8IbceFaJ-;Giey6)9Si-=g7Z^e%KriJF(dY%syQL#L0!9Ar4Jm? z2=5B<7wMGcAcgBQa`v|WYIb)_r?%#P-!@E(H-Ff5Z2#ZqzIoWq8LzO|NVRZ|NQb{#lx5X zGYIDU5_hyH(v^KOM}!_;*>c3=q|@O&uPfD~vv*qES9u-mcgli0vTElsaqSwFzNLW) zy%Ucc-dG{$BmG3FZ%D}q^`v+GN639`cmK|dBOc2)Za;3mE$OjsS=G^M$ySx{^Im#s zvK>A6W_v zzWVjt>b~n###YX~>(tKf&1BnWPfjJohk}$pd$x1=j5${#=*V&5_){1ERpVCgjnoP^ z?nEi7Rz(imRfn*4u1)R2P-_(x_l@HWKa^DGe{YtNYTSRrDBaiayxNDt+hbPrTJ`={ z*-rHKMnyd%#$LV`E9d`Y?$KSLqwkL%IDW$UYtu5%$;|KnVeZPHPr`tX366M2j4rfC zHcMKIvMpbv(M0=|wEwL{uFI>7Gxkq#dUv?pG~41o&x3*{cahn4?Yqgw+<^IGo<}ZU z#-o(amsuUzf0&BbiLdXQD*MS9c_!4El%CD(c~0g*R?%UfZ`IRNP8D69JZjpJuhtcl z#zh2e@A2Do(6wpQA(XxuUQji{b4Q*Kk)^oihJcqjnFUypAmBWCDE^ zctC8Mdy2kQ$mjG%#?LV{?1k}@u==L{se7{}oQ5AL;`pgPoCmq!d$xv;ycS6K4(wEX zcnchBT$;;&4KJ@SqNKP?s|7xJh(IGu$f%S6Z_BXNRRLQ>R|P_-O~owo$^rU-q&z`USJAv(X+{@xXE80@$L@lsN z0Z!W4QJY)<+S-ySC+E{`$&J7+<`HgJ%_l93^6IO#;FwCq)|z!+&z(7w1-Vhw%~6fL zb8;~I=?WjO?ZcE5Nm@CAaxzz!bITx#{QbgL00>i~L%+%FG+f<2eei^DXO*Q3nG2`-28uTHZ(P{;qo$Q{vtz z4S!rPalnz20re`q?HEedwiJ>`>+LYuBuGBCiv|L-5nKer&76Vv_oDmuUQ<{9?16-{ zR^=?8gZBtEhJ{iuEUmZQn3&tr_4v7Y`;4dUIzR35z%~}mHY>LF(Re8LAaq;6Ce078uO=_##n-)-7Qe%J`M!glPAhauU3qQRL@ZK#hp1foe%-Lp3>?TI ztUUdQM@EZq@PG)Sv3-~;J8(kWN2u%RPwy`0aQxIg`ZG(X8zmzye$h}XoqM<2=^Flz zpJz2O)4@KeW#XC}t&i`$_%mrs{+fp}FCz&OKJo8XS(U3_{CfS_x_vTZBDNn78e}kM zPL|BBMcw7(u6NL=e5UsOoRm)MvNYYy2b

ym?RmMt|KHwd+C4b*34qe%NeX+Dl`^ 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 literal 0 HcmV?d00001 diff --git a/doc/img/LoRaMod_plugin.xcf b/doc/img/ChirpChatMod_plugin.xcf similarity index 92% rename from doc/img/LoRaMod_plugin.xcf rename to doc/img/ChirpChatMod_plugin.xcf index eaee9cc723e4d9e479e2d799948562d4dfc3dbfa..cbcd7a39a4184ce418dca9a4d535387805fc531d 100644 GIT binary patch delta 7578 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 Y=zvb>f?)JSAM`~S2Bi%jVrgdl2ig5(mjD0& delta 6392 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 I@THXTKlU@I8UO$Q diff --git a/doc/img/LoRaMod_plugin.png b/doc/img/LoRaMod_plugin.png deleted file mode 100644 index 1e5b15e92bbcb7fcee36cb7c51f9a573b0309573..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45855 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 z 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 #include @@ -36,16 +36,16 @@ #include "device/deviceapi.h" #include "util/db.h" -#include "loramodbaseband.h" -#include "loramod.h" +#include "chirpchatmodbaseband.h" +#include "chirpchatmod.h" -MESSAGE_CLASS_DEFINITION(LoRaMod::MsgConfigureLoRaMod, Message) -MESSAGE_CLASS_DEFINITION(LoRaMod::MsgReportPayloadTime, Message) +MESSAGE_CLASS_DEFINITION(ChirpChatMod::MsgConfigureChirpChatMod, Message) +MESSAGE_CLASS_DEFINITION(ChirpChatMod::MsgReportPayloadTime, Message) -const QString LoRaMod::m_channelIdURI = "sdrangel.channeltx.modlora"; -const QString LoRaMod::m_channelId = "LoRaMod"; +const QString ChirpChatMod::m_channelIdURI = "sdrangel.channeltx.modchirpchat"; +const QString ChirpChatMod::m_channelId = "ChirpChatMod"; -LoRaMod::LoRaMod(DeviceAPI *deviceAPI) : +ChirpChatMod::ChirpChatMod(DeviceAPI *deviceAPI) : ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSource), m_deviceAPI(deviceAPI), m_currentPayloadTime(0.0), @@ -55,7 +55,7 @@ LoRaMod::LoRaMod(DeviceAPI *deviceAPI) : setObjectName(m_channelId); m_thread = new QThread(this); - m_basebandSource = new LoRaModBaseband(); + m_basebandSource = new ChirpChatModBaseband(); m_basebandSource->moveToThread(m_thread); applySettings(m_settings, true); @@ -67,7 +67,7 @@ LoRaMod::LoRaMod(DeviceAPI *deviceAPI) : connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); } -LoRaMod::~LoRaMod() +ChirpChatMod::~ChirpChatMod() { disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); delete m_networkManager; @@ -77,31 +77,31 @@ LoRaMod::~LoRaMod() delete m_thread; } -void LoRaMod::start() +void ChirpChatMod::start() { - qDebug("LoRaMod::start"); + qDebug("ChirpChatMod::start"); m_basebandSource->reset(); m_thread->start(); } -void LoRaMod::stop() +void ChirpChatMod::stop() { - qDebug("LoRaMod::stop"); + qDebug("ChirpChatMod::stop"); m_thread->exit(); m_thread->wait(); } -void LoRaMod::pull(SampleVector::iterator& begin, unsigned int nbSamples) +void ChirpChatMod::pull(SampleVector::iterator& begin, unsigned int nbSamples) { m_basebandSource->pull(begin, nbSamples); } -bool LoRaMod::handleMessage(const Message& cmd) +bool ChirpChatMod::handleMessage(const Message& cmd) { - if (MsgConfigureLoRaMod::match(cmd)) + if (MsgConfigureChirpChatMod::match(cmd)) { - MsgConfigureLoRaMod& cfg = (MsgConfigureLoRaMod&) cmd; - qDebug() << "LoRaMod::handleMessage: MsgConfigureLoRaMod"; + MsgConfigureChirpChatMod& cfg = (MsgConfigureChirpChatMod&) cmd; + qDebug() << "ChirpChatMod::handleMessage: MsgConfigureChirpChatMod"; applySettings(cfg.getSettings(), cfg.getForce()); @@ -112,7 +112,7 @@ bool LoRaMod::handleMessage(const Message& cmd) // Forward to the source DSPSignalNotification& notif = (DSPSignalNotification&) cmd; DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy - qDebug() << "LoRaMod::handleMessage: DSPSignalNotification"; + qDebug() << "ChirpChatMod::handleMessage: DSPSignalNotification"; m_basebandSource->getInputMessageQueue()->push(rep); // Forward to the GUI @@ -130,12 +130,12 @@ bool LoRaMod::handleMessage(const Message& cmd) } } -void LoRaMod::applySettings(const LoRaModSettings& settings, bool force) +void ChirpChatMod::applySettings(const ChirpChatModSettings& settings, bool force) { - qDebug() << "LoRaMod::applySettings:" + qDebug() << "ChirpChatMod::applySettings:" << " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset << " m_rfBandwidth: " << settings.m_bandwidthIndex - << " bandwidth: " << LoRaModSettings::bandwidths[settings.m_bandwidthIndex] + << " bandwidth: " << ChirpChatModSettings::bandwidths[settings.m_bandwidthIndex] << " m_channelMute: " << settings.m_channelMute << " m_beaconMessage: " << settings.m_beaconMessage << " m_cqMessage: " << settings.m_cqMessage @@ -234,89 +234,89 @@ void LoRaMod::applySettings(const LoRaModSettings& settings, bool force) reverseAPIKeys.append("bytesMessage"); } - LoRaModBaseband::MsgConfigureLoRaModPayload *payloadMsg = nullptr; + ChirpChatModBaseband::MsgConfigureChirpChatModPayload *payloadMsg = nullptr; std::vector symbols; - if ((settings.m_messageType == LoRaModSettings::MessageNone) + if ((settings.m_messageType == ChirpChatModSettings::MessageNone) && ((settings.m_messageType != m_settings.m_messageType) || force)) { - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(); } - else if ((settings.m_messageType == LoRaModSettings::MessageBeacon) + else if ((settings.m_messageType == ChirpChatModSettings::MessageBeacon) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_beaconMessage != m_settings.m_beaconMessage) || force)) { m_encoder.encodeString(settings.m_beaconMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageCQ) + else if ((settings.m_messageType == ChirpChatModSettings::MessageCQ) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_cqMessage != m_settings.m_cqMessage) || force)) { m_encoder.encodeString(settings.m_cqMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageReply) + else if ((settings.m_messageType == ChirpChatModSettings::MessageReply) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_replyMessage != m_settings.m_replyMessage) || force)) { m_encoder.encodeString(settings.m_replyMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageReport) + else if ((settings.m_messageType == ChirpChatModSettings::MessageReport) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_reportMessage != m_settings.m_reportMessage) || force)) { m_encoder.encodeString(settings.m_reportMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageReplyReport) + else if ((settings.m_messageType == ChirpChatModSettings::MessageReplyReport) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_replyReportMessage != m_settings.m_replyReportMessage) || force)) { m_encoder.encodeString(settings.m_replyReportMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageRRR) + else if ((settings.m_messageType == ChirpChatModSettings::MessageRRR) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_rrrMessage != m_settings.m_rrrMessage) || force)) { m_encoder.encodeString(settings.m_rrrMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::Message73) + else if ((settings.m_messageType == ChirpChatModSettings::Message73) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_73Message != m_settings.m_73Message) || force)) { m_encoder.encodeString(settings.m_73Message, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageQSOText) + else if ((settings.m_messageType == ChirpChatModSettings::MessageQSOText) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_qsoTextMessage != m_settings.m_qsoTextMessage) || force)) { m_encoder.encodeString(settings.m_qsoTextMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageText) + else if ((settings.m_messageType == ChirpChatModSettings::MessageText) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_textMessage != m_settings.m_textMessage) || force)) { m_encoder.encodeString(settings.m_textMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } - else if ((settings.m_messageType == LoRaModSettings::MessageBytes) + else if ((settings.m_messageType == ChirpChatModSettings::MessageBytes) && ((settings.m_messageType != m_settings.m_messageType) || (settings.m_bytesMessage != m_settings.m_bytesMessage) || force)) { m_encoder.encodeBytes(settings.m_bytesMessage, symbols); - payloadMsg = LoRaModBaseband::MsgConfigureLoRaModPayload::create(symbols); + payloadMsg = ChirpChatModBaseband::MsgConfigureChirpChatModPayload::create(symbols); } if (payloadMsg) { m_basebandSource->getInputMessageQueue()->push(payloadMsg); - m_currentPayloadTime = (symbols.size()*(1<getInputMessageQueue()->push(msg); if (settings.m_useReverseAPI) @@ -354,12 +355,12 @@ void LoRaMod::applySettings(const LoRaModSettings& settings, bool force) m_settings = settings; } -QByteArray LoRaMod::serialize() const +QByteArray ChirpChatMod::serialize() const { return m_settings.serialize(); } -bool LoRaMod::deserialize(const QByteArray& data) +bool ChirpChatMod::deserialize(const QByteArray& data) { bool success = true; @@ -369,40 +370,40 @@ bool LoRaMod::deserialize(const QByteArray& data) success = false; } - MsgConfigureLoRaMod *msg = MsgConfigureLoRaMod::create(m_settings, true); + MsgConfigureChirpChatMod *msg = MsgConfigureChirpChatMod::create(m_settings, true); m_inputMessageQueue.push(msg); return success; } -int LoRaMod::webapiSettingsGet( +int ChirpChatMod::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) { (void) errorMessage; - response.setLoRaModSettings(new SWGSDRangel::SWGLoRaModSettings()); - response.getLoRaModSettings()->init(); + response.setChirpChatModSettings(new SWGSDRangel::SWGChirpChatModSettings()); + response.getChirpChatModSettings()->init(); webapiFormatChannelSettings(response, m_settings); return 200; } -int LoRaMod::webapiSettingsPutPatch( +int ChirpChatMod::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) { (void) errorMessage; - LoRaModSettings settings = m_settings; + ChirpChatModSettings settings = m_settings; webapiUpdateChannelSettings(settings, channelSettingsKeys, response); - MsgConfigureLoRaMod *msg = MsgConfigureLoRaMod::create(settings, force); + MsgConfigureChirpChatMod *msg = MsgConfigureChirpChatMod::create(settings, force); m_inputMessageQueue.push(msg); if (m_guiMessageQueue) // forward to GUI if any { - MsgConfigureLoRaMod *msgToGUI = MsgConfigureLoRaMod::create(settings, force); + MsgConfigureChirpChatMod *msgToGUI = MsgConfigureChirpChatMod::create(settings, force); m_guiMessageQueue->push(msgToGUI); } @@ -411,95 +412,95 @@ int LoRaMod::webapiSettingsPutPatch( return 200; } -void LoRaMod::webapiUpdateChannelSettings( - LoRaModSettings& settings, +void ChirpChatMod::webapiUpdateChannelSettings( + ChirpChatModSettings& settings, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response) { if (channelSettingsKeys.contains("inputFrequencyOffset")) { - settings.m_inputFrequencyOffset = response.getLoRaModSettings()->getInputFrequencyOffset(); + settings.m_inputFrequencyOffset = response.getChirpChatModSettings()->getInputFrequencyOffset(); } if (channelSettingsKeys.contains("bandwidthIndex")) { - settings.m_bandwidthIndex = response.getLoRaModSettings()->getBandwidthIndex(); + settings.m_bandwidthIndex = response.getChirpChatModSettings()->getBandwidthIndex(); } if (channelSettingsKeys.contains("spreadFactor")) { - settings.m_spreadFactor = response.getLoRaModSettings()->getSpreadFactor(); + settings.m_spreadFactor = response.getChirpChatModSettings()->getSpreadFactor(); } if (channelSettingsKeys.contains("deBits")) { - settings.m_deBits = response.getLoRaModSettings()->getDeBits(); + settings.m_deBits = response.getChirpChatModSettings()->getDeBits(); } if (channelSettingsKeys.contains("preambleChirps")) { - settings.m_preambleChirps = response.getLoRaModSettings()->getPreambleChirps(); + settings.m_preambleChirps = response.getChirpChatModSettings()->getPreambleChirps(); } if (channelSettingsKeys.contains("quietMillis")) { - settings.m_quietMillis = response.getLoRaModSettings()->getQuietMillis(); + settings.m_quietMillis = response.getChirpChatModSettings()->getQuietMillis(); } if (channelSettingsKeys.contains("syncWord")) { - settings.m_syncWord = response.getLoRaModSettings()->getSyncWord(); + settings.m_syncWord = response.getChirpChatModSettings()->getSyncWord(); } if (channelSettingsKeys.contains("syncWord")) { - settings.m_syncWord = response.getLoRaModSettings()->getSyncWord(); + settings.m_syncWord = response.getChirpChatModSettings()->getSyncWord(); } if (channelSettingsKeys.contains("channelMute")) { - settings.m_channelMute = response.getLoRaModSettings()->getChannelMute() != 0; + settings.m_channelMute = response.getChirpChatModSettings()->getChannelMute() != 0; } if (channelSettingsKeys.contains("codingScheme")) { - settings.m_codingScheme = (LoRaModSettings::CodingScheme) response.getLoRaModSettings()->getCodingScheme(); + settings.m_codingScheme = (ChirpChatModSettings::CodingScheme) response.getChirpChatModSettings()->getCodingScheme(); } if (channelSettingsKeys.contains("nbParityBits")) { - settings.m_nbParityBits = response.getLoRaModSettings()->getNbParityBits(); + settings.m_nbParityBits = response.getChirpChatModSettings()->getNbParityBits(); } if (channelSettingsKeys.contains("hasCRC")) { - settings.m_hasCRC = response.getLoRaModSettings()->getHasCrc() != 0; + settings.m_hasCRC = response.getChirpChatModSettings()->getHasCrc() != 0; } if (channelSettingsKeys.contains("hasHeader")) { - settings.m_hasHeader = response.getLoRaModSettings()->getHasHeader() != 0; + settings.m_hasHeader = response.getChirpChatModSettings()->getHasHeader() != 0; } if (channelSettingsKeys.contains("myCall")) { - settings.m_myCall = *response.getLoRaModSettings()->getMyCall(); + settings.m_myCall = *response.getChirpChatModSettings()->getMyCall(); } if (channelSettingsKeys.contains("urCall")) { - settings.m_urCall = *response.getLoRaModSettings()->getUrCall(); + settings.m_urCall = *response.getChirpChatModSettings()->getUrCall(); } if (channelSettingsKeys.contains("myLoc")) { - settings.m_myLoc = *response.getLoRaModSettings()->getMyLoc(); + settings.m_myLoc = *response.getChirpChatModSettings()->getMyLoc(); } if (channelSettingsKeys.contains("myRpt")) { - settings.m_myRpt = *response.getLoRaModSettings()->getMyRpt(); + settings.m_myRpt = *response.getChirpChatModSettings()->getMyRpt(); } if (channelSettingsKeys.contains("messageType")) { - settings.m_messageType = (LoRaModSettings::MessageType) response.getLoRaModSettings()->getMessageType(); + settings.m_messageType = (ChirpChatModSettings::MessageType) response.getChirpChatModSettings()->getMessageType(); } if (channelSettingsKeys.contains("beaconMessage")) { - settings.m_beaconMessage = *response.getLoRaModSettings()->getBeaconMessage(); + settings.m_beaconMessage = *response.getChirpChatModSettings()->getBeaconMessage(); } if (channelSettingsKeys.contains("cqMessage")) { - settings.m_cqMessage = *response.getLoRaModSettings()->getCqMessage(); + settings.m_cqMessage = *response.getChirpChatModSettings()->getCqMessage(); } if (channelSettingsKeys.contains("replyMessage")) { - settings.m_replyMessage = *response.getLoRaModSettings()->getReplyMessage(); + settings.m_replyMessage = *response.getChirpChatModSettings()->getReplyMessage(); } if (channelSettingsKeys.contains("reportMessage")) { - settings.m_reportMessage = *response.getLoRaModSettings()->getReportMessage(); + settings.m_reportMessage = *response.getChirpChatModSettings()->getReportMessage(); } if (channelSettingsKeys.contains("replyReportMessage")) { - settings.m_replyReportMessage = *response.getLoRaModSettings()->getReplyReportMessage(); + settings.m_replyReportMessage = *response.getChirpChatModSettings()->getReplyReportMessage(); } if (channelSettingsKeys.contains("rrrMessage")) { - settings.m_rrrMessage = *response.getLoRaModSettings()->getRrrMessage(); + settings.m_rrrMessage = *response.getChirpChatModSettings()->getRrrMessage(); } if (channelSettingsKeys.contains("message73")) { - settings.m_73Message = *response.getLoRaModSettings()->getMessage73(); + settings.m_73Message = *response.getChirpChatModSettings()->getMessage73(); } if (channelSettingsKeys.contains("qsoTextMessage")) { - settings.m_qsoTextMessage = *response.getLoRaModSettings()->getQsoTextMessage(); + settings.m_qsoTextMessage = *response.getChirpChatModSettings()->getQsoTextMessage(); } if (channelSettingsKeys.contains("textMessage")) { - settings.m_textMessage = *response.getLoRaModSettings()->getTextMessage(); + settings.m_textMessage = *response.getChirpChatModSettings()->getTextMessage(); } if (channelSettingsKeys.contains("bytesMessage")) { - const QList *bytesStr = response.getLoRaModSettings()->getBytesMessage(); + const QList *bytesStr = response.getChirpChatModSettings()->getBytesMessage(); settings.m_bytesMessage.clear(); for (QList::const_iterator it = bytesStr->begin(); it != bytesStr->end(); ++it) @@ -513,142 +514,142 @@ void LoRaMod::webapiUpdateChannelSettings( } } if (channelSettingsKeys.contains("messageRepeat")) { - settings.m_messageRepeat = response.getLoRaModSettings()->getMessageRepeat(); + settings.m_messageRepeat = response.getChirpChatModSettings()->getMessageRepeat(); } if (channelSettingsKeys.contains("rgbColor")) { - settings.m_rgbColor = response.getLoRaModSettings()->getRgbColor(); + settings.m_rgbColor = response.getChirpChatModSettings()->getRgbColor(); } if (channelSettingsKeys.contains("title")) { - settings.m_title = *response.getLoRaModSettings()->getTitle(); + settings.m_title = *response.getChirpChatModSettings()->getTitle(); } if (channelSettingsKeys.contains("streamIndex")) { - settings.m_streamIndex = response.getLoRaModSettings()->getStreamIndex(); + settings.m_streamIndex = response.getChirpChatModSettings()->getStreamIndex(); } if (channelSettingsKeys.contains("useReverseAPI")) { - settings.m_useReverseAPI = response.getLoRaModSettings()->getUseReverseApi() != 0; + settings.m_useReverseAPI = response.getChirpChatModSettings()->getUseReverseApi() != 0; } if (channelSettingsKeys.contains("reverseAPIAddress")) { - settings.m_reverseAPIAddress = *response.getLoRaModSettings()->getReverseApiAddress(); + settings.m_reverseAPIAddress = *response.getChirpChatModSettings()->getReverseApiAddress(); } if (channelSettingsKeys.contains("reverseAPIPort")) { - settings.m_reverseAPIPort = response.getLoRaModSettings()->getReverseApiPort(); + settings.m_reverseAPIPort = response.getChirpChatModSettings()->getReverseApiPort(); } if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) { - settings.m_reverseAPIDeviceIndex = response.getLoRaModSettings()->getReverseApiDeviceIndex(); + settings.m_reverseAPIDeviceIndex = response.getChirpChatModSettings()->getReverseApiDeviceIndex(); } if (channelSettingsKeys.contains("reverseAPIChannelIndex")) { - settings.m_reverseAPIChannelIndex = response.getLoRaModSettings()->getReverseApiChannelIndex(); + settings.m_reverseAPIChannelIndex = response.getChirpChatModSettings()->getReverseApiChannelIndex(); } } -int LoRaMod::webapiReportGet( +int ChirpChatMod::webapiReportGet( SWGSDRangel::SWGChannelReport& response, QString& errorMessage) { (void) errorMessage; - response.setLoRaModReport(new SWGSDRangel::SWGLoRaModReport()); - response.getLoRaModReport()->init(); + response.setChirpChatModReport(new SWGSDRangel::SWGChirpChatModReport()); + response.getChirpChatModReport()->init(); webapiFormatChannelReport(response); return 200; } -void LoRaMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const LoRaModSettings& settings) +void ChirpChatMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const ChirpChatModSettings& settings) { - response.getLoRaModSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset); - response.getLoRaModSettings()->setBandwidthIndex(settings.m_bandwidthIndex); - response.getLoRaModSettings()->setSpreadFactor(settings.m_spreadFactor); - response.getLoRaModSettings()->setDeBits(settings.m_deBits); - response.getLoRaModSettings()->setPreambleChirps(settings.m_preambleChirps); - response.getLoRaModSettings()->setQuietMillis(settings.m_quietMillis); - response.getLoRaModSettings()->setSyncWord(settings.m_syncWord); - response.getLoRaModSettings()->setChannelMute(settings.m_channelMute ? 1 : 0); - response.getLoRaModSettings()->setCodingScheme((int) settings.m_codingScheme); - response.getLoRaModSettings()->setNbParityBits(settings.m_nbParityBits); - response.getLoRaModSettings()->setHasCrc(settings.m_hasCRC ? 1 : 0); - response.getLoRaModSettings()->setHasHeader(settings.m_hasHeader ? 1 : 0); + response.getChirpChatModSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset); + response.getChirpChatModSettings()->setBandwidthIndex(settings.m_bandwidthIndex); + response.getChirpChatModSettings()->setSpreadFactor(settings.m_spreadFactor); + response.getChirpChatModSettings()->setDeBits(settings.m_deBits); + response.getChirpChatModSettings()->setPreambleChirps(settings.m_preambleChirps); + response.getChirpChatModSettings()->setQuietMillis(settings.m_quietMillis); + response.getChirpChatModSettings()->setSyncWord(settings.m_syncWord); + response.getChirpChatModSettings()->setChannelMute(settings.m_channelMute ? 1 : 0); + response.getChirpChatModSettings()->setCodingScheme((int) settings.m_codingScheme); + response.getChirpChatModSettings()->setNbParityBits(settings.m_nbParityBits); + response.getChirpChatModSettings()->setHasCrc(settings.m_hasCRC ? 1 : 0); + response.getChirpChatModSettings()->setHasHeader(settings.m_hasHeader ? 1 : 0); - if (response.getLoRaModSettings()->getMyCall()) { - *response.getLoRaModSettings()->getMyCall() = settings.m_myCall; + if (response.getChirpChatModSettings()->getMyCall()) { + *response.getChirpChatModSettings()->getMyCall() = settings.m_myCall; } else { - response.getLoRaModSettings()->setMyCall(new QString(settings.m_myCall)); + response.getChirpChatModSettings()->setMyCall(new QString(settings.m_myCall)); } - if (response.getLoRaModSettings()->getUrCall()) { - *response.getLoRaModSettings()->getUrCall() = settings.m_urCall; + if (response.getChirpChatModSettings()->getUrCall()) { + *response.getChirpChatModSettings()->getUrCall() = settings.m_urCall; } else { - response.getLoRaModSettings()->setUrCall(new QString(settings.m_urCall)); + response.getChirpChatModSettings()->setUrCall(new QString(settings.m_urCall)); } - if (response.getLoRaModSettings()->getMyLoc()) { - *response.getLoRaModSettings()->getMyLoc() = settings.m_myLoc; + if (response.getChirpChatModSettings()->getMyLoc()) { + *response.getChirpChatModSettings()->getMyLoc() = settings.m_myLoc; } else { - response.getLoRaModSettings()->setMyLoc(new QString(settings.m_myLoc)); + response.getChirpChatModSettings()->setMyLoc(new QString(settings.m_myLoc)); } - if (response.getLoRaModSettings()->getMyRpt()) { - *response.getLoRaModSettings()->getMyRpt() = settings.m_myRpt; + if (response.getChirpChatModSettings()->getMyRpt()) { + *response.getChirpChatModSettings()->getMyRpt() = settings.m_myRpt; } else { - response.getLoRaModSettings()->setMyRpt(new QString(settings.m_myRpt)); + response.getChirpChatModSettings()->setMyRpt(new QString(settings.m_myRpt)); } - response.getLoRaModSettings()->setMessageType((int) settings.m_messageType); + response.getChirpChatModSettings()->setMessageType((int) settings.m_messageType); - if (response.getLoRaModSettings()->getBeaconMessage()) { - *response.getLoRaModSettings()->getBeaconMessage() = settings.m_beaconMessage; + if (response.getChirpChatModSettings()->getBeaconMessage()) { + *response.getChirpChatModSettings()->getBeaconMessage() = settings.m_beaconMessage; } else { - response.getLoRaModSettings()->setBeaconMessage(new QString(settings.m_beaconMessage)); + response.getChirpChatModSettings()->setBeaconMessage(new QString(settings.m_beaconMessage)); } - if (response.getLoRaModSettings()->getCqMessage()) { - *response.getLoRaModSettings()->getCqMessage() = settings.m_cqMessage; + if (response.getChirpChatModSettings()->getCqMessage()) { + *response.getChirpChatModSettings()->getCqMessage() = settings.m_cqMessage; } else { - response.getLoRaModSettings()->setCqMessage(new QString(settings.m_cqMessage)); + response.getChirpChatModSettings()->setCqMessage(new QString(settings.m_cqMessage)); } - if (response.getLoRaModSettings()->getReplyMessage()) { - *response.getLoRaModSettings()->getReplyMessage() = settings.m_replyMessage; + if (response.getChirpChatModSettings()->getReplyMessage()) { + *response.getChirpChatModSettings()->getReplyMessage() = settings.m_replyMessage; } else { - response.getLoRaModSettings()->setReplyMessage(new QString(settings.m_replyMessage)); + response.getChirpChatModSettings()->setReplyMessage(new QString(settings.m_replyMessage)); } - if (response.getLoRaModSettings()->getReportMessage()) { - *response.getLoRaModSettings()->getReportMessage() = settings.m_reportMessage; + if (response.getChirpChatModSettings()->getReportMessage()) { + *response.getChirpChatModSettings()->getReportMessage() = settings.m_reportMessage; } else { - response.getLoRaModSettings()->setReportMessage(new QString(settings.m_reportMessage)); + response.getChirpChatModSettings()->setReportMessage(new QString(settings.m_reportMessage)); } - if (response.getLoRaModSettings()->getReplyReportMessage()) { - *response.getLoRaModSettings()->getReplyReportMessage() = settings.m_replyReportMessage; + if (response.getChirpChatModSettings()->getReplyReportMessage()) { + *response.getChirpChatModSettings()->getReplyReportMessage() = settings.m_replyReportMessage; } else { - response.getLoRaModSettings()->setReplyReportMessage(new QString(settings.m_replyReportMessage)); + response.getChirpChatModSettings()->setReplyReportMessage(new QString(settings.m_replyReportMessage)); } - if (response.getLoRaModSettings()->getRrrMessage()) { - *response.getLoRaModSettings()->getRrrMessage() = settings.m_rrrMessage; + if (response.getChirpChatModSettings()->getRrrMessage()) { + *response.getChirpChatModSettings()->getRrrMessage() = settings.m_rrrMessage; } else { - response.getLoRaModSettings()->setRrrMessage(new QString(settings.m_rrrMessage)); + response.getChirpChatModSettings()->setRrrMessage(new QString(settings.m_rrrMessage)); } - if (response.getLoRaModSettings()->getMessage73()) { - *response.getLoRaModSettings()->getMessage73() = settings.m_73Message; + if (response.getChirpChatModSettings()->getMessage73()) { + *response.getChirpChatModSettings()->getMessage73() = settings.m_73Message; } else { - response.getLoRaModSettings()->setMessage73(new QString(settings.m_73Message)); + response.getChirpChatModSettings()->setMessage73(new QString(settings.m_73Message)); } - if (response.getLoRaModSettings()->getQsoTextMessage()) { - *response.getLoRaModSettings()->getQsoTextMessage() = settings.m_qsoTextMessage; + if (response.getChirpChatModSettings()->getQsoTextMessage()) { + *response.getChirpChatModSettings()->getQsoTextMessage() = settings.m_qsoTextMessage; } else { - response.getLoRaModSettings()->setQsoTextMessage(new QString(settings.m_qsoTextMessage)); + response.getChirpChatModSettings()->setQsoTextMessage(new QString(settings.m_qsoTextMessage)); } - if (response.getLoRaModSettings()->getTextMessage()) { - *response.getLoRaModSettings()->getTextMessage() = settings.m_textMessage; + if (response.getChirpChatModSettings()->getTextMessage()) { + *response.getChirpChatModSettings()->getTextMessage() = settings.m_textMessage; } else { - response.getLoRaModSettings()->setTextMessage(new QString(settings.m_textMessage)); + response.getChirpChatModSettings()->setTextMessage(new QString(settings.m_textMessage)); } - response.getLoRaModSettings()->setBytesMessage(new QList); - QList *bytesStr = response.getLoRaModSettings()->getBytesMessage(); + response.getChirpChatModSettings()->setBytesMessage(new QList); + QList *bytesStr = response.getChirpChatModSettings()->getBytesMessage(); for (QByteArray::const_iterator it = settings.m_bytesMessage.begin(); it != settings.m_bytesMessage.end(); ++it) { @@ -656,133 +657,133 @@ void LoRaMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respo bytesStr->push_back(new QString(tr("%1").arg(b, 2, 16, QChar('0')))); } - response.getLoRaModSettings()->setRgbColor(settings.m_rgbColor); + response.getChirpChatModSettings()->setRgbColor(settings.m_rgbColor); - if (response.getLoRaModSettings()->getTitle()) { - *response.getLoRaModSettings()->getTitle() = settings.m_title; + if (response.getChirpChatModSettings()->getTitle()) { + *response.getChirpChatModSettings()->getTitle() = settings.m_title; } else { - response.getLoRaModSettings()->setTitle(new QString(settings.m_title)); + response.getChirpChatModSettings()->setTitle(new QString(settings.m_title)); } - response.getLoRaModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); + response.getChirpChatModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); - if (response.getLoRaModSettings()->getReverseApiAddress()) { - *response.getLoRaModSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; + if (response.getChirpChatModSettings()->getReverseApiAddress()) { + *response.getChirpChatModSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; } else { - response.getLoRaModSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); + response.getChirpChatModSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); } - response.getLoRaModSettings()->setReverseApiPort(settings.m_reverseAPIPort); - response.getLoRaModSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); - response.getLoRaModSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); + response.getChirpChatModSettings()->setReverseApiPort(settings.m_reverseAPIPort); + response.getChirpChatModSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); + response.getChirpChatModSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); } -void LoRaMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) +void ChirpChatMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) { - response.getLoRaModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq())); - response.getLoRaModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate()); - float fourthsMs = ((1<setChannelPowerDb(CalcDb::dbPower(getMagSq())); + response.getChirpChatModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate()); + float fourthsMs = ((1<setPayloadTimeMs(m_currentPayloadTime); - response.getLoRaModReport()->setTotalTimeMs(m_currentPayloadTime + controlMs); - response.getLoRaModReport()->setSymbolTimeMs(4.0 * fourthsMs); + response.getChirpChatModReport()->setPayloadTimeMs(m_currentPayloadTime); + response.getChirpChatModReport()->setTotalTimeMs(m_currentPayloadTime + controlMs); + response.getChirpChatModReport()->setSymbolTimeMs(4.0 * fourthsMs); } -void LoRaMod::webapiReverseSendSettings(QList& channelSettingsKeys, const LoRaModSettings& settings, bool force) +void ChirpChatMod::webapiReverseSendSettings(QList& channelSettingsKeys, const ChirpChatModSettings& settings, bool force) { SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings(); swgChannelSettings->setDirection(1); // single source (Tx) swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet()); swgChannelSettings->setOriginatorDeviceSetIndex(getDeviceSetIndex()); - swgChannelSettings->setChannelType(new QString("LoRaMod")); - swgChannelSettings->setLoRaModSettings(new SWGSDRangel::SWGLoRaModSettings()); - SWGSDRangel::SWGLoRaModSettings *swgLoRaModSettings = swgChannelSettings->getLoRaModSettings(); + swgChannelSettings->setChannelType(new QString("ChirpChatMod")); + swgChannelSettings->setChirpChatModSettings(new SWGSDRangel::SWGChirpChatModSettings()); + SWGSDRangel::SWGChirpChatModSettings *swgChirpChatModSettings = swgChannelSettings->getChirpChatModSettings(); // transfer data that has been modified. When force is on transfer all data except reverse API data if (channelSettingsKeys.contains("inputFrequencyOffset") || force) { - swgLoRaModSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset); + swgChirpChatModSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset); } if (channelSettingsKeys.contains("bandwidthIndex") || force) { - swgLoRaModSettings->setBandwidthIndex(settings.m_bandwidthIndex); + swgChirpChatModSettings->setBandwidthIndex(settings.m_bandwidthIndex); } if (channelSettingsKeys.contains("spreadFactor") || force) { - swgLoRaModSettings->setSpreadFactor(settings.m_spreadFactor); + swgChirpChatModSettings->setSpreadFactor(settings.m_spreadFactor); } if (channelSettingsKeys.contains("deBits") || force) { - swgLoRaModSettings->setDeBits(settings.m_deBits); + swgChirpChatModSettings->setDeBits(settings.m_deBits); } if (channelSettingsKeys.contains("preambleChirps") || force) { - swgLoRaModSettings->setPreambleChirps(settings.m_preambleChirps); + swgChirpChatModSettings->setPreambleChirps(settings.m_preambleChirps); } if (channelSettingsKeys.contains("quietMillis") || force) { - swgLoRaModSettings->setQuietMillis(settings.m_quietMillis); + swgChirpChatModSettings->setQuietMillis(settings.m_quietMillis); } if (channelSettingsKeys.contains("syncWord") || force) { - swgLoRaModSettings->setSyncWord(settings.m_syncWord); + swgChirpChatModSettings->setSyncWord(settings.m_syncWord); } if (channelSettingsKeys.contains("channelMute") || force) { - swgLoRaModSettings->setChannelMute(settings.m_channelMute ? 1 : 0); + swgChirpChatModSettings->setChannelMute(settings.m_channelMute ? 1 : 0); } if (channelSettingsKeys.contains("codingScheme") || force) { - swgLoRaModSettings->setCodingScheme((int) settings.m_codingScheme); + swgChirpChatModSettings->setCodingScheme((int) settings.m_codingScheme); } if (channelSettingsKeys.contains("nbParityBits") || force) { - swgLoRaModSettings->setNbParityBits(settings.m_nbParityBits); + swgChirpChatModSettings->setNbParityBits(settings.m_nbParityBits); } if (channelSettingsKeys.contains("hasCRC") || force) { - swgLoRaModSettings->setHasCrc(settings.m_hasCRC ? 1 : 0); + swgChirpChatModSettings->setHasCrc(settings.m_hasCRC ? 1 : 0); } if (channelSettingsKeys.contains("hasHeader") || force) { - swgLoRaModSettings->setHasHeader(settings.m_hasHeader ? 1 : 0); + swgChirpChatModSettings->setHasHeader(settings.m_hasHeader ? 1 : 0); } if (channelSettingsKeys.contains("myCall") || force) { - swgLoRaModSettings->setMyCall(new QString(settings.m_myCall)); + swgChirpChatModSettings->setMyCall(new QString(settings.m_myCall)); } if (channelSettingsKeys.contains("urCall") || force) { - swgLoRaModSettings->setUrCall(new QString(settings.m_urCall)); + swgChirpChatModSettings->setUrCall(new QString(settings.m_urCall)); } if (channelSettingsKeys.contains("myLoc") || force) { - swgLoRaModSettings->setMyLoc(new QString(settings.m_myLoc)); + swgChirpChatModSettings->setMyLoc(new QString(settings.m_myLoc)); } if (channelSettingsKeys.contains("myRpt") || force) { - swgLoRaModSettings->setMyRpt(new QString(settings.m_myRpt)); + swgChirpChatModSettings->setMyRpt(new QString(settings.m_myRpt)); } if (channelSettingsKeys.contains("messageType") || force) { - swgLoRaModSettings->setMessageType((int) settings.m_messageType); + swgChirpChatModSettings->setMessageType((int) settings.m_messageType); } if (channelSettingsKeys.contains("beaconMessage") || force) { - swgLoRaModSettings->setBeaconMessage(new QString(settings.m_beaconMessage)); + swgChirpChatModSettings->setBeaconMessage(new QString(settings.m_beaconMessage)); } if (channelSettingsKeys.contains("cqMessage") || force) { - swgLoRaModSettings->setCqMessage(new QString(settings.m_cqMessage)); + swgChirpChatModSettings->setCqMessage(new QString(settings.m_cqMessage)); } if (channelSettingsKeys.contains("replyMessage") || force) { - swgLoRaModSettings->setReplyMessage(new QString(settings.m_replyMessage)); + swgChirpChatModSettings->setReplyMessage(new QString(settings.m_replyMessage)); } if (channelSettingsKeys.contains("reportMessage") || force) { - swgLoRaModSettings->setReportMessage(new QString(settings.m_reportMessage)); + swgChirpChatModSettings->setReportMessage(new QString(settings.m_reportMessage)); } if (channelSettingsKeys.contains("replyReportMessage") || force) { - swgLoRaModSettings->setReplyReportMessage(new QString(settings.m_replyReportMessage)); + swgChirpChatModSettings->setReplyReportMessage(new QString(settings.m_replyReportMessage)); } if (channelSettingsKeys.contains("rrrMessage") || force) { - swgLoRaModSettings->setRrrMessage(new QString(settings.m_rrrMessage)); + swgChirpChatModSettings->setRrrMessage(new QString(settings.m_rrrMessage)); } if (channelSettingsKeys.contains("message73") || force) { - swgLoRaModSettings->setMessage73(new QString(settings.m_73Message)); + swgChirpChatModSettings->setMessage73(new QString(settings.m_73Message)); } if (channelSettingsKeys.contains("qsoTextMessage") || force) { - swgLoRaModSettings->setQsoTextMessage(new QString(settings.m_qsoTextMessage)); + swgChirpChatModSettings->setQsoTextMessage(new QString(settings.m_qsoTextMessage)); } if (channelSettingsKeys.contains("textMessage") || force) { - swgLoRaModSettings->setTextMessage(new QString(settings.m_textMessage)); + swgChirpChatModSettings->setTextMessage(new QString(settings.m_textMessage)); } if (channelSettingsKeys.contains("bytesMessage") || force) { - swgLoRaModSettings->setBytesMessage(new QList); - QList *bytesStr = swgLoRaModSettings-> getBytesMessage(); + swgChirpChatModSettings->setBytesMessage(new QList); + QList *bytesStr = swgChirpChatModSettings-> getBytesMessage(); for (QByteArray::const_iterator it = settings.m_bytesMessage.begin(); it != settings.m_bytesMessage.end(); ++it) { @@ -792,14 +793,14 @@ void LoRaMod::webapiReverseSendSettings(QList& channelSettingsKeys, con } if (channelSettingsKeys.contains("messageRepeat") || force) { - swgLoRaModSettings->setMessageRepeat(settings.m_messageRepeat); + swgChirpChatModSettings->setMessageRepeat(settings.m_messageRepeat); } if (channelSettingsKeys.contains("rgbColor") || force) { - swgLoRaModSettings->setRgbColor(settings.m_rgbColor); + swgChirpChatModSettings->setRgbColor(settings.m_rgbColor); } if (channelSettingsKeys.contains("title") || force) { - swgLoRaModSettings->setTitle(new QString(settings.m_title)); + swgChirpChatModSettings->setTitle(new QString(settings.m_title)); } QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") @@ -822,13 +823,13 @@ void LoRaMod::webapiReverseSendSettings(QList& channelSettingsKeys, con delete swgChannelSettings; } -void LoRaMod::networkManagerFinished(QNetworkReply *reply) +void ChirpChatMod::networkManagerFinished(QNetworkReply *reply) { QNetworkReply::NetworkError replyError = reply->error(); if (replyError) { - qWarning() << "LoRaMod::networkManagerFinished:" + qWarning() << "ChirpChatMod::networkManagerFinished:" << " error(" << (int) replyError << "): " << replyError << ": " << reply->errorString(); @@ -837,28 +838,28 @@ void LoRaMod::networkManagerFinished(QNetworkReply *reply) { QString answer = reply->readAll(); answer.chop(1); // remove last \n - qDebug("LoRaMod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str()); + qDebug("ChirpChatMod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str()); } reply->deleteLater(); } -double LoRaMod::getMagSq() const +double ChirpChatMod::getMagSq() const { return m_basebandSource->getMagSq(); } -void LoRaMod::setLevelMeter(QObject *levelMeter) +void ChirpChatMod::setLevelMeter(QObject *levelMeter) { connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), levelMeter, SLOT(levelChanged(qreal, qreal, int))); } -uint32_t LoRaMod::getNumberOfDeviceStreams() const +uint32_t ChirpChatMod::getNumberOfDeviceStreams() const { return m_deviceAPI->getNbSinkStreams(); } -bool LoRaMod::getModulatorActive() const +bool ChirpChatMod::getModulatorActive() const { return m_basebandSource->getActive(); } diff --git a/plugins/channeltx/modlora/loramod.h b/plugins/channeltx/modchirpchat/chirpchatmod.h similarity index 79% rename from plugins/channeltx/modlora/loramod.h rename to plugins/channeltx/modchirpchat/chirpchatmod.h index ff71e376b..207ae118a 100644 --- a/plugins/channeltx/modlora/loramod.h +++ b/plugins/channeltx/modchirpchat/chirpchatmod.h @@ -15,8 +15,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef PLUGINS_CHANNELTX_MODLORA_LORAMOD_H_ -#define PLUGINS_CHANNELTX_MODLORA_LORAMOD_H_ +#ifndef PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMOD_H_ +#define PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMOD_H_ #include #include @@ -29,37 +29,37 @@ #include "channel/channelapi.h" #include "util/message.h" -#include "loramodsettings.h" -#include "loramodencoder.h" +#include "chirpchatmodsettings.h" +#include "chirpchatmodencoder.h" class QNetworkAccessManager; class QNetworkReply; class QThread; class DeviceAPI; class CWKeyer; -class LoRaModBaseband; +class ChirpChatModBaseband; -class LoRaMod : public BasebandSampleSource, public ChannelAPI { +class ChirpChatMod : public BasebandSampleSource, public ChannelAPI { Q_OBJECT public: - class MsgConfigureLoRaMod : public Message { + class MsgConfigureChirpChatMod : public Message { MESSAGE_CLASS_DECLARATION public: - const LoRaModSettings& getSettings() const { return m_settings; } + const ChirpChatModSettings& getSettings() const { return m_settings; } bool getForce() const { return m_force; } - static MsgConfigureLoRaMod* create(const LoRaModSettings& settings, bool force) + static MsgConfigureChirpChatMod* create(const ChirpChatModSettings& settings, bool force) { - return new MsgConfigureLoRaMod(settings, force); + return new MsgConfigureChirpChatMod(settings, force); } private: - LoRaModSettings m_settings; + ChirpChatModSettings m_settings; bool m_force; - MsgConfigureLoRaMod(const LoRaModSettings& settings, bool force) : + MsgConfigureChirpChatMod(const ChirpChatModSettings& settings, bool force) : Message(), m_settings(settings), m_force(force) @@ -86,8 +86,8 @@ public: //================================================================= - LoRaMod(DeviceAPI *deviceAPI); - ~LoRaMod(); + ChirpChatMod(DeviceAPI *deviceAPI); + ~ChirpChatMod(); virtual void destroy() { delete this; } virtual void start(); @@ -128,10 +128,10 @@ public: static void webapiFormatChannelSettings( SWGSDRangel::SWGChannelSettings& response, - const LoRaModSettings& settings); + const ChirpChatModSettings& settings); static void webapiUpdateChannelSettings( - LoRaModSettings& settings, + ChirpChatModSettings& settings, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response); @@ -147,9 +147,9 @@ public: private: DeviceAPI* m_deviceAPI; QThread *m_thread; - LoRaModBaseband* m_basebandSource; - LoRaModEncoder m_encoder; // TODO: check if it needs to be on its own thread - LoRaModSettings m_settings; + ChirpChatModBaseband* m_basebandSource; + ChirpChatModEncoder m_encoder; // TODO: check if it needs to be on its own thread + ChirpChatModSettings m_settings; float m_currentPayloadTime; SampleVector m_sampleBuffer; @@ -160,13 +160,13 @@ private: QNetworkAccessManager *m_networkManager; QNetworkRequest m_networkRequest; - void applySettings(const LoRaModSettings& settings, bool force = false); + void applySettings(const ChirpChatModSettings& settings, bool force = false); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); - void webapiReverseSendSettings(QList& channelSettingsKeys, const LoRaModSettings& settings, bool force); + void webapiReverseSendSettings(QList& channelSettingsKeys, const ChirpChatModSettings& settings, bool force); private slots: void networkManagerFinished(QNetworkReply *reply); }; -#endif /* PLUGINS_CHANNELTX_MODLORA_LORAMOD_H_ */ +#endif /* PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMOD_H_ */ diff --git a/plugins/channeltx/modlora/loramodbaseband.cpp b/plugins/channeltx/modchirpchat/chirpchatmodbaseband.cpp similarity index 74% rename from plugins/channeltx/modlora/loramodbaseband.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodbaseband.cpp index d150dd7af..ebd1cd4d3 100644 --- a/plugins/channeltx/modlora/loramodbaseband.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodbaseband.cpp @@ -21,41 +21,41 @@ #include "dsp/dspengine.h" #include "dsp/dspcommands.h" -#include "loramodbaseband.h" +#include "chirpchatmodbaseband.h" -MESSAGE_CLASS_DEFINITION(LoRaModBaseband::MsgConfigureLoRaModBaseband, Message) -MESSAGE_CLASS_DEFINITION(LoRaModBaseband::MsgConfigureLoRaModPayload, Message) +MESSAGE_CLASS_DEFINITION(ChirpChatModBaseband::MsgConfigureChirpChatModBaseband, Message) +MESSAGE_CLASS_DEFINITION(ChirpChatModBaseband::MsgConfigureChirpChatModPayload, Message) -LoRaModBaseband::LoRaModBaseband() : +ChirpChatModBaseband::ChirpChatModBaseband() : m_mutex(QMutex::Recursive) { m_sampleFifo.resize(SampleSourceFifo::getSizePolicy(48000)); m_channelizer = new UpChannelizer(&m_source); - qDebug("LoRaModBaseband::LoRaModBaseband"); + qDebug("ChirpChatModBaseband::ChirpChatModBaseband"); QObject::connect( &m_sampleFifo, &SampleSourceFifo::dataRead, this, - &LoRaModBaseband::handleData, + &ChirpChatModBaseband::handleData, Qt::QueuedConnection ); connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); } -LoRaModBaseband::~LoRaModBaseband() +ChirpChatModBaseband::~ChirpChatModBaseband() { delete m_channelizer; } -void LoRaModBaseband::reset() +void ChirpChatModBaseband::reset() { QMutexLocker mutexLocker(&m_mutex); m_sampleFifo.reset(); } -void LoRaModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbSamples) +void ChirpChatModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbSamples) { unsigned int part1Begin, part1End, part2Begin, part2End; m_sampleFifo.read(nbSamples, part1Begin, part1End, part2Begin, part2End); @@ -82,7 +82,7 @@ void LoRaModBaseband::pull(const SampleVector::iterator& begin, unsigned int nbS } } -void LoRaModBaseband::handleData() +void ChirpChatModBaseband::handleData() { QMutexLocker mutexLocker(&m_mutex); SampleVector& data = m_sampleFifo.getData(); @@ -114,12 +114,12 @@ void LoRaModBaseband::handleData() emit levelChanged(rmsLevel, peakLevel, numSamples); } -void LoRaModBaseband::processFifo(SampleVector& data, unsigned int iBegin, unsigned int iEnd) +void ChirpChatModBaseband::processFifo(SampleVector& data, unsigned int iBegin, unsigned int iEnd) { m_channelizer->pull(data.begin() + iBegin, iEnd - iBegin); } -void LoRaModBaseband::handleInputMessages() +void ChirpChatModBaseband::handleInputMessages() { Message* message; @@ -131,23 +131,23 @@ void LoRaModBaseband::handleInputMessages() } } -bool LoRaModBaseband::handleMessage(const Message& cmd) +bool ChirpChatModBaseband::handleMessage(const Message& cmd) { - if (MsgConfigureLoRaModBaseband::match(cmd)) + if (MsgConfigureChirpChatModBaseband::match(cmd)) { - qDebug() << "LoRaModBaseband::handleMessage: MsgConfigureLoRaModBaseband"; + qDebug() << "ChirpChatModBaseband::handleMessage: MsgConfigureChirpChatModBaseband"; QMutexLocker mutexLocker(&m_mutex); - MsgConfigureLoRaModBaseband& cfg = (MsgConfigureLoRaModBaseband&) cmd; + MsgConfigureChirpChatModBaseband& cfg = (MsgConfigureChirpChatModBaseband&) cmd; applySettings(cfg.getSettings(), cfg.getForce()); return true; } - else if (MsgConfigureLoRaModPayload::match(cmd)) + else if (MsgConfigureChirpChatModPayload::match(cmd)) { QMutexLocker mutexLocker(&m_mutex); - MsgConfigureLoRaModPayload& cfg = (MsgConfigureLoRaModPayload&) cmd; - qDebug() << "LoRaModBaseband::handleMessage: MsgConfigureLoRaModPayload:" << cfg.getPayload().size(); + MsgConfigureChirpChatModPayload& cfg = (MsgConfigureChirpChatModPayload&) cmd; + qDebug() << "ChirpChatModBaseband::handleMessage: MsgConfigureChirpChatModPayload:" << cfg.getPayload().size(); m_source.setSymbols(cfg.getPayload()); return true; @@ -157,11 +157,11 @@ bool LoRaModBaseband::handleMessage(const Message& cmd) QMutexLocker mutexLocker(&m_mutex); DSPSignalNotification& notif = (DSPSignalNotification&) cmd; m_sampleFifo.resize(SampleSourceFifo::getSizePolicy(notif.getSampleRate())); - qDebug() << "LoRaModBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate(); + qDebug() << "ChirpChatModBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate(); m_channelizer->setBasebandSampleRate(notif.getSampleRate()); m_source.applyChannelSettings( m_channelizer->getChannelSampleRate(), - LoRaModSettings::bandwidths[m_settings.m_bandwidthIndex], + ChirpChatModSettings::bandwidths[m_settings.m_bandwidthIndex], m_channelizer->getChannelFrequencyOffset() ); @@ -173,14 +173,14 @@ bool LoRaModBaseband::handleMessage(const Message& cmd) } } -void LoRaModBaseband::applySettings(const LoRaModSettings& settings, bool force) +void ChirpChatModBaseband::applySettings(const ChirpChatModSettings& settings, bool force) { if ((settings.m_bandwidthIndex != m_settings.m_bandwidthIndex) || (settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) { - int thisBW = LoRaModSettings::bandwidths[settings.m_bandwidthIndex]; + int thisBW = ChirpChatModSettings::bandwidths[settings.m_bandwidthIndex]; m_channelizer->setChannelization( - thisBW * LoRaModSettings::oversampling, + thisBW * ChirpChatModSettings::oversampling, settings.m_inputFrequencyOffset ); m_source.applyChannelSettings( @@ -195,7 +195,7 @@ void LoRaModBaseband::applySettings(const LoRaModSettings& settings, bool force) m_settings = settings; } -int LoRaModBaseband::getChannelSampleRate() const +int ChirpChatModBaseband::getChannelSampleRate() const { return m_channelizer->getChannelSampleRate(); } diff --git a/plugins/channeltx/modlora/loramodbaseband.h b/plugins/channeltx/modchirpchat/chirpchatmodbaseband.h similarity index 69% rename from plugins/channeltx/modlora/loramodbaseband.h rename to plugins/channeltx/modchirpchat/chirpchatmodbaseband.h index dd0568afc..87f55a93d 100644 --- a/plugins/channeltx/modlora/loramodbaseband.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodbaseband.h @@ -15,8 +15,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef INCLUDE_LORAMODBASEBAND_H -#define INCLUDE_LORAMODBASEBAND_H +#ifndef INCLUDE_CHIRPCHATMODBASEBAND_H +#define INCLUDE_CHIRPCHATMODBASEBAND_H #include #include @@ -25,63 +25,63 @@ #include "util/message.h" #include "util/messagequeue.h" -#include "loramodsource.h" +#include "chirpchatmodsource.h" class UpChannelizer; -class LoRaModBaseband : public QObject +class ChirpChatModBaseband : public QObject { Q_OBJECT public: - class MsgConfigureLoRaModBaseband : public Message { + class MsgConfigureChirpChatModBaseband : public Message { MESSAGE_CLASS_DECLARATION public: - const LoRaModSettings& getSettings() const { return m_settings; } + const ChirpChatModSettings& getSettings() const { return m_settings; } bool getForce() const { return m_force; } - static MsgConfigureLoRaModBaseband* create(const LoRaModSettings& settings, bool force) + static MsgConfigureChirpChatModBaseband* create(const ChirpChatModSettings& settings, bool force) { - return new MsgConfigureLoRaModBaseband(settings, force); + return new MsgConfigureChirpChatModBaseband(settings, force); } private: - LoRaModSettings m_settings; + ChirpChatModSettings m_settings; bool m_force; - MsgConfigureLoRaModBaseband(const LoRaModSettings& settings, bool force) : + MsgConfigureChirpChatModBaseband(const ChirpChatModSettings& settings, bool force) : Message(), m_settings(settings), m_force(force) { } }; - class MsgConfigureLoRaModPayload : public Message { + class MsgConfigureChirpChatModPayload : public Message { MESSAGE_CLASS_DECLARATION public: const std::vector& getPayload() const { return m_payload; } - static MsgConfigureLoRaModPayload* create() { - return new MsgConfigureLoRaModPayload(); + static MsgConfigureChirpChatModPayload* create() { + return new MsgConfigureChirpChatModPayload(); } - static MsgConfigureLoRaModPayload* create(const std::vector& payload) { - return new MsgConfigureLoRaModPayload(payload); + static MsgConfigureChirpChatModPayload* create(const std::vector& payload) { + return new MsgConfigureChirpChatModPayload(payload); } private: std::vector m_payload; - MsgConfigureLoRaModPayload() : // This is empty payload notification + MsgConfigureChirpChatModPayload() : // This is empty payload notification Message() {} - MsgConfigureLoRaModPayload(const std::vector& payload) : + MsgConfigureChirpChatModPayload(const std::vector& payload) : Message() { m_payload = payload; } }; - LoRaModBaseband(); - ~LoRaModBaseband(); + ChirpChatModBaseband(); + ~ChirpChatModBaseband(); void reset(); void pull(const SampleVector::iterator& begin, unsigned int nbSamples); MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication @@ -101,14 +101,14 @@ signals: private: SampleSourceFifo m_sampleFifo; UpChannelizer *m_channelizer; - LoRaModSource m_source; + ChirpChatModSource m_source; MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication - LoRaModSettings m_settings; + ChirpChatModSettings m_settings; QMutex m_mutex; void processFifo(SampleVector& data, unsigned int iBegin, unsigned int iEnd); bool handleMessage(const Message& cmd); - void applySettings(const LoRaModSettings& settings, bool force = false); + void applySettings(const ChirpChatModSettings& settings, bool force = false); private slots: void handleInputMessages(); @@ -116,4 +116,4 @@ private slots: }; -#endif // INCLUDE_NFMMODBASEBAND_H +#endif // INCLUDE_CHIRPCHATMODBASEBAND_H diff --git a/plugins/channeltx/modlora/loramodencoder.cpp b/plugins/channeltx/modchirpchat/chirpchatmodencoder.cpp similarity index 65% rename from plugins/channeltx/modlora/loramodencoder.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodencoder.cpp index f80cd6f55..eb2c3ce5d 100644 --- a/plugins/channeltx/modlora/loramodencoder.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodencoder.cpp @@ -15,23 +15,23 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "loramodencoder.h" -#include "loramodencodertty.h" -#include "loramodencoderascii.h" -#include "loramodencoderlora.h" +#include "chirpchatmodencoder.h" +#include "chirpchatmodencodertty.h" +#include "chirpchatmodencoderascii.h" +#include "chirpchatmodencoderlora.h" -LoRaModEncoder::LoRaModEncoder() : - m_codingScheme(LoRaModSettings::CodingTTY), +ChirpChatModEncoder::ChirpChatModEncoder() : + m_codingScheme(ChirpChatModSettings::CodingTTY), m_nbSymbolBits(5), m_nbParityBits(1), m_hasCRC(true), m_hasHeader(true) {} -LoRaModEncoder::~LoRaModEncoder() +ChirpChatModEncoder::~ChirpChatModEncoder() {} -void LoRaModEncoder::setNbSymbolBits(unsigned int spreadFactor, unsigned int deBits) +void ChirpChatModEncoder::setNbSymbolBits(unsigned int spreadFactor, unsigned int deBits) { m_spreadFactor = spreadFactor; @@ -44,21 +44,21 @@ void LoRaModEncoder::setNbSymbolBits(unsigned int spreadFactor, unsigned int deB m_nbSymbolBits = m_spreadFactor - m_deBits; } -void LoRaModEncoder::encodeString(const QString& str, std::vector& symbols) +void ChirpChatModEncoder::encodeString(const QString& str, std::vector& symbols) { switch (m_codingScheme) { - case LoRaModSettings::CodingTTY: + case ChirpChatModSettings::CodingTTY: if (m_nbSymbolBits == 5) { - LoRaModEncoderTTY::encodeString(str, symbols); + ChirpChatModEncoderTTY::encodeString(str, symbols); } break; - case LoRaModSettings::CodingASCII: + case ChirpChatModSettings::CodingASCII: if (m_nbSymbolBits == 7) { - LoRaModEncoderASCII::encodeString(str, symbols); + ChirpChatModEncoderASCII::encodeString(str, symbols); } break; - case LoRaModSettings::CodingLoRa: + case ChirpChatModSettings::CodingLoRa: if (m_nbSymbolBits >= 5) { QByteArray bytes = str.toUtf8(); @@ -70,11 +70,11 @@ void LoRaModEncoder::encodeString(const QString& str, std::vector& symbols) +void ChirpChatModEncoder::encodeBytes(const QByteArray& bytes, std::vector& symbols) { switch (m_codingScheme) { - case LoRaModSettings::CodingLoRa: + case ChirpChatModSettings::CodingLoRa: encodeBytesLoRa(bytes, symbols); break; default: @@ -82,13 +82,13 @@ void LoRaModEncoder::encodeBytes(const QByteArray& bytes, std::vector& symbols) +void ChirpChatModEncoder::encodeBytesLoRa(const QByteArray& bytes, std::vector& symbols) { QByteArray payload(bytes); if (m_hasCRC) { - LoRaModEncoderLoRa::addChecksum(payload); + ChirpChatModEncoderLoRa::addChecksum(payload); } - LoRaModEncoderLoRa::encodeBytes(payload, symbols, m_nbSymbolBits, m_hasHeader, m_hasCRC, m_nbParityBits); + ChirpChatModEncoderLoRa::encodeBytes(payload, symbols, m_nbSymbolBits, m_hasHeader, m_hasCRC, m_nbParityBits); } \ No newline at end of file diff --git a/plugins/channeltx/modlora/loramodencoder.h b/plugins/channeltx/modchirpchat/chirpchatmodencoder.h similarity index 82% rename from plugins/channeltx/modlora/loramodencoder.h rename to plugins/channeltx/modchirpchat/chirpchatmodencoder.h index ef9142701..c7778f56b 100644 --- a/plugins/channeltx/modlora/loramodencoder.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodencoder.h @@ -15,19 +15,19 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef PLUGINS_CHANNELTX_MODLORA_LORAMODENCODER_H_ -#define PLUGINS_CHANNELTX_MODLORA_LORAMODENCODER_H_ +#ifndef PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODER_H_ +#define PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODER_H_ #include -#include "loramodsettings.h" +#include "chirpchatmodsettings.h" -class LoRaModEncoder +class ChirpChatModEncoder { public: - LoRaModEncoder(); - ~LoRaModEncoder(); + ChirpChatModEncoder(); + ~ChirpChatModEncoder(); - void setCodingScheme(LoRaModSettings::CodingScheme codingScheme) { m_codingScheme = codingScheme; } + void setCodingScheme(ChirpChatModSettings::CodingScheme codingScheme) { m_codingScheme = codingScheme; } void setNbSymbolBits(unsigned int spreadFactor, unsigned int deBits); void setLoRaParityBits(unsigned int parityBits) { m_nbParityBits = parityBits; } void setLoRaHasHeader(bool hasHeader) { m_hasHeader = hasHeader; } @@ -40,7 +40,7 @@ private: void encodeBytesLoRa(const QByteArray& bytes, std::vector& symbols); // General attributes - LoRaModSettings::CodingScheme m_codingScheme; + ChirpChatModSettings::CodingScheme m_codingScheme; unsigned int m_spreadFactor; unsigned int m_deBits; unsigned int m_nbSymbolBits; @@ -50,5 +50,5 @@ private: bool m_hasHeader; }; -#endif // PLUGINS_CHANNELTX_MODLORA_LORAMODENCODER_H_ +#endif // PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODER_H_ diff --git a/plugins/channeltx/modlora/loramodencoderascii.cpp b/plugins/channeltx/modchirpchat/chirpchatmodencoderascii.cpp similarity index 91% rename from plugins/channeltx/modlora/loramodencoderascii.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodencoderascii.cpp index ae35e7582..d4258fd49 100644 --- a/plugins/channeltx/modlora/loramodencoderascii.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodencoderascii.cpp @@ -15,9 +15,9 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "loramodencoderascii.h" +#include "chirpchatmodencoderascii.h" -void LoRaModEncoderASCII::encodeString(const QString& str, std::vector& symbols) +void ChirpChatModEncoderASCII::encodeString(const QString& str, std::vector& symbols) { QByteArray asciiStr = str.toUtf8(); QByteArray::const_iterator it = asciiStr.begin(); diff --git a/plugins/channeltx/modlora/loramodencoderascii.h b/plugins/channeltx/modchirpchat/chirpchatmodencoderascii.h similarity index 86% rename from plugins/channeltx/modlora/loramodencoderascii.h rename to plugins/channeltx/modchirpchat/chirpchatmodencoderascii.h index 6783ee172..6c83acdc1 100644 --- a/plugins/channeltx/modlora/loramodencoderascii.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodencoderascii.h @@ -15,16 +15,16 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERASCII_H_ -#define PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERASCII_H_ +#ifndef PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERASCII_H_ +#define PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERASCII_H_ #include #include -class LoRaModEncoderASCII +class ChirpChatModEncoderASCII { public: static void encodeString(const QString& str, std::vector& symbols); }; -#endif // PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERASCII_H_ +#endif // PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERASCII_H_ diff --git a/plugins/channeltx/modlora/loramodencoderlora.cpp b/plugins/channeltx/modchirpchat/chirpchatmodencoderlora.cpp similarity index 97% rename from plugins/channeltx/modlora/loramodencoderlora.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodencoderlora.cpp index f89627c6b..6f44f9fab 100644 --- a/plugins/channeltx/modlora/loramodencoderlora.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodencoderlora.cpp @@ -17,16 +17,16 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "loramodencoderlora.h" +#include "chirpchatmodencoderlora.h" -void LoRaModEncoderLoRa::addChecksum(QByteArray& bytes) +void ChirpChatModEncoderLoRa::addChecksum(QByteArray& bytes) { uint16_t crc = sx1272DataChecksum(reinterpret_cast(bytes.data()), bytes.size()); bytes.append(crc & 0xff); bytes.append((crc >> 8) & 0xff); } -void LoRaModEncoderLoRa::encodeBytes( +void ChirpChatModEncoderLoRa::encodeBytes( const QByteArray& bytes, std::vector& symbols, unsigned int nbSymbolBits, @@ -93,7 +93,7 @@ void LoRaModEncoderLoRa::encodeBytes( } } -void LoRaModEncoderLoRa::encodeFec( +void ChirpChatModEncoderLoRa::encodeFec( std::vector &codewords, unsigned int nbParityBits, unsigned int& cOfs, diff --git a/plugins/channeltx/modlora/loramodencoderlora.h b/plugins/channeltx/modchirpchat/chirpchatmodencoderlora.h similarity index 97% rename from plugins/channeltx/modlora/loramodencoderlora.h rename to plugins/channeltx/modchirpchat/chirpchatmodencoderlora.h index 67e77eeea..6b47a5354 100644 --- a/plugins/channeltx/modlora/loramodencoderlora.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodencoderlora.h @@ -17,13 +17,13 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERLORA_H_ -#define PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERLORA_H_ +#ifndef PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERLORA_H_ +#define PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERLORA_H_ #include #include -class LoRaModEncoderLoRa +class ChirpChatModEncoderLoRa { public: static void addChecksum(QByteArray& bytes); @@ -271,4 +271,4 @@ private: } }; -#endif // PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERLORA_H_ +#endif // PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERLORA_H_ diff --git a/plugins/channeltx/modlora/loramodencodertty.cpp b/plugins/channeltx/modchirpchat/chirpchatmodencodertty.cpp similarity index 96% rename from plugins/channeltx/modlora/loramodencodertty.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodencodertty.cpp index 95df5f1d8..b7f4f4bf1 100644 --- a/plugins/channeltx/modlora/loramodencodertty.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodencodertty.cpp @@ -15,9 +15,9 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "loramodencodertty.h" +#include "chirpchatmodencodertty.h" -const signed char LoRaModEncoderTTY::asciiToTTYLetters[128] = { +const signed char ChirpChatModEncoderTTY::asciiToTTYLetters[128] = { // '\x00' '\x01' '\x02' '\x03' '\x04' '\x05' '\x06' '\x07' 0x00, -1 , -1 , -1 , -1 , -1 , -1 , -1 , // '\x08' '\t' '\n' '\x0b' '\x0c' '\r' '\x0e' '\x0f' @@ -52,7 +52,7 @@ const signed char LoRaModEncoderTTY::asciiToTTYLetters[128] = { 0x1d, 0x15, 0x11, -1 , -1 , -1 , -1 , -1 }; -const signed char LoRaModEncoderTTY::asciiToTTYFigures[128] = { +const signed char ChirpChatModEncoderTTY::asciiToTTYFigures[128] = { // '\x00' '\x01' '\x02' '\x03' '\x04' '\x05' '\x06' '\x07' 0x00, -1 , -1 , -1 , -1 , -1 , -1 , 0x05, // '\x08' '\t' '\n' '\x0b' '\x0c' '\r' '\x0e' '\x0f' @@ -87,7 +87,7 @@ const signed char LoRaModEncoderTTY::asciiToTTYFigures[128] = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; -void LoRaModEncoderTTY::encodeString(const QString& str, std::vector& symbols) +void ChirpChatModEncoderTTY::encodeString(const QString& str, std::vector& symbols) { TTYState ttyState = TTYLetters; QByteArray asciiStr = str.toUtf8(); diff --git a/plugins/channeltx/modlora/loramodencodertty.h b/plugins/channeltx/modchirpchat/chirpchatmodencodertty.h similarity index 88% rename from plugins/channeltx/modlora/loramodencodertty.h rename to plugins/channeltx/modchirpchat/chirpchatmodencodertty.h index 02d32e144..ede968710 100644 --- a/plugins/channeltx/modlora/loramodencodertty.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodencodertty.h @@ -15,13 +15,13 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERTTY_H_ -#define PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERTTY_H_ +#ifndef PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERTTY_H_ +#define PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERTTY_H_ #include #include -class LoRaModEncoderTTY +class ChirpChatModEncoderTTY { public: static void encodeString(const QString& str, std::vector& symbols); @@ -39,4 +39,4 @@ private: static const char ttyFigures = 0x1b; }; -#endif // PLUGINS_CHANNELTX_MODLORA_LORAMODENCODERTTY_H_ \ No newline at end of file +#endif // PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODENCODERTTY_H_ \ No newline at end of file diff --git a/plugins/channeltx/modlora/loramodgui.cpp b/plugins/channeltx/modchirpchat/chirpchatmodgui.cpp similarity index 66% rename from plugins/channeltx/modlora/loramodgui.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodgui.cpp index 596fca7c9..8333dc294 100644 --- a/plugins/channeltx/modlora/loramodgui.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodgui.cpp @@ -32,54 +32,54 @@ #include "gui/devicestreamselectiondialog.h" #include "mainwindow.h" -#include "ui_loramodgui.h" -#include "loramodgui.h" +#include "ui_chirpchatmodgui.h" +#include "chirpchatmodgui.h" -LoRaModGUI* LoRaModGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx) +ChirpChatModGUI* ChirpChatModGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx) { - LoRaModGUI* gui = new LoRaModGUI(pluginAPI, deviceUISet, channelTx); + ChirpChatModGUI* gui = new ChirpChatModGUI(pluginAPI, deviceUISet, channelTx); return gui; } -void LoRaModGUI::destroy() +void ChirpChatModGUI::destroy() { delete this; } -void LoRaModGUI::setName(const QString& name) +void ChirpChatModGUI::setName(const QString& name) { setObjectName(name); } -QString LoRaModGUI::getName() const +QString ChirpChatModGUI::getName() const { return objectName(); } -qint64 LoRaModGUI::getCenterFrequency() const { +qint64 ChirpChatModGUI::getCenterFrequency() const { return m_channelMarker.getCenterFrequency(); } -void LoRaModGUI::setCenterFrequency(qint64 centerFrequency) +void ChirpChatModGUI::setCenterFrequency(qint64 centerFrequency) { m_channelMarker.setCenterFrequency(centerFrequency); applySettings(); } -void LoRaModGUI::resetToDefaults() +void ChirpChatModGUI::resetToDefaults() { m_settings.resetToDefaults(); displaySettings(); applySettings(true); } -QByteArray LoRaModGUI::serialize() const +QByteArray ChirpChatModGUI::serialize() const { return m_settings.serialize(); } -bool LoRaModGUI::deserialize(const QByteArray& data) +bool ChirpChatModGUI::deserialize(const QByteArray& data) { if (m_settings.deserialize(data)) { @@ -94,21 +94,21 @@ bool LoRaModGUI::deserialize(const QByteArray& data) } } -bool LoRaModGUI::handleMessage(const Message& message) +bool ChirpChatModGUI::handleMessage(const Message& message) { - if (LoRaMod::MsgConfigureLoRaMod::match(message)) + if (ChirpChatMod::MsgConfigureChirpChatMod::match(message)) { - const LoRaMod::MsgConfigureLoRaMod& cfg = (LoRaMod::MsgConfigureLoRaMod&) message; + const ChirpChatMod::MsgConfigureChirpChatMod& cfg = (ChirpChatMod::MsgConfigureChirpChatMod&) message; m_settings = cfg.getSettings(); blockApplySettings(true); displaySettings(); blockApplySettings(false); return true; } - else if (LoRaMod::MsgReportPayloadTime::match(message)) + else if (ChirpChatMod::MsgReportPayloadTime::match(message)) { - const LoRaMod::MsgReportPayloadTime& rpt = (LoRaMod::MsgReportPayloadTime&) message; - float fourthsMs = ((1<timePayloadText->setText(tr("%1 ms").arg(QString::number(rpt.getPayloadTimeMs(), 'f', 0))); ui->timeTotalText->setText(tr("%1 ms").arg(QString::number(rpt.getPayloadTimeMs() + controlMs, 'f', 0))); @@ -119,7 +119,7 @@ bool LoRaModGUI::handleMessage(const Message& message) { DSPSignalNotification& notif = (DSPSignalNotification&) message; int basebandSampleRate = notif.getSampleRate(); - qDebug() << "LoRaModGUI::handleMessage: DSPSignalNotification: m_basebandSampleRate: " << basebandSampleRate; + qDebug() << "ChirpChatModGUI::handleMessage: DSPSignalNotification: m_basebandSampleRate: " << basebandSampleRate; if (basebandSampleRate != m_basebandSampleRate) { @@ -135,14 +135,14 @@ bool LoRaModGUI::handleMessage(const Message& message) } } -void LoRaModGUI::channelMarkerChangedByCursor() +void ChirpChatModGUI::channelMarkerChangedByCursor() { ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency(); applySettings(); } -void LoRaModGUI::handleSourceMessages() +void ChirpChatModGUI::handleSourceMessages() { Message* message; @@ -155,37 +155,37 @@ void LoRaModGUI::handleSourceMessages() } } -void LoRaModGUI::on_deltaFrequency_changed(qint64 value) +void ChirpChatModGUI::on_deltaFrequency_changed(qint64 value) { m_channelMarker.setCenterFrequency(value); m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency(); applySettings(); } -void LoRaModGUI::on_bw_valueChanged(int value) +void ChirpChatModGUI::on_bw_valueChanged(int value) { if (value < 0) { m_settings.m_bandwidthIndex = 0; - } else if (value < LoRaModSettings::nbBandwidths) { + } else if (value < ChirpChatModSettings::nbBandwidths) { m_settings.m_bandwidthIndex = value; } else { - m_settings.m_bandwidthIndex = LoRaModSettings::nbBandwidths - 1; + m_settings.m_bandwidthIndex = ChirpChatModSettings::nbBandwidths - 1; } - int thisBW = LoRaModSettings::bandwidths[value]; + int thisBW = ChirpChatModSettings::bandwidths[value]; ui->bwText->setText(QString("%1 Hz").arg(thisBW)); m_channelMarker.setBandwidth(thisBW); applySettings(); } -void LoRaModGUI::on_channelMute_toggled(bool checked) +void ChirpChatModGUI::on_channelMute_toggled(bool checked) { m_settings.m_channelMute = checked; applySettings(); } -void LoRaModGUI::on_spread_valueChanged(int value) +void ChirpChatModGUI::on_spread_valueChanged(int value) { m_settings.m_spreadFactor = value; ui->spreadText->setText(tr("%1").arg(value)); @@ -193,28 +193,28 @@ void LoRaModGUI::on_spread_valueChanged(int value) applySettings(); } -void LoRaModGUI::on_deBits_valueChanged(int value) +void ChirpChatModGUI::on_deBits_valueChanged(int value) { m_settings.m_deBits = value; ui->deBitsText->setText(tr("%1").arg(m_settings.m_deBits)); applySettings(); } -void LoRaModGUI::on_preambleChirps_valueChanged(int value) +void ChirpChatModGUI::on_preambleChirps_valueChanged(int value) { m_settings.m_preambleChirps = value; ui->preambleChirpsText->setText(tr("%1").arg(m_settings.m_preambleChirps)); applySettings(); } -void LoRaModGUI::on_idleTime_valueChanged(int value) +void ChirpChatModGUI::on_idleTime_valueChanged(int value) { m_settings.m_quietMillis = value * 100; ui->idleTimeText->setText(tr("%1").arg(m_settings.m_quietMillis / 1000.0, 0, 'f', 1)); applySettings(); } -void LoRaModGUI::on_syncWord_editingFinished() +void ChirpChatModGUI::on_syncWord_editingFinished() { bool ok; unsigned int syncWord = ui->syncWord->text().toUInt(&ok, 16); @@ -226,66 +226,66 @@ void LoRaModGUI::on_syncWord_editingFinished() } } -void LoRaModGUI::on_scheme_currentIndexChanged(int index) +void ChirpChatModGUI::on_scheme_currentIndexChanged(int index) { - m_settings.m_codingScheme = (LoRaModSettings::CodingScheme) index; - ui->fecParity->setEnabled(m_settings.m_codingScheme == LoRaModSettings::CodingLoRa); - ui->crc->setEnabled(m_settings.m_codingScheme == LoRaModSettings::CodingLoRa); - ui->header->setEnabled(m_settings.m_codingScheme == LoRaModSettings::CodingLoRa); + m_settings.m_codingScheme = (ChirpChatModSettings::CodingScheme) index; + ui->fecParity->setEnabled(m_settings.m_codingScheme == ChirpChatModSettings::CodingLoRa); + ui->crc->setEnabled(m_settings.m_codingScheme == ChirpChatModSettings::CodingLoRa); + ui->header->setEnabled(m_settings.m_codingScheme == ChirpChatModSettings::CodingLoRa); applySettings(); } -void LoRaModGUI::on_fecParity_valueChanged(int value) +void ChirpChatModGUI::on_fecParity_valueChanged(int value) { m_settings.m_nbParityBits = value; ui->fecParityText->setText(tr("%1").arg(m_settings.m_nbParityBits)); applySettings(); } -void LoRaModGUI::on_crc_stateChanged(int state) +void ChirpChatModGUI::on_crc_stateChanged(int state) { m_settings.m_hasCRC = (state == Qt::Checked); applySettings(); } -void LoRaModGUI::on_header_stateChanged(int state) +void ChirpChatModGUI::on_header_stateChanged(int state) { m_settings.m_hasHeader = (state == Qt::Checked); applySettings(); } -void LoRaModGUI::on_myCall_editingFinished() +void ChirpChatModGUI::on_myCall_editingFinished() { m_settings.m_myCall = ui->myCall->text(); applySettings(); } -void LoRaModGUI::on_urCall_editingFinished() +void ChirpChatModGUI::on_urCall_editingFinished() { m_settings.m_urCall = ui->urCall->text(); applySettings(); } -void LoRaModGUI::on_myLocator_editingFinished() +void ChirpChatModGUI::on_myLocator_editingFinished() { m_settings.m_myLoc = ui->myLocator->text(); applySettings(); } -void LoRaModGUI::on_report_editingFinished() +void ChirpChatModGUI::on_report_editingFinished() { m_settings.m_myRpt = ui->report->text(); applySettings(); } -void LoRaModGUI::on_msgType_currentIndexChanged(int index) +void ChirpChatModGUI::on_msgType_currentIndexChanged(int index) { - m_settings.m_messageType = (LoRaModSettings::MessageType) index; + m_settings.m_messageType = (ChirpChatModSettings::MessageType) index; displayCurrentPayloadMessage(); applySettings(); } -void LoRaModGUI::on_resetMessages_clicked(bool checked) +void ChirpChatModGUI::on_resetMessages_clicked(bool checked) { (void) checked; m_settings.setDefaultTemplates(); @@ -293,25 +293,25 @@ void LoRaModGUI::on_resetMessages_clicked(bool checked) applySettings(); } -void LoRaModGUI::on_playMessage_clicked(bool checked) +void ChirpChatModGUI::on_playMessage_clicked(bool checked) { (void) checked; // Switch to message None then back to current message type to trigger sending process - LoRaModSettings::MessageType msgType = m_settings.m_messageType; - m_settings.m_messageType = LoRaModSettings::MessageNone; + ChirpChatModSettings::MessageType msgType = m_settings.m_messageType; + m_settings.m_messageType = ChirpChatModSettings::MessageNone; applySettings(); m_settings.m_messageType = msgType; applySettings(); } -void LoRaModGUI::on_repeatMessage_valueChanged(int value) +void ChirpChatModGUI::on_repeatMessage_valueChanged(int value) { m_settings.m_messageRepeat = value; ui->repeatText->setText(tr("%1").arg(m_settings.m_messageRepeat)); applySettings(); } -void LoRaModGUI::on_generateMessages_clicked(bool checked) +void ChirpChatModGUI::on_generateMessages_clicked(bool checked) { (void) checked; m_settings.generateMessages(); @@ -319,44 +319,44 @@ void LoRaModGUI::on_generateMessages_clicked(bool checked) applySettings(); } -void LoRaModGUI::on_messageText_editingFinished() +void ChirpChatModGUI::on_messageText_editingFinished() { - if (m_settings.m_messageType == LoRaModSettings::MessageBeacon) { + if (m_settings.m_messageType == ChirpChatModSettings::MessageBeacon) { m_settings.m_beaconMessage = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageCQ) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageCQ) { m_settings.m_cqMessage = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageReply) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageReply) { m_settings.m_replyMessage = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageReport) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageReport) { m_settings.m_reportMessage = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageReplyReport) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageReplyReport) { m_settings.m_replyReportMessage = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageRRR) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageRRR) { m_settings.m_rrrMessage = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::Message73) { + } else if (m_settings.m_messageType == ChirpChatModSettings::Message73) { m_settings.m_73Message = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageQSOText) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageQSOText) { m_settings.m_qsoTextMessage = ui->messageText->toPlainText(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageText) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageText) { m_settings.m_textMessage = ui->messageText->toPlainText(); } applySettings(); } -void LoRaModGUI::on_hexText_editingFinished() +void ChirpChatModGUI::on_hexText_editingFinished() { m_settings.m_bytesMessage = QByteArray::fromHex(ui->hexText->text().toLatin1()); applySettings(); } -void LoRaModGUI::onWidgetRolled(QWidget* widget, bool rollDown) +void ChirpChatModGUI::onWidgetRolled(QWidget* widget, bool rollDown) { (void) widget; (void) rollDown; } -void LoRaModGUI::onMenuDialogCalled(const QPoint &p) +void ChirpChatModGUI::onMenuDialogCalled(const QPoint &p) { if (m_contextMenuType == ContextMenuChannelSettings) { @@ -386,7 +386,7 @@ void LoRaModGUI::onMenuDialogCalled(const QPoint &p) else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) { DeviceStreamSelectionDialog dialog(this); - dialog.setNumberOfStreams(m_loRaMod->getNumberOfDeviceStreams()); + dialog.setNumberOfStreams(m_chirpChatMod->getNumberOfDeviceStreams()); dialog.setStreamIndex(m_settings.m_streamIndex); dialog.move(p); dialog.exec(); @@ -401,9 +401,9 @@ void LoRaModGUI::onMenuDialogCalled(const QPoint &p) resetContextMenuType(); } -LoRaModGUI::LoRaModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent) : +ChirpChatModGUI::ChirpChatModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent) : RollupWidget(parent), - ui(new Ui::LoRaModGUI), + ui(new Ui::ChirpChatModGUI), m_pluginAPI(pluginAPI), m_deviceUISet(deviceUISet), m_channelMarker(this), @@ -417,8 +417,8 @@ LoRaModGUI::LoRaModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); - m_loRaMod = (LoRaMod*) channelTx; - m_loRaMod->setMessageQueueToGUI(getInputMessageQueue()); + m_chirpChatMod = (ChirpChatMod*) channelTx; + m_chirpChatMod->setMessageQueueToGUI(getInputMessageQueue()); connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); @@ -430,12 +430,12 @@ LoRaModGUI::LoRaModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS m_channelMarker.setColor(Qt::red); m_channelMarker.setBandwidth(12500); m_channelMarker.setCenterFrequency(0); - m_channelMarker.setTitle("LoRa Modulator"); + m_channelMarker.setTitle("ChirpChat Modulator"); m_channelMarker.setSourceOrSinkStream(false); m_channelMarker.blockSignals(false); m_channelMarker.setVisible(true); // activate signal on the last setting only - m_deviceUISet->registerTxChannelInstance(LoRaMod::m_channelIdURI, this); + m_deviceUISet->registerTxChannelInstance(ChirpChatMod::m_channelIdURI, this); m_deviceUISet->addChannelMarker(&m_channelMarker); m_deviceUISet->addRollupWidget(this); @@ -450,30 +450,30 @@ LoRaModGUI::LoRaModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS applySettings(); } -LoRaModGUI::~LoRaModGUI() +ChirpChatModGUI::~ChirpChatModGUI() { m_deviceUISet->removeTxChannelInstance(this); - delete m_loRaMod; // TODO: check this: when the GUI closes it has to delete the modulator + delete m_chirpChatMod; // TODO: check this: when the GUI closes it has to delete the modulator delete ui; } -void LoRaModGUI::blockApplySettings(bool block) +void ChirpChatModGUI::blockApplySettings(bool block) { m_doApplySettings = !block; } -void LoRaModGUI::applySettings(bool force) +void ChirpChatModGUI::applySettings(bool force) { if (m_doApplySettings) { - LoRaMod::MsgConfigureLoRaMod *msg = LoRaMod::MsgConfigureLoRaMod::create(m_settings, force); - m_loRaMod->getInputMessageQueue()->push(msg); + ChirpChatMod::MsgConfigureChirpChatMod *msg = ChirpChatMod::MsgConfigureChirpChatMod::create(m_settings, force); + m_chirpChatMod->getInputMessageQueue()->push(msg); } } -void LoRaModGUI::displaySettings() +void ChirpChatModGUI::displaySettings() { - int thisBW = LoRaModSettings::bandwidths[m_settings.m_bandwidthIndex]; + int thisBW = ChirpChatModSettings::bandwidths[m_settings.m_bandwidthIndex]; m_channelMarker.blockSignals(true); m_channelMarker.setTitle(m_settings.m_title); @@ -488,9 +488,9 @@ void LoRaModGUI::displaySettings() displayCurrentPayloadMessage(); displayBinaryMessage(); - ui->fecParity->setEnabled(m_settings.m_codingScheme == LoRaModSettings::CodingLoRa); - ui->crc->setEnabled(m_settings.m_codingScheme == LoRaModSettings::CodingLoRa); - ui->header->setEnabled(m_settings.m_codingScheme == LoRaModSettings::CodingLoRa); + ui->fecParity->setEnabled(m_settings.m_codingScheme == ChirpChatModSettings::CodingLoRa); + ui->crc->setEnabled(m_settings.m_codingScheme == ChirpChatModSettings::CodingLoRa); + ui->header->setEnabled(m_settings.m_codingScheme == ChirpChatModSettings::CodingLoRa); blockApplySettings(true); ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); @@ -521,7 +521,7 @@ void LoRaModGUI::displaySettings() blockApplySettings(false); } -void LoRaModGUI::displayStreamIndex() +void ChirpChatModGUI::displayStreamIndex() { if (m_deviceUISet->m_deviceMIMOEngine) { setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); @@ -530,68 +530,68 @@ void LoRaModGUI::displayStreamIndex() } } -void LoRaModGUI::displayCurrentPayloadMessage() +void ChirpChatModGUI::displayCurrentPayloadMessage() { ui->messageText->blockSignals(true); - if (m_settings.m_messageType == LoRaModSettings::MessageNone) { + if (m_settings.m_messageType == ChirpChatModSettings::MessageNone) { ui->messageText->clear(); - } else if (m_settings.m_messageType == LoRaModSettings::MessageBeacon) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageBeacon) { ui->messageText->setText(m_settings.m_beaconMessage); - } else if (m_settings.m_messageType == LoRaModSettings::MessageCQ) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageCQ) { ui->messageText->setText(m_settings.m_cqMessage); - } else if (m_settings.m_messageType == LoRaModSettings::MessageReply) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageReply) { ui->messageText->setText(m_settings.m_replyMessage); - } else if (m_settings.m_messageType == LoRaModSettings::MessageReport) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageReport) { ui->messageText->setText(m_settings.m_reportMessage); - } else if (m_settings.m_messageType == LoRaModSettings::MessageReplyReport) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageReplyReport) { ui->messageText->setText(m_settings.m_replyReportMessage); - } else if (m_settings.m_messageType == LoRaModSettings::MessageRRR) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageRRR) { ui->messageText->setText(m_settings.m_rrrMessage); - } else if (m_settings.m_messageType == LoRaModSettings::Message73) { + } else if (m_settings.m_messageType == ChirpChatModSettings::Message73) { ui->messageText->setText(m_settings.m_73Message); - } else if (m_settings.m_messageType == LoRaModSettings::MessageQSOText) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageQSOText) { ui->messageText->setText(m_settings.m_qsoTextMessage); - } else if (m_settings.m_messageType == LoRaModSettings::MessageText) { + } else if (m_settings.m_messageType == ChirpChatModSettings::MessageText) { ui->messageText->setText(m_settings.m_textMessage); } ui->messageText->blockSignals(false); } -void LoRaModGUI::displayBinaryMessage() +void ChirpChatModGUI::displayBinaryMessage() { ui->hexText->setText(m_settings.m_bytesMessage.toHex()); } -void LoRaModGUI::setBandwidths() +void ChirpChatModGUI::setBandwidths() { - int maxBandwidth = m_basebandSampleRate / LoRaModSettings::oversampling; + int maxBandwidth = m_basebandSampleRate / ChirpChatModSettings::oversampling; int maxIndex = 0; - for (; (maxIndex < LoRaModSettings::nbBandwidths) && (LoRaModSettings::bandwidths[maxIndex] <= maxBandwidth); maxIndex++) + for (; (maxIndex < ChirpChatModSettings::nbBandwidths) && (ChirpChatModSettings::bandwidths[maxIndex] <= maxBandwidth); maxIndex++) {} if (maxIndex != 0) { - qDebug("LoRaModGUI::setBandwidths: avl: %d max: %d", maxBandwidth, LoRaModSettings::bandwidths[maxIndex-1]); + qDebug("ChirpChatModGUI::setBandwidths: avl: %d max: %d", maxBandwidth, ChirpChatModSettings::bandwidths[maxIndex-1]); ui->bw->setMaximum(maxIndex - 1); int index = ui->bw->value(); - ui->bwText->setText(QString("%1 Hz").arg(LoRaModSettings::bandwidths[index])); + ui->bwText->setText(QString("%1 Hz").arg(ChirpChatModSettings::bandwidths[index])); } } -void LoRaModGUI::leaveEvent(QEvent*) +void ChirpChatModGUI::leaveEvent(QEvent*) { m_channelMarker.setHighlighted(false); } -void LoRaModGUI::enterEvent(QEvent*) +void ChirpChatModGUI::enterEvent(QEvent*) { m_channelMarker.setHighlighted(true); } -void LoRaModGUI::tick() +void ChirpChatModGUI::tick() { if (m_tickCount < 10) { @@ -600,11 +600,11 @@ void LoRaModGUI::tick() else { m_tickCount = 0; - double powDb = CalcDb::dbPower(m_loRaMod->getMagSq()); + double powDb = CalcDb::dbPower(m_chirpChatMod->getMagSq()); m_channelPowerDbAvg(powDb); ui->channelPower->setText(tr("%1 dB").arg(m_channelPowerDbAvg.asDouble(), 0, 'f', 1)); - if (m_loRaMod->getModulatorActive()) { + if (m_chirpChatMod->getModulatorActive()) { ui->playMessage->setStyleSheet("QPushButton { background-color : green; }"); } else { ui->playMessage->setStyleSheet("QPushButton { background:rgb(79,79,79); }"); diff --git a/plugins/channeltx/modlora/loramodgui.h b/plugins/channeltx/modchirpchat/chirpchatmodgui.h similarity index 88% rename from plugins/channeltx/modlora/loramodgui.h rename to plugins/channeltx/modchirpchat/chirpchatmodgui.h index dd5a3fc58..f10a77acb 100644 --- a/plugins/channeltx/modlora/loramodgui.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodgui.h @@ -24,22 +24,22 @@ #include "util/movingaverage.h" #include "util/messagequeue.h" -#include "loramod.h" -#include "loramodsettings.h" +#include "chirpchatmod.h" +#include "chirpchatmodsettings.h" class PluginAPI; class DeviceUISet; class BasebandSampleSource; namespace Ui { - class LoRaModGUI; + class ChirpChatModGUI; } -class LoRaModGUI : public RollupWidget, public PluginInstanceGUI { +class ChirpChatModGUI : public RollupWidget, public PluginInstanceGUI { Q_OBJECT public: - static LoRaModGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx); + static ChirpChatModGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx); virtual void destroy(); void setName(const QString& name); @@ -57,22 +57,22 @@ public slots: void channelMarkerChangedByCursor(); private: - Ui::LoRaModGUI* ui; + Ui::ChirpChatModGUI* ui; PluginAPI* m_pluginAPI; DeviceUISet* m_deviceUISet; ChannelMarker m_channelMarker; - LoRaModSettings m_settings; + ChirpChatModSettings m_settings; int m_basebandSampleRate; bool m_doApplySettings; - LoRaMod* m_loRaMod; + ChirpChatMod* m_chirpChatMod; MovingAverageUtil m_channelPowerDbAvg; std::size_t m_tickCount; MessageQueue m_inputMessageQueue; - explicit LoRaModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent = nullptr); - virtual ~LoRaModGUI(); + explicit ChirpChatModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx, QWidget* parent = nullptr); + virtual ~ChirpChatModGUI(); void blockApplySettings(bool block); void applySettings(bool force = false); diff --git a/plugins/channeltx/modlora/loramodgui.ui b/plugins/channeltx/modchirpchat/chirpchatmodgui.ui similarity index 99% rename from plugins/channeltx/modlora/loramodgui.ui rename to plugins/channeltx/modchirpchat/chirpchatmodgui.ui index 1a1963aea..de5124db3 100644 --- a/plugins/channeltx/modlora/loramodgui.ui +++ b/plugins/channeltx/modchirpchat/chirpchatmodgui.ui @@ -1,7 +1,7 @@ - LoRaModGUI - + ChirpChatModGUI + 0 @@ -23,7 +23,7 @@ - LoRa Modulator + ChirpChat Modulator diff --git a/plugins/channeltx/modlora/loramodplugin.cpp b/plugins/channeltx/modchirpchat/chirpchatmodplugin.cpp similarity index 61% rename from plugins/channeltx/modlora/loramodplugin.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodplugin.cpp index 931b7a213..b8f417ead 100644 --- a/plugins/channeltx/modlora/loramodplugin.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodplugin.cpp @@ -19,66 +19,66 @@ #include "plugin/pluginapi.h" #ifndef SERVER_MODE -#include "loramodgui.h" +#include "chirpchatmodgui.h" #endif -#include "loramod.h" -#include "loramodwebapiadapter.h" -#include "loramodplugin.h" +#include "chirpchatmod.h" +#include "chirpchatmodwebapiadapter.h" +#include "chirpchatmodplugin.h" -const PluginDescriptor LoRaModPlugin::m_pluginDescriptor = { - LoRaMod::m_channelId, - QString("LoRa Modulator"), - QString("5.2.0"), +const PluginDescriptor ChirpChatModPlugin::m_pluginDescriptor = { + ChirpChatMod::m_channelId, + QString("ChirpChat Modulator"), + QString("5.3.0"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, QString("https://github.com/f4exb/sdrangel") }; -LoRaModPlugin::LoRaModPlugin(QObject* parent) : +ChirpChatModPlugin::ChirpChatModPlugin(QObject* parent) : QObject(parent), m_pluginAPI(0) { } -const PluginDescriptor& LoRaModPlugin::getPluginDescriptor() const +const PluginDescriptor& ChirpChatModPlugin::getPluginDescriptor() const { return m_pluginDescriptor; } -void LoRaModPlugin::initPlugin(PluginAPI* pluginAPI) +void ChirpChatModPlugin::initPlugin(PluginAPI* pluginAPI) { m_pluginAPI = pluginAPI; // register LoRa modulator - m_pluginAPI->registerTxChannel(LoRaMod::m_channelIdURI, LoRaMod::m_channelId, this); + m_pluginAPI->registerTxChannel(ChirpChatMod::m_channelIdURI, ChirpChatMod::m_channelId, this); } #ifdef SERVER_MODE -PluginInstanceGUI* LoRaModPlugin::createTxChannelGUI( +PluginInstanceGUI* ChirpChatModPlugin::createTxChannelGUI( DeviceUISet *deviceUISet, BasebandSampleSource *txChannel) const { return 0; } #else -PluginInstanceGUI* LoRaModPlugin::createTxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSource *txChannel) const +PluginInstanceGUI* ChirpChatModPlugin::createTxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSource *txChannel) const { - return LoRaModGUI::create(m_pluginAPI, deviceUISet, txChannel); + return ChirpChatModGUI::create(m_pluginAPI, deviceUISet, txChannel); } #endif -BasebandSampleSource* LoRaModPlugin::createTxChannelBS(DeviceAPI *deviceAPI) const +BasebandSampleSource* ChirpChatModPlugin::createTxChannelBS(DeviceAPI *deviceAPI) const { - return new LoRaMod(deviceAPI); + return new ChirpChatMod(deviceAPI); } -ChannelAPI* LoRaModPlugin::createTxChannelCS(DeviceAPI *deviceAPI) const +ChannelAPI* ChirpChatModPlugin::createTxChannelCS(DeviceAPI *deviceAPI) const { - return new LoRaMod(deviceAPI); + return new ChirpChatMod(deviceAPI); } -ChannelWebAPIAdapter* LoRaModPlugin::createChannelWebAPIAdapter() const +ChannelWebAPIAdapter* ChirpChatModPlugin::createChannelWebAPIAdapter() const { - return new LoRaModWebAPIAdapter(); + return new ChirpChatModWebAPIAdapter(); } diff --git a/plugins/channeltx/modlora/loramodplugin.h b/plugins/channeltx/modchirpchat/chirpchatmodplugin.h similarity index 87% rename from plugins/channeltx/modlora/loramodplugin.h rename to plugins/channeltx/modchirpchat/chirpchatmodplugin.h index 444b96d29..c9695649a 100644 --- a/plugins/channeltx/modlora/loramodplugin.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodplugin.h @@ -15,8 +15,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef INCLUDE_LORAMODPLUGIN_H -#define INCLUDE_LORAMODPLUGIN_H +#ifndef INCLUDE_CHIRPCHATMODPLUGIN_H +#define INCLUDE_CHIRPCHATMODPLUGIN_H #include #include "plugin/plugininterface.h" @@ -24,13 +24,13 @@ class DeviceUISet; class BasebandSampleSource; -class LoRaModPlugin : public QObject, PluginInterface { +class ChirpChatModPlugin : public QObject, PluginInterface { Q_OBJECT Q_INTERFACES(PluginInterface) - Q_PLUGIN_METADATA(IID "sdrangel.channeltx.loramod") + Q_PLUGIN_METADATA(IID "sdrangel.channeltx.modchirpchat") public: - explicit LoRaModPlugin(QObject* parent = nullptr); + explicit ChirpChatModPlugin(QObject* parent = nullptr); const PluginDescriptor& getPluginDescriptor() const; void initPlugin(PluginAPI* pluginAPI); @@ -46,4 +46,4 @@ private: PluginAPI* m_pluginAPI; }; -#endif // INCLUDE_LORAMODPLUGIN_H +#endif // INCLUDE_CHIRPCHATMODPLUGIN_H diff --git a/plugins/channeltx/modlora/loramodsettings.cpp b/plugins/channeltx/modchirpchat/chirpchatmodsettings.cpp similarity index 94% rename from plugins/channeltx/modlora/loramodsettings.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodsettings.cpp index c27271a13..5e446955b 100644 --- a/plugins/channeltx/modlora/loramodsettings.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodsettings.cpp @@ -15,16 +15,15 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#include "loramodsettings.h" - #include #include "dsp/dspengine.h" #include "util/simpleserializer.h" #include "settings/serializable.h" -#include "loramodsettings.h" -const int LoRaModSettings::bandwidths[] = { +#include "chirpchatmodsettings.h" + +const int ChirpChatModSettings::bandwidths[] = { 2604, // 333k / 128 3125, // 400k / 128 3906, // 500k / 128 @@ -50,17 +49,17 @@ const int LoRaModSettings::bandwidths[] = { 400000, // 400k / 1 500000 // 500k / 1 }; -const int LoRaModSettings::nbBandwidths = 3*8; -const int LoRaModSettings::oversampling = 4; +const int ChirpChatModSettings::nbBandwidths = 3*8; +const int ChirpChatModSettings::oversampling = 4; -LoRaModSettings::LoRaModSettings() : +ChirpChatModSettings::ChirpChatModSettings() : m_inputFrequencyOffset(0), m_channelMarker(0) { resetToDefaults(); } -void LoRaModSettings::resetToDefaults() +void ChirpChatModSettings::resetToDefaults() { m_bandwidthIndex = 5; m_spreadFactor = 7; @@ -80,7 +79,7 @@ void LoRaModSettings::resetToDefaults() m_channelMute = false; m_messageRepeat = 1; m_rgbColor = QColor(255, 0, 255).rgb(); - m_title = "LoRa Modulator"; + m_title = "ChirpChat Modulator"; m_streamIndex = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; @@ -90,7 +89,7 @@ void LoRaModSettings::resetToDefaults() setDefaultTemplates(); } -void LoRaModSettings::setDefaultTemplates() +void ChirpChatModSettings::setDefaultTemplates() { // %1: myCall %2: urCall %3: myLoc %4: report m_beaconMessage = "VVV DE %1 %2"; // Beacon @@ -103,7 +102,7 @@ void LoRaModSettings::setDefaultTemplates() m_qsoTextMessage = "%1 %2 %3"; // Freeflow message to caller - %3 is m_textMessage } -void LoRaModSettings::generateMessages() +void ChirpChatModSettings::generateMessages() { m_beaconMessage = m_beaconMessage .arg(m_myCall).arg(m_myLoc); @@ -123,7 +122,7 @@ void LoRaModSettings::generateMessages() .arg(m_urCall).arg(m_myCall).arg(m_textMessage); } -QByteArray LoRaModSettings::serialize() const +QByteArray ChirpChatModSettings::serialize() const { SimpleSerializer s(1); s.writeS32(1, m_inputFrequencyOffset); @@ -175,7 +174,7 @@ QByteArray LoRaModSettings::serialize() const return s.final(); } -bool LoRaModSettings::deserialize(const QByteArray& data) +bool ChirpChatModSettings::deserialize(const QByteArray& data) { SimpleDeserializer d(data); diff --git a/plugins/channeltx/modlora/loramodsettings.h b/plugins/channeltx/modchirpchat/chirpchatmodsettings.h similarity index 93% rename from plugins/channeltx/modlora/loramodsettings.h rename to plugins/channeltx/modchirpchat/chirpchatmodsettings.h index 950851168..36fdc4581 100644 --- a/plugins/channeltx/modlora/loramodsettings.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodsettings.h @@ -15,8 +15,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef PLUGINS_CHANNELTX_MODLORA_LORAMODSETTINGS_H_ -#define PLUGINS_CHANNELTX_MODLORA_LORAMODSETTINGS_H_ +#ifndef PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODSETTINGS_H_ +#define PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODSETTINGS_H_ #include #include @@ -25,7 +25,7 @@ class Serializable; -struct LoRaModSettings +struct ChirpChatModSettings { enum CodingScheme { @@ -92,7 +92,7 @@ struct LoRaModSettings static const int nbBandwidths; static const int oversampling; - LoRaModSettings(); + ChirpChatModSettings(); void resetToDefaults(); void setDefaultTemplates(); void generateMessages(); @@ -103,4 +103,4 @@ struct LoRaModSettings -#endif /* PLUGINS_CHANNELTX_MODLORA_LORAMODSETTINGS_H_ */ +#endif /* PLUGINS_CHANNELTX_MODCHIRPCHAT_CHIRPCHATMODSETTINGS_H_ */ diff --git a/plugins/channeltx/modlora/loramodsource.cpp b/plugins/channeltx/modchirpchat/chirpchatmodsource.cpp similarity index 69% rename from plugins/channeltx/modlora/loramodsource.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodsource.cpp index 9c28d33c6..092b67497 100644 --- a/plugins/channeltx/modlora/loramodsource.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodsource.cpp @@ -17,11 +17,11 @@ #include -#include "loramodsource.h" +#include "chirpchatmodsource.h" -const int LoRaModSource::m_levelNbSamples = 480; // every 10ms +const int ChirpChatModSource::m_levelNbSamples = 480; // every 10ms -LoRaModSource::LoRaModSource() : +ChirpChatModSource::ChirpChatModSource() : m_channelSampleRate(48000), m_channelFrequencyOffset(0), m_downChirps(nullptr), @@ -43,14 +43,14 @@ LoRaModSource::LoRaModSource() : applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true); } -LoRaModSource::~LoRaModSource() +ChirpChatModSource::~ChirpChatModSource() { delete[] m_downChirps; delete[] m_upChirps; delete[] m_phaseIncrements; } -void LoRaModSource::initSF(unsigned int sf) +void ChirpChatModSource::initSF(unsigned int sf) { if (m_downChirps) { delete[] m_downChirps; @@ -60,21 +60,21 @@ void LoRaModSource::initSF(unsigned int sf) } m_fftLength = 1 << sf; - m_state = LoRaStateIdle; - m_quarterSamples = (m_fftLength/4)*LoRaModSettings::oversampling; - m_downChirps = new Complex[2*m_fftLength*LoRaModSettings::oversampling]; // Each table is 2 chirps long to allow use from arbitrary offsets. - m_upChirps = new Complex[2*m_fftLength*LoRaModSettings::oversampling]; + m_state = ChirpChatStateIdle; + m_quarterSamples = (m_fftLength/4)*ChirpChatModSettings::oversampling; + m_downChirps = new Complex[2*m_fftLength*ChirpChatModSettings::oversampling]; // Each table is 2 chirps long to allow use from arbitrary offsets. + m_upChirps = new Complex[2*m_fftLength*ChirpChatModSettings::oversampling]; - float halfAngle = M_PI/LoRaModSettings::oversampling; + float halfAngle = M_PI/ChirpChatModSettings::oversampling; float phase = -halfAngle; double accumulator = 0; - for (int i = 0; i < 2*m_fftLength*LoRaModSettings::oversampling; i++) + for (int i = 0; i < 2*m_fftLength*ChirpChatModSettings::oversampling; i++) { accumulator = fmod(accumulator + phase, 2*M_PI); m_downChirps[i] = Complex(std::conj(std::polar(0.891235351562 * SDR_TX_SCALED, accumulator))); // -1 dB m_upChirps[i] = Complex(std::polar(0.891235351562 * SDR_TX_SCALED, accumulator)); - phase += (2*halfAngle) / (m_fftLength*LoRaModSettings::oversampling); + phase += (2*halfAngle) / (m_fftLength*ChirpChatModSettings::oversampling); phase = phase > halfAngle ? phase - 2.0*halfAngle : phase; } @@ -82,23 +82,23 @@ void LoRaModSource::initSF(unsigned int sf) delete[] m_phaseIncrements; } - m_phaseIncrements = new double[2*m_fftLength*LoRaModSettings::oversampling]; + m_phaseIncrements = new double[2*m_fftLength*ChirpChatModSettings::oversampling]; phase = -halfAngle; - for (int i = 0; i < m_fftLength*LoRaModSettings::oversampling; i++) + for (int i = 0; i < m_fftLength*ChirpChatModSettings::oversampling; i++) { m_phaseIncrements[i] = phase; - phase += (2*halfAngle) / (m_fftLength*LoRaModSettings::oversampling); + phase += (2*halfAngle) / (m_fftLength*ChirpChatModSettings::oversampling); } std::copy( m_phaseIncrements, - m_phaseIncrements+m_fftLength*LoRaModSettings::oversampling, - m_phaseIncrements+m_fftLength*LoRaModSettings::oversampling + m_phaseIncrements+m_fftLength*ChirpChatModSettings::oversampling, + m_phaseIncrements+m_fftLength*ChirpChatModSettings::oversampling ); } -void LoRaModSource::initTest(unsigned int sf, unsigned int deBits) +void ChirpChatModSource::initTest(unsigned int sf, unsigned int deBits) { unsigned int fftLength = 1<> ((1-m_chirpCount)*4)) & 0xf)*8; - m_chirp = (m_chirp0 + m_fftLength)*LoRaModSettings::oversampling - 1; + m_chirp = (m_chirp0 + m_fftLength)*ChirpChatModSettings::oversampling - 1; m_fftCounter = 0; - m_state = LoRaStateSyncWord; + m_state = ChirpChatStateSyncWord; } } } - else if (m_state == LoRaStateSyncWord) + else if (m_state == ChirpChatStateSyncWord) { // m_modSample = m_upChirps[m_chirp]; m_modSample = Complex(std::polar(0.891235351562 * SDR_TX_SCALED, m_modPhasor)); m_modPhasor += m_phaseIncrements[m_chirp]; m_fftCounter++; - if (m_fftCounter == m_fftLength*LoRaModSettings::oversampling) + if (m_fftCounter == m_fftLength*ChirpChatModSettings::oversampling) { m_chirpCount++; m_chirp0 = ((m_settings.m_syncWord >> ((1-m_chirpCount)*4)) & 0xf)*8; - m_chirp = (m_chirp0 + m_fftLength)*LoRaModSettings::oversampling - 1; + m_chirp = (m_chirp0 + m_fftLength)*ChirpChatModSettings::oversampling - 1; m_fftCounter = 0; if (m_chirpCount == 2) @@ -259,24 +259,24 @@ void LoRaModSource::modulateSample() m_sampleCounter = 0; m_chirpCount = 0; m_chirp0 = 0; - m_chirp = m_fftLength*LoRaModSettings::oversampling - 1; - m_state = LoRaStateSFD; + m_chirp = m_fftLength*ChirpChatModSettings::oversampling - 1; + m_state = ChirpChatStateSFD; } } } - else if (m_state == LoRaStateSFD) + else if (m_state == ChirpChatStateSFD) { // m_modSample = m_downChirps[m_chirp]; m_modSample = Complex(std::polar(0.891235351562 * SDR_TX_SCALED, m_modPhasor)); - int chirpIndex = m_fftLength*LoRaModSettings::oversampling - 1 - m_chirp; + int chirpIndex = m_fftLength*ChirpChatModSettings::oversampling - 1 - m_chirp; m_modPhasor += m_phaseIncrements[chirpIndex]; m_fftCounter++; m_sampleCounter++; - if (m_fftCounter == m_fftLength*LoRaModSettings::oversampling) + if (m_fftCounter == m_fftLength*ChirpChatModSettings::oversampling) { m_chirp0 = 0; - m_chirp = m_fftLength*LoRaModSettings::oversampling - 1; + m_chirp = m_fftLength*ChirpChatModSettings::oversampling - 1; m_fftCounter = 0; } @@ -291,30 +291,30 @@ void LoRaModSource::modulateSample() m_fftCounter = 0; m_chirpCount = 0; m_chirp0 = encodeSymbol(m_symbols[m_chirpCount]); - m_chirp = (m_chirp0 + m_fftLength)*LoRaModSettings::oversampling - 1; - m_state = LoRaStatePayload; + m_chirp = (m_chirp0 + m_fftLength)*ChirpChatModSettings::oversampling - 1; + m_state = ChirpChatStatePayload; } } - else if (m_state == LoRaStatePayload) + else if (m_state == ChirpChatStatePayload) { // m_modSample = m_upChirps[m_chirp]; m_modSample = Complex(std::polar(0.891235351562 * SDR_TX_SCALED, m_modPhasor)); m_modPhasor += m_phaseIncrements[m_chirp]; m_fftCounter++; - if (m_fftCounter == m_fftLength*LoRaModSettings::oversampling) + if (m_fftCounter == m_fftLength*ChirpChatModSettings::oversampling) { m_chirpCount++; if (m_chirpCount == m_symbols.size()) { reset(); - m_state = LoRaStateIdle; + m_state = ChirpChatStateIdle; } else { m_chirp0 = encodeSymbol(m_symbols[m_chirpCount]); - m_chirp = (m_chirp0 + m_fftLength)*LoRaModSettings::oversampling - 1; + m_chirp = (m_chirp0 + m_fftLength)*ChirpChatModSettings::oversampling - 1; m_fftCounter = 0; } } @@ -327,12 +327,12 @@ void LoRaModSource::modulateSample() m_chirp++; - if (m_chirp >= (m_chirp0 + m_fftLength)*LoRaModSettings::oversampling) { - m_chirp = m_chirp0*LoRaModSettings::oversampling; + if (m_chirp >= (m_chirp0 + m_fftLength)*ChirpChatModSettings::oversampling) { + m_chirp = m_chirp0*ChirpChatModSettings::oversampling; } } -unsigned short LoRaModSource::encodeSymbol(unsigned short symbol) +unsigned short ChirpChatModSource::encodeSymbol(unsigned short symbol) { if (m_settings.m_deBits == 0) { return symbol; @@ -344,11 +344,11 @@ unsigned short LoRaModSource::encodeSymbol(unsigned short symbol) // return deWidth*baseSymbol + (deWidth/2) - 1; } -void LoRaModSource::processOneSample(Complex& ci) +void ChirpChatModSource::processOneSample(Complex& ci) { } -void LoRaModSource::calculateLevel(Real& sample) +void ChirpChatModSource::calculateLevel(Real& sample) { if (m_levelCalcCount < m_levelNbSamples) { @@ -366,7 +366,7 @@ void LoRaModSource::calculateLevel(Real& sample) } } -void LoRaModSource::applySettings(const LoRaModSettings& settings, bool force) +void ChirpChatModSource::applySettings(const ChirpChatModSettings& settings, bool force) { if ((settings.m_spreadFactor != m_settings.m_spreadFactor) || (settings.m_deBits != m_settings.m_deBits) @@ -390,13 +390,13 @@ void LoRaModSource::applySettings(const LoRaModSettings& settings, bool force) m_settings = settings; } -void LoRaModSource::applyChannelSettings(int channelSampleRate, int bandwidth, int channelFrequencyOffset, bool force) +void ChirpChatModSource::applyChannelSettings(int channelSampleRate, int bandwidth, int channelFrequencyOffset, bool force) { - qDebug() << "LoRaModSource::applyChannelSettings:" + qDebug() << "ChirpChatModSource::applyChannelSettings:" << " channelSampleRate: " << channelSampleRate << " channelFrequencyOffset: " << channelFrequencyOffset << " bandwidth: " << bandwidth - << " SR: " << bandwidth * LoRaModSettings::oversampling; + << " SR: " << bandwidth * ChirpChatModSettings::oversampling; if ((channelFrequencyOffset != m_channelFrequencyOffset) || (channelSampleRate != m_channelSampleRate) || force) @@ -409,7 +409,7 @@ void LoRaModSource::applyChannelSettings(int channelSampleRate, int bandwidth, i { m_interpolatorDistanceRemain = 0; m_interpolatorConsumed = false; - m_interpolatorDistance = (Real) (bandwidth*LoRaModSettings::oversampling) / (Real) channelSampleRate; + m_interpolatorDistance = (Real) (bandwidth*ChirpChatModSettings::oversampling) / (Real) channelSampleRate; m_interpolator.create(16, bandwidth, bandwidth / 2.2); } @@ -417,16 +417,16 @@ void LoRaModSource::applyChannelSettings(int channelSampleRate, int bandwidth, i m_channelFrequencyOffset = channelFrequencyOffset; m_bandwidth = bandwidth; m_quietSamples = (bandwidth*m_settings.m_quietMillis) / 1000; - m_state = LoRaStateIdle; + m_state = ChirpChatStateIdle; reset(); } -void LoRaModSource::setSymbols(const std::vector& symbols) +void ChirpChatModSource::setSymbols(const std::vector& symbols) { m_symbols = symbols; - qDebug("LoRaModSource::setSymbols: m_symbols: %lu", m_symbols.size()); + qDebug("ChirpChatModSource::setSymbols: m_symbols: %lu", m_symbols.size()); m_repeatCount = m_settings.m_messageRepeat; - m_state = LoRaStateIdle; // first reset to idle + m_state = ChirpChatStateIdle; // first reset to idle reset(); - m_sampleCounter = m_quietSamples*LoRaModSettings::oversampling - 1; // start immediately + m_sampleCounter = m_quietSamples*ChirpChatModSettings::oversampling - 1; // start immediately } diff --git a/plugins/channeltx/modlora/loramodsource.h b/plugins/channeltx/modchirpchat/chirpchatmodsource.h similarity index 84% rename from plugins/channeltx/modlora/loramodsource.h rename to plugins/channeltx/modchirpchat/chirpchatmodsource.h index 998bf55d6..0ab0f0460 100644 --- a/plugins/channeltx/modlora/loramodsource.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodsource.h @@ -15,8 +15,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef INCLUDE_LORAMODSOURCE_H -#define INCLUDE_LORAMODSOURCE_H +#ifndef INCLUDE_CHIRPCHATMODSOURCE_H +#define INCLUDE_CHIRPCHATMODSOURCE_H #include @@ -26,13 +26,13 @@ #include "dsp/bandpass.h" #include "util/movingaverage.h" -#include "loramodsettings.h" +#include "chirpchatmodsettings.h" -class LoRaModSource : public ChannelSampleSource +class ChirpChatModSource : public ChannelSampleSource { public: - LoRaModSource(); - virtual ~LoRaModSource(); + ChirpChatModSource(); + virtual ~ChirpChatModSource(); virtual void pull(SampleVector::iterator begin, unsigned int nbSamples); virtual void pullOne(Sample& sample); @@ -45,34 +45,27 @@ public: peakLevel = m_peakLevelOut; numSamples = m_levelNbSamples; } - void applySettings(const LoRaModSettings& settings, bool force = false); + void applySettings(const ChirpChatModSettings& settings, bool force = false); void applyChannelSettings(int channelSampleRate, int bandwidth, int channelFrequencyOffset, bool force = false); void setSymbols(const std::vector& symbols); bool getActive() const { return m_active; } private: - enum LoRaMode + enum ChirpChatState { - LoRaStandard, //!< Classic - LoRaTTY //!< Special TTY (SF=7, DE=2) - }; - - enum LoRaState - { - LoRaStateIdle, //!< Quiet time - LoRaStatePreamble, //!< Transmit preamble - LoRaStateSyncWord, //!< Tramsmit sync word - LoRaStateSFD, //!< Transmit SFD - LoRaStatePayload, //!< Tramsmoit payload - LoRaStateTest + ChirpChatStateIdle, //!< Quiet time + ChirpChatStatePreamble, //!< Transmit preamble + ChirpChatStateSyncWord, //!< Tramsmit sync word + ChirpChatStateSFD, //!< Transmit SFD + ChirpChatStatePayload //!< Tramsmoit payload }; int m_channelSampleRate; int m_channelFrequencyOffset; int m_bandwidth; - LoRaModSettings m_settings; + ChirpChatModSettings m_settings; - LoRaState m_state; + ChirpChatState m_state; Complex *m_downChirps; Complex *m_upChirps; double *m_phaseIncrements; @@ -119,4 +112,4 @@ private: unsigned short encodeSymbol(unsigned short symbol); //!< Encodes symbol with possible DE bits spacing }; -#endif // INCLUDE_LORAMODSOURCE_H +#endif // INCLUDE_CHIRPCHATMODSOURCE_H diff --git a/plugins/channeltx/modlora/loramodwebapiadapter.cpp b/plugins/channeltx/modchirpchat/chirpchatmodwebapiadapter.cpp similarity index 72% rename from plugins/channeltx/modlora/loramodwebapiadapter.cpp rename to plugins/channeltx/modchirpchat/chirpchatmodwebapiadapter.cpp index 24bbde259..6674b0e46 100644 --- a/plugins/channeltx/modlora/loramodwebapiadapter.cpp +++ b/plugins/channeltx/modchirpchat/chirpchatmodwebapiadapter.cpp @@ -16,34 +16,34 @@ /////////////////////////////////////////////////////////////////////////////////// #include "SWGChannelSettings.h" -#include "loramod.h" -#include "loramodwebapiadapter.h" +#include "chirpchatmod.h" +#include "chirpchatmodwebapiadapter.h" -LoRaModWebAPIAdapter::LoRaModWebAPIAdapter() +ChirpChatModWebAPIAdapter::ChirpChatModWebAPIAdapter() {} -LoRaModWebAPIAdapter::~LoRaModWebAPIAdapter() +ChirpChatModWebAPIAdapter::~ChirpChatModWebAPIAdapter() {} -int LoRaModWebAPIAdapter::webapiSettingsGet( +int ChirpChatModWebAPIAdapter::webapiSettingsGet( SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) { (void) errorMessage; - response.setLoRaModSettings(new SWGSDRangel::SWGLoRaModSettings()); - response.getLoRaModSettings()->init(); - LoRaMod::webapiFormatChannelSettings(response, m_settings); + response.setChirpChatModSettings(new SWGSDRangel::SWGChirpChatModSettings()); + response.getChirpChatModSettings()->init(); + ChirpChatMod::webapiFormatChannelSettings(response, m_settings); return 200; } -int LoRaModWebAPIAdapter::webapiSettingsPutPatch( +int ChirpChatModWebAPIAdapter::webapiSettingsPutPatch( bool force, const QStringList& channelSettingsKeys, SWGSDRangel::SWGChannelSettings& response, QString& errorMessage) { (void) errorMessage; - LoRaMod::webapiUpdateChannelSettings(m_settings, channelSettingsKeys, response); - LoRaMod::webapiFormatChannelSettings(response, m_settings); + ChirpChatMod::webapiUpdateChannelSettings(m_settings, channelSettingsKeys, response); + ChirpChatMod::webapiFormatChannelSettings(response, m_settings); return 200; } diff --git a/plugins/channeltx/modlora/loramodwebapiadapter.h b/plugins/channeltx/modchirpchat/chirpchatmodwebapiadapter.h similarity index 87% rename from plugins/channeltx/modlora/loramodwebapiadapter.h rename to plugins/channeltx/modchirpchat/chirpchatmodwebapiadapter.h index af5318b3f..af00be7be 100644 --- a/plugins/channeltx/modlora/loramodwebapiadapter.h +++ b/plugins/channeltx/modchirpchat/chirpchatmodwebapiadapter.h @@ -15,19 +15,19 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// -#ifndef INCLUDE_LORAMOD_WEBAPIADAPTER_H -#define INCLUDE_LORAMOD_WEBAPIADAPTER_H +#ifndef INCLUDE_CHIRPCHATMOD_WEBAPIADAPTER_H +#define INCLUDE_CHIRPCHATMOD_WEBAPIADAPTER_H #include "channel/channelwebapiadapter.h" -#include "loramodsettings.h" +#include "chirpchatmodsettings.h" /** * Standalone API adapter only for the settings */ -class LoRaModWebAPIAdapter : public ChannelWebAPIAdapter { +class ChirpChatModWebAPIAdapter : public ChannelWebAPIAdapter { public: - LoRaModWebAPIAdapter(); - virtual ~LoRaModWebAPIAdapter(); + ChirpChatModWebAPIAdapter(); + virtual ~ChirpChatModWebAPIAdapter(); virtual QByteArray serialize() const { return m_settings.serialize(); } virtual bool deserialize(const QByteArray& data) { return m_settings.deserialize(data); } @@ -43,7 +43,7 @@ public: QString& errorMessage); private: - LoRaModSettings m_settings; + ChirpChatModSettings m_settings; }; #endif // INCLUDE_LORAMOD_WEBAPIADAPTER_H diff --git a/plugins/channeltx/modlora/readme.md b/plugins/channeltx/modchirpchat/readme.md similarity index 77% rename from plugins/channeltx/modlora/readme.md rename to plugins/channeltx/modchirpchat/readme.md index aa88a43eb..7e8e504c0 100644 --- a/plugins/channeltx/modlora/readme.md +++ b/plugins/channeltx/modchirpchat/readme.md @@ -2,22 +2,24 @@

Introduction

-This plugin can be used to generate a LoRa signal. +This plugin can be used to code and modulate a transmission signal based on Chirp Spread Spectrum (CSS). The basic idea is to transform each symbol of a MFSK modulation to an ascending frequency ramp shifted in time. It could equally be a descending ramp but this one is reserved to detect a break in the preamble sequence (synchronization). This plugin has been designed to work in conjunction with the ChirpChat demodulator plugin that should be used ideally on the reception side. + +It has clearly been inspired by the LoRa technique but is designed for experimentation and extension to other protocols mostly inspired by amateur radio techniques using chirp modulation to transmit symbols. Thanks to the MFSK to chirp translation it is possible to adapt any MFSK based mode. + +LoRa is a property of Semtech and the details of the protocol are not made public. However a LoRa compatible protocol has been implemented based on the reverse engineering performed by the community. It is mainly based on the work done in https://github.com/myriadrf/LoRa-SDR. You can find more information about LoRa and chirp modulation here: - To get an idea of what is LoRa: [here](https://www.link-labs.com/blog/what-is-lora) - A detailed inspection of LoRa modulation and protocol: [here](https://static1.squarespace.com/static/54cecce7e4b054df1848b5f9/t/57489e6e07eaa0105215dc6c/1464376943218/Reversing-Lora-Knight.pdf) -This plugin has been designed to work in conjunction with the LoRa demodulator plugin. However the transmission can be received with commercial products provided the coding and modulation parameters are compatible. +This LoRa encoder is designed for experimentation. For production grade applications it is recommended to use dedicated hardware instead. -The standard LoRa specification has been extended to support plain ASCII and TTY encoded message using the same chirp based modulation. Distance Enhancement factor values have also been extended to cover the full 0 to 4 range. - -This plugin is designed to experiment with chirp modulation and LoRa technique. It does not replace dedicated hardware for production grade links. +Modulation characteristics from LoRa have been augmented with more bandwidths and FFT bin collations (DE factor). Plain TTY and ASCII have also been added and there are plans to add some more complex typically amateur radio MFSK based modes like JT65. Note: this plugin is available in version 5 only (since 5.2.0).

Interface

-![LoRa Modulator plugin GUI](../../../doc/img/LoRaMod_plugin.png) +![ChitpChat Modulator plugin GUI](../../../doc/img/ChirpChatMod_plugin.png)

1: Frequency shift from center frequency of reception

@@ -33,7 +35,7 @@ Use this button to mute/unmute transmission.

4: Bandwidth

-This is the bandwidth of the LoRa signal. AS per LoRa specs the signal sweeps between the lower and the upper frequency of this bandwidth. The sample rate of the LoRa signal in seconds is exactly one over this bandwidth in Hertz. +This is the bandwidth of the ChirpChat signal. Similarly to LoRa the signal sweeps between the lower and the upper frequency of this bandwidth. The sample rate of the ChirpChat signal in seconds is exactly one over this bandwidth in Hertz. In the LoRa standard there are 2 base bandwidths: 500 and 333.333 kHz. A 400 kHz base has been added. Possible bandwidths are obtained by a division of these base bandwidths by a power of two from 1 to 64. An extra divisor of 128 is provided to achieve smaller bandwidths that can fit in a SSB channel. @@ -64,15 +66,15 @@ Thus available bandwidths are: - **3125** (400000 / 128) Hz not in LoRa standard - **2604** (333333 / 128) Hz not in LoRa standard -The LoRa signal is oversampled by four therefore it needs a baseband of at least four times the bandwidth. This drives the maximum value on the slider automatically. +The ChirpChat signal is oversampled by four therefore it needs a baseband of at least four times the bandwidth. This drives the maximum value on the slider automatically.

5: Spread Factor

-This is the Spread Factor parameter of the LoRa signal. This is the log2 of the possible frequency shifts used over the bandwidth (3). The number of symbols is 2SF-DE where SF is the spread factor and DE the Distance Enhancement factor (8). To +This is the Spread Factor parameter of the ChirpChat signal. This is the log2 of the possible frequency shifts used over the bandwidth (3). The number of symbols is 2SF-DE where SF is the spread factor and DE the Distance Enhancement factor (8). To

6: Distance Enhancement factor

-The LoRa standard specifies 0 (no DE) or 2 (DE active). The present range is extended to all values between 0 and 4 bits. +The LoRa standard specifies 0 (no DE) or 2 (DE active). The ChirpChat range is extended to all values between 0 and 4 bits. This is the log2 of the number of frequency shifts separating two consecutive shifts that represent a symbol. On the receiving side this decreases the probabilty to detect the wrong symbol as an adjacent FFT bin. It can also overcome frequency drift on long messages. @@ -92,15 +94,15 @@ When sending a message repeatedly this is the time between the end of one transm

10: Message and encoding details

-![LoRa Modulator plugin GUI](../../../doc/img/LoRaMod_payload.png) +![ChirpChat Modulator plugin GUI](../../../doc/img/ChirpChatMod_payload.png) -With LoRa it is quite possible to make QSOs in the amateur radio sense. To be efficient the messages have to be kept short and minimal therefore the standard exchange follows WSJT scheme and is reflected in the sequence of messages you can follow with the message selection combo (10.9): CQ, Reply to CQ, Report to callee, Report to caller (R-Report), RRR and 73. +ChirpChat is primarily designed to make QSOs in the amateur radio sense. To be efficient the messages have to be kept short and minimal therefore the standard exchange follows WSJT scheme and is reflected in the sequence of messages you can follow with the message selection combo (10.9): CQ, Reply to CQ, Report to callee, Report to caller (R-Report), RRR and 73. To populate messages you can specify your callsign (10.5), the other party callsign (10.6), your QRA locator (10.7) and a signal report (10.8)

10.1: Modulation scheme

- - **LoRa**: original LoRa + - **LoRa**: LoRa compatible - **ASCII**: 7 bit plain ASCII without FEC and CRC. Requires exactly 7 bit effective samples thus SF-DE = 7 where SF is the spreading factor (5) and DE the distance enhancement factor (6) - **TTY**: 5 bit Baudot (Teletype) without FEC and CRC. Requires exactly 5 bit effective samples thus SF-DE = 5 where SF is the spreading factor (5) and DE the distance enhancement factor (6) diff --git a/plugins/channeltx/modlora/CMakeLists.txt b/plugins/channeltx/modlora/CMakeLists.txt deleted file mode 100644 index 0a9608a37..000000000 --- a/plugins/channeltx/modlora/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -project(modlora) - -set(modlora_SOURCES - loramod.cpp - loramodsettings.cpp - loramodsource.cpp - loramodbaseband.cpp - loramodplugin.cpp - loramodencoder.cpp - loramodencodertty.cpp - loramodencoderascii.cpp - loramodencoderlora.cpp - loramodwebapiadapter.cpp -) - -set(modlora_HEADERS - loramod.h - loramodsettings.h - loramodsource.h - loramodbaseband.h - loramodplugin.h - loramodencoder.h - loramodencodertty.h - loramodencoderascii.h - loramodencoderlora.h - loramodwebapiadapter.h -) - -include_directories( - ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client -) - -if(NOT SERVER_MODE) - set(modlora_SOURCES - ${modlora_SOURCES} - loramodgui.cpp - loramodgui.ui - ) - set(modlora_HEADERS - ${modlora_HEADERS} - loramodgui.h - ) - - set(TARGET_NAME modlora) - set(TARGET_LIB "Qt5::Widgets") - set(TARGET_LIB_GUI "sdrgui") - set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR}) -else() - set(TARGET_NAME modlorasrv) - set(TARGET_LIB "") - set(TARGET_LIB_GUI "") - set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR}) -endif() - -add_library(${TARGET_NAME} SHARED - ${modlora_SOURCES} -) - -target_link_libraries(${TARGET_NAME} - Qt5::Core - ${TARGET_LIB} - sdrbase - ${TARGET_LIB_GUI} - swagger -) - -install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER}) diff --git a/sdrbase/resources/webapi.qrc b/sdrbase/resources/webapi.qrc index 44f85c0c3..1bc9f75cd 100644 --- a/sdrbase/resources/webapi.qrc +++ b/sdrbase/resources/webapi.qrc @@ -16,6 +16,7 @@ webapi/doc/swagger/include/ChannelAnalyzer.yaml webapi/doc/swagger/include/ChannelSettings.yaml webapi/doc/swagger/include/ChirpChatDemod.yaml + webapi/doc/swagger/include/ChirpChatMod.yaml webapi/doc/swagger/include/Command.yaml webapi/doc/swagger/include/CWKeyer.yaml webapi/doc/swagger/include/DATVDemod.yaml @@ -37,7 +38,6 @@ webapi/doc/swagger/include/KiwiSDR.yaml webapi/doc/swagger/include/LocalInput.yaml webapi/doc/swagger/include/LocalOutput.yaml - webapi/doc/swagger/include/LoRaMod.yaml webapi/doc/swagger/include/NFMDemod.yaml webapi/doc/swagger/include/NFMMod.yaml webapi/doc/swagger/include/Perseus.yaml diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index 512727d6f..a3b8cecd6 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -2172,6 +2172,9 @@ margin-bottom: 20px; "ChirpChatDemodReport" : { "$ref" : "#/definitions/ChirpChatDemodReport" }, + "ChirpChatModReport" : { + "$ref" : "#/definitions/ChirpChatModReport" + }, "DSDDemodReport" : { "$ref" : "#/definitions/DSDDemodReport" }, @@ -2187,9 +2190,6 @@ margin-bottom: 20px; "FreqTrackerReport" : { "$ref" : "#/definitions/FreqTrackerReport" }, - "LoRaModReport" : { - "$ref" : "#/definitions/LoRaModReport" - }, "NFMDemodReport" : { "$ref" : "#/definitions/NFMDemodReport" }, @@ -2264,6 +2264,9 @@ margin-bottom: 20px; "ChirpChatDemodSettings" : { "$ref" : "#/definitions/ChirpChatDemodSettings" }, + "ChirpChatModSettings" : { + "$ref" : "#/definitions/ChirpChatModSettings" + }, "DATVDemodSettings" : { "$ref" : "#/definitions/DATVDemodSettings" }, @@ -2285,9 +2288,6 @@ margin-bottom: 20px; "InterferometerSettings" : { "$ref" : "#/definitions/InterferometerSettings" }, - "LoRaModSettings" : { - "$ref" : "#/definitions/LoRaModSettings" - }, "NFMDemodSettings" : { "$ref" : "#/definitions/NFMDemodSettings" }, @@ -2524,6 +2524,179 @@ margin-bottom: 20px; } }, "description" : "ChirpChatDemod" +}; + defs.ChirpChatModReport = { + "properties" : { + "channelPowerDB" : { + "type" : "number", + "format" : "float", + "description" : "power transmitted in channel (dB)" + }, + "channelSampleRate" : { + "type" : "integer" + }, + "symbolTimeMs" : { + "type" : "number", + "format" : "float", + "description" : "symbol duration (ms)" + }, + "payloadTimeMs" : { + "type" : "number", + "format" : "float", + "description" : "payload duration (ms)" + }, + "totalTimeMs" : { + "type" : "number", + "format" : "float", + "description" : "total message duration inc. preamble and SFD (ms)" + } + }, + "description" : "ChirpChatMod" +}; + defs.ChirpChatModSettings = { + "properties" : { + "inputFrequencyOffset" : { + "type" : "integer", + "format" : "int64" + }, + "bandwidthIndex" : { + "type" : "integer", + "description" : "standard bandwidths index:\n * 0 - 2604 Hz (333333 / 128)\n * 1 - 3125 Hz (400000 / 128)\n * 2 - 3906 Hz (500000 / 128)\n * 3 - 5208 Hz (333333 / 64)\n * 4 - 6250 Hz (400000 / 64)\n * 5 - 7813 Hz (500000 / 64)\n * 6 - 10417 Hz (333333 / 32)\n * 7 - 12500 Hz (400000 / 32)\n * 8 - 15625 Hz (500000 / 32)\n * 9 - 20833 Hz (333333 / 16)\n * 10 - 25000 Hz (400000 / 16)\n * 11 - 31250 Hz (500000 / 16)\n * 12 - 41667 Hz (333333 / 8)\n * 13 - 50000 Hz (400000 / 8)\n * 14 - 62500 Hz (500000 / 8)\n * 15 - 83333 Hz (333333 / 4)\n * 16 - 100000 Hz (400000 / 4)\n * 17 - 125000 Hz (500000 / 4)\n * 18 - 166667 Hz (333333 / 2)\n * 19 - 200000 Hz (400000 / 2)\n * 20 - 250000 Hz (500000 / 2)\n * 21 - 333333 Hz (333333 / 1)\n * 22 - 400000 Hz (400000 / 1)\n * 23 - 500000 Hz (500000 / 1)\n" + }, + "spreadFactor" : { + "type" : "integer" + }, + "deBits" : { + "type" : "integer", + "description" : "Low data rate optmize (DE) bits i.e. nb of FFT bins per effective symbol" + }, + "preambleChirps" : { + "type" : "integer", + "description" : "Number of preamble chirps" + }, + "quietMillis" : { + "type" : "integer", + "description" : "Number of milliseconds to pause between transmissions" + }, + "syncWord" : { + "type" : "integer", + "description" : "2 byte (0..65535) synchronization syncWord" + }, + "channelMute" : { + "type" : "integer", + "description" : "boolean" + }, + "codingScheme" : { + "type" : "integer", + "description" : "message encoding scheme (LoRaModSettings::CodingScheme):\n * 0 - LoRa\n * 1 - Plain ASCII (7 bit)\n * 2 - Teletype (5 bit Baudot) a.k.a TTY\n" + }, + "nbParityBits" : { + "type" : "integer", + "description" : "Hamming FEC parity bits (LoRa)" + }, + "hasCRC" : { + "type" : "integer", + "description" : "Payload has CRC (LoRa)" + }, + "hasHeader" : { + "type" : "integer", + "description" : "Header present before actual payload (LoRa)" + }, + "myCall" : { + "type" : "string", + "description" : "own callsign placeholder (QSO mode)" + }, + "urCall" : { + "type" : "string", + "description" : "other party callsign placeholder (QSO mode)" + }, + "myLoc" : { + "type" : "string", + "description" : "own QRA locator (QSO mode)" + }, + "myRpt" : { + "type" : "string", + "description" : "report sent to other party (QSO mode)" + }, + "messageType" : { + "type" : "integer", + "description" : "type of message to send (LoRaModSettings::MessageType):\n * 0 - No message i.e no output. Use this as a transition to resend the same message.\n * 1 - Beacon. Sends message specified in beaconMessage\n * 2 - CQ call. Sends message specified in cqMessage\n * 3 - Reply to CQ call. Sends message specified in replyMessage\n * 4 - Report to callee. Sends message specified in reportMessage\n * 5 - Report to caller. Sends message specified in replyReportMessage\n * 6 - RRR to callee. Sends message specified in rrrMessage\n * 7 - 73 to caller. Sends message specified in message73\n * 8 - Random message with callsigns. Sends message specified in qsoTextMessage\n * 9 - Plain text. Sends message specified in textMessage\n * 10 - Binary payload. Sends bytes specified in bytesMessage\n" + }, + "beaconMessage" : { + "type" : "string", + "description" : "text message to be sent (repeatedly) as a beaconMessage" + }, + "cqMessage" : { + "type" : "string", + "description" : "general call message (QSO mode)" + }, + "replyMessage" : { + "type" : "string", + "description" : "reply to caller message (QSO mode)" + }, + "reportMessage" : { + "type" : "string", + "description" : "report to callee message (QSO mode)" + }, + "replyReportMessage" : { + "type" : "string", + "description" : "report back to caller message (QSO mode)" + }, + "rrrMessage" : { + "type" : "string", + "description" : "caller RRR message (QSO mode)" + }, + "message73" : { + "type" : "string", + "description" : "73 message back to caller to close QSO (QSO mode)" + }, + "qsoTextMessage" : { + "type" : "string", + "description" : "QSO random message exchange (QSO mode)" + }, + "textMessage" : { + "type" : "string", + "description" : "freeform text message" + }, + "bytesMessage" : { + "type" : "array", + "description" : "message to send as an array of hex string represented bytes (00..FF)", + "items" : { + "type" : "string" + } + }, + "messageRepeat" : { + "type" : "integer", + "description" : "number of repetitions of the same message (0 for infinite)" + }, + "rgbColor" : { + "type" : "integer" + }, + "title" : { + "type" : "string" + }, + "streamIndex" : { + "type" : "integer", + "description" : "MIMO channel. Not relevant when connected to SI (single Rx)." + }, + "useReverseAPI" : { + "type" : "integer", + "description" : "Synchronize with reverse API (1 for yes, 0 for no)" + }, + "reverseAPIAddress" : { + "type" : "string" + }, + "reverseAPIPort" : { + "type" : "integer" + }, + "reverseAPIDeviceIndex" : { + "type" : "integer" + }, + "reverseAPIChannelIndex" : { + "type" : "integer" + } + }, + "description" : "ChirpChatMod" }; defs.Command = { "properties" : { @@ -4566,179 +4739,6 @@ margin-bottom: 20px; } }, "description" : "LimeSDR" -}; - defs.LoRaModReport = { - "properties" : { - "channelPowerDB" : { - "type" : "number", - "format" : "float", - "description" : "power transmitted in channel (dB)" - }, - "channelSampleRate" : { - "type" : "integer" - }, - "symbolTimeMs" : { - "type" : "number", - "format" : "float", - "description" : "symbol duration (ms)" - }, - "payloadTimeMs" : { - "type" : "number", - "format" : "float", - "description" : "payload duration (ms)" - }, - "totalTimeMs" : { - "type" : "number", - "format" : "float", - "description" : "total message duration inc. preamble and SFD (ms)" - } - }, - "description" : "LoRaMod" -}; - defs.LoRaModSettings = { - "properties" : { - "inputFrequencyOffset" : { - "type" : "integer", - "format" : "int64" - }, - "bandwidthIndex" : { - "type" : "integer", - "description" : "standard bandwidths index:\n * 0 - 2604 Hz (333333 / 128)\n * 1 - 3125 Hz (400000 / 128)\n * 2 - 3906 Hz (500000 / 128)\n * 3 - 5208 Hz (333333 / 64)\n * 4 - 6250 Hz (400000 / 64)\n * 5 - 7813 Hz (500000 / 64)\n * 6 - 10417 Hz (333333 / 32)\n * 7 - 12500 Hz (400000 / 32)\n * 8 - 15625 Hz (500000 / 32)\n * 9 - 20833 Hz (333333 / 16)\n * 10 - 25000 Hz (400000 / 16)\n * 11 - 31250 Hz (500000 / 16)\n * 12 - 41667 Hz (333333 / 8)\n * 13 - 50000 Hz (400000 / 8)\n * 14 - 62500 Hz (500000 / 8)\n * 15 - 83333 Hz (333333 / 4)\n * 16 - 100000 Hz (400000 / 4)\n * 17 - 125000 Hz (500000 / 4)\n * 18 - 166667 Hz (333333 / 2)\n * 19 - 200000 Hz (400000 / 2)\n * 20 - 250000 Hz (500000 / 2)\n * 21 - 333333 Hz (333333 / 1)\n * 22 - 400000 Hz (400000 / 1)\n * 23 - 500000 Hz (500000 / 1)\n" - }, - "spreadFactor" : { - "type" : "integer" - }, - "deBits" : { - "type" : "integer", - "description" : "Low data rate optmize (DE) bits i.e. nb of FFT bins per effective symbol" - }, - "preambleChirps" : { - "type" : "integer", - "description" : "Number of preamble chirps" - }, - "quietMillis" : { - "type" : "integer", - "description" : "Number of milliseconds to pause between transmissions" - }, - "syncWord" : { - "type" : "integer", - "description" : "2 byte (0..65535) synchronization syncWord" - }, - "channelMute" : { - "type" : "integer", - "description" : "boolean" - }, - "codingScheme" : { - "type" : "integer", - "description" : "message encoding scheme (LoRaModSettings::CodingScheme):\n * 0 - LoRa\n * 1 - Plain ASCII (7 bit)\n * 2 - Teletype (5 bit Baudot) a.k.a TTY\n" - }, - "nbParityBits" : { - "type" : "integer", - "description" : "Hamming FEC parity bits (LoRa)" - }, - "hasCRC" : { - "type" : "integer", - "description" : "Payload has CRC (LoRa)" - }, - "hasHeader" : { - "type" : "integer", - "description" : "Header present before actual payload (LoRa)" - }, - "myCall" : { - "type" : "string", - "description" : "own callsign placeholder (QSO mode)" - }, - "urCall" : { - "type" : "string", - "description" : "other party callsign placeholder (QSO mode)" - }, - "myLoc" : { - "type" : "string", - "description" : "own QRA locator (QSO mode)" - }, - "myRpt" : { - "type" : "string", - "description" : "report sent to other party (QSO mode)" - }, - "messageType" : { - "type" : "integer", - "description" : "type of message to send (LoRaModSettings::MessageType):\n * 0 - No message i.e no output. Use this as a transition to resend the same message.\n * 1 - Beacon. Sends message specified in beaconMessage\n * 2 - CQ call. Sends message specified in cqMessage\n * 3 - Reply to CQ call. Sends message specified in replyMessage\n * 4 - Report to callee. Sends message specified in reportMessage\n * 5 - Report to caller. Sends message specified in replyReportMessage\n * 6 - RRR to callee. Sends message specified in rrrMessage\n * 7 - 73 to caller. Sends message specified in message73\n * 8 - Random message with callsigns. Sends message specified in qsoTextMessage\n * 9 - Plain text. Sends message specified in textMessage\n * 10 - Binary payload. Sends bytes specified in bytesMessage\n" - }, - "beaconMessage" : { - "type" : "string", - "description" : "text message to be sent (repeatedly) as a beaconMessage" - }, - "cqMessage" : { - "type" : "string", - "description" : "general call message (QSO mode)" - }, - "replyMessage" : { - "type" : "string", - "description" : "reply to caller message (QSO mode)" - }, - "reportMessage" : { - "type" : "string", - "description" : "report to callee message (QSO mode)" - }, - "replyReportMessage" : { - "type" : "string", - "description" : "report back to caller message (QSO mode)" - }, - "rrrMessage" : { - "type" : "string", - "description" : "caller RRR message (QSO mode)" - }, - "message73" : { - "type" : "string", - "description" : "73 message back to caller to close QSO (QSO mode)" - }, - "qsoTextMessage" : { - "type" : "string", - "description" : "QSO random message exchange (QSO mode)" - }, - "textMessage" : { - "type" : "string", - "description" : "freeform text message" - }, - "bytesMessage" : { - "type" : "array", - "description" : "message to send as an array of hex string represented bytes (00..FF)", - "items" : { - "type" : "string" - } - }, - "messageRepeat" : { - "type" : "integer", - "description" : "number of repetitions of the same message (0 for infinite)" - }, - "rgbColor" : { - "type" : "integer" - }, - "title" : { - "type" : "string" - }, - "streamIndex" : { - "type" : "integer", - "description" : "MIMO channel. Not relevant when connected to SI (single Rx)." - }, - "useReverseAPI" : { - "type" : "integer", - "description" : "Synchronize with reverse API (1 for yes, 0 for no)" - }, - "reverseAPIAddress" : { - "type" : "string" - }, - "reverseAPIPort" : { - "type" : "integer" - }, - "reverseAPIDeviceIndex" : { - "type" : "integer" - }, - "reverseAPIChannelIndex" : { - "type" : "integer" - } - }, - "description" : "LoRaMod" }; defs.LocalInputReport = { "properties" : { @@ -32618,7 +32618,7 @@ except ApiException as e:
- Generated 2020-03-03T20:19:50.511+01:00 + Generated 2020-03-03T23:14:21.625+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/ChannelSettings.yaml b/sdrbase/resources/webapi/doc/swagger/include/ChannelSettings.yaml index f0a622e78..051564fba 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/ChannelSettings.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/ChannelSettings.yaml @@ -33,6 +33,8 @@ ChannelSettings: $ref: "/doc/swagger/include/ChannelAnalyzer.yaml#/ChannelAnalyzerSettings" ChirpChatDemodSettings: $ref: "/doc/swagger/include/ChirpChatDemod.yaml#/ChirpChatDemodSettings" + ChirpChatModSettings: + $ref: "/doc/swagger/include/ChirpChatMod.yaml#/ChirpChatModSettings" DATVDemodSettings: $ref: "/doc/swagger/include/DATVDemod.yaml#/DATVDemodSettings" DSDDemodSettings: @@ -47,8 +49,6 @@ ChannelSettings: $ref: "/doc/swagger/include/FreqTracker.yaml#/FreqTrackerSettings" InterferometerSettings: $ref: "/doc/swagger/include/Interferometer.yaml#/InterferometerSettings" - LoRaModSettings: - $ref: "/doc/swagger/include/LoRaMod.yaml#/LoRaModSettings" NFMDemodSettings: $ref: "/doc/swagger/include/NFMDemod.yaml#/NFMDemodSettings" NFMModSettings: diff --git a/sdrbase/resources/webapi/doc/swagger/include/ChirpChatDemod.yaml b/sdrbase/resources/webapi/doc/swagger/include/ChirpChatDemod.yaml index 7194cf866..4593e093b 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/ChirpChatDemod.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/ChirpChatDemod.yaml @@ -40,7 +40,7 @@ ChirpChatDemodSettings: codingScheme: type: integer description: > - message encoding scheme (LoRaModSettings::CodingScheme): + message encoding scheme (ChirpChatModSettings::CodingScheme): * 0 - LoRa * 1 - Plain ASCII (7 bit) * 2 - Teletype (5 bit Baudot) a.k.a TTY diff --git a/swagger/sdrangel/api/swagger/include/LoRaMod.yaml b/sdrbase/resources/webapi/doc/swagger/include/ChirpChatMod.yaml similarity index 95% rename from swagger/sdrangel/api/swagger/include/LoRaMod.yaml rename to sdrbase/resources/webapi/doc/swagger/include/ChirpChatMod.yaml index 47375613a..0316cbe99 100644 --- a/swagger/sdrangel/api/swagger/include/LoRaMod.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/ChirpChatMod.yaml @@ -1,5 +1,5 @@ -LoRaModSettings: - description: LoRaMod +ChirpChatModSettings: + description: ChirpChatMod properties: inputFrequencyOffset: type: integer @@ -52,7 +52,7 @@ LoRaModSettings: codingScheme: type: integer description: > - message encoding scheme (LoRaModSettings::CodingScheme): + message encoding scheme (ChirpChatModSettings::CodingScheme): * 0 - LoRa * 1 - Plain ASCII (7 bit) * 2 - Teletype (5 bit Baudot) a.k.a TTY @@ -80,7 +80,7 @@ LoRaModSettings: messageType: type: integer description: > - type of message to send (LoRaModSettings::MessageType): + type of message to send (ChirpChatModSettings::MessageType): * 0 - No message i.e no output. Use this as a transition to resend the same message. * 1 - Beacon. Sends message specified in beaconMessage * 2 - CQ call. Sends message specified in cqMessage @@ -146,8 +146,8 @@ LoRaModSettings: reverseAPIChannelIndex: type: integer -LoRaModReport: - description: LoRaMod +ChirpChatModReport: + description: ChirpChatMod properties: channelPowerDB: description: power transmitted in channel (dB) diff --git a/sdrbase/resources/webapi/doc/swagger/include/LoRaDemod.yaml b/sdrbase/resources/webapi/doc/swagger/include/LoRaDemod.yaml deleted file mode 100644 index 7f91f480c..000000000 --- a/sdrbase/resources/webapi/doc/swagger/include/LoRaDemod.yaml +++ /dev/null @@ -1,173 +0,0 @@ -LoRaDemodSettings: - description: LoRaDemod - properties: - inputFrequencyOffset: - type: integer - format: int64 - bandwidthIndex: - type: integer - description: > - standard bandwidths index: - * 0 - 2604 Hz (333333 / 128) - * 1 - 3125 Hz (400000 / 128) - * 2 - 3906 Hz (500000 / 128) - * 3 - 5208 Hz (333333 / 64) - * 4 - 6250 Hz (400000 / 64) - * 5 - 7813 Hz (500000 / 64) - * 6 - 10417 Hz (333333 / 32) - * 7 - 12500 Hz (400000 / 32) - * 8 - 15625 Hz (500000 / 32) - * 9 - 20833 Hz (333333 / 16) - * 10 - 25000 Hz (400000 / 16) - * 11 - 31250 Hz (500000 / 16) - * 12 - 41667 Hz (333333 / 8) - * 13 - 50000 Hz (400000 / 8) - * 14 - 62500 Hz (500000 / 8) - * 15 - 83333 Hz (333333 / 4) - * 16 - 100000 Hz (400000 / 4) - * 17 - 125000 Hz (500000 / 4) - * 18 - 166667 Hz (333333 / 2) - * 19 - 200000 Hz (400000 / 2) - * 20 - 250000 Hz (500000 / 2) - * 21 - 333333 Hz (333333 / 1) - * 22 - 400000 Hz (400000 / 1) - * 23 - 500000 Hz (500000 / 1) - spreadFactor: - type: integer - deBits: - description: Low data rate optmize (DE) bits i.e. nb of FFT bins per effective symbol - type: integer - codingScheme: - type: integer - description: > - message encoding scheme (LoRaModSettings::CodingScheme): - * 0 - LoRa - * 1 - Plain ASCII (7 bit) - * 2 - Teletype (5 bit Baudot) a.k.a TTY - decodeActive: - description: boolean 1 to activate 0 to de-activate decoder - type: integer - eomSquelchTenths: - description: argmax squared magnitude is compared between current multiplied by this factor and maximum during decoding. This value is divided by 10 - type: integer - nbSymbolsMax: - description: expected maximum number of symbols in a payload - type: integer - autoNbSymbolsMax: - description: adjust maximum number of symbols in a payload to the value just received (LoRa) - type: integer - preambleChirps: - description: Number of expected preamble chirps - type: integer - nbParityBits: - description: Hamming FEC parity bits (LoRa) - type: integer - packetLength: - description: expected packet length in number of bytes (LoRa) - type: integer - hasCRC: - description: Payload has CRC (LoRa) - type: integer - hasHeader: - description: Header present before actual payload (LoRa) - type: integer - sendViaUDP: - description: boolean 1 to send decoded message via UDP else 0 - type: integer - udpAddress: - description: UDP destination udpAddress - type: string - udpPort: - description: UDP destination properties - type: integer - rgbColor: - type: integer - title: - type: string - streamIndex: - description: MIMO channel. Not relevant when connected to SI (single Rx). - type: integer - useReverseAPI: - description: Synchronize with reverse API (1 for yes, 0 for no) - type: integer - reverseAPIAddress: - type: string - reverseAPIPort: - type: integer - reverseAPIDeviceIndex: - type: integer - reverseAPIChannelIndex: - type: integer - -LoRaDemodReport: - description: LoRaDemod - properties: - channelPowerDB: - description: current de-chirped total channel power (dB) - type: number - format: float - noisePowerDB: - description: current de-chirped noise argmax power (dB) - type: number - format: float - signalPowerDB: - description: last message de-chirped signal argmax power (dB) - type: number - format: float - snrPowerDB: - description: last message de-chirped signal to noise ratio power (dB) - type: number - format: float - channelSampleRate: - type: integer - syncWord: - description: 2 bytes sync word (0..65535) - type: integer - hasCRC: - description: boolean 1 if payload CRC is present else 0 (LoRa) - type: integer - nbParityBits: - description: Hamming FEC parity bits (LoRa) - type: integer - packetLength: - description: Packet length in number of bytes (LoRa) - type: integer - nbSymbols: - description: Number of symbols in the payload with header and CRC (LoRa) - type: integer - nbCodewords: - description: Number of codewords in the payload with header and CRC (LoRa) - type: integer - headerParityStatus: - type: integer - description: > - Header FEC parity status: - * 0 - Undefined - * 1 - Uncorrectable error - * 2 - Corrected error - * 3 - OK - headerCRCStatus: - description: header CRC check status. Boolean 1 if OK else 0 - type: integer - payloadParityStatus: - type: integer - description: > - Payload FEC parity status: - * 0 - Undefined - * 1 - Uncorrectable error - * 2 - Corrected error - * 3 - OK - payloadCRCStatus: - description: payload CRC check status. Boolean 1 if OK else 0 - type: integer - messageTimestamp: - description: timestamp of the last decoded message - type: string - messageString: - description: string representation of the last decoded message - type: string - messageBytes: - description: bytes of the last decoded message as an array of hex string represented bytes (00..FF) - type: array - items: - type: string diff --git a/sdrbase/resources/webapi/doc/swagger/swagger.yaml b/sdrbase/resources/webapi/doc/swagger/swagger.yaml index 6a94d4dc6..cdd5f320f 100644 --- a/sdrbase/resources/webapi/doc/swagger/swagger.yaml +++ b/sdrbase/resources/webapi/doc/swagger/swagger.yaml @@ -2264,6 +2264,8 @@ definitions: $ref: "/doc/swagger/include/BFMDemod.yaml#/BFMDemodReport" ChirpChatDemodReport: $ref: "/doc/swagger/include/ChirpChatDemod.yaml#/ChirpChatDemodReport" + ChirpChatModReport: + $ref: "/doc/swagger/include/ChirpChatMod.yaml#/ChirpChatModReport" DSDDemodReport: $ref: "/doc/swagger/include/DSDDemod.yaml#/DSDDemodReport" FileSourceReport: @@ -2274,8 +2276,6 @@ definitions: $ref: "/doc/swagger/include/FreeDVMod.yaml#/FreeDVModReport" FreqTrackerReport: $ref: "/doc/swagger/include/FreqTracker.yaml#/FreqTrackerReport" - LoRaModReport: - $ref: "/doc/swagger/include/LoRaMod.yaml#/LoRaModReport" NFMDemodReport: $ref: "/doc/swagger/include/NFMDemod.yaml#/NFMDemodReport" NFMModReport: diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index 7bef3af39..8631939cb 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -60,6 +60,7 @@ const QMap WebAPIRequestMapper::m_channelURIToSettingsKey = { {"sdrangel.channel.chanalyzerng", "ChannelAnalyzerSettings"}, // remap {"org.f4exb.sdrangelove.channel.chanalyzer", "ChannelAnalyzerSettings"}, // remap {"sdrangel.channel.chirpchatdemod", "ChirpChatDemodSettings"}, + {"sdrangel.channel.modchirpchat", "ChirpChatModSettings"}, {"sdrangel.channel.demodatv", "ATVDemodSettings"}, {"sdrangel.channel.demoddatv", "DATVDemodSettings"}, {"sdrangel.channel.dsddemod", "DSDDemodSettings"}, @@ -73,7 +74,6 @@ const QMap WebAPIRequestMapper::m_channelURIToSettingsKey = { {"sdrangel.demod.localsink", "LocalSinkSettings"}, {"sdrangel.channel.localsink", "LocalSinkSettings"}, // remap {"sdrangel.channel.localsource", "LocalSourceSettings"}, - {"sdrangel.channel.modlora", "LoRaModSettings"}, {"sdrangel.demod.remotesink", "RemoteSinkSettings"}, {"sdrangel.channeltx.remotesource", "RemoteSourceSettings"}, {"sdrangel.channeltx.modssb", "SSBModSettings"}, @@ -139,6 +139,7 @@ const QMap WebAPIRequestMapper::m_channelTypeToSettingsKey = { {"BFMDemod", "BFMDemodSettings"}, {"ChannelAnalyzer", "ChannelAnalyzerSettings"}, {"ChirpChatDemod", "ChirpChatDemodSettings"}, + {"ChirpChatMod", "ChirpChatModSettings"}, {"DATVDemod", "DATVDemodSettings"}, {"DSDDemod", "DSDDemodSettings"}, {"FileSource", "FileSourceSettings"}, @@ -149,7 +150,6 @@ const QMap WebAPIRequestMapper::m_channelTypeToSettingsKey = { {"NFMMod", "NFMModSettings"}, {"LocalSink", "LocalSinkSettings"}, {"LocalSource", "LocalSourceSettings"}, - {"LoRaMod", "LoRaModSettings"}, {"RemoteSink", "RemoteSinkSettings"}, {"RemoteSource", "RemoteSourceSettings"}, {"SSBMod", "SSBModSettings"}, @@ -2920,11 +2920,11 @@ bool WebAPIRequestMapper::getChannel( channelSettings->setChirpChatDemodSettings(new SWGSDRangel::SWGChirpChatDemodSettings()); channelSettings->getChirpChatDemodSettings()->fromJsonObject(settingsJsonObject); } - else if (channelSettingsKey == "LoRaModSettings") + else if (channelSettingsKey == "ChirpChatModSettings") { - channelSettings->setLoRaModSettings(new SWGSDRangel::SWGLoRaModSettings()); - channelSettings->getLoRaModSettings()->init(); // contains a list of strings - channelSettings->getLoRaModSettings()->fromJsonObject(settingsJsonObject); + channelSettings->setChirpChatModSettings(new SWGSDRangel::SWGChirpChatModSettings()); + channelSettings->getChirpChatModSettings()->init(); // contains a list of strings + channelSettings->getChirpChatModSettings()->fromJsonObject(settingsJsonObject); } else if (channelSettingsKey == "RemoteSinkSettings") { diff --git a/swagger/sdrangel/api/swagger/include/ChannelSettings.yaml b/swagger/sdrangel/api/swagger/include/ChannelSettings.yaml index a5ba9d963..8a326ccb6 100644 --- a/swagger/sdrangel/api/swagger/include/ChannelSettings.yaml +++ b/swagger/sdrangel/api/swagger/include/ChannelSettings.yaml @@ -33,6 +33,8 @@ ChannelSettings: $ref: "http://localhost:8081/api/swagger/include/ChannelAnalyzer.yaml#/ChannelAnalyzerSettings" ChirpChatDemodSettings: $ref: "http://localhost:8081/api/swagger/include/ChirpChatDemod.yaml#/ChirpChatDemodSettings" + ChirpChatModSettings: + $ref: "http://localhost:8081/api/swagger/include/ChirpChatMod.yaml#/ChirpChatModSettings" DATVDemodSettings: $ref: "http://localhost:8081/api/swagger/include/DATVDemod.yaml#/DATVDemodSettings" DSDDemodSettings: @@ -47,8 +49,6 @@ ChannelSettings: $ref: "http://localhost:8081/api/swagger/include/FreqTracker.yaml#/FreqTrackerSettings" InterferometerSettings: $ref: "http://localhost:8081/api/swagger/include/Interferometer.yaml#/InterferometerSettings" - LoRaModSettings: - $ref: "http://localhost:8081/api/swagger/include/LoRaMod.yaml#/LoRaModSettings" NFMDemodSettings: $ref: "http://localhost:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodSettings" NFMModSettings: diff --git a/swagger/sdrangel/api/swagger/include/ChirpChatDemod.yaml b/swagger/sdrangel/api/swagger/include/ChirpChatDemod.yaml index 7194cf866..33a1469f0 100644 --- a/swagger/sdrangel/api/swagger/include/ChirpChatDemod.yaml +++ b/swagger/sdrangel/api/swagger/include/ChirpChatDemod.yaml @@ -40,7 +40,7 @@ ChirpChatDemodSettings: codingScheme: type: integer description: > - message encoding scheme (LoRaModSettings::CodingScheme): + message encoding scheme (ChirpChatDemodSettings::CodingScheme): * 0 - LoRa * 1 - Plain ASCII (7 bit) * 2 - Teletype (5 bit Baudot) a.k.a TTY diff --git a/sdrbase/resources/webapi/doc/swagger/include/LoRaMod.yaml b/swagger/sdrangel/api/swagger/include/ChirpChatMod.yaml similarity index 95% rename from sdrbase/resources/webapi/doc/swagger/include/LoRaMod.yaml rename to swagger/sdrangel/api/swagger/include/ChirpChatMod.yaml index 47375613a..0316cbe99 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/LoRaMod.yaml +++ b/swagger/sdrangel/api/swagger/include/ChirpChatMod.yaml @@ -1,5 +1,5 @@ -LoRaModSettings: - description: LoRaMod +ChirpChatModSettings: + description: ChirpChatMod properties: inputFrequencyOffset: type: integer @@ -52,7 +52,7 @@ LoRaModSettings: codingScheme: type: integer description: > - message encoding scheme (LoRaModSettings::CodingScheme): + message encoding scheme (ChirpChatModSettings::CodingScheme): * 0 - LoRa * 1 - Plain ASCII (7 bit) * 2 - Teletype (5 bit Baudot) a.k.a TTY @@ -80,7 +80,7 @@ LoRaModSettings: messageType: type: integer description: > - type of message to send (LoRaModSettings::MessageType): + type of message to send (ChirpChatModSettings::MessageType): * 0 - No message i.e no output. Use this as a transition to resend the same message. * 1 - Beacon. Sends message specified in beaconMessage * 2 - CQ call. Sends message specified in cqMessage @@ -146,8 +146,8 @@ LoRaModSettings: reverseAPIChannelIndex: type: integer -LoRaModReport: - description: LoRaMod +ChirpChatModReport: + description: ChirpChatMod properties: channelPowerDB: description: power transmitted in channel (dB) diff --git a/swagger/sdrangel/api/swagger/swagger.yaml b/swagger/sdrangel/api/swagger/swagger.yaml index eeabb05da..4579b08ac 100644 --- a/swagger/sdrangel/api/swagger/swagger.yaml +++ b/swagger/sdrangel/api/swagger/swagger.yaml @@ -2264,6 +2264,8 @@ definitions: $ref: "http://localhost:8081/api/swagger/include/BFMDemod.yaml#/BFMDemodReport" ChirpChatDemodReport: $ref: "http://localhost:8081/api/swagger/include/ChirpChatDemod.yaml#/ChirpChatDemodReport" + ChirpChatModReport: + $ref: "http://localhost:8081/api/swagger/include/ChirpChatMod.yaml#/ChirpChatModReport" DSDDemodReport: $ref: "http://localhost:8081/api/swagger/include/DSDDemod.yaml#/DSDDemodReport" FileSourceReport: @@ -2274,8 +2276,6 @@ definitions: $ref: "http://localhost:8081/api/swagger/include/FreeDVMod.yaml#/FreeDVModReport" FreqTrackerReport: $ref: "http://localhost:8081/api/swagger/include/FreqTracker.yaml#/FreqTrackerReport" - LoRaModReport: - $ref: "http://localhost:8081/api/swagger/include/LoRaMod.yaml#/LoRaModReport" NFMDemodReport: $ref: "http://localhost:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodReport" NFMModReport: diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index 512727d6f..a3b8cecd6 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -2172,6 +2172,9 @@ margin-bottom: 20px; "ChirpChatDemodReport" : { "$ref" : "#/definitions/ChirpChatDemodReport" }, + "ChirpChatModReport" : { + "$ref" : "#/definitions/ChirpChatModReport" + }, "DSDDemodReport" : { "$ref" : "#/definitions/DSDDemodReport" }, @@ -2187,9 +2190,6 @@ margin-bottom: 20px; "FreqTrackerReport" : { "$ref" : "#/definitions/FreqTrackerReport" }, - "LoRaModReport" : { - "$ref" : "#/definitions/LoRaModReport" - }, "NFMDemodReport" : { "$ref" : "#/definitions/NFMDemodReport" }, @@ -2264,6 +2264,9 @@ margin-bottom: 20px; "ChirpChatDemodSettings" : { "$ref" : "#/definitions/ChirpChatDemodSettings" }, + "ChirpChatModSettings" : { + "$ref" : "#/definitions/ChirpChatModSettings" + }, "DATVDemodSettings" : { "$ref" : "#/definitions/DATVDemodSettings" }, @@ -2285,9 +2288,6 @@ margin-bottom: 20px; "InterferometerSettings" : { "$ref" : "#/definitions/InterferometerSettings" }, - "LoRaModSettings" : { - "$ref" : "#/definitions/LoRaModSettings" - }, "NFMDemodSettings" : { "$ref" : "#/definitions/NFMDemodSettings" }, @@ -2524,6 +2524,179 @@ margin-bottom: 20px; } }, "description" : "ChirpChatDemod" +}; + defs.ChirpChatModReport = { + "properties" : { + "channelPowerDB" : { + "type" : "number", + "format" : "float", + "description" : "power transmitted in channel (dB)" + }, + "channelSampleRate" : { + "type" : "integer" + }, + "symbolTimeMs" : { + "type" : "number", + "format" : "float", + "description" : "symbol duration (ms)" + }, + "payloadTimeMs" : { + "type" : "number", + "format" : "float", + "description" : "payload duration (ms)" + }, + "totalTimeMs" : { + "type" : "number", + "format" : "float", + "description" : "total message duration inc. preamble and SFD (ms)" + } + }, + "description" : "ChirpChatMod" +}; + defs.ChirpChatModSettings = { + "properties" : { + "inputFrequencyOffset" : { + "type" : "integer", + "format" : "int64" + }, + "bandwidthIndex" : { + "type" : "integer", + "description" : "standard bandwidths index:\n * 0 - 2604 Hz (333333 / 128)\n * 1 - 3125 Hz (400000 / 128)\n * 2 - 3906 Hz (500000 / 128)\n * 3 - 5208 Hz (333333 / 64)\n * 4 - 6250 Hz (400000 / 64)\n * 5 - 7813 Hz (500000 / 64)\n * 6 - 10417 Hz (333333 / 32)\n * 7 - 12500 Hz (400000 / 32)\n * 8 - 15625 Hz (500000 / 32)\n * 9 - 20833 Hz (333333 / 16)\n * 10 - 25000 Hz (400000 / 16)\n * 11 - 31250 Hz (500000 / 16)\n * 12 - 41667 Hz (333333 / 8)\n * 13 - 50000 Hz (400000 / 8)\n * 14 - 62500 Hz (500000 / 8)\n * 15 - 83333 Hz (333333 / 4)\n * 16 - 100000 Hz (400000 / 4)\n * 17 - 125000 Hz (500000 / 4)\n * 18 - 166667 Hz (333333 / 2)\n * 19 - 200000 Hz (400000 / 2)\n * 20 - 250000 Hz (500000 / 2)\n * 21 - 333333 Hz (333333 / 1)\n * 22 - 400000 Hz (400000 / 1)\n * 23 - 500000 Hz (500000 / 1)\n" + }, + "spreadFactor" : { + "type" : "integer" + }, + "deBits" : { + "type" : "integer", + "description" : "Low data rate optmize (DE) bits i.e. nb of FFT bins per effective symbol" + }, + "preambleChirps" : { + "type" : "integer", + "description" : "Number of preamble chirps" + }, + "quietMillis" : { + "type" : "integer", + "description" : "Number of milliseconds to pause between transmissions" + }, + "syncWord" : { + "type" : "integer", + "description" : "2 byte (0..65535) synchronization syncWord" + }, + "channelMute" : { + "type" : "integer", + "description" : "boolean" + }, + "codingScheme" : { + "type" : "integer", + "description" : "message encoding scheme (LoRaModSettings::CodingScheme):\n * 0 - LoRa\n * 1 - Plain ASCII (7 bit)\n * 2 - Teletype (5 bit Baudot) a.k.a TTY\n" + }, + "nbParityBits" : { + "type" : "integer", + "description" : "Hamming FEC parity bits (LoRa)" + }, + "hasCRC" : { + "type" : "integer", + "description" : "Payload has CRC (LoRa)" + }, + "hasHeader" : { + "type" : "integer", + "description" : "Header present before actual payload (LoRa)" + }, + "myCall" : { + "type" : "string", + "description" : "own callsign placeholder (QSO mode)" + }, + "urCall" : { + "type" : "string", + "description" : "other party callsign placeholder (QSO mode)" + }, + "myLoc" : { + "type" : "string", + "description" : "own QRA locator (QSO mode)" + }, + "myRpt" : { + "type" : "string", + "description" : "report sent to other party (QSO mode)" + }, + "messageType" : { + "type" : "integer", + "description" : "type of message to send (LoRaModSettings::MessageType):\n * 0 - No message i.e no output. Use this as a transition to resend the same message.\n * 1 - Beacon. Sends message specified in beaconMessage\n * 2 - CQ call. Sends message specified in cqMessage\n * 3 - Reply to CQ call. Sends message specified in replyMessage\n * 4 - Report to callee. Sends message specified in reportMessage\n * 5 - Report to caller. Sends message specified in replyReportMessage\n * 6 - RRR to callee. Sends message specified in rrrMessage\n * 7 - 73 to caller. Sends message specified in message73\n * 8 - Random message with callsigns. Sends message specified in qsoTextMessage\n * 9 - Plain text. Sends message specified in textMessage\n * 10 - Binary payload. Sends bytes specified in bytesMessage\n" + }, + "beaconMessage" : { + "type" : "string", + "description" : "text message to be sent (repeatedly) as a beaconMessage" + }, + "cqMessage" : { + "type" : "string", + "description" : "general call message (QSO mode)" + }, + "replyMessage" : { + "type" : "string", + "description" : "reply to caller message (QSO mode)" + }, + "reportMessage" : { + "type" : "string", + "description" : "report to callee message (QSO mode)" + }, + "replyReportMessage" : { + "type" : "string", + "description" : "report back to caller message (QSO mode)" + }, + "rrrMessage" : { + "type" : "string", + "description" : "caller RRR message (QSO mode)" + }, + "message73" : { + "type" : "string", + "description" : "73 message back to caller to close QSO (QSO mode)" + }, + "qsoTextMessage" : { + "type" : "string", + "description" : "QSO random message exchange (QSO mode)" + }, + "textMessage" : { + "type" : "string", + "description" : "freeform text message" + }, + "bytesMessage" : { + "type" : "array", + "description" : "message to send as an array of hex string represented bytes (00..FF)", + "items" : { + "type" : "string" + } + }, + "messageRepeat" : { + "type" : "integer", + "description" : "number of repetitions of the same message (0 for infinite)" + }, + "rgbColor" : { + "type" : "integer" + }, + "title" : { + "type" : "string" + }, + "streamIndex" : { + "type" : "integer", + "description" : "MIMO channel. Not relevant when connected to SI (single Rx)." + }, + "useReverseAPI" : { + "type" : "integer", + "description" : "Synchronize with reverse API (1 for yes, 0 for no)" + }, + "reverseAPIAddress" : { + "type" : "string" + }, + "reverseAPIPort" : { + "type" : "integer" + }, + "reverseAPIDeviceIndex" : { + "type" : "integer" + }, + "reverseAPIChannelIndex" : { + "type" : "integer" + } + }, + "description" : "ChirpChatMod" }; defs.Command = { "properties" : { @@ -4566,179 +4739,6 @@ margin-bottom: 20px; } }, "description" : "LimeSDR" -}; - defs.LoRaModReport = { - "properties" : { - "channelPowerDB" : { - "type" : "number", - "format" : "float", - "description" : "power transmitted in channel (dB)" - }, - "channelSampleRate" : { - "type" : "integer" - }, - "symbolTimeMs" : { - "type" : "number", - "format" : "float", - "description" : "symbol duration (ms)" - }, - "payloadTimeMs" : { - "type" : "number", - "format" : "float", - "description" : "payload duration (ms)" - }, - "totalTimeMs" : { - "type" : "number", - "format" : "float", - "description" : "total message duration inc. preamble and SFD (ms)" - } - }, - "description" : "LoRaMod" -}; - defs.LoRaModSettings = { - "properties" : { - "inputFrequencyOffset" : { - "type" : "integer", - "format" : "int64" - }, - "bandwidthIndex" : { - "type" : "integer", - "description" : "standard bandwidths index:\n * 0 - 2604 Hz (333333 / 128)\n * 1 - 3125 Hz (400000 / 128)\n * 2 - 3906 Hz (500000 / 128)\n * 3 - 5208 Hz (333333 / 64)\n * 4 - 6250 Hz (400000 / 64)\n * 5 - 7813 Hz (500000 / 64)\n * 6 - 10417 Hz (333333 / 32)\n * 7 - 12500 Hz (400000 / 32)\n * 8 - 15625 Hz (500000 / 32)\n * 9 - 20833 Hz (333333 / 16)\n * 10 - 25000 Hz (400000 / 16)\n * 11 - 31250 Hz (500000 / 16)\n * 12 - 41667 Hz (333333 / 8)\n * 13 - 50000 Hz (400000 / 8)\n * 14 - 62500 Hz (500000 / 8)\n * 15 - 83333 Hz (333333 / 4)\n * 16 - 100000 Hz (400000 / 4)\n * 17 - 125000 Hz (500000 / 4)\n * 18 - 166667 Hz (333333 / 2)\n * 19 - 200000 Hz (400000 / 2)\n * 20 - 250000 Hz (500000 / 2)\n * 21 - 333333 Hz (333333 / 1)\n * 22 - 400000 Hz (400000 / 1)\n * 23 - 500000 Hz (500000 / 1)\n" - }, - "spreadFactor" : { - "type" : "integer" - }, - "deBits" : { - "type" : "integer", - "description" : "Low data rate optmize (DE) bits i.e. nb of FFT bins per effective symbol" - }, - "preambleChirps" : { - "type" : "integer", - "description" : "Number of preamble chirps" - }, - "quietMillis" : { - "type" : "integer", - "description" : "Number of milliseconds to pause between transmissions" - }, - "syncWord" : { - "type" : "integer", - "description" : "2 byte (0..65535) synchronization syncWord" - }, - "channelMute" : { - "type" : "integer", - "description" : "boolean" - }, - "codingScheme" : { - "type" : "integer", - "description" : "message encoding scheme (LoRaModSettings::CodingScheme):\n * 0 - LoRa\n * 1 - Plain ASCII (7 bit)\n * 2 - Teletype (5 bit Baudot) a.k.a TTY\n" - }, - "nbParityBits" : { - "type" : "integer", - "description" : "Hamming FEC parity bits (LoRa)" - }, - "hasCRC" : { - "type" : "integer", - "description" : "Payload has CRC (LoRa)" - }, - "hasHeader" : { - "type" : "integer", - "description" : "Header present before actual payload (LoRa)" - }, - "myCall" : { - "type" : "string", - "description" : "own callsign placeholder (QSO mode)" - }, - "urCall" : { - "type" : "string", - "description" : "other party callsign placeholder (QSO mode)" - }, - "myLoc" : { - "type" : "string", - "description" : "own QRA locator (QSO mode)" - }, - "myRpt" : { - "type" : "string", - "description" : "report sent to other party (QSO mode)" - }, - "messageType" : { - "type" : "integer", - "description" : "type of message to send (LoRaModSettings::MessageType):\n * 0 - No message i.e no output. Use this as a transition to resend the same message.\n * 1 - Beacon. Sends message specified in beaconMessage\n * 2 - CQ call. Sends message specified in cqMessage\n * 3 - Reply to CQ call. Sends message specified in replyMessage\n * 4 - Report to callee. Sends message specified in reportMessage\n * 5 - Report to caller. Sends message specified in replyReportMessage\n * 6 - RRR to callee. Sends message specified in rrrMessage\n * 7 - 73 to caller. Sends message specified in message73\n * 8 - Random message with callsigns. Sends message specified in qsoTextMessage\n * 9 - Plain text. Sends message specified in textMessage\n * 10 - Binary payload. Sends bytes specified in bytesMessage\n" - }, - "beaconMessage" : { - "type" : "string", - "description" : "text message to be sent (repeatedly) as a beaconMessage" - }, - "cqMessage" : { - "type" : "string", - "description" : "general call message (QSO mode)" - }, - "replyMessage" : { - "type" : "string", - "description" : "reply to caller message (QSO mode)" - }, - "reportMessage" : { - "type" : "string", - "description" : "report to callee message (QSO mode)" - }, - "replyReportMessage" : { - "type" : "string", - "description" : "report back to caller message (QSO mode)" - }, - "rrrMessage" : { - "type" : "string", - "description" : "caller RRR message (QSO mode)" - }, - "message73" : { - "type" : "string", - "description" : "73 message back to caller to close QSO (QSO mode)" - }, - "qsoTextMessage" : { - "type" : "string", - "description" : "QSO random message exchange (QSO mode)" - }, - "textMessage" : { - "type" : "string", - "description" : "freeform text message" - }, - "bytesMessage" : { - "type" : "array", - "description" : "message to send as an array of hex string represented bytes (00..FF)", - "items" : { - "type" : "string" - } - }, - "messageRepeat" : { - "type" : "integer", - "description" : "number of repetitions of the same message (0 for infinite)" - }, - "rgbColor" : { - "type" : "integer" - }, - "title" : { - "type" : "string" - }, - "streamIndex" : { - "type" : "integer", - "description" : "MIMO channel. Not relevant when connected to SI (single Rx)." - }, - "useReverseAPI" : { - "type" : "integer", - "description" : "Synchronize with reverse API (1 for yes, 0 for no)" - }, - "reverseAPIAddress" : { - "type" : "string" - }, - "reverseAPIPort" : { - "type" : "integer" - }, - "reverseAPIDeviceIndex" : { - "type" : "integer" - }, - "reverseAPIChannelIndex" : { - "type" : "integer" - } - }, - "description" : "LoRaMod" }; defs.LocalInputReport = { "properties" : { @@ -32618,7 +32618,7 @@ except ApiException as e:
- Generated 2020-03-03T20:19:50.511+01:00 + Generated 2020-03-03T23:14:21.625+01:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGChannelReport.cpp b/swagger/sdrangel/code/qt5/client/SWGChannelReport.cpp index f3f20c34c..bb216cfb9 100644 --- a/swagger/sdrangel/code/qt5/client/SWGChannelReport.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGChannelReport.cpp @@ -42,6 +42,8 @@ SWGChannelReport::SWGChannelReport() { m_bfm_demod_report_isSet = false; chirp_chat_demod_report = nullptr; m_chirp_chat_demod_report_isSet = false; + chirp_chat_mod_report = nullptr; + m_chirp_chat_mod_report_isSet = false; dsd_demod_report = nullptr; m_dsd_demod_report_isSet = false; file_source_report = nullptr; @@ -52,8 +54,6 @@ SWGChannelReport::SWGChannelReport() { m_free_dv_mod_report_isSet = false; freq_tracker_report = nullptr; m_freq_tracker_report_isSet = false; - lo_ra_mod_report = nullptr; - m_lo_ra_mod_report_isSet = false; nfm_demod_report = nullptr; m_nfm_demod_report_isSet = false; nfm_mod_report = nullptr; @@ -94,6 +94,8 @@ SWGChannelReport::init() { m_bfm_demod_report_isSet = false; chirp_chat_demod_report = new SWGChirpChatDemodReport(); m_chirp_chat_demod_report_isSet = false; + chirp_chat_mod_report = new SWGChirpChatModReport(); + m_chirp_chat_mod_report_isSet = false; dsd_demod_report = new SWGDSDDemodReport(); m_dsd_demod_report_isSet = false; file_source_report = new SWGFileSourceReport(); @@ -104,8 +106,6 @@ SWGChannelReport::init() { m_free_dv_mod_report_isSet = false; freq_tracker_report = new SWGFreqTrackerReport(); m_freq_tracker_report_isSet = false; - lo_ra_mod_report = new SWGLoRaModReport(); - m_lo_ra_mod_report_isSet = false; nfm_demod_report = new SWGNFMDemodReport(); m_nfm_demod_report_isSet = false; nfm_mod_report = new SWGNFMModReport(); @@ -147,6 +147,9 @@ SWGChannelReport::cleanup() { if(chirp_chat_demod_report != nullptr) { delete chirp_chat_demod_report; } + if(chirp_chat_mod_report != nullptr) { + delete chirp_chat_mod_report; + } if(dsd_demod_report != nullptr) { delete dsd_demod_report; } @@ -162,9 +165,6 @@ SWGChannelReport::cleanup() { if(freq_tracker_report != nullptr) { delete freq_tracker_report; } - if(lo_ra_mod_report != nullptr) { - delete lo_ra_mod_report; - } if(nfm_demod_report != nullptr) { delete nfm_demod_report; } @@ -219,6 +219,8 @@ SWGChannelReport::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&chirp_chat_demod_report, pJson["ChirpChatDemodReport"], "SWGChirpChatDemodReport", "SWGChirpChatDemodReport"); + ::SWGSDRangel::setValue(&chirp_chat_mod_report, pJson["ChirpChatModReport"], "SWGChirpChatModReport", "SWGChirpChatModReport"); + ::SWGSDRangel::setValue(&dsd_demod_report, pJson["DSDDemodReport"], "SWGDSDDemodReport", "SWGDSDDemodReport"); ::SWGSDRangel::setValue(&file_source_report, pJson["FileSourceReport"], "SWGFileSourceReport", "SWGFileSourceReport"); @@ -229,8 +231,6 @@ SWGChannelReport::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&freq_tracker_report, pJson["FreqTrackerReport"], "SWGFreqTrackerReport", "SWGFreqTrackerReport"); - ::SWGSDRangel::setValue(&lo_ra_mod_report, pJson["LoRaModReport"], "SWGLoRaModReport", "SWGLoRaModReport"); - ::SWGSDRangel::setValue(&nfm_demod_report, pJson["NFMDemodReport"], "SWGNFMDemodReport", "SWGNFMDemodReport"); ::SWGSDRangel::setValue(&nfm_mod_report, pJson["NFMModReport"], "SWGNFMModReport", "SWGNFMModReport"); @@ -286,6 +286,9 @@ SWGChannelReport::asJsonObject() { if((chirp_chat_demod_report != nullptr) && (chirp_chat_demod_report->isSet())){ toJsonValue(QString("ChirpChatDemodReport"), chirp_chat_demod_report, obj, QString("SWGChirpChatDemodReport")); } + if((chirp_chat_mod_report != nullptr) && (chirp_chat_mod_report->isSet())){ + toJsonValue(QString("ChirpChatModReport"), chirp_chat_mod_report, obj, QString("SWGChirpChatModReport")); + } if((dsd_demod_report != nullptr) && (dsd_demod_report->isSet())){ toJsonValue(QString("DSDDemodReport"), dsd_demod_report, obj, QString("SWGDSDDemodReport")); } @@ -301,9 +304,6 @@ SWGChannelReport::asJsonObject() { if((freq_tracker_report != nullptr) && (freq_tracker_report->isSet())){ toJsonValue(QString("FreqTrackerReport"), freq_tracker_report, obj, QString("SWGFreqTrackerReport")); } - if((lo_ra_mod_report != nullptr) && (lo_ra_mod_report->isSet())){ - toJsonValue(QString("LoRaModReport"), lo_ra_mod_report, obj, QString("SWGLoRaModReport")); - } if((nfm_demod_report != nullptr) && (nfm_demod_report->isSet())){ toJsonValue(QString("NFMDemodReport"), nfm_demod_report, obj, QString("SWGNFMDemodReport")); } @@ -405,6 +405,16 @@ SWGChannelReport::setChirpChatDemodReport(SWGChirpChatDemodReport* chirp_chat_de this->m_chirp_chat_demod_report_isSet = true; } +SWGChirpChatModReport* +SWGChannelReport::getChirpChatModReport() { + return chirp_chat_mod_report; +} +void +SWGChannelReport::setChirpChatModReport(SWGChirpChatModReport* chirp_chat_mod_report) { + this->chirp_chat_mod_report = chirp_chat_mod_report; + this->m_chirp_chat_mod_report_isSet = true; +} + SWGDSDDemodReport* SWGChannelReport::getDsdDemodReport() { return dsd_demod_report; @@ -455,16 +465,6 @@ SWGChannelReport::setFreqTrackerReport(SWGFreqTrackerReport* freq_tracker_report this->m_freq_tracker_report_isSet = true; } -SWGLoRaModReport* -SWGChannelReport::getLoRaModReport() { - return lo_ra_mod_report; -} -void -SWGChannelReport::setLoRaModReport(SWGLoRaModReport* lo_ra_mod_report) { - this->lo_ra_mod_report = lo_ra_mod_report; - this->m_lo_ra_mod_report_isSet = true; -} - SWGNFMDemodReport* SWGChannelReport::getNfmDemodReport() { return nfm_demod_report; @@ -581,6 +581,9 @@ SWGChannelReport::isSet(){ if(chirp_chat_demod_report && chirp_chat_demod_report->isSet()){ isObjectUpdated = true; break; } + if(chirp_chat_mod_report && chirp_chat_mod_report->isSet()){ + isObjectUpdated = true; break; + } if(dsd_demod_report && dsd_demod_report->isSet()){ isObjectUpdated = true; break; } @@ -596,9 +599,6 @@ SWGChannelReport::isSet(){ if(freq_tracker_report && freq_tracker_report->isSet()){ isObjectUpdated = true; break; } - if(lo_ra_mod_report && lo_ra_mod_report->isSet()){ - isObjectUpdated = true; break; - } if(nfm_demod_report && nfm_demod_report->isSet()){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGChannelReport.h b/swagger/sdrangel/code/qt5/client/SWGChannelReport.h index 5757bd601..cf6b53733 100644 --- a/swagger/sdrangel/code/qt5/client/SWGChannelReport.h +++ b/swagger/sdrangel/code/qt5/client/SWGChannelReport.h @@ -27,12 +27,12 @@ #include "SWGATVModReport.h" #include "SWGBFMDemodReport.h" #include "SWGChirpChatDemodReport.h" +#include "SWGChirpChatModReport.h" #include "SWGDSDDemodReport.h" #include "SWGFileSourceReport.h" #include "SWGFreeDVDemodReport.h" #include "SWGFreeDVModReport.h" #include "SWGFreqTrackerReport.h" -#include "SWGLoRaModReport.h" #include "SWGNFMDemodReport.h" #include "SWGNFMModReport.h" #include "SWGRemoteSourceReport.h" @@ -83,6 +83,9 @@ public: SWGChirpChatDemodReport* getChirpChatDemodReport(); void setChirpChatDemodReport(SWGChirpChatDemodReport* chirp_chat_demod_report); + SWGChirpChatModReport* getChirpChatModReport(); + void setChirpChatModReport(SWGChirpChatModReport* chirp_chat_mod_report); + SWGDSDDemodReport* getDsdDemodReport(); void setDsdDemodReport(SWGDSDDemodReport* dsd_demod_report); @@ -98,9 +101,6 @@ public: SWGFreqTrackerReport* getFreqTrackerReport(); void setFreqTrackerReport(SWGFreqTrackerReport* freq_tracker_report); - SWGLoRaModReport* getLoRaModReport(); - void setLoRaModReport(SWGLoRaModReport* lo_ra_mod_report); - SWGNFMDemodReport* getNfmDemodReport(); void setNfmDemodReport(SWGNFMDemodReport* nfm_demod_report); @@ -153,6 +153,9 @@ private: SWGChirpChatDemodReport* chirp_chat_demod_report; bool m_chirp_chat_demod_report_isSet; + SWGChirpChatModReport* chirp_chat_mod_report; + bool m_chirp_chat_mod_report_isSet; + SWGDSDDemodReport* dsd_demod_report; bool m_dsd_demod_report_isSet; @@ -168,9 +171,6 @@ private: SWGFreqTrackerReport* freq_tracker_report; bool m_freq_tracker_report_isSet; - SWGLoRaModReport* lo_ra_mod_report; - bool m_lo_ra_mod_report_isSet; - SWGNFMDemodReport* nfm_demod_report; bool m_nfm_demod_report_isSet; diff --git a/swagger/sdrangel/code/qt5/client/SWGChannelSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGChannelSettings.cpp index 0c21c1132..f0482f79f 100644 --- a/swagger/sdrangel/code/qt5/client/SWGChannelSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGChannelSettings.cpp @@ -52,6 +52,8 @@ SWGChannelSettings::SWGChannelSettings() { m_channel_analyzer_settings_isSet = false; chirp_chat_demod_settings = nullptr; m_chirp_chat_demod_settings_isSet = false; + chirp_chat_mod_settings = nullptr; + m_chirp_chat_mod_settings_isSet = false; datv_demod_settings = nullptr; m_datv_demod_settings_isSet = false; dsd_demod_settings = nullptr; @@ -66,8 +68,6 @@ SWGChannelSettings::SWGChannelSettings() { m_freq_tracker_settings_isSet = false; interferometer_settings = nullptr; m_interferometer_settings_isSet = false; - lo_ra_mod_settings = nullptr; - m_lo_ra_mod_settings_isSet = false; nfm_demod_settings = nullptr; m_nfm_demod_settings_isSet = false; nfm_mod_settings = nullptr; @@ -124,6 +124,8 @@ SWGChannelSettings::init() { m_channel_analyzer_settings_isSet = false; chirp_chat_demod_settings = new SWGChirpChatDemodSettings(); m_chirp_chat_demod_settings_isSet = false; + chirp_chat_mod_settings = new SWGChirpChatModSettings(); + m_chirp_chat_mod_settings_isSet = false; datv_demod_settings = new SWGDATVDemodSettings(); m_datv_demod_settings_isSet = false; dsd_demod_settings = new SWGDSDDemodSettings(); @@ -138,8 +140,6 @@ SWGChannelSettings::init() { m_freq_tracker_settings_isSet = false; interferometer_settings = new SWGInterferometerSettings(); m_interferometer_settings_isSet = false; - lo_ra_mod_settings = new SWGLoRaModSettings(); - m_lo_ra_mod_settings_isSet = false; nfm_demod_settings = new SWGNFMDemodSettings(); m_nfm_demod_settings_isSet = false; nfm_mod_settings = new SWGNFMModSettings(); @@ -198,6 +198,9 @@ SWGChannelSettings::cleanup() { if(chirp_chat_demod_settings != nullptr) { delete chirp_chat_demod_settings; } + if(chirp_chat_mod_settings != nullptr) { + delete chirp_chat_mod_settings; + } if(datv_demod_settings != nullptr) { delete datv_demod_settings; } @@ -219,9 +222,6 @@ SWGChannelSettings::cleanup() { if(interferometer_settings != nullptr) { delete interferometer_settings; } - if(lo_ra_mod_settings != nullptr) { - delete lo_ra_mod_settings; - } if(nfm_demod_settings != nullptr) { delete nfm_demod_settings; } @@ -295,6 +295,8 @@ SWGChannelSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&chirp_chat_demod_settings, pJson["ChirpChatDemodSettings"], "SWGChirpChatDemodSettings", "SWGChirpChatDemodSettings"); + ::SWGSDRangel::setValue(&chirp_chat_mod_settings, pJson["ChirpChatModSettings"], "SWGChirpChatModSettings", "SWGChirpChatModSettings"); + ::SWGSDRangel::setValue(&datv_demod_settings, pJson["DATVDemodSettings"], "SWGDATVDemodSettings", "SWGDATVDemodSettings"); ::SWGSDRangel::setValue(&dsd_demod_settings, pJson["DSDDemodSettings"], "SWGDSDDemodSettings", "SWGDSDDemodSettings"); @@ -309,8 +311,6 @@ SWGChannelSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&interferometer_settings, pJson["InterferometerSettings"], "SWGInterferometerSettings", "SWGInterferometerSettings"); - ::SWGSDRangel::setValue(&lo_ra_mod_settings, pJson["LoRaModSettings"], "SWGLoRaModSettings", "SWGLoRaModSettings"); - ::SWGSDRangel::setValue(&nfm_demod_settings, pJson["NFMDemodSettings"], "SWGNFMDemodSettings", "SWGNFMDemodSettings"); ::SWGSDRangel::setValue(&nfm_mod_settings, pJson["NFMModSettings"], "SWGNFMModSettings", "SWGNFMModSettings"); @@ -387,6 +387,9 @@ SWGChannelSettings::asJsonObject() { if((chirp_chat_demod_settings != nullptr) && (chirp_chat_demod_settings->isSet())){ toJsonValue(QString("ChirpChatDemodSettings"), chirp_chat_demod_settings, obj, QString("SWGChirpChatDemodSettings")); } + if((chirp_chat_mod_settings != nullptr) && (chirp_chat_mod_settings->isSet())){ + toJsonValue(QString("ChirpChatModSettings"), chirp_chat_mod_settings, obj, QString("SWGChirpChatModSettings")); + } if((datv_demod_settings != nullptr) && (datv_demod_settings->isSet())){ toJsonValue(QString("DATVDemodSettings"), datv_demod_settings, obj, QString("SWGDATVDemodSettings")); } @@ -408,9 +411,6 @@ SWGChannelSettings::asJsonObject() { if((interferometer_settings != nullptr) && (interferometer_settings->isSet())){ toJsonValue(QString("InterferometerSettings"), interferometer_settings, obj, QString("SWGInterferometerSettings")); } - if((lo_ra_mod_settings != nullptr) && (lo_ra_mod_settings->isSet())){ - toJsonValue(QString("LoRaModSettings"), lo_ra_mod_settings, obj, QString("SWGLoRaModSettings")); - } if((nfm_demod_settings != nullptr) && (nfm_demod_settings->isSet())){ toJsonValue(QString("NFMDemodSettings"), nfm_demod_settings, obj, QString("SWGNFMDemodSettings")); } @@ -571,6 +571,16 @@ SWGChannelSettings::setChirpChatDemodSettings(SWGChirpChatDemodSettings* chirp_c this->m_chirp_chat_demod_settings_isSet = true; } +SWGChirpChatModSettings* +SWGChannelSettings::getChirpChatModSettings() { + return chirp_chat_mod_settings; +} +void +SWGChannelSettings::setChirpChatModSettings(SWGChirpChatModSettings* chirp_chat_mod_settings) { + this->chirp_chat_mod_settings = chirp_chat_mod_settings; + this->m_chirp_chat_mod_settings_isSet = true; +} + SWGDATVDemodSettings* SWGChannelSettings::getDatvDemodSettings() { return datv_demod_settings; @@ -641,16 +651,6 @@ SWGChannelSettings::setInterferometerSettings(SWGInterferometerSettings* interfe this->m_interferometer_settings_isSet = true; } -SWGLoRaModSettings* -SWGChannelSettings::getLoRaModSettings() { - return lo_ra_mod_settings; -} -void -SWGChannelSettings::setLoRaModSettings(SWGLoRaModSettings* lo_ra_mod_settings) { - this->lo_ra_mod_settings = lo_ra_mod_settings; - this->m_lo_ra_mod_settings_isSet = true; -} - SWGNFMDemodSettings* SWGChannelSettings::getNfmDemodSettings() { return nfm_demod_settings; @@ -812,6 +812,9 @@ SWGChannelSettings::isSet(){ if(chirp_chat_demod_settings && chirp_chat_demod_settings->isSet()){ isObjectUpdated = true; break; } + if(chirp_chat_mod_settings && chirp_chat_mod_settings->isSet()){ + isObjectUpdated = true; break; + } if(datv_demod_settings && datv_demod_settings->isSet()){ isObjectUpdated = true; break; } @@ -833,9 +836,6 @@ SWGChannelSettings::isSet(){ if(interferometer_settings && interferometer_settings->isSet()){ isObjectUpdated = true; break; } - if(lo_ra_mod_settings && lo_ra_mod_settings->isSet()){ - isObjectUpdated = true; break; - } if(nfm_demod_settings && nfm_demod_settings->isSet()){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGChannelSettings.h b/swagger/sdrangel/code/qt5/client/SWGChannelSettings.h index 630f99bef..b7d6b6c38 100644 --- a/swagger/sdrangel/code/qt5/client/SWGChannelSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGChannelSettings.h @@ -30,6 +30,7 @@ #include "SWGBeamSteeringCWModSettings.h" #include "SWGChannelAnalyzerSettings.h" #include "SWGChirpChatDemodSettings.h" +#include "SWGChirpChatModSettings.h" #include "SWGDATVDemodSettings.h" #include "SWGDSDDemodSettings.h" #include "SWGFileSourceSettings.h" @@ -37,7 +38,6 @@ #include "SWGFreeDVModSettings.h" #include "SWGFreqTrackerSettings.h" #include "SWGInterferometerSettings.h" -#include "SWGLoRaModSettings.h" #include "SWGLocalSinkSettings.h" #include "SWGLocalSourceSettings.h" #include "SWGNFMDemodSettings.h" @@ -106,6 +106,9 @@ public: SWGChirpChatDemodSettings* getChirpChatDemodSettings(); void setChirpChatDemodSettings(SWGChirpChatDemodSettings* chirp_chat_demod_settings); + SWGChirpChatModSettings* getChirpChatModSettings(); + void setChirpChatModSettings(SWGChirpChatModSettings* chirp_chat_mod_settings); + SWGDATVDemodSettings* getDatvDemodSettings(); void setDatvDemodSettings(SWGDATVDemodSettings* datv_demod_settings); @@ -127,9 +130,6 @@ public: SWGInterferometerSettings* getInterferometerSettings(); void setInterferometerSettings(SWGInterferometerSettings* interferometer_settings); - SWGLoRaModSettings* getLoRaModSettings(); - void setLoRaModSettings(SWGLoRaModSettings* lo_ra_mod_settings); - SWGNFMDemodSettings* getNfmDemodSettings(); void setNfmDemodSettings(SWGNFMDemodSettings* nfm_demod_settings); @@ -206,6 +206,9 @@ private: SWGChirpChatDemodSettings* chirp_chat_demod_settings; bool m_chirp_chat_demod_settings_isSet; + SWGChirpChatModSettings* chirp_chat_mod_settings; + bool m_chirp_chat_mod_settings_isSet; + SWGDATVDemodSettings* datv_demod_settings; bool m_datv_demod_settings_isSet; @@ -227,9 +230,6 @@ private: SWGInterferometerSettings* interferometer_settings; bool m_interferometer_settings_isSet; - SWGLoRaModSettings* lo_ra_mod_settings; - bool m_lo_ra_mod_settings_isSet; - SWGNFMDemodSettings* nfm_demod_settings; bool m_nfm_demod_settings_isSet; diff --git a/swagger/sdrangel/code/qt5/client/SWGLoRaModReport.cpp b/swagger/sdrangel/code/qt5/client/SWGChirpChatModReport.cpp similarity index 82% rename from swagger/sdrangel/code/qt5/client/SWGLoRaModReport.cpp rename to swagger/sdrangel/code/qt5/client/SWGChirpChatModReport.cpp index d8c5abf4c..3480ab685 100644 --- a/swagger/sdrangel/code/qt5/client/SWGLoRaModReport.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGChirpChatModReport.cpp @@ -11,7 +11,7 @@ */ -#include "SWGLoRaModReport.h" +#include "SWGChirpChatModReport.h" #include "SWGHelpers.h" @@ -22,12 +22,12 @@ namespace SWGSDRangel { -SWGLoRaModReport::SWGLoRaModReport(QString* json) { +SWGChirpChatModReport::SWGChirpChatModReport(QString* json) { init(); this->fromJson(*json); } -SWGLoRaModReport::SWGLoRaModReport() { +SWGChirpChatModReport::SWGChirpChatModReport() { channel_power_db = 0.0f; m_channel_power_db_isSet = false; channel_sample_rate = 0; @@ -40,12 +40,12 @@ SWGLoRaModReport::SWGLoRaModReport() { m_total_time_ms_isSet = false; } -SWGLoRaModReport::~SWGLoRaModReport() { +SWGChirpChatModReport::~SWGChirpChatModReport() { this->cleanup(); } void -SWGLoRaModReport::init() { +SWGChirpChatModReport::init() { channel_power_db = 0.0f; m_channel_power_db_isSet = false; channel_sample_rate = 0; @@ -59,7 +59,7 @@ SWGLoRaModReport::init() { } void -SWGLoRaModReport::cleanup() { +SWGChirpChatModReport::cleanup() { @@ -67,8 +67,8 @@ SWGLoRaModReport::cleanup() { } -SWGLoRaModReport* -SWGLoRaModReport::fromJson(QString &json) { +SWGChirpChatModReport* +SWGChirpChatModReport::fromJson(QString &json) { QByteArray array (json.toStdString().c_str()); QJsonDocument doc = QJsonDocument::fromJson(array); QJsonObject jsonObject = doc.object(); @@ -77,7 +77,7 @@ SWGLoRaModReport::fromJson(QString &json) { } void -SWGLoRaModReport::fromJsonObject(QJsonObject &pJson) { +SWGChirpChatModReport::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&channel_power_db, pJson["channelPowerDB"], "float", ""); ::SWGSDRangel::setValue(&channel_sample_rate, pJson["channelSampleRate"], "qint32", ""); @@ -91,7 +91,7 @@ SWGLoRaModReport::fromJsonObject(QJsonObject &pJson) { } QString -SWGLoRaModReport::asJson () +SWGChirpChatModReport::asJson () { QJsonObject* obj = this->asJsonObject(); @@ -102,7 +102,7 @@ SWGLoRaModReport::asJson () } QJsonObject* -SWGLoRaModReport::asJsonObject() { +SWGChirpChatModReport::asJsonObject() { QJsonObject* obj = new QJsonObject(); if(m_channel_power_db_isSet){ obj->insert("channelPowerDB", QJsonValue(channel_power_db)); @@ -124,58 +124,58 @@ SWGLoRaModReport::asJsonObject() { } float -SWGLoRaModReport::getChannelPowerDb() { +SWGChirpChatModReport::getChannelPowerDb() { return channel_power_db; } void -SWGLoRaModReport::setChannelPowerDb(float channel_power_db) { +SWGChirpChatModReport::setChannelPowerDb(float channel_power_db) { this->channel_power_db = channel_power_db; this->m_channel_power_db_isSet = true; } qint32 -SWGLoRaModReport::getChannelSampleRate() { +SWGChirpChatModReport::getChannelSampleRate() { return channel_sample_rate; } void -SWGLoRaModReport::setChannelSampleRate(qint32 channel_sample_rate) { +SWGChirpChatModReport::setChannelSampleRate(qint32 channel_sample_rate) { this->channel_sample_rate = channel_sample_rate; this->m_channel_sample_rate_isSet = true; } float -SWGLoRaModReport::getSymbolTimeMs() { +SWGChirpChatModReport::getSymbolTimeMs() { return symbol_time_ms; } void -SWGLoRaModReport::setSymbolTimeMs(float symbol_time_ms) { +SWGChirpChatModReport::setSymbolTimeMs(float symbol_time_ms) { this->symbol_time_ms = symbol_time_ms; this->m_symbol_time_ms_isSet = true; } float -SWGLoRaModReport::getPayloadTimeMs() { +SWGChirpChatModReport::getPayloadTimeMs() { return payload_time_ms; } void -SWGLoRaModReport::setPayloadTimeMs(float payload_time_ms) { +SWGChirpChatModReport::setPayloadTimeMs(float payload_time_ms) { this->payload_time_ms = payload_time_ms; this->m_payload_time_ms_isSet = true; } float -SWGLoRaModReport::getTotalTimeMs() { +SWGChirpChatModReport::getTotalTimeMs() { return total_time_ms; } void -SWGLoRaModReport::setTotalTimeMs(float total_time_ms) { +SWGChirpChatModReport::setTotalTimeMs(float total_time_ms) { this->total_time_ms = total_time_ms; this->m_total_time_ms_isSet = true; } bool -SWGLoRaModReport::isSet(){ +SWGChirpChatModReport::isSet(){ bool isObjectUpdated = false; do{ if(m_channel_power_db_isSet){ diff --git a/swagger/sdrangel/code/qt5/client/SWGLoRaModReport.h b/swagger/sdrangel/code/qt5/client/SWGChirpChatModReport.h similarity index 87% rename from swagger/sdrangel/code/qt5/client/SWGLoRaModReport.h rename to swagger/sdrangel/code/qt5/client/SWGChirpChatModReport.h index 9b5d03e99..2fe57340e 100644 --- a/swagger/sdrangel/code/qt5/client/SWGLoRaModReport.h +++ b/swagger/sdrangel/code/qt5/client/SWGChirpChatModReport.h @@ -11,13 +11,13 @@ */ /* - * SWGLoRaModReport.h + * SWGChirpChatModReport.h * - * LoRaMod + * ChirpChatMod */ -#ifndef SWGLoRaModReport_H_ -#define SWGLoRaModReport_H_ +#ifndef SWGChirpChatModReport_H_ +#define SWGChirpChatModReport_H_ #include @@ -28,18 +28,18 @@ namespace SWGSDRangel { -class SWG_API SWGLoRaModReport: public SWGObject { +class SWG_API SWGChirpChatModReport: public SWGObject { public: - SWGLoRaModReport(); - SWGLoRaModReport(QString* json); - virtual ~SWGLoRaModReport(); + SWGChirpChatModReport(); + SWGChirpChatModReport(QString* json); + virtual ~SWGChirpChatModReport(); void init(); void cleanup(); virtual QString asJson () override; virtual QJsonObject* asJsonObject() override; virtual void fromJsonObject(QJsonObject &json) override; - virtual SWGLoRaModReport* fromJson(QString &jsonString) override; + virtual SWGChirpChatModReport* fromJson(QString &jsonString) override; float getChannelPowerDb(); void setChannelPowerDb(float channel_power_db); @@ -79,4 +79,4 @@ private: } -#endif /* SWGLoRaModReport_H_ */ +#endif /* SWGChirpChatModReport_H_ */ diff --git a/swagger/sdrangel/code/qt5/client/SWGLoRaModSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGChirpChatModSettings.cpp similarity index 84% rename from swagger/sdrangel/code/qt5/client/SWGLoRaModSettings.cpp rename to swagger/sdrangel/code/qt5/client/SWGChirpChatModSettings.cpp index d38cfbf17..04194b72a 100644 --- a/swagger/sdrangel/code/qt5/client/SWGLoRaModSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGChirpChatModSettings.cpp @@ -11,7 +11,7 @@ */ -#include "SWGLoRaModSettings.h" +#include "SWGChirpChatModSettings.h" #include "SWGHelpers.h" @@ -22,12 +22,12 @@ namespace SWGSDRangel { -SWGLoRaModSettings::SWGLoRaModSettings(QString* json) { +SWGChirpChatModSettings::SWGChirpChatModSettings(QString* json) { init(); this->fromJson(*json); } -SWGLoRaModSettings::SWGLoRaModSettings() { +SWGChirpChatModSettings::SWGChirpChatModSettings() { input_frequency_offset = 0L; m_input_frequency_offset_isSet = false; bandwidth_index = 0; @@ -102,12 +102,12 @@ SWGLoRaModSettings::SWGLoRaModSettings() { m_reverse_api_channel_index_isSet = false; } -SWGLoRaModSettings::~SWGLoRaModSettings() { +SWGChirpChatModSettings::~SWGChirpChatModSettings() { this->cleanup(); } void -SWGLoRaModSettings::init() { +SWGChirpChatModSettings::init() { input_frequency_offset = 0L; m_input_frequency_offset_isSet = false; bandwidth_index = 0; @@ -183,7 +183,7 @@ SWGLoRaModSettings::init() { } void -SWGLoRaModSettings::cleanup() { +SWGChirpChatModSettings::cleanup() { @@ -258,8 +258,8 @@ SWGLoRaModSettings::cleanup() { } -SWGLoRaModSettings* -SWGLoRaModSettings::fromJson(QString &json) { +SWGChirpChatModSettings* +SWGChirpChatModSettings::fromJson(QString &json) { QByteArray array (json.toStdString().c_str()); QJsonDocument doc = QJsonDocument::fromJson(array); QJsonObject jsonObject = doc.object(); @@ -268,7 +268,7 @@ SWGLoRaModSettings::fromJson(QString &json) { } void -SWGLoRaModSettings::fromJsonObject(QJsonObject &pJson) { +SWGChirpChatModSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", ""); ::SWGSDRangel::setValue(&bandwidth_index, pJson["bandwidthIndex"], "qint32", ""); @@ -344,7 +344,7 @@ SWGLoRaModSettings::fromJsonObject(QJsonObject &pJson) { } QString -SWGLoRaModSettings::asJson () +SWGChirpChatModSettings::asJson () { QJsonObject* obj = this->asJsonObject(); @@ -355,7 +355,7 @@ SWGLoRaModSettings::asJson () } QJsonObject* -SWGLoRaModSettings::asJsonObject() { +SWGChirpChatModSettings::asJsonObject() { QJsonObject* obj = new QJsonObject(); if(m_input_frequency_offset_isSet){ obj->insert("inputFrequencyOffset", QJsonValue(input_frequency_offset)); @@ -470,368 +470,368 @@ SWGLoRaModSettings::asJsonObject() { } qint64 -SWGLoRaModSettings::getInputFrequencyOffset() { +SWGChirpChatModSettings::getInputFrequencyOffset() { return input_frequency_offset; } void -SWGLoRaModSettings::setInputFrequencyOffset(qint64 input_frequency_offset) { +SWGChirpChatModSettings::setInputFrequencyOffset(qint64 input_frequency_offset) { this->input_frequency_offset = input_frequency_offset; this->m_input_frequency_offset_isSet = true; } qint32 -SWGLoRaModSettings::getBandwidthIndex() { +SWGChirpChatModSettings::getBandwidthIndex() { return bandwidth_index; } void -SWGLoRaModSettings::setBandwidthIndex(qint32 bandwidth_index) { +SWGChirpChatModSettings::setBandwidthIndex(qint32 bandwidth_index) { this->bandwidth_index = bandwidth_index; this->m_bandwidth_index_isSet = true; } qint32 -SWGLoRaModSettings::getSpreadFactor() { +SWGChirpChatModSettings::getSpreadFactor() { return spread_factor; } void -SWGLoRaModSettings::setSpreadFactor(qint32 spread_factor) { +SWGChirpChatModSettings::setSpreadFactor(qint32 spread_factor) { this->spread_factor = spread_factor; this->m_spread_factor_isSet = true; } qint32 -SWGLoRaModSettings::getDeBits() { +SWGChirpChatModSettings::getDeBits() { return de_bits; } void -SWGLoRaModSettings::setDeBits(qint32 de_bits) { +SWGChirpChatModSettings::setDeBits(qint32 de_bits) { this->de_bits = de_bits; this->m_de_bits_isSet = true; } qint32 -SWGLoRaModSettings::getPreambleChirps() { +SWGChirpChatModSettings::getPreambleChirps() { return preamble_chirps; } void -SWGLoRaModSettings::setPreambleChirps(qint32 preamble_chirps) { +SWGChirpChatModSettings::setPreambleChirps(qint32 preamble_chirps) { this->preamble_chirps = preamble_chirps; this->m_preamble_chirps_isSet = true; } qint32 -SWGLoRaModSettings::getQuietMillis() { +SWGChirpChatModSettings::getQuietMillis() { return quiet_millis; } void -SWGLoRaModSettings::setQuietMillis(qint32 quiet_millis) { +SWGChirpChatModSettings::setQuietMillis(qint32 quiet_millis) { this->quiet_millis = quiet_millis; this->m_quiet_millis_isSet = true; } qint32 -SWGLoRaModSettings::getSyncWord() { +SWGChirpChatModSettings::getSyncWord() { return sync_word; } void -SWGLoRaModSettings::setSyncWord(qint32 sync_word) { +SWGChirpChatModSettings::setSyncWord(qint32 sync_word) { this->sync_word = sync_word; this->m_sync_word_isSet = true; } qint32 -SWGLoRaModSettings::getChannelMute() { +SWGChirpChatModSettings::getChannelMute() { return channel_mute; } void -SWGLoRaModSettings::setChannelMute(qint32 channel_mute) { +SWGChirpChatModSettings::setChannelMute(qint32 channel_mute) { this->channel_mute = channel_mute; this->m_channel_mute_isSet = true; } qint32 -SWGLoRaModSettings::getCodingScheme() { +SWGChirpChatModSettings::getCodingScheme() { return coding_scheme; } void -SWGLoRaModSettings::setCodingScheme(qint32 coding_scheme) { +SWGChirpChatModSettings::setCodingScheme(qint32 coding_scheme) { this->coding_scheme = coding_scheme; this->m_coding_scheme_isSet = true; } qint32 -SWGLoRaModSettings::getNbParityBits() { +SWGChirpChatModSettings::getNbParityBits() { return nb_parity_bits; } void -SWGLoRaModSettings::setNbParityBits(qint32 nb_parity_bits) { +SWGChirpChatModSettings::setNbParityBits(qint32 nb_parity_bits) { this->nb_parity_bits = nb_parity_bits; this->m_nb_parity_bits_isSet = true; } qint32 -SWGLoRaModSettings::getHasCrc() { +SWGChirpChatModSettings::getHasCrc() { return has_crc; } void -SWGLoRaModSettings::setHasCrc(qint32 has_crc) { +SWGChirpChatModSettings::setHasCrc(qint32 has_crc) { this->has_crc = has_crc; this->m_has_crc_isSet = true; } qint32 -SWGLoRaModSettings::getHasHeader() { +SWGChirpChatModSettings::getHasHeader() { return has_header; } void -SWGLoRaModSettings::setHasHeader(qint32 has_header) { +SWGChirpChatModSettings::setHasHeader(qint32 has_header) { this->has_header = has_header; this->m_has_header_isSet = true; } QString* -SWGLoRaModSettings::getMyCall() { +SWGChirpChatModSettings::getMyCall() { return my_call; } void -SWGLoRaModSettings::setMyCall(QString* my_call) { +SWGChirpChatModSettings::setMyCall(QString* my_call) { this->my_call = my_call; this->m_my_call_isSet = true; } QString* -SWGLoRaModSettings::getUrCall() { +SWGChirpChatModSettings::getUrCall() { return ur_call; } void -SWGLoRaModSettings::setUrCall(QString* ur_call) { +SWGChirpChatModSettings::setUrCall(QString* ur_call) { this->ur_call = ur_call; this->m_ur_call_isSet = true; } QString* -SWGLoRaModSettings::getMyLoc() { +SWGChirpChatModSettings::getMyLoc() { return my_loc; } void -SWGLoRaModSettings::setMyLoc(QString* my_loc) { +SWGChirpChatModSettings::setMyLoc(QString* my_loc) { this->my_loc = my_loc; this->m_my_loc_isSet = true; } QString* -SWGLoRaModSettings::getMyRpt() { +SWGChirpChatModSettings::getMyRpt() { return my_rpt; } void -SWGLoRaModSettings::setMyRpt(QString* my_rpt) { +SWGChirpChatModSettings::setMyRpt(QString* my_rpt) { this->my_rpt = my_rpt; this->m_my_rpt_isSet = true; } qint32 -SWGLoRaModSettings::getMessageType() { +SWGChirpChatModSettings::getMessageType() { return message_type; } void -SWGLoRaModSettings::setMessageType(qint32 message_type) { +SWGChirpChatModSettings::setMessageType(qint32 message_type) { this->message_type = message_type; this->m_message_type_isSet = true; } QString* -SWGLoRaModSettings::getBeaconMessage() { +SWGChirpChatModSettings::getBeaconMessage() { return beacon_message; } void -SWGLoRaModSettings::setBeaconMessage(QString* beacon_message) { +SWGChirpChatModSettings::setBeaconMessage(QString* beacon_message) { this->beacon_message = beacon_message; this->m_beacon_message_isSet = true; } QString* -SWGLoRaModSettings::getCqMessage() { +SWGChirpChatModSettings::getCqMessage() { return cq_message; } void -SWGLoRaModSettings::setCqMessage(QString* cq_message) { +SWGChirpChatModSettings::setCqMessage(QString* cq_message) { this->cq_message = cq_message; this->m_cq_message_isSet = true; } QString* -SWGLoRaModSettings::getReplyMessage() { +SWGChirpChatModSettings::getReplyMessage() { return reply_message; } void -SWGLoRaModSettings::setReplyMessage(QString* reply_message) { +SWGChirpChatModSettings::setReplyMessage(QString* reply_message) { this->reply_message = reply_message; this->m_reply_message_isSet = true; } QString* -SWGLoRaModSettings::getReportMessage() { +SWGChirpChatModSettings::getReportMessage() { return report_message; } void -SWGLoRaModSettings::setReportMessage(QString* report_message) { +SWGChirpChatModSettings::setReportMessage(QString* report_message) { this->report_message = report_message; this->m_report_message_isSet = true; } QString* -SWGLoRaModSettings::getReplyReportMessage() { +SWGChirpChatModSettings::getReplyReportMessage() { return reply_report_message; } void -SWGLoRaModSettings::setReplyReportMessage(QString* reply_report_message) { +SWGChirpChatModSettings::setReplyReportMessage(QString* reply_report_message) { this->reply_report_message = reply_report_message; this->m_reply_report_message_isSet = true; } QString* -SWGLoRaModSettings::getRrrMessage() { +SWGChirpChatModSettings::getRrrMessage() { return rrr_message; } void -SWGLoRaModSettings::setRrrMessage(QString* rrr_message) { +SWGChirpChatModSettings::setRrrMessage(QString* rrr_message) { this->rrr_message = rrr_message; this->m_rrr_message_isSet = true; } QString* -SWGLoRaModSettings::getMessage73() { +SWGChirpChatModSettings::getMessage73() { return message73; } void -SWGLoRaModSettings::setMessage73(QString* message73) { +SWGChirpChatModSettings::setMessage73(QString* message73) { this->message73 = message73; this->m_message73_isSet = true; } QString* -SWGLoRaModSettings::getQsoTextMessage() { +SWGChirpChatModSettings::getQsoTextMessage() { return qso_text_message; } void -SWGLoRaModSettings::setQsoTextMessage(QString* qso_text_message) { +SWGChirpChatModSettings::setQsoTextMessage(QString* qso_text_message) { this->qso_text_message = qso_text_message; this->m_qso_text_message_isSet = true; } QString* -SWGLoRaModSettings::getTextMessage() { +SWGChirpChatModSettings::getTextMessage() { return text_message; } void -SWGLoRaModSettings::setTextMessage(QString* text_message) { +SWGChirpChatModSettings::setTextMessage(QString* text_message) { this->text_message = text_message; this->m_text_message_isSet = true; } QList* -SWGLoRaModSettings::getBytesMessage() { +SWGChirpChatModSettings::getBytesMessage() { return bytes_message; } void -SWGLoRaModSettings::setBytesMessage(QList* bytes_message) { +SWGChirpChatModSettings::setBytesMessage(QList* bytes_message) { this->bytes_message = bytes_message; this->m_bytes_message_isSet = true; } qint32 -SWGLoRaModSettings::getMessageRepeat() { +SWGChirpChatModSettings::getMessageRepeat() { return message_repeat; } void -SWGLoRaModSettings::setMessageRepeat(qint32 message_repeat) { +SWGChirpChatModSettings::setMessageRepeat(qint32 message_repeat) { this->message_repeat = message_repeat; this->m_message_repeat_isSet = true; } qint32 -SWGLoRaModSettings::getRgbColor() { +SWGChirpChatModSettings::getRgbColor() { return rgb_color; } void -SWGLoRaModSettings::setRgbColor(qint32 rgb_color) { +SWGChirpChatModSettings::setRgbColor(qint32 rgb_color) { this->rgb_color = rgb_color; this->m_rgb_color_isSet = true; } QString* -SWGLoRaModSettings::getTitle() { +SWGChirpChatModSettings::getTitle() { return title; } void -SWGLoRaModSettings::setTitle(QString* title) { +SWGChirpChatModSettings::setTitle(QString* title) { this->title = title; this->m_title_isSet = true; } qint32 -SWGLoRaModSettings::getStreamIndex() { +SWGChirpChatModSettings::getStreamIndex() { return stream_index; } void -SWGLoRaModSettings::setStreamIndex(qint32 stream_index) { +SWGChirpChatModSettings::setStreamIndex(qint32 stream_index) { this->stream_index = stream_index; this->m_stream_index_isSet = true; } qint32 -SWGLoRaModSettings::getUseReverseApi() { +SWGChirpChatModSettings::getUseReverseApi() { return use_reverse_api; } void -SWGLoRaModSettings::setUseReverseApi(qint32 use_reverse_api) { +SWGChirpChatModSettings::setUseReverseApi(qint32 use_reverse_api) { this->use_reverse_api = use_reverse_api; this->m_use_reverse_api_isSet = true; } QString* -SWGLoRaModSettings::getReverseApiAddress() { +SWGChirpChatModSettings::getReverseApiAddress() { return reverse_api_address; } void -SWGLoRaModSettings::setReverseApiAddress(QString* reverse_api_address) { +SWGChirpChatModSettings::setReverseApiAddress(QString* reverse_api_address) { this->reverse_api_address = reverse_api_address; this->m_reverse_api_address_isSet = true; } qint32 -SWGLoRaModSettings::getReverseApiPort() { +SWGChirpChatModSettings::getReverseApiPort() { return reverse_api_port; } void -SWGLoRaModSettings::setReverseApiPort(qint32 reverse_api_port) { +SWGChirpChatModSettings::setReverseApiPort(qint32 reverse_api_port) { this->reverse_api_port = reverse_api_port; this->m_reverse_api_port_isSet = true; } qint32 -SWGLoRaModSettings::getReverseApiDeviceIndex() { +SWGChirpChatModSettings::getReverseApiDeviceIndex() { return reverse_api_device_index; } void -SWGLoRaModSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) { +SWGChirpChatModSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) { this->reverse_api_device_index = reverse_api_device_index; this->m_reverse_api_device_index_isSet = true; } qint32 -SWGLoRaModSettings::getReverseApiChannelIndex() { +SWGChirpChatModSettings::getReverseApiChannelIndex() { return reverse_api_channel_index; } void -SWGLoRaModSettings::setReverseApiChannelIndex(qint32 reverse_api_channel_index) { +SWGChirpChatModSettings::setReverseApiChannelIndex(qint32 reverse_api_channel_index) { this->reverse_api_channel_index = reverse_api_channel_index; this->m_reverse_api_channel_index_isSet = true; } bool -SWGLoRaModSettings::isSet(){ +SWGChirpChatModSettings::isSet(){ bool isObjectUpdated = false; do{ if(m_input_frequency_offset_isSet){ diff --git a/swagger/sdrangel/code/qt5/client/SWGLoRaModSettings.h b/swagger/sdrangel/code/qt5/client/SWGChirpChatModSettings.h similarity index 94% rename from swagger/sdrangel/code/qt5/client/SWGLoRaModSettings.h rename to swagger/sdrangel/code/qt5/client/SWGChirpChatModSettings.h index 0cdb40a6d..ece18ab60 100644 --- a/swagger/sdrangel/code/qt5/client/SWGLoRaModSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGChirpChatModSettings.h @@ -11,13 +11,13 @@ */ /* - * SWGLoRaModSettings.h + * SWGChirpChatModSettings.h * - * LoRaMod + * ChirpChatMod */ -#ifndef SWGLoRaModSettings_H_ -#define SWGLoRaModSettings_H_ +#ifndef SWGChirpChatModSettings_H_ +#define SWGChirpChatModSettings_H_ #include @@ -30,18 +30,18 @@ namespace SWGSDRangel { -class SWG_API SWGLoRaModSettings: public SWGObject { +class SWG_API SWGChirpChatModSettings: public SWGObject { public: - SWGLoRaModSettings(); - SWGLoRaModSettings(QString* json); - virtual ~SWGLoRaModSettings(); + SWGChirpChatModSettings(); + SWGChirpChatModSettings(QString* json); + virtual ~SWGChirpChatModSettings(); void init(); void cleanup(); virtual QString asJson () override; virtual QJsonObject* asJsonObject() override; virtual void fromJsonObject(QJsonObject &json) override; - virtual SWGLoRaModSettings* fromJson(QString &jsonString) override; + virtual SWGChirpChatModSettings* fromJson(QString &jsonString) override; qint64 getInputFrequencyOffset(); void setInputFrequencyOffset(qint64 input_frequency_offset); @@ -267,4 +267,4 @@ private: } -#endif /* SWGLoRaModSettings_H_ */ +#endif /* SWGChirpChatModSettings_H_ */ diff --git a/swagger/sdrangel/code/qt5/client/SWGModelFactory.h b/swagger/sdrangel/code/qt5/client/SWGModelFactory.h index abf2db718..38e1fc247 100644 --- a/swagger/sdrangel/code/qt5/client/SWGModelFactory.h +++ b/swagger/sdrangel/code/qt5/client/SWGModelFactory.h @@ -53,6 +53,8 @@ #include "SWGChannelsDetail.h" #include "SWGChirpChatDemodReport.h" #include "SWGChirpChatDemodSettings.h" +#include "SWGChirpChatModReport.h" +#include "SWGChirpChatModSettings.h" #include "SWGCommand.h" #include "SWGComplex.h" #include "SWGDATVDemodSettings.h" @@ -103,8 +105,6 @@ #include "SWGLimeSdrInputSettings.h" #include "SWGLimeSdrOutputReport.h" #include "SWGLimeSdrOutputSettings.h" -#include "SWGLoRaModReport.h" -#include "SWGLoRaModSettings.h" #include "SWGLocalInputReport.h" #include "SWGLocalInputSettings.h" #include "SWGLocalOutputReport.h" @@ -299,6 +299,12 @@ namespace SWGSDRangel { if(QString("SWGChirpChatDemodSettings").compare(type) == 0) { return new SWGChirpChatDemodSettings(); } + if(QString("SWGChirpChatModReport").compare(type) == 0) { + return new SWGChirpChatModReport(); + } + if(QString("SWGChirpChatModSettings").compare(type) == 0) { + return new SWGChirpChatModSettings(); + } if(QString("SWGCommand").compare(type) == 0) { return new SWGCommand(); } @@ -449,12 +455,6 @@ namespace SWGSDRangel { if(QString("SWGLimeSdrOutputSettings").compare(type) == 0) { return new SWGLimeSdrOutputSettings(); } - if(QString("SWGLoRaModReport").compare(type) == 0) { - return new SWGLoRaModReport(); - } - if(QString("SWGLoRaModSettings").compare(type) == 0) { - return new SWGLoRaModSettings(); - } if(QString("SWGLocalInputReport").compare(type) == 0) { return new SWGLocalInputReport(); }