Merge branch 'master' into testing

testing
Simon 3 years ago
commit c70711deac

@ -27,6 +27,7 @@ build-dev: # This job runs in the build stage, which runs first.
#- docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY #- docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t hacknix/freedmr:development-latest -t $CI_REGISTRY/hacknix/freedmr:development-latest --platform linux/arm/v7,linux/amd64,linux/i386,linux/arm64 --push . - docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t hacknix/freedmr:development-latest -t $CI_REGISTRY/hacknix/freedmr:development-latest --platform linux/arm/v7,linux/amd64,linux/i386,linux/arm64 --push .
# - docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t hacknix/freedmr:development-latest -t $CI_REGISTRY/hacknix/freedmr:development-latest --platform linux/amd64,linux/i386 --push .
- echo "Compile complete." - echo "Compile complete."
@ -63,7 +64,7 @@ build-debug: # This job runs in the build stage, which runs first.
script: script:
- echo "Compiling the code..." - echo "Compiling the code..."
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker buildx build --no-cache -f Dockerfile-ci -t gitlab.hacknix.net:5050/hacknix/freedmr:debug --platform linux/amd64 --push . - docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t gitlab.hacknix.net:5050/hacknix/freedmr:debug --platform linux/amd64 --push .
only: only:
- debug - debug
@ -75,6 +76,7 @@ build-release: # This job runs in the build stage, which runs first.
- echo "Compiling the code..." - echo "Compiling the code..."
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t hacknix/freedmr:latest -t gitlab.hacknix.net:5050/hacknix/freedmr:latest -t hacknix/$CI_COMMIT_TAG-with-proxy -t gitlab.hacknix.net:5050/hacknix/freedmr:$CI_COMMIT_TAG-with-proxy -t hacknix/freedmr:development-latest -t gitlab.hacknix.net:5050/hacknix/freedmr:development-latest --platform linux/arm/v7,linux/amd64,linux/i386,linux/arm64 --push . - docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t hacknix/freedmr:latest -t gitlab.hacknix.net:5050/hacknix/freedmr:latest -t hacknix/$CI_COMMIT_TAG-with-proxy -t gitlab.hacknix.net:5050/hacknix/freedmr:$CI_COMMIT_TAG-with-proxy -t hacknix/freedmr:development-latest -t gitlab.hacknix.net:5050/hacknix/freedmr:development-latest --platform linux/arm/v7,linux/amd64,linux/i386,linux/arm64 --push .
#- docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t hacknix/freedmr:latest -t gitlab.hacknix.net:5050/hacknix/freedmr:latest -t hacknix/$CI_COMMIT_TAG-with-proxy -t gitlab.hacknix.net:5050/hacknix/freedmr:$CI_COMMIT_TAG-with-proxy -t hacknix/freedmr:development-latest -t gitlab.hacknix.net:5050/hacknix/freedmr:development-latest --platform linux/amd64,linux/i386 --push .

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,3 +1,4 @@
úò†@tŠ;û%Œ¥æds*Þ‚ÇŠÅfu”Ú OüÕê BPlŒùÅG«šéãPÐjQ~ç¸<C3A7>ñ¿Ø e½æ<C2BD>P "t­ÁÀV.%E¿Æ…B>,5g®àÑ`>FGq¾Á×°t¸GQ<47>õ åÕG‰eC™á‡¶qçQš½ñmÚ0e¬ÀDL7³aa» P‰¦fp­¤Tu´eW­áP\b¿a@ËM(øH1ÞePÄÉ[SØBúj5Ûã°¹E:e?#¹ÅnH«Yo$ŽY&ëð,\J}úp:-…K<E280A6>Øb__+jò õ¿´<C2BF>MÓiŸ™<Ÿ<>Ý<08>ÅDënTçà?*~Ùºó|ÛÍi ÷¹ÇCEMû9€ÅsGrͳ…ÇD`fWcºÑÄ¢$C>ÑPC•ÅbA!GB«J5^©ÛÑFuz
?—ÞiZZ]ä¯ÈØô±x_Ä EÚ²_þQÆ"Tøà|Ëc[â'tú[眄BžÚÂÓ…n'”øÃ ­,—SÞÙõ0Т m9í_ÓE *ø ÂÎÔ{{<>Dd”ˆ 1á¸Õ1½hq2'·ŠÅ”A(2f4ÇàPÖî!EÔÕƺhq#'¦ŠÄ„rB­#SöǘAüESã™a™3ßecÑ<63>XúUã&wœUEfàerÆÉ@È{€ÐI1¦'ræi„Ñ}FÒduå­TØ[f‰Bã ìyˆUœ&,á“‹\Þm{óK4©E^NŸa®ï+`æQb+ü \ yÖ:°ò+£.ðbÛÛë.¶ Õ÷ü™€õ™ñ<_ÌÁãñaàÏ'ìà8ûÔ9às%] x•ÖmÎÙŸ°+/¤'д?§aÔR
WÍXä<EFBFBD>Y.·nz<6E>M¶G4ò.VÀª¡Rž_ 9R¬lô¯i,Ã,³¨äs™8“!³È(jyjÒqžÄ¿4`© ¶nZØ]•7d|Ö,Ö­J™I“.óHŸÿiœÑóÀuöúX¶ó°²‡Bò&ëyAüW†s?Â…âW ¥WR­çj²þ¥C³ù†|€ì†w—± "ä{àFvðàü[ó.¦RÔ#
5•¢)”>—…‡/x<>ÖSiYÁRžÐù ©<08> }…_W…¢Lœ†¢fƒD }<7D>¢ÇDàF8×S¥0 MUJÓM>åö‡<.> (Zš[†\pælt/énãB[‚‚“Ù\Ò`C]àà¢øH±oRN“|è=HòO\ô1Á÷m:<3A>’ÅÙ‰h·JŸÇZ<C387>¢38öÔ~bt<ñà"ê7¹¹¦<37>gÚpâs2Å#¦•Ê£0z¹<7A>ñÚ¢c3>ϸƒ

Binary file not shown.

Binary file not shown.

@ -1,2 +1,4 @@
ÆÁb €÷è±ñ¦dgƒCKtª±È!pÑUæ¹å2 Ch¯*´ú€Ap,¼Í<C2BC>çÇeqHÿ @È}<7D>šÙ/‡.tîg žû½*Pé!¿Š<E280B9>K5ûe<>­¨ò>RéZ%êÆƒè$ªH'lšË<C5A1>¬ÃC`·ÉDÆÑ„A‡”«ïð<C3AF>Gèž7oÏу¾¨0]×e<C397>%æ¼Gë¡Ób¦!£ ¡ õE¢eäŽPëõÅ>á'²œ(€—¥3»Ôë—:Ƈgú­ªe!ïý®k|PkI¦ïèý:œ›_n²¬ïÊ4K_öÈôN&æ Jfêª[Ø6¤d0Ÿûù<C3BB>î8ù#f³ßA«ZW8?Í%c»X` Ì·ÐT!qWM%š[ |dÊ¿ôˆÅGwS^è ô¹åep|ßmÄ™çgGqmë„ú‚!$ù<>ã@é}혽.‡?Vîf/ßÿ½*Ts­`'Ø/Jž+Q½`GéPê;#€+C ]DëcB¡ž ®Âc%p·bð÷4gJÀTWïÒ£EØÿ7M‰µÁ'œ …| ÿ Ï<;áï9õAáaeü¹Ñ³'â¦Ø%sƒ^£#X7P …†Ãq@¿T/:Ɔgú­ªgˆ»¤+ìÐï-ÐyëëYªÂÙHÈoZ< ;Y9Ö¢¹¢Ì/lcˆ<1B>ºjàÙ[=Ñî<ÿE`ã³<C3A3>æs
:L¾tÞþ*ÿzßw­E0;­8WŒNüg«HÝ=rÒú<C392><C3BA>zYÏ\uï"^g'*¿xTÐ¥lïö9<C3B6>F”Ô|ï9@ÜHƒ÷lçyÍσÃ@æg q†Jå3G:þ„zc;7Ù¬(<28>o¥0ìr<>•JiøqéÙ†1vÎ+šA ûaeãJ׊¼;éBGóXàŽ¾ÚWÚB_÷~ù¥<17>Á°]É83Ǽãç ½69CGú}Ï5
ê’'#Jû=>àkúYé,2ã9Ìz¾ ÊÏ#yè
k &÷[Ëâ5*"-ûÃXœ¢YDÃûØA¯EÍ4Ë´yˆ±dͼý9<C3BD>¤å' Nû×A

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,2 +0,0 @@
JНА7░╝1-&яЕ\Po-bW8┴╘╧ФCБ1 ┬И╩┤Nv,╗а┤▄{╫├|ч ≤!рМ%г (uЭlFиNЕДЩu╧,дй╢─b▀OёCM╥Ьс─⌡$V├]RR╩gO└б▄┤гFQ▄║&╞0ё!ы█ШО$B-БxкПЦ^А╚║║з│╦nЦ┴:╘КH²0 !*с ├5°^=╖Н│'ВфHC╦╩┤Mj∙-W┼≈Аюу(▐:DЭk╘U╦yмL6÷yeТА╧╣й дhЮПй┤╙e╖,О╟Ч▒2iв0yТб▄╠И└p
m╡┼┴┐П╝n°ао│■╗{и+▐8OgУ┼oКaХ jй╒R'О╜6▐⌡1╜X2*Мм╣╘IФePlАК

Binary file not shown.

@ -1,4 +0,0 @@
Τpγa0­l9φπ 膕Aμ@/«ΐCΕeΝψζ=sy=Ό”=<3D>ί#DZΤό7ζυC;#v¨|<7C> 7 <0F>bϊΘΣ,S;DωO-BPEGκ· \<5C>‰.s‰Ϋ@ϊΞ&¬¥<>«ρΧWΝd*ψ<>©Pdήn"Ϊy‡ςΘFΨmrGγθQYΐ><3E>)V|αΟΟ•PνΗƒu ·λΌ•δwT]ά§sΡΞ½nυ•_x<1B>ι<EFBFBD><EFBFBD>sN
<EFBFBD>νςxήI( 2A²J
Ω’Ζ
ίh¥c»΅δ…µ,Σ|U½5<>µ[Ο~'<27>6Hudjύ.p°<70><C2B0>Ο<[JρP £ν*<2A>-ίθ&+”.ξ{ε¤.<18> }΄NΠζj/n°‡ UΜΝ9hM$δyκ)Ν~jJ„·"δQ~*Ώn<CE8F>δSΑqS­¬‡·<7F>βP6Νd pβ,„BQγ5zgΕtH2οΥ[0s‰

@ -1,2 +0,0 @@
¶FÆ <¦\—È€p~­ÇÁžƒP?p,èøÇ„6¨W$8 ‰…Àw¿ ô.;Ø=ÀaÕTÈ¿«~„!ÖM§¹7ü;Ä'µ™ç%†*à„ËçS ©8¼®õ™ÐÔs¬HÌ«£<06>9®%´P@ØXE™áØ`É8ÀOt!
xF¢¹­d ®áRA…¹vØH¥‡«™ß• îÁ£dÎÚFSoîñ€‰¬qJjÂv¾B<C2BE>«(—k…6zØC™]û5Â9wÝ“#…ê€!(Œªçx˜ê"³AÈ ËÖ׬Ÿ³¹5/)…wþ©¿)¿øðl«ºXÑj¾Ÿ[`J†=AƒÇÀ?ðbѯÿÀ=f âß}<‰´/¿6<C2BF>°¨»”Îm¹÷9­9tþJŽeˆjß]ue|R'†mˆBÙ-Mƒñv/ÙCYÍt¶àeØ.<2E>uÑ¥ Á丹÷R-»†Ã<07>8ñ( Ó´§ž°U{Ži€5æÇÆ·«™_¦3ÀJ„úT ŽØ¸öA@‡äÐøàl4åÿ/r&»qka|6ú¤ÅÜÝeT'7

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,2 +0,0 @@
€^Β64Κυkψφ€tpHGλΔ9£{D0<44>µθ€ >έ¬ΑO\ΑdvK‡¦ Oo ϊΙ―U:ic_χψ®ς<C2AE>Ο*uσ©*ύ©C'ηΈρ<CE88>ζΑicjK<6A>†M”Ε@¬hΏνΟ /<2F>•…!nqΏ@Fο YΚXγ@·Μ…Ω<>F…‡ΈDΨ“ΊF'KθP<>Φ;U<>-<18><>r―#r§δ<C2A7> 4h@!EεΩπ¤&XS—ά¤AY*Xμ7<CEBC>Ve YvΊϊΕµΣΔz3<7A>ΚM]<5D>ki<6B>„¬Π/<<3C>ΘξΑΥ Ο*χΫ…τά―€Tk¦ψ…µj+Ρ<‚Ψώ!΅]<5D>Jm<4A>¤<EFBFBD>ρXΉnkοΜΣH<CEA3>/OΤX&ό?«jξƒΥΛUJΩ
Ο,8|<08>-ιgω?d¤1¥Ff—)·ζ„ „bfΔm§ς±6΅@&

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,5 +0,0 @@
´Ø¢2KÿˆÐXU†\œÓ~¯|É[#ºSIA|˜pë}ÝÈ<C39D> çFºCÙŒº¥úépŸruÙI¨K^g+‡°ê+/mÀ¿ÜŒ8 +ÅÚ—&šAY7H7¼Ù;'g,þåj˜ b2¸¨p©»ouTC»»SgÇ\tFA<46>ýVÕLUDVŒÛ!aÔnWdRϾd÷-%#S˜€§6/ YRT]JÆÃuzÔã­
ã ÐyO«#~Y“œ[Aãîû²û˜ 'ÝïÉ:O"({F&<26>ùøZF'ïûOìgMB¼öŠÇ%yÄ(åfZÁñš.ËÄf8ˆ/;/lOÅξ<C38E>\}]<5D>ɺ1
(Il^Þ+fQû*õBN¨hX¶ÐfH‰‡F~ ×#NÁ¡ÿÓ<C3BF>Õ+B¦=G~X<vêåpÃYJ$XvÌÏ¿(]uD#<23>ùe3ÖNffÿ¹R@ƒ 5 %Þò†o?c·™Ïá J}Æ™µ‚ p9/dX©¡»sñ.mDÿ«}õé„“Jzë“ñ
¿èI¥ÊŒsP
<EFBFBD>¨ž`j²Mélɸâ—Ã~ØnªþÃÅQ•´ˆ5kH.ÑãwÃè×àŒ<C3A0>·[%ùÛäÒÈÕ=óÆ0™ ÁwRôüéÍ?®<>£liydž5£bu6ü”äEsK‰âv

Binary file not shown.

@ -1,2 +0,0 @@
ŠN¦eà(çí ª{ÆA" iÒÉÁæ¨Isú˜¹»¹•âš ó}‰%çp·Í[¥š&‡0¼#ÍäͲzâš1ì<31>¢iµº}&7ÑÅÐàˆc­Ü9¥AÝ!´ì¦Aܵ §þ>I_«êÑe>*m® ê«§m!e/˧±üvC"(Ìùp«úBÙYØÇ¢Ü¸>R<>wúcèzùÀ’‹&fºEC¬†<0F><>ÜeÖükCî SG:%Í .HoÖ3Á÷<C381>J/.<2E> ‡0½ß}nÃg ]áó´„é s ¬Ëçmh;މýØìe\}¢Éª¾3_Nh Ê”4¥H—-FÚ°£À—x vªµ·Ðç|² qß³Ÿ9?‰,@™³ŸKc:Œ+t¾MÜc<C39C> [Ý~¤Poâ¬å&‡ö)ƾ av~BLì,á¥8Èo…§¦©¤lœÈ¼h<C2BC> šën§kÉÁp
F=ºòåcâ%%¨­ç

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1 +0,0 @@
«çÆñBÄõKsôÞ¢ñ9ÉðÑ<EFBFBD>Ì~<7E>WŸÝx|2Sú_Ü™<C39C>;àK«.ÜÜ­Ê;E.aŸiëUÞdKÝ<4B>þ*5Ë2b¿º¨à^øF¾œÒ]gÜaÃøÓC‰<<12>žG®úwü«íæjNuFA¾½sAÃ?`'×½ðÊç³:F™àëçj‡Gê•ç<E280A2>õŒ d<>h¨3ÜX™kÒØ``á™Jº+óÓˆ‘=³ê,ãÏk<C38F>ä#žN<C5BE>Ü”—ØYÏÂAÊUi7¬X¡q£ÕæÕÍí)Äw÷Üaã&¯j¢S<C2A2>ÇÔŒ¥u³àuÀÿäFÖ¯[¢²”·†©Ï)ÆBöîTÒvÝ´YÄ$KÛ62é7|!ùBt 4Œ°äé|Ì·é 2D8ìž§·ë 2ßù×

Binary file not shown.

@ -1,3 +0,0 @@
úò†@tŠ;û%Œ¥æds*Þ‚ÇŠÅfu”Ú OüÕê BPlŒùÅG«šéãPÐjQ~ç¸<C3A7>ñ¿Ø e½æ<C2BD>P "t­ÁÀV.%E¿Æ…B>,5g®àÑ`>FGq¾Á×°t¸GQ<47>õ åÕG‰eC™á‡¶qçQš½ñmÚ0e¬ÀDL7³aa» P‰¦fp­¤Tu´eW­áP\b¿a@ËM(øH1ÞePÄÉ[SØBúj5Ûã°¹E:e?#¹ÅnH«Yo$ŽY&ëð,\J}úp:-…K<E280A6>Øb__+jò õ¿´<C2BF>MÓiŸ™<Ÿ<>Ý<08>ÅDënTçà?*~Ùºó|ÛÍi
?—ÞiZZ]ä¯ÈØô±x_Ä EÚ²_þQÆ"Tøà|Ëc[â'tú[眄BžÚÂÓ…n'”øÃ ­,—SÞÙõ0Т m9í_ÓE *ø ÂÎÔ{{<>Dd”ˆ
WÍXä<EFBFBD>Y.·nz<6E>M¶G4ò.VÀª¡Rž_ 9R¬lô¯i,Ã,³¨äs™8“!³È(jyjÒqžÄ¿4`© ¶nZØ]•7d|Ö,Ö­J™I“.óHŸÿiœÑóÀuöúX¶ó°²‡Bò&ëyAüW†s?Â…âW ¥WR­çj²þ¥C³ù†|€ì†w—±

@ -1,2 +0,0 @@
Ń.ĄWá kgć*˘@`1šśóŇł'[<5B>@řhhË„0sě­Łs”;‡:d;›Ű™ń%ŔD7ąˇ ‰,}B‡îŮ\Á~zNŚvX ˇ!âEąí±ˇ“p!]Śń—|&CQIRB<52>W«L+® 5i*nS)Ą.(¬«Ę„ź#gđĎ*ţ:©ă¬™c®ďEÁǰŤůÝ0űŃżęNz+€„ĺ4TQŮÄń„3ĆĐ ŰÂäPˇ!Ččéü4~[™šż›ź.bŃźŢ ĺ` Č, ĺHâ%všZXőą[ă%Ih<49>čhĎfM<66>dĎÉ\Űak@¦g(˝đ©çOĆ*Ř+:üëď łŘ<C582>±ż˙YM-¸Ľ‰ˇĘ=¨ÍŔż,<2C>¸˘ĘćQÁ•$ëĹ–ýŕ…}5±;„<><E2809E>F FĄ]ÚĐÓŠlI śŠ> ŁGd }˝HĆíĺZpYčq‰´ŘA0mĎŢă¦ë #
ýŮ×

Binary file not shown.

@ -1,2 +0,0 @@
ÆÁb €÷è±ñ¦dgƒCKtª±È!pÑUæ¹å2 Ch¯*´ú€Ap,¼Í<C2BC>çÇeqHÿ @È}<7D>šÙ/‡.tîg žû½*Pé!¿Š<E280B9>K5ûe<>­¨ò>RéZ%êÆƒè$ªH'lšË<C5A1>¬ÃC`·ÉDÆÑ„A‡”«ïð<C3AF>Gèž7oÏу¾¨0]×e<C397>%æ¼Gë¡Ób¦!£ ¡ õE¢eäŽPëõÅ>á'²œ(€—¥3»Ôë—:Ƈgú­ªe!ïý®k|PkI¦ïèý:œ›_n²¬ïÊ4K_öÈôN&æ Jfêª[Ø6¤d0Ÿûù<C3BB>î8ù#f³ßA«ZW8?Í%c»X`
:L¾tÞþ*ÿzßw­E0;­8WŒNüg«HÝ=rÒú<C392><C3BA>zYÏ\uï"^g'*¿xTÐ¥lïö9<C3B6>F”Ô|ï9@ÜHƒ÷lçyÍσÃ@æg q†Jå3G:þ„zc;7Ù¬(<28>o¥0ìr<>•JiøqéÙ†1vÎ+šA

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -4,6 +4,7 @@
[GLOBAL] [GLOBAL]
SERVER_ID: 0000 SERVER_ID: 0000
DEBUG_BRIDGES: True
[REPORTS] [REPORTS]

@ -791,7 +791,11 @@ class routerHBP(HBSYSTEM):
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), call_duration).encode(encoding='utf-8', errors='ignore')) systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), call_duration).encode(encoding='utf-8', errors='ignore'))
# Create a Burst B-E packet (Embedded LC) # Create a Burst B-E packet (Embedded LC)
elif _dtype_vseq in [1,2,3,4]: elif _dtype_vseq in [1,2,3,4]:
dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264] #catch weird bug, so we can work out what's going on (N2CID)
try:
dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264]
except Exception as e:
logger.warning('(N2CID) Caught error [non-fatal] %s',e)
dmrpkt = dmrbits.tobytes() dmrpkt = dmrbits.tobytes()
_tmp_data = b''.join([_tmp_data, dmrpkt, _data[53:55]]) _tmp_data = b''.join([_tmp_data, dmrpkt, _data[53:55]])

@ -263,7 +263,7 @@ def reset_static_tg(tg,ts,_tmout,system):
BRIDGES[str(tg)] = bridgetemp BRIDGES[str(tg)] = bridgetemp
except KeyError: except KeyError:
logger.exception('(ERROR) KeyError in reset_static_tg() - bridge gone away?') logger.exception('(%s) KeyError in reset_static_tg() - bridge gone away? TG: %s',system,tg)
return return
def reset_default_reflector(reflector,_tmout,system): def reset_default_reflector(reflector,_tmout,system):
@ -388,6 +388,53 @@ def statTrimmer():
if CONFIG['REPORTS']['REPORT']: if CONFIG['REPORTS']['REPORT']:
report_server.send_clients(b'bridge updated') report_server.send_clients(b'bridge updated')
#Debug and fix bridge table issues.
def bridgeDebug():
logger.info('(BRIDGEDEBUG) Running bridge debug')
statroll = 0
for system in CONFIG['SYSTEMS']:
bridgeroll = 0
dialroll = 0
activeroll = 0
for _bridge in BRIDGES:
for enabled_system in BRIDGES[_bridge]:
if enabled_system['SYSTEM'] == system:
bridgeroll += 1
if enabled_system['ACTIVE']:
if _bridge and _bridge[0:1] == '#':
dialroll += 1
activeroll += 1
else:
activeroll += 1
if enabled_system['TO_TYPE'] == 'STAT':
statroll += 1
if bridgeroll:
logger.debug('(BRIDGEDEBUG) system %s has %s bridges of which %s are in an ACTIVE state', system, bridgeroll, activeroll)
if dialroll > 1 and CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER':
logger.warning('(BRIDGEDEBUG) system %s has more than one active dial bridge (%s) - fixing',system, dialroll)
times = {}
for _bridge in BRIDGES:
for enabled_system in BRIDGES[_bridge]:
if enabled_system['ACTIVE'] and _bridge and _bridge[0:1] == '#':
times[enabled_system['TIMER']] = _bridge
ordered = sorted(times.keys())
_setbridge = times[ordered.pop()]
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER':
logger.warning('(BRIDGEDEBUG) setting %s dial bridge to %s as this bridge has the longest timer set to run',system, _setbridge)
for _tstamp in ordered:
for _bridge in times.values():
for _entry in BRIDGES[_bridge]:
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER':
if _entry['SYSTEM'] == system:
_entry['ACTIVE'] = False
logger.info('(BRIDGEDEBUG) The server currently has %s STATic bridges',statroll)
def kaReporting(): def kaReporting():
logger.debug('(ROUTER) KeepAlive reporting loop started') logger.debug('(ROUTER) KeepAlive reporting loop started')
for system in systems: for system in systems:
@ -882,6 +929,12 @@ def options_config():
if isinstance(_options['DEFAULT_UA_TIMER'], str) and not _options['DEFAULT_UA_TIMER'].isdigit(): if isinstance(_options['DEFAULT_UA_TIMER'], str) and not _options['DEFAULT_UA_TIMER'].isdigit():
logger.debug('(OPTIONS) %s - DEFAULT_REFLECTOR is not an integer, ignoring',_system) logger.debug('(OPTIONS) %s - DEFAULT_REFLECTOR is not an integer, ignoring',_system)
continue continue
#if the UA timer is set to 0 - actually set it to (close to) maximum size of a 32
#bit signed int - which works out at around 68 years!
#For all practical purposes, this implements an unlimited timer - aka sticky static.
if int(_options['DEFAULT_UA_TIMER']) == 0:
_options['DEFAULT_UA_TIMER'] = 35791394
_tmout = int(_options['DEFAULT_UA_TIMER']) _tmout = int(_options['DEFAULT_UA_TIMER'])
@ -1481,6 +1534,7 @@ class routerOBP(OPENBRIDGE):
#Rate drop #Rate drop
if self.STATUS[_stream_id]['packets'] > 18 and (self.STATUS[_stream_id]['packets'] / self.STATUS[_stream_id]['START'] > 25): if self.STATUS[_stream_id]['packets'] > 18 and (self.STATUS[_stream_id]['packets'] / self.STATUS[_stream_id]['START'] > 25):
logger.warning("(%s) *PacketControl* RATE DROP! Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id)) logger.warning("(%s) *PacketControl* RATE DROP! Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id))
self.proxy_BadPeer()
return return
#Duplicate handling# #Duplicate handling#
@ -2536,7 +2590,7 @@ if __name__ == '__main__':
if cli_args.LOG_LEVEL: if cli_args.LOG_LEVEL:
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
logger = log.config_logging(CONFIG['LOGGER']) logger = log.config_logging(CONFIG['LOGGER'])
logger.info('\n\nCopyright (c) 2020, 2021, 2022 Simon G7RZU simon@gb7fr.org.uk') logger.info('\n\nCopyright (c) 2020, 2021, 2022, 2023 Simon G7RZU simon@gb7fr.org.uk')
logger.info('Copyright (c) 2013, 2014, 2015, 2016, 2018, 2019\n\tThe Regents of the K0USY Group. All rights reserved.\n') logger.info('Copyright (c) 2013, 2014, 2015, 2016, 2018, 2019\n\tThe Regents of the K0USY Group. All rights reserved.\n')
logger.debug('(GLOBAL) Logging system started, anything from here on gets logged') logger.debug('(GLOBAL) Logging system started, anything from here on gets logged')
@ -2757,6 +2811,13 @@ if __name__ == '__main__':
ka_task = task.LoopingCall(kaReporting) ka_task = task.LoopingCall(kaReporting)
ka = ka_task.start(60) ka = ka_task.start(60)
ka.addErrback(loopingErrHandle) ka.addErrback(loopingErrHandle)
#Debug bridges
if CONFIG['GLOBAL']['DEBUG_BRIDGES']:
debug_bridges_task = task.LoopingCall(bridgeDebug)
debug_bridges = debug_bridges_task.start(66)
debug_bridges.addErrback(loopingErrHandle)
#Subscriber map trimmer #Subscriber map trimmer
sub_trimmer_task = task.LoopingCall(SubMapTrimmer) sub_trimmer_task = task.LoopingCall(SubMapTrimmer)

@ -147,7 +147,8 @@ def build_config(_config_file):
'ANNOUNCEMENT_LANGUAGES': config.get(section, 'ANNOUNCEMENT_LANGUAGES', fallback=''), 'ANNOUNCEMENT_LANGUAGES': config.get(section, 'ANNOUNCEMENT_LANGUAGES', fallback=''),
'SERVER_ID': config.getint(section, 'SERVER_ID', fallback=0).to_bytes(4, 'big'), 'SERVER_ID': config.getint(section, 'SERVER_ID', fallback=0).to_bytes(4, 'big'),
'DATA_GATEWAY': config.getboolean(section, 'DATA_GATEWAY', fallback=False), 'DATA_GATEWAY': config.getboolean(section, 'DATA_GATEWAY', fallback=False),
'VALIDATE_SERVER_IDS': config.getboolean(section, 'VALIDATE_SERVER_IDS', fallback=True) 'VALIDATE_SERVER_IDS': config.getboolean(section, 'VALIDATE_SERVER_IDS', fallback=True),
'DEBUG_BRIDGES' : config.getboolean(section, 'DEBUG_BRIDGES', fallback=True)
}) })
if not CONFIG['GLOBAL']['ANNOUNCEMENT_LANGUAGES']: if not CONFIG['GLOBAL']['ANNOUNCEMENT_LANGUAGES']:
@ -158,7 +159,7 @@ def build_config(_config_file):
'REPORT': config.getboolean(section, 'REPORT', fallback=True), 'REPORT': config.getboolean(section, 'REPORT', fallback=True),
'REPORT_INTERVAL': config.getint(section, 'REPORT_INTERVAL', fallback=60), 'REPORT_INTERVAL': config.getint(section, 'REPORT_INTERVAL', fallback=60),
'REPORT_PORT': config.getint(section, 'REPORT_PORT', fallback=4321), 'REPORT_PORT': config.getint(section, 'REPORT_PORT', fallback=4321),
'REPORT_CLIENTS': config.get(section, 'REPORT_CLIENTS',fallback='127.0.0.1').split(',') 'REPORT_CLIENTS': config.get(section, 'REPORT_CLIENTS',fallback='*').split(',')
}) })
elif section == 'LOGGER': elif section == 'LOGGER':

@ -15,7 +15,7 @@
# along with this program; if not, write to the Free Software Foundation, # along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
############################################################################### ###############################################################################
FROM python:3.10-alpine FROM python:3.11-alpine
ENTRYPOINT [ "/entrypoint" ] ENTRYPOINT [ "/entrypoint" ]

@ -15,7 +15,7 @@
# along with this program; if not, write to the Free Software Foundation, # along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
############################################################################### ###############################################################################
FROM python:3.10-alpine FROM python:3.11-alpine
ENTRYPOINT [ "/entrypoint" ] ENTRYPOINT [ "/entrypoint" ]

@ -0,0 +1,104 @@
#This empty config file will use defaults for everything apart from OBP and HBP config
#This is usually a sensible choice.
#I have moved to a config like this to encourage servers to use the accepted defaults
#unless you really know what you are doing.
[GLOBAL]
#If you join the FreeDMR network, you need to add your ServerID Here.
SERVER_ID: 0
[REPORTS]
[LOGGER]
[ALIASES]
[ALLSTAR]
#This is an example OpenBridgeProtocol (OBP) or FreeBridgeProtocol (FBP) configuration
#If you joing FreeDMR, you will be given a config like this to paste in
[OBP-TEST]
MODE: OPENBRIDGE
ENABLED: False
IP:
PORT: 62044
#The ID which you expect to see sent from the other end of the link.
NETWORK_ID: 1
PASSPHRASE: mypass
TARGET_IP:
TARGET_PORT: 62044
USE_ACL: True
SUB_ACL: DENY:1
TGID_ACL: PERMIT:ALL
#Should always be true if using docker.
RELAX_CHECKS: True
#True for FBP, False for OBP
ENHANCED_OBP: True
#PROTO_VER should be 5 for FreeDMR servers using FBP
#1 for other servers using OBP
PROTO_VER: 5
#This defines parameters for repeater/hotspot connections
#via HomeBrewProtocol (HBP)
#I don't recommend changing most of this unless you know what you are doing
[SYSTEM]
MODE: MASTER
ENABLED: True
REPEAT: True
MAX_PEERS: 1
EXPORT_AMBE: False
IP: 127.0.0.1
PORT: 54000
PASSPHRASE:
GROUP_HANGTIME: 5
USE_ACL: True
REG_ACL: DENY:1
SUB_ACL: DENY:1
TGID_TS1_ACL: PERMIT:ALL
TGID_TS2_ACL: PERMIT:ALL
DEFAULT_UA_TIMER: 10
SINGLE_MODE: True
VOICE_IDENT: True
TS1_STATIC:
TS2_STATIC:
DEFAULT_REFLECTOR: 0
ANNOUNCEMENT_LANGUAGE: en_GB
GENERATOR: 100
ALLOW_UNREG_ID: False
PROXY_CONTROL: True
OVERRIDE_IDENT_TG:
#Echo (Loro / Parrot) server
[ECHO]
MODE: PEER
ENABLED: True
LOOSE: False
EXPORT_AMBE: False
IP: 127.0.0.1
PORT: 54916
MASTER_IP: 127.0.0.1
MASTER_PORT: 54915
PASSPHRASE: passw0rd
CALLSIGN: ECHO
RADIO_ID: 1000001
RX_FREQ: 449000000
TX_FREQ: 444000000
TX_POWER: 25
COLORCODE: 1
SLOTS: 1
LATITUDE: 00.0000
LONGITUDE: 000.0000
HEIGHT: 0
LOCATION: Earth
DESCRIPTION: ECHO
URL: www.freedmr.uk
SOFTWARE_ID: 20170620
PACKAGE_ID: MMDVM_FreeDMR
GROUP_HANGTIME: 5
OPTIONS:
USE_ACL: True
SUB_ACL: DENY:1
TGID_TS1_ACL: PERMIT:ALL
TGID_TS2_ACL: PERMIT:ALL
ANNOUNCEMENT_LANGUAGE: en_GB

@ -66,6 +66,8 @@ from urllib.request import urlopen
import shutil import shutil
import csv import csv
import math
logging.TRACE = 5 logging.TRACE = 5
logging.addLevelName(logging.TRACE, 'TRACE') logging.addLevelName(logging.TRACE, 'TRACE')
@ -502,7 +504,7 @@ class OPENBRIDGE(DatagramProtocol):
self._laststrid.append(_stream_id) self._laststrid.append(_stream_id)
return return
if (_int_dst_id >= 80 and _int_dst_id <= 89) or (_int_dst_id >= 800 and _int_dst_id <= 899) and int(str(int.from_bytes(_source_server,'big'))[:3]) != int(str(int.from_bytes(self._CONFIG['GLOBAL']['SERVER_ID'],'big'))[:3]): if ((_int_dst_id >= 80 and _int_dst_id <= 89) or (_int_dst_id >= 800 and _int_dst_id <= 899)) and int(str(int.from_bytes(_source_server,'big'))[:3]) != int(str(int.from_bytes(self._CONFIG['GLOBAL']['SERVER_ID'],'big'))[:3]):
if _stream_id not in self._laststrid: if _stream_id not in self._laststrid:
logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER (local to MCC)', self._system, int_id(_stream_id), _int_dst_id) logger.info('(%s) CALL DROPPED WITH STREAM ID %s FROM SUBSCRIBER %s BY GLOBAL TG FILTER (local to MCC)', self._system, int_id(_stream_id), _int_dst_id)
self.send_bcsq(_dst_id,_stream_id) self.send_bcsq(_dst_id,_stream_id)
@ -802,6 +804,10 @@ class HBSYSTEM(DatagramProtocol):
_bltime = str(_bltime) _bltime = str(_bltime)
_prpacket = b''.join([PRBL,peer_id,_bltime.encode('UTF-8')]) _prpacket = b''.join([PRBL,peer_id,_bltime.encode('UTF-8')])
self.transport.write(_prpacket,sockaddr) self.transport.write(_prpacket,sockaddr)
def proxy_BadPeer(self):
for _pi in self._peers:
self.proxy_IPBlackList(_pi,self._peers[_pi]['SOCKADDR'])
def validate_id(self,_peer_id): def validate_id(self,_peer_id):
@ -1343,7 +1349,7 @@ def mk_aliases(_config):
# Make Dictionaries # Make Dictionaries
#Peer IDs #Peer IDs
try: try:
if exists(_config['ALIASES']['PATH'] + _config['ALIASES']['PEER_FILE'] + '.bak') and (getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['PEER_FILE'] + '.bak') > getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['PEER_FILE'])): if exists(_config['ALIASES']['PATH'] + _config['ALIASES']['PEER_FILE'] + '.bak') and not math.isclose(getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['PEER_FILE'] + '.bak'),getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['PEER_FILE']), rel_tol=1000):
raise Exception('backup peer_ids file is larger than new file') raise Exception('backup peer_ids file is larger than new file')
try: try:
if blake2bsum(''.join([_config['ALIASES']['PATH'], _config['ALIASES']['PEER_FILE']])) != checksums['peer_ids']: if blake2bsum(''.join([_config['ALIASES']['PATH'], _config['ALIASES']['PEER_FILE']])) != checksums['peer_ids']:
@ -1371,7 +1377,7 @@ def mk_aliases(_config):
#Subscriber IDs #Subscriber IDs
try: try:
if exists(_config['ALIASES']['PATH'] + _config['ALIASES']['SUBSCRIBER_FILE'] + '.bak') and (getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['SUBSCRIBER_FILE'] + '.bak') > getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['SUBSCRIBER_FILE'])): if exists(_config['ALIASES']['PATH'] + _config['ALIASES']['SUBSCRIBER_FILE'] + '.bak') and not math.isclose(getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['SUBSCRIBER_FILE'] + '.bak'), getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['SUBSCRIBER_FILE']),rel_tol=1000):
raise Exception('backup subscriber_ids file is larger than new file') raise Exception('backup subscriber_ids file is larger than new file')
try: try:
if blake2bsum(''.join([_config['ALIASES']['PATH'], _config['ALIASES']['SUBSCRIBER_FILE']])) != checksums['subscriber_ids']: if blake2bsum(''.join([_config['ALIASES']['PATH'], _config['ALIASES']['SUBSCRIBER_FILE']])) != checksums['subscriber_ids']:
@ -1402,7 +1408,7 @@ def mk_aliases(_config):
#Talkgroup IDs #Talkgroup IDs
try: try:
if exists(_config['ALIASES']['PATH'] + _config['ALIASES']['TGID_FILE'] + '.bak') and (getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['TGID_FILE'] + '.bak') > getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['TGID_FILE'])): if exists(_config['ALIASES']['PATH'] + _config['ALIASES']['TGID_FILE'] + '.bak') and not math.isclose(getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['TGID_FILE'] + '.bak'), getsize(_config['ALIASES']['PATH'] + _config['ALIASES']['TGID_FILE']),rel_tol=1000):
raise Exception('backup talkgroup_ids file is larger than new file') raise Exception('backup talkgroup_ids file is larger than new file')
try: try:
if blake2bsum(''.join([_config['ALIASES']['PATH'], _config['ALIASES']['TGID_FILE']])) != checksums['talkgroup_ids']: if blake2bsum(''.join([_config['ALIASES']['PATH'], _config['ALIASES']['TGID_FILE']])) != checksums['talkgroup_ids']:

@ -283,6 +283,7 @@ if __name__ == '__main__':
BlackList = [1234567] BlackList = [1234567]
#e.g. {10.0.0.1: 0, 10.0.0.2: 0} #e.g. {10.0.0.1: 0, 10.0.0.2: 0}
IPBlackList = {} IPBlackList = {}
UsePrivilegedHelper = False
#******************* #*******************
@ -313,6 +314,11 @@ if __name__ == '__main__':
ClientInfo = bool(os.environ['FDPROXY_CLIENTINFO']) ClientInfo = bool(os.environ['FDPROXY_CLIENTINFO'])
if 'FDPROXY_LISTENPORT' in os.environ: if 'FDPROXY_LISTENPORT' in os.environ:
ListenPort = int(os.environ['FDPROXY_LISTENPORT']) ListenPort = int(os.environ['FDPROXY_LISTENPORT'])
if 'USE_PRIV_HELPER' in os.environ:
UsePrivilegedHelper = os.environ['USE_PRIV_HELPER']
if UsePrivilegedHelper:
for port in range(DestportStart,DestPortEnd+1,1): for port in range(DestportStart,DestPortEnd+1,1):
CONNTRACK[port] = False CONNTRACK[port] = False

@ -121,47 +121,7 @@ voiceMap = {
}, },
'es_ES': { 'es_ES': {
'1': 'one', '0': 'zero',
'2': 'two',
'3': 'three',
'4': 'four',
'5': 'five',
'6': 'six',
'7': 'seven',
'8': 'eight',
'9': 'nine',
'A': 'alfa',
'B': 'bravo',
'C': 'charlie',
'D': 'delta',
'E': 'echo',
'F': 'foxtrot',
'G': 'golf',
'H': 'hotel',
'I': 'india',
'J': 'juliet',
'K': 'kilo',
'L': 'lima',
'M': 'mike',
'N': 'november',
'O': 'oscar',
'P': 'papa',
'Q': 'quebec',
'R': 'romeo',
'S': 'sierra',
'T': 'tango',
'U': 'uniform',
'V': 'victor',
'W': 'whiskey',
'X': 'x-ray',
'Y': 'yankee',
'Z': 'zulu',
'to': 'silence',
'notlinked': 'not-linked',
'linkedto': 'linked-to',
'allstar-link-mode': 'alfa'
},
'es_ES_2': {
'1': 'one', '1': 'one',
'2': 'two', '2': 'two',
'3': 'three', '3': 'three',

Loading…
Cancel
Save

Powered by TurnKey Linux.